vite-plugin-openapi-codegen 3.2.1 → 3.3.0
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/dist/cli.mjs +42 -7
- package/dist/index.mjs +43 -8
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -268,13 +268,45 @@ function collectOperations(spec, pathPrefix = "/api/", stripPrefix = true) {
|
|
|
268
268
|
});
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
|
-
|
|
271
|
+
const publicEntries = excludeInternalOperations(entries, spec);
|
|
272
|
+
if (entries.length > 0 && publicEntries.length === 0) throw new Error(`All ${entries.length} operation(s) matching prefix "${pathPrefix}" are internal-only and were excluded`);
|
|
273
|
+
const excludedCount = entries.length - publicEntries.length;
|
|
274
|
+
if (excludedCount > 0) console.info(`[openapi-codegen] excluded ${excludedCount} internal-only operation(s) from generated artifacts.`);
|
|
275
|
+
return publicEntries;
|
|
272
276
|
}
|
|
273
277
|
function excludeInternalOperations(entries, spec) {
|
|
274
278
|
const securitySchemes = spec.components?.securitySchemes;
|
|
275
279
|
if (!securitySchemes) return entries;
|
|
276
280
|
return entries.filter((entry) => readSecurityRequirement(entry, securitySchemes, spec.security)?.kind !== "internal");
|
|
277
281
|
}
|
|
282
|
+
function excludeInternalOperationsFromSpec(spec) {
|
|
283
|
+
const securitySchemes = spec.components?.securitySchemes;
|
|
284
|
+
if (!securitySchemes || !spec.paths) return {
|
|
285
|
+
excludedCount: 0,
|
|
286
|
+
spec
|
|
287
|
+
};
|
|
288
|
+
const clone = structuredClone(spec);
|
|
289
|
+
let excludedCount = 0;
|
|
290
|
+
for (const [path, pathItem] of Object.entries(clone.paths ?? {})) {
|
|
291
|
+
let removedFromPath = 0;
|
|
292
|
+
for (const method of HTTP_METHODS) {
|
|
293
|
+
const operation = pathItem[method];
|
|
294
|
+
if (!operation) continue;
|
|
295
|
+
if (readSecurityRequirement({
|
|
296
|
+
operation,
|
|
297
|
+
operationId: operation.operationId ?? `${method.toUpperCase()} ${path}`
|
|
298
|
+
}, securitySchemes, clone.security)?.kind !== "internal") continue;
|
|
299
|
+
delete pathItem[method];
|
|
300
|
+
removedFromPath += 1;
|
|
301
|
+
}
|
|
302
|
+
excludedCount += removedFromPath;
|
|
303
|
+
if (removedFromPath > 0 && !HTTP_METHODS.some((method) => pathItem[method])) delete clone.paths?.[path];
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
excludedCount,
|
|
307
|
+
spec: clone
|
|
308
|
+
};
|
|
309
|
+
}
|
|
278
310
|
function readSecurityRequirement(entry, securitySchemes, topLevelSecurity) {
|
|
279
311
|
const security = entry.operation.security ?? topLevelSecurity;
|
|
280
312
|
if (security === void 0) return null;
|
|
@@ -646,9 +678,10 @@ function resolveHttpClientConfig(config) {
|
|
|
646
678
|
};
|
|
647
679
|
}
|
|
648
680
|
const GENERATED_HEADER = ["// This file is auto-generated by vite-plugin-openapi-codegen.", "// Do not edit manually. Changes will be overwritten on next build."];
|
|
649
|
-
async function generateApiTypes(
|
|
681
|
+
async function generateApiTypes(input, outputDir, useTypeAliases) {
|
|
650
682
|
const { default: openapiTS, astToString } = await import("openapi-typescript");
|
|
651
|
-
const
|
|
683
|
+
const { excludedCount, spec } = excludeInternalOperationsFromSpec(input.spec);
|
|
684
|
+
const contents = astToString(await openapiTS(excludedCount > 0 ? spec : input.apiTypesSource, useTypeAliases ? {
|
|
652
685
|
rootTypes: true,
|
|
653
686
|
rootTypesKeepCasing: true,
|
|
654
687
|
rootTypesNoSchemaPrefix: true
|
|
@@ -769,11 +802,13 @@ function parseOpenAPISpec(sourceText, inputLabel) {
|
|
|
769
802
|
async function generateOpenAPIArtifacts(root, options) {
|
|
770
803
|
const outputDir = resolve(root, options.output);
|
|
771
804
|
mkdirSync(outputDir, { recursive: true });
|
|
772
|
-
const
|
|
773
|
-
const
|
|
774
|
-
const
|
|
805
|
+
const input = await loadOpenAPIInput(root, options.input);
|
|
806
|
+
const pathPrefix = options.pathPrefix ?? "/api/";
|
|
807
|
+
const stripPrefix = options.stripPrefix ?? true;
|
|
808
|
+
const operations = collectOperations(input.spec, pathPrefix, stripPrefix);
|
|
809
|
+
const artifacts = renderGeneratedArtifacts(input.spec, options, operations);
|
|
775
810
|
warnOnParameterLocationMismatch(operations);
|
|
776
|
-
await generateApiTypes(
|
|
811
|
+
await generateApiTypes(input, outputDir, options.typeAliases ?? false);
|
|
777
812
|
if (artifacts.apiTypes) writeFileSync(resolve(outputDir, "api-types.d.ts"), artifacts.apiTypes, { flag: "a" });
|
|
778
813
|
if (artifacts.accessPolicies) writeFileSync(resolve(outputDir, "access-policies.ts"), artifacts.accessPolicies);
|
|
779
814
|
writeFileSync(resolve(outputDir, "api.ts"), artifacts.api);
|
package/dist/index.mjs
CHANGED
|
@@ -266,13 +266,45 @@ function collectOperations(spec, pathPrefix = "/api/", stripPrefix = true) {
|
|
|
266
266
|
});
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
|
-
|
|
269
|
+
const publicEntries = excludeInternalOperations(entries, spec);
|
|
270
|
+
if (entries.length > 0 && publicEntries.length === 0) throw new Error(`All ${entries.length} operation(s) matching prefix "${pathPrefix}" are internal-only and were excluded`);
|
|
271
|
+
const excludedCount = entries.length - publicEntries.length;
|
|
272
|
+
if (excludedCount > 0) console.info(`[openapi-codegen] excluded ${excludedCount} internal-only operation(s) from generated artifacts.`);
|
|
273
|
+
return publicEntries;
|
|
270
274
|
}
|
|
271
275
|
function excludeInternalOperations(entries, spec) {
|
|
272
276
|
const securitySchemes = spec.components?.securitySchemes;
|
|
273
277
|
if (!securitySchemes) return entries;
|
|
274
278
|
return entries.filter((entry) => readSecurityRequirement(entry, securitySchemes, spec.security)?.kind !== "internal");
|
|
275
279
|
}
|
|
280
|
+
function excludeInternalOperationsFromSpec(spec) {
|
|
281
|
+
const securitySchemes = spec.components?.securitySchemes;
|
|
282
|
+
if (!securitySchemes || !spec.paths) return {
|
|
283
|
+
excludedCount: 0,
|
|
284
|
+
spec
|
|
285
|
+
};
|
|
286
|
+
const clone = structuredClone(spec);
|
|
287
|
+
let excludedCount = 0;
|
|
288
|
+
for (const [path, pathItem] of Object.entries(clone.paths ?? {})) {
|
|
289
|
+
let removedFromPath = 0;
|
|
290
|
+
for (const method of HTTP_METHODS) {
|
|
291
|
+
const operation = pathItem[method];
|
|
292
|
+
if (!operation) continue;
|
|
293
|
+
if (readSecurityRequirement({
|
|
294
|
+
operation,
|
|
295
|
+
operationId: operation.operationId ?? `${method.toUpperCase()} ${path}`
|
|
296
|
+
}, securitySchemes, clone.security)?.kind !== "internal") continue;
|
|
297
|
+
delete pathItem[method];
|
|
298
|
+
removedFromPath += 1;
|
|
299
|
+
}
|
|
300
|
+
excludedCount += removedFromPath;
|
|
301
|
+
if (removedFromPath > 0 && !HTTP_METHODS.some((method) => pathItem[method])) delete clone.paths?.[path];
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
excludedCount,
|
|
305
|
+
spec: clone
|
|
306
|
+
};
|
|
307
|
+
}
|
|
276
308
|
function readSecurityRequirement(entry, securitySchemes, topLevelSecurity) {
|
|
277
309
|
const security = entry.operation.security ?? topLevelSecurity;
|
|
278
310
|
if (security === void 0) return null;
|
|
@@ -644,9 +676,10 @@ function resolveHttpClientConfig(config) {
|
|
|
644
676
|
};
|
|
645
677
|
}
|
|
646
678
|
const GENERATED_HEADER = ["// This file is auto-generated by vite-plugin-openapi-codegen.", "// Do not edit manually. Changes will be overwritten on next build."];
|
|
647
|
-
async function generateApiTypes(
|
|
679
|
+
async function generateApiTypes(input, outputDir, useTypeAliases) {
|
|
648
680
|
const { default: openapiTS, astToString } = await import("openapi-typescript");
|
|
649
|
-
const
|
|
681
|
+
const { excludedCount, spec } = excludeInternalOperationsFromSpec(input.spec);
|
|
682
|
+
const contents = astToString(await openapiTS(excludedCount > 0 ? spec : input.apiTypesSource, useTypeAliases ? {
|
|
650
683
|
rootTypes: true,
|
|
651
684
|
rootTypesKeepCasing: true,
|
|
652
685
|
rootTypesNoSchemaPrefix: true
|
|
@@ -767,11 +800,13 @@ function parseOpenAPISpec(sourceText, inputLabel) {
|
|
|
767
800
|
async function generateOpenAPIArtifacts(root, options) {
|
|
768
801
|
const outputDir = resolve(root, options.output);
|
|
769
802
|
mkdirSync(outputDir, { recursive: true });
|
|
770
|
-
const
|
|
771
|
-
const
|
|
772
|
-
const
|
|
803
|
+
const input = await loadOpenAPIInput(root, options.input);
|
|
804
|
+
const pathPrefix = options.pathPrefix ?? "/api/";
|
|
805
|
+
const stripPrefix = options.stripPrefix ?? true;
|
|
806
|
+
const operations = collectOperations(input.spec, pathPrefix, stripPrefix);
|
|
807
|
+
const artifacts = renderGeneratedArtifacts(input.spec, options, operations);
|
|
773
808
|
warnOnParameterLocationMismatch(operations);
|
|
774
|
-
await generateApiTypes(
|
|
809
|
+
await generateApiTypes(input, outputDir, options.typeAliases ?? false);
|
|
775
810
|
if (artifacts.apiTypes) writeFileSync(resolve(outputDir, "api-types.d.ts"), artifacts.apiTypes, { flag: "a" });
|
|
776
811
|
if (artifacts.accessPolicies) writeFileSync(resolve(outputDir, "access-policies.ts"), artifacts.accessPolicies);
|
|
777
812
|
writeFileSync(resolve(outputDir, "api.ts"), artifacts.api);
|
|
@@ -790,7 +825,7 @@ function openapiCodegen(options) {
|
|
|
790
825
|
},
|
|
791
826
|
async buildStart() {
|
|
792
827
|
if (command === "serve" && options.generateOnDev !== false) {
|
|
793
|
-
runDevelopmentGeneration(root, options, { onError: resolvePluginErrorRaiser(this) });
|
|
828
|
+
runDevelopmentGeneration(root, options, { onError: resolvePluginErrorRaiser(this) }).catch(() => {});
|
|
794
829
|
return;
|
|
795
830
|
}
|
|
796
831
|
},
|