@kubb/ast 5.0.0-beta.29 → 5.0.0-beta.30
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 +256 -211
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1041 -837
- package/dist/index.js +251 -212
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/dialect.ts +64 -0
- package/src/dispatch.ts +53 -0
- package/src/factory.ts +93 -6
- package/src/guards.ts +15 -0
- package/src/index.ts +6 -1
- package/src/nodes/base.ts +2 -0
- package/src/nodes/content.ts +37 -0
- package/src/nodes/index.ts +6 -2
- package/src/nodes/operation.ts +98 -62
- package/src/nodes/response.ts +2 -16
- package/src/types.ts +6 -0
- package/src/utils.ts +13 -6
- package/src/visitor.ts +140 -174
package/dist/index.js
CHANGED
|
@@ -201,6 +201,60 @@ const mediaTypes = {
|
|
|
201
201
|
videoMp4: "video/mp4"
|
|
202
202
|
};
|
|
203
203
|
//#endregion
|
|
204
|
+
//#region src/dialect.ts
|
|
205
|
+
/**
|
|
206
|
+
* Identity helper that types a {@link SchemaDialect} for an adapter. Like
|
|
207
|
+
* `defineParser`, it adds no runtime behavior — it pins the dialect's type for
|
|
208
|
+
* inference and gives adapter authors a discoverable anchor.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```ts
|
|
212
|
+
* export const oasDialect = defineSchemaDialect({
|
|
213
|
+
* name: 'oas',
|
|
214
|
+
* isNullable,
|
|
215
|
+
* isReference,
|
|
216
|
+
* isDiscriminator,
|
|
217
|
+
* isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',
|
|
218
|
+
* resolveRef,
|
|
219
|
+
* })
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
function defineSchemaDialect(dialect) {
|
|
223
|
+
return dialect;
|
|
224
|
+
}
|
|
225
|
+
//#endregion
|
|
226
|
+
//#region src/dispatch.ts
|
|
227
|
+
/**
|
|
228
|
+
* Walks an ordered list of {@link DispatchRule}s and returns the first node produced.
|
|
229
|
+
*
|
|
230
|
+
* This is the shared backbone for spec adapters (OpenAPI today, AsyncAPI and others later).
|
|
231
|
+
* The contract an adapter follows is intentionally minimal:
|
|
232
|
+
*
|
|
233
|
+
* context → [rule.match → rule.convert] → node
|
|
234
|
+
*
|
|
235
|
+
* An adapter derives a context from a source spec node, then declares an ordered table of
|
|
236
|
+
* rules mapping spec shapes onto Kubb AST nodes. To add support for a new spec, write a new
|
|
237
|
+
* context type and a new rules table — the traversal here is reused unchanged.
|
|
238
|
+
*
|
|
239
|
+
* Order is significant: earlier rules win, so list higher-precedence or more specific shapes
|
|
240
|
+
* first (e.g. composition keywords before plain `type`). A rule whose `match` returns `true`
|
|
241
|
+
* may still `convert` to `null` to defer to later rules. When no rule produces a node this
|
|
242
|
+
* returns `null`, leaving the caller to apply its own fallback.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* const node = dispatch(schemaRules, schemaContext) ?? createSchema({ type: fallbackType })
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
function dispatch(rules, context) {
|
|
250
|
+
for (const rule of rules) {
|
|
251
|
+
if (!rule.match(context)) continue;
|
|
252
|
+
const node = rule.convert(context);
|
|
253
|
+
if (node !== null && node !== void 0) return node;
|
|
254
|
+
}
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
//#endregion
|
|
204
258
|
//#region ../../internals/utils/src/casing.ts
|
|
205
259
|
/**
|
|
206
260
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -475,6 +529,19 @@ const isOutputNode = isKind("Output");
|
|
|
475
529
|
*/
|
|
476
530
|
const isOperationNode = isKind("Operation");
|
|
477
531
|
/**
|
|
532
|
+
* Narrows an `OperationNode` to an `HttpOperationNode`, guaranteeing `method` and `path`.
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```ts
|
|
536
|
+
* if (isHttpOperationNode(node)) {
|
|
537
|
+
* console.log(node.method, node.path)
|
|
538
|
+
* }
|
|
539
|
+
* ```
|
|
540
|
+
*/
|
|
541
|
+
function isHttpOperationNode(node) {
|
|
542
|
+
return node.protocol === "http" || node.method !== void 0 && node.path !== void 0;
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
478
545
|
* Returns `true` when the input is a `SchemaNode`.
|
|
479
546
|
*
|
|
480
547
|
* @example
|
|
@@ -537,58 +604,84 @@ function createLimit(concurrency) {
|
|
|
537
604
|
});
|
|
538
605
|
};
|
|
539
606
|
}
|
|
607
|
+
const visitorKeysByKind = {
|
|
608
|
+
Input: ["schemas", "operations"],
|
|
609
|
+
Operation: [
|
|
610
|
+
"parameters",
|
|
611
|
+
"requestBody",
|
|
612
|
+
"responses"
|
|
613
|
+
],
|
|
614
|
+
RequestBody: ["content"],
|
|
615
|
+
Content: ["schema"],
|
|
616
|
+
Response: ["content"],
|
|
617
|
+
Schema: [
|
|
618
|
+
"properties",
|
|
619
|
+
"items",
|
|
620
|
+
"members",
|
|
621
|
+
"additionalProperties"
|
|
622
|
+
],
|
|
623
|
+
Property: ["schema"],
|
|
624
|
+
Parameter: ["schema"]
|
|
625
|
+
};
|
|
540
626
|
/**
|
|
541
|
-
* Returns
|
|
627
|
+
* Returns `true` when `value` is an AST node (an object carrying a `kind`).
|
|
628
|
+
*/
|
|
629
|
+
function isNode(value) {
|
|
630
|
+
return typeof value === "object" && value !== null && "kind" in value;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Returns the immediate traversable children of `node` based on {@link VISITOR_KEYS}.
|
|
542
634
|
*
|
|
543
|
-
*
|
|
544
|
-
* `additionalProperties`) are only included
|
|
545
|
-
* when `recurse` is `true`; shallow mode skips them.
|
|
635
|
+
* `Schema` children are only included when `recurse` is `true`; shallow mode skips them.
|
|
546
636
|
*
|
|
547
637
|
* @example
|
|
548
638
|
* ```ts
|
|
549
639
|
* const children = getChildren(operationNode, true)
|
|
550
|
-
* // returns parameters,
|
|
640
|
+
* // returns parameters, the request body, and responses
|
|
551
641
|
* ```
|
|
552
642
|
*/
|
|
553
643
|
function* getChildren(node, recurse) {
|
|
554
|
-
if (node.kind === "
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
if (
|
|
563
|
-
for (const c of node.requestBody.content) if (c.schema) yield c.schema;
|
|
564
|
-
}
|
|
565
|
-
yield* node.responses;
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
if (node.kind === "Schema") {
|
|
569
|
-
if (!recurse) return;
|
|
570
|
-
if ("properties" in node && node.properties.length > 0) yield* node.properties;
|
|
571
|
-
if ("items" in node && node.items) yield* node.items;
|
|
572
|
-
if ("members" in node && node.members) yield* node.members;
|
|
573
|
-
if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) yield node.additionalProperties;
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
if (node.kind === "Property") {
|
|
577
|
-
yield node.schema;
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
if (node.kind === "Parameter") {
|
|
581
|
-
yield node.schema;
|
|
582
|
-
return;
|
|
583
|
-
}
|
|
584
|
-
if (node.kind === "Response") {
|
|
585
|
-
if (node.content) {
|
|
586
|
-
for (const c of node.content) if (c.schema) yield c.schema;
|
|
587
|
-
}
|
|
588
|
-
return;
|
|
644
|
+
if (node.kind === "Schema" && !recurse) return;
|
|
645
|
+
const keys = visitorKeysByKind[node.kind];
|
|
646
|
+
if (!keys) return;
|
|
647
|
+
const record = node;
|
|
648
|
+
for (const key of keys) {
|
|
649
|
+
const value = record[key];
|
|
650
|
+
if (Array.isArray(value)) {
|
|
651
|
+
for (const item of value) if (isNode(item)) yield item;
|
|
652
|
+
} else if (isNode(value)) yield value;
|
|
589
653
|
}
|
|
590
654
|
}
|
|
591
655
|
/**
|
|
656
|
+
* Maps a node `kind` to the matching visitor callback name. Only the seven
|
|
657
|
+
* traversable node kinds have an entry; every other kind resolves to
|
|
658
|
+
* `undefined` and is skipped.
|
|
659
|
+
*/
|
|
660
|
+
const VISITOR_KEY_BY_KIND = {
|
|
661
|
+
Input: "input",
|
|
662
|
+
Output: "output",
|
|
663
|
+
Operation: "operation",
|
|
664
|
+
Schema: "schema",
|
|
665
|
+
Property: "property",
|
|
666
|
+
Parameter: "parameter",
|
|
667
|
+
Response: "response"
|
|
668
|
+
};
|
|
669
|
+
/**
|
|
670
|
+
* Invokes the visitor callback that matches `node.kind`, passing the traversal
|
|
671
|
+
* context. Returns the callback's result (a replacement node, a collected
|
|
672
|
+
* value, or `undefined` when no callback is registered for the kind).
|
|
673
|
+
*
|
|
674
|
+
* Shared by `walk`, `transform`, and `collectLazy` so node-kind dispatch lives
|
|
675
|
+
* in one place. `TResult` is the caller's expected return: the same node type
|
|
676
|
+
* for `transform`, the collected value type for `collectLazy`, ignored for `walk`.
|
|
677
|
+
*/
|
|
678
|
+
function applyVisitor(node, visitor, parent) {
|
|
679
|
+
const key = VISITOR_KEY_BY_KIND[node.kind];
|
|
680
|
+
if (!key) return void 0;
|
|
681
|
+
const fn = visitor[key];
|
|
682
|
+
return fn?.(node, { parent });
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
592
685
|
* Async depth-first traversal for side effects. Visitor return values are
|
|
593
686
|
* ignored. Use `transform` when you want to rewrite nodes.
|
|
594
687
|
*
|
|
@@ -614,122 +707,63 @@ async function walk(node, options) {
|
|
|
614
707
|
return _walk(node, options, (options.depth ?? visitorDepths.deep) === visitorDepths.deep, createLimit(options.concurrency ?? 30), void 0);
|
|
615
708
|
}
|
|
616
709
|
async function _walk(node, visitor, recurse, limit, parent) {
|
|
617
|
-
|
|
618
|
-
case "Input":
|
|
619
|
-
await limit(() => visitor.input?.(node, { parent }));
|
|
620
|
-
break;
|
|
621
|
-
case "Output":
|
|
622
|
-
await limit(() => visitor.output?.(node, { parent }));
|
|
623
|
-
break;
|
|
624
|
-
case "Operation":
|
|
625
|
-
await limit(() => visitor.operation?.(node, { parent }));
|
|
626
|
-
break;
|
|
627
|
-
case "Schema":
|
|
628
|
-
await limit(() => visitor.schema?.(node, { parent }));
|
|
629
|
-
break;
|
|
630
|
-
case "Property":
|
|
631
|
-
await limit(() => visitor.property?.(node, { parent }));
|
|
632
|
-
break;
|
|
633
|
-
case "Parameter":
|
|
634
|
-
await limit(() => visitor.parameter?.(node, { parent }));
|
|
635
|
-
break;
|
|
636
|
-
case "Response":
|
|
637
|
-
await limit(() => visitor.response?.(node, { parent }));
|
|
638
|
-
break;
|
|
639
|
-
}
|
|
710
|
+
await limit(() => applyVisitor(node, visitor, parent));
|
|
640
711
|
const children = getChildren(node, recurse);
|
|
641
712
|
for (const child of children) await _walk(child, visitor, recurse, limit, node);
|
|
642
713
|
}
|
|
643
714
|
function transform(node, options) {
|
|
644
715
|
const { depth, parent, ...visitor } = options;
|
|
645
716
|
const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep;
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
}
|
|
691
|
-
return {
|
|
692
|
-
...schema,
|
|
693
|
-
..."properties" in schema && recurse ? { properties: schema.properties.map((p) => transform(p, childOptions)) } : {},
|
|
694
|
-
..."items" in schema && recurse ? { items: schema.items?.map((i) => transform(i, childOptions)) } : {},
|
|
695
|
-
..."members" in schema && recurse ? { members: schema.members?.map((m) => transform(m, childOptions)) } : {},
|
|
696
|
-
..."additionalProperties" in schema && recurse && schema.additionalProperties && schema.additionalProperties !== true ? { additionalProperties: transform(schema.additionalProperties, childOptions) } : {}
|
|
697
|
-
};
|
|
698
|
-
}
|
|
699
|
-
if (node.kind === "Property") {
|
|
700
|
-
const prop = visitor.property?.(node, { parent }) ?? node;
|
|
701
|
-
return createProperty({
|
|
702
|
-
...prop,
|
|
703
|
-
schema: transform(prop.schema, {
|
|
704
|
-
...options,
|
|
705
|
-
parent: prop
|
|
706
|
-
})
|
|
707
|
-
});
|
|
708
|
-
}
|
|
709
|
-
if (node.kind === "Parameter") {
|
|
710
|
-
const param = visitor.parameter?.(node, { parent }) ?? node;
|
|
711
|
-
return createParameter({
|
|
712
|
-
...param,
|
|
713
|
-
schema: transform(param.schema, {
|
|
714
|
-
...options,
|
|
715
|
-
parent: param
|
|
716
|
-
})
|
|
717
|
-
});
|
|
718
|
-
}
|
|
719
|
-
if (node.kind === "Response") {
|
|
720
|
-
const response = visitor.response?.(node, { parent }) ?? node;
|
|
721
|
-
return {
|
|
722
|
-
...response,
|
|
723
|
-
content: response.content?.map((entry) => ({
|
|
724
|
-
...entry,
|
|
725
|
-
schema: entry.schema ? transform(entry.schema, {
|
|
726
|
-
...options,
|
|
727
|
-
parent: response
|
|
728
|
-
}) : entry.schema
|
|
729
|
-
}))
|
|
730
|
-
};
|
|
717
|
+
const rebuilt = transformChildren(applyVisitor(node, visitor, parent) ?? node, options, recurse);
|
|
718
|
+
if (rebuilt === node) return node;
|
|
719
|
+
const finalize = nodeFinalizers[rebuilt.kind];
|
|
720
|
+
return finalize ? finalize(rebuilt) : rebuilt;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Per-kind builders rerun after children are rebuilt. `Property`/`Parameter`
|
|
724
|
+
* resync schema optionality against their `required` flag once the schema may
|
|
725
|
+
* have changed.
|
|
726
|
+
*/
|
|
727
|
+
const nodeFinalizers = {
|
|
728
|
+
Property: (node) => createProperty(node),
|
|
729
|
+
Parameter: (node) => createParameter(node)
|
|
730
|
+
};
|
|
731
|
+
/**
|
|
732
|
+
* Immutably rebuilds a node's children using {@link VISITOR_KEYS}, transforming
|
|
733
|
+
* each child node and leaving non-node values (e.g. `additionalProperties: true`) intact.
|
|
734
|
+
* `Schema` children are skipped in shallow mode.
|
|
735
|
+
*/
|
|
736
|
+
function transformChildren(node, options, recurse) {
|
|
737
|
+
if (node.kind === "Schema" && !recurse) return node;
|
|
738
|
+
const keys = visitorKeysByKind[node.kind];
|
|
739
|
+
if (!keys) return node;
|
|
740
|
+
const record = node;
|
|
741
|
+
const childOptions = {
|
|
742
|
+
...options,
|
|
743
|
+
parent: node
|
|
744
|
+
};
|
|
745
|
+
let updates;
|
|
746
|
+
for (const key of keys) {
|
|
747
|
+
if (!(key in record)) continue;
|
|
748
|
+
const value = record[key];
|
|
749
|
+
if (Array.isArray(value)) {
|
|
750
|
+
let changed = false;
|
|
751
|
+
const mapped = value.map((item) => {
|
|
752
|
+
if (!isNode(item)) return item;
|
|
753
|
+
const next = transform(item, childOptions);
|
|
754
|
+
if (next !== item) changed = true;
|
|
755
|
+
return next;
|
|
756
|
+
});
|
|
757
|
+
if (changed) (updates ??= {})[key] = mapped;
|
|
758
|
+
} else if (isNode(value)) {
|
|
759
|
+
const next = transform(value, childOptions);
|
|
760
|
+
if (next !== value) (updates ??= {})[key] = next;
|
|
761
|
+
}
|
|
731
762
|
}
|
|
732
|
-
return
|
|
763
|
+
return updates ? {
|
|
764
|
+
...node,
|
|
765
|
+
...updates
|
|
766
|
+
} : node;
|
|
733
767
|
}
|
|
734
768
|
/**
|
|
735
769
|
* Lazy depth-first collection pass. Yields every non-null value returned by
|
|
@@ -750,30 +784,7 @@ function transform(node, options) {
|
|
|
750
784
|
function* collectLazy(node, options) {
|
|
751
785
|
const { depth, parent, ...visitor } = options;
|
|
752
786
|
const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep;
|
|
753
|
-
|
|
754
|
-
switch (node.kind) {
|
|
755
|
-
case "Input":
|
|
756
|
-
v = visitor.input?.(node, { parent });
|
|
757
|
-
break;
|
|
758
|
-
case "Output":
|
|
759
|
-
v = visitor.output?.(node, { parent });
|
|
760
|
-
break;
|
|
761
|
-
case "Operation":
|
|
762
|
-
v = visitor.operation?.(node, { parent });
|
|
763
|
-
break;
|
|
764
|
-
case "Schema":
|
|
765
|
-
v = visitor.schema?.(node, { parent });
|
|
766
|
-
break;
|
|
767
|
-
case "Property":
|
|
768
|
-
v = visitor.property?.(node, { parent });
|
|
769
|
-
break;
|
|
770
|
-
case "Parameter":
|
|
771
|
-
v = visitor.parameter?.(node, { parent });
|
|
772
|
-
break;
|
|
773
|
-
case "Response":
|
|
774
|
-
v = visitor.response?.(node, { parent });
|
|
775
|
-
break;
|
|
776
|
-
}
|
|
787
|
+
const v = applyVisitor(node, visitor, parent);
|
|
777
788
|
if (v != null) yield v;
|
|
778
789
|
for (const child of getChildren(node, recurse)) yield* collectLazy(child, {
|
|
779
790
|
...options,
|
|
@@ -1135,6 +1146,16 @@ function combineSources(sources) {
|
|
|
1135
1146
|
return [...seen.values()];
|
|
1136
1147
|
}
|
|
1137
1148
|
/**
|
|
1149
|
+
* Merges `incoming` names into `existing`, preserving order and dropping duplicates.
|
|
1150
|
+
*
|
|
1151
|
+
* Shared by `combineExports` and `combineImports` for the same-path name-merge case.
|
|
1152
|
+
*/
|
|
1153
|
+
function mergeNameArrays(existing, incoming) {
|
|
1154
|
+
const merged = new Set(existing);
|
|
1155
|
+
for (const name of incoming) merged.add(name);
|
|
1156
|
+
return [...merged];
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1138
1159
|
* Deduplicates and merges `ExportNode` objects by path and type.
|
|
1139
1160
|
*
|
|
1140
1161
|
* Named exports with the same path and `isTypeOnly` flag have their names merged into a single export.
|
|
@@ -1155,11 +1176,8 @@ function combineExports(exports) {
|
|
|
1155
1176
|
if (!name.length) continue;
|
|
1156
1177
|
const key = pathTypeKey(path, isTypeOnly);
|
|
1157
1178
|
const existing = namedByPath.get(key);
|
|
1158
|
-
if (existing && Array.isArray(existing.name))
|
|
1159
|
-
|
|
1160
|
-
for (const n of name) merged.add(n);
|
|
1161
|
-
existing.name = [...merged];
|
|
1162
|
-
} else {
|
|
1179
|
+
if (existing && Array.isArray(existing.name)) existing.name = mergeNameArrays(existing.name, name);
|
|
1180
|
+
else {
|
|
1163
1181
|
const newItem = {
|
|
1164
1182
|
...curr,
|
|
1165
1183
|
name: [...new Set(name)]
|
|
@@ -1217,11 +1235,8 @@ function combineImports(imports, exports, source) {
|
|
|
1217
1235
|
if (!name.length) continue;
|
|
1218
1236
|
const key = pathTypeKey(path, isTypeOnly);
|
|
1219
1237
|
const existing = namedByPath.get(key);
|
|
1220
|
-
if (existing && Array.isArray(existing.name))
|
|
1221
|
-
|
|
1222
|
-
for (const n of name) merged.add(n);
|
|
1223
|
-
existing.name = [...merged];
|
|
1224
|
-
} else {
|
|
1238
|
+
if (existing && Array.isArray(existing.name)) existing.name = mergeNameArrays(existing.name, name);
|
|
1239
|
+
else {
|
|
1225
1240
|
const newItem = {
|
|
1226
1241
|
...curr,
|
|
1227
1242
|
name
|
|
@@ -1440,6 +1455,29 @@ function syncOptionality(schema, required) {
|
|
|
1440
1455
|
};
|
|
1441
1456
|
}
|
|
1442
1457
|
/**
|
|
1458
|
+
* Identity-preserving node update: returns `node` unchanged when every field in
|
|
1459
|
+
* `changes` already equals (by reference) the current value, otherwise a new node
|
|
1460
|
+
* with the changes applied.
|
|
1461
|
+
*
|
|
1462
|
+
* Mirrors the TypeScript compiler's `factory.updateX` contract — pair it with the
|
|
1463
|
+
* structural sharing in {@link transform} so a no-op rewrite doesn't allocate and
|
|
1464
|
+
* downstream passes can detect "nothing changed" by identity. Comparison is
|
|
1465
|
+
* shallow: a structurally-equal but newly-allocated array/object counts as a change.
|
|
1466
|
+
*
|
|
1467
|
+
* @example
|
|
1468
|
+
* ```ts
|
|
1469
|
+
* update(node, { name: node.name }) // -> same `node` reference
|
|
1470
|
+
* update(node, { name: 'renamed' }) // -> new node, `name` replaced
|
|
1471
|
+
* ```
|
|
1472
|
+
*/
|
|
1473
|
+
function update(node, changes) {
|
|
1474
|
+
for (const key in changes) if (changes[key] !== node[key]) return {
|
|
1475
|
+
...node,
|
|
1476
|
+
...changes
|
|
1477
|
+
};
|
|
1478
|
+
return node;
|
|
1479
|
+
}
|
|
1480
|
+
/**
|
|
1443
1481
|
* Creates an `InputNode` with stable defaults for `schemas` and `operations`.
|
|
1444
1482
|
*
|
|
1445
1483
|
* @example
|
|
@@ -1504,35 +1542,35 @@ function createOutput(overrides = {}) {
|
|
|
1504
1542
|
};
|
|
1505
1543
|
}
|
|
1506
1544
|
/**
|
|
1507
|
-
* Creates
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
*
|
|
1517
|
-
* ```
|
|
1518
|
-
*
|
|
1519
|
-
* @example
|
|
1520
|
-
* ```ts
|
|
1521
|
-
* const operation = createOperation({
|
|
1522
|
-
* operationId: 'findPets',
|
|
1523
|
-
* method: 'GET',
|
|
1524
|
-
* path: '/pet/findByStatus',
|
|
1525
|
-
* tags: ['pet'],
|
|
1526
|
-
* })
|
|
1527
|
-
* ```
|
|
1545
|
+
* Creates a `ContentNode` for a single request-body or response content type.
|
|
1546
|
+
*/
|
|
1547
|
+
function createContent(props) {
|
|
1548
|
+
return {
|
|
1549
|
+
...props,
|
|
1550
|
+
kind: "Content"
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
/**
|
|
1554
|
+
* Creates a `RequestBodyNode`, normalizing each content entry into a `ContentNode`.
|
|
1528
1555
|
*/
|
|
1556
|
+
function createRequestBody(props) {
|
|
1557
|
+
return {
|
|
1558
|
+
...props,
|
|
1559
|
+
kind: "RequestBody",
|
|
1560
|
+
content: props.content?.map(createContent)
|
|
1561
|
+
};
|
|
1562
|
+
}
|
|
1529
1563
|
function createOperation(props) {
|
|
1564
|
+
const { requestBody, ...rest } = props;
|
|
1565
|
+
const isHttp = rest.method !== void 0 && rest.path !== void 0;
|
|
1530
1566
|
return {
|
|
1531
1567
|
tags: [],
|
|
1532
1568
|
parameters: [],
|
|
1533
1569
|
responses: [],
|
|
1534
|
-
...
|
|
1535
|
-
|
|
1570
|
+
...rest,
|
|
1571
|
+
...isHttp ? { protocol: "http" } : {},
|
|
1572
|
+
kind: "Operation",
|
|
1573
|
+
requestBody: requestBody ? createRequestBody(requestBody) : void 0
|
|
1536
1574
|
};
|
|
1537
1575
|
}
|
|
1538
1576
|
/**
|
|
@@ -1660,14 +1698,15 @@ function createParameter(props) {
|
|
|
1660
1698
|
*/
|
|
1661
1699
|
function createResponse(props) {
|
|
1662
1700
|
const { schema, mediaType, keysToOmit, content, ...rest } = props;
|
|
1701
|
+
const entries = content ?? (schema ? [{
|
|
1702
|
+
contentType: mediaType ?? "application/json",
|
|
1703
|
+
schema,
|
|
1704
|
+
keysToOmit: keysToOmit ?? null
|
|
1705
|
+
}] : void 0);
|
|
1663
1706
|
return {
|
|
1664
1707
|
...rest,
|
|
1665
1708
|
kind: "Response",
|
|
1666
|
-
content:
|
|
1667
|
-
contentType: mediaType ?? "application/json",
|
|
1668
|
-
schema,
|
|
1669
|
-
keysToOmit: keysToOmit ?? null
|
|
1670
|
-
}] : void 0)
|
|
1709
|
+
content: entries?.map(createContent)
|
|
1671
1710
|
};
|
|
1672
1711
|
}
|
|
1673
1712
|
/**
|
|
@@ -2292,6 +2331,6 @@ function setEnumName(propNode, parentName, propName, enumSuffix) {
|
|
|
2292
2331
|
return propNode;
|
|
2293
2332
|
}
|
|
2294
2333
|
//#endregion
|
|
2295
|
-
export { caseParams, childName, collect, collectImports, collectLazy, collectReferencedSchemaNames, collectUsedSchemaNames, containsCircularRef, createArrowFunction, createBreak, createConst, createDiscriminantNode, createExport, createFile, createFunction, createFunctionParameter, createFunctionParameters, createImport, createInput, createJsx, createOperation, createOperationParams, createOutput, createParameter, createParameterGroup, createParamsType, createPrinterFactory, createProperty, createResponse, createSchema, createSource, createStreamInput, createText, createType, definePrinter, enumPropName, extractRefName, extractStringsFromNodes, findCircularSchemas, findDiscriminator, httpMethods, isInputNode, isOperationNode, isOutputNode, isScalarPrimitive, isSchemaNode, isStringType, mediaTypes, mergeAdjacentObjects, mergeAdjacentObjectsLazy, narrowSchema, nodeKinds, resolveRefName, schemaTypes, setDiscriminatorEnum, setEnumName, simplifyUnion, syncOptionality, syncSchemaRef, transform, walk };
|
|
2334
|
+
export { caseParams, childName, collect, collectImports, collectLazy, collectReferencedSchemaNames, collectUsedSchemaNames, containsCircularRef, createArrowFunction, createBreak, createConst, createContent, createDiscriminantNode, createExport, createFile, createFunction, createFunctionParameter, createFunctionParameters, createImport, createInput, createJsx, createOperation, createOperationParams, createOutput, createParameter, createParameterGroup, createParamsType, createPrinterFactory, createProperty, createRequestBody, createResponse, createSchema, createSource, createStreamInput, createText, createType, definePrinter, defineSchemaDialect, dispatch, enumPropName, extractRefName, extractStringsFromNodes, findCircularSchemas, findDiscriminator, httpMethods, isHttpOperationNode, isInputNode, isOperationNode, isOutputNode, isScalarPrimitive, isSchemaNode, isStringType, mediaTypes, mergeAdjacentObjects, mergeAdjacentObjectsLazy, narrowSchema, nodeKinds, resolveRefName, schemaTypes, setDiscriminatorEnum, setEnumName, simplifyUnion, syncOptionality, syncSchemaRef, transform, update, walk };
|
|
2296
2335
|
|
|
2297
2336
|
//# sourceMappingURL=index.js.map
|