@acrool/rtk-query-codegen-openapi 0.0.2 → 0.0.7

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/lib/index.js CHANGED
@@ -326,14 +326,14 @@ function removeUndefined(t) {
326
326
 
327
327
  // src/generators/react-hooks.ts
328
328
  var createBinding = ({
329
- operationDefinition: { verb, path: path4, operation },
329
+ operationDefinition: { verb, path: path4 },
330
330
  overrides,
331
331
  isLazy = false
332
332
  }) => factory.createBindingElement(
333
333
  void 0,
334
334
  void 0,
335
335
  factory.createIdentifier(
336
- `use${isLazy ? "Lazy" : ""}${capitalize((0, import_generate.getOperationName)(verb, path4, operation.operationId))}${isQuery(verb, overrides) ? "Query" : "Mutation"}`
336
+ `use${isLazy ? "Lazy" : ""}${capitalize((0, import_generate.getOperationName)(verb, path4, void 0))}${isQuery(verb, overrides) ? "Query" : "Mutation"}`
337
337
  ),
338
338
  void 0
339
339
  );
@@ -387,8 +387,8 @@ function defaultIsDataResponse(code, includeDefault) {
387
387
  const parsedCode = Number(code);
388
388
  return !Number.isNaN(parsedCode) && parsedCode >= 200 && parsedCode < 300;
389
389
  }
390
- function getOperationName2({ verb, path: path4, operation }) {
391
- return (0, import_generate3.getOperationName)(verb, path4, operation.operationId);
390
+ function getOperationName2({ verb, path: path4 }) {
391
+ return (0, import_generate3.getOperationName)(verb, path4, void 0);
392
392
  }
393
393
  function getTags({ verb, pathItem }) {
394
394
  return verb ? pathItem[verb]?.tags || [] : [];
@@ -462,41 +462,154 @@ async function generateApi(spec, {
462
462
  useEnumType,
463
463
  mergeReadWriteOnly
464
464
  });
465
+ const schemeTypeNames = /* @__PURE__ */ new Set();
466
+ function addSchemeTypeName(name) {
467
+ schemeTypeNames.add(name);
468
+ schemeTypeNames.add((0, import_lodash.default)(name));
469
+ schemeTypeNames.add(capitalize((0, import_lodash.default)(name)));
470
+ }
465
471
  if (sharedTypesFile) {
472
+ const resultFile2 = import_typescript4.default.createSourceFile(
473
+ "sharedTypes.ts",
474
+ "",
475
+ import_typescript4.default.ScriptTarget.Latest,
476
+ /*setParentNodes*/
477
+ false,
478
+ import_typescript4.default.ScriptKind.TS
479
+ );
480
+ const printer2 = import_typescript4.default.createPrinter({ newLine: import_typescript4.default.NewLineKind.LineFeed });
481
+ const allTypeDefinitions = [];
482
+ const definedTypeNames = /* @__PURE__ */ new Set();
466
483
  const components = v3Doc.components;
467
484
  if (components) {
468
- const resultFile2 = import_typescript4.default.createSourceFile(
469
- "sharedTypes.ts",
470
- "",
471
- import_typescript4.default.ScriptTarget.Latest,
472
- /*setParentNodes*/
473
- false,
474
- import_typescript4.default.ScriptKind.TS
475
- );
476
- const printer2 = import_typescript4.default.createPrinter({ newLine: import_typescript4.default.NewLineKind.LineFeed });
477
- const typeDefinitions = Object.entries(components).flatMap(([_, componentDefs]) => {
478
- return Object.entries(componentDefs).map(([name, def]) => {
479
- const typeNode = apiGen.getTypeFromSchema(def);
485
+ if (components.schemas) {
486
+ const typeEntries = Object.entries(components.schemas).map(([name, def]) => {
487
+ addSchemeTypeName(name);
488
+ const typeName = capitalize((0, import_lodash.default)(name));
489
+ definedTypeNames.add(typeName);
490
+ const typeNode = wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(def));
480
491
  return factory.createTypeAliasDeclaration(
481
492
  [factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
482
- factory.createIdentifier(name),
493
+ factory.createIdentifier(typeName),
483
494
  void 0,
484
495
  typeNode
485
496
  );
486
497
  });
487
- });
488
- const output = printer2.printNode(
489
- import_typescript4.default.EmitHint.Unspecified,
490
- factory.createSourceFile(
491
- typeDefinitions,
492
- factory.createToken(import_typescript4.default.SyntaxKind.EndOfFileToken),
493
- import_typescript4.default.NodeFlags.None
494
- ),
495
- resultFile2
498
+ allTypeDefinitions.push(
499
+ factory.createModuleDeclaration(
500
+ [factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
501
+ factory.createIdentifier("Scheme"),
502
+ factory.createModuleBlock(typeEntries),
503
+ import_typescript4.default.NodeFlags.Namespace
504
+ )
505
+ );
506
+ }
507
+ }
508
+ const enumEntries = [
509
+ ...apiGen.enumAliases.filter((e) => import_typescript4.default.isEnumDeclaration(e)),
510
+ ...apiGen.enumAliases.filter((e) => import_typescript4.default.isTypeAliasDeclaration(e))
511
+ ].map((enumDecl) => {
512
+ if (import_typescript4.default.isEnumDeclaration(enumDecl)) {
513
+ return factory.createEnumDeclaration(
514
+ [factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
515
+ enumDecl.name,
516
+ enumDecl.members
517
+ );
518
+ } else if (import_typescript4.default.isTypeAliasDeclaration(enumDecl)) {
519
+ return factory.createTypeAliasDeclaration(
520
+ [factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
521
+ enumDecl.name,
522
+ enumDecl.typeParameters,
523
+ enumDecl.type
524
+ );
525
+ }
526
+ return enumDecl;
527
+ });
528
+ const unionTypeEnums = apiGen.aliases.filter((alias) => {
529
+ if (import_typescript4.default.isTypeAliasDeclaration(alias) && alias.type) {
530
+ return import_typescript4.default.isUnionTypeNode(alias.type);
531
+ }
532
+ return false;
533
+ }).map((alias) => {
534
+ if (import_typescript4.default.isTypeAliasDeclaration(alias)) {
535
+ return factory.createTypeAliasDeclaration(
536
+ [factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
537
+ alias.name,
538
+ alias.typeParameters,
539
+ alias.type
540
+ );
541
+ }
542
+ return alias;
543
+ });
544
+ const allEnumEntries = [...enumEntries, ...unionTypeEnums];
545
+ if (allEnumEntries.length > 0) {
546
+ allTypeDefinitions.push(
547
+ factory.createModuleDeclaration(
548
+ [factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
549
+ factory.createIdentifier("Enum"),
550
+ factory.createModuleBlock(allEnumEntries),
551
+ import_typescript4.default.NodeFlags.Namespace
552
+ )
496
553
  );
497
- const fs2 = await import("node:fs/promises");
498
- await fs2.writeFile(sharedTypesFile, output, "utf-8");
499
554
  }
555
+ if (apiGen.aliases.length > 0) {
556
+ const aliasEntries = apiGen.aliases.filter((alias) => {
557
+ if (import_typescript4.default.isTypeAliasDeclaration(alias)) {
558
+ const isDefinedInComponents = definedTypeNames.has(alias.name.text);
559
+ const isUnionTypeEnum = import_typescript4.default.isUnionTypeNode(alias.type);
560
+ return !isDefinedInComponents && !isUnionTypeEnum;
561
+ }
562
+ return false;
563
+ }).map((alias) => {
564
+ if (import_typescript4.default.isTypeAliasDeclaration(alias)) {
565
+ return factory.createTypeAliasDeclaration(
566
+ [factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
567
+ alias.name,
568
+ alias.typeParameters,
569
+ alias.type
570
+ );
571
+ }
572
+ return alias;
573
+ });
574
+ if (aliasEntries.length > 0) {
575
+ const existingSchemeIndex = allTypeDefinitions.findIndex(
576
+ (def) => import_typescript4.default.isModuleDeclaration(def) && import_typescript4.default.isIdentifier(def.name) && def.name.text === "Scheme"
577
+ );
578
+ if (existingSchemeIndex >= 0) {
579
+ const existingScheme = allTypeDefinitions[existingSchemeIndex];
580
+ const mergedMembers = [...existingScheme.body.statements, ...aliasEntries];
581
+ allTypeDefinitions[existingSchemeIndex] = factory.createModuleDeclaration(
582
+ [factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
583
+ factory.createIdentifier("Scheme"),
584
+ factory.createModuleBlock(mergedMembers),
585
+ import_typescript4.default.NodeFlags.Namespace
586
+ );
587
+ } else {
588
+ allTypeDefinitions.push(
589
+ factory.createModuleDeclaration(
590
+ [factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
591
+ factory.createIdentifier("Scheme"),
592
+ factory.createModuleBlock(aliasEntries),
593
+ import_typescript4.default.NodeFlags.Namespace
594
+ )
595
+ );
596
+ }
597
+ }
598
+ }
599
+ const fs2 = await import("node:fs/promises");
600
+ const path4 = await import("node:path");
601
+ const sharedTypesDir = path4.dirname(sharedTypesFile);
602
+ await fs2.mkdir(sharedTypesDir, { recursive: true });
603
+ const output = printer2.printNode(
604
+ import_typescript4.default.EmitHint.Unspecified,
605
+ factory.createSourceFile(
606
+ allTypeDefinitions,
607
+ factory.createToken(import_typescript4.default.SyntaxKind.EndOfFileToken),
608
+ import_typescript4.default.NodeFlags.None
609
+ ),
610
+ resultFile2
611
+ );
612
+ await fs2.writeFile(sharedTypesFile, output, "utf-8");
500
613
  }
501
614
  if (apiGen.spec.components?.schemas) {
502
615
  apiGen.preprocessComponents(apiGen.spec.components.schemas);
@@ -527,16 +640,13 @@ async function generateApi(spec, {
527
640
  apiFile = apiFile.replace(/\\/g, "/");
528
641
  if (!apiFile.startsWith(".")) apiFile = `./${apiFile}`;
529
642
  }
530
- if (sharedTypesFile && sharedTypesFile.startsWith(".")) {
531
- sharedTypesFile = import_node_path2.default.relative(import_node_path2.default.dirname(outputFile), sharedTypesFile);
532
- sharedTypesFile = sharedTypesFile.replace(/\\/g, "/");
533
- if (!sharedTypesFile.startsWith(".")) sharedTypesFile = `./${sharedTypesFile}`;
534
- }
535
643
  }
536
644
  apiFile = apiFile.replace(/\.[jt]sx?$/, "");
537
- if (sharedTypesFile) {
538
- sharedTypesFile = sharedTypesFile.replace(/\.[jt]sx?$/, "");
539
- }
645
+ const sharedTypesImportPath = sharedTypesFile && outputFile ? (() => {
646
+ let rel = import_node_path2.default.relative(import_node_path2.default.dirname(outputFile), sharedTypesFile).replace(/\\/g, "/").replace(/\.[jt]sx?$/, "");
647
+ if (!rel.startsWith(".")) rel = "./" + rel;
648
+ return rel;
649
+ })() : "./shared-types";
540
650
  return printer.printNode(
541
651
  import_typescript4.default.EmitHint.Unspecified,
542
652
  factory.createSourceFile(
@@ -544,16 +654,10 @@ async function generateApi(spec, {
544
654
  generateImportNode(apiFile, { [apiImport]: "api" }),
545
655
  generateImportNode("@acrool/react-fetcher", { IRestFulEndpointsQueryReturn: "IRestFulEndpointsQueryReturn" }),
546
656
  ...sharedTypesFile ? [
547
- factory.createImportDeclaration(
548
- void 0,
549
- factory.createImportClause(
550
- false,
551
- void 0,
552
- factory.createNamespaceImport(factory.createIdentifier("SharedTypes"))
553
- ),
554
- factory.createStringLiteral(sharedTypesFile),
555
- void 0
556
- )
657
+ generateImportNode(sharedTypesImportPath, {
658
+ Scheme: "Scheme",
659
+ ...useEnumType ? { Enum: "Enum" } : {}
660
+ })
557
661
  ] : [],
558
662
  ...tag ? [generateTagTypes({ addTagTypes: extractAllTagTypes({ operationDefinitions }) })] : [],
559
663
  generateCreateApiCall({
@@ -562,17 +666,14 @@ async function generateApi(spec, {
562
666
  operationDefinitions.map(
563
667
  (operationDefinition) => generateEndpoint({
564
668
  operationDefinition,
565
- overrides: getOverrides(operationDefinition, endpointOverrides)
669
+ overrides: getOverrides(operationDefinition, endpointOverrides),
670
+ sharedTypesFile: !!sharedTypesFile
566
671
  })
567
672
  ),
568
673
  true
569
674
  )
570
675
  }),
571
- factory.createExportAssignment(
572
- void 0,
573
- void 0,
574
- factory.createIdentifier(generatedApiName)
575
- ),
676
+ factory.createExportAssignment(void 0, void 0, factory.createIdentifier(generatedApiName)),
576
677
  ...Object.values(interfaces),
577
678
  ...sharedTypesFile ? [] : [...apiGen.aliases, ...apiGen.enumAliases],
578
679
  ...hooks ? [
@@ -601,7 +702,8 @@ async function generateApi(spec, {
601
702
  }
602
703
  function generateEndpoint({
603
704
  operationDefinition,
604
- overrides
705
+ overrides,
706
+ sharedTypesFile: sharedTypesFile2
605
707
  }) {
606
708
  const {
607
709
  verb,
@@ -610,60 +712,30 @@ async function generateApi(spec, {
610
712
  operation,
611
713
  operation: { responses, requestBody }
612
714
  } = operationDefinition;
613
- const operationName = getOperationName2({ verb, path: path4, operation });
715
+ const operationName = getOperationName2({ verb, path: path4 });
614
716
  const tags = tag ? getTags({ verb, pathItem }) : [];
615
717
  const isQuery2 = isQuery(verb, overrides);
616
718
  const returnsJson = apiGen.getResponseType(responses) === "json";
617
719
  let ResponseType = factory.createKeywordTypeNode(import_typescript4.default.SyntaxKind.UnknownKeyword);
618
- function replaceReferences(schema) {
619
- if (!schema) return factory.createKeywordTypeNode(import_typescript4.default.SyntaxKind.UnknownKeyword);
620
- const refName = (0, import_generate3.getReferenceName)(schema);
621
- if (refName && sharedTypesFile) {
622
- return factory.createTypeReferenceNode(
623
- factory.createQualifiedName(
624
- factory.createIdentifier("SharedTypes"),
625
- factory.createIdentifier(refName)
626
- ),
627
- void 0
628
- );
629
- }
630
- if (schema.type === "object" && schema.properties) {
631
- const members = Object.entries(schema.properties).map(([key, value]) => {
632
- return factory.createPropertySignature(
633
- void 0,
634
- factory.createIdentifier(key),
635
- schema.required?.includes(key) ? void 0 : factory.createToken(import_typescript4.default.SyntaxKind.QuestionToken),
636
- replaceReferences(value)
637
- );
638
- });
639
- return factory.createTypeLiteralNode(members);
640
- }
641
- if (schema.type === "array" && schema.items) {
642
- return factory.createArrayTypeNode(replaceReferences(schema.items));
643
- }
644
- return apiGen.getTypeFromSchema(schema);
645
- }
646
720
  if (returnsJson) {
647
721
  const returnTypes = Object.entries(responses || {}).map(
648
- ([code, response]) => {
649
- const resolvedResponse = apiGen.resolve(response);
650
- if (!resolvedResponse.content?.["application/json"]?.schema) {
651
- return [code, resolvedResponse, factory.createKeywordTypeNode(import_typescript4.default.SyntaxKind.UndefinedKeyword)];
652
- }
653
- const schema = resolvedResponse.content["application/json"].schema;
654
- const type = replaceReferences(schema);
655
- return [code, resolvedResponse, type];
656
- }
722
+ ([code, response]) => [
723
+ code,
724
+ apiGen.resolve(response),
725
+ wrapWithSchemeIfComponent(
726
+ apiGen.getTypeFromResponse(response, "readOnly") || factory.createKeywordTypeNode(import_typescript4.default.SyntaxKind.UndefinedKeyword)
727
+ )
728
+ ]
657
729
  ).filter(
658
730
  ([status, response]) => isDataResponse(status, includeDefault, apiGen.resolve(response), responses || {})
659
- ).filter(([_1, _2, type]) => type !== import_generate3.keywordType.void).map(
660
- ([code, response, type]) => import_typescript4.default.addSyntheticLeadingComment(
661
- { ...type },
731
+ ).filter(([_1, _2, type]) => type !== import_generate3.keywordType.void).map(([code, response, type]) => {
732
+ return import_typescript4.default.addSyntheticLeadingComment(
733
+ type,
662
734
  import_typescript4.default.SyntaxKind.MultiLineCommentTrivia,
663
735
  `* status ${code} ${response.description} `,
664
736
  false
665
- )
666
- );
737
+ );
738
+ });
667
739
  if (returnTypes.length > 0) {
668
740
  ResponseType = factory.createUnionTypeNode(returnTypes);
669
741
  }
@@ -698,10 +770,23 @@ async function generateApi(spec, {
698
770
  }
699
771
  return name;
700
772
  }
773
+ for (const param of parameters) {
774
+ const name = generateName(param.name, param.in);
775
+ queryArg[name] = {
776
+ origin: "param",
777
+ name,
778
+ originalName: param.name,
779
+ type: wrapWithSchemeIfComponent(
780
+ apiGen.getTypeFromSchema((0, import_generate3.isReference)(param) ? param : param.schema, void 0, "writeOnly")
781
+ ),
782
+ required: param.required,
783
+ param
784
+ };
785
+ }
701
786
  if (requestBody) {
702
787
  const body = apiGen.resolve(requestBody);
703
788
  const schema = apiGen.getSchemaFromContent(body.content);
704
- const type = replaceReferences(schema);
789
+ const type = wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(schema));
705
790
  const schemaName = (0, import_lodash.default)(
706
791
  type.name || (0, import_generate3.getReferenceName)(schema) || typeof schema === "object" && "title" in schema && schema.title || "body"
707
792
  );
@@ -710,24 +795,11 @@ async function generateApi(spec, {
710
795
  origin: "body",
711
796
  name,
712
797
  originalName: schemaName,
713
- type,
798
+ type: wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(schema, void 0, "writeOnly")),
714
799
  required: true,
715
800
  body
716
801
  };
717
802
  }
718
- for (const param of parameters) {
719
- const name = generateName(param.name, param.in);
720
- const paramSchema = (0, import_generate3.isReference)(param) ? param : param.schema;
721
- const type = replaceReferences(paramSchema);
722
- queryArg[name] = {
723
- origin: "param",
724
- name,
725
- originalName: param.name,
726
- type,
727
- required: param.required,
728
- param
729
- };
730
- }
731
803
  const propertyName = (name) => {
732
804
  if (typeof name === "string") {
733
805
  return (0, import_generate3.isValidIdentifier)(name) ? factory.createIdentifier(name) : factory.createStringLiteral(name);
@@ -770,10 +842,7 @@ async function generateApi(spec, {
770
842
  operationName: operationNameSuffix ? capitalize(operationName + operationNameSuffix) : operationName,
771
843
  type: isQuery2 ? "query" : "mutation",
772
844
  Response: ResponseTypeName,
773
- QueryArg: factory.createTypeReferenceNode(
774
- factory.createIdentifier("IRestFulEndpointsQueryReturn"),
775
- [QueryArg]
776
- ),
845
+ QueryArg: factory.createTypeReferenceNode(factory.createIdentifier("IRestFulEndpointsQueryReturn"), [QueryArg]),
777
846
  queryFn: generateQueryFn({
778
847
  operationDefinition,
779
848
  queryArg,
@@ -794,10 +863,18 @@ async function generateApi(spec, {
794
863
  encodePathParams: encodePathParams2,
795
864
  encodeQueryParams: encodeQueryParams2
796
865
  }) {
797
- const { path: path4, verb } = operationDefinition;
866
+ const { path: path4, verb, operation } = operationDefinition;
798
867
  const bodyParameter = Object.values(queryArg).find((def) => def.origin === "body");
799
868
  const rootObject = factory.createIdentifier("queryArg");
800
869
  const variablesObject = factory.createPropertyAccessExpression(rootObject, factory.createIdentifier("variables"));
870
+ function getContentType() {
871
+ if (operation.requestBody) {
872
+ const requestBody = apiGen.resolve(operation.requestBody);
873
+ const contentTypes = Object.keys(requestBody.content || {});
874
+ return contentTypes[0];
875
+ }
876
+ return void 0;
877
+ }
801
878
  function pickParams(paramIn) {
802
879
  return Object.values(queryArg).filter((def) => def.origin === "param" && def.param.in === paramIn);
803
880
  }
@@ -821,6 +898,7 @@ async function generateApi(spec, {
821
898
  factory.createObjectLiteralExpression(properties, true)
822
899
  );
823
900
  }
901
+ const contentType = getContentType();
824
902
  return factory.createArrowFunction(
825
903
  void 0,
826
904
  void 0,
@@ -838,9 +916,16 @@ async function generateApi(spec, {
838
916
  factory.createIdentifier("method"),
839
917
  factory.createStringLiteral(verb.toUpperCase())
840
918
  ),
919
+ contentType ? factory.createPropertyAssignment(
920
+ factory.createIdentifier("contentType"),
921
+ factory.createStringLiteral(contentType)
922
+ ) : void 0,
841
923
  bodyParameter === void 0 ? void 0 : factory.createPropertyAssignment(
842
924
  factory.createIdentifier("body"),
843
- isFlatArg ? variablesObject : factory.createPropertyAccessExpression(variablesObject, factory.createIdentifier(bodyParameter.name))
925
+ isFlatArg ? variablesObject : factory.createPropertyAccessExpression(
926
+ variablesObject,
927
+ factory.createIdentifier(bodyParameter.name)
928
+ )
844
929
  ),
845
930
  createObjectLiteralProperty(pickParams("cookie"), "cookies"),
846
931
  createObjectLiteralProperty(pickParams("query"), "params"),
@@ -864,6 +949,99 @@ async function generateApi(spec, {
864
949
  function generateMutationEndpointProps({}) {
865
950
  return {};
866
951
  }
952
+ function wrapWithSchemeIfComponent(typeNode) {
953
+ if (import_typescript4.default.isTypeReferenceNode(typeNode) && import_typescript4.default.isIdentifier(typeNode.typeName)) {
954
+ const typeName = typeNode.typeName.text;
955
+ const isEnumType = useEnumType && (apiGen.enumAliases.some((enumDecl) => {
956
+ if (import_typescript4.default.isEnumDeclaration(enumDecl) || import_typescript4.default.isTypeAliasDeclaration(enumDecl)) {
957
+ return enumDecl.name.text === typeName;
958
+ }
959
+ return false;
960
+ }) || apiGen.aliases.some((alias) => {
961
+ if (import_typescript4.default.isTypeAliasDeclaration(alias) && alias.type) {
962
+ if (import_typescript4.default.isUnionTypeNode(alias.type)) {
963
+ return alias.name.text === typeName;
964
+ }
965
+ }
966
+ return false;
967
+ }));
968
+ if (isEnumType) {
969
+ return factory.createTypeReferenceNode(
970
+ factory.createQualifiedName(factory.createIdentifier("Enum"), typeNode.typeName),
971
+ typeNode.typeArguments?.map(wrapWithSchemeIfComponent)
972
+ );
973
+ }
974
+ if (schemeTypeNames.has(typeName)) {
975
+ return factory.createTypeReferenceNode(
976
+ factory.createQualifiedName(factory.createIdentifier("Scheme"), typeNode.typeName),
977
+ typeNode.typeArguments?.map(wrapWithSchemeIfComponent)
978
+ );
979
+ }
980
+ if (typeNode.typeArguments) {
981
+ return factory.createTypeReferenceNode(
982
+ typeNode.typeName,
983
+ typeNode.typeArguments.map(wrapWithSchemeIfComponent)
984
+ );
985
+ }
986
+ }
987
+ if (import_typescript4.default.isArrayTypeNode(typeNode)) {
988
+ return factory.createArrayTypeNode(wrapWithSchemeIfComponent(typeNode.elementType));
989
+ }
990
+ if (import_typescript4.default.isUnionTypeNode(typeNode)) {
991
+ const unionTypes = typeNode.types;
992
+ if (unionTypes.length > 0 && unionTypes.every(
993
+ (type) => import_typescript4.default.isLiteralTypeNode(type) && (import_typescript4.default.isStringLiteral(type.literal) || import_typescript4.default.isNumericLiteral(type.literal))
994
+ )) {
995
+ const enumValues = unionTypes.map((type) => {
996
+ if (import_typescript4.default.isLiteralTypeNode(type)) {
997
+ if (import_typescript4.default.isStringLiteral(type.literal)) {
998
+ return type.literal.text;
999
+ } else if (import_typescript4.default.isNumericLiteral(type.literal)) {
1000
+ return type.literal.text;
1001
+ }
1002
+ }
1003
+ return null;
1004
+ }).filter(Boolean);
1005
+ const matchingEnum = apiGen.aliases.find((alias) => {
1006
+ if (import_typescript4.default.isTypeAliasDeclaration(alias) && import_typescript4.default.isUnionTypeNode(alias.type)) {
1007
+ const aliasValues = alias.type.types.map((type) => {
1008
+ if (import_typescript4.default.isLiteralTypeNode(type)) {
1009
+ if (import_typescript4.default.isStringLiteral(type.literal)) {
1010
+ return type.literal.text;
1011
+ } else if (import_typescript4.default.isNumericLiteral(type.literal)) {
1012
+ return type.literal.text;
1013
+ }
1014
+ }
1015
+ return null;
1016
+ }).filter(Boolean);
1017
+ return aliasValues.length === enumValues.length && aliasValues.every((val) => enumValues.includes(val));
1018
+ }
1019
+ return false;
1020
+ });
1021
+ if (matchingEnum && import_typescript4.default.isTypeAliasDeclaration(matchingEnum)) {
1022
+ return typeNode;
1023
+ }
1024
+ }
1025
+ return factory.createUnionTypeNode(typeNode.types.map(wrapWithSchemeIfComponent));
1026
+ }
1027
+ if (import_typescript4.default.isTypeLiteralNode(typeNode)) {
1028
+ return factory.createTypeLiteralNode(
1029
+ typeNode.members.map((member) => {
1030
+ if (import_typescript4.default.isPropertySignature(member) && member.type) {
1031
+ return factory.updatePropertySignature(
1032
+ member,
1033
+ member.modifiers,
1034
+ member.name,
1035
+ member.questionToken,
1036
+ wrapWithSchemeIfComponent(member.type)
1037
+ );
1038
+ }
1039
+ return member;
1040
+ })
1041
+ );
1042
+ }
1043
+ return typeNode;
1044
+ }
867
1045
  }
868
1046
  function generatePathExpression(path4, pathParameters, rootObject, isFlatArg, encodePathParams) {
869
1047
  const expressions = [];
@@ -891,8 +1069,115 @@ function generatePathExpression(path4, pathParameters, rootObject, isFlatArg, en
891
1069
  }
892
1070
 
893
1071
  // src/index.ts
1072
+ var import_lodash2 = __toESM(require("lodash.camelcase"));
894
1073
  var require2 = (0, import_node_module.createRequire)(__filename);
1074
+ async function ensureDirectoryExists(filePath) {
1075
+ const dirname = import_node_path3.default.dirname(filePath);
1076
+ if (!import_node_fs.default.existsSync(dirname)) {
1077
+ await import_node_fs.default.promises.mkdir(dirname, { recursive: true });
1078
+ }
1079
+ }
1080
+ function fileExists(filePath) {
1081
+ try {
1082
+ return import_node_fs.default.statSync(filePath).isFile();
1083
+ } catch {
1084
+ return false;
1085
+ }
1086
+ }
1087
+ function getApiNameFromDir(dirPath) {
1088
+ const dirName = import_node_path3.default.basename(dirPath);
1089
+ return `${dirName}Api`;
1090
+ }
1091
+ async function ensureBaseFilesExist(outputDir) {
1092
+ const enhanceEndpointsPath = import_node_path3.default.join(outputDir, "enhanceEndpoints.ts");
1093
+ const indexPath = import_node_path3.default.join(outputDir, "index.ts");
1094
+ const apiName = getApiNameFromDir(outputDir);
1095
+ if (!fileExists(enhanceEndpointsPath)) {
1096
+ const enhanceEndpointsContent = `import api from './query.generated';
1097
+
1098
+ const enhancedApi = api.enhanceEndpoints({
1099
+ endpoints: {
1100
+ },
1101
+ });
1102
+
1103
+ export default enhancedApi;
1104
+ `;
1105
+ await import_node_fs.default.promises.writeFile(enhanceEndpointsPath, enhanceEndpointsContent, "utf-8");
1106
+ }
1107
+ if (!fileExists(indexPath)) {
1108
+ const indexContent = `export * from './query.generated';
1109
+ export {default as ${apiName}} from './enhanceEndpoints';
1110
+ `;
1111
+ await import_node_fs.default.promises.writeFile(indexPath, indexContent, "utf-8");
1112
+ }
1113
+ }
1114
+ function getGroupNameFromPath(path4, pattern) {
1115
+ const match = path4.match(pattern);
1116
+ if (match && match[1]) {
1117
+ return (0, import_lodash2.default)(match[1]);
1118
+ }
1119
+ return "common";
1120
+ }
895
1121
  async function generateEndpoints(options) {
1122
+ const schemaLocation = options.schemaFile;
1123
+ const schemaAbsPath = isValidUrl(options.schemaFile) ? options.schemaFile : import_node_path3.default.resolve(process.cwd(), schemaLocation);
1124
+ if (isValidUrl(options.schemaFile) && "outputFiles" in options) {
1125
+ const { outputFiles, ...commonConfig } = options;
1126
+ const openApiDoc = await getV3Doc(options.schemaFile, options.httpResolverOptions);
1127
+ const paths = Object.keys(openApiDoc.paths);
1128
+ const outputFilesEntries = Object.entries(outputFiles);
1129
+ const [outputPath, config] = outputFilesEntries[0];
1130
+ const patterns = config.groupMatch;
1131
+ const filterEndpoint = config.filterEndpoint;
1132
+ const pattern = patterns;
1133
+ const groupedPaths = paths.reduce((acc, path4) => {
1134
+ const groupName = getGroupNameFromPath(path4, pattern);
1135
+ if (!acc[groupName]) {
1136
+ acc[groupName] = [];
1137
+ }
1138
+ acc[groupName].push(path4);
1139
+ return acc;
1140
+ }, {});
1141
+ for (const [groupName, paths2] of Object.entries(groupedPaths)) {
1142
+ const finalOutputPath = outputPath.replace("$1", groupName);
1143
+ if (filterEndpoint) {
1144
+ const pathBasedFilter = (operationName, operationDefinition) => {
1145
+ const path4 = operationDefinition.path;
1146
+ const pathGroupName = getGroupNameFromPath(path4, pattern);
1147
+ if (pathGroupName !== groupName) {
1148
+ return false;
1149
+ }
1150
+ const endpointFilter = filterEndpoint(groupName);
1151
+ if (endpointFilter instanceof RegExp) {
1152
+ return endpointFilter.test(operationName);
1153
+ }
1154
+ return true;
1155
+ };
1156
+ const groupOptions = {
1157
+ ...commonConfig,
1158
+ outputFile: finalOutputPath,
1159
+ filterEndpoints: pathBasedFilter
1160
+ };
1161
+ await generateSingleEndpoint(groupOptions);
1162
+ } else {
1163
+ const pathBasedFilter = (operationName, operationDefinition) => {
1164
+ const path4 = operationDefinition.path;
1165
+ const pathGroupName = getGroupNameFromPath(path4, pattern);
1166
+ return pathGroupName === groupName;
1167
+ };
1168
+ const groupOptions = {
1169
+ ...commonConfig,
1170
+ outputFile: finalOutputPath,
1171
+ filterEndpoints: pathBasedFilter
1172
+ };
1173
+ await generateSingleEndpoint(groupOptions);
1174
+ }
1175
+ }
1176
+ return;
1177
+ }
1178
+ await generateSingleEndpoint(options);
1179
+ }
1180
+ async function generateSingleEndpoint(options) {
896
1181
  const schemaLocation = options.schemaFile;
897
1182
  const schemaAbsPath = isValidUrl(options.schemaFile) ? options.schemaFile : import_node_path3.default.resolve(process.cwd(), schemaLocation);
898
1183
  const sourceCode = await enforceOazapftsTsVersion(async () => {
@@ -900,8 +1185,12 @@ async function generateEndpoints(options) {
900
1185
  });
901
1186
  const { outputFile, prettierConfigFile } = options;
902
1187
  if (outputFile) {
1188
+ const outputPath = import_node_path3.default.resolve(process.cwd(), outputFile);
1189
+ await ensureDirectoryExists(outputPath);
1190
+ const outputDir = import_node_path3.default.dirname(outputPath);
1191
+ await ensureBaseFilesExist(outputDir);
903
1192
  import_node_fs.default.writeFileSync(
904
- import_node_path3.default.resolve(process.cwd(), outputFile),
1193
+ outputPath,
905
1194
  await prettify(outputFile, sourceCode, prettierConfigFile)
906
1195
  );
907
1196
  } else {
@@ -912,13 +1201,60 @@ function parseConfig(fullConfig) {
912
1201
  const outFiles = [];
913
1202
  if ("outputFiles" in fullConfig) {
914
1203
  const { outputFiles, ...commonConfig } = fullConfig;
915
- for (const [outputFile, specificConfig] of Object.entries(outputFiles)) {
916
- outFiles.push({
917
- ...commonConfig,
918
- ...specificConfig,
919
- outputFile
920
- });
1204
+ let openApiDoc;
1205
+ if (isValidUrl(fullConfig.schemaFile)) {
1206
+ outFiles.push(fullConfig);
1207
+ return outFiles;
1208
+ } else {
1209
+ openApiDoc = JSON.parse(import_node_fs.default.readFileSync(fullConfig.schemaFile, "utf-8"));
921
1210
  }
1211
+ const paths = Object.keys(openApiDoc.paths);
1212
+ const outputFilesEntries = Object.entries(outputFiles);
1213
+ const [outputPath, config] = outputFilesEntries[0];
1214
+ const patterns = config.groupMatch;
1215
+ const filterEndpoint = config.filterEndpoint;
1216
+ const pattern = patterns;
1217
+ const groupedPaths = paths.reduce((acc, path4) => {
1218
+ const groupName = getGroupNameFromPath(path4, pattern);
1219
+ if (!acc[groupName]) {
1220
+ acc[groupName] = [];
1221
+ }
1222
+ acc[groupName].push(path4);
1223
+ return acc;
1224
+ }, {});
1225
+ Object.entries(groupedPaths).forEach(([groupName, paths2]) => {
1226
+ const finalOutputPath = outputPath.replace("$1", groupName);
1227
+ if (filterEndpoint) {
1228
+ const pathBasedFilter = (operationName, operationDefinition) => {
1229
+ const path4 = operationDefinition.path;
1230
+ const pathGroupName = getGroupNameFromPath(path4, pattern);
1231
+ if (pathGroupName !== groupName) {
1232
+ return false;
1233
+ }
1234
+ const endpointFilter = filterEndpoint(groupName);
1235
+ if (endpointFilter instanceof RegExp) {
1236
+ return endpointFilter.test(operationName);
1237
+ }
1238
+ return true;
1239
+ };
1240
+ outFiles.push({
1241
+ ...commonConfig,
1242
+ outputFile: finalOutputPath,
1243
+ filterEndpoints: pathBasedFilter
1244
+ });
1245
+ } else {
1246
+ const pathBasedFilter = (operationName, operationDefinition) => {
1247
+ const path4 = operationDefinition.path;
1248
+ const pathGroupName = getGroupNameFromPath(path4, pattern);
1249
+ return pathGroupName === groupName;
1250
+ };
1251
+ outFiles.push({
1252
+ ...commonConfig,
1253
+ outputFile: finalOutputPath,
1254
+ filterEndpoints: pathBasedFilter
1255
+ });
1256
+ }
1257
+ });
922
1258
  } else {
923
1259
  outFiles.push(fullConfig);
924
1260
  }