@acrool/rtk-query-codegen-openapi 0.0.6 → 0.0.9
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 +33 -0
- package/lib/index.d.mts +15 -5
- package/lib/index.d.ts +15 -5
- package/lib/index.js +219 -157
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +219 -157
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/generate.ts +180 -132
- package/src/generators/react-hooks.ts +10 -4
- package/src/index.ts +76 -77
- package/src/types.ts +20 -5
- package/src/utils/downloadSchema.ts +33 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/isQuery.ts +9 -1
package/lib/index.js
CHANGED
|
@@ -34,13 +34,13 @@ __export(src_exports, {
|
|
|
34
34
|
parseConfig: () => parseConfig
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(src_exports);
|
|
37
|
-
var
|
|
37
|
+
var import_node_fs2 = __toESM(require("node:fs"));
|
|
38
38
|
var import_node_module = require("node:module");
|
|
39
|
-
var
|
|
39
|
+
var import_node_path4 = __toESM(require("node:path"));
|
|
40
40
|
|
|
41
41
|
// src/generate.ts
|
|
42
42
|
var import_lodash = __toESM(require("lodash.camelcase"));
|
|
43
|
-
var
|
|
43
|
+
var import_node_path3 = __toESM(require("node:path"));
|
|
44
44
|
var import_generate3 = __toESM(require("oazapfts/generate"));
|
|
45
45
|
var import_typescript4 = __toESM(require("typescript"));
|
|
46
46
|
|
|
@@ -223,16 +223,54 @@ function capitalize(str) {
|
|
|
223
223
|
return str.replace(str[0], str[0].toUpperCase());
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
// src/utils/downloadSchema.ts
|
|
227
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
228
|
+
var import_node_path = __toESM(require("node:path"));
|
|
229
|
+
|
|
230
|
+
// src/utils/isValidUrl.ts
|
|
231
|
+
function isValidUrl(string) {
|
|
232
|
+
try {
|
|
233
|
+
new URL(string);
|
|
234
|
+
} catch (_) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// src/utils/downloadSchema.ts
|
|
241
|
+
async function downloadSchemaFile(remoteFile, targetPath) {
|
|
242
|
+
if (!isValidUrl(remoteFile)) {
|
|
243
|
+
throw new Error(`remoteFile must be a valid URL: ${remoteFile}`);
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
const dir = import_node_path.default.dirname(targetPath);
|
|
247
|
+
if (!import_node_fs.default.existsSync(dir)) {
|
|
248
|
+
await import_node_fs.default.promises.mkdir(dir, { recursive: true });
|
|
249
|
+
}
|
|
250
|
+
const response = await fetch(remoteFile);
|
|
251
|
+
if (!response.ok) {
|
|
252
|
+
throw new Error(`Failed to download schema from ${remoteFile}: ${response.statusText}`);
|
|
253
|
+
}
|
|
254
|
+
const content = await response.text();
|
|
255
|
+
await import_node_fs.default.promises.writeFile(targetPath, content, "utf-8");
|
|
256
|
+
console.log(`Schema downloaded from ${remoteFile} to ${targetPath}`);
|
|
257
|
+
return targetPath;
|
|
258
|
+
} catch (error) {
|
|
259
|
+
console.error(`Error downloading schema from ${remoteFile}:`, error);
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
226
264
|
// src/types.ts
|
|
227
265
|
var operationKeys = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
|
|
228
266
|
|
|
229
267
|
// src/utils/getOperationDefinitions.ts
|
|
230
268
|
function getOperationDefinitions(v3Doc) {
|
|
231
269
|
return Object.entries(v3Doc.paths).flatMap(
|
|
232
|
-
([
|
|
270
|
+
([path5, pathItem]) => !pathItem ? [] : Object.entries(pathItem).filter(
|
|
233
271
|
(arg) => operationKeys.includes(arg[0])
|
|
234
272
|
).map(([verb, operation]) => ({
|
|
235
|
-
path:
|
|
273
|
+
path: path5,
|
|
236
274
|
verb,
|
|
237
275
|
pathItem,
|
|
238
276
|
operation
|
|
@@ -259,25 +297,18 @@ async function getV3Doc(spec, httpResolverOptions) {
|
|
|
259
297
|
}
|
|
260
298
|
|
|
261
299
|
// src/utils/isQuery.ts
|
|
262
|
-
function isQuery(verb, overrides) {
|
|
300
|
+
function isQuery(verb, path5, overrides, queryMatch) {
|
|
301
|
+
if (queryMatch) {
|
|
302
|
+
return queryMatch(verb, path5);
|
|
303
|
+
}
|
|
263
304
|
if (overrides?.type) {
|
|
264
305
|
return overrides.type === "query";
|
|
265
306
|
}
|
|
266
307
|
return verb === "get";
|
|
267
308
|
}
|
|
268
309
|
|
|
269
|
-
// src/utils/isValidUrl.ts
|
|
270
|
-
function isValidUrl(string) {
|
|
271
|
-
try {
|
|
272
|
-
new URL(string);
|
|
273
|
-
} catch (_) {
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
return true;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
310
|
// src/utils/prettier.ts
|
|
280
|
-
var
|
|
311
|
+
var import_node_path2 = __toESM(require("node:path"));
|
|
281
312
|
var import_prettier = __toESM(require("prettier"));
|
|
282
313
|
var EXTENSION_TO_PARSER = {
|
|
283
314
|
ts: "typescript",
|
|
@@ -300,7 +331,7 @@ async function prettify(filePath, content, prettierConfigFile) {
|
|
|
300
331
|
let config = null;
|
|
301
332
|
let parser = "typescript";
|
|
302
333
|
if (filePath) {
|
|
303
|
-
const fileExtension =
|
|
334
|
+
const fileExtension = import_node_path2.default.extname(filePath).slice(1);
|
|
304
335
|
parser = EXTENSION_TO_PARSER[fileExtension];
|
|
305
336
|
config = await import_prettier.default.resolveConfig(process.cwd(), {
|
|
306
337
|
useCache: true,
|
|
@@ -326,24 +357,26 @@ function removeUndefined(t) {
|
|
|
326
357
|
|
|
327
358
|
// src/generators/react-hooks.ts
|
|
328
359
|
var createBinding = ({
|
|
329
|
-
operationDefinition: { verb, path:
|
|
360
|
+
operationDefinition: { verb, path: path5 },
|
|
330
361
|
overrides,
|
|
331
|
-
isLazy = false
|
|
362
|
+
isLazy = false,
|
|
363
|
+
queryMatch
|
|
332
364
|
}) => factory.createBindingElement(
|
|
333
365
|
void 0,
|
|
334
366
|
void 0,
|
|
335
367
|
factory.createIdentifier(
|
|
336
|
-
`use${isLazy ? "Lazy" : ""}${capitalize((0, import_generate.getOperationName)(verb,
|
|
368
|
+
`use${isLazy ? "Lazy" : ""}${capitalize((0, import_generate.getOperationName)(verb, path5, void 0))}${isQuery(verb, path5, overrides, queryMatch) ? "Query" : "Mutation"}`
|
|
337
369
|
),
|
|
338
370
|
void 0
|
|
339
371
|
);
|
|
340
|
-
var getReactHookName = ({ operationDefinition, endpointOverrides, config }) => {
|
|
372
|
+
var getReactHookName = ({ operationDefinition, endpointOverrides, config, queryMatch }) => {
|
|
341
373
|
const overrides = getOverrides(operationDefinition, endpointOverrides);
|
|
342
374
|
const baseParams = {
|
|
343
375
|
operationDefinition,
|
|
344
|
-
overrides
|
|
376
|
+
overrides,
|
|
377
|
+
queryMatch
|
|
345
378
|
};
|
|
346
|
-
const _isQuery = isQuery(operationDefinition.verb, overrides);
|
|
379
|
+
const _isQuery = isQuery(operationDefinition.verb, operationDefinition.path, overrides, queryMatch);
|
|
347
380
|
if (typeof config === "boolean") {
|
|
348
381
|
return createBinding(baseParams);
|
|
349
382
|
}
|
|
@@ -359,14 +392,15 @@ var generateReactHooks = ({
|
|
|
359
392
|
exportName,
|
|
360
393
|
operationDefinitions,
|
|
361
394
|
endpointOverrides,
|
|
362
|
-
config
|
|
395
|
+
config,
|
|
396
|
+
queryMatch
|
|
363
397
|
}) => factory.createVariableStatement(
|
|
364
398
|
[factory.createModifier(import_typescript3.default.SyntaxKind.ExportKeyword)],
|
|
365
399
|
factory.createVariableDeclarationList(
|
|
366
400
|
[
|
|
367
401
|
factory.createVariableDeclaration(
|
|
368
402
|
factory.createObjectBindingPattern(
|
|
369
|
-
operationDefinitions.map((operationDefinition) => getReactHookName({ operationDefinition, endpointOverrides, config })).flat()
|
|
403
|
+
operationDefinitions.map((operationDefinition) => getReactHookName({ operationDefinition, endpointOverrides, config, queryMatch })).flat()
|
|
370
404
|
),
|
|
371
405
|
void 0,
|
|
372
406
|
void 0,
|
|
@@ -387,8 +421,8 @@ function defaultIsDataResponse(code, includeDefault) {
|
|
|
387
421
|
const parsedCode = Number(code);
|
|
388
422
|
return !Number.isNaN(parsedCode) && parsedCode >= 200 && parsedCode < 300;
|
|
389
423
|
}
|
|
390
|
-
function getOperationName2({ verb, path:
|
|
391
|
-
return (0, import_generate3.getOperationName)(verb,
|
|
424
|
+
function getOperationName2({ verb, path: path5 }) {
|
|
425
|
+
return (0, import_generate3.getOperationName)(verb, path5, void 0);
|
|
392
426
|
}
|
|
393
427
|
function getTags({ verb, pathItem }) {
|
|
394
428
|
return verb ? pathItem[verb]?.tags || [] : [];
|
|
@@ -454,7 +488,9 @@ async function generateApi(spec, {
|
|
|
454
488
|
useEnumType = false,
|
|
455
489
|
mergeReadWriteOnly = false,
|
|
456
490
|
httpResolverOptions,
|
|
457
|
-
sharedTypesFile
|
|
491
|
+
sharedTypesFile,
|
|
492
|
+
queryMatch,
|
|
493
|
+
endpointsQueryReturnTypeFile = "./endpointsQueryReturnType"
|
|
458
494
|
}) {
|
|
459
495
|
const v3Doc = v3DocCache[spec] ??= await getV3Doc(spec, httpResolverOptions);
|
|
460
496
|
const apiGen = new import_generate3.default(v3Doc, {
|
|
@@ -482,8 +518,8 @@ async function generateApi(spec, {
|
|
|
482
518
|
const definedTypeNames = /* @__PURE__ */ new Set();
|
|
483
519
|
const components = v3Doc.components;
|
|
484
520
|
if (components) {
|
|
485
|
-
|
|
486
|
-
const typeEntries = Object.entries(
|
|
521
|
+
if (components.schemas) {
|
|
522
|
+
const typeEntries = Object.entries(components.schemas).map(([name, def]) => {
|
|
487
523
|
addSchemeTypeName(name);
|
|
488
524
|
const typeName = capitalize((0, import_lodash.default)(name));
|
|
489
525
|
definedTypeNames.add(typeName);
|
|
@@ -495,14 +531,15 @@ async function generateApi(spec, {
|
|
|
495
531
|
typeNode
|
|
496
532
|
);
|
|
497
533
|
});
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
534
|
+
allTypeDefinitions.push(
|
|
535
|
+
factory.createModuleDeclaration(
|
|
536
|
+
[factory.createModifier(import_typescript4.default.SyntaxKind.ExportKeyword)],
|
|
537
|
+
factory.createIdentifier("Scheme"),
|
|
538
|
+
factory.createModuleBlock(typeEntries),
|
|
539
|
+
import_typescript4.default.NodeFlags.Namespace
|
|
540
|
+
)
|
|
503
541
|
);
|
|
504
|
-
}
|
|
505
|
-
allTypeDefinitions.push(...componentDefinitions);
|
|
542
|
+
}
|
|
506
543
|
}
|
|
507
544
|
const enumEntries = [
|
|
508
545
|
...apiGen.enumAliases.filter((e) => import_typescript4.default.isEnumDeclaration(e)),
|
|
@@ -595,10 +632,10 @@ async function generateApi(spec, {
|
|
|
595
632
|
}
|
|
596
633
|
}
|
|
597
634
|
}
|
|
598
|
-
const
|
|
599
|
-
const
|
|
600
|
-
const sharedTypesDir =
|
|
601
|
-
await
|
|
635
|
+
const fs3 = await import("node:fs/promises");
|
|
636
|
+
const path5 = await import("node:path");
|
|
637
|
+
const sharedTypesDir = path5.dirname(sharedTypesFile);
|
|
638
|
+
await fs3.mkdir(sharedTypesDir, { recursive: true });
|
|
602
639
|
const output = printer2.printNode(
|
|
603
640
|
import_typescript4.default.EmitHint.Unspecified,
|
|
604
641
|
factory.createSourceFile(
|
|
@@ -608,7 +645,7 @@ async function generateApi(spec, {
|
|
|
608
645
|
),
|
|
609
646
|
resultFile2
|
|
610
647
|
);
|
|
611
|
-
await
|
|
648
|
+
await fs3.writeFile(sharedTypesFile, output, "utf-8");
|
|
612
649
|
}
|
|
613
650
|
if (apiGen.spec.components?.schemas) {
|
|
614
651
|
apiGen.preprocessComponents(apiGen.spec.components.schemas);
|
|
@@ -633,25 +670,32 @@ async function generateApi(spec, {
|
|
|
633
670
|
return declaration;
|
|
634
671
|
}
|
|
635
672
|
if (outputFile) {
|
|
636
|
-
outputFile =
|
|
673
|
+
outputFile = import_node_path3.default.resolve(process.cwd(), outputFile);
|
|
637
674
|
if (apiFile.startsWith(".")) {
|
|
638
|
-
apiFile =
|
|
675
|
+
apiFile = import_node_path3.default.relative(import_node_path3.default.dirname(outputFile), apiFile);
|
|
639
676
|
apiFile = apiFile.replace(/\\/g, "/");
|
|
640
677
|
if (!apiFile.startsWith(".")) apiFile = `./${apiFile}`;
|
|
641
678
|
}
|
|
679
|
+
if (endpointsQueryReturnTypeFile.startsWith(".")) {
|
|
680
|
+
endpointsQueryReturnTypeFile = import_node_path3.default.relative(import_node_path3.default.dirname(outputFile), endpointsQueryReturnTypeFile);
|
|
681
|
+
endpointsQueryReturnTypeFile = endpointsQueryReturnTypeFile.replace(/\\/g, "/");
|
|
682
|
+
if (!endpointsQueryReturnTypeFile.startsWith(".")) endpointsQueryReturnTypeFile = `./${endpointsQueryReturnTypeFile}`;
|
|
683
|
+
}
|
|
642
684
|
}
|
|
643
685
|
apiFile = apiFile.replace(/\.[jt]sx?$/, "");
|
|
686
|
+
endpointsQueryReturnTypeFile = endpointsQueryReturnTypeFile.replace(/\.[jt]sx?$/, "");
|
|
644
687
|
const sharedTypesImportPath = sharedTypesFile && outputFile ? (() => {
|
|
645
|
-
let rel =
|
|
688
|
+
let rel = import_node_path3.default.relative(import_node_path3.default.dirname(outputFile), sharedTypesFile).replace(/\\/g, "/").replace(/\.[jt]sx?$/, "");
|
|
646
689
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
647
690
|
return rel;
|
|
648
691
|
})() : "./shared-types";
|
|
649
|
-
|
|
692
|
+
const operationNames = [];
|
|
693
|
+
const sourceCode = printer.printNode(
|
|
650
694
|
import_typescript4.default.EmitHint.Unspecified,
|
|
651
695
|
factory.createSourceFile(
|
|
652
696
|
[
|
|
653
697
|
generateImportNode(apiFile, { [apiImport]: "api" }),
|
|
654
|
-
generateImportNode(
|
|
698
|
+
generateImportNode(endpointsQueryReturnTypeFile, { IRestFulEndpointsQueryReturn: "IRestFulEndpointsQueryReturn" }),
|
|
655
699
|
...sharedTypesFile ? [
|
|
656
700
|
generateImportNode(sharedTypesImportPath, {
|
|
657
701
|
Scheme: "Scheme",
|
|
@@ -662,21 +706,21 @@ async function generateApi(spec, {
|
|
|
662
706
|
generateCreateApiCall({
|
|
663
707
|
tag,
|
|
664
708
|
endpointDefinitions: factory.createObjectLiteralExpression(
|
|
665
|
-
operationDefinitions.map(
|
|
666
|
-
(operationDefinition
|
|
709
|
+
operationDefinitions.map((operationDefinition) => {
|
|
710
|
+
const operationName = getOperationName2({ verb: operationDefinition.verb, path: operationDefinition.path });
|
|
711
|
+
const finalOperationName = operationNameSuffix ? capitalize(operationName + operationNameSuffix) : operationName;
|
|
712
|
+
operationNames.push(finalOperationName);
|
|
713
|
+
return generateEndpoint({
|
|
667
714
|
operationDefinition,
|
|
668
715
|
overrides: getOverrides(operationDefinition, endpointOverrides),
|
|
669
|
-
sharedTypesFile: !!sharedTypesFile
|
|
670
|
-
|
|
671
|
-
|
|
716
|
+
sharedTypesFile: !!sharedTypesFile,
|
|
717
|
+
queryMatch
|
|
718
|
+
});
|
|
719
|
+
}),
|
|
672
720
|
true
|
|
673
721
|
)
|
|
674
722
|
}),
|
|
675
|
-
factory.createExportAssignment(
|
|
676
|
-
void 0,
|
|
677
|
-
void 0,
|
|
678
|
-
factory.createIdentifier(generatedApiName)
|
|
679
|
-
),
|
|
723
|
+
factory.createExportAssignment(void 0, void 0, factory.createIdentifier(generatedApiName)),
|
|
680
724
|
...Object.values(interfaces),
|
|
681
725
|
...sharedTypesFile ? [] : [...apiGen.aliases, ...apiGen.enumAliases],
|
|
682
726
|
...hooks ? [
|
|
@@ -684,7 +728,8 @@ async function generateApi(spec, {
|
|
|
684
728
|
exportName: generatedApiName,
|
|
685
729
|
operationDefinitions,
|
|
686
730
|
endpointOverrides,
|
|
687
|
-
config: hooks
|
|
731
|
+
config: hooks,
|
|
732
|
+
queryMatch
|
|
688
733
|
})
|
|
689
734
|
] : []
|
|
690
735
|
],
|
|
@@ -693,6 +738,10 @@ async function generateApi(spec, {
|
|
|
693
738
|
),
|
|
694
739
|
resultFile
|
|
695
740
|
);
|
|
741
|
+
return {
|
|
742
|
+
sourceCode,
|
|
743
|
+
operationNames
|
|
744
|
+
};
|
|
696
745
|
function extractAllTagTypes({ operationDefinitions: operationDefinitions2 }) {
|
|
697
746
|
const allTagTypes = /* @__PURE__ */ new Set();
|
|
698
747
|
for (const operationDefinition of operationDefinitions2) {
|
|
@@ -706,18 +755,19 @@ async function generateApi(spec, {
|
|
|
706
755
|
function generateEndpoint({
|
|
707
756
|
operationDefinition,
|
|
708
757
|
overrides,
|
|
709
|
-
sharedTypesFile: sharedTypesFile2
|
|
758
|
+
sharedTypesFile: sharedTypesFile2,
|
|
759
|
+
queryMatch: queryMatch2
|
|
710
760
|
}) {
|
|
711
761
|
const {
|
|
712
762
|
verb,
|
|
713
|
-
path:
|
|
763
|
+
path: path5,
|
|
714
764
|
pathItem,
|
|
715
765
|
operation,
|
|
716
766
|
operation: { responses, requestBody }
|
|
717
767
|
} = operationDefinition;
|
|
718
|
-
const operationName = getOperationName2({ verb, path:
|
|
768
|
+
const operationName = getOperationName2({ verb, path: path5 });
|
|
719
769
|
const tags = tag ? getTags({ verb, pathItem }) : [];
|
|
720
|
-
const isQuery2 = isQuery(verb, overrides);
|
|
770
|
+
const isQuery2 = isQuery(verb, path5, overrides, queryMatch2);
|
|
721
771
|
const returnsJson = apiGen.getResponseType(responses) === "json";
|
|
722
772
|
let ResponseType = factory.createKeywordTypeNode(import_typescript4.default.SyntaxKind.UnknownKeyword);
|
|
723
773
|
if (returnsJson) {
|
|
@@ -779,7 +829,9 @@ async function generateApi(spec, {
|
|
|
779
829
|
origin: "param",
|
|
780
830
|
name,
|
|
781
831
|
originalName: param.name,
|
|
782
|
-
type: wrapWithSchemeIfComponent(
|
|
832
|
+
type: wrapWithSchemeIfComponent(
|
|
833
|
+
apiGen.getTypeFromSchema((0, import_generate3.isReference)(param) ? param : param.schema, void 0, "writeOnly")
|
|
834
|
+
),
|
|
783
835
|
required: param.required,
|
|
784
836
|
param
|
|
785
837
|
};
|
|
@@ -843,10 +895,7 @@ async function generateApi(spec, {
|
|
|
843
895
|
operationName: operationNameSuffix ? capitalize(operationName + operationNameSuffix) : operationName,
|
|
844
896
|
type: isQuery2 ? "query" : "mutation",
|
|
845
897
|
Response: ResponseTypeName,
|
|
846
|
-
QueryArg: factory.createTypeReferenceNode(
|
|
847
|
-
factory.createIdentifier("IRestFulEndpointsQueryReturn"),
|
|
848
|
-
[QueryArg]
|
|
849
|
-
),
|
|
898
|
+
QueryArg: factory.createTypeReferenceNode(factory.createIdentifier("IRestFulEndpointsQueryReturn"), [QueryArg]),
|
|
850
899
|
queryFn: generateQueryFn({
|
|
851
900
|
operationDefinition,
|
|
852
901
|
queryArg,
|
|
@@ -867,10 +916,18 @@ async function generateApi(spec, {
|
|
|
867
916
|
encodePathParams: encodePathParams2,
|
|
868
917
|
encodeQueryParams: encodeQueryParams2
|
|
869
918
|
}) {
|
|
870
|
-
const { path:
|
|
919
|
+
const { path: path5, verb, operation } = operationDefinition;
|
|
871
920
|
const bodyParameter = Object.values(queryArg).find((def) => def.origin === "body");
|
|
872
921
|
const rootObject = factory.createIdentifier("queryArg");
|
|
873
922
|
const variablesObject = factory.createPropertyAccessExpression(rootObject, factory.createIdentifier("variables"));
|
|
923
|
+
function getContentType() {
|
|
924
|
+
if (operation.requestBody) {
|
|
925
|
+
const requestBody = apiGen.resolve(operation.requestBody);
|
|
926
|
+
const contentTypes = Object.keys(requestBody.content || {});
|
|
927
|
+
return contentTypes[0];
|
|
928
|
+
}
|
|
929
|
+
return void 0;
|
|
930
|
+
}
|
|
874
931
|
function pickParams(paramIn) {
|
|
875
932
|
return Object.values(queryArg).filter((def) => def.origin === "param" && def.param.in === paramIn);
|
|
876
933
|
}
|
|
@@ -894,6 +951,7 @@ async function generateApi(spec, {
|
|
|
894
951
|
factory.createObjectLiteralExpression(properties, true)
|
|
895
952
|
);
|
|
896
953
|
}
|
|
954
|
+
const contentType = getContentType();
|
|
897
955
|
return factory.createArrowFunction(
|
|
898
956
|
void 0,
|
|
899
957
|
void 0,
|
|
@@ -905,15 +963,22 @@ async function generateApi(spec, {
|
|
|
905
963
|
[
|
|
906
964
|
factory.createPropertyAssignment(
|
|
907
965
|
factory.createIdentifier("url"),
|
|
908
|
-
generatePathExpression(
|
|
966
|
+
generatePathExpression(path5, pickParams("path"), variablesObject, isFlatArg, encodePathParams2)
|
|
909
967
|
),
|
|
910
968
|
isQuery2 && verb.toUpperCase() === "GET" ? void 0 : factory.createPropertyAssignment(
|
|
911
969
|
factory.createIdentifier("method"),
|
|
912
970
|
factory.createStringLiteral(verb.toUpperCase())
|
|
913
971
|
),
|
|
972
|
+
contentType ? factory.createPropertyAssignment(
|
|
973
|
+
factory.createIdentifier("contentType"),
|
|
974
|
+
factory.createStringLiteral(contentType)
|
|
975
|
+
) : void 0,
|
|
914
976
|
bodyParameter === void 0 ? void 0 : factory.createPropertyAssignment(
|
|
915
977
|
factory.createIdentifier("body"),
|
|
916
|
-
isFlatArg ? variablesObject : factory.createPropertyAccessExpression(
|
|
978
|
+
isFlatArg ? variablesObject : factory.createPropertyAccessExpression(
|
|
979
|
+
variablesObject,
|
|
980
|
+
factory.createIdentifier(bodyParameter.name)
|
|
981
|
+
)
|
|
917
982
|
),
|
|
918
983
|
createObjectLiteralProperty(pickParams("cookie"), "cookies"),
|
|
919
984
|
createObjectLiteralProperty(pickParams("query"), "params"),
|
|
@@ -955,19 +1020,13 @@ async function generateApi(spec, {
|
|
|
955
1020
|
}));
|
|
956
1021
|
if (isEnumType) {
|
|
957
1022
|
return factory.createTypeReferenceNode(
|
|
958
|
-
factory.createQualifiedName(
|
|
959
|
-
factory.createIdentifier("Enum"),
|
|
960
|
-
typeNode.typeName
|
|
961
|
-
),
|
|
1023
|
+
factory.createQualifiedName(factory.createIdentifier("Enum"), typeNode.typeName),
|
|
962
1024
|
typeNode.typeArguments?.map(wrapWithSchemeIfComponent)
|
|
963
1025
|
);
|
|
964
1026
|
}
|
|
965
1027
|
if (schemeTypeNames.has(typeName)) {
|
|
966
1028
|
return factory.createTypeReferenceNode(
|
|
967
|
-
factory.createQualifiedName(
|
|
968
|
-
factory.createIdentifier("Scheme"),
|
|
969
|
-
typeNode.typeName
|
|
970
|
-
),
|
|
1029
|
+
factory.createQualifiedName(factory.createIdentifier("Scheme"), typeNode.typeName),
|
|
971
1030
|
typeNode.typeArguments?.map(wrapWithSchemeIfComponent)
|
|
972
1031
|
);
|
|
973
1032
|
}
|
|
@@ -1037,12 +1096,12 @@ async function generateApi(spec, {
|
|
|
1037
1096
|
return typeNode;
|
|
1038
1097
|
}
|
|
1039
1098
|
}
|
|
1040
|
-
function generatePathExpression(
|
|
1099
|
+
function generatePathExpression(path5, pathParameters, rootObject, isFlatArg, encodePathParams) {
|
|
1041
1100
|
const expressions = [];
|
|
1042
|
-
const head =
|
|
1101
|
+
const head = path5.replace(/\{(.*?)}(.*?)(?=\{|$)/g, (_, expression, literal) => {
|
|
1043
1102
|
const param = pathParameters.find((p) => p.originalName === expression);
|
|
1044
1103
|
if (!param) {
|
|
1045
|
-
throw new Error(`path parameter ${expression} does not seem to be defined in '${
|
|
1104
|
+
throw new Error(`path parameter ${expression} does not seem to be defined in '${path5}'!`);
|
|
1046
1105
|
}
|
|
1047
1106
|
expressions.push([param.name, literal]);
|
|
1048
1107
|
return "";
|
|
@@ -1066,82 +1125,81 @@ function generatePathExpression(path4, pathParameters, rootObject, isFlatArg, en
|
|
|
1066
1125
|
var import_lodash2 = __toESM(require("lodash.camelcase"));
|
|
1067
1126
|
var require2 = (0, import_node_module.createRequire)(__filename);
|
|
1068
1127
|
async function ensureDirectoryExists(filePath) {
|
|
1069
|
-
const dirname =
|
|
1070
|
-
if (!
|
|
1071
|
-
await
|
|
1128
|
+
const dirname = import_node_path4.default.dirname(filePath);
|
|
1129
|
+
if (!import_node_fs2.default.existsSync(dirname)) {
|
|
1130
|
+
await import_node_fs2.default.promises.mkdir(dirname, { recursive: true });
|
|
1072
1131
|
}
|
|
1073
1132
|
}
|
|
1074
1133
|
function fileExists(filePath) {
|
|
1075
1134
|
try {
|
|
1076
|
-
return
|
|
1135
|
+
return import_node_fs2.default.statSync(filePath).isFile();
|
|
1077
1136
|
} catch {
|
|
1078
1137
|
return false;
|
|
1079
1138
|
}
|
|
1080
1139
|
}
|
|
1081
1140
|
function getApiNameFromDir(dirPath) {
|
|
1082
|
-
const dirName =
|
|
1141
|
+
const dirName = import_node_path4.default.basename(dirPath);
|
|
1083
1142
|
return `${dirName}Api`;
|
|
1084
1143
|
}
|
|
1085
|
-
async function ensureBaseFilesExist(outputDir) {
|
|
1086
|
-
const enhanceEndpointsPath =
|
|
1087
|
-
const indexPath =
|
|
1144
|
+
async function ensureBaseFilesExist(outputDir, operationNames) {
|
|
1145
|
+
const enhanceEndpointsPath = import_node_path4.default.join(outputDir, "enhanceEndpoints.ts");
|
|
1146
|
+
const indexPath = import_node_path4.default.join(outputDir, "index.ts");
|
|
1088
1147
|
const apiName = getApiNameFromDir(outputDir);
|
|
1089
1148
|
if (!fileExists(enhanceEndpointsPath)) {
|
|
1149
|
+
const operationNamesString = operationNames.map((name) => ` ${name}: {},`).join("\n");
|
|
1090
1150
|
const enhanceEndpointsContent = `import api from './query.generated';
|
|
1091
1151
|
|
|
1092
1152
|
const enhancedApi = api.enhanceEndpoints({
|
|
1093
1153
|
endpoints: {
|
|
1154
|
+
${operationNamesString}
|
|
1094
1155
|
},
|
|
1095
1156
|
});
|
|
1096
1157
|
|
|
1097
1158
|
export default enhancedApi;
|
|
1098
1159
|
`;
|
|
1099
|
-
await
|
|
1160
|
+
await import_node_fs2.default.promises.writeFile(enhanceEndpointsPath, enhanceEndpointsContent, "utf-8");
|
|
1100
1161
|
}
|
|
1101
1162
|
if (!fileExists(indexPath)) {
|
|
1102
1163
|
const indexContent = `export * from './query.generated';
|
|
1103
1164
|
export {default as ${apiName}} from './enhanceEndpoints';
|
|
1104
1165
|
`;
|
|
1105
|
-
await
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
function getGroupNameFromPath(path4, pattern) {
|
|
1109
|
-
const match = path4.match(pattern);
|
|
1110
|
-
if (match && match[1]) {
|
|
1111
|
-
return (0, import_lodash2.default)(match[1]);
|
|
1166
|
+
await import_node_fs2.default.promises.writeFile(indexPath, indexContent, "utf-8");
|
|
1112
1167
|
}
|
|
1113
|
-
return "common";
|
|
1114
1168
|
}
|
|
1115
1169
|
async function generateEndpoints(options) {
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1170
|
+
let actualSchemaFile = options.schemaFile;
|
|
1171
|
+
if (options.remoteFile) {
|
|
1172
|
+
actualSchemaFile = await downloadSchemaFile(options.remoteFile, options.schemaFile);
|
|
1173
|
+
}
|
|
1174
|
+
const updatedOptions = {
|
|
1175
|
+
...options,
|
|
1176
|
+
schemaFile: actualSchemaFile
|
|
1177
|
+
};
|
|
1178
|
+
const schemaLocation = updatedOptions.schemaFile;
|
|
1179
|
+
const schemaAbsPath = import_node_path4.default.resolve(process.cwd(), schemaLocation);
|
|
1180
|
+
if ("outputFiles" in options) {
|
|
1181
|
+
const { outputFiles, ...commonConfig } = updatedOptions;
|
|
1182
|
+
const openApiDoc = await getV3Doc(actualSchemaFile, updatedOptions.httpResolverOptions);
|
|
1121
1183
|
const paths = Object.keys(openApiDoc.paths);
|
|
1122
|
-
const
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
const groupedPaths = paths.reduce((acc, path4) => {
|
|
1128
|
-
const groupName = getGroupNameFromPath(path4, pattern);
|
|
1129
|
-
if (!acc[groupName]) {
|
|
1130
|
-
acc[groupName] = [];
|
|
1184
|
+
const { groupKeyMatch, outputDir, filterEndpoint, queryMatch } = outputFiles;
|
|
1185
|
+
const groupedPaths = paths.reduce((acc, path5) => {
|
|
1186
|
+
const groupKey = (0, import_lodash2.default)(groupKeyMatch(path5));
|
|
1187
|
+
if (!acc[groupKey]) {
|
|
1188
|
+
acc[groupKey] = [];
|
|
1131
1189
|
}
|
|
1132
|
-
acc[
|
|
1190
|
+
acc[groupKey].push(path5);
|
|
1133
1191
|
return acc;
|
|
1134
1192
|
}, {});
|
|
1135
|
-
for (const [
|
|
1136
|
-
const finalOutputPath =
|
|
1193
|
+
for (const [groupKey, paths2] of Object.entries(groupedPaths)) {
|
|
1194
|
+
const finalOutputPath = `${outputDir}/${groupKey}/query.generated.ts`;
|
|
1137
1195
|
if (filterEndpoint) {
|
|
1138
1196
|
const pathBasedFilter = (operationName, operationDefinition) => {
|
|
1139
|
-
const
|
|
1140
|
-
const
|
|
1141
|
-
if (
|
|
1197
|
+
const path5 = operationDefinition.path;
|
|
1198
|
+
const pathGroupKey = (0, import_lodash2.default)(groupKeyMatch(path5));
|
|
1199
|
+
if (pathGroupKey !== groupKey) {
|
|
1142
1200
|
return false;
|
|
1143
1201
|
}
|
|
1144
|
-
const endpointFilter = filterEndpoint(
|
|
1202
|
+
const endpointFilter = filterEndpoint(groupKey);
|
|
1145
1203
|
if (endpointFilter instanceof RegExp) {
|
|
1146
1204
|
return endpointFilter.test(operationName);
|
|
1147
1205
|
}
|
|
@@ -1150,45 +1208,49 @@ async function generateEndpoints(options) {
|
|
|
1150
1208
|
const groupOptions = {
|
|
1151
1209
|
...commonConfig,
|
|
1152
1210
|
outputFile: finalOutputPath,
|
|
1153
|
-
|
|
1211
|
+
sharedTypesFile: `${outputDir}/shared-types.ts`,
|
|
1212
|
+
filterEndpoints: pathBasedFilter,
|
|
1213
|
+
queryMatch
|
|
1154
1214
|
};
|
|
1155
1215
|
await generateSingleEndpoint(groupOptions);
|
|
1156
1216
|
} else {
|
|
1157
1217
|
const pathBasedFilter = (operationName, operationDefinition) => {
|
|
1158
|
-
const
|
|
1159
|
-
const
|
|
1160
|
-
return
|
|
1218
|
+
const path5 = operationDefinition.path;
|
|
1219
|
+
const pathGroupKey = (0, import_lodash2.default)(groupKeyMatch(path5));
|
|
1220
|
+
return pathGroupKey === groupKey;
|
|
1161
1221
|
};
|
|
1162
1222
|
const groupOptions = {
|
|
1163
1223
|
...commonConfig,
|
|
1164
1224
|
outputFile: finalOutputPath,
|
|
1165
|
-
|
|
1225
|
+
sharedTypesFile: `${outputDir}/shared-types.ts`,
|
|
1226
|
+
filterEndpoints: pathBasedFilter,
|
|
1227
|
+
queryMatch
|
|
1166
1228
|
};
|
|
1167
1229
|
await generateSingleEndpoint(groupOptions);
|
|
1168
1230
|
}
|
|
1169
1231
|
}
|
|
1170
1232
|
return;
|
|
1171
1233
|
}
|
|
1172
|
-
await generateSingleEndpoint(
|
|
1234
|
+
await generateSingleEndpoint(updatedOptions);
|
|
1173
1235
|
}
|
|
1174
1236
|
async function generateSingleEndpoint(options) {
|
|
1175
1237
|
const schemaLocation = options.schemaFile;
|
|
1176
|
-
const schemaAbsPath =
|
|
1177
|
-
const
|
|
1238
|
+
const schemaAbsPath = import_node_path4.default.resolve(process.cwd(), schemaLocation);
|
|
1239
|
+
const result = await enforceOazapftsTsVersion(async () => {
|
|
1178
1240
|
return generateApi(schemaAbsPath, options);
|
|
1179
1241
|
});
|
|
1180
1242
|
const { outputFile, prettierConfigFile } = options;
|
|
1181
1243
|
if (outputFile) {
|
|
1182
|
-
const outputPath =
|
|
1244
|
+
const outputPath = import_node_path4.default.resolve(process.cwd(), outputFile);
|
|
1183
1245
|
await ensureDirectoryExists(outputPath);
|
|
1184
|
-
const outputDir =
|
|
1185
|
-
await ensureBaseFilesExist(outputDir);
|
|
1186
|
-
|
|
1246
|
+
const outputDir = import_node_path4.default.dirname(outputPath);
|
|
1247
|
+
await ensureBaseFilesExist(outputDir, result.operationNames);
|
|
1248
|
+
import_node_fs2.default.writeFileSync(
|
|
1187
1249
|
outputPath,
|
|
1188
|
-
await prettify(outputFile, sourceCode, prettierConfigFile)
|
|
1250
|
+
await prettify(outputFile, result.sourceCode, prettierConfigFile)
|
|
1189
1251
|
);
|
|
1190
1252
|
} else {
|
|
1191
|
-
return await prettify(null, sourceCode, prettierConfigFile);
|
|
1253
|
+
return await prettify(null, result.sourceCode, prettierConfigFile);
|
|
1192
1254
|
}
|
|
1193
1255
|
}
|
|
1194
1256
|
function parseConfig(fullConfig) {
|
|
@@ -1196,36 +1258,32 @@ function parseConfig(fullConfig) {
|
|
|
1196
1258
|
if ("outputFiles" in fullConfig) {
|
|
1197
1259
|
const { outputFiles, ...commonConfig } = fullConfig;
|
|
1198
1260
|
let openApiDoc;
|
|
1199
|
-
if (
|
|
1261
|
+
if (fullConfig.remoteFile) {
|
|
1200
1262
|
outFiles.push(fullConfig);
|
|
1201
1263
|
return outFiles;
|
|
1202
1264
|
} else {
|
|
1203
|
-
openApiDoc = JSON.parse(
|
|
1265
|
+
openApiDoc = JSON.parse(import_node_fs2.default.readFileSync(fullConfig.schemaFile, "utf-8"));
|
|
1204
1266
|
}
|
|
1205
1267
|
const paths = Object.keys(openApiDoc.paths);
|
|
1206
|
-
const
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
const groupedPaths = paths.reduce((acc, path4) => {
|
|
1212
|
-
const groupName = getGroupNameFromPath(path4, pattern);
|
|
1213
|
-
if (!acc[groupName]) {
|
|
1214
|
-
acc[groupName] = [];
|
|
1268
|
+
const { groupKeyMatch, outputDir, filterEndpoint, queryMatch } = outputFiles;
|
|
1269
|
+
const groupedPaths = paths.reduce((acc, path5) => {
|
|
1270
|
+
const groupKey = (0, import_lodash2.default)(groupKeyMatch(path5));
|
|
1271
|
+
if (!acc[groupKey]) {
|
|
1272
|
+
acc[groupKey] = [];
|
|
1215
1273
|
}
|
|
1216
|
-
acc[
|
|
1274
|
+
acc[groupKey].push(path5);
|
|
1217
1275
|
return acc;
|
|
1218
1276
|
}, {});
|
|
1219
|
-
Object.entries(groupedPaths).forEach(([
|
|
1220
|
-
const finalOutputPath =
|
|
1277
|
+
Object.entries(groupedPaths).forEach(([groupKey, paths2]) => {
|
|
1278
|
+
const finalOutputPath = `${outputDir}/${groupKey}/query.generated.ts`;
|
|
1221
1279
|
if (filterEndpoint) {
|
|
1222
1280
|
const pathBasedFilter = (operationName, operationDefinition) => {
|
|
1223
|
-
const
|
|
1224
|
-
const
|
|
1225
|
-
if (
|
|
1281
|
+
const path5 = operationDefinition.path;
|
|
1282
|
+
const pathGroupKey = (0, import_lodash2.default)(groupKeyMatch(path5));
|
|
1283
|
+
if (pathGroupKey !== groupKey) {
|
|
1226
1284
|
return false;
|
|
1227
1285
|
}
|
|
1228
|
-
const endpointFilter = filterEndpoint(
|
|
1286
|
+
const endpointFilter = filterEndpoint(groupKey);
|
|
1229
1287
|
if (endpointFilter instanceof RegExp) {
|
|
1230
1288
|
return endpointFilter.test(operationName);
|
|
1231
1289
|
}
|
|
@@ -1234,18 +1292,22 @@ function parseConfig(fullConfig) {
|
|
|
1234
1292
|
outFiles.push({
|
|
1235
1293
|
...commonConfig,
|
|
1236
1294
|
outputFile: finalOutputPath,
|
|
1237
|
-
|
|
1295
|
+
sharedTypesFile: `${outputDir}/shared-types.ts`,
|
|
1296
|
+
filterEndpoints: pathBasedFilter,
|
|
1297
|
+
queryMatch
|
|
1238
1298
|
});
|
|
1239
1299
|
} else {
|
|
1240
1300
|
const pathBasedFilter = (operationName, operationDefinition) => {
|
|
1241
|
-
const
|
|
1242
|
-
const
|
|
1243
|
-
return
|
|
1301
|
+
const path5 = operationDefinition.path;
|
|
1302
|
+
const pathGroupKey = (0, import_lodash2.default)(groupKeyMatch(path5));
|
|
1303
|
+
return pathGroupKey === groupKey;
|
|
1244
1304
|
};
|
|
1245
1305
|
outFiles.push({
|
|
1246
1306
|
...commonConfig,
|
|
1247
1307
|
outputFile: finalOutputPath,
|
|
1248
|
-
|
|
1308
|
+
sharedTypesFile: `${outputDir}/shared-types.ts`,
|
|
1309
|
+
filterEndpoints: pathBasedFilter,
|
|
1310
|
+
queryMatch
|
|
1249
1311
|
});
|
|
1250
1312
|
}
|
|
1251
1313
|
});
|