@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.d.mts +8 -4
- package/lib/index.d.ts +8 -4
- package/lib/index.js +460 -124
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +460 -124
- package/lib/index.mjs.map +1 -1
- package/package.json +11 -2
- package/src/generate.ts +365 -142
- package/src/generators/react-hooks.ts +2 -2
- package/src/index.ts +250 -9
- package/src/types.ts +9 -1
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
|
|
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,
|
|
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
|
|
391
|
-
return (0, import_generate3.getOperationName)(verb, path4,
|
|
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
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
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(
|
|
493
|
+
factory.createIdentifier(typeName),
|
|
483
494
|
void 0,
|
|
484
495
|
typeNode
|
|
485
496
|
);
|
|
486
497
|
});
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
)
|
|
495
|
-
|
|
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
|
-
|
|
538
|
-
|
|
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
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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
|
|
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
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
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
|
-
|
|
661
|
-
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
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
|
}
|