apiwatcher-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/changesets/stripe/2025-09-30.clover__2026-08-26.dahlia.json +4576 -0
  2. package/changesets/stripe/index.json +16 -0
  3. package/data/stripe/events.json +271 -0
  4. package/data/stripe/method-map.json +5718 -0
  5. package/dist/changeset/index-file.d.ts +30 -0
  6. package/dist/changeset/index-file.d.ts.map +1 -0
  7. package/dist/changeset/index-file.js +34 -0
  8. package/dist/changeset/index-file.js.map +1 -0
  9. package/dist/changeset/load.d.ts +21 -0
  10. package/dist/changeset/load.d.ts.map +1 -0
  11. package/dist/changeset/load.js +113 -0
  12. package/dist/changeset/load.js.map +1 -0
  13. package/dist/changeset/types.d.ts +97 -0
  14. package/dist/changeset/types.d.ts.map +1 -0
  15. package/dist/changeset/types.js +18 -0
  16. package/dist/changeset/types.js.map +1 -0
  17. package/dist/changeset/version.d.ts +17 -0
  18. package/dist/changeset/version.d.ts.map +1 -0
  19. package/dist/changeset/version.js +33 -0
  20. package/dist/changeset/version.js.map +1 -0
  21. package/dist/cli/args.d.ts +15 -0
  22. package/dist/cli/args.d.ts.map +1 -0
  23. package/dist/cli/args.js +82 -0
  24. package/dist/cli/args.js.map +1 -0
  25. package/dist/cli/index.d.ts +5 -0
  26. package/dist/cli/index.d.ts.map +1 -0
  27. package/dist/cli/index.js +333 -0
  28. package/dist/cli/index.js.map +1 -0
  29. package/dist/config.d.ts +26 -0
  30. package/dist/config.d.ts.map +1 -0
  31. package/dist/config.js +92 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/index.d.ts +14 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +14 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/report/impact.d.ts +40 -0
  38. package/dist/report/impact.d.ts.map +1 -0
  39. package/dist/report/impact.js +331 -0
  40. package/dist/report/impact.js.map +1 -0
  41. package/dist/report/impact.test.d.ts +2 -0
  42. package/dist/report/impact.test.d.ts.map +1 -0
  43. package/dist/report/impact.test.js +247 -0
  44. package/dist/report/impact.test.js.map +1 -0
  45. package/dist/report/render.d.ts +9 -0
  46. package/dist/report/render.d.ts.map +1 -0
  47. package/dist/report/render.js +211 -0
  48. package/dist/report/render.js.map +1 -0
  49. package/dist/scanner/ast.d.ts +74 -0
  50. package/dist/scanner/ast.d.ts.map +1 -0
  51. package/dist/scanner/ast.js +930 -0
  52. package/dist/scanner/ast.js.map +1 -0
  53. package/dist/scanner/paths.d.ts +42 -0
  54. package/dist/scanner/paths.d.ts.map +1 -0
  55. package/dist/scanner/paths.js +179 -0
  56. package/dist/scanner/paths.js.map +1 -0
  57. package/dist/scanner/scan.d.ts +11 -0
  58. package/dist/scanner/scan.d.ts.map +1 -0
  59. package/dist/scanner/scan.js +268 -0
  60. package/dist/scanner/scan.js.map +1 -0
  61. package/dist/scanner/scan.test.d.ts +2 -0
  62. package/dist/scanner/scan.test.d.ts.map +1 -0
  63. package/dist/scanner/scan.test.js +134 -0
  64. package/dist/scanner/scan.test.js.map +1 -0
  65. package/dist/scanner/types.d.ts +74 -0
  66. package/dist/scanner/types.d.ts.map +1 -0
  67. package/dist/scanner/types.js +7 -0
  68. package/dist/scanner/types.js.map +1 -0
  69. package/dist/scanner/version.d.ts +23 -0
  70. package/dist/scanner/version.d.ts.map +1 -0
  71. package/dist/scanner/version.js +155 -0
  72. package/dist/scanner/version.js.map +1 -0
  73. package/dist/scanner/walk.d.ts +26 -0
  74. package/dist/scanner/walk.d.ts.map +1 -0
  75. package/dist/scanner/walk.js +117 -0
  76. package/dist/scanner/walk.js.map +1 -0
  77. package/dist/scanner/wrapper.test.d.ts +2 -0
  78. package/dist/scanner/wrapper.test.d.ts.map +1 -0
  79. package/dist/scanner/wrapper.test.js +92 -0
  80. package/dist/scanner/wrapper.test.js.map +1 -0
  81. package/dist/specdiff/build-method-map.d.ts +6 -0
  82. package/dist/specdiff/build-method-map.d.ts.map +1 -0
  83. package/dist/specdiff/build-method-map.js +231 -0
  84. package/dist/specdiff/build-method-map.js.map +1 -0
  85. package/dist/specdiff/compat.d.ts +20 -0
  86. package/dist/specdiff/compat.d.ts.map +1 -0
  87. package/dist/specdiff/compat.js +58 -0
  88. package/dist/specdiff/compat.js.map +1 -0
  89. package/dist/specdiff/diff.d.ts +28 -0
  90. package/dist/specdiff/diff.d.ts.map +1 -0
  91. package/dist/specdiff/diff.js +529 -0
  92. package/dist/specdiff/diff.js.map +1 -0
  93. package/dist/specdiff/diff.test.d.ts +2 -0
  94. package/dist/specdiff/diff.test.d.ts.map +1 -0
  95. package/dist/specdiff/diff.test.js +260 -0
  96. package/dist/specdiff/diff.test.js.map +1 -0
  97. package/dist/specdiff/fetch.d.ts +28 -0
  98. package/dist/specdiff/fetch.d.ts.map +1 -0
  99. package/dist/specdiff/fetch.js +68 -0
  100. package/dist/specdiff/fetch.js.map +1 -0
  101. package/dist/specdiff/methodmap.d.ts +45 -0
  102. package/dist/specdiff/methodmap.d.ts.map +1 -0
  103. package/dist/specdiff/methodmap.js +109 -0
  104. package/dist/specdiff/methodmap.js.map +1 -0
  105. package/dist/specdiff/openapi.d.ts +166 -0
  106. package/dist/specdiff/openapi.d.ts.map +1 -0
  107. package/dist/specdiff/openapi.js +282 -0
  108. package/dist/specdiff/openapi.js.map +1 -0
  109. package/package.json +33 -0
@@ -0,0 +1,134 @@
1
+ import assert from 'node:assert/strict';
2
+ import { test } from 'node:test';
3
+ import { dirname, join, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { scanRepo } from './scan.js';
6
+ import { resolveCall, extractStripePath } from './ast.js';
7
+ import { matchesIgnore } from './walk.js';
8
+ import { loadMethodMap } from '../specdiff/methodmap.js';
9
+ const HERE = dirname(fileURLToPath(import.meta.url));
10
+ const FIXTURE = resolve(HERE, '../../test/fixtures/sample-app');
11
+ /** Hand-built map so the scanner tests do not depend on a generated artifact. */
12
+ const MAP = {
13
+ sdkVersion: 'test',
14
+ generatedAt: new Date(0).toISOString(),
15
+ byEndpoint: {
16
+ 'post /v1/payment_intents': [{ namespace: 'paymentIntents', method: 'create' }],
17
+ 'post /v1/checkout/sessions': [{ namespace: 'checkout.sessions', method: 'create' }],
18
+ 'get /v1/refunds': [{ namespace: 'refunds', method: 'list' }],
19
+ 'post /v1/terminal/configurations/{id}': [
20
+ { namespace: 'terminal.configurations', method: 'update' },
21
+ ],
22
+ },
23
+ byCall: {
24
+ 'paymentIntents.create': { method: 'post', path: '/v1/payment_intents' },
25
+ 'checkout.sessions.create': { method: 'post', path: '/v1/checkout/sessions' },
26
+ 'refunds.list': { method: 'get', path: '/v1/refunds' },
27
+ 'terminal.configurations.update': { method: 'post', path: '/v1/terminal/configurations/{id}' },
28
+ },
29
+ };
30
+ function find(usages, kind, predicate) {
31
+ return usages.filter((u) => u.kind === kind && predicate(u));
32
+ }
33
+ test('resolveCall matches the longest namespace suffix', () => {
34
+ assert.deepEqual(resolveCall(MAP, ['paymentIntents', 'create'])?.namespace, 'paymentIntents');
35
+ assert.deepEqual(resolveCall(MAP, ['checkout', 'sessions', 'create'])?.namespace, 'checkout.sessions');
36
+ });
37
+ test('resolveCall sees through a wrapper prefix', () => {
38
+ // `payments.client.checkout.sessions.create(...)` still resolves.
39
+ const resolved = resolveCall(MAP, ['client', 'checkout', 'sessions', 'create']);
40
+ assert.equal(resolved?.namespace, 'checkout.sessions');
41
+ assert.equal(resolved?.droppedPrefix, 1);
42
+ assert.equal(resolved?.path, '/v1/checkout/sessions');
43
+ });
44
+ test('resolveCall rejects a chain that is not a Stripe call', () => {
45
+ assert.equal(resolveCall(MAP, ['orders', 'create']), null);
46
+ assert.equal(resolveCall(MAP, ['create']), null);
47
+ });
48
+ test('extractStripePath reads full URLs and bare v1 paths', () => {
49
+ assert.deepEqual(extractStripePath('https://api.stripe.com/v1/charges'), {
50
+ path: '/v1/charges',
51
+ viaHost: true,
52
+ });
53
+ // Query strings are not part of the endpoint.
54
+ assert.equal(extractStripePath('https://api.stripe.com/v1/charges?limit=3')?.path, '/v1/charges');
55
+ assert.deepEqual(extractStripePath('/v1/customers'), { path: '/v1/customers', viaHost: false });
56
+ assert.equal(extractStripePath('https://example.com/v1/charges'), null);
57
+ assert.equal(extractStripePath('just a string'), null);
58
+ });
59
+ test('matchesIgnore handles bare names, globs and double-star', () => {
60
+ assert.equal(matchesIgnore('src/generated/api.ts', ['generated']), true);
61
+ assert.equal(matchesIgnore('src/a/b/c.ts', ['src/**']), true);
62
+ assert.equal(matchesIgnore('src/a.ts', ['src/*.ts']), true);
63
+ assert.equal(matchesIgnore('src/a/b.ts', ['src/*.ts']), false);
64
+ assert.equal(matchesIgnore('lib/x.ts', ['generated']), false);
65
+ });
66
+ // --- end-to-end over the fixture repo --------------------------------------
67
+ test('the scanner resolves a client imported through a barrel re-export', async () => {
68
+ const scan = await scanRepo(FIXTURE, { methodMap: MAP });
69
+ // `new Stripe(...)` lives in lib/payments.ts; routes import it via lib/index.ts.
70
+ const calls = find(scan.usages, 'sdkCall', (u) => u.namespace === 'checkout.sessions');
71
+ assert.equal(calls.length, 1);
72
+ assert.equal(calls[0]?.confidence, 1, 'a resolved client binding should be full confidence');
73
+ assert.equal(calls[0]?.evidence.file, 'src/routes/checkout.ts');
74
+ });
75
+ test('the scanner reads the pinned apiVersion and the declared SDK range', async () => {
76
+ const scan = await scanRepo(FIXTURE, { methodMap: MAP });
77
+ assert.equal(scan.version.apiVersion, '2025-09-30.clover');
78
+ assert.equal(scan.version.sdkRange, '^22.0.0');
79
+ assert.equal(scan.version.apiVersionEvidence?.file, 'src/lib/payments.ts');
80
+ });
81
+ test('the scanner records request parameters with their nested paths', async () => {
82
+ const scan = await scanRepo(FIXTURE, { methodMap: MAP });
83
+ const fields = find(scan.usages, 'requestParam', (u) => u.namespace === 'terminal.configurations').map((u) => u.field);
84
+ assert.ok(fields.includes('tipping'), 'top-level key');
85
+ assert.ok(fields.includes('tipping.bgn'), 'nested key');
86
+ });
87
+ test('the scanner attributes fields read inside a .map callback', async () => {
88
+ const scan = await scanRepo(FIXTURE, { methodMap: MAP });
89
+ const fields = find(scan.usages, 'responseField', (u) => u.namespace === 'refunds').map((u) => u.field);
90
+ // `refunds.data.map((r) => r.destination_details)` — the array marker must sit
91
+ // on `data`, or the path will not line up with a spec path of `data[].x`.
92
+ assert.ok(fields.includes('data[].destination_details'), `expected data[].destination_details, got ${JSON.stringify(fields)}`);
93
+ });
94
+ test('the scanner finds a raw REST call written as a template literal', async () => {
95
+ const scan = await scanRepo(FIXTURE, { methodMap: MAP });
96
+ const raw = find(scan.usages, 'rawUrl', () => true);
97
+ assert.equal(raw.length, 1);
98
+ assert.equal(raw[0]?.path, '/v1/payment_intents/{}/cancel');
99
+ assert.equal(raw[0]?.httpMethod, 'post', 'verb should come from the fetch options');
100
+ assert.equal(raw[0]?.confidence, 1, 'an api.stripe.com URL is unambiguous');
101
+ });
102
+ test('the scanner finds webhook event types in switch cases', async () => {
103
+ const scan = await scanRepo(FIXTURE, {
104
+ methodMap: MAP,
105
+ knownEvents: new Set(['invoice.payment_failed', 'customer.subscription.deleted']),
106
+ });
107
+ const events = find(scan.usages, 'webhookEvent', () => true).map((u) => u.event);
108
+ assert.deepEqual(events.sort(), ['customer.subscription.deleted', 'invoice.payment_failed']);
109
+ assert.ok(find(scan.usages, 'webhookEvent', () => true).every((u) => u.confidence === 1), 'known events should be full confidence');
110
+ });
111
+ test('a known-event list suppresses unrelated dotted strings', async () => {
112
+ const scan = await scanRepo(FIXTURE, { methodMap: MAP, knownEvents: new Set(['nothing.matches']) });
113
+ assert.equal(find(scan.usages, 'webhookEvent', () => true).length, 0);
114
+ });
115
+ test('ignore patterns keep files out of the scan', async () => {
116
+ const all = await scanRepo(FIXTURE, { methodMap: MAP });
117
+ const partial = await scanRepo(FIXTURE, { methodMap: MAP, ignore: ['src/routes'] });
118
+ assert.ok(partial.filesScanned < all.filesScanned);
119
+ assert.equal(find(partial.usages, 'sdkCall', (u) => u.namespace === 'checkout.sessions').length, 0);
120
+ });
121
+ test('the generated method map covers well-known Stripe calls', async () => {
122
+ const map = await loadMethodMap(join(HERE, '../../data/stripe/method-map.json'));
123
+ // Guards against the stripe package layout changing and the generator silently
124
+ // producing an empty map.
125
+ assert.ok(Object.keys(map.byCall).length > 300, 'expected a populated method map');
126
+ assert.deepEqual(map.byCall['paymentIntents.create'], { method: 'post', path: '/v1/payment_intents' });
127
+ assert.deepEqual(map.byCall['checkout.sessions.create'], {
128
+ method: 'post',
129
+ path: '/v1/checkout/sessions',
130
+ });
131
+ // Three-level namespace, to prove nested containers are walked.
132
+ assert.ok(map.byCall['testHelpers.issuing.authorizations.capture']);
133
+ });
134
+ //# sourceMappingURL=scan.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.test.js","sourceRoot":"","sources":["../../src/scanner/scan.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * What the scanner produces. Every finding carries evidence — file, line,
3
+ * snippet — because a report a customer cannot verify is a report they will not
4
+ * act on.
5
+ */
6
+ export type UsageKind = 'sdkCall' | 'rawUrl' | 'responseField' | 'requestParam' | 'webhookEvent' | 'clientInit';
7
+ export interface Evidence {
8
+ /** Repo-relative path, POSIX separators. */
9
+ file: string;
10
+ /** 1-indexed. */
11
+ line: number;
12
+ column: number;
13
+ /** The source line, trimmed. Truncated to keep reports readable. */
14
+ snippet: string;
15
+ }
16
+ export interface Usage {
17
+ kind: UsageKind;
18
+ evidence: Evidence;
19
+ /** 0..1. Deterministic matches are 1; inferred ones are lower. */
20
+ confidence: number;
21
+ /** For `sdkCall`: dotted accessor, e.g. `checkout.sessions`. */
22
+ namespace?: string;
23
+ /** For `sdkCall`: the method, e.g. `create`. */
24
+ method?: string;
25
+ /** Resolved endpoint, when known. */
26
+ httpMethod?: string;
27
+ path?: string;
28
+ /** For `responseField` / `requestParam`: the dotted field path touched. */
29
+ field?: string;
30
+ /** For `webhookEvent`: the event type string. */
31
+ event?: string;
32
+ /**
33
+ * How the Stripe client was reached, e.g. `stripe` or `payments.client`.
34
+ * Useful when a repo wraps the SDK and the call site does not say "stripe".
35
+ */
36
+ via?: string;
37
+ /**
38
+ * Ties a `requestParam` or destructured `responseField` back to the
39
+ * `sdkCall` it came from. Lets the report tell "this call already passes the
40
+ * newly-required field" apart from "this call needs updating".
41
+ */
42
+ callId?: string;
43
+ }
44
+ export interface DetectedVersion {
45
+ /** The pinned `apiVersion`, if the client config sets one. */
46
+ apiVersion?: string;
47
+ /** Where the pin was found. */
48
+ apiVersionEvidence?: Evidence;
49
+ /** Version range from package.json, e.g. `^18.0.0`. */
50
+ sdkRange?: string;
51
+ /** Exact installed version from the lockfile, when resolvable. */
52
+ sdkInstalled?: string;
53
+ /** The `apiVersion` the installed SDK defaults to, if we can read it. */
54
+ sdkDefaultApiVersion?: string;
55
+ }
56
+ export interface ScanResult {
57
+ root: string;
58
+ /** Files actually parsed. */
59
+ filesScanned: number;
60
+ usages: Usage[];
61
+ version: DetectedVersion;
62
+ /** Client variables the scanner resolved, for transparency in the report. */
63
+ clients: ClientBinding[];
64
+ warnings: string[];
65
+ }
66
+ export interface ClientBinding {
67
+ /** Local identifier bound to a Stripe client, e.g. `stripe`. */
68
+ name: string;
69
+ file: string;
70
+ line: number;
71
+ /** How we concluded it is a Stripe client. */
72
+ reason: 'newStripe' | 'importedDefault' | 'reexport' | 'wrapperProperty';
73
+ }
74
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scanner/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,QAAQ,GACR,eAAe,GACf,cAAc,GACd,cAAc,GACd,YAAY,CAAC;AAEjB,MAAM,WAAW,QAAQ;IACvB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IAEnB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,kBAAkB,CAAC,EAAE,QAAQ,CAAC;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,6EAA6E;IAC7E,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,MAAM,EAAE,WAAW,GAAG,iBAAiB,GAAG,UAAU,GAAG,iBAAiB,CAAC;CAC1E"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * What the scanner produces. Every finding carries evidence — file, line,
3
+ * snippet — because a report a customer cannot verify is a report they will not
4
+ * act on.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/scanner/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,23 @@
1
+ import type { DetectedVersion } from './types.js';
2
+ /**
3
+ * The declared `stripe` range, from the root manifest or any workspace package.
4
+ *
5
+ * Monorepos usually declare Stripe in one package rather than at the root, so
6
+ * checking only the root would report "no Stripe dependency" for a repo that
7
+ * plainly has one — and that flag feeds every confidence score.
8
+ */
9
+ export declare function readStripeRange(root: string): Promise<string | null>;
10
+ /**
11
+ * Exact installed version, preferring the lockfile over node_modules so the scan
12
+ * works in CI before `npm install` runs.
13
+ */
14
+ export declare function readInstalledStripeVersion(root: string): Promise<string | null>;
15
+ /**
16
+ * The API version the installed SDK pins by default.
17
+ *
18
+ * stripe-node hardcodes this in `apiVersion.js`; when a repo does not pass
19
+ * `apiVersion` explicitly, this is the version their calls actually run against.
20
+ */
21
+ export declare function readSdkDefaultApiVersion(root: string): Promise<string | null>;
22
+ export declare function detectVersion(root: string): Promise<DetectedVersion>;
23
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/scanner/version.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA+BlD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAe1E;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmBrF;AA2CD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAenF;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAW1E"}
@@ -0,0 +1,155 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ function rangeFrom(pkg) {
5
+ for (const section of [
6
+ pkg.dependencies,
7
+ pkg.devDependencies,
8
+ pkg.peerDependencies,
9
+ pkg.optionalDependencies,
10
+ ]) {
11
+ const range = section?.stripe;
12
+ if (typeof range === 'string')
13
+ return range;
14
+ }
15
+ return null;
16
+ }
17
+ async function readManifest(file) {
18
+ if (!existsSync(file))
19
+ return null;
20
+ try {
21
+ return JSON.parse(await readFile(file, 'utf8'));
22
+ }
23
+ catch {
24
+ return null;
25
+ }
26
+ }
27
+ /**
28
+ * The declared `stripe` range, from the root manifest or any workspace package.
29
+ *
30
+ * Monorepos usually declare Stripe in one package rather than at the root, so
31
+ * checking only the root would report "no Stripe dependency" for a repo that
32
+ * plainly has one — and that flag feeds every confidence score.
33
+ */
34
+ export async function readStripeRange(root) {
35
+ const rootPkg = await readManifest(join(root, 'package.json'));
36
+ if (rootPkg) {
37
+ const direct = rangeFrom(rootPkg);
38
+ if (direct)
39
+ return direct;
40
+ }
41
+ const { loadWorkspacePackages } = await import('./paths.js');
42
+ const workspaces = await loadWorkspacePackages(root);
43
+ for (const dir of workspaces.values()) {
44
+ const pkg = await readManifest(join(root, dir, 'package.json'));
45
+ const range = pkg ? rangeFrom(pkg) : null;
46
+ if (range)
47
+ return range;
48
+ }
49
+ return null;
50
+ }
51
+ /**
52
+ * Exact installed version, preferring the lockfile over node_modules so the scan
53
+ * works in CI before `npm install` runs.
54
+ */
55
+ export async function readInstalledStripeVersion(root) {
56
+ const fromLock = await readFromNpmLock(root);
57
+ if (fromLock)
58
+ return fromLock;
59
+ const fromYarn = await readFromYarnLock(root);
60
+ if (fromYarn)
61
+ return fromYarn;
62
+ const fromPnpm = await readFromPnpmLock(root);
63
+ if (fromPnpm)
64
+ return fromPnpm;
65
+ const installed = join(root, 'node_modules', 'stripe', 'package.json');
66
+ if (existsSync(installed)) {
67
+ try {
68
+ return JSON.parse(await readFile(installed, 'utf8')).version ?? null;
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ }
74
+ return null;
75
+ }
76
+ async function readFromNpmLock(root) {
77
+ const file = join(root, 'package-lock.json');
78
+ if (!existsSync(file))
79
+ return null;
80
+ try {
81
+ const lock = JSON.parse(await readFile(file, 'utf8'));
82
+ const v1 = lock.packages?.['node_modules/stripe']?.version;
83
+ if (v1)
84
+ return v1;
85
+ return lock.dependencies?.stripe?.version ?? null;
86
+ }
87
+ catch {
88
+ return null;
89
+ }
90
+ }
91
+ async function readFromYarnLock(root) {
92
+ const file = join(root, 'yarn.lock');
93
+ if (!existsSync(file))
94
+ return null;
95
+ try {
96
+ const text = await readFile(file, 'utf8');
97
+ // Classic: `stripe@^18.0.0:\n version "18.2.1"`. Berry: `"stripe@npm:^18.0.0":`.
98
+ const m = /^"?stripe@[^\n]*:\n(?:\s+[^\n]*\n)*?\s+version:?\s+"?([0-9][^"\s]*)"?/m.exec(text);
99
+ return m?.[1] ?? null;
100
+ }
101
+ catch {
102
+ return null;
103
+ }
104
+ }
105
+ async function readFromPnpmLock(root) {
106
+ const file = join(root, 'pnpm-lock.yaml');
107
+ if (!existsSync(file))
108
+ return null;
109
+ try {
110
+ const text = await readFile(file, 'utf8');
111
+ const m = /^\s+stripe:\n(?:\s+[^\n]*\n)*?\s+version:\s+([0-9][^\s(]*)/m.exec(text);
112
+ return m?.[1] ?? null;
113
+ }
114
+ catch {
115
+ return null;
116
+ }
117
+ }
118
+ /**
119
+ * The API version the installed SDK pins by default.
120
+ *
121
+ * stripe-node hardcodes this in `apiVersion.js`; when a repo does not pass
122
+ * `apiVersion` explicitly, this is the version their calls actually run against.
123
+ */
124
+ export async function readSdkDefaultApiVersion(root) {
125
+ for (const candidate of [
126
+ join(root, 'node_modules', 'stripe', 'cjs', 'apiVersion.js'),
127
+ join(root, 'node_modules', 'stripe', 'esm', 'apiVersion.js'),
128
+ ]) {
129
+ if (!existsSync(candidate))
130
+ continue;
131
+ try {
132
+ const text = await readFile(candidate, 'utf8');
133
+ const m = /ApiVersion\s*=\s*['"]([^'"]+)['"]/.exec(text);
134
+ if (m?.[1])
135
+ return m[1];
136
+ }
137
+ catch {
138
+ // fall through
139
+ }
140
+ }
141
+ return null;
142
+ }
143
+ export async function detectVersion(root) {
144
+ const [sdkRange, sdkInstalled, sdkDefaultApiVersion] = await Promise.all([
145
+ readStripeRange(root),
146
+ readInstalledStripeVersion(root),
147
+ readSdkDefaultApiVersion(root),
148
+ ]);
149
+ return {
150
+ ...(sdkRange ? { sdkRange } : {}),
151
+ ...(sdkInstalled ? { sdkInstalled } : {}),
152
+ ...(sdkDefaultApiVersion ? { sdkDefaultApiVersion } : {}),
153
+ };
154
+ }
155
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/scanner/version.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export interface WalkOptions {
2
+ /** Extra glob-ish ignore patterns from config. Matched against POSIX relative paths. */
3
+ ignore?: string[];
4
+ maxFiles?: number;
5
+ }
6
+ /**
7
+ * Very small glob matcher: supports `*` (within a segment), `**` (any depth)
8
+ * and a bare directory name meaning "anywhere". Enough for an `ignore` list in a
9
+ * config file, without pulling in a glob dependency.
10
+ */
11
+ export declare function matchesIgnore(relPath: string, patterns: readonly string[]): boolean;
12
+ export declare function isSourceFile(name: string): boolean;
13
+ export interface SourceFile {
14
+ /** Absolute path. */
15
+ absolute: string;
16
+ /** Repo-relative, POSIX separators. */
17
+ relative: string;
18
+ text: string;
19
+ }
20
+ /** Collect candidate source files under `root`. */
21
+ export declare function collectSourceFiles(root: string, options?: WalkOptions): Promise<{
22
+ files: SourceFile[];
23
+ skipped: string[];
24
+ }>;
25
+ export declare function findUp(from: string, filename: string, levels?: number): string | null;
26
+ //# sourceMappingURL=walk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../../src/scanner/walk.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,WAAW;IAC1B,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAyBnF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIlD;AAED,MAAM,WAAW,UAAU;IACzB,qBAAqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,mDAAmD;AACnD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA2CrD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,MAAM,GAAG,IAAI,CAUhF"}
@@ -0,0 +1,117 @@
1
+ import { readdir, readFile, stat } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { join, relative, sep } from 'node:path';
4
+ /** Directories never worth parsing. Keeps a monorepo scan from taking minutes. */
5
+ const DEFAULT_IGNORES = [
6
+ 'node_modules',
7
+ '.git',
8
+ 'dist',
9
+ 'build',
10
+ 'out',
11
+ 'coverage',
12
+ '.next',
13
+ '.nuxt',
14
+ '.svelte-kit',
15
+ '.turbo',
16
+ '.cache',
17
+ 'vendor',
18
+ '__snapshots__',
19
+ ];
20
+ const SOURCE_EXTENSIONS = ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs'];
21
+ /** Files above this size are almost always generated or bundled. */
22
+ const MAX_FILE_BYTES = 1_500_000;
23
+ /**
24
+ * Very small glob matcher: supports `*` (within a segment), `**` (any depth)
25
+ * and a bare directory name meaning "anywhere". Enough for an `ignore` list in a
26
+ * config file, without pulling in a glob dependency.
27
+ */
28
+ export function matchesIgnore(relPath, patterns) {
29
+ for (const raw of patterns) {
30
+ const pattern = raw.replace(/^\.\//, '').replace(/\/$/, '');
31
+ if (pattern === '')
32
+ continue;
33
+ if (!pattern.includes('/') && !pattern.includes('*')) {
34
+ // Bare name: match any path segment.
35
+ if (relPath.split('/').includes(pattern))
36
+ return true;
37
+ continue;
38
+ }
39
+ const regex = new RegExp(`^${pattern
40
+ .split('**')
41
+ .map((part) => part
42
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
43
+ .replace(/\?/g, '[^/]')
44
+ .replace(/\*/g, '[^/]*'))
45
+ .join('.*')}(/.*)?$`);
46
+ if (regex.test(relPath))
47
+ return true;
48
+ }
49
+ return false;
50
+ }
51
+ export function isSourceFile(name) {
52
+ if (name.endsWith('.d.ts'))
53
+ return false;
54
+ if (/\.(test|spec)\.[cm]?[jt]sx?$/.test(name))
55
+ return false;
56
+ return SOURCE_EXTENSIONS.some((ext) => name.endsWith(ext));
57
+ }
58
+ /** Collect candidate source files under `root`. */
59
+ export async function collectSourceFiles(root, options = {}) {
60
+ const ignore = [...DEFAULT_IGNORES, ...(options.ignore ?? [])];
61
+ const maxFiles = options.maxFiles ?? 20_000;
62
+ const files = [];
63
+ const skipped = [];
64
+ const walkDir = async (dir) => {
65
+ if (files.length >= maxFiles)
66
+ return;
67
+ let entries;
68
+ try {
69
+ entries = await readdir(dir, { withFileTypes: true });
70
+ }
71
+ catch {
72
+ return; // unreadable directory: not fatal
73
+ }
74
+ for (const entry of entries) {
75
+ if (files.length >= maxFiles)
76
+ return;
77
+ const absolute = join(dir, entry.name);
78
+ const rel = relative(root, absolute).split(sep).join('/');
79
+ if (matchesIgnore(rel, ignore))
80
+ continue;
81
+ if (entry.isDirectory()) {
82
+ await walkDir(absolute);
83
+ continue;
84
+ }
85
+ if (!entry.isFile() || !isSourceFile(entry.name))
86
+ continue;
87
+ try {
88
+ const info = await stat(absolute);
89
+ if (info.size > MAX_FILE_BYTES) {
90
+ skipped.push(`${rel} (${Math.round(info.size / 1024)}KB, likely generated)`);
91
+ continue;
92
+ }
93
+ files.push({ absolute, relative: rel, text: await readFile(absolute, 'utf8') });
94
+ }
95
+ catch {
96
+ skipped.push(`${rel} (unreadable)`);
97
+ }
98
+ }
99
+ };
100
+ await walkDir(root);
101
+ files.sort((a, b) => a.relative.localeCompare(b.relative));
102
+ return { files, skipped };
103
+ }
104
+ export function findUp(from, filename, levels = 6) {
105
+ let dir = from;
106
+ for (let i = 0; i < levels; i++) {
107
+ const candidate = join(dir, filename);
108
+ if (existsSync(candidate))
109
+ return candidate;
110
+ const parent = join(dir, '..');
111
+ if (parent === dir)
112
+ break;
113
+ dir = parent;
114
+ }
115
+ return null;
116
+ }
117
+ //# sourceMappingURL=walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/scanner/walk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=wrapper.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper.test.d.ts","sourceRoot":"","sources":["../../src/scanner/wrapper.test.ts"],"names":[],"mappings":""}