@kubb/plugin-ts 5.0.0-alpha.23 → 5.0.0-alpha.25

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 CHANGED
@@ -25,11 +25,11 @@ let node_path = require("node:path");
25
25
  node_path = __toESM(node_path);
26
26
  let _kubb_fabric_core_parsers_typescript = require("@kubb/fabric-core/parsers/typescript");
27
27
  let _kubb_react_fabric = require("@kubb/react-fabric");
28
+ let _kubb_ast = require("@kubb/ast");
28
29
  let remeda = require("remeda");
29
30
  let typescript = require("typescript");
30
31
  typescript = __toESM(typescript);
31
32
  let _kubb_react_fabric_jsx_runtime = require("@kubb/react-fabric/jsx-runtime");
32
- let _kubb_ast = require("@kubb/ast");
33
33
  let _kubb_core = require("@kubb/core");
34
34
  //#region ../../internals/utils/src/casing.ts
35
35
  /**
@@ -200,6 +200,15 @@ const ENUM_TYPES_WITH_TYPE_ONLY = new Set([
200
200
  "literal",
201
201
  void 0
202
202
  ]);
203
+ /**
204
+ * Ordering priority for function parameters: lower = sorted earlier.
205
+ */
206
+ const PARAM_RANK = {
207
+ required: 0,
208
+ optional: 1,
209
+ withDefault: 2,
210
+ rest: 3
211
+ };
203
212
  //#endregion
204
213
  //#region src/factory.ts
205
214
  const { SyntaxKind, factory } = typescript.default;
@@ -288,7 +297,7 @@ function createInterfaceDeclaration({ modifiers, name, typeParameters, members }
288
297
  function createTypeDeclaration({ syntax, isExportable, comments, name, type }) {
289
298
  if (syntax === "interface" && "members" in type) return appendJSDocToNode({
290
299
  node: createInterfaceDeclaration({
291
- members: type.members,
300
+ members: [...type.members],
292
301
  modifiers: isExportable ? [modifiers.export] : [],
293
302
  name,
294
303
  typeParameters: void 0
@@ -421,64 +430,6 @@ const createFalse = factory.createFalse;
421
430
  factory.createIndexedAccessTypeNode;
422
431
  factory.createTypeOperatorNode;
423
432
  const createPrefixUnaryExpression = factory.createPrefixUnaryExpression;
424
- //#endregion
425
- //#region src/components/Enum.tsx
426
- /**
427
- * Resolves the runtime identifier name and the TypeScript type name for an enum schema node.
428
- *
429
- * The raw `node.name` may be a YAML key such as `"enumNames.Type"` which is not a
430
- * valid TypeScript identifier. The resolver normalizes it; for inline enum
431
- * properties the adapter already emits a PascalCase+suffix name so resolution is typically a no-op.
432
- */
433
- function getEnumNames({ node, enumType, enumTypeSuffix, resolver }) {
434
- const resolved = resolver.default(node.name, "type");
435
- return {
436
- enumName: enumType === "asPascalConst" ? resolved : camelCase(node.name),
437
- typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolved,
438
- refName: resolved
439
- };
440
- }
441
- /**
442
- * Renders the enum declaration(s) for a single named `EnumSchemaNode`.
443
- *
444
- * Depending on `enumType` this may emit:
445
- * - A runtime object (`asConst` / `asPascalConst`) plus a `typeof` type alias
446
- * - A `const enum` or plain `enum` declaration (`constEnum` / `enum`)
447
- * - A union literal type alias (`literal`)
448
- *
449
- * The emitted `File.Source` nodes carry the resolved names so that the barrel
450
- * index picks up the correct export identifiers.
451
- */
452
- function Enum({ node, enumType, enumTypeSuffix, enumKeyCasing, resolver }) {
453
- const { enumName, typeName } = getEnumNames({
454
- node,
455
- enumType,
456
- enumTypeSuffix,
457
- resolver
458
- });
459
- const [nameNode, typeNode] = createEnumDeclaration({
460
- name: enumName,
461
- typeName,
462
- enums: node.namedEnumValues?.map((v) => [trimQuotes(v.name.toString()), v.value]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
463
- type: enumType,
464
- enumKeyCasing
465
- });
466
- return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [nameNode && /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
467
- name: enumName,
468
- isExportable: true,
469
- isIndexable: true,
470
- isTypeOnly: false,
471
- children: (0, _kubb_fabric_core_parsers_typescript.safePrint)(nameNode)
472
- }), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
473
- name: typeName,
474
- isIndexable: true,
475
- isExportable: ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumType),
476
- isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumType),
477
- children: (0, _kubb_fabric_core_parsers_typescript.safePrint)(typeNode)
478
- })] });
479
- }
480
- //#endregion
481
- //#region src/printers/printerTs.ts
482
433
  /**
483
434
  * Converts a primitive const value to a TypeScript literal type node.
484
435
  * Handles negative numbers via a prefix unary expression.
@@ -524,28 +475,13 @@ function buildTupleNode(node, print) {
524
475
  */
525
476
  function buildPropertyType(schema, baseType, optionalType) {
526
477
  const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
478
+ const meta = (0, _kubb_ast.syncSchemaRef)(schema);
527
479
  let type = baseType;
528
- if (schema.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
529
- if ((schema.nullish || schema.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
480
+ if (meta.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
481
+ if ((meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
530
482
  return type;
531
483
  }
532
484
  /**
533
- * Collects JSDoc annotation strings (description, deprecated, min/max, pattern, default, example, type) for a schema node.
534
- */
535
- function buildPropertyJSDocComments(schema) {
536
- const isArray = schema.type === "array";
537
- return [
538
- "description" in schema && schema.description ? `@description ${jsStringEscape(schema.description)}` : void 0,
539
- "deprecated" in schema && schema.deprecated ? "@deprecated" : void 0,
540
- !isArray && "min" in schema && schema.min !== void 0 ? `@minLength ${schema.min}` : void 0,
541
- !isArray && "max" in schema && schema.max !== void 0 ? `@maxLength ${schema.max}` : void 0,
542
- "pattern" in schema && schema.pattern ? `@pattern ${schema.pattern}` : void 0,
543
- "default" in schema && schema.default !== void 0 ? `@default ${"primitive" in schema && schema.primitive === "string" ? stringify(schema.default) : schema.default}` : void 0,
544
- "example" in schema && schema.example !== void 0 ? `@example ${schema.example}` : void 0,
545
- "primitive" in schema && schema.primitive ? [`@type ${schema.primitive || "unknown"}`, "optional" in schema && schema.optional ? " | undefined" : void 0].filter(Boolean).join("") : void 0
546
- ];
547
- }
548
- /**
549
485
  * Creates TypeScript index signatures for `additionalProperties` and `patternProperties` on an object schema node.
550
486
  */
551
487
  function buildIndexSignatures(node, propertyCount, print) {
@@ -564,6 +500,194 @@ function buildIndexSignatures(node, propertyCount, print) {
564
500
  }
565
501
  return elements;
566
502
  }
503
+ //#endregion
504
+ //#region src/components/Enum.tsx
505
+ /**
506
+ * Resolves the runtime identifier name and the TypeScript type name for an enum schema node.
507
+ *
508
+ * The raw `node.name` may be a YAML key such as `"enumNames.Type"` which is not a
509
+ * valid TypeScript identifier. The resolver normalizes it; for inline enum
510
+ * properties the adapter already emits a PascalCase+suffix name so resolution is typically a no-op.
511
+ */
512
+ function getEnumNames({ node, enumType, enumTypeSuffix, resolver }) {
513
+ const resolved = resolver.default(node.name, "type");
514
+ return {
515
+ enumName: enumType === "asPascalConst" ? resolved : camelCase(node.name),
516
+ typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolved
517
+ };
518
+ }
519
+ /**
520
+ * Renders the enum declaration(s) for a single named `EnumSchemaNode`.
521
+ *
522
+ * Depending on `enumType` this may emit:
523
+ * - A runtime object (`asConst` / `asPascalConst`) plus a `typeof` type alias
524
+ * - A `const enum` or plain `enum` declaration (`constEnum` / `enum`)
525
+ * - A union literal type alias (`literal`)
526
+ *
527
+ * The emitted `File.Source` nodes carry the resolved names so that the barrel
528
+ * index picks up the correct export identifiers.
529
+ */
530
+ function Enum({ node, enumType, enumTypeSuffix, enumKeyCasing, resolver }) {
531
+ const { enumName, typeName } = getEnumNames({
532
+ node,
533
+ enumType,
534
+ enumTypeSuffix,
535
+ resolver
536
+ });
537
+ const [nameNode, typeNode] = createEnumDeclaration({
538
+ name: enumName,
539
+ typeName,
540
+ enums: node.namedEnumValues?.map((v) => [trimQuotes(v.name.toString()), v.value]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
541
+ type: enumType,
542
+ enumKeyCasing
543
+ });
544
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [nameNode && /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
545
+ name: enumName,
546
+ isExportable: true,
547
+ isIndexable: true,
548
+ isTypeOnly: false,
549
+ children: (0, _kubb_fabric_core_parsers_typescript.safePrint)(nameNode)
550
+ }), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
551
+ name: typeName,
552
+ isIndexable: true,
553
+ isExportable: ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumType),
554
+ isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumType),
555
+ children: (0, _kubb_fabric_core_parsers_typescript.safePrint)(typeNode)
556
+ })] });
557
+ }
558
+ //#endregion
559
+ //#region src/utils.ts
560
+ /**
561
+ * Collects JSDoc annotation strings for a schema node.
562
+ *
563
+ * Only uses official JSDoc tags from https://jsdoc.app/: `@description`, `@deprecated`, `@default`, `@example`, `@type`.
564
+ * Constraint metadata (min/max length, pattern, multipleOf, min/maxProperties) is emitted as plain-text lines.
565
+
566
+ */
567
+ function buildPropertyJSDocComments(schema) {
568
+ const meta = (0, _kubb_ast.syncSchemaRef)(schema);
569
+ const isArray = meta?.primitive === "array";
570
+ return [
571
+ meta && "description" in meta && meta.description ? `@description ${jsStringEscape(meta.description)}` : void 0,
572
+ meta && "deprecated" in meta && meta.deprecated ? "@deprecated" : void 0,
573
+ !isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : void 0,
574
+ !isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : void 0,
575
+ meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : void 0,
576
+ meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` : void 0,
577
+ meta && "example" in meta && meta.example !== void 0 ? `@example ${meta.example}` : void 0,
578
+ meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, "optional" in schema && schema.optional ? " | undefined" : void 0].filter(Boolean).join("") : void 0
579
+ ].filter(Boolean);
580
+ }
581
+ function buildParams(node, { params, resolver }) {
582
+ return (0, _kubb_ast.createSchema)({
583
+ type: "object",
584
+ properties: params.map((param) => (0, _kubb_ast.createProperty)({
585
+ name: param.name,
586
+ required: param.required,
587
+ schema: (0, _kubb_ast.createSchema)({
588
+ type: "ref",
589
+ name: resolver.resolveParamName(node, param)
590
+ })
591
+ }))
592
+ });
593
+ }
594
+ function buildData(node, { resolver }) {
595
+ const pathParams = node.parameters.filter((p) => p.in === "path");
596
+ const queryParams = node.parameters.filter((p) => p.in === "query");
597
+ const headerParams = node.parameters.filter((p) => p.in === "header");
598
+ return (0, _kubb_ast.createSchema)({
599
+ type: "object",
600
+ deprecated: node.deprecated,
601
+ properties: [
602
+ (0, _kubb_ast.createProperty)({
603
+ name: "data",
604
+ schema: node.requestBody?.schema ? (0, _kubb_ast.createSchema)({
605
+ type: "ref",
606
+ name: resolver.resolveDataName(node),
607
+ optional: true
608
+ }) : (0, _kubb_ast.createSchema)({
609
+ type: "never",
610
+ primitive: void 0,
611
+ optional: true
612
+ })
613
+ }),
614
+ (0, _kubb_ast.createProperty)({
615
+ name: "pathParams",
616
+ required: pathParams.length > 0,
617
+ schema: pathParams.length > 0 ? buildParams(node, {
618
+ params: pathParams,
619
+ resolver
620
+ }) : (0, _kubb_ast.createSchema)({
621
+ type: "never",
622
+ primitive: void 0
623
+ })
624
+ }),
625
+ (0, _kubb_ast.createProperty)({
626
+ name: "queryParams",
627
+ schema: queryParams.length > 0 ? (0, _kubb_ast.createSchema)({
628
+ ...buildParams(node, {
629
+ params: queryParams,
630
+ resolver
631
+ }),
632
+ optional: true
633
+ }) : (0, _kubb_ast.createSchema)({
634
+ type: "never",
635
+ primitive: void 0,
636
+ optional: true
637
+ })
638
+ }),
639
+ (0, _kubb_ast.createProperty)({
640
+ name: "headerParams",
641
+ schema: headerParams.length > 0 ? (0, _kubb_ast.createSchema)({
642
+ ...buildParams(node, {
643
+ params: headerParams,
644
+ resolver
645
+ }),
646
+ optional: true
647
+ }) : (0, _kubb_ast.createSchema)({
648
+ type: "never",
649
+ primitive: void 0,
650
+ optional: true
651
+ })
652
+ }),
653
+ (0, _kubb_ast.createProperty)({
654
+ name: "url",
655
+ required: true,
656
+ schema: (0, _kubb_ast.createSchema)({
657
+ type: "url",
658
+ path: node.path
659
+ })
660
+ })
661
+ ]
662
+ });
663
+ }
664
+ function buildResponses(node, { resolver }) {
665
+ if (node.responses.length === 0) return null;
666
+ return (0, _kubb_ast.createSchema)({
667
+ type: "object",
668
+ properties: node.responses.map((res) => (0, _kubb_ast.createProperty)({
669
+ name: String(res.statusCode),
670
+ required: true,
671
+ schema: (0, _kubb_ast.createSchema)({
672
+ type: "ref",
673
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
674
+ })
675
+ }))
676
+ });
677
+ }
678
+ function buildResponseUnion(node, { resolver }) {
679
+ const responsesWithSchema = node.responses.filter((res) => res.schema);
680
+ if (responsesWithSchema.length === 0) return null;
681
+ return (0, _kubb_ast.createSchema)({
682
+ type: "union",
683
+ members: responsesWithSchema.map((res) => (0, _kubb_ast.createSchema)({
684
+ type: "ref",
685
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
686
+ }))
687
+ });
688
+ }
689
+ //#endregion
690
+ //#region src/printers/printerTs.ts
567
691
  /**
568
692
  * TypeScript type printer built with `definePrinter`.
569
693
  *
@@ -607,6 +731,8 @@ const printerTs = (0, _kubb_core.definePrinter)((options) => {
607
731
  if (node.path) return createUrlTemplateType(node.path);
608
732
  return keywordTypeNodes.string;
609
733
  },
734
+ ipv4: () => keywordTypeNodes.string,
735
+ ipv6: () => keywordTypeNodes.string,
610
736
  datetime: () => keywordTypeNodes.string,
611
737
  number: () => keywordTypeNodes.number,
612
738
  integer: () => keywordTypeNodes.number,
@@ -615,14 +741,14 @@ const printerTs = (0, _kubb_core.definePrinter)((options) => {
615
741
  time: dateOrStringNode,
616
742
  ref(node) {
617
743
  if (!node.name) return;
618
- const refName = node.ref ? node.ref.split("/").at(-1) ?? node.name : node.name;
619
- return createTypeReferenceNode(node.ref ? this.options.resolver.default(refName, "type") : refName, void 0);
744
+ const refName = node.ref ? (0, _kubb_ast.extractRefName)(node.ref) ?? node.name : node.name;
745
+ return createTypeReferenceNode(node.ref && ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enumType) && this.options.enumTypeSuffix && this.options.enumSchemaNames?.has(refName) ? this.options.resolver.resolveEnumKeyName({ name: refName }, this.options.enumTypeSuffix) : node.ref ? this.options.resolver.default(refName, "type") : refName, void 0);
620
746
  },
621
747
  enum(node) {
622
748
  const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
623
749
  if (this.options.enumType === "inlineLiteral" || !node.name) return createUnionDeclaration({
624
750
  withParentheses: true,
625
- nodes: values.filter((v) => v !== null).map((value) => constToTypeNode(value, typeof value)).filter(Boolean)
751
+ nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(Boolean)
626
752
  }) ?? void 0;
627
753
  return createTypeReferenceNode(ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enumType) && this.options.enumTypeSuffix ? this.options.resolver.resolveEnumKeyName(node, this.options.enumTypeSuffix) : this.options.resolver.default(node.name, "type"), void 0);
628
754
  },
@@ -668,12 +794,13 @@ const printerTs = (0, _kubb_core.definePrinter)((options) => {
668
794
  const propertyNodes = node.properties.map((prop) => {
669
795
  const baseType = transform(prop.schema) ?? keywordTypeNodes.unknown;
670
796
  const type = buildPropertyType(prop.schema, baseType, options.optionalType);
797
+ const propMeta = (0, _kubb_ast.syncSchemaRef)(prop.schema);
671
798
  return appendJSDocToNode({
672
799
  node: createPropertySignature({
673
800
  questionToken: prop.schema.optional || prop.schema.nullish ? addsQuestionToken : false,
674
801
  name: prop.name,
675
802
  type,
676
- readOnly: prop.schema.readOnly
803
+ readOnly: propMeta?.readOnly
677
804
  }),
678
805
  comments: buildPropertyJSDocComments(prop.schema)
679
806
  });
@@ -684,39 +811,39 @@ const printerTs = (0, _kubb_core.definePrinter)((options) => {
684
811
  }
685
812
  },
686
813
  print(node) {
687
- let type = this.transform(node);
688
- if (!type) return null;
689
- if (node.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
690
- if ((node.nullish || node.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
691
814
  const { name, syntaxType = "type", description, keysToOmit } = this.options;
692
- if (!name) return (0, _kubb_fabric_core_parsers_typescript.safePrint)(type);
693
- const useTypeGeneration = syntaxType === "type" || type.kind === syntaxKind.union || !!keysToOmit?.length;
815
+ let base = this.transform(node);
816
+ if (!base) return null;
817
+ const meta = (0, _kubb_ast.syncSchemaRef)(node);
818
+ if (!name) {
819
+ if (meta.nullable) base = createUnionDeclaration({ nodes: [base, keywordTypeNodes.null] });
820
+ if ((meta.nullish || meta.optional) && addsUndefined) base = createUnionDeclaration({ nodes: [base, keywordTypeNodes.undefined] });
821
+ return (0, _kubb_fabric_core_parsers_typescript.safePrint)(base);
822
+ }
823
+ let inner = keysToOmit?.length ? createOmitDeclaration({
824
+ keys: keysToOmit,
825
+ type: base,
826
+ nonNullable: true
827
+ }) : base;
828
+ if (meta.nullable) inner = createUnionDeclaration({ nodes: [inner, keywordTypeNodes.null] });
829
+ if (meta.nullish || meta.optional) inner = createUnionDeclaration({ nodes: [inner, keywordTypeNodes.undefined] });
830
+ const useTypeGeneration = syntaxType === "type" || inner.kind === syntaxKind.union || !!keysToOmit?.length;
694
831
  return (0, _kubb_fabric_core_parsers_typescript.safePrint)(createTypeDeclaration({
695
832
  name,
696
833
  isExportable: true,
697
- type: keysToOmit?.length ? createOmitDeclaration({
698
- keys: keysToOmit,
699
- type,
700
- nonNullable: true
701
- }) : type,
834
+ type: inner,
702
835
  syntax: useTypeGeneration ? "type" : "interface",
703
- comments: [
704
- node?.title ? jsStringEscape(node.title) : void 0,
705
- description ? `@description ${jsStringEscape(description)}` : void 0,
706
- node?.deprecated ? "@deprecated" : void 0,
707
- node && "min" in node && node.min !== void 0 ? `@minLength ${node.min}` : void 0,
708
- node && "max" in node && node.max !== void 0 ? `@maxLength ${node.max}` : void 0,
709
- node && "pattern" in node && node.pattern ? `@pattern ${node.pattern}` : void 0,
710
- node?.default ? `@default ${node.default}` : void 0,
711
- node?.example ? `@example ${node.example}` : void 0
712
- ]
836
+ comments: buildPropertyJSDocComments({
837
+ ...meta,
838
+ description
839
+ })
713
840
  }));
714
841
  }
715
842
  };
716
843
  });
717
844
  //#endregion
718
845
  //#region src/components/Type.tsx
719
- function Type({ name, node, keysToOmit, optionalType, arrayType, syntaxType, enumType, enumTypeSuffix, enumKeyCasing, description, resolver }) {
846
+ function Type({ name, node, keysToOmit, optionalType, arrayType, syntaxType, enumType, enumTypeSuffix, enumKeyCasing, description, resolver, enumSchemaNames }) {
720
847
  const resolvedDescription = description || node?.description;
721
848
  const enumSchemaNodes = (0, _kubb_ast.collect)(node, { schema(n) {
722
849
  const enumNode = (0, _kubb_ast.narrowSchema)(n, _kubb_ast.schemaTypes.enum);
@@ -731,7 +858,8 @@ function Type({ name, node, keysToOmit, optionalType, arrayType, syntaxType, enu
731
858
  syntaxType,
732
859
  description: resolvedDescription,
733
860
  keysToOmit,
734
- resolver
861
+ resolver,
862
+ enumSchemaNames
735
863
  }).print(node);
736
864
  if (!output) return;
737
865
  const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((node) => {
@@ -762,137 +890,104 @@ function Type({ name, node, keysToOmit, optionalType, arrayType, syntaxType, enu
762
890
  })] });
763
891
  }
764
892
  //#endregion
765
- //#region src/utils.ts
766
- function buildParams({ params, node, resolver }) {
767
- return (0, _kubb_ast.createSchema)({
768
- type: "object",
769
- properties: params.map((param) => (0, _kubb_ast.createProperty)({
770
- name: param.name,
771
- required: param.required,
772
- schema: (0, _kubb_ast.createSchema)({
773
- type: "ref",
774
- name: resolver.resolveParamName(node, param)
775
- })
776
- }))
777
- });
778
- }
779
- function buildData({ node, resolver }) {
780
- const pathParams = node.parameters.filter((p) => p.in === "path");
781
- const queryParams = node.parameters.filter((p) => p.in === "query");
782
- const headerParams = node.parameters.filter((p) => p.in === "header");
783
- return (0, _kubb_ast.createSchema)({
784
- type: "object",
785
- deprecated: node.deprecated,
786
- properties: [
787
- (0, _kubb_ast.createProperty)({
788
- name: "data",
789
- schema: node.requestBody?.schema ? (0, _kubb_ast.createSchema)({
790
- type: "ref",
791
- name: resolver.resolveDataName(node),
792
- optional: true
793
- }) : (0, _kubb_ast.createSchema)({
794
- type: "never",
795
- optional: true
796
- })
797
- }),
798
- (0, _kubb_ast.createProperty)({
799
- name: "pathParams",
800
- required: pathParams.length > 0,
801
- schema: pathParams.length > 0 ? buildParams({
802
- params: pathParams,
803
- node,
804
- resolver
805
- }) : (0, _kubb_ast.createSchema)({ type: "never" })
806
- }),
807
- (0, _kubb_ast.createProperty)({
808
- name: "queryParams",
809
- schema: queryParams.length > 0 ? (0, _kubb_ast.createSchema)({
810
- ...buildParams({
811
- params: queryParams,
812
- node,
813
- resolver
814
- }),
815
- optional: true
816
- }) : (0, _kubb_ast.createSchema)({
817
- type: "never",
818
- optional: true
819
- })
820
- }),
821
- (0, _kubb_ast.createProperty)({
822
- name: "headerParams",
823
- schema: headerParams.length > 0 ? (0, _kubb_ast.createSchema)({
824
- ...buildParams({
825
- params: headerParams,
826
- node,
827
- resolver
828
- }),
829
- optional: true
830
- }) : (0, _kubb_ast.createSchema)({
831
- type: "never",
832
- optional: true
833
- })
834
- }),
835
- (0, _kubb_ast.createProperty)({
836
- name: "url",
837
- required: true,
838
- schema: (0, _kubb_ast.createSchema)({
839
- type: "url",
840
- path: node.path
841
- })
842
- })
843
- ]
844
- });
845
- }
846
- function buildResponses({ node, resolver }) {
847
- if (node.responses.length === 0) return null;
848
- return (0, _kubb_ast.createSchema)({
849
- type: "object",
850
- properties: node.responses.map((res) => (0, _kubb_ast.createProperty)({
851
- name: String(res.statusCode),
852
- required: true,
853
- schema: (0, _kubb_ast.createSchema)({
854
- type: "ref",
855
- name: resolver.resolveResponseStatusName(node, res.statusCode)
856
- })
857
- }))
858
- });
859
- }
860
- function buildResponseUnion({ node, resolver }) {
861
- const responsesWithSchema = node.responses.filter((res) => res.schema);
862
- if (responsesWithSchema.length === 0) return null;
863
- return (0, _kubb_ast.createSchema)({
864
- type: "union",
865
- members: responsesWithSchema.map((res) => (0, _kubb_ast.createSchema)({
866
- type: "ref",
867
- name: resolver.resolveResponseStatusName(node, res.statusCode)
868
- }))
869
- });
870
- }
871
- //#endregion
872
893
  //#region src/generators/typeGenerator.tsx
873
894
  const typeGenerator = (0, _kubb_core.defineGenerator)({
874
895
  name: "typescript",
875
896
  type: "react",
897
+ Schema({ node, adapter, options, config, resolver }) {
898
+ const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, transformers = [] } = options;
899
+ const transformedNode = (0, _kubb_ast.transform)(node, (0, _kubb_ast.composeTransformers)(...transformers));
900
+ if (!transformedNode.name) return;
901
+ const root = node_path.default.resolve(config.root, config.output.path);
902
+ const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
903
+ const enumSchemaNames = new Set((adapter.rootNode?.schemas ?? []).filter((s) => (0, _kubb_ast.narrowSchema)(s, _kubb_ast.schemaTypes.enum) && s.name).map((s) => s.name));
904
+ function resolveImportName(schemaName) {
905
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && enumTypeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumTypeSuffix);
906
+ return resolver.default(schemaName, "type");
907
+ }
908
+ const imports = adapter.getImports(transformedNode, (schemaName) => ({
909
+ name: resolveImportName(schemaName),
910
+ path: resolver.resolveFile({
911
+ name: schemaName,
912
+ extname: ".ts"
913
+ }, {
914
+ root,
915
+ output,
916
+ group
917
+ }).path
918
+ }));
919
+ const isEnumSchema = !!(0, _kubb_ast.narrowSchema)(transformedNode, _kubb_ast.schemaTypes.enum);
920
+ const meta = {
921
+ name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyName(transformedNode, enumTypeSuffix) : resolver.resolveName(transformedNode.name),
922
+ file: resolver.resolveFile({
923
+ name: transformedNode.name,
924
+ extname: ".ts"
925
+ }, {
926
+ root,
927
+ output,
928
+ group
929
+ })
930
+ };
931
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
932
+ baseName: meta.file.baseName,
933
+ path: meta.file.path,
934
+ meta: meta.file.meta,
935
+ banner: resolver.resolveBanner(adapter.rootNode, {
936
+ output,
937
+ config
938
+ }),
939
+ footer: resolver.resolveFooter(adapter.rootNode, {
940
+ output,
941
+ config
942
+ }),
943
+ children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
944
+ root: meta.file.path,
945
+ path: imp.path,
946
+ name: imp.name,
947
+ isTypeOnly: true
948
+ }, [
949
+ transformedNode.name,
950
+ imp.path,
951
+ imp.isTypeOnly
952
+ ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
953
+ name: meta.name,
954
+ node: transformedNode,
955
+ enumType,
956
+ enumTypeSuffix,
957
+ enumKeyCasing,
958
+ optionalType,
959
+ arrayType,
960
+ syntaxType,
961
+ resolver,
962
+ enumSchemaNames
963
+ })]
964
+ });
965
+ },
876
966
  Operation({ node, adapter, options, config, resolver }) {
877
967
  const { enumType, enumTypeSuffix, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group, output, transformers = [] } = options;
968
+ const transformedNode = (0, _kubb_ast.transform)(node, (0, _kubb_ast.composeTransformers)(...transformers));
878
969
  const root = node_path.default.resolve(config.root, config.output.path);
879
970
  const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
880
- const file = resolver.resolveFile({
881
- name: node.operationId,
971
+ const params = (0, _kubb_ast.caseParams)(transformedNode.parameters, paramsCasing);
972
+ const meta = { file: resolver.resolveFile({
973
+ name: transformedNode.operationId,
882
974
  extname: ".ts",
883
- tag: node.tags[0] ?? "default",
884
- path: node.path
975
+ tag: transformedNode.tags[0] ?? "default",
976
+ path: transformedNode.path
885
977
  }, {
886
978
  root,
887
979
  output,
888
980
  group
889
- });
890
- const params = (0, _kubb_ast.caseParams)(node.parameters, paramsCasing);
891
- function renderSchemaType({ node: schemaNode, name, description, keysToOmit }) {
892
- if (!schemaNode) return null;
893
- const transformedNode = (0, _kubb_ast.transform)(schemaNode, (0, _kubb_ast.composeTransformers)(...transformers));
894
- const imports = adapter.getImports(transformedNode, (schemaName) => ({
895
- name: resolver.default(schemaName, "type"),
981
+ }) };
982
+ const enumSchemaNames = new Set((adapter.rootNode?.schemas ?? []).filter((s) => (0, _kubb_ast.narrowSchema)(s, _kubb_ast.schemaTypes.enum) && s.name).map((s) => s.name));
983
+ function resolveImportName(schemaName) {
984
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && enumTypeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumTypeSuffix);
985
+ return resolver.default(schemaName, "type");
986
+ }
987
+ function renderSchemaType({ schema, name, keysToOmit }) {
988
+ if (!schema) return null;
989
+ const imports = adapter.getImports(schema, (schemaName) => ({
990
+ name: resolveImportName(schemaName),
896
991
  path: resolver.resolveFile({
897
992
  name: schemaName,
898
993
  extname: ".ts"
@@ -903,7 +998,7 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
903
998
  }).path
904
999
  }));
905
1000
  return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
906
- root: file.path,
1001
+ root: meta.file.path,
907
1002
  path: imp.path,
908
1003
  name: imp.name,
909
1004
  isTypeOnly: true
@@ -913,8 +1008,7 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
913
1008
  imp.isTypeOnly
914
1009
  ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
915
1010
  name,
916
- node: transformedNode,
917
- description,
1011
+ node: schema,
918
1012
  enumType,
919
1013
  enumTypeSuffix,
920
1014
  enumKeyCasing,
@@ -922,54 +1016,49 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
922
1016
  arrayType,
923
1017
  syntaxType,
924
1018
  resolver,
925
- keysToOmit
1019
+ keysToOmit,
1020
+ enumSchemaNames
926
1021
  })] });
927
1022
  }
928
1023
  const paramTypes = params.map((param) => renderSchemaType({
929
- node: param.schema,
930
- name: resolver.resolveParamName(node, param)
1024
+ schema: param.schema,
1025
+ name: resolver.resolveParamName(transformedNode, param)
931
1026
  }));
932
- const requestType = node.requestBody?.schema ? renderSchemaType({
933
- node: node.requestBody.schema,
934
- name: resolver.resolveDataName(node),
935
- description: node.requestBody.description ?? node.requestBody.schema.description,
936
- keysToOmit: node.requestBody.keysToOmit
1027
+ const requestType = transformedNode.requestBody?.schema ? renderSchemaType({
1028
+ schema: {
1029
+ ...transformedNode.requestBody.schema,
1030
+ description: transformedNode.requestBody.description ?? transformedNode.requestBody.schema.description
1031
+ },
1032
+ name: resolver.resolveDataName(transformedNode),
1033
+ keysToOmit: transformedNode.requestBody.keysToOmit
937
1034
  }) : null;
938
- const responseTypes = node.responses.map((res) => renderSchemaType({
939
- node: res.schema,
940
- name: resolver.resolveResponseStatusName(node, res.statusCode),
941
- description: res.description,
1035
+ const responseTypes = transformedNode.responses.map((res) => renderSchemaType({
1036
+ schema: res.schema,
1037
+ name: resolver.resolveResponseStatusName(transformedNode, res.statusCode),
942
1038
  keysToOmit: res.keysToOmit
943
1039
  }));
944
1040
  const dataType = renderSchemaType({
945
- node: buildData({
946
- node: {
947
- ...node,
948
- parameters: params
949
- },
950
- resolver
951
- }),
952
- name: resolver.resolveRequestConfigName(node)
1041
+ schema: buildData({
1042
+ ...transformedNode,
1043
+ parameters: params
1044
+ }, { resolver }),
1045
+ name: resolver.resolveRequestConfigName(transformedNode)
953
1046
  });
954
1047
  const responsesType = renderSchemaType({
955
- node: buildResponses({
956
- node,
957
- resolver
958
- }),
959
- name: resolver.resolveResponsesName(node)
1048
+ schema: buildResponses(transformedNode, { resolver }),
1049
+ name: resolver.resolveResponsesName(transformedNode)
960
1050
  });
961
1051
  const responseType = renderSchemaType({
962
- node: buildResponseUnion({
963
- node,
964
- resolver
965
- }),
966
- name: resolver.resolveResponseName(node),
967
- description: "Union of all possible responses"
1052
+ schema: transformedNode.responses.some((res) => res.schema) ? {
1053
+ ...buildResponseUnion(transformedNode, { resolver }),
1054
+ description: "Union of all possible responses"
1055
+ } : null,
1056
+ name: resolver.resolveResponseName(transformedNode)
968
1057
  });
969
1058
  return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
970
- baseName: file.baseName,
971
- path: file.path,
972
- meta: file.meta,
1059
+ baseName: meta.file.baseName,
1060
+ path: meta.file.path,
1061
+ meta: meta.file.meta,
973
1062
  banner: resolver.resolveBanner(adapter.rootNode, {
974
1063
  output,
975
1064
  config
@@ -987,74 +1076,11 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
987
1076
  responseType
988
1077
  ]
989
1078
  });
990
- },
991
- Schema({ node, adapter, options, config, resolver }) {
992
- const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, transformers = [] } = options;
993
- const root = node_path.default.resolve(config.root, config.output.path);
994
- const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
995
- if (!node.name) return;
996
- const transformedNode = (0, _kubb_ast.transform)(node, (0, _kubb_ast.composeTransformers)(...transformers));
997
- const imports = adapter.getImports(transformedNode, (schemaName) => ({
998
- name: resolver.default(schemaName, "type"),
999
- path: resolver.resolveFile({
1000
- name: schemaName,
1001
- extname: ".ts"
1002
- }, {
1003
- root,
1004
- output,
1005
- group
1006
- }).path
1007
- }));
1008
- const isEnumSchema = !!(0, _kubb_ast.narrowSchema)(node, _kubb_ast.schemaTypes.enum);
1009
- const type = {
1010
- name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolver.resolveName(node.name),
1011
- file: resolver.resolveFile({
1012
- name: node.name,
1013
- extname: ".ts"
1014
- }, {
1015
- root,
1016
- output,
1017
- group
1018
- })
1019
- };
1020
- return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1021
- baseName: type.file.baseName,
1022
- path: type.file.path,
1023
- meta: type.file.meta,
1024
- banner: resolver.resolveBanner(adapter.rootNode, {
1025
- output,
1026
- config
1027
- }),
1028
- footer: resolver.resolveFooter(adapter.rootNode, {
1029
- output,
1030
- config
1031
- }),
1032
- children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1033
- root: type.file.path,
1034
- path: imp.path,
1035
- name: imp.name,
1036
- isTypeOnly: true
1037
- }, [
1038
- node.name,
1039
- imp.path,
1040
- imp.isTypeOnly
1041
- ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
1042
- name: type.name,
1043
- node: transformedNode,
1044
- enumType,
1045
- enumTypeSuffix,
1046
- enumKeyCasing,
1047
- optionalType,
1048
- arrayType,
1049
- syntaxType,
1050
- resolver
1051
- })]
1052
- });
1053
1079
  }
1054
1080
  });
1055
1081
  //#endregion
1056
1082
  //#region src/resolvers/resolverTs.ts
1057
- function resolveName(name, type) {
1083
+ function toTypeName(name, type) {
1058
1084
  return pascalCase(name, { isFile: type === "file" });
1059
1085
  }
1060
1086
  /**
@@ -1079,7 +1105,7 @@ const resolverTs = (0, _kubb_core.defineResolver)(() => {
1079
1105
  name: "default",
1080
1106
  pluginName: "plugin-ts",
1081
1107
  default(name, type) {
1082
- return resolveName(name, type);
1108
+ return toTypeName(name, type);
1083
1109
  },
1084
1110
  resolveName(name) {
1085
1111
  return this.default(name, "function");
@@ -1198,7 +1224,7 @@ function buildGroupedParamsSchema({ params, parentName }) {
1198
1224
  })
1199
1225
  });
1200
1226
  }
1201
- function buildLegacyResponsesSchemaNode({ node, resolver }) {
1227
+ function buildLegacyResponsesSchemaNode(node, { resolver }) {
1202
1228
  const isGet = node.method.toLowerCase() === "get";
1203
1229
  const successResponses = node.responses.filter((res) => {
1204
1230
  const code = Number(res.statusCode);
@@ -1214,7 +1240,10 @@ function buildLegacyResponsesSchemaNode({ node, resolver }) {
1214
1240
  type: "ref",
1215
1241
  name: resolver.resolveResponseStatusName(node, res.statusCode)
1216
1242
  }))
1217
- }) : (0, _kubb_ast.createSchema)({ type: "any" });
1243
+ }) : (0, _kubb_ast.createSchema)({
1244
+ type: "any",
1245
+ primitive: void 0
1246
+ });
1218
1247
  const errorsSchema = errorResponses.length > 0 ? errorResponses.length === 1 ? (0, _kubb_ast.createSchema)({
1219
1248
  type: "ref",
1220
1249
  name: resolver.resolveResponseStatusName(node, errorResponses[0].statusCode)
@@ -1224,7 +1253,10 @@ function buildLegacyResponsesSchemaNode({ node, resolver }) {
1224
1253
  type: "ref",
1225
1254
  name: resolver.resolveResponseStatusName(node, res.statusCode)
1226
1255
  }))
1227
- }) : (0, _kubb_ast.createSchema)({ type: "any" });
1256
+ }) : (0, _kubb_ast.createSchema)({
1257
+ type: "any",
1258
+ primitive: void 0
1259
+ });
1228
1260
  const properties = [(0, _kubb_ast.createProperty)({
1229
1261
  name: "Response",
1230
1262
  required: true,
@@ -1275,12 +1307,15 @@ function buildLegacyResponsesSchemaNode({ node, resolver }) {
1275
1307
  properties
1276
1308
  });
1277
1309
  }
1278
- function buildLegacyResponseUnionSchemaNode({ node, resolver }) {
1310
+ function buildLegacyResponseUnionSchemaNode(node, { resolver }) {
1279
1311
  const successResponses = node.responses.filter((res) => {
1280
1312
  const code = Number(res.statusCode);
1281
1313
  return !Number.isNaN(code) && code >= 200 && code < 300;
1282
1314
  });
1283
- if (successResponses.length === 0) return (0, _kubb_ast.createSchema)({ type: "any" });
1315
+ if (successResponses.length === 0) return (0, _kubb_ast.createSchema)({
1316
+ type: "any",
1317
+ primitive: void 0
1318
+ });
1284
1319
  if (successResponses.length === 1) return (0, _kubb_ast.createSchema)({
1285
1320
  type: "ref",
1286
1321
  name: resolver.resolveResponseStatusName(node, successResponses[0].statusCode)
@@ -1321,25 +1356,88 @@ function nameUnnamedEnums(node, parentName) {
1321
1356
  const typeGeneratorLegacy = (0, _kubb_core.defineGenerator)({
1322
1357
  name: "typescript-legacy",
1323
1358
  type: "react",
1359
+ Schema({ node, adapter, options, config, resolver }) {
1360
+ const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, transformers = [] } = options;
1361
+ const transformedNode = (0, _kubb_ast.transform)(node, (0, _kubb_ast.composeTransformers)(...transformers));
1362
+ if (!transformedNode.name) return;
1363
+ const root = node_path.default.resolve(config.root, config.output.path);
1364
+ const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
1365
+ const imports = adapter.getImports(transformedNode, (schemaName) => ({
1366
+ name: resolver.default(schemaName, "type"),
1367
+ path: resolver.resolveFile({
1368
+ name: schemaName,
1369
+ extname: ".ts"
1370
+ }, {
1371
+ root,
1372
+ output,
1373
+ group
1374
+ }).path
1375
+ }));
1376
+ const isEnumSchema = !!(0, _kubb_ast.narrowSchema)(transformedNode, _kubb_ast.schemaTypes.enum);
1377
+ const meta = {
1378
+ name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyName(transformedNode, enumTypeSuffix) : resolver.resolveName(transformedNode.name),
1379
+ file: resolver.resolveFile({
1380
+ name: transformedNode.name,
1381
+ extname: ".ts"
1382
+ }, {
1383
+ root,
1384
+ output,
1385
+ group
1386
+ })
1387
+ };
1388
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1389
+ baseName: meta.file.baseName,
1390
+ path: meta.file.path,
1391
+ meta: meta.file.meta,
1392
+ banner: resolver.resolveBanner(adapter.rootNode, {
1393
+ output,
1394
+ config
1395
+ }),
1396
+ footer: resolver.resolveFooter(adapter.rootNode, {
1397
+ output,
1398
+ config
1399
+ }),
1400
+ children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1401
+ root: meta.file.path,
1402
+ path: imp.path,
1403
+ name: imp.name,
1404
+ isTypeOnly: true
1405
+ }, [
1406
+ transformedNode.name,
1407
+ imp.path,
1408
+ imp.isTypeOnly
1409
+ ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
1410
+ name: meta.name,
1411
+ node: transformedNode,
1412
+ enumType,
1413
+ enumTypeSuffix,
1414
+ enumKeyCasing,
1415
+ optionalType,
1416
+ arrayType,
1417
+ syntaxType,
1418
+ resolver
1419
+ })]
1420
+ });
1421
+ },
1324
1422
  Operation({ node, adapter, options, config, resolver }) {
1325
1423
  const { enumType, enumTypeSuffix, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group, output, transformers = [] } = options;
1424
+ const transformedNode = (0, _kubb_ast.transform)(node, (0, _kubb_ast.composeTransformers)(...transformers));
1326
1425
  const root = node_path.default.resolve(config.root, config.output.path);
1327
1426
  const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
1328
- const file = resolver.resolveFile({
1329
- name: node.operationId,
1427
+ const params = (0, _kubb_ast.caseParams)(node.parameters, paramsCasing);
1428
+ const meta = { file: resolver.resolveFile({
1429
+ name: transformedNode.operationId,
1330
1430
  extname: ".ts",
1331
- tag: node.tags[0] ?? "default",
1332
- path: node.path
1431
+ tag: transformedNode.tags[0] ?? "default",
1432
+ path: transformedNode.path
1333
1433
  }, {
1334
1434
  root,
1335
1435
  output,
1336
1436
  group
1337
- });
1338
- const params = (0, _kubb_ast.caseParams)(node.parameters, paramsCasing);
1339
- function renderSchemaType({ node: schemaNode, name, description, keysToOmit }) {
1340
- if (!schemaNode) return null;
1341
- const transformedNode = (0, _kubb_ast.transform)(schemaNode, (0, _kubb_ast.composeTransformers)(...transformers));
1342
- const imports = adapter.getImports(transformedNode, (schemaName) => ({
1437
+ }) };
1438
+ function renderSchemaType({ schema, name, description, keysToOmit }) {
1439
+ if (!schema) return null;
1440
+ const imports = adapter.getImports(schema, (schemaName) => ({
1343
1441
  name: resolver.default(schemaName, "type"),
1344
1442
  path: resolver.resolveFile({
1345
1443
  name: schemaName,
@@ -1351,7 +1449,7 @@ const typeGeneratorLegacy = (0, _kubb_core.defineGenerator)({
1351
1449
  }).path
1352
1450
  }));
1353
1451
  return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1354
- root: file.path,
1452
+ root: meta.file.path,
1355
1453
  path: imp.path,
1356
1454
  name: imp.name,
1357
1455
  isTypeOnly: true
@@ -1361,7 +1459,7 @@ const typeGeneratorLegacy = (0, _kubb_core.defineGenerator)({
1361
1459
  imp.isTypeOnly
1362
1460
  ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
1363
1461
  name,
1364
- node: transformedNode,
1462
+ node: schema,
1365
1463
  description,
1366
1464
  enumType,
1367
1465
  enumTypeSuffix,
@@ -1380,35 +1478,35 @@ const typeGeneratorLegacy = (0, _kubb_core.defineGenerator)({
1380
1478
  const responseName = resolver.resolveResponseStatusName(node, res.statusCode);
1381
1479
  const baseResponseName = resolverTsLegacy.resolveResponseStatusName(node, res.statusCode);
1382
1480
  return renderSchemaType({
1383
- node: res.schema ? nameUnnamedEnums(res.schema, baseResponseName) : res.schema,
1481
+ schema: res.schema ? nameUnnamedEnums(res.schema, baseResponseName) : res.schema,
1384
1482
  name: responseName,
1385
1483
  description: res.description,
1386
1484
  keysToOmit: res.keysToOmit
1387
1485
  });
1388
1486
  });
1389
1487
  const requestType = node.requestBody?.schema ? renderSchemaType({
1390
- node: nameUnnamedEnums(node.requestBody.schema, resolverTsLegacy.resolveDataName(node)),
1488
+ schema: nameUnnamedEnums(node.requestBody.schema, resolverTsLegacy.resolveDataName(node)),
1391
1489
  name: resolver.resolveDataName(node),
1392
1490
  description: node.requestBody.description ?? node.requestBody.schema.description,
1393
1491
  keysToOmit: node.requestBody.keysToOmit
1394
1492
  }) : null;
1395
1493
  const legacyParamTypes = [
1396
1494
  pathParams.length > 0 ? renderSchemaType({
1397
- node: buildGroupedParamsSchema({
1495
+ schema: buildGroupedParamsSchema({
1398
1496
  params: pathParams,
1399
1497
  parentName: resolverTsLegacy.resolvePathParamsName(node, pathParams[0])
1400
1498
  }),
1401
1499
  name: resolver.resolvePathParamsName(node, pathParams[0])
1402
1500
  }) : null,
1403
1501
  queryParams.length > 0 ? renderSchemaType({
1404
- node: buildGroupedParamsSchema({
1502
+ schema: buildGroupedParamsSchema({
1405
1503
  params: queryParams,
1406
1504
  parentName: resolverTsLegacy.resolveQueryParamsName(node, queryParams[0])
1407
1505
  }),
1408
1506
  name: resolver.resolveQueryParamsName(node, queryParams[0])
1409
1507
  }) : null,
1410
1508
  headerParams.length > 0 ? renderSchemaType({
1411
- node: buildGroupedParamsSchema({
1509
+ schema: buildGroupedParamsSchema({
1412
1510
  params: headerParams,
1413
1511
  parentName: resolverTsLegacy.resolveHeaderParamsName(node, headerParams[0])
1414
1512
  }),
@@ -1416,23 +1514,17 @@ const typeGeneratorLegacy = (0, _kubb_core.defineGenerator)({
1416
1514
  }) : null
1417
1515
  ];
1418
1516
  const legacyResponsesType = renderSchemaType({
1419
- node: buildLegacyResponsesSchemaNode({
1420
- node,
1421
- resolver
1422
- }),
1517
+ schema: buildLegacyResponsesSchemaNode(node, { resolver }),
1423
1518
  name: resolver.resolveResponsesName(node)
1424
1519
  });
1425
1520
  const legacyResponseType = renderSchemaType({
1426
- node: buildLegacyResponseUnionSchemaNode({
1427
- node,
1428
- resolver
1429
- }),
1521
+ schema: buildLegacyResponseUnionSchemaNode(node, { resolver }),
1430
1522
  name: resolver.resolveResponseName(node)
1431
1523
  });
1432
1524
  return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1433
- baseName: file.baseName,
1434
- path: file.path,
1435
- meta: file.meta,
1525
+ baseName: meta.file.baseName,
1526
+ path: meta.file.path,
1527
+ meta: meta.file.meta,
1436
1528
  banner: resolver.resolveBanner(adapter.rootNode, {
1437
1529
  output,
1438
1530
  config
@@ -1449,69 +1541,6 @@ const typeGeneratorLegacy = (0, _kubb_core.defineGenerator)({
1449
1541
  legacyResponsesType
1450
1542
  ]
1451
1543
  });
1452
- },
1453
- Schema({ node, adapter, options, config, resolver }) {
1454
- const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, transformers = [] } = options;
1455
- const root = node_path.default.resolve(config.root, config.output.path);
1456
- const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
1457
- if (!node.name) return;
1458
- const transformedNode = (0, _kubb_ast.transform)(node, (0, _kubb_ast.composeTransformers)(...transformers));
1459
- const imports = adapter.getImports(transformedNode, (schemaName) => ({
1460
- name: resolver.default(schemaName, "type"),
1461
- path: resolver.resolveFile({
1462
- name: schemaName,
1463
- extname: ".ts"
1464
- }, {
1465
- root,
1466
- output,
1467
- group
1468
- }).path
1469
- }));
1470
- const isEnumSchema = !!(0, _kubb_ast.narrowSchema)(node, _kubb_ast.schemaTypes.enum);
1471
- const type = {
1472
- name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolver.resolveName(node.name),
1473
- file: resolver.resolveFile({
1474
- name: node.name,
1475
- extname: ".ts"
1476
- }, {
1477
- root,
1478
- output,
1479
- group
1480
- })
1481
- };
1482
- return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1483
- baseName: type.file.baseName,
1484
- path: type.file.path,
1485
- meta: type.file.meta,
1486
- banner: resolver.resolveBanner(adapter.rootNode, {
1487
- output,
1488
- config
1489
- }),
1490
- footer: resolver.resolveFooter(adapter.rootNode, {
1491
- output,
1492
- config
1493
- }),
1494
- children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1495
- root: type.file.path,
1496
- path: imp.path,
1497
- name: imp.name,
1498
- isTypeOnly: true
1499
- }, [
1500
- node.name,
1501
- imp.path,
1502
- imp.isTypeOnly
1503
- ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
1504
- name: type.name,
1505
- node: transformedNode,
1506
- enumType,
1507
- enumTypeSuffix,
1508
- enumKeyCasing,
1509
- optionalType,
1510
- arrayType,
1511
- syntaxType,
1512
- resolver
1513
- })]
1514
- });
1515
1544
  }
1516
1545
  });
1517
1546
  //#endregion
@@ -1580,9 +1609,9 @@ const pluginTs = (0, _kubb_core.createPlugin)((options) => {
1580
1609
  output,
1581
1610
  optionalType,
1582
1611
  group: group ? {
1583
- ...options.group,
1612
+ ...group,
1584
1613
  name: (ctx) => {
1585
- if (options.group?.type === "path") return `${ctx.group.split("/")[1]}`;
1614
+ if (group.type === "path") return `${ctx.group.split("/")[1]}`;
1586
1615
  return `${camelCase(ctx.group)}Controller`;
1587
1616
  }
1588
1617
  } : void 0,
@@ -1621,59 +1650,37 @@ const pluginTs = (0, _kubb_core.createPlugin)((options) => {
1621
1650
  async install() {
1622
1651
  const { config, fabric, plugin, adapter, rootNode, driver, openInStudio, resolver } = this;
1623
1652
  const root = node_path.default.resolve(config.root, config.output.path);
1624
- if (!adapter) throw new Error("Plugin cannot work without adapter being set");
1653
+ if (!adapter) throw new Error(`[${pluginTsName}] No adapter found. Add an OAS adapter (e.g. pluginOas()) before this plugin in your Kubb config.`);
1625
1654
  await openInStudio({ ast: true });
1655
+ const collectedOperations = [];
1656
+ const generatorContext = {
1657
+ generators: preset.generators,
1658
+ plugin,
1659
+ resolver,
1660
+ exclude,
1661
+ include,
1662
+ override,
1663
+ fabric,
1664
+ adapter,
1665
+ config,
1666
+ driver
1667
+ };
1626
1668
  await (0, _kubb_ast.walk)(rootNode, {
1627
1669
  depth: "shallow",
1628
1670
  async schema(schemaNode) {
1629
- const writeTasks = preset.generators.map(async (generator) => {
1630
- if (generator.type === "react" && generator.version === "2") {
1631
- const options = resolver.resolveOptions(schemaNode, {
1632
- options: plugin.options,
1633
- exclude,
1634
- include,
1635
- override
1636
- });
1637
- if (options === null) return;
1638
- await (0, _kubb_core.renderSchema)(schemaNode, {
1639
- options,
1640
- resolver,
1641
- adapter,
1642
- config,
1643
- fabric,
1644
- Component: generator.Schema,
1645
- plugin,
1646
- driver
1647
- });
1648
- }
1649
- });
1650
- await Promise.all(writeTasks);
1671
+ await (0, _kubb_core.runGeneratorSchema)(schemaNode, generatorContext);
1651
1672
  },
1652
1673
  async operation(operationNode) {
1653
- const writeTasks = preset.generators.map(async (generator) => {
1654
- if (generator.type === "react" && generator.version === "2") {
1655
- const options = resolver.resolveOptions(operationNode, {
1656
- options: plugin.options,
1657
- exclude,
1658
- include,
1659
- override
1660
- });
1661
- if (options === null) return;
1662
- await (0, _kubb_core.renderOperation)(operationNode, {
1663
- options,
1664
- resolver,
1665
- adapter,
1666
- config,
1667
- fabric,
1668
- Component: generator.Operation,
1669
- plugin,
1670
- driver
1671
- });
1672
- }
1673
- });
1674
- await Promise.all(writeTasks);
1674
+ if (resolver.resolveOptions(operationNode, {
1675
+ options: plugin.options,
1676
+ exclude,
1677
+ include,
1678
+ override
1679
+ }) !== null) collectedOperations.push(operationNode);
1680
+ await (0, _kubb_core.runGeneratorOperation)(operationNode, generatorContext);
1675
1681
  }
1676
1682
  });
1683
+ await (0, _kubb_core.runGeneratorOperations)(collectedOperations, generatorContext);
1677
1684
  const barrelFiles = await (0, _kubb_core.getBarrelFiles)(this.fabric.files, {
1678
1685
  type: output.barrelType ?? "named",
1679
1686
  root,
@@ -1701,12 +1708,12 @@ const kindToHandlerKey = {
1701
1708
  const defineFunctionPrinter = (0, _kubb_ast.createPrinterFactory)((node) => kindToHandlerKey[node.kind]);
1702
1709
  function rank(param) {
1703
1710
  if (param.kind === "ParameterGroup") {
1704
- if (param.default) return 2;
1705
- return param.optional ?? param.properties.every((p) => p.optional || p.default !== void 0) ? 1 : 0;
1711
+ if (param.default) return PARAM_RANK.withDefault;
1712
+ return param.optional ?? param.properties.every((p) => p.optional || p.default !== void 0) ? PARAM_RANK.optional : PARAM_RANK.required;
1706
1713
  }
1707
- if (param.rest) return 3;
1708
- if (param.default) return 2;
1709
- return param.optional ? 1 : 0;
1714
+ if (param.rest) return PARAM_RANK.rest;
1715
+ if (param.default) return PARAM_RANK.withDefault;
1716
+ return param.optional ? PARAM_RANK.optional : PARAM_RANK.required;
1710
1717
  }
1711
1718
  function sortParams(params) {
1712
1719
  return [...params].sort((a, b) => rank(a) - rank(b));