Skip to content

Commit bfa3d05

Browse files
committed
fixes type issues, using node:test
1 parent 32b1a8b commit bfa3d05

8 files changed

Lines changed: 43 additions & 38 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
},
153153
"devDependencies": {
154154
"@types/mocha": "^10.0.10",
155-
"@types/node": "22.x",
155+
"@types/node": "22.19.19",
156156
"@types/vscode": "^1.120.0",
157157
"@vscode/test-cli": "^0.0.12",
158158
"@vscode/test-electron": "^2.5.2",

src/controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const DEBOUNCE_MS = 400;
1616
* decorations. Debounced per document, with a generation counter + AbortController
1717
* so superseded refreshes are cancelled and their stale results dropped.
1818
*/
19-
export class InsightController {
19+
export class InsightController {
2020
private readonly generations = new Map<string, number>();
2121
private readonly debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();
2222
private readonly inflight = new Map<string, AbortController>();

src/enrich/enrich.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { resolveVersion } from '../packageJson/resolveVersion';
99
import { countTransitive } from '../packageJson/transitive';
1010
import { InspectSummary, PurlCache } from './cache';
1111
import { mapWithConcurrency } from './pool';
12+
import { purlNameKey } from '../utils';
13+
export { purlNameKey } from '../utils';
1214

1315
/** A per-package map of open risks in the connected asset, keyed by purlNameKey. */
1416
export type AssetXref = Map<string, AssetRisk>;
@@ -117,19 +119,3 @@ function distill(resp: PurlInspectResponse): InspectSummary {
117119
project,
118120
};
119121
}
120-
121-
/**
122-
* Canonical version-less key for matching purls across the package.json side and
123-
* the backend. Drops qualifiers/subpath, decodes the `%40` the backend uses for
124-
* scoped npm packages, removes the version, and lowercases. So both
125-
* `pkg:npm/@sentry/nextjs@8` and `pkg:npm/%40sentry/nextjs@8` -> `pkg:npm/@sentry/nextjs`.
126-
*/
127-
export function purlNameKey(purl: string): string {
128-
let s = purl.split('?')[0].split('#')[0].replace(/%40/gi, '@');
129-
const lastSlash = s.lastIndexOf('/');
130-
const versionAt = s.indexOf('@', lastSlash < 0 ? 0 : lastSlash);
131-
if (versionAt !== -1) {
132-
s = s.slice(0, versionAt);
133-
}
134-
return s.toLowerCase();
135-
}

src/test/packageGraph.test.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as assert from 'assert';
2-
import { purlNameKey } from '../enrich/enrich';
2+
import { describe, it } from 'node:test';
3+
import { purlNameKey } from '../utils';
34
import { Lockfile } from '../packageJson/lockfile';
45
import { cleanRange } from '../packageJson/resolveVersion';
56
import { countTransitive } from '../packageJson/transitive';
67

7-
suite('countTransitive', () => {
8+
describe('countTransitive', () => {
89
const lock: Lockfile = {
910
dir: '/x',
1011
lockfileVersion: 3,
@@ -18,12 +19,12 @@ suite('countTransitive', () => {
1819
},
1920
};
2021

21-
test('counts unique transitive deps and ignores unrelated packages', () => {
22+
it('counts unique transitive deps and ignores unrelated packages', () => {
2223
// a -> b, c ; b -> c. Nested d is not in a's manifest deps, standalone unreachable.
2324
assert.strictEqual(countTransitive(lock, 'a'), 2);
2425
});
2526

26-
test('prefers the nested copy when resolving', () => {
27+
it('prefers the nested copy when resolving', () => {
2728
const nested: Lockfile = {
2829
dir: '/x',
2930
lockfileVersion: 3,
@@ -39,41 +40,41 @@ suite('countTransitive', () => {
3940
assert.strictEqual(countTransitive(nested, 'a'), 2);
4041
});
4142

42-
test('returns undefined for missing package or non-v2/v3 lockfile', () => {
43+
it('returns undefined for missing package or non-v2/v3 lockfile', () => {
4344
assert.strictEqual(countTransitive(lock, 'missing'), undefined);
4445
assert.strictEqual(countTransitive({ dir: '/x', lockfileVersion: 1, dependencies: {} }, 'a'), undefined);
4546
assert.strictEqual(countTransitive(undefined, 'a'), undefined);
4647
});
4748
});
4849

49-
suite('cleanRange', () => {
50-
test('extracts a concrete version from a range', () => {
50+
describe('cleanRange', () => {
51+
it('extracts a concrete version from a range', () => {
5152
assert.strictEqual(cleanRange('^4.17.21'), '4.17.21');
5253
assert.strictEqual(cleanRange('~1.2.3'), '1.2.3');
5354
assert.strictEqual(cleanRange('>=1.0.0 <2.0.0'), '1.0.0');
5455
assert.strictEqual(cleanRange('1.2.3-beta.1'), '1.2.3-beta.1');
5556
});
5657

57-
test('returns undefined for non-concrete specs', () => {
58+
it('returns undefined for non-concrete specs', () => {
5859
assert.strictEqual(cleanRange('*'), undefined);
5960
assert.strictEqual(cleanRange('latest'), undefined);
6061
assert.strictEqual(cleanRange('workspace:*'), undefined);
6162
assert.strictEqual(cleanRange('1.2.x'), undefined);
6263
});
6364
});
6465

65-
suite('purlNameKey', () => {
66-
test('collapses backend %40 and literal @ scoped purls to the same key', () => {
66+
describe('purlNameKey', () => {
67+
it('collapses backend %40 and literal @ scoped purls to the same key', () => {
6768
assert.strictEqual(purlNameKey('pkg:npm/%40sentry/nextjs@8.0.0'), 'pkg:npm/@sentry/nextjs');
6869
assert.strictEqual(purlNameKey('pkg:npm/@sentry/nextjs@8.0.0'), 'pkg:npm/@sentry/nextjs');
6970
});
7071

71-
test('strips version and qualifiers for unscoped purls', () => {
72+
it('strips version and qualifiers for unscoped purls', () => {
7273
assert.strictEqual(purlNameKey('pkg:npm/next@14.2.0'), 'pkg:npm/next');
7374
assert.strictEqual(purlNameKey('pkg:npm/next@14.2.0?type=module'), 'pkg:npm/next');
7475
});
7576

76-
test('keeps the name when there is no version', () => {
77+
it('keeps the name when there is no version', () => {
7778
assert.strictEqual(purlNameKey('pkg:npm/%40scope/name'), 'pkg:npm/@scope/name');
7879
assert.strictEqual(purlNameKey('pkg:npm/next'), 'pkg:npm/next');
7980
});

src/test/signing.test.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as assert from 'assert';
22
import { createHash } from 'node:crypto';
3+
import { describe, it } from 'node:test';
34
import { p256 } from '@noble/curves/p256';
45
import { deriveFingerprint, isValidTokenFormat, signRequest } from '../api/signing';
56

@@ -10,25 +11,25 @@ const FIXED = '1a73970f31816d996ab514c4ffea04b6dee0eadc107267d0c911fd817a7b5167'
1011
const GOLDEN_FINGERPRINT = 'b6c40569c43b73924a56e90e4130916b556afe42b20e45ba6fcd9a25d4378c96';
1112
const EMPTY_BODY_DIGEST = 'sha-256=:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=:';
1213

13-
suite('signing', () => {
14-
test('fingerprint matches the Go-computed golden value', () => {
14+
describe('signing', () => {
15+
it('fingerprint matches the Go-computed golden value', () => {
1516
assert.strictEqual(deriveFingerprint(FIXED), GOLDEN_FINGERPRINT);
1617
});
1718

18-
test('content-digest is the structured sha-256 of the empty body', () => {
19+
it('content-digest is the structured sha-256 of the empty body', () => {
1920
const headers = signRequest(FIXED, { method: 'GET' });
2021
assert.strictEqual(headers['Content-Digest'], EMPTY_BODY_DIGEST);
2122
});
2223

23-
test('signature-input covers @method and content-digest with created + alg', () => {
24+
it('signature-input covers @method and content-digest with created + alg', () => {
2425
const headers = signRequest(FIXED, { method: 'GET' });
2526
assert.match(
2627
headers['Signature-Input'],
2728
/^sig77=\("@method" "content-digest"\);created=\d+;alg="ecdsa-p256-sha256"$/,
2829
);
2930
});
3031

31-
test('signature verifies against the derived public key (round trip)', () => {
32+
it('signature verifies against the derived public key (round trip)', () => {
3233
const headers = signRequest(FIXED, { method: 'GET' });
3334
const created = /created=(\d+)/.exec(headers['Signature-Input'])?.[1];
3435
const params = `("@method" "content-digest");created=${created};alg="ecdsa-p256-sha256"`;
@@ -39,7 +40,7 @@ suite('signing', () => {
3940
assert.ok(p256.verify(rs, hash, pub));
4041
});
4142

42-
test('isValidTokenFormat accepts hex keys and rejects junk', () => {
43+
it('isValidTokenFormat accepts hex keys and rejects junk', () => {
4344
assert.ok(isValidTokenFormat(FIXED));
4445
assert.ok(isValidTokenFormat(`0x${FIXED}`));
4546
assert.ok(!isValidTokenFormat('not-a-token'));

src/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Canonical version-less key for matching purls across the package.json side and
3+
* the backend. Drops qualifiers/subpath, decodes the `%40` the backend uses for
4+
* scoped npm packages, removes the version, and lowercases. So both
5+
* `pkg:npm/@sentry/nextjs@8` and `pkg:npm/%40sentry/nextjs@8` -> `pkg:npm/@sentry/nextjs`.
6+
*/
7+
export function purlNameKey(purl: string): string {
8+
let s = purl.split('?')[0].split('#')[0].replace(/%40/gi, '@');
9+
const lastSlash = s.lastIndexOf('/');
10+
const versionAt = s.indexOf('@', lastSlash < 0 ? 0 : lastSlash);
11+
if (versionAt !== -1) {
12+
s = s.slice(0, versionAt);
13+
}
14+
return s.toLowerCase();
15+
}

tsconfig.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
"target": "ES2022",
55
"outDir": "out",
66
"lib": [
7-
"ES2022"
7+
"ES2022",
8+
"DOM"
89
],
910
"sourceMap": true,
1011
"rootDir": "src",
12+
"types": ["node"],
1113
"strict": true, /* enable all strict type-checking options */
1214
/* Additional Checks */
1315
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */

0 commit comments

Comments
 (0)