Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/wasm/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Use `.pipeThrough()` instead of `.pipe()`.
*/

import type { Transformer } from 'node:stream/web';
import { createLZMAError } from '../errors.js';
import type { LZMAOptions } from '../types.js';
import { code, decoderInit, encoderInit, end, getModule } from './bindings.js';
Expand Down Expand Up @@ -65,9 +66,13 @@ export function createXz(opts?: LZMAOptions): TransformStream<Uint8Array, Uint8A
}
},
/* cancel() frees WASM resources when the readable side is cancelled.
Part of the Streams spec but not yet in TypeScript's DOM lib. */
// @ts-expect-error cancel is a valid Transformer method per Streams spec
Part of the Streams spec; @types/node added `cancel?:` to the Transformer
interface in 25.7.0. The intersection cast accepts the property on both
older typings (where it's absent) and newer typings (where it's present),
keeping the typecheck stable across `@types/node` minor bumps. */
cancel: doCleanup,
} as Transformer<Uint8Array, Uint8Array> & {
cancel?: (reason: unknown) => void | PromiseLike<void>;
});
Comment thread
oorabona marked this conversation as resolved.
}

Expand Down Expand Up @@ -125,9 +130,10 @@ export function createUnxz(): TransformStream<Uint8Array, Uint8Array> {
}
},
/* cancel() frees WASM resources when the readable side is cancelled.
Part of the Streams spec but not yet in TypeScript's DOM lib. */
// @ts-expect-error cancel is a valid Transformer method per Streams spec
See createXz() for the rationale on the intersection cast. */
cancel: doCleanup,
} as Transformer<Uint8Array, Uint8Array> & {
cancel?: (reason: unknown) => void | PromiseLike<void>;
});
}

Expand Down
29 changes: 29 additions & 0 deletions test/wasm/stream-directive-hygiene.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';

/**
* Forward-compat guard for `src/wasm/stream.ts`.
*
* `@types/node` adds and (more rarely) removes typed members of the Streams
* interfaces across minor bumps. The file deliberately uses an intersection
* cast on `TransformStream` constructor calls so it needs ZERO TypeScript
* suppression directives. Any directive — in either the expect-error or
* ignore form — would either mask a real upstream regression, or fire
* TS2578 ("unused directive") the moment the typing it suppresses lands
* upstream, breaking the daily Refresh Lockfile workflow.
*
* This test is the deterministic regression detector for that invariant.
*/
describe('src/wasm/stream.ts — TS directive hygiene', () => {
it('contains no @ts-ignore or @ts-expect-error directive', () => {
const path = fileURLToPath(new URL('../../src/wasm/stream.ts', import.meta.url));
const source = readFileSync(path, 'utf8');

// Match the directive form specifically (with leading `//` and a word boundary
// after the directive name), so the rule name appearing inside a doc-comment
// or string literal does not produce a false positive.
const directivePattern = /\/\/\s*@ts-(expect-error|ignore)\b/;
expect(source).not.toMatch(directivePattern);
});
});
Loading