@acrool/rtk-query-codegen-openapi 0.0.2-test.8 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.mjs CHANGED
@@ -305,14 +305,14 @@ function removeUndefined(t) {
305
305
 
306
306
  // src/generators/react-hooks.ts
307
307
  var createBinding = ({
308
- operationDefinition: { verb, path: path4 },
308
+ operationDefinition: { verb, path: path4, operation },
309
309
  overrides,
310
310
  isLazy = false
311
311
  }) => factory.createBindingElement(
312
312
  void 0,
313
313
  void 0,
314
314
  factory.createIdentifier(
315
- `use${isLazy ? "Lazy" : ""}${capitalize(getOperationName(verb, path4, void 0))}${isQuery(verb, overrides) ? "Query" : "Mutation"}`
315
+ `use${isLazy ? "Lazy" : ""}${capitalize(getOperationName(verb, path4, operation.operationId))}${isQuery(verb, overrides) ? "Query" : "Mutation"}`
316
316
  ),
317
317
  void 0
318
318
  );
@@ -366,8 +366,8 @@ function defaultIsDataResponse(code, includeDefault) {
366
366
  const parsedCode = Number(code);
367
367
  return !Number.isNaN(parsedCode) && parsedCode >= 200 && parsedCode < 300;
368
368
  }
369
- function getOperationName2({ verb, path: path4 }) {
370
- return _getOperationName(verb, path4, void 0);
369
+ function getOperationName2({ verb, path: path4, operation }) {
370
+ return _getOperationName(verb, path4, operation.operationId);
371
371
  }
372
372
  function getTags({ verb, pathItem }) {
373
373
  return verb ? pathItem[verb]?.tags || [] : [];
@@ -441,61 +441,41 @@ async function generateApi(spec, {
441
441
  useEnumType,
442
442
  mergeReadWriteOnly
443
443
  });
444
- const schemeTypeNames = /* @__PURE__ */ new Set();
445
- function addSchemeTypeName(name) {
446
- schemeTypeNames.add(name);
447
- schemeTypeNames.add(camelCase(name));
448
- schemeTypeNames.add(capitalize(camelCase(name)));
449
- }
450
444
  if (sharedTypesFile) {
451
- const resultFile2 = ts4.createSourceFile(
452
- "sharedTypes.ts",
453
- "",
454
- ts4.ScriptTarget.Latest,
455
- /*setParentNodes*/
456
- false,
457
- ts4.ScriptKind.TS
458
- );
459
- const printer2 = ts4.createPrinter({ newLine: ts4.NewLineKind.LineFeed });
460
- const allTypeDefinitions = [];
461
445
  const components = v3Doc.components;
462
446
  if (components) {
463
- const componentDefinitions = Object.entries(components).map(([componentType, componentDefs]) => {
464
- const typeEntries = Object.entries(componentDefs).map(([name, def]) => {
465
- addSchemeTypeName(name);
466
- const typeName = capitalize(camelCase(name));
467
- const typeNode = wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(def));
447
+ const resultFile2 = ts4.createSourceFile(
448
+ "sharedTypes.ts",
449
+ "",
450
+ ts4.ScriptTarget.Latest,
451
+ /*setParentNodes*/
452
+ false,
453
+ ts4.ScriptKind.TS
454
+ );
455
+ const printer2 = ts4.createPrinter({ newLine: ts4.NewLineKind.LineFeed });
456
+ const typeDefinitions = Object.entries(components).flatMap(([_, componentDefs]) => {
457
+ return Object.entries(componentDefs).map(([name, def]) => {
458
+ const typeNode = apiGen.getTypeFromSchema(def);
468
459
  return factory.createTypeAliasDeclaration(
469
460
  [factory.createModifier(ts4.SyntaxKind.ExportKeyword)],
470
- factory.createIdentifier(typeName),
461
+ factory.createIdentifier(name),
471
462
  void 0,
472
463
  typeNode
473
464
  );
474
465
  });
475
- return factory.createModuleDeclaration(
476
- [factory.createModifier(ts4.SyntaxKind.ExportKeyword)],
477
- factory.createIdentifier("Scheme"),
478
- factory.createModuleBlock(typeEntries),
479
- ts4.NodeFlags.Namespace
480
- );
481
466
  });
482
- allTypeDefinitions.push(...componentDefinitions);
483
- }
484
- if (useEnumType) {
485
- allTypeDefinitions.push(...apiGen.enumAliases);
467
+ const output = printer2.printNode(
468
+ ts4.EmitHint.Unspecified,
469
+ factory.createSourceFile(
470
+ typeDefinitions,
471
+ factory.createToken(ts4.SyntaxKind.EndOfFileToken),
472
+ ts4.NodeFlags.None
473
+ ),
474
+ resultFile2
475
+ );
476
+ const fs2 = await import("node:fs/promises");
477
+ await fs2.writeFile(sharedTypesFile, output, "utf-8");
486
478
  }
487
- allTypeDefinitions.push(...apiGen.aliases);
488
- const output = printer2.printNode(
489
- ts4.EmitHint.Unspecified,
490
- factory.createSourceFile(
491
- allTypeDefinitions,
492
- factory.createToken(ts4.SyntaxKind.EndOfFileToken),
493
- ts4.NodeFlags.None
494
- ),
495
- resultFile2
496
- );
497
- const fs2 = await import("node:fs/promises");
498
- await fs2.writeFile(sharedTypesFile, output, "utf-8");
499
479
  }
500
480
  if (apiGen.spec.components?.schemas) {
501
481
  apiGen.preprocessComponents(apiGen.spec.components.schemas);
@@ -526,20 +506,34 @@ async function generateApi(spec, {
526
506
  apiFile = apiFile.replace(/\\/g, "/");
527
507
  if (!apiFile.startsWith(".")) apiFile = `./${apiFile}`;
528
508
  }
509
+ if (sharedTypesFile && sharedTypesFile.startsWith(".")) {
510
+ sharedTypesFile = path2.relative(path2.dirname(outputFile), sharedTypesFile);
511
+ sharedTypesFile = sharedTypesFile.replace(/\\/g, "/");
512
+ if (!sharedTypesFile.startsWith(".")) sharedTypesFile = `./${sharedTypesFile}`;
513
+ }
529
514
  }
530
515
  apiFile = apiFile.replace(/\.[jt]sx?$/, "");
531
- const sharedTypesImportPath = sharedTypesFile && outputFile ? (() => {
532
- let rel = path2.relative(path2.dirname(outputFile), sharedTypesFile).replace(/\\/g, "/").replace(/\.[jt]sx?$/, "");
533
- if (!rel.startsWith(".")) rel = "./" + rel;
534
- return rel;
535
- })() : "./shared-types";
516
+ if (sharedTypesFile) {
517
+ sharedTypesFile = sharedTypesFile.replace(/\.[jt]sx?$/, "");
518
+ }
536
519
  return printer.printNode(
537
520
  ts4.EmitHint.Unspecified,
538
521
  factory.createSourceFile(
539
522
  [
540
523
  generateImportNode(apiFile, { [apiImport]: "api" }),
541
524
  generateImportNode("@acrool/react-fetcher", { IRestFulEndpointsQueryReturn: "IRestFulEndpointsQueryReturn" }),
542
- ...sharedTypesFile ? [generateImportNode(sharedTypesImportPath, { Scheme: "Scheme" })] : [],
525
+ ...sharedTypesFile ? [
526
+ factory.createImportDeclaration(
527
+ void 0,
528
+ factory.createImportClause(
529
+ false,
530
+ void 0,
531
+ factory.createNamespaceImport(factory.createIdentifier("SharedTypes"))
532
+ ),
533
+ factory.createStringLiteral(sharedTypesFile),
534
+ void 0
535
+ )
536
+ ] : [],
543
537
  ...tag ? [generateTagTypes({ addTagTypes: extractAllTagTypes({ operationDefinitions }) })] : [],
544
538
  generateCreateApiCall({
545
539
  tag,
@@ -547,8 +541,7 @@ async function generateApi(spec, {
547
541
  operationDefinitions.map(
548
542
  (operationDefinition) => generateEndpoint({
549
543
  operationDefinition,
550
- overrides: getOverrides(operationDefinition, endpointOverrides),
551
- sharedTypesFile: !!sharedTypesFile
544
+ overrides: getOverrides(operationDefinition, endpointOverrides)
552
545
  })
553
546
  ),
554
547
  true
@@ -587,8 +580,7 @@ async function generateApi(spec, {
587
580
  }
588
581
  function generateEndpoint({
589
582
  operationDefinition,
590
- overrides,
591
- sharedTypesFile: sharedTypesFile2
583
+ overrides
592
584
  }) {
593
585
  const {
594
586
  verb,
@@ -597,49 +589,60 @@ async function generateApi(spec, {
597
589
  operation,
598
590
  operation: { responses, requestBody }
599
591
  } = operationDefinition;
600
- const operationName = getOperationName2({ verb, path: path4 });
592
+ const operationName = getOperationName2({ verb, path: path4, operation });
601
593
  const tags = tag ? getTags({ verb, pathItem }) : [];
602
594
  const isQuery2 = isQuery(verb, overrides);
603
595
  const returnsJson = apiGen.getResponseType(responses) === "json";
604
596
  let ResponseType = factory.createKeywordTypeNode(ts4.SyntaxKind.UnknownKeyword);
597
+ function replaceReferences(schema) {
598
+ if (!schema) return factory.createKeywordTypeNode(ts4.SyntaxKind.UnknownKeyword);
599
+ const refName = getReferenceName(schema);
600
+ if (refName && sharedTypesFile) {
601
+ return factory.createTypeReferenceNode(
602
+ factory.createQualifiedName(
603
+ factory.createIdentifier("SharedTypes"),
604
+ factory.createIdentifier(refName)
605
+ ),
606
+ void 0
607
+ );
608
+ }
609
+ if (schema.type === "object" && schema.properties) {
610
+ const members = Object.entries(schema.properties).map(([key, value]) => {
611
+ return factory.createPropertySignature(
612
+ void 0,
613
+ factory.createIdentifier(key),
614
+ schema.required?.includes(key) ? void 0 : factory.createToken(ts4.SyntaxKind.QuestionToken),
615
+ replaceReferences(value)
616
+ );
617
+ });
618
+ return factory.createTypeLiteralNode(members);
619
+ }
620
+ if (schema.type === "array" && schema.items) {
621
+ return factory.createArrayTypeNode(replaceReferences(schema.items));
622
+ }
623
+ return apiGen.getTypeFromSchema(schema);
624
+ }
605
625
  if (returnsJson) {
606
626
  const returnTypes = Object.entries(responses || {}).map(
607
- ([code, response]) => [
608
- code,
609
- apiGen.resolve(response),
610
- wrapWithSchemeIfComponent(
611
- apiGen.getTypeFromResponse(response, "readOnly") || factory.createKeywordTypeNode(ts4.SyntaxKind.UndefinedKeyword)
612
- )
613
- ]
614
- ).filter(
615
- ([status, response]) => isDataResponse(status, includeDefault, apiGen.resolve(response), responses || {})
616
- ).filter(([_1, _2, type]) => type !== keywordType.void).map(([code, response, type]) => {
617
- if (sharedTypesFile2 && ts4.isTypeReferenceNode(type) && type.typeName) {
618
- if (ts4.isIdentifier(type.typeName)) {
619
- const typeName = type.typeName.text;
620
- if (typeName in apiGen.aliases || typeName in apiGen.enumAliases) {
621
- return ts4.addSyntheticLeadingComment(
622
- factory.createTypeReferenceNode(
623
- factory.createQualifiedName(
624
- factory.createIdentifier("sharedTypes"),
625
- factory.createIdentifier(camelCase(typeName))
626
- ),
627
- type.typeArguments
628
- ),
629
- ts4.SyntaxKind.MultiLineCommentTrivia,
630
- `* status ${code} ${response.description} `,
631
- false
632
- );
633
- }
627
+ ([code, response]) => {
628
+ const resolvedResponse = apiGen.resolve(response);
629
+ if (!resolvedResponse.content?.["application/json"]?.schema) {
630
+ return [code, resolvedResponse, factory.createKeywordTypeNode(ts4.SyntaxKind.UndefinedKeyword)];
634
631
  }
632
+ const schema = resolvedResponse.content["application/json"].schema;
633
+ const type = replaceReferences(schema);
634
+ return [code, resolvedResponse, type];
635
635
  }
636
- return ts4.addSyntheticLeadingComment(
637
- type,
636
+ ).filter(
637
+ ([status, response]) => isDataResponse(status, includeDefault, apiGen.resolve(response), responses || {})
638
+ ).filter(([_1, _2, type]) => type !== keywordType.void).map(
639
+ ([code, response, type]) => ts4.addSyntheticLeadingComment(
640
+ { ...type },
638
641
  ts4.SyntaxKind.MultiLineCommentTrivia,
639
642
  `* status ${code} ${response.description} `,
640
643
  false
641
- );
642
- });
644
+ )
645
+ );
643
646
  if (returnTypes.length > 0) {
644
647
  ResponseType = factory.createUnionTypeNode(returnTypes);
645
648
  }
@@ -674,21 +677,10 @@ async function generateApi(spec, {
674
677
  }
675
678
  return name;
676
679
  }
677
- for (const param of parameters) {
678
- const name = generateName(param.name, param.in);
679
- queryArg[name] = {
680
- origin: "param",
681
- name,
682
- originalName: param.name,
683
- type: wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(isReference(param) ? param : param.schema, void 0, "writeOnly")),
684
- required: param.required,
685
- param
686
- };
687
- }
688
680
  if (requestBody) {
689
681
  const body = apiGen.resolve(requestBody);
690
682
  const schema = apiGen.getSchemaFromContent(body.content);
691
- const type = wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(schema));
683
+ const type = replaceReferences(schema);
692
684
  const schemaName = camelCase(
693
685
  type.name || getReferenceName(schema) || typeof schema === "object" && "title" in schema && schema.title || "body"
694
686
  );
@@ -697,11 +689,24 @@ async function generateApi(spec, {
697
689
  origin: "body",
698
690
  name,
699
691
  originalName: schemaName,
700
- type: wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(schema, void 0, "writeOnly")),
692
+ type,
701
693
  required: true,
702
694
  body
703
695
  };
704
696
  }
697
+ for (const param of parameters) {
698
+ const name = generateName(param.name, param.in);
699
+ const paramSchema = isReference(param) ? param : param.schema;
700
+ const type = replaceReferences(paramSchema);
701
+ queryArg[name] = {
702
+ origin: "param",
703
+ name,
704
+ originalName: param.name,
705
+ type,
706
+ required: param.required,
707
+ param
708
+ };
709
+ }
705
710
  const propertyName = (name) => {
706
711
  if (typeof name === "string") {
707
712
  return isValidIdentifier(name) ? factory.createIdentifier(name) : factory.createStringLiteral(name);
@@ -838,49 +843,6 @@ async function generateApi(spec, {
838
843
  function generateMutationEndpointProps({}) {
839
844
  return {};
840
845
  }
841
- function wrapWithSchemeIfComponent(typeNode) {
842
- if (ts4.isTypeReferenceNode(typeNode) && ts4.isIdentifier(typeNode.typeName)) {
843
- const typeName = typeNode.typeName.text;
844
- if (schemeTypeNames.has(typeName)) {
845
- return factory.createTypeReferenceNode(
846
- factory.createQualifiedName(
847
- factory.createIdentifier("Scheme"),
848
- typeNode.typeName
849
- ),
850
- typeNode.typeArguments?.map(wrapWithSchemeIfComponent)
851
- );
852
- }
853
- if (typeNode.typeArguments) {
854
- return factory.createTypeReferenceNode(
855
- typeNode.typeName,
856
- typeNode.typeArguments.map(wrapWithSchemeIfComponent)
857
- );
858
- }
859
- }
860
- if (ts4.isArrayTypeNode(typeNode)) {
861
- return factory.createArrayTypeNode(wrapWithSchemeIfComponent(typeNode.elementType));
862
- }
863
- if (ts4.isUnionTypeNode(typeNode)) {
864
- return factory.createUnionTypeNode(typeNode.types.map(wrapWithSchemeIfComponent));
865
- }
866
- if (ts4.isTypeLiteralNode(typeNode)) {
867
- return factory.createTypeLiteralNode(
868
- typeNode.members.map((member) => {
869
- if (ts4.isPropertySignature(member) && member.type) {
870
- return factory.updatePropertySignature(
871
- member,
872
- member.modifiers,
873
- member.name,
874
- member.questionToken,
875
- wrapWithSchemeIfComponent(member.type)
876
- );
877
- }
878
- return member;
879
- })
880
- );
881
- }
882
- return typeNode;
883
- }
884
846
  }
885
847
  function generatePathExpression(path4, pathParameters, rootObject, isFlatArg, encodePathParams) {
886
848
  const expressions = [];
@@ -908,55 +870,7 @@ function generatePathExpression(path4, pathParameters, rootObject, isFlatArg, en
908
870
  }
909
871
 
910
872
  // src/index.ts
911
- import camelCase2 from "lodash.camelcase";
912
873
  var require2 = createRequire(__filename);
913
- async function ensureDirectoryExists(filePath) {
914
- const dirname = path3.dirname(filePath);
915
- if (!fs.existsSync(dirname)) {
916
- await fs.promises.mkdir(dirname, { recursive: true });
917
- }
918
- }
919
- function fileExists(filePath) {
920
- try {
921
- return fs.statSync(filePath).isFile();
922
- } catch {
923
- return false;
924
- }
925
- }
926
- function getApiNameFromDir(dirPath) {
927
- const dirName = path3.basename(dirPath);
928
- return `${dirName}Api`;
929
- }
930
- async function ensureBaseFilesExist(outputDir) {
931
- const enhanceEndpointsPath = path3.join(outputDir, "enhanceEndpoints.ts");
932
- const indexPath = path3.join(outputDir, "index.ts");
933
- const apiName = getApiNameFromDir(outputDir);
934
- if (!fileExists(enhanceEndpointsPath)) {
935
- const enhanceEndpointsContent = `import api from './query.generated';
936
-
937
- const enhancedApi = api.enhanceEndpoints({
938
- endpoints: {
939
- },
940
- });
941
-
942
- export default enhancedApi;
943
- `;
944
- await fs.promises.writeFile(enhanceEndpointsPath, enhanceEndpointsContent, "utf-8");
945
- }
946
- if (!fileExists(indexPath)) {
947
- const indexContent = `export * from './query.generated';
948
- export {default as ${apiName}} from './enhanceEndpoints';
949
- `;
950
- await fs.promises.writeFile(indexPath, indexContent, "utf-8");
951
- }
952
- }
953
- function getGroupNameFromPath(path4, pattern) {
954
- const match = path4.match(pattern);
955
- if (match && match[1]) {
956
- return camelCase2(match[1]);
957
- }
958
- return "common";
959
- }
960
874
  async function generateEndpoints(options) {
961
875
  const schemaLocation = options.schemaFile;
962
876
  const schemaAbsPath = isValidUrl(options.schemaFile) ? options.schemaFile : path3.resolve(process.cwd(), schemaLocation);
@@ -965,12 +879,8 @@ async function generateEndpoints(options) {
965
879
  });
966
880
  const { outputFile, prettierConfigFile } = options;
967
881
  if (outputFile) {
968
- const outputPath = path3.resolve(process.cwd(), outputFile);
969
- await ensureDirectoryExists(outputPath);
970
- const outputDir = path3.dirname(outputPath);
971
- await ensureBaseFilesExist(outputDir);
972
882
  fs.writeFileSync(
973
- outputPath,
883
+ path3.resolve(process.cwd(), outputFile),
974
884
  await prettify(outputFile, sourceCode, prettierConfigFile)
975
885
  );
976
886
  } else {
@@ -981,53 +891,13 @@ function parseConfig(fullConfig) {
981
891
  const outFiles = [];
982
892
  if ("outputFiles" in fullConfig) {
983
893
  const { outputFiles, ...commonConfig } = fullConfig;
984
- const openApiDoc = JSON.parse(fs.readFileSync(fullConfig.schemaFile, "utf-8"));
985
- const paths = Object.keys(openApiDoc.paths);
986
- const [outputPath, config] = Object.entries(outputFiles)[0];
987
- const patterns = config.groupMatch;
988
- const filterEndpoint = config.filterEndpoint;
989
- const pattern = patterns;
990
- const groupedPaths = paths.reduce((acc, path4) => {
991
- const groupName = getGroupNameFromPath(path4, pattern);
992
- if (!acc[groupName]) {
993
- acc[groupName] = [];
994
- }
995
- acc[groupName].push(path4);
996
- return acc;
997
- }, {});
998
- Object.entries(groupedPaths).forEach(([groupName, paths2]) => {
999
- const finalOutputPath = outputPath.replace("$1", groupName);
1000
- if (filterEndpoint) {
1001
- const pathBasedFilter = (operationName, operationDefinition) => {
1002
- const path4 = operationDefinition.path;
1003
- const pathGroupName = getGroupNameFromPath(path4, pattern);
1004
- if (pathGroupName !== groupName) {
1005
- return false;
1006
- }
1007
- const endpointFilter = filterEndpoint(groupName);
1008
- if (endpointFilter instanceof RegExp) {
1009
- return endpointFilter.test(operationName);
1010
- }
1011
- return true;
1012
- };
1013
- outFiles.push({
1014
- ...commonConfig,
1015
- outputFile: finalOutputPath,
1016
- filterEndpoints: pathBasedFilter
1017
- });
1018
- } else {
1019
- const pathBasedFilter = (operationName, operationDefinition) => {
1020
- const path4 = operationDefinition.path;
1021
- const pathGroupName = getGroupNameFromPath(path4, pattern);
1022
- return pathGroupName === groupName;
1023
- };
1024
- outFiles.push({
1025
- ...commonConfig,
1026
- outputFile: finalOutputPath,
1027
- filterEndpoints: pathBasedFilter
1028
- });
1029
- }
1030
- });
894
+ for (const [outputFile, specificConfig] of Object.entries(outputFiles)) {
895
+ outFiles.push({
896
+ ...commonConfig,
897
+ ...specificConfig,
898
+ outputFile
899
+ });
900
+ }
1031
901
  } else {
1032
902
  outFiles.push(fullConfig);
1033
903
  }