assert-json-body 1.0.2
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/README.md +352 -0
- package/dist/assertion/diff-recordings-vs-spec.d.ts +3 -0
- package/dist/assertion/diff-recordings-vs-spec.d.ts.map +1 -0
- package/dist/assertion/diff-recordings-vs-spec.js +176 -0
- package/dist/assertion/diff-recordings-vs-spec.js.map +1 -0
- package/dist/assertion/index.d.ts +2 -0
- package/dist/assertion/index.d.ts.map +1 -0
- package/dist/assertion/index.js +2 -0
- package/dist/assertion/index.js.map +1 -0
- package/dist/assertion/recorder.d.ts +7 -0
- package/dist/assertion/recorder.d.ts.map +1 -0
- package/dist/assertion/recorder.js +81 -0
- package/dist/assertion/recorder.js.map +1 -0
- package/dist/assertion/summarize-recordings.d.ts +3 -0
- package/dist/assertion/summarize-recordings.d.ts.map +1 -0
- package/dist/assertion/summarize-recordings.js +121 -0
- package/dist/assertion/summarize-recordings.js.map +1 -0
- package/dist/assertion/validator.d.ts +2 -0
- package/dist/assertion/validator.d.ts.map +1 -0
- package/dist/assertion/validator.js +3 -0
- package/dist/assertion/validator.js.map +1 -0
- package/dist/base.d.ts +2 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +3 -0
- package/dist/base.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +84 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/extractor/src/lib/child-expansion.d.ts +8 -0
- package/dist/extractor/src/lib/child-expansion.d.ts.map +1 -0
- package/dist/extractor/src/lib/child-expansion.js +72 -0
- package/dist/extractor/src/lib/child-expansion.js.map +1 -0
- package/dist/extractor/src/lib/git.d.ts +9 -0
- package/dist/extractor/src/lib/git.d.ts.map +1 -0
- package/dist/extractor/src/lib/git.js +22 -0
- package/dist/extractor/src/lib/git.js.map +1 -0
- package/dist/extractor/src/lib/schema-flatten.d.ts +10 -0
- package/dist/extractor/src/lib/schema-flatten.d.ts.map +1 -0
- package/dist/extractor/src/lib/schema-flatten.js +203 -0
- package/dist/extractor/src/lib/schema-flatten.js.map +1 -0
- package/dist/extractor/src/lib/type-utils.d.ts +5 -0
- package/dist/extractor/src/lib/type-utils.d.ts.map +1 -0
- package/dist/extractor/src/lib/type-utils.js +27 -0
- package/dist/extractor/src/lib/type-utils.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/assert.d.ts +27 -0
- package/dist/lib/assert.d.ts.map +1 -0
- package/dist/lib/assert.js +32 -0
- package/dist/lib/assert.js.map +1 -0
- package/dist/lib/child-expansion.d.ts +2 -0
- package/dist/lib/child-expansion.d.ts.map +1 -0
- package/dist/lib/child-expansion.js +2 -0
- package/dist/lib/child-expansion.js.map +1 -0
- package/dist/lib/config.d.ts +27 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +139 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/extractor.d.ts +6 -0
- package/dist/lib/extractor.d.ts.map +1 -0
- package/dist/lib/extractor.js +164 -0
- package/dist/lib/extractor.js.map +1 -0
- package/dist/lib/git.d.ts +2 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +2 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/recorder.d.ts +8 -0
- package/dist/lib/recorder.d.ts.map +1 -0
- package/dist/lib/recorder.js +68 -0
- package/dist/lib/recorder.js.map +1 -0
- package/dist/lib/responses.d.ts +13 -0
- package/dist/lib/responses.d.ts.map +1 -0
- package/dist/lib/responses.js +114 -0
- package/dist/lib/responses.js.map +1 -0
- package/dist/lib/schema-flatten.d.ts +2 -0
- package/dist/lib/schema-flatten.d.ts.map +1 -0
- package/dist/lib/schema-flatten.js +2 -0
- package/dist/lib/schema-flatten.js.map +1 -0
- package/dist/lib/tools/diff-recordings-vs-spec.d.ts +2 -0
- package/dist/lib/tools/diff-recordings-vs-spec.d.ts.map +1 -0
- package/dist/lib/tools/diff-recordings-vs-spec.js +2 -0
- package/dist/lib/tools/diff-recordings-vs-spec.js.map +1 -0
- package/dist/lib/tools/recorder.d.ts +2 -0
- package/dist/lib/tools/recorder.d.ts.map +1 -0
- package/dist/lib/tools/recorder.js +3 -0
- package/dist/lib/tools/recorder.js.map +1 -0
- package/dist/lib/tools/summarize-recordings.d.ts +2 -0
- package/dist/lib/tools/summarize-recordings.d.ts.map +1 -0
- package/dist/lib/tools/summarize-recordings.js +2 -0
- package/dist/lib/tools/summarize-recordings.js.map +1 -0
- package/dist/lib/type-utils.d.ts +2 -0
- package/dist/lib/type-utils.d.ts.map +1 -0
- package/dist/lib/type-utils.js +2 -0
- package/dist/lib/type-utils.js.map +1 -0
- package/dist/lib/validator.d.ts +33 -0
- package/dist/lib/validator.d.ts.map +1 -0
- package/dist/lib/validator.js +179 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/types/index.d.ts +88 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist-cjs/assertion/diff-recordings-vs-spec.d.ts +3 -0
- package/dist-cjs/assertion/diff-recordings-vs-spec.d.ts.map +1 -0
- package/dist-cjs/assertion/diff-recordings-vs-spec.js +178 -0
- package/dist-cjs/assertion/diff-recordings-vs-spec.js.map +1 -0
- package/dist-cjs/assertion/index.d.ts +2 -0
- package/dist-cjs/assertion/index.d.ts.map +1 -0
- package/dist-cjs/assertion/index.js +3 -0
- package/dist-cjs/assertion/index.js.map +1 -0
- package/dist-cjs/assertion/recorder.d.ts +7 -0
- package/dist-cjs/assertion/recorder.d.ts.map +1 -0
- package/dist-cjs/assertion/recorder.js +84 -0
- package/dist-cjs/assertion/recorder.js.map +1 -0
- package/dist-cjs/assertion/summarize-recordings.d.ts +3 -0
- package/dist-cjs/assertion/summarize-recordings.d.ts.map +1 -0
- package/dist-cjs/assertion/summarize-recordings.js +123 -0
- package/dist-cjs/assertion/summarize-recordings.js.map +1 -0
- package/dist-cjs/assertion/validator.d.ts +2 -0
- package/dist-cjs/assertion/validator.d.ts.map +1 -0
- package/dist-cjs/assertion/validator.js +7 -0
- package/dist-cjs/assertion/validator.js.map +1 -0
- package/dist-cjs/base.d.ts +2 -0
- package/dist-cjs/base.d.ts.map +1 -0
- package/dist-cjs/base.js +7 -0
- package/dist-cjs/base.js.map +1 -0
- package/dist-cjs/cli/index.d.ts +3 -0
- package/dist-cjs/cli/index.d.ts.map +1 -0
- package/dist-cjs/cli/index.js +86 -0
- package/dist-cjs/cli/index.js.map +1 -0
- package/dist-cjs/extractor/src/lib/child-expansion.d.ts +8 -0
- package/dist-cjs/extractor/src/lib/child-expansion.d.ts.map +1 -0
- package/dist-cjs/extractor/src/lib/child-expansion.js +76 -0
- package/dist-cjs/extractor/src/lib/child-expansion.js.map +1 -0
- package/dist-cjs/extractor/src/lib/git.d.ts +9 -0
- package/dist-cjs/extractor/src/lib/git.d.ts.map +1 -0
- package/dist-cjs/extractor/src/lib/git.js +26 -0
- package/dist-cjs/extractor/src/lib/git.js.map +1 -0
- package/dist-cjs/extractor/src/lib/schema-flatten.d.ts +10 -0
- package/dist-cjs/extractor/src/lib/schema-flatten.d.ts.map +1 -0
- package/dist-cjs/extractor/src/lib/schema-flatten.js +211 -0
- package/dist-cjs/extractor/src/lib/schema-flatten.js.map +1 -0
- package/dist-cjs/extractor/src/lib/type-utils.d.ts +5 -0
- package/dist-cjs/extractor/src/lib/type-utils.d.ts.map +1 -0
- package/dist-cjs/extractor/src/lib/type-utils.js +32 -0
- package/dist-cjs/extractor/src/lib/type-utils.js.map +1 -0
- package/dist-cjs/index.d.ts +5 -0
- package/dist-cjs/index.d.ts.map +1 -0
- package/dist-cjs/index.js +26 -0
- package/dist-cjs/index.js.map +1 -0
- package/dist-cjs/lib/assert.d.ts +27 -0
- package/dist-cjs/lib/assert.d.ts.map +1 -0
- package/dist-cjs/lib/assert.js +35 -0
- package/dist-cjs/lib/assert.js.map +1 -0
- package/dist-cjs/lib/child-expansion.d.ts +2 -0
- package/dist-cjs/lib/child-expansion.d.ts.map +1 -0
- package/dist-cjs/lib/child-expansion.js +7 -0
- package/dist-cjs/lib/child-expansion.js.map +1 -0
- package/dist-cjs/lib/config.d.ts +27 -0
- package/dist-cjs/lib/config.d.ts.map +1 -0
- package/dist-cjs/lib/config.js +147 -0
- package/dist-cjs/lib/config.js.map +1 -0
- package/dist-cjs/lib/extractor.d.ts +6 -0
- package/dist-cjs/lib/extractor.d.ts.map +1 -0
- package/dist-cjs/lib/extractor.js +172 -0
- package/dist-cjs/lib/extractor.js.map +1 -0
- package/dist-cjs/lib/git.d.ts +2 -0
- package/dist-cjs/lib/git.d.ts.map +1 -0
- package/dist-cjs/lib/git.js +6 -0
- package/dist-cjs/lib/git.js.map +1 -0
- package/dist-cjs/lib/recorder.d.ts +8 -0
- package/dist-cjs/lib/recorder.d.ts.map +1 -0
- package/dist-cjs/lib/recorder.js +71 -0
- package/dist-cjs/lib/recorder.js.map +1 -0
- package/dist-cjs/lib/responses.d.ts +13 -0
- package/dist-cjs/lib/responses.d.ts.map +1 -0
- package/dist-cjs/lib/responses.js +117 -0
- package/dist-cjs/lib/responses.js.map +1 -0
- package/dist-cjs/lib/schema-flatten.d.ts +2 -0
- package/dist-cjs/lib/schema-flatten.d.ts.map +1 -0
- package/dist-cjs/lib/schema-flatten.js +11 -0
- package/dist-cjs/lib/schema-flatten.js.map +1 -0
- package/dist-cjs/lib/tools/diff-recordings-vs-spec.d.ts +2 -0
- package/dist-cjs/lib/tools/diff-recordings-vs-spec.d.ts.map +1 -0
- package/dist-cjs/lib/tools/diff-recordings-vs-spec.js +18 -0
- package/dist-cjs/lib/tools/diff-recordings-vs-spec.js.map +1 -0
- package/dist-cjs/lib/tools/recorder.d.ts +2 -0
- package/dist-cjs/lib/tools/recorder.d.ts.map +1 -0
- package/dist-cjs/lib/tools/recorder.js +19 -0
- package/dist-cjs/lib/tools/recorder.js.map +1 -0
- package/dist-cjs/lib/tools/summarize-recordings.d.ts +2 -0
- package/dist-cjs/lib/tools/summarize-recordings.d.ts.map +1 -0
- package/dist-cjs/lib/tools/summarize-recordings.js +18 -0
- package/dist-cjs/lib/tools/summarize-recordings.js.map +1 -0
- package/dist-cjs/lib/type-utils.d.ts +2 -0
- package/dist-cjs/lib/type-utils.d.ts.map +1 -0
- package/dist-cjs/lib/type-utils.js +8 -0
- package/dist-cjs/lib/type-utils.js.map +1 -0
- package/dist-cjs/lib/validator.d.ts +33 -0
- package/dist-cjs/lib/validator.d.ts.map +1 -0
- package/dist-cjs/lib/validator.js +182 -0
- package/dist-cjs/lib/validator.js.map +1 -0
- package/dist-cjs/package.json +1 -0
- package/dist-cjs/types/index.d.ts +88 -0
- package/dist-cjs/types/index.d.ts.map +1 -0
- package/dist-cjs/types/index.js +4 -0
- package/dist-cjs/types/index.js.map +1 -0
- package/package.json +125 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
|
|
4
|
+
* one or more contributor license agreements. See the NOTICE file distributed
|
|
5
|
+
* with this work for additional information regarding copyright ownership.
|
|
6
|
+
* Licensed under the Camunda License 1.0. You may not use this file
|
|
7
|
+
* except in compliance with the Camunda License 1.0.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Summarize recorded response bodies (JSONL) produced by TEST_RESPONSE_BODY_RECORD_DIR
|
|
11
|
+
* to propose fields that appear in N% (default 100%) of observations but are not
|
|
12
|
+
* marked required in the spec-derived artifact.
|
|
13
|
+
*/
|
|
14
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
15
|
+
import { resolve } from 'node:path';
|
|
16
|
+
const dir = process.argv[2] || process.env.TEST_RESPONSE_BODY_RECORD_DIR;
|
|
17
|
+
if (!dir) {
|
|
18
|
+
console.error('Usage: summarize-recordings <record-dir> [thresholdPct=100]');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
const thresholdPct = Number(process.argv[3] || '100');
|
|
22
|
+
function isJsonlFile(f) {
|
|
23
|
+
return f.endsWith('.jsonl');
|
|
24
|
+
}
|
|
25
|
+
function groupKey(route, method, status) {
|
|
26
|
+
return `${method || 'ANY'} ${status || 'ANY'} ${route}`;
|
|
27
|
+
}
|
|
28
|
+
const aggregates = new Map();
|
|
29
|
+
for (const file of readdirSync(dir)) {
|
|
30
|
+
const full = resolve(dir, file);
|
|
31
|
+
if (!isJsonlFile(file))
|
|
32
|
+
continue;
|
|
33
|
+
const stat = statSync(full);
|
|
34
|
+
if (!stat.isFile())
|
|
35
|
+
continue;
|
|
36
|
+
const lines = readFileSync(full, 'utf8').split(/\n+/).filter(Boolean);
|
|
37
|
+
for (const line of lines) {
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(line);
|
|
40
|
+
const key = groupKey(parsed.route, parsed.method, parsed.status);
|
|
41
|
+
let agg = aggregates.get(key);
|
|
42
|
+
if (!agg) {
|
|
43
|
+
agg = {
|
|
44
|
+
route: parsed.route,
|
|
45
|
+
method: parsed.method || 'ANY',
|
|
46
|
+
status: parsed.status || 'ANY',
|
|
47
|
+
samples: 0,
|
|
48
|
+
required: new Set(parsed.required || []),
|
|
49
|
+
presentCounts: new Map(),
|
|
50
|
+
deepCounts: new Map(),
|
|
51
|
+
};
|
|
52
|
+
aggregates.set(key, agg);
|
|
53
|
+
}
|
|
54
|
+
agg.samples++;
|
|
55
|
+
for (const f of parsed.present || []) {
|
|
56
|
+
agg.presentCounts.set(f, (agg.presentCounts.get(f) || 0) + 1);
|
|
57
|
+
}
|
|
58
|
+
for (const p of parsed.deepPresent || []) {
|
|
59
|
+
agg.deepCounts.set(p, (agg.deepCounts.get(p) || 0) + 1);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// skip malformed line
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const report = [];
|
|
68
|
+
for (const [key, agg] of aggregates.entries()) {
|
|
69
|
+
const promote = [];
|
|
70
|
+
const thresholdCount = Math.ceil((thresholdPct / 100) * agg.samples);
|
|
71
|
+
for (const [field, count] of agg.presentCounts.entries()) {
|
|
72
|
+
if (!agg.required.has(field) && count >= thresholdCount) {
|
|
73
|
+
promote.push({
|
|
74
|
+
field,
|
|
75
|
+
pct: (count / agg.samples) * 100,
|
|
76
|
+
count,
|
|
77
|
+
level: 'top',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const [ptr, count] of agg.deepCounts.entries()) {
|
|
82
|
+
// Skip root-level (empty) and focus on pointers like /field, /field/sub, /field/*/id
|
|
83
|
+
if (!ptr.startsWith('/'))
|
|
84
|
+
continue;
|
|
85
|
+
const topSeg = ptr.split('/')[1];
|
|
86
|
+
if (agg.required.has(topSeg))
|
|
87
|
+
continue; // already required at top-level
|
|
88
|
+
if (count >= thresholdCount) {
|
|
89
|
+
promote.push({
|
|
90
|
+
field: ptr,
|
|
91
|
+
pct: (count / agg.samples) * 100,
|
|
92
|
+
count,
|
|
93
|
+
level: 'deep',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
promote.sort((a, b) => b.pct - a.pct || a.field.localeCompare(b.field));
|
|
98
|
+
report.push({
|
|
99
|
+
key,
|
|
100
|
+
route: agg.route,
|
|
101
|
+
method: agg.method,
|
|
102
|
+
status: agg.status,
|
|
103
|
+
samples: agg.samples,
|
|
104
|
+
required: Array.from(agg.required).sort(),
|
|
105
|
+
promote,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
report.sort((a, b) => a.route.localeCompare(b.route) ||
|
|
109
|
+
a.method.localeCompare(b.method) ||
|
|
110
|
+
a.status.localeCompare(b.status));
|
|
111
|
+
// Output JSON for machine usage & a concise human summary
|
|
112
|
+
console.log(JSON.stringify({ thresholdPct, generatedAt: new Date().toISOString(), items: report }, null, 2));
|
|
113
|
+
console.error('\n--- Promotion summary (top candidates) ---');
|
|
114
|
+
for (const r of report) {
|
|
115
|
+
const tops = r.promote
|
|
116
|
+
.slice(0, 8)
|
|
117
|
+
.map((p) => `${p.field}(${p.level === 'top' ? 'T' : 'D'}:${p.pct.toFixed(0)}%)`)
|
|
118
|
+
.join(', ');
|
|
119
|
+
console.error(`${r.method} ${r.status} ${r.route} samples=${r.samples} promote: ${tops}`);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=summarize-recordings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarize-recordings.js","sourceRoot":"","sources":["../../src/assertion/summarize-recordings.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG;AAEH;;;;GAIG;AACH,OAAO,EAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAqBlC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;AACzE,IAAI,CAAC,GAAG,EAAE,CAAC;IACT,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AACD,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC;AAEtD,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,MAAe,EAAE,MAAe;IAC/D,OAAO,GAAG,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;AAEhD,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,SAAS;IACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;QAAE,SAAS;IAC7B,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACtE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAc,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YACjE,IAAI,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,GAAG,GAAG;oBACJ,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,KAAK;oBAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,KAAK;oBAC9B,OAAO,EAAE,CAAC;oBACV,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;oBACxC,aAAa,EAAE,IAAI,GAAG,EAAE;oBACxB,UAAU,EAAE,IAAI,GAAG,EAAE;iBACtB,CAAC;gBACF,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3B,CAAC;YACD,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;gBACrC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAChE,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;gBACzC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;IACH,CAAC;AACH,CAAC;AAmBD,MAAM,MAAM,GAAgB,EAAE,CAAC;AAE/B,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;IACrE,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;QACzD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,cAAc,EAAE,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK;gBACL,GAAG,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG;gBAChC,KAAK;gBACL,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;QACpD,qFAAqF;QACrF,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACnC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,SAAS,CAAC,gCAAgC;QACxE,IAAI,KAAK,IAAI,cAAc,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,GAAG;gBACV,GAAG,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG;gBAChC,KAAK;gBACL,KAAK,EAAE,MAAM;aACd,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,MAAM,CAAC,IAAI,CAAC;QACV,GAAG;QACH,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE;QACzC,OAAO;KACR,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,IAAI,CACT,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9B,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;IAChC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CACnC,CAAC;AAEF,0DAA0D;AAC1D,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAC,EACpE,IAAI,EACJ,CAAC,CACF,CACF,CAAC;AAEF,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;AAC9D,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO;SACnB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CACtE;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,CAAC,KAAK,CACX,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,OAAO,cAAc,IAAI,EAAE,CAC7E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/assertion/validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/assertion/validator.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/base.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/base.js
ADDED
package/dist/base.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { generate } from '../lib/extractor.js';
|
|
3
|
+
import { buildConfig, parseCliArgs, cliConfigSubset } from '../lib/config.js';
|
|
4
|
+
import { writeFileSync, existsSync, readFileSync } from 'node:fs';
|
|
5
|
+
function printVersion() {
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
7
|
+
const pkg = require('../../package.json');
|
|
8
|
+
console.log(pkg.version);
|
|
9
|
+
}
|
|
10
|
+
function printHelp() {
|
|
11
|
+
console.log(`assert-json-body <command> [options]\n\nCommands:\n extract Run extraction (default)\n init-config Create example assert-json-body.config.json\n help Show this help\n version Print version\n\nExtraction Options (CLI/env override config.extract):\n --repo=URL\n --specPath=PATH\n --ref=REF (branch/tag/sha)\n --outputDir=DIR (default: assert-json-body)\n --responsesFile=FILE (override output file path)\n --preserveCheckout (do not delete temp git checkout)\n --dryRun (simulate, no filesystem writes)\n --failIfExists (error if responses file exists)\n --logLevel=VAL (silent|error|warn|info|debug)\n --config=FILE (explicit config file path)\n\nValidation (env overrides only for now):\n AJB_RECORD / TEST_RESPONSE_BODY_RECORD (enable global recording)\n AJB_THROW_ON_FAIL (default throw behaviour)\n\nSchema file resolution precedence:\n explicit option > env (AJB_RESPONSES_FILE / ROUTE_TEST_RESPONSES_FILE) > config.extract.responsesFile or <outputDir>/responses.json > default ./assert-json-body/responses.json\n`);
|
|
12
|
+
}
|
|
13
|
+
function initConfig() {
|
|
14
|
+
const path = 'assert-json-body.config.json';
|
|
15
|
+
if (existsSync(path)) {
|
|
16
|
+
console.error(`Config file already exists at ${path}`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const example = {
|
|
20
|
+
extract: {
|
|
21
|
+
repo: 'https://github.com/camunda/camunda-orchestration-cluster-api',
|
|
22
|
+
specPath: 'specification/openapi.yaml',
|
|
23
|
+
ref: 'main',
|
|
24
|
+
outputDir: 'assert-json-body',
|
|
25
|
+
preserveCheckout: false,
|
|
26
|
+
dryRun: false,
|
|
27
|
+
logLevel: 'info',
|
|
28
|
+
failIfExists: false
|
|
29
|
+
},
|
|
30
|
+
validate: {
|
|
31
|
+
recordResponses: false,
|
|
32
|
+
throwOnValidationFail: true
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
writeFileSync(path, JSON.stringify(example, null, 2));
|
|
36
|
+
console.log(`Wrote example config to ${path}`);
|
|
37
|
+
// Idempotently add npm script to consumer package.json if exists
|
|
38
|
+
const pkgPath = 'package.json';
|
|
39
|
+
if (existsSync(pkgPath)) {
|
|
40
|
+
try {
|
|
41
|
+
const raw = readFileSync(pkgPath, 'utf8');
|
|
42
|
+
const pkg = JSON.parse(raw);
|
|
43
|
+
pkg.scripts = pkg.scripts || {};
|
|
44
|
+
if (pkg.scripts['responses:regenerate'] !== 'assert-json-body extract') {
|
|
45
|
+
pkg.scripts['responses:regenerate'] = 'assert-json-body extract';
|
|
46
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
47
|
+
console.log('Added script "responses:regenerate" to package.json');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
console.log('Script "responses:regenerate" already present in package.json');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
console.warn('Could not update package.json with responses:regenerate script:', e.message);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function run() {
|
|
59
|
+
const { command, args } = parseCliArgs();
|
|
60
|
+
const baseCommand = command || 'extract';
|
|
61
|
+
if (args.help || baseCommand === 'help')
|
|
62
|
+
return printHelp();
|
|
63
|
+
if (args.version || baseCommand === 'version' || args.v)
|
|
64
|
+
return printVersion();
|
|
65
|
+
if (baseCommand === 'init-config')
|
|
66
|
+
return initConfig();
|
|
67
|
+
if (baseCommand !== 'extract') {
|
|
68
|
+
console.error(`Unknown command: ${baseCommand}`);
|
|
69
|
+
printHelp();
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const cfgPath = typeof args.config === 'string' ? String(args.config) : undefined;
|
|
73
|
+
buildConfig(cfgPath);
|
|
74
|
+
const cliOverrides = cliConfigSubset(args);
|
|
75
|
+
try {
|
|
76
|
+
await generate(cliOverrides);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
console.error('[assert-json-body] extract failed:', err);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
run();
|
|
84
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGlE,SAAS,YAAY;IACnB,iEAAiE;IACjE,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC,ipCAAipC,CAAC,CAAC;AACjqC,CAAC;AAED,SAAS,UAAU;IACjB,MAAM,IAAI,GAAG,8BAA8B,CAAC;IAC5C,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,OAAO,GAAG;QACd,OAAO,EAAE;YACP,IAAI,EAAE,8DAA8D;YACpE,QAAQ,EAAE,4BAA4B;YACtC,GAAG,EAAE,MAAM;YACX,SAAS,EAAE,kBAAkB;YAC7B,gBAAgB,EAAE,KAAK;YACvB,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,MAAM;YAChB,YAAY,EAAE,KAAK;SACpB;QACD,QAAQ,EAAE;YACR,eAAe,EAAE,KAAK;YACtB,qBAAqB,EAAE,IAAI;SAC5B;KACO,CAAC;IACX,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IAE/C,iEAAiE;IACjE,MAAM,OAAO,GAAG,cAAc,CAAC;IAC/B,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5B,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC,KAAK,0BAA0B,EAAE,CAAC;gBACvE,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC,GAAG,0BAA0B,CAAC;gBACjE,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBACrD,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,iEAAiE,EAAG,CAAW,CAAC,OAAO,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,YAAY,EAAE,CAAC;IACzC,MAAM,WAAW,GAAG,OAAO,IAAI,SAAS,CAAC;IACzC,IAAI,IAAI,CAAC,IAAI,IAAI,WAAW,KAAK,MAAM;QAAE,OAAO,SAAS,EAAE,CAAC;IAC5D,IAAI,IAAI,CAAC,OAAO,IAAI,WAAW,KAAK,SAAS,IAAI,IAAI,CAAC,CAAC;QAAE,OAAO,YAAY,EAAE,CAAC;IAC/E,IAAI,WAAW,KAAK,aAAa;QAAE,OAAO,UAAU,EAAE,CAAC;IACvD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC;QACjD,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClF,WAAW,CAAC,OAAO,CAAC,CAAC;IACrB,MAAM,YAAY,GAAkB,eAAe,CAAC,IAAqC,CAAC,CAAC;IAC3F,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SchemaGroup as OutputSchema } from '../../../types/index.js';
|
|
2
|
+
import { SchemaOrRef } from './schema-flatten.js';
|
|
3
|
+
export declare function buildSchemaTree(schema: SchemaOrRef, components: Record<string, SchemaOrRef>, seen?: Set<string>): OutputSchema;
|
|
4
|
+
export declare function resolveFieldSchema(fieldName: string, parentSchema: SchemaOrRef, components: Record<string, SchemaOrRef>): {
|
|
5
|
+
kind: string;
|
|
6
|
+
target?: SchemaOrRef;
|
|
7
|
+
} | null;
|
|
8
|
+
//# sourceMappingURL=child-expansion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"child-expansion.d.ts","sourceRoot":"","sources":["../../../../src/extractor/src/lib/child-expansion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAW,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAG3D,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,cAAoB,GAAG,YAAY,CAgBpI;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GAAG,IAAI,CAuCvK"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { refNameOf } from './type-utils.js';
|
|
2
|
+
import { flatten } from './schema-flatten.js';
|
|
3
|
+
export function buildSchemaTree(schema, components, seen = new Set()) {
|
|
4
|
+
const flat = flatten(schema, components, seen);
|
|
5
|
+
for (const group of [flat.required, flat.optional]) {
|
|
6
|
+
for (const field of group) {
|
|
7
|
+
const resolved = resolveFieldSchema(field.name, schema, components);
|
|
8
|
+
if (resolved) {
|
|
9
|
+
const { kind, target } = resolved;
|
|
10
|
+
if ((kind === 'object' || kind === 'array-object') && target) {
|
|
11
|
+
field.children = buildSchemaTree(target, components, new Set(seen));
|
|
12
|
+
}
|
|
13
|
+
else if (kind === 'ref-object' && target) {
|
|
14
|
+
field.children = buildSchemaTree(target, components, new Set(seen.add(refNameOf(field.type))));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return flat;
|
|
20
|
+
}
|
|
21
|
+
export function resolveFieldSchema(fieldName, parentSchema, components) {
|
|
22
|
+
const isRef = (s) => '$ref' in s;
|
|
23
|
+
const isSchemaObject = (s) => !('$ref' in s);
|
|
24
|
+
const visited = new Set();
|
|
25
|
+
const propertyDefs = {};
|
|
26
|
+
const collect = (sch) => {
|
|
27
|
+
if (!sch)
|
|
28
|
+
return;
|
|
29
|
+
if (isRef(sch)) {
|
|
30
|
+
const refName = sch.$ref.split('/').pop();
|
|
31
|
+
if (visited.has(refName))
|
|
32
|
+
return;
|
|
33
|
+
visited.add(refName);
|
|
34
|
+
const target = components[refName];
|
|
35
|
+
if (target)
|
|
36
|
+
collect(target);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (isSchemaObject(sch) && sch.allOf)
|
|
40
|
+
for (const part of sch.allOf)
|
|
41
|
+
collect(part);
|
|
42
|
+
if (isSchemaObject(sch) && sch.properties)
|
|
43
|
+
Object.assign(propertyDefs, sch.properties);
|
|
44
|
+
};
|
|
45
|
+
collect(parentSchema);
|
|
46
|
+
const propSchema = propertyDefs[fieldName];
|
|
47
|
+
if (!propSchema)
|
|
48
|
+
return null;
|
|
49
|
+
if (isRef(propSchema)) {
|
|
50
|
+
const refName = propSchema.$ref.split('/').pop();
|
|
51
|
+
const target = components[refName];
|
|
52
|
+
if (target && isSchemaObject(target) && (target.type === 'object' || target.properties || target.allOf))
|
|
53
|
+
return { kind: 'ref-object', target };
|
|
54
|
+
return { kind: 'ref' };
|
|
55
|
+
}
|
|
56
|
+
if (propSchema.type === 'object' || propSchema.properties || propSchema.allOf)
|
|
57
|
+
return { kind: 'object', target: propSchema };
|
|
58
|
+
if (propSchema.type === 'array' && propSchema.items) {
|
|
59
|
+
const it = propSchema.items;
|
|
60
|
+
if (isRef(it)) {
|
|
61
|
+
const refName = it.$ref.split('/').pop();
|
|
62
|
+
const target = components[refName];
|
|
63
|
+
if (target && isSchemaObject(target) && (target.type === 'object' || target.properties || target.allOf))
|
|
64
|
+
return { kind: 'array-object', target };
|
|
65
|
+
}
|
|
66
|
+
else if (it.type === 'object' || it.properties || it.allOf) {
|
|
67
|
+
return { kind: 'array-object', target: it };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=child-expansion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"child-expansion.js","sourceRoot":"","sources":["../../../../src/extractor/src/lib/child-expansion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function run(cmd: string, args: string[], opts?: {
|
|
2
|
+
inherit?: boolean;
|
|
3
|
+
}): string;
|
|
4
|
+
export declare function sparseCheckout(repo: string, specPath: string, ref?: string): {
|
|
5
|
+
workdir: string;
|
|
6
|
+
commit: string;
|
|
7
|
+
specContent: string;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../../src/extractor/src/lib/git.ts"],"names":[],"mappings":"AAKA,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,UAIhF;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAUrI"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
export function run(cmd, args, opts = {}) {
|
|
6
|
+
const res = spawnSync(cmd, args, { stdio: opts.inherit ? 'inherit' : 'pipe', encoding: 'utf8' });
|
|
7
|
+
if (res.status !== 0)
|
|
8
|
+
throw new Error(`${cmd} ${args.join(' ')} failed: ${res.stderr || res.status}`);
|
|
9
|
+
return res.stdout;
|
|
10
|
+
}
|
|
11
|
+
export function sparseCheckout(repo, specPath, ref = 'main') {
|
|
12
|
+
const workdir = join(tmpdir(), `spec-checkout-${Date.now()}`);
|
|
13
|
+
run('git', ['init', workdir]);
|
|
14
|
+
run('git', ['-C', workdir, 'remote', 'add', '-f', 'origin', repo]);
|
|
15
|
+
run('git', ['-C', workdir, 'config', 'core.sparseCheckout', 'true']);
|
|
16
|
+
writeFileSync(join(workdir, '.git', 'info', 'sparse-checkout'), specPath + '\n');
|
|
17
|
+
run('git', ['-C', workdir, 'pull', 'origin', ref]);
|
|
18
|
+
const commit = run('git', ['-C', workdir, 'rev-parse', 'HEAD']).trim();
|
|
19
|
+
const specContent = readFileSync(join(workdir, specPath), 'utf8');
|
|
20
|
+
return { workdir, commit, specContent };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../../src/extractor/src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,IAAc,EAAE,OAA8B,EAAE;IAC/E,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACjG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACtG,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,QAAgB,EAAE,GAAG,GAAG,MAAM;IACzE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC9D,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9B,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IACnE,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC;IACrE,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAC;IACjF,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACvE,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;IAClE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FieldSpec, FlattenResult, SchemaGroup as OutputSchema } from '../../../types/index.js';
|
|
2
|
+
import { OpenAPIV3 } from 'openapi-types';
|
|
3
|
+
export type SchemaOrRef = OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject;
|
|
4
|
+
export declare function flatten(schema: SchemaOrRef, components: Record<string, SchemaOrRef>, seen?: Set<string>): OutputSchema;
|
|
5
|
+
export declare function flattenInternal(schema: SchemaOrRef, components: Record<string, SchemaOrRef>, seen?: Set<string>): FlattenResult;
|
|
6
|
+
export declare function describeType(schema: SchemaOrRef | undefined, components: Record<string, SchemaOrRef>, stack?: string[]): string;
|
|
7
|
+
export declare function deriveFieldMetadata(schema: SchemaOrRef, components: Record<string, SchemaOrRef>): Partial<FieldSpec>;
|
|
8
|
+
export declare function isObjectLike(s: SchemaOrRef | undefined | null): boolean;
|
|
9
|
+
export declare function primitiveFromSchema(schema: SchemaOrRef | undefined, components: Record<string, SchemaOrRef>, stack: string[]): string | null;
|
|
10
|
+
//# sourceMappingURL=schema-flatten.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-flatten.d.ts","sourceRoot":"","sources":["../../../../src/extractor/src/lib/schema-flatten.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEhG,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG1C,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,YAAY,GAAG,SAAS,CAAC,eAAe,CAAC;AAM7E,wBAAgB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,cAAoB,GAAG,YAAY,CAG5H;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,cAAoB,GAAG,aAAa,CAkDrI;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,MAAM,CAoCnI;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CA2CpH;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAIvE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CA2B5I"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { normalizeType, dedupeFields } from './type-utils.js';
|
|
2
|
+
function isRef(s) { return !!s && '$ref' in s; }
|
|
3
|
+
function isSchemaObject(s) { return !!s && !('$ref' in s); }
|
|
4
|
+
// Functions here are extracted from original single-file implementation for clarity and testability.
|
|
5
|
+
export function flatten(schema, components, seen = new Set()) {
|
|
6
|
+
const { required, optional } = flattenInternal(schema, components, seen);
|
|
7
|
+
return { required, optional };
|
|
8
|
+
}
|
|
9
|
+
export function flattenInternal(schema, components, seen = new Set()) {
|
|
10
|
+
if (isRef(schema)) {
|
|
11
|
+
const ref = schema.$ref.split('/').pop();
|
|
12
|
+
if (seen.has(ref))
|
|
13
|
+
return { required: [], optional: [] };
|
|
14
|
+
seen.add(ref);
|
|
15
|
+
const target = components[ref];
|
|
16
|
+
if (!target)
|
|
17
|
+
return { required: [], optional: [] };
|
|
18
|
+
return flattenInternal(target, components, seen);
|
|
19
|
+
}
|
|
20
|
+
let reqFields = [];
|
|
21
|
+
let optFields = [];
|
|
22
|
+
const expand = (sch, acc, refSeen) => {
|
|
23
|
+
if (!sch)
|
|
24
|
+
return;
|
|
25
|
+
if (isRef(sch)) {
|
|
26
|
+
const name = sch.$ref.split('/').pop();
|
|
27
|
+
if (refSeen.has(name))
|
|
28
|
+
return;
|
|
29
|
+
refSeen.add(name);
|
|
30
|
+
const target = components[name];
|
|
31
|
+
if (target)
|
|
32
|
+
expand(target, acc, refSeen);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (sch.allOf)
|
|
36
|
+
for (const part of sch.allOf)
|
|
37
|
+
expand(part, acc, refSeen);
|
|
38
|
+
if (isSchemaObject(sch))
|
|
39
|
+
acc.push(sch);
|
|
40
|
+
};
|
|
41
|
+
const directSchemas = [];
|
|
42
|
+
expand(schema, directSchemas, new Set());
|
|
43
|
+
const collectedRequired = new Set();
|
|
44
|
+
const collectedProps = {};
|
|
45
|
+
for (const s of directSchemas) {
|
|
46
|
+
for (const r of (s.required || []))
|
|
47
|
+
collectedRequired.add(r);
|
|
48
|
+
if (s.properties)
|
|
49
|
+
Object.assign(collectedProps, s.properties);
|
|
50
|
+
}
|
|
51
|
+
for (const [prop, propSchema] of Object.entries(collectedProps)) {
|
|
52
|
+
const metadata = deriveFieldMetadata(propSchema, components);
|
|
53
|
+
const rawType = describeType(propSchema, components);
|
|
54
|
+
const spec = {
|
|
55
|
+
name: prop,
|
|
56
|
+
type: normalizeType(rawType),
|
|
57
|
+
...metadata,
|
|
58
|
+
};
|
|
59
|
+
if (collectedRequired.has(prop))
|
|
60
|
+
reqFields.push(spec);
|
|
61
|
+
else
|
|
62
|
+
optFields.push(spec);
|
|
63
|
+
}
|
|
64
|
+
reqFields = dedupeFields(reqFields);
|
|
65
|
+
optFields = dedupeFields(optFields.filter(f => !reqFields.some(r => r.name === f.name)));
|
|
66
|
+
return { required: reqFields, optional: optFields };
|
|
67
|
+
}
|
|
68
|
+
export function describeType(schema, components, stack = []) {
|
|
69
|
+
if (!schema)
|
|
70
|
+
return 'unknown';
|
|
71
|
+
if (isRef(schema)) {
|
|
72
|
+
const ref = schema.$ref.split('/').pop();
|
|
73
|
+
const target = components[ref];
|
|
74
|
+
if (!target)
|
|
75
|
+
return ref;
|
|
76
|
+
const prim = primitiveFromSchema(target, components, [...stack, ref]);
|
|
77
|
+
return prim ?? ref;
|
|
78
|
+
}
|
|
79
|
+
if (schema.type === 'array') {
|
|
80
|
+
const items = schema.items;
|
|
81
|
+
return `array<${normalizeType(describeType(items, components, stack))}>`;
|
|
82
|
+
}
|
|
83
|
+
if (schema.allOf) {
|
|
84
|
+
const primCandidates = schema.allOf
|
|
85
|
+
.map((s) => primitiveFromSchema(s, components, stack))
|
|
86
|
+
.filter((t) => !!t && t !== 'object');
|
|
87
|
+
const unique = [...new Set(primCandidates)];
|
|
88
|
+
if (unique.length === 1)
|
|
89
|
+
return unique[0];
|
|
90
|
+
const hasObject = schema.allOf.some((s) => isObjectLike(s));
|
|
91
|
+
if (hasObject)
|
|
92
|
+
return 'object';
|
|
93
|
+
}
|
|
94
|
+
if (schema.type === 'object' || schema.properties)
|
|
95
|
+
return 'object';
|
|
96
|
+
if (schema.type) {
|
|
97
|
+
if (schema.type === 'string')
|
|
98
|
+
return 'string';
|
|
99
|
+
return schema.format ? `${schema.type}(${schema.format})` : schema.type;
|
|
100
|
+
}
|
|
101
|
+
if (schema.oneOf) {
|
|
102
|
+
const branches = schema.oneOf.map((s) => normalizeType(describeType(s, components, stack)));
|
|
103
|
+
return branches.join('|');
|
|
104
|
+
}
|
|
105
|
+
if (schema.anyOf) {
|
|
106
|
+
const branches = schema.anyOf.map((s) => normalizeType(describeType(s, components, stack)));
|
|
107
|
+
return branches.join('|');
|
|
108
|
+
}
|
|
109
|
+
return 'unknown';
|
|
110
|
+
}
|
|
111
|
+
export function deriveFieldMetadata(schema, components) {
|
|
112
|
+
const meta = {};
|
|
113
|
+
const collectEnum = (sch) => {
|
|
114
|
+
if (!sch)
|
|
115
|
+
return undefined;
|
|
116
|
+
if (isSchemaObject(sch) && Array.isArray(sch.enum))
|
|
117
|
+
return sch.enum.map((v) => String(v));
|
|
118
|
+
if (isSchemaObject(sch) && sch.allOf) {
|
|
119
|
+
const enums = sch.allOf
|
|
120
|
+
.map((p) => collectEnum(p))
|
|
121
|
+
.filter((e) => Array.isArray(e));
|
|
122
|
+
if (enums.length)
|
|
123
|
+
return [...new Set(enums.flat())];
|
|
124
|
+
}
|
|
125
|
+
return undefined;
|
|
126
|
+
};
|
|
127
|
+
const detectWrapper = (refName, target) => {
|
|
128
|
+
if (!target)
|
|
129
|
+
return {};
|
|
130
|
+
const enumValues = collectEnum(target);
|
|
131
|
+
const underlyingPrim = primitiveFromSchema(target, components, [refName]);
|
|
132
|
+
const isPrimitiveLike = !!underlyingPrim && !(isSchemaObject(target) && (target.properties || target.type === 'object'));
|
|
133
|
+
return {
|
|
134
|
+
underlying: underlyingPrim ? normalizeType(underlyingPrim) : undefined,
|
|
135
|
+
wrapper: !!underlyingPrim && isPrimitiveLike,
|
|
136
|
+
enumValues,
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
if (isRef(schema)) {
|
|
140
|
+
const ref = schema.$ref.split('/').pop();
|
|
141
|
+
const target = components[ref];
|
|
142
|
+
const { underlying, wrapper, enumValues } = detectWrapper(ref, target);
|
|
143
|
+
if (enumValues?.length)
|
|
144
|
+
meta.enumValues = enumValues;
|
|
145
|
+
if (wrapper && underlying)
|
|
146
|
+
meta.underlyingPrimitive = underlying;
|
|
147
|
+
meta.rawRefName = ref;
|
|
148
|
+
if (wrapper)
|
|
149
|
+
meta.wrapper = true;
|
|
150
|
+
return meta;
|
|
151
|
+
}
|
|
152
|
+
if (schema.allOf) {
|
|
153
|
+
const enumValues = collectEnum(schema);
|
|
154
|
+
if (enumValues?.length)
|
|
155
|
+
meta.enumValues = enumValues;
|
|
156
|
+
}
|
|
157
|
+
else if (isSchemaObject(schema) && schema.enum) {
|
|
158
|
+
meta.enumValues = schema.enum.map((v) => String(v));
|
|
159
|
+
}
|
|
160
|
+
return meta;
|
|
161
|
+
}
|
|
162
|
+
export function isObjectLike(s) {
|
|
163
|
+
if (!s)
|
|
164
|
+
return false;
|
|
165
|
+
if (isRef(s))
|
|
166
|
+
return false; // handled elsewhere
|
|
167
|
+
return !!(s.type === 'object' || s.properties || s.allOf);
|
|
168
|
+
}
|
|
169
|
+
export function primitiveFromSchema(schema, components, stack) {
|
|
170
|
+
if (!schema)
|
|
171
|
+
return null;
|
|
172
|
+
if (isRef(schema)) {
|
|
173
|
+
const ref = schema.$ref.split('/').pop();
|
|
174
|
+
if (stack.includes(ref))
|
|
175
|
+
return ref; // cycle guard returns ref name
|
|
176
|
+
const target = components[ref];
|
|
177
|
+
if (!target)
|
|
178
|
+
return ref;
|
|
179
|
+
const rec = primitiveFromSchema(target, components, [...stack, ref]);
|
|
180
|
+
return rec ?? ref;
|
|
181
|
+
}
|
|
182
|
+
if (schema.allOf) {
|
|
183
|
+
const parts = schema.allOf.map((p) => primitiveFromSchema(p, components, stack)).filter(Boolean);
|
|
184
|
+
const uniq = [...new Set(parts)];
|
|
185
|
+
if (uniq.length === 1)
|
|
186
|
+
return uniq[0];
|
|
187
|
+
const bases = [...new Set(uniq.map(u => u.split('(')[0]))];
|
|
188
|
+
if (bases.length === 1) {
|
|
189
|
+
const withFormat = uniq.filter(u => u.includes('('));
|
|
190
|
+
if (withFormat.length === 1)
|
|
191
|
+
return withFormat[0];
|
|
192
|
+
return uniq.sort((a, b) => b.length - a.length)[0];
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
if (schema.type && schema.type !== 'object' && !schema.properties && schema.items === undefined) {
|
|
197
|
+
if (schema.type === 'string')
|
|
198
|
+
return 'string';
|
|
199
|
+
return schema.format ? `${schema.type}(${schema.format})` : schema.type;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=schema-flatten.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-flatten.js","sourceRoot":"","sources":["../../../../src/extractor/src/lib/schema-flatten.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK9D,SAAS,KAAK,CAAC,CAAiC,IAAoC,OAAO,CAAC,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;AAChH,SAAS,cAAc,CAAC,CAAiC,IAAiC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzH,qGAAqG;AAErG,MAAM,UAAU,OAAO,CAAC,MAAmB,EAAE,UAAuC,EAAE,OAAO,IAAI,GAAG,EAAU;IAC5G,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IACzE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAmB,EAAE,UAAuC,EAAE,OAAO,IAAI,GAAG,EAAU;IACpH,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC;QAC1C,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACzD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACnD,OAAO,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,SAAS,GAAgB,EAAE,CAAC;IAChC,IAAI,SAAS,GAAgB,EAAE,CAAC;IAEhC,MAAM,MAAM,GAAG,CAAC,GAA4B,EAAE,GAA6B,EAAE,OAAoB,EAAE,EAAE;QACnG,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC;YACxC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO;YAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClB,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,MAAM;gBAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,KAAK;YAAE,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAsB;gBAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACzF,IAAI,cAAc,CAAC,GAAG,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC;IAEF,MAAM,aAAa,GAA6B,EAAE,CAAC;IACnD,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,GAAG,EAAU,CAAC,CAAC;IAEjD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,MAAM,cAAc,GAAgC,EAAE,CAAC;IACvD,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC;YAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,CAAC,UAAU;YAAE,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAc,cAAc,CAAC,EAAE,CAAC;QAC7E,MAAM,QAAQ,GAAG,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACrD,MAAM,IAAI,GAAc;YACtB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC;YAC5B,GAAG,QAAQ;SACZ,CAAC;QACF,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnF,CAAC;IAED,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACpC,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAA+B,EAAE,UAAuC,EAAE,QAAkB,EAAE;IACzH,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC;QAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC;QACxB,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QACtE,OAAO,IAAI,IAAI,GAAG,CAAC;IACrB,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAI,MAAsC,CAAC,KAAgC,CAAC;QACvF,OAAO,SAAS,aAAa,CAAC,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC;IAC3E,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,cAAc,GAAc,MAAM,CAAC,KAAuB;aAC7D,GAAG,CAAC,CAAC,CAAC,EAAC,EAAE,CAAA,mBAAmB,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;aACnD,MAAM,CAAC,CAAC,CAAgB,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC;QACpE,MAAM,MAAM,GAAa,CAAC,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;QACtD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAI,MAAM,CAAC,KAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,EAAE,CAAA,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,IAAI,SAAS;YAAE,OAAO,QAAQ,CAAC;IACjC,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,UAAU;QAAE,OAAO,QAAQ,CAAC;IACnE,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1E,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAI,MAAM,CAAC,KAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,EAAE,CAAA,aAAa,CAAC,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7G,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAI,MAAM,CAAC,KAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,EAAE,CAAA,aAAa,CAAC,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7G,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAmB,EAAE,UAAuC;IAC9F,MAAM,IAAI,GAAuB,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,CAAC,GAA4B,EAAwB,EAAE;QACzE,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACnG,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACrC,MAAM,KAAK,GAAI,GAAG,CAAC,KAAuB;iBACvC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;iBAC1B,MAAM,CAAC,CAAC,CAAuB,EAAiB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YACxE,IAAI,KAAK,CAAC,MAAM;gBAAE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAE,KAAoB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,MAA+B,EAAqE,EAAE;QAC5I,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,cAAc,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1E,MAAM,eAAe,GAAG,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC;QACzH,OAAO;YACL,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;YACtE,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,eAAe;YAC5C,UAAU;SACX,CAAC;IACJ,CAAC,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC;QAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvE,IAAI,UAAU,EAAE,MAAM;YAAE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QACrD,IAAI,OAAO,IAAI,UAAU;YAAE,IAAI,CAAC,mBAAmB,GAAG,UAAU,CAAC;QACjE,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,IAAI,OAAO;YAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,UAAU,EAAE,MAAM;YAAE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACvD,CAAC;SAAM,IAAI,cAAc,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAiC;IAC5D,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,IAAI,KAAK,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,oBAAoB;IAChD,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAA+B,EAAE,UAAuC,EAAE,KAAe;IAC3H,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC;QAC1C,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC,CAAC,+BAA+B;QACpE,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC;QACxB,MAAM,GAAG,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QACrE,OAAO,GAAG,IAAI,GAAG,CAAC;IACpB,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,KAAK,GAAI,MAAM,CAAC,KAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,EAAE,CAAA,mBAAmB,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;QAC9H,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YACrD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,EAAC,EAAE,CAAA,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,UAAU,IAAK,MAAsC,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjI,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|