@acrool/rtk-query-codegen-openapi 0.0.2-test.5 → 0.0.2-test.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/README.md +1 -0
- package/lib/index.d.mts +9 -4
- package/lib/index.d.ts +9 -4
- package/lib/index.js +220 -24
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +220 -24
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/generate.ts +162 -23
- package/src/generators/react-hooks.ts +2 -2
- package/src/index.ts +120 -8
- package/src/types.ts +10 -1
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 },
|
|
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,
|
|
315
|
+
`use${isLazy ? "Lazy" : ""}${capitalize(getOperationName(verb, path4, void 0))}${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,
|
|
369
|
+
function getOperationName2({ verb, path: path4 }) {
|
|
370
|
+
return _getOperationName(verb, path4, void 0);
|
|
371
371
|
}
|
|
372
372
|
function getTags({ verb, pathItem }) {
|
|
373
373
|
return verb ? pathItem[verb]?.tags || [] : [];
|
|
@@ -432,7 +432,8 @@ async function generateApi(spec, {
|
|
|
432
432
|
includeDefault = false,
|
|
433
433
|
useEnumType = false,
|
|
434
434
|
mergeReadWriteOnly = false,
|
|
435
|
-
httpResolverOptions
|
|
435
|
+
httpResolverOptions,
|
|
436
|
+
sharedTypesFile
|
|
436
437
|
}) {
|
|
437
438
|
const v3Doc = v3DocCache[spec] ??= await getV3Doc(spec, httpResolverOptions);
|
|
438
439
|
const apiGen = new ApiGenerator(v3Doc, {
|
|
@@ -440,6 +441,62 @@ async function generateApi(spec, {
|
|
|
440
441
|
useEnumType,
|
|
441
442
|
mergeReadWriteOnly
|
|
442
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
|
+
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
|
+
const components = v3Doc.components;
|
|
462
|
+
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));
|
|
468
|
+
return factory.createTypeAliasDeclaration(
|
|
469
|
+
[factory.createModifier(ts4.SyntaxKind.ExportKeyword)],
|
|
470
|
+
factory.createIdentifier(typeName),
|
|
471
|
+
void 0,
|
|
472
|
+
typeNode
|
|
473
|
+
);
|
|
474
|
+
});
|
|
475
|
+
return factory.createModuleDeclaration(
|
|
476
|
+
[factory.createModifier(ts4.SyntaxKind.ExportKeyword)],
|
|
477
|
+
factory.createIdentifier("Scheme"),
|
|
478
|
+
factory.createModuleBlock(typeEntries),
|
|
479
|
+
ts4.NodeFlags.Namespace
|
|
480
|
+
);
|
|
481
|
+
});
|
|
482
|
+
allTypeDefinitions.push(...componentDefinitions);
|
|
483
|
+
}
|
|
484
|
+
if (useEnumType) {
|
|
485
|
+
allTypeDefinitions.push(...apiGen.enumAliases);
|
|
486
|
+
}
|
|
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
|
+
}
|
|
443
500
|
if (apiGen.spec.components?.schemas) {
|
|
444
501
|
apiGen.preprocessComponents(apiGen.spec.components.schemas);
|
|
445
502
|
}
|
|
@@ -471,12 +528,18 @@ async function generateApi(spec, {
|
|
|
471
528
|
}
|
|
472
529
|
}
|
|
473
530
|
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";
|
|
474
536
|
return printer.printNode(
|
|
475
537
|
ts4.EmitHint.Unspecified,
|
|
476
538
|
factory.createSourceFile(
|
|
477
539
|
[
|
|
478
540
|
generateImportNode(apiFile, { [apiImport]: "api" }),
|
|
479
541
|
generateImportNode("@acrool/react-fetcher", { IRestFulEndpointsQueryReturn: "IRestFulEndpointsQueryReturn" }),
|
|
542
|
+
...sharedTypesFile ? [generateImportNode(sharedTypesImportPath, { Scheme: "Scheme" })] : [],
|
|
480
543
|
...tag ? [generateTagTypes({ addTagTypes: extractAllTagTypes({ operationDefinitions }) })] : [],
|
|
481
544
|
generateCreateApiCall({
|
|
482
545
|
tag,
|
|
@@ -484,7 +547,8 @@ async function generateApi(spec, {
|
|
|
484
547
|
operationDefinitions.map(
|
|
485
548
|
(operationDefinition) => generateEndpoint({
|
|
486
549
|
operationDefinition,
|
|
487
|
-
overrides: getOverrides(operationDefinition, endpointOverrides)
|
|
550
|
+
overrides: getOverrides(operationDefinition, endpointOverrides),
|
|
551
|
+
sharedTypesFile: !!sharedTypesFile
|
|
488
552
|
})
|
|
489
553
|
),
|
|
490
554
|
true
|
|
@@ -496,8 +560,7 @@ async function generateApi(spec, {
|
|
|
496
560
|
factory.createIdentifier(generatedApiName)
|
|
497
561
|
),
|
|
498
562
|
...Object.values(interfaces),
|
|
499
|
-
...apiGen.aliases,
|
|
500
|
-
...apiGen.enumAliases,
|
|
563
|
+
...sharedTypesFile ? [] : [...apiGen.aliases, ...apiGen.enumAliases],
|
|
501
564
|
...hooks ? [
|
|
502
565
|
generateReactHooks({
|
|
503
566
|
exportName: generatedApiName,
|
|
@@ -524,7 +587,8 @@ async function generateApi(spec, {
|
|
|
524
587
|
}
|
|
525
588
|
function generateEndpoint({
|
|
526
589
|
operationDefinition,
|
|
527
|
-
overrides
|
|
590
|
+
overrides,
|
|
591
|
+
sharedTypesFile: sharedTypesFile2
|
|
528
592
|
}) {
|
|
529
593
|
const {
|
|
530
594
|
verb,
|
|
@@ -533,7 +597,7 @@ async function generateApi(spec, {
|
|
|
533
597
|
operation,
|
|
534
598
|
operation: { responses, requestBody }
|
|
535
599
|
} = operationDefinition;
|
|
536
|
-
const operationName = getOperationName2({ verb, path: path4
|
|
600
|
+
const operationName = getOperationName2({ verb, path: path4 });
|
|
537
601
|
const tags = tag ? getTags({ verb, pathItem }) : [];
|
|
538
602
|
const isQuery2 = isQuery(verb, overrides);
|
|
539
603
|
const returnsJson = apiGen.getResponseType(responses) === "json";
|
|
@@ -543,18 +607,39 @@ async function generateApi(spec, {
|
|
|
543
607
|
([code, response]) => [
|
|
544
608
|
code,
|
|
545
609
|
apiGen.resolve(response),
|
|
546
|
-
|
|
610
|
+
wrapWithSchemeIfComponent(
|
|
611
|
+
apiGen.getTypeFromResponse(response, "readOnly") || factory.createKeywordTypeNode(ts4.SyntaxKind.UndefinedKeyword)
|
|
612
|
+
)
|
|
547
613
|
]
|
|
548
614
|
).filter(
|
|
549
615
|
([status, response]) => isDataResponse(status, includeDefault, apiGen.resolve(response), responses || {})
|
|
550
|
-
).filter(([_1, _2, type]) => type !== keywordType.void).map(
|
|
551
|
-
(
|
|
552
|
-
|
|
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
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
return ts4.addSyntheticLeadingComment(
|
|
637
|
+
type,
|
|
553
638
|
ts4.SyntaxKind.MultiLineCommentTrivia,
|
|
554
639
|
`* status ${code} ${response.description} `,
|
|
555
640
|
false
|
|
556
|
-
)
|
|
557
|
-
);
|
|
641
|
+
);
|
|
642
|
+
});
|
|
558
643
|
if (returnTypes.length > 0) {
|
|
559
644
|
ResponseType = factory.createUnionTypeNode(returnTypes);
|
|
560
645
|
}
|
|
@@ -595,7 +680,7 @@ async function generateApi(spec, {
|
|
|
595
680
|
origin: "param",
|
|
596
681
|
name,
|
|
597
682
|
originalName: param.name,
|
|
598
|
-
type: apiGen.getTypeFromSchema(isReference(param) ? param : param.schema, void 0, "writeOnly"),
|
|
683
|
+
type: wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(isReference(param) ? param : param.schema, void 0, "writeOnly")),
|
|
599
684
|
required: param.required,
|
|
600
685
|
param
|
|
601
686
|
};
|
|
@@ -603,7 +688,7 @@ async function generateApi(spec, {
|
|
|
603
688
|
if (requestBody) {
|
|
604
689
|
const body = apiGen.resolve(requestBody);
|
|
605
690
|
const schema = apiGen.getSchemaFromContent(body.content);
|
|
606
|
-
const type = apiGen.getTypeFromSchema(schema);
|
|
691
|
+
const type = wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(schema));
|
|
607
692
|
const schemaName = camelCase(
|
|
608
693
|
type.name || getReferenceName(schema) || typeof schema === "object" && "title" in schema && schema.title || "body"
|
|
609
694
|
);
|
|
@@ -612,7 +697,7 @@ async function generateApi(spec, {
|
|
|
612
697
|
origin: "body",
|
|
613
698
|
name,
|
|
614
699
|
originalName: schemaName,
|
|
615
|
-
type: apiGen.getTypeFromSchema(schema, void 0, "writeOnly"),
|
|
700
|
+
type: wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(schema, void 0, "writeOnly")),
|
|
616
701
|
required: true,
|
|
617
702
|
body
|
|
618
703
|
};
|
|
@@ -753,6 +838,49 @@ async function generateApi(spec, {
|
|
|
753
838
|
function generateMutationEndpointProps({}) {
|
|
754
839
|
return {};
|
|
755
840
|
}
|
|
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
|
+
}
|
|
756
884
|
}
|
|
757
885
|
function generatePathExpression(path4, pathParameters, rootObject, isFlatArg, encodePathParams) {
|
|
758
886
|
const expressions = [];
|
|
@@ -780,7 +908,55 @@ function generatePathExpression(path4, pathParameters, rootObject, isFlatArg, en
|
|
|
780
908
|
}
|
|
781
909
|
|
|
782
910
|
// src/index.ts
|
|
911
|
+
import camelCase2 from "lodash.camelcase";
|
|
783
912
|
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
|
+
}
|
|
784
960
|
async function generateEndpoints(options) {
|
|
785
961
|
const schemaLocation = options.schemaFile;
|
|
786
962
|
const schemaAbsPath = isValidUrl(options.schemaFile) ? options.schemaFile : path3.resolve(process.cwd(), schemaLocation);
|
|
@@ -789,8 +965,12 @@ async function generateEndpoints(options) {
|
|
|
789
965
|
});
|
|
790
966
|
const { outputFile, prettierConfigFile } = options;
|
|
791
967
|
if (outputFile) {
|
|
968
|
+
const outputPath = path3.resolve(process.cwd(), outputFile);
|
|
969
|
+
await ensureDirectoryExists(outputPath);
|
|
970
|
+
const outputDir = path3.dirname(outputPath);
|
|
971
|
+
await ensureBaseFilesExist(outputDir);
|
|
792
972
|
fs.writeFileSync(
|
|
793
|
-
|
|
973
|
+
outputPath,
|
|
794
974
|
await prettify(outputFile, sourceCode, prettierConfigFile)
|
|
795
975
|
);
|
|
796
976
|
} else {
|
|
@@ -801,13 +981,29 @@ function parseConfig(fullConfig) {
|
|
|
801
981
|
const outFiles = [];
|
|
802
982
|
if ("outputFiles" in fullConfig) {
|
|
803
983
|
const { outputFiles, ...commonConfig } = fullConfig;
|
|
804
|
-
|
|
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
|
+
const filterEndpoints = filterEndpoint(groupName);
|
|
805
1001
|
outFiles.push({
|
|
806
1002
|
...commonConfig,
|
|
807
|
-
|
|
808
|
-
|
|
1003
|
+
outputFile: finalOutputPath,
|
|
1004
|
+
filterEndpoints: [filterEndpoints]
|
|
809
1005
|
});
|
|
810
|
-
}
|
|
1006
|
+
});
|
|
811
1007
|
} else {
|
|
812
1008
|
outFiles.push(fullConfig);
|
|
813
1009
|
}
|