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.
- package/changesets/stripe/2025-09-30.clover__2026-08-26.dahlia.json +4576 -0
- package/changesets/stripe/index.json +16 -0
- package/data/stripe/events.json +271 -0
- package/data/stripe/method-map.json +5718 -0
- package/dist/changeset/index-file.d.ts +30 -0
- package/dist/changeset/index-file.d.ts.map +1 -0
- package/dist/changeset/index-file.js +34 -0
- package/dist/changeset/index-file.js.map +1 -0
- package/dist/changeset/load.d.ts +21 -0
- package/dist/changeset/load.d.ts.map +1 -0
- package/dist/changeset/load.js +113 -0
- package/dist/changeset/load.js.map +1 -0
- package/dist/changeset/types.d.ts +97 -0
- package/dist/changeset/types.d.ts.map +1 -0
- package/dist/changeset/types.js +18 -0
- package/dist/changeset/types.js.map +1 -0
- package/dist/changeset/version.d.ts +17 -0
- package/dist/changeset/version.d.ts.map +1 -0
- package/dist/changeset/version.js +33 -0
- package/dist/changeset/version.js.map +1 -0
- package/dist/cli/args.d.ts +15 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +82 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +333 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +92 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/report/impact.d.ts +40 -0
- package/dist/report/impact.d.ts.map +1 -0
- package/dist/report/impact.js +331 -0
- package/dist/report/impact.js.map +1 -0
- package/dist/report/impact.test.d.ts +2 -0
- package/dist/report/impact.test.d.ts.map +1 -0
- package/dist/report/impact.test.js +247 -0
- package/dist/report/impact.test.js.map +1 -0
- package/dist/report/render.d.ts +9 -0
- package/dist/report/render.d.ts.map +1 -0
- package/dist/report/render.js +211 -0
- package/dist/report/render.js.map +1 -0
- package/dist/scanner/ast.d.ts +74 -0
- package/dist/scanner/ast.d.ts.map +1 -0
- package/dist/scanner/ast.js +930 -0
- package/dist/scanner/ast.js.map +1 -0
- package/dist/scanner/paths.d.ts +42 -0
- package/dist/scanner/paths.d.ts.map +1 -0
- package/dist/scanner/paths.js +179 -0
- package/dist/scanner/paths.js.map +1 -0
- package/dist/scanner/scan.d.ts +11 -0
- package/dist/scanner/scan.d.ts.map +1 -0
- package/dist/scanner/scan.js +268 -0
- package/dist/scanner/scan.js.map +1 -0
- package/dist/scanner/scan.test.d.ts +2 -0
- package/dist/scanner/scan.test.d.ts.map +1 -0
- package/dist/scanner/scan.test.js +134 -0
- package/dist/scanner/scan.test.js.map +1 -0
- package/dist/scanner/types.d.ts +74 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +7 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/scanner/version.d.ts +23 -0
- package/dist/scanner/version.d.ts.map +1 -0
- package/dist/scanner/version.js +155 -0
- package/dist/scanner/version.js.map +1 -0
- package/dist/scanner/walk.d.ts +26 -0
- package/dist/scanner/walk.d.ts.map +1 -0
- package/dist/scanner/walk.js +117 -0
- package/dist/scanner/walk.js.map +1 -0
- package/dist/scanner/wrapper.test.d.ts +2 -0
- package/dist/scanner/wrapper.test.d.ts.map +1 -0
- package/dist/scanner/wrapper.test.js +92 -0
- package/dist/scanner/wrapper.test.js.map +1 -0
- package/dist/specdiff/build-method-map.d.ts +6 -0
- package/dist/specdiff/build-method-map.d.ts.map +1 -0
- package/dist/specdiff/build-method-map.js +231 -0
- package/dist/specdiff/build-method-map.js.map +1 -0
- package/dist/specdiff/compat.d.ts +20 -0
- package/dist/specdiff/compat.d.ts.map +1 -0
- package/dist/specdiff/compat.js +58 -0
- package/dist/specdiff/compat.js.map +1 -0
- package/dist/specdiff/diff.d.ts +28 -0
- package/dist/specdiff/diff.d.ts.map +1 -0
- package/dist/specdiff/diff.js +529 -0
- package/dist/specdiff/diff.js.map +1 -0
- package/dist/specdiff/diff.test.d.ts +2 -0
- package/dist/specdiff/diff.test.d.ts.map +1 -0
- package/dist/specdiff/diff.test.js +260 -0
- package/dist/specdiff/diff.test.js.map +1 -0
- package/dist/specdiff/fetch.d.ts +28 -0
- package/dist/specdiff/fetch.d.ts.map +1 -0
- package/dist/specdiff/fetch.js +68 -0
- package/dist/specdiff/fetch.js.map +1 -0
- package/dist/specdiff/methodmap.d.ts +45 -0
- package/dist/specdiff/methodmap.d.ts.map +1 -0
- package/dist/specdiff/methodmap.js +109 -0
- package/dist/specdiff/methodmap.js.map +1 -0
- package/dist/specdiff/openapi.d.ts +166 -0
- package/dist/specdiff/openapi.d.ts.map +1 -0
- package/dist/specdiff/openapi.js +282 -0
- package/dist/specdiff/openapi.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { appendFile, writeFile, mkdir } from 'node:fs/promises';
|
|
3
|
+
import { dirname, resolve } from 'node:path';
|
|
4
|
+
import { flagBool, flagList, flagNumber, flagString, parseArgs } from './args.js';
|
|
5
|
+
import { changesBetween, latestKnownVersion, loadChangesets } from '../changeset/load.js';
|
|
6
|
+
import { buildIndex, writeIndex } from '../changeset/index-file.js';
|
|
7
|
+
import { compareApiVersions, isApiVersion } from '../changeset/version.js';
|
|
8
|
+
import { DEFAULT_CONFIG, loadConfig } from '../config.js';
|
|
9
|
+
import { scanRepo } from '../scanner/scan.js';
|
|
10
|
+
import { loadEventCatalog, loadMethodMap } from '../specdiff/methodmap.js';
|
|
11
|
+
import { buildMethodMap, writeMethodMap } from '../specdiff/build-method-map.js';
|
|
12
|
+
import { buildReport, exitCodeFor } from '../report/impact.js';
|
|
13
|
+
import { renderJson, renderMarkdown, renderTerminal } from '../report/render.js';
|
|
14
|
+
import { diffSpecs } from '../specdiff/diff.js';
|
|
15
|
+
import { changesetFilename, fetchSpecAt, listSpecCommits, readSpecFile, resolveSpecCommit, STRIPE_SPEC_REPO, } from '../specdiff/fetch.js';
|
|
16
|
+
import { eventTypes } from '../specdiff/openapi.js';
|
|
17
|
+
const USAGE = `apiwatcher — find every call site a breaking Stripe API change affects
|
|
18
|
+
|
|
19
|
+
Usage
|
|
20
|
+
apiwatcher scan [dir] [options] Scan a repo and print an impact report
|
|
21
|
+
apiwatcher spec-diff [options] Diff two Stripe spec versions into a changeset
|
|
22
|
+
apiwatcher build-method-map [options] Regenerate the SDK call -> endpoint map
|
|
23
|
+
apiwatcher list-changesets Show known changesets
|
|
24
|
+
apiwatcher index-changesets Regenerate changesets/stripe/index.json
|
|
25
|
+
apiwatcher watch Diff Stripe's current spec forward (cron entry point)
|
|
26
|
+
|
|
27
|
+
scan options
|
|
28
|
+
--target <version|latest> Version to check against (default: latest known)
|
|
29
|
+
--from <version> Override the detected current version
|
|
30
|
+
--format <pretty|md|json> Output format (default: pretty)
|
|
31
|
+
--out <file> Also write the report to a file
|
|
32
|
+
--fail-on <breaking|deprecating|additive|never> (default: breaking)
|
|
33
|
+
--min-confidence <0..1> Drop weaker matches (default: 0.4)
|
|
34
|
+
--ignore <a,b> Extra paths to skip
|
|
35
|
+
--changesets <dir> Changeset directory
|
|
36
|
+
--no-color Disable ANSI colour
|
|
37
|
+
|
|
38
|
+
spec-diff options
|
|
39
|
+
--from-ref <git ref> Spec commit to diff from (stripe/openapi)
|
|
40
|
+
--to-ref <git ref> Spec commit to diff to (default: master)
|
|
41
|
+
--from-file <path> Use a local spec file instead
|
|
42
|
+
--to-file <path> Use a local spec file instead
|
|
43
|
+
--out-dir <dir> Where to write the changeset (default: ./changesets/stripe)
|
|
44
|
+
--include-additive Record additive changes too
|
|
45
|
+
--max-depth <n> Field nesting depth to compare (default: 3)
|
|
46
|
+
--stdout Print the changeset instead of writing it
|
|
47
|
+
--events-out <file> Event catalogue path (default: packages/apiwatcher/data/stripe/events.json)
|
|
48
|
+
|
|
49
|
+
build-method-map options
|
|
50
|
+
--out <file> Output path (default: packages/apiwatcher/data/stripe/method-map.json)
|
|
51
|
+
|
|
52
|
+
Nothing leaves your machine during a scan. No account, no API keys.
|
|
53
|
+
`;
|
|
54
|
+
async function main(argv) {
|
|
55
|
+
const args = parseArgs(argv);
|
|
56
|
+
if (args.flags.has('help') || args.flags.has('h') || args.command === 'help' || args.command === null) {
|
|
57
|
+
process.stdout.write(USAGE);
|
|
58
|
+
return args.command === null && !args.flags.has('help') && !args.flags.has('h') ? 1 : 0;
|
|
59
|
+
}
|
|
60
|
+
if (args.flags.has('version') || args.flags.has('v')) {
|
|
61
|
+
process.stdout.write('apiwatcher 0.1.0\n');
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
switch (args.command) {
|
|
65
|
+
case 'scan':
|
|
66
|
+
return runScan(args);
|
|
67
|
+
case 'spec-diff':
|
|
68
|
+
return runSpecDiff(args);
|
|
69
|
+
case 'build-method-map':
|
|
70
|
+
return runBuildMethodMap(args);
|
|
71
|
+
case 'list-changesets':
|
|
72
|
+
return runListChangesets(args);
|
|
73
|
+
case 'index-changesets':
|
|
74
|
+
return runIndexChangesets(args);
|
|
75
|
+
case 'watch':
|
|
76
|
+
return runWatch(args);
|
|
77
|
+
default:
|
|
78
|
+
process.stderr.write(`Unknown command: ${args.command}\n\n${USAGE}`);
|
|
79
|
+
return 1;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function runScan(args) {
|
|
83
|
+
const root = resolve(args.positionals[0] ?? '.');
|
|
84
|
+
const { config, file: configFile } = await loadConfig(root);
|
|
85
|
+
const changesetDir = flagString(args, 'changesets');
|
|
86
|
+
const changesets = await loadChangesets(changesetDir);
|
|
87
|
+
if (changesets.length === 0) {
|
|
88
|
+
process.stderr.write('No changesets found. Run `apiwatcher spec-diff` first, or pass --changesets <dir>.\n');
|
|
89
|
+
return 2;
|
|
90
|
+
}
|
|
91
|
+
const latest = latestKnownVersion(changesets);
|
|
92
|
+
if (latest === null) {
|
|
93
|
+
process.stderr.write('Changesets are present but none declare a target version.\n');
|
|
94
|
+
return 2;
|
|
95
|
+
}
|
|
96
|
+
const requestedTarget = flagString(args, 'target') ?? config.target ?? DEFAULT_CONFIG.target;
|
|
97
|
+
const target = requestedTarget === 'latest' ? latest : requestedTarget;
|
|
98
|
+
if (!isApiVersion(target)) {
|
|
99
|
+
process.stderr.write(`--target must be a Stripe version or "latest", got "${target}".\n`);
|
|
100
|
+
return 2;
|
|
101
|
+
}
|
|
102
|
+
const methodMap = await loadMethodMap();
|
|
103
|
+
const knownEvents = await loadEventCatalog();
|
|
104
|
+
const minConfidence = flagNumber(args, 'min-confidence') ?? config.minConfidence ?? DEFAULT_CONFIG.minConfidence;
|
|
105
|
+
const scan = await scanRepo(root, {
|
|
106
|
+
methodMap,
|
|
107
|
+
minConfidence,
|
|
108
|
+
...(knownEvents ? { knownEvents } : {}),
|
|
109
|
+
ignore: [...(config.ignorePaths ?? []), ...(flagList(args, 'ignore') ?? [])],
|
|
110
|
+
});
|
|
111
|
+
// Current version: explicit override, then the pin, then the SDK default.
|
|
112
|
+
const override = flagString(args, 'from');
|
|
113
|
+
if (override !== undefined) {
|
|
114
|
+
if (!isApiVersion(override)) {
|
|
115
|
+
process.stderr.write(`--from must be a Stripe version, got "${override}".\n`);
|
|
116
|
+
return 2;
|
|
117
|
+
}
|
|
118
|
+
scan.version.apiVersion = override;
|
|
119
|
+
delete scan.version.apiVersionEvidence;
|
|
120
|
+
}
|
|
121
|
+
const current = scan.version.apiVersion ?? scan.version.sdkDefaultApiVersion ?? null;
|
|
122
|
+
if (current === null) {
|
|
123
|
+
scan.warnings.push('Could not determine the current API version (no apiVersion pin, no installed SDK). Comparing against the full changeset history — pass --from to narrow it.');
|
|
124
|
+
}
|
|
125
|
+
else if (compareApiVersions(current, target) >= 0) {
|
|
126
|
+
scan.warnings.push(`Detected current version ${current} is not older than the target ${target}; there is nothing to migrate.`);
|
|
127
|
+
}
|
|
128
|
+
const oldestFrom = changesets[0]?.from ?? target;
|
|
129
|
+
const changes = changesBetween(changesets, current ?? oldestFrom, target);
|
|
130
|
+
const report = buildReport({
|
|
131
|
+
scan,
|
|
132
|
+
changes,
|
|
133
|
+
targetVersion: target,
|
|
134
|
+
minConfidence,
|
|
135
|
+
...(config.ignoreChanges ? { ignoreIds: config.ignoreChanges } : {}),
|
|
136
|
+
});
|
|
137
|
+
if (configFile)
|
|
138
|
+
report.warnings.push(`Using config from ${configFile}`);
|
|
139
|
+
const format = flagString(args, 'format') ?? 'pretty';
|
|
140
|
+
const colorFlag = flagBool(args, 'color');
|
|
141
|
+
const rendered = format === 'json'
|
|
142
|
+
? renderJson(report)
|
|
143
|
+
: format === 'md' || format === 'markdown'
|
|
144
|
+
? renderMarkdown(report)
|
|
145
|
+
: renderTerminal(report, colorFlag === undefined ? {} : { color: colorFlag });
|
|
146
|
+
if (format !== 'pretty' && format !== 'json' && format !== 'md' && format !== 'markdown') {
|
|
147
|
+
process.stderr.write(`Unknown --format "${format}". Use pretty, md, or json.\n`);
|
|
148
|
+
return 2;
|
|
149
|
+
}
|
|
150
|
+
process.stdout.write(rendered);
|
|
151
|
+
const outFile = flagString(args, 'out');
|
|
152
|
+
if (outFile) {
|
|
153
|
+
// Default the file's format from its extension so `--out report.md` behaves.
|
|
154
|
+
const body = outFile.endsWith('.json')
|
|
155
|
+
? renderJson(report)
|
|
156
|
+
: outFile.endsWith('.md')
|
|
157
|
+
? renderMarkdown(report)
|
|
158
|
+
: rendered;
|
|
159
|
+
await mkdir(dirname(resolve(outFile)), { recursive: true });
|
|
160
|
+
await writeFile(resolve(outFile), body, 'utf8');
|
|
161
|
+
process.stderr.write(`Wrote ${outFile}\n`);
|
|
162
|
+
}
|
|
163
|
+
const failOn = (flagString(args, 'fail-on') ?? config.failOn ?? DEFAULT_CONFIG.failOn);
|
|
164
|
+
return exitCodeFor(report, failOn);
|
|
165
|
+
}
|
|
166
|
+
async function runSpecDiff(args) {
|
|
167
|
+
const fromFile = flagString(args, 'from-file');
|
|
168
|
+
const toFile = flagString(args, 'to-file');
|
|
169
|
+
const fromRef = flagString(args, 'from-ref');
|
|
170
|
+
const toRef = flagString(args, 'to-ref') ?? 'master';
|
|
171
|
+
if (!fromFile && !fromRef) {
|
|
172
|
+
process.stderr.write('spec-diff needs a starting point: --from-file <path> or --from-ref <git ref>.\n' +
|
|
173
|
+
'Tip: `apiwatcher spec-diff --from-ref <sha>` diffs against stripe/openapi at that commit.\n');
|
|
174
|
+
return 2;
|
|
175
|
+
}
|
|
176
|
+
process.stderr.write('Loading specs…\n');
|
|
177
|
+
const [oldSpec, newSpec] = await Promise.all([
|
|
178
|
+
fromFile ? readSpecFile(fromFile) : fetchSpecAt(fromRef),
|
|
179
|
+
toFile ? readSpecFile(toFile) : fetchSpecAt(toRef),
|
|
180
|
+
]);
|
|
181
|
+
const methodMap = await loadMethodMap();
|
|
182
|
+
const maxDepth = flagNumber(args, 'max-depth') ?? 3;
|
|
183
|
+
process.stderr.write(`Diffing ${oldSpec.info?.version ?? '?'} -> ${newSpec.info?.version ?? '?'} (depth ${maxDepth})…\n`);
|
|
184
|
+
const changeset = diffSpecs(oldSpec, newSpec, {
|
|
185
|
+
methodMap,
|
|
186
|
+
maxDepth,
|
|
187
|
+
includeAdditive: flagBool(args, 'include-additive') === true,
|
|
188
|
+
...(fromFile || toFile
|
|
189
|
+
? {}
|
|
190
|
+
: {
|
|
191
|
+
source: {
|
|
192
|
+
repo: STRIPE_SPEC_REPO,
|
|
193
|
+
fromRef: fromRef,
|
|
194
|
+
// Pinned, so `apiwatcher watch` has a fixed point to diff forward from.
|
|
195
|
+
toRef: await resolveSpecCommit(toRef),
|
|
196
|
+
},
|
|
197
|
+
}),
|
|
198
|
+
});
|
|
199
|
+
const body = `${JSON.stringify(changeset, null, 2)}\n`;
|
|
200
|
+
if (flagBool(args, 'stdout') === true) {
|
|
201
|
+
process.stdout.write(body);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
const outDir = resolve(flagString(args, 'out-dir') ?? 'changesets/stripe');
|
|
205
|
+
await mkdir(outDir, { recursive: true });
|
|
206
|
+
const outFile = resolve(outDir, changesetFilename(changeset.from, changeset.to));
|
|
207
|
+
await writeFile(outFile, body, 'utf8');
|
|
208
|
+
process.stdout.write(`${outFile}\n`);
|
|
209
|
+
// The event catalogue lets the scanner recognise webhook event strings
|
|
210
|
+
// exactly rather than inferring them from surrounding code.
|
|
211
|
+
const catalogFile = resolve(flagString(args, 'events-out') ?? 'packages/apiwatcher/data/stripe/events.json');
|
|
212
|
+
await mkdir(dirname(catalogFile), { recursive: true });
|
|
213
|
+
await writeFile(catalogFile, `${JSON.stringify({
|
|
214
|
+
apiVersion: changeset.to,
|
|
215
|
+
generatedAt: changeset.generatedAt,
|
|
216
|
+
events: [...eventTypes(newSpec).keys()].sort(),
|
|
217
|
+
}, null, 2)}\n`, 'utf8');
|
|
218
|
+
}
|
|
219
|
+
const breaking = changeset.changes.filter((c) => c.severity === 'breaking').length;
|
|
220
|
+
process.stderr.write(`${changeset.changes.length} change(s), ${breaking} breaking.\n`);
|
|
221
|
+
return 0;
|
|
222
|
+
}
|
|
223
|
+
async function runBuildMethodMap(args) {
|
|
224
|
+
const out = resolve(flagString(args, 'out') ?? 'packages/apiwatcher/data/stripe/method-map.json');
|
|
225
|
+
const map = await buildMethodMap();
|
|
226
|
+
await writeMethodMap(map, out);
|
|
227
|
+
process.stdout.write(`${out}\n${Object.keys(map.byCall).length} SDK methods across ${Object.keys(map.byEndpoint).length} endpoints (stripe@${map.sdkVersion}).\n`);
|
|
228
|
+
return 0;
|
|
229
|
+
}
|
|
230
|
+
async function runListChangesets(args) {
|
|
231
|
+
const sets = await loadChangesets(flagString(args, 'changesets'));
|
|
232
|
+
if (sets.length === 0) {
|
|
233
|
+
process.stdout.write('No changesets found.\n');
|
|
234
|
+
return 0;
|
|
235
|
+
}
|
|
236
|
+
for (const cs of sets) {
|
|
237
|
+
const breaking = cs.changes.filter((c) => c.severity === 'breaking').length;
|
|
238
|
+
process.stdout.write(`${cs.from} -> ${cs.to} ${String(cs.changes.length).padStart(5)} change(s) ${String(breaking).padStart(5)} breaking\n`);
|
|
239
|
+
}
|
|
240
|
+
return 0;
|
|
241
|
+
}
|
|
242
|
+
async function runIndexChangesets(args) {
|
|
243
|
+
const dir = resolve(flagString(args, 'changesets') ?? 'changesets', 'stripe');
|
|
244
|
+
const sets = await loadChangesets(flagString(args, 'changesets'));
|
|
245
|
+
const withFiles = sets.map((changeset) => ({
|
|
246
|
+
changeset,
|
|
247
|
+
file: changesetFilename(changeset.from, changeset.to),
|
|
248
|
+
}));
|
|
249
|
+
const file = await writeIndex(buildIndex(withFiles), dir);
|
|
250
|
+
process.stdout.write(`${file}\n`);
|
|
251
|
+
return 0;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* The spec watcher.
|
|
255
|
+
*
|
|
256
|
+
* Diffs Stripe's current spec against the point the last changeset stopped at. If
|
|
257
|
+
* the API version has not moved, it exits 0 having written nothing, so a daily
|
|
258
|
+
* cron is a no-op on almost every run.
|
|
259
|
+
*/
|
|
260
|
+
async function runWatch(args) {
|
|
261
|
+
const changesetRoot = flagString(args, 'changesets');
|
|
262
|
+
const sets = await loadChangesets(changesetRoot);
|
|
263
|
+
const newest = sets[sets.length - 1];
|
|
264
|
+
if (!newest) {
|
|
265
|
+
process.stderr.write('No existing changeset to continue from. Bootstrap one first:\n' +
|
|
266
|
+
' apiwatcher spec-diff --from-ref <old spec sha> --to-ref master\n');
|
|
267
|
+
return 2;
|
|
268
|
+
}
|
|
269
|
+
const fromRef = newest.source?.toRef;
|
|
270
|
+
if (!fromRef) {
|
|
271
|
+
process.stderr.write(`Changeset ${newest.from} -> ${newest.to} has no source.toRef, so the watcher cannot diff forward.\n` +
|
|
272
|
+
'Regenerate it with --from-ref/--to-ref so provenance is recorded.\n');
|
|
273
|
+
return 2;
|
|
274
|
+
}
|
|
275
|
+
// Pin the branch to a commit up front: the recorded ref becomes the next
|
|
276
|
+
// run's starting point, and a branch name there would move under us.
|
|
277
|
+
const requestedRef = flagString(args, 'to-ref') ?? 'master';
|
|
278
|
+
const toRef = await resolveSpecCommit(requestedRef);
|
|
279
|
+
process.stderr.write(`Checking ${STRIPE_SPEC_REPO}@${requestedRef} (${toRef.slice(0, 8)}) against ${newest.to}…\n`);
|
|
280
|
+
const newSpec = await fetchSpecAt(toRef);
|
|
281
|
+
const incoming = newSpec.info?.version;
|
|
282
|
+
if (!incoming) {
|
|
283
|
+
process.stderr.write('Fetched spec does not declare info.version.\n');
|
|
284
|
+
return 2;
|
|
285
|
+
}
|
|
286
|
+
if (compareApiVersions(incoming, newest.to) <= 0) {
|
|
287
|
+
process.stdout.write(`No new Stripe version (still ${newest.to}).\n`);
|
|
288
|
+
return 0;
|
|
289
|
+
}
|
|
290
|
+
process.stderr.write(`New version ${incoming}; diffing from ${newest.to}…\n`);
|
|
291
|
+
const oldSpec = await fetchSpecAt(fromRef);
|
|
292
|
+
const methodMap = await loadMethodMap();
|
|
293
|
+
const changeset = diffSpecs(oldSpec, newSpec, {
|
|
294
|
+
methodMap,
|
|
295
|
+
maxDepth: flagNumber(args, 'max-depth') ?? 3,
|
|
296
|
+
includeAdditive: flagBool(args, 'include-additive') === true,
|
|
297
|
+
source: { repo: STRIPE_SPEC_REPO, fromRef, toRef },
|
|
298
|
+
});
|
|
299
|
+
const outDir = resolve(flagString(args, 'out-dir') ?? 'changesets/stripe');
|
|
300
|
+
await mkdir(outDir, { recursive: true });
|
|
301
|
+
const outFile = resolve(outDir, changesetFilename(changeset.from, changeset.to));
|
|
302
|
+
await writeFile(outFile, `${JSON.stringify(changeset, null, 2)}\n`, 'utf8');
|
|
303
|
+
const catalogFile = resolve(flagString(args, 'events-out') ?? 'packages/apiwatcher/data/stripe/events.json');
|
|
304
|
+
await mkdir(dirname(catalogFile), { recursive: true });
|
|
305
|
+
await writeFile(catalogFile, `${JSON.stringify({
|
|
306
|
+
apiVersion: changeset.to,
|
|
307
|
+
generatedAt: changeset.generatedAt,
|
|
308
|
+
events: [...eventTypes(newSpec).keys()].sort(),
|
|
309
|
+
}, null, 2)}\n`, 'utf8');
|
|
310
|
+
// Refresh the manifest so the GitHub App notices the new version.
|
|
311
|
+
const refreshed = await loadChangesets(changesetRoot);
|
|
312
|
+
await writeIndex(buildIndex(refreshed.map((cs) => ({ changeset: cs, file: changesetFilename(cs.from, cs.to) }))), outDir);
|
|
313
|
+
const breaking = changeset.changes.filter((c) => c.severity === 'breaking').length;
|
|
314
|
+
process.stdout.write(`${changeset.from} -> ${changeset.to}: ${changeset.changes.length} change(s), ${breaking} breaking\n`);
|
|
315
|
+
// Let the workflow branch on the result without parsing stdout.
|
|
316
|
+
const githubOutput = process.env.GITHUB_OUTPUT;
|
|
317
|
+
if (githubOutput) {
|
|
318
|
+
await appendFile(githubOutput, `new_version=${changeset.to}\nbreaking=${breaking}\nchangeset=${outFile}\n`, 'utf8');
|
|
319
|
+
}
|
|
320
|
+
return 0;
|
|
321
|
+
}
|
|
322
|
+
/** Useful for the spec watcher: which spec commits exist. */
|
|
323
|
+
export { listSpecCommits };
|
|
324
|
+
main(process.argv.slice(2))
|
|
325
|
+
.then((code) => {
|
|
326
|
+
process.exitCode = code;
|
|
327
|
+
})
|
|
328
|
+
.catch((err) => {
|
|
329
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
330
|
+
process.stderr.write(`apiwatcher: ${message}\n`);
|
|
331
|
+
process.exitCode = 2;
|
|
332
|
+
});
|
|
333
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Severity } from './changeset/types.js';
|
|
2
|
+
/** Per-repo config. Everything is optional; zero-config is the default path. */
|
|
3
|
+
export interface RepoConfig {
|
|
4
|
+
/** Version to check against. `latest` means the newest changeset we know about. */
|
|
5
|
+
target?: string | 'latest';
|
|
6
|
+
/** Paths to skip, in addition to the built-in ignores. */
|
|
7
|
+
ignorePaths?: string[];
|
|
8
|
+
/** Change ids to suppress — the escape hatch for a false positive. */
|
|
9
|
+
ignoreChanges?: string[];
|
|
10
|
+
/** Whether the GitHub App should open issues for this repo. */
|
|
11
|
+
alerts?: boolean;
|
|
12
|
+
/** Severity that makes the CLI exit non-zero. */
|
|
13
|
+
failOn?: Severity | 'never';
|
|
14
|
+
/** Drop findings below this confidence. */
|
|
15
|
+
minConfidence?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare const CONFIG_FILENAMES: string[];
|
|
18
|
+
export declare const DEFAULT_CONFIG: Required<Pick<RepoConfig, 'target' | 'alerts' | 'failOn' | 'minConfidence'>>;
|
|
19
|
+
export declare function findConfigFile(root: string): string | null;
|
|
20
|
+
/** Validate explicitly so a typo in config fails loudly instead of being ignored. */
|
|
21
|
+
export declare function validateConfig(raw: unknown, origin: string): RepoConfig;
|
|
22
|
+
export declare function loadConfig(root: string): Promise<{
|
|
23
|
+
config: RepoConfig;
|
|
24
|
+
file: string | null;
|
|
25
|
+
}>;
|
|
26
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGrD,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC5B,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,gBAAgB,UAI5B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,eAAe,CAAC,CAKvG,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM1D;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAwDvE;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAWnG"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { isApiVersion } from './changeset/version.js';
|
|
5
|
+
export const CONFIG_FILENAMES = [
|
|
6
|
+
'.apiwatcher.json',
|
|
7
|
+
'apiwatcher.config.json',
|
|
8
|
+
'.github/apiwatcher.json',
|
|
9
|
+
];
|
|
10
|
+
export const DEFAULT_CONFIG = {
|
|
11
|
+
target: 'latest',
|
|
12
|
+
alerts: true,
|
|
13
|
+
failOn: 'breaking',
|
|
14
|
+
minConfidence: 0.4,
|
|
15
|
+
};
|
|
16
|
+
export function findConfigFile(root) {
|
|
17
|
+
for (const name of CONFIG_FILENAMES) {
|
|
18
|
+
const candidate = join(root, name);
|
|
19
|
+
if (existsSync(candidate))
|
|
20
|
+
return candidate;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
/** Validate explicitly so a typo in config fails loudly instead of being ignored. */
|
|
25
|
+
export function validateConfig(raw, origin) {
|
|
26
|
+
if (typeof raw !== 'object' || raw === null)
|
|
27
|
+
throw new Error(`${origin}: config must be an object`);
|
|
28
|
+
const cfg = raw;
|
|
29
|
+
const out = {};
|
|
30
|
+
if (cfg.target !== undefined) {
|
|
31
|
+
if (typeof cfg.target !== 'string' || (cfg.target !== 'latest' && !isApiVersion(cfg.target))) {
|
|
32
|
+
throw new Error(`${origin}: "target" must be "latest" or a Stripe version like 2026-08-26.dahlia`);
|
|
33
|
+
}
|
|
34
|
+
out.target = cfg.target;
|
|
35
|
+
}
|
|
36
|
+
for (const key of ['ignorePaths', 'ignoreChanges']) {
|
|
37
|
+
const value = cfg[key];
|
|
38
|
+
if (value === undefined)
|
|
39
|
+
continue;
|
|
40
|
+
if (!Array.isArray(value) || value.some((v) => typeof v !== 'string')) {
|
|
41
|
+
throw new Error(`${origin}: "${key}" must be an array of strings`);
|
|
42
|
+
}
|
|
43
|
+
out[key] = value;
|
|
44
|
+
}
|
|
45
|
+
if (cfg.alerts !== undefined) {
|
|
46
|
+
if (typeof cfg.alerts !== 'boolean')
|
|
47
|
+
throw new Error(`${origin}: "alerts" must be a boolean`);
|
|
48
|
+
out.alerts = cfg.alerts;
|
|
49
|
+
}
|
|
50
|
+
if (cfg.failOn !== undefined) {
|
|
51
|
+
const allowed = ['breaking', 'deprecating', 'additive', 'never'];
|
|
52
|
+
if (typeof cfg.failOn !== 'string' || !allowed.includes(cfg.failOn)) {
|
|
53
|
+
throw new Error(`${origin}: "failOn" must be one of ${allowed.join(', ')}`);
|
|
54
|
+
}
|
|
55
|
+
out.failOn = cfg.failOn;
|
|
56
|
+
}
|
|
57
|
+
if (cfg.minConfidence !== undefined) {
|
|
58
|
+
if (typeof cfg.minConfidence !== 'number' || cfg.minConfidence < 0 || cfg.minConfidence > 1) {
|
|
59
|
+
throw new Error(`${origin}: "minConfidence" must be a number between 0 and 1`);
|
|
60
|
+
}
|
|
61
|
+
out.minConfidence = cfg.minConfidence;
|
|
62
|
+
}
|
|
63
|
+
const known = new Set([
|
|
64
|
+
'target',
|
|
65
|
+
'ignorePaths',
|
|
66
|
+
'ignoreChanges',
|
|
67
|
+
'alerts',
|
|
68
|
+
'failOn',
|
|
69
|
+
'minConfidence',
|
|
70
|
+
'$schema',
|
|
71
|
+
]);
|
|
72
|
+
const unknown = Object.keys(cfg).filter((k) => !known.has(k));
|
|
73
|
+
if (unknown.length > 0) {
|
|
74
|
+
throw new Error(`${origin}: unknown config key(s): ${unknown.join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
export async function loadConfig(root) {
|
|
79
|
+
const file = findConfigFile(root);
|
|
80
|
+
if (!file)
|
|
81
|
+
return { config: {}, file: null };
|
|
82
|
+
const text = await readFile(file, 'utf8');
|
|
83
|
+
let parsed;
|
|
84
|
+
try {
|
|
85
|
+
parsed = JSON.parse(text);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
throw new Error(`${file}: invalid JSON (${err.message})`);
|
|
89
|
+
}
|
|
90
|
+
return { config: validateConfig(parsed, file), file };
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from './changeset/types.js';
|
|
2
|
+
export * from './changeset/version.js';
|
|
3
|
+
export { loadChangeset, loadChangesets, changesBetween, latestKnownVersion, validateChangeset, defaultChangesetDir, } from './changeset/load.js';
|
|
4
|
+
export { diffSpecs, type DiffOptions } from './specdiff/diff.js';
|
|
5
|
+
export { fetchSpecAt, listSpecCommits, readSpecFile, changesetFilename, versionSlug, STRIPE_SPEC_PATH, STRIPE_SPEC_REPO, } from './specdiff/fetch.js';
|
|
6
|
+
export { loadMethodMap, defaultMethodMapPath, lookupSdkMethods, normalizePath, endpointKey, callKey, type MethodMap, } from './specdiff/methodmap.js';
|
|
7
|
+
export { buildMethodMap, writeMethodMap, findStripeCore } from './specdiff/build-method-map.js';
|
|
8
|
+
export { scanRepo, type ScanOptions } from './scanner/scan.js';
|
|
9
|
+
export * from './scanner/types.js';
|
|
10
|
+
export { detectVersion } from './scanner/version.js';
|
|
11
|
+
export { buildReport, exitCodeFor, type ImpactReport, type Finding } from './report/impact.js';
|
|
12
|
+
export { renderTerminal, renderMarkdown, renderJson } from './report/render.js';
|
|
13
|
+
export { loadConfig, validateConfig, findConfigFile, DEFAULT_CONFIG, CONFIG_FILENAMES, type RepoConfig, } from './config.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EACL,WAAW,EACX,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,OAAO,EACP,KAAK,SAAS,GACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhG,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/D,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EACL,UAAU,EACV,cAAc,EACd,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from './changeset/types.js';
|
|
2
|
+
export * from './changeset/version.js';
|
|
3
|
+
export { loadChangeset, loadChangesets, changesBetween, latestKnownVersion, validateChangeset, defaultChangesetDir, } from './changeset/load.js';
|
|
4
|
+
export { diffSpecs } from './specdiff/diff.js';
|
|
5
|
+
export { fetchSpecAt, listSpecCommits, readSpecFile, changesetFilename, versionSlug, STRIPE_SPEC_PATH, STRIPE_SPEC_REPO, } from './specdiff/fetch.js';
|
|
6
|
+
export { loadMethodMap, defaultMethodMapPath, lookupSdkMethods, normalizePath, endpointKey, callKey, } from './specdiff/methodmap.js';
|
|
7
|
+
export { buildMethodMap, writeMethodMap, findStripeCore } from './specdiff/build-method-map.js';
|
|
8
|
+
export { scanRepo } from './scanner/scan.js';
|
|
9
|
+
export * from './scanner/types.js';
|
|
10
|
+
export { detectVersion } from './scanner/version.js';
|
|
11
|
+
export { buildReport, exitCodeFor } from './report/impact.js';
|
|
12
|
+
export { renderTerminal, renderMarkdown, renderJson } from './report/render.js';
|
|
13
|
+
export { loadConfig, validateConfig, findConfigFile, DEFAULT_CONFIG, CONFIG_FILENAMES, } from './config.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAoB,MAAM,oBAAoB,CAAC;AACjE,OAAO,EACL,WAAW,EACX,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,OAAO,GAER,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhG,OAAO,EAAE,QAAQ,EAAoB,MAAM,mBAAmB,CAAC;AAC/D,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAmC,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EACL,UAAU,EACV,cAAc,EACd,cAAc,EACd,cAAc,EACd,gBAAgB,GAEjB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Severity, SpecChange } from '../changeset/types.js';
|
|
2
|
+
import type { ScanResult, Usage } from '../scanner/types.js';
|
|
3
|
+
export interface Finding {
|
|
4
|
+
change: SpecChange;
|
|
5
|
+
/** Call sites this change reaches, most confident first. */
|
|
6
|
+
sites: Usage[];
|
|
7
|
+
severity: Severity;
|
|
8
|
+
/** Highest confidence among the matched sites. */
|
|
9
|
+
confidence: number;
|
|
10
|
+
/** One line telling the reader what to do. */
|
|
11
|
+
suggestion: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ImpactReport {
|
|
14
|
+
api: 'stripe';
|
|
15
|
+
/** Version the repo is on today, and how we concluded that. */
|
|
16
|
+
currentVersion: string | null;
|
|
17
|
+
currentVersionSource: 'pinned' | 'sdkDefault' | 'unknown';
|
|
18
|
+
targetVersion: string;
|
|
19
|
+
scannedAt: string;
|
|
20
|
+
root: string;
|
|
21
|
+
filesScanned: number;
|
|
22
|
+
findings: Finding[];
|
|
23
|
+
/** Changes in range that touch nothing in this repo. Counted, not listed. */
|
|
24
|
+
unaffectedChanges: number;
|
|
25
|
+
totals: Record<Severity, number>;
|
|
26
|
+
warnings: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface BuildReportInput {
|
|
29
|
+
scan: ScanResult;
|
|
30
|
+
changes: readonly SpecChange[];
|
|
31
|
+
targetVersion: string;
|
|
32
|
+
/** Change ids to suppress, from config. */
|
|
33
|
+
ignoreIds?: readonly string[];
|
|
34
|
+
/** Drop findings whose best site is below this confidence. */
|
|
35
|
+
minConfidence?: number;
|
|
36
|
+
}
|
|
37
|
+
export declare function buildReport(input: BuildReportInput): ImpactReport;
|
|
38
|
+
/** Exit code contract: non-zero only when something is actually breaking. */
|
|
39
|
+
export declare function exitCodeFor(report: ImpactReport, failOn?: Severity | 'never'): number;
|
|
40
|
+
//# sourceMappingURL=impact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact.d.ts","sourceRoot":"","sources":["../../src/report/impact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,UAAU,CAAC;IACnB,4DAA4D;IAC5D,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,QAAQ,CAAC;IACd,+DAA+D;IAC/D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,oBAAoB,EAAE,QAAQ,GAAG,YAAY,GAAG,SAAS,CAAC;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,6EAA6E;IAC7E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CA+DjE;AA6RD,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,GAAE,QAAQ,GAAG,OAAoB,GAAG,MAAM,CAKjG"}
|