@kubb/ast 5.12.8 → 5.13.1
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/dist/index.cjs +147 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -1
- package/dist/index.d.ts +67 -1
- package/dist/index.js +144 -19
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -195,6 +195,7 @@ const VISITOR_KEYS = {
|
|
|
195
195
|
"members",
|
|
196
196
|
"additionalProperties",
|
|
197
197
|
"patternProperties",
|
|
198
|
+
"propertyNames",
|
|
198
199
|
"rest"
|
|
199
200
|
],
|
|
200
201
|
Property: ["schema"],
|
|
@@ -241,24 +242,102 @@ function isNodeRecord(value) {
|
|
|
241
242
|
* // returns parameters, the request body, and responses
|
|
242
243
|
* ```
|
|
243
244
|
*/
|
|
244
|
-
function
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
function getChildren(node, recurse) {
|
|
246
|
+
if (node.kind === "Schema" && !recurse) return [];
|
|
247
|
+
const children = [];
|
|
248
|
+
visitChildNodes(node, (child) => {
|
|
249
|
+
children.push(child);
|
|
250
|
+
return false;
|
|
251
|
+
});
|
|
252
|
+
return children;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Visits each direct child node in the AST's traversal order.
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```ts
|
|
259
|
+
* forEachChild(operationNode, (child) => {
|
|
260
|
+
* console.log(child.kind)
|
|
261
|
+
* })
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
function forEachChild(node, visit) {
|
|
265
|
+
visitChildNodes(node, (child) => {
|
|
266
|
+
visit(child);
|
|
267
|
+
return false;
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function visitChildNodes(node, visit) {
|
|
271
|
+
const keys = VISITOR_KEYS[node.kind];
|
|
272
|
+
if (!keys) return false;
|
|
247
273
|
const record = node;
|
|
248
274
|
for (const key of keys) {
|
|
249
275
|
const value = record[key];
|
|
250
276
|
if (Array.isArray(value)) {
|
|
251
|
-
for (const item of value) if (isNode(item))
|
|
277
|
+
for (const item of value) if (isNode(item) && visit(item)) return true;
|
|
252
278
|
continue;
|
|
253
279
|
}
|
|
254
280
|
if (isNode(value)) {
|
|
255
|
-
|
|
281
|
+
if (visit(value)) return true;
|
|
256
282
|
continue;
|
|
257
283
|
}
|
|
258
|
-
if (isNodeRecord(value)) {
|
|
259
|
-
|
|
284
|
+
if (isNodeRecord(value)) for (const name in value) {
|
|
285
|
+
if (!Object.hasOwn(value, name)) continue;
|
|
286
|
+
const item = value[name];
|
|
287
|
+
if (isNode(item) && visit(item)) return true;
|
|
260
288
|
}
|
|
261
289
|
}
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Visits each schema in a node's child tree in depth-first order. Includes `node` when it is a schema.
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```ts
|
|
297
|
+
* forEachSchema(operationNode, (schema) => {
|
|
298
|
+
* console.log(schema.type)
|
|
299
|
+
* })
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
function forEachSchema(node, visit) {
|
|
303
|
+
const walk = (current) => {
|
|
304
|
+
if (current.kind === "Schema") visit(current);
|
|
305
|
+
forEachChild(current, walk);
|
|
306
|
+
};
|
|
307
|
+
walk(node);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Finds the first schema that matches `predicate` in depth-first order. Set `followRefs` to include resolved ref targets.
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```ts
|
|
314
|
+
* const firstString = findSchema(operationNode, {
|
|
315
|
+
* predicate: (schema) => schema.type === 'string',
|
|
316
|
+
* })
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
function findSchema(node, { predicate, followRefs = false }) {
|
|
320
|
+
const seen = followRefs ? /* @__PURE__ */ new WeakSet() : void 0;
|
|
321
|
+
const walk = (current) => {
|
|
322
|
+
if (current.kind === "Schema") {
|
|
323
|
+
if (predicate(current)) return current;
|
|
324
|
+
if (seen) {
|
|
325
|
+
if (seen.has(current)) return void 0;
|
|
326
|
+
seen.add(current);
|
|
327
|
+
if (current.type === "ref" && current.schema) {
|
|
328
|
+
const found = walk(current.schema);
|
|
329
|
+
if (found) return found;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
let found;
|
|
334
|
+
visitChildNodes(current, (child) => {
|
|
335
|
+
found = walk(child);
|
|
336
|
+
return found !== void 0;
|
|
337
|
+
});
|
|
338
|
+
if (found) return found;
|
|
339
|
+
};
|
|
340
|
+
return walk(node);
|
|
262
341
|
}
|
|
263
342
|
/**
|
|
264
343
|
* Runs the visitor callback that matches `node.kind` with the traversal
|
|
@@ -395,7 +474,15 @@ function* collectNode(node, visitor, recurse, parent) {
|
|
|
395
474
|
* ```
|
|
396
475
|
*/
|
|
397
476
|
function collectSync(node, options) {
|
|
398
|
-
|
|
477
|
+
const { depth, parent, ...visitor } = options;
|
|
478
|
+
const result = [];
|
|
479
|
+
collectInto(node, visitor, (depth ?? "deep") === "deep", parent, result);
|
|
480
|
+
return result;
|
|
481
|
+
}
|
|
482
|
+
function collectInto(node, visitor, recurse, parent, result) {
|
|
483
|
+
const v = applyVisitor(node, visitor, parent);
|
|
484
|
+
if (v != null) result.push(v);
|
|
485
|
+
for (const child of getChildren(node, recurse)) collectInto(child, visitor, recurse, node, result);
|
|
399
486
|
}
|
|
400
487
|
//#endregion
|
|
401
488
|
//#region src/defineMacro.ts
|
|
@@ -635,6 +722,33 @@ function resolveRefName(node) {
|
|
|
635
722
|
return node.name ?? node.schema?.name ?? null;
|
|
636
723
|
}
|
|
637
724
|
/**
|
|
725
|
+
* Follows a resolved ref chain to its target schema. Returns an unresolved or cyclic ref as is.
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* ```ts
|
|
729
|
+
* const target = resolveRef(refSchema)
|
|
730
|
+
* ```
|
|
731
|
+
*/
|
|
732
|
+
function resolveRef(node) {
|
|
733
|
+
if (node.type !== "ref" || !node.schema) return node;
|
|
734
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
735
|
+
let current = node;
|
|
736
|
+
while (current.type === "ref" && current.schema) {
|
|
737
|
+
if (seen.has(current)) return current;
|
|
738
|
+
seen.add(current);
|
|
739
|
+
current = current.schema;
|
|
740
|
+
}
|
|
741
|
+
return current;
|
|
742
|
+
}
|
|
743
|
+
/** Fields of a ref node that describe the ref itself, so they never override the resolved schema. */
|
|
744
|
+
const REF_OWN_KEYS = /* @__PURE__ */ new Set([
|
|
745
|
+
"kind",
|
|
746
|
+
"type",
|
|
747
|
+
"name",
|
|
748
|
+
"ref",
|
|
749
|
+
"schema"
|
|
750
|
+
]);
|
|
751
|
+
/**
|
|
638
752
|
* Merges a ref node with its resolved schema, giving the fields set at the usage site precedence.
|
|
639
753
|
*
|
|
640
754
|
* Every field on the ref except `kind`, `type`, `name`, `ref`, and `schema` overrides the same field
|
|
@@ -650,12 +764,12 @@ function resolveRefName(node) {
|
|
|
650
764
|
*/
|
|
651
765
|
function mergeRefWithSchema(node) {
|
|
652
766
|
if (!node.schema) return node;
|
|
653
|
-
const
|
|
654
|
-
const
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
767
|
+
const merged = { ...node.schema };
|
|
768
|
+
for (const key of Object.keys(node)) {
|
|
769
|
+
const value = node[key];
|
|
770
|
+
if (value !== void 0 && !REF_OWN_KEYS.has(key)) merged[key] = value;
|
|
771
|
+
}
|
|
772
|
+
return merged;
|
|
659
773
|
}
|
|
660
774
|
/**
|
|
661
775
|
* Returns `true` when a schema is a bare ref without modifiers, metadata, or omit keys.
|
|
@@ -1109,16 +1223,23 @@ function mergeByPath(result) {
|
|
|
1109
1223
|
return ({ node, names }) => {
|
|
1110
1224
|
const key = `${node.path}:${node.isTypeOnly ?? false}`;
|
|
1111
1225
|
const existing = byPath.get(key);
|
|
1112
|
-
if (existing
|
|
1113
|
-
|
|
1226
|
+
if (existing) {
|
|
1227
|
+
for (const name of names) {
|
|
1228
|
+
if (existing.seen.has(name)) continue;
|
|
1229
|
+
existing.seen.add(name);
|
|
1230
|
+
existing.names.push(name);
|
|
1231
|
+
}
|
|
1114
1232
|
return;
|
|
1115
1233
|
}
|
|
1116
1234
|
const item = {
|
|
1117
1235
|
...node,
|
|
1118
|
-
name: names
|
|
1236
|
+
name: [...names]
|
|
1119
1237
|
};
|
|
1120
1238
|
result.push(item);
|
|
1121
|
-
byPath.set(key,
|
|
1239
|
+
byPath.set(key, {
|
|
1240
|
+
names: item.name,
|
|
1241
|
+
seen: new Set(names)
|
|
1242
|
+
});
|
|
1122
1243
|
};
|
|
1123
1244
|
}
|
|
1124
1245
|
/**
|
|
@@ -1513,6 +1634,9 @@ var src_exports = /* @__PURE__ */ __exportAll({
|
|
|
1513
1634
|
factory: () => nodes_exports,
|
|
1514
1635
|
findCircularSchemas: () => findCircularSchemas,
|
|
1515
1636
|
findCircularSchemasFromGraph: () => findCircularSchemasFromGraph,
|
|
1637
|
+
findSchema: () => findSchema,
|
|
1638
|
+
forEachChild: () => forEachChild,
|
|
1639
|
+
forEachSchema: () => forEachSchema,
|
|
1516
1640
|
getSchemaLiteralValues: () => getSchemaLiteralValues,
|
|
1517
1641
|
inferDiscriminatorPropertyName: () => inferDiscriminatorPropertyName,
|
|
1518
1642
|
isBareRef: () => isBareRef,
|
|
@@ -1521,6 +1645,7 @@ var src_exports = /* @__PURE__ */ __exportAll({
|
|
|
1521
1645
|
narrowSchema: () => narrowSchema,
|
|
1522
1646
|
optionality: () => optionality,
|
|
1523
1647
|
refName: () => refName,
|
|
1648
|
+
resolveRef: () => resolveRef,
|
|
1524
1649
|
resolveRefName: () => resolveRefName,
|
|
1525
1650
|
resolveSchemaProperties: () => resolveSchemaProperties,
|
|
1526
1651
|
schemaTypes: () => schemaTypes,
|
|
@@ -1551,6 +1676,9 @@ Object.defineProperty(exports, "factory", {
|
|
|
1551
1676
|
});
|
|
1552
1677
|
exports.findCircularSchemas = findCircularSchemas;
|
|
1553
1678
|
exports.findCircularSchemasFromGraph = findCircularSchemasFromGraph;
|
|
1679
|
+
exports.findSchema = findSchema;
|
|
1680
|
+
exports.forEachChild = forEachChild;
|
|
1681
|
+
exports.forEachSchema = forEachSchema;
|
|
1554
1682
|
exports.getSchemaLiteralValues = getSchemaLiteralValues;
|
|
1555
1683
|
exports.inferDiscriminatorPropertyName = inferDiscriminatorPropertyName;
|
|
1556
1684
|
exports.isBareRef = isBareRef;
|
|
@@ -1559,6 +1687,7 @@ exports.mergeRefWithSchema = mergeRefWithSchema;
|
|
|
1559
1687
|
exports.narrowSchema = narrowSchema;
|
|
1560
1688
|
exports.optionality = optionality;
|
|
1561
1689
|
exports.refName = refName;
|
|
1690
|
+
exports.resolveRef = resolveRef;
|
|
1562
1691
|
exports.resolveRefName = resolveRefName;
|
|
1563
1692
|
exports.resolveSchemaProperties = resolveSchemaProperties;
|
|
1564
1693
|
exports.schemaTypes = schemaTypes;
|