vite-plugin-openapi-codegen 3.2.0 → 3.2.1
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 +43 -24
- package/dist/index.mjs +58 -29
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -268,7 +268,49 @@ function collectOperations(spec, pathPrefix = "/api/", stripPrefix = true) {
|
|
|
268
268
|
});
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
|
-
return entries;
|
|
271
|
+
return excludeInternalOperations(entries, spec);
|
|
272
|
+
}
|
|
273
|
+
function excludeInternalOperations(entries, spec) {
|
|
274
|
+
const securitySchemes = spec.components?.securitySchemes;
|
|
275
|
+
if (!securitySchemes) return entries;
|
|
276
|
+
return entries.filter((entry) => readSecurityRequirement(entry, securitySchemes, spec.security)?.kind !== "internal");
|
|
277
|
+
}
|
|
278
|
+
function readSecurityRequirement(entry, securitySchemes, topLevelSecurity) {
|
|
279
|
+
const security = entry.operation.security ?? topLevelSecurity;
|
|
280
|
+
if (security === void 0) return null;
|
|
281
|
+
if (!Array.isArray(security)) throw new Error(`Operation "${entry.operationId}" has invalid security`);
|
|
282
|
+
if (security.length === 0) return { kind: "public" };
|
|
283
|
+
if (security.length > 1) throw new Error(`Operation "${entry.operationId}" declares ${security.length} security requirements; the backend contract emits at most one`);
|
|
284
|
+
const requirement = security[0];
|
|
285
|
+
if (!isRecord(requirement)) throw new Error(`Operation "${entry.operationId}" has an invalid security requirement`);
|
|
286
|
+
const schemeEntries = Object.entries(requirement);
|
|
287
|
+
if (schemeEntries.length > 1) throw new Error(`Operation "${entry.operationId}" declares ${schemeEntries.length} schemes in one security requirement; the backend contract emits exactly one`);
|
|
288
|
+
const schemeEntry = schemeEntries[0];
|
|
289
|
+
if (schemeEntry) {
|
|
290
|
+
const [schemeName, scopes] = schemeEntry;
|
|
291
|
+
const scheme = securitySchemes?.[schemeName];
|
|
292
|
+
if (scheme?.type === "apiKey" && scheme.in === "header") return { kind: "internal" };
|
|
293
|
+
if (scheme?.type === "http" || scheme?.type === "apiKey" && scheme.in === "cookie") {
|
|
294
|
+
const roles = readSecurityScopes(entry, schemeName, scopes);
|
|
295
|
+
return roles.length === 0 ? { kind: "authenticated" } : {
|
|
296
|
+
kind: "role",
|
|
297
|
+
roles
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
throw new Error(`Operation "${entry.operationId}" has an unrecognized security scheme`);
|
|
302
|
+
}
|
|
303
|
+
function readSecurityScopes(entry, schemeName, scopes) {
|
|
304
|
+
if (!Array.isArray(scopes)) throw new Error(`Operation "${entry.operationId}" has non-array scopes for security scheme "${schemeName}"`);
|
|
305
|
+
const roles = [];
|
|
306
|
+
for (const scope of scopes) {
|
|
307
|
+
if (typeof scope !== "string") throw new Error(`Operation "${entry.operationId}" has a non-string scope for security scheme "${schemeName}"`);
|
|
308
|
+
roles.push(scope);
|
|
309
|
+
}
|
|
310
|
+
return roles;
|
|
311
|
+
}
|
|
312
|
+
function isRecord(value) {
|
|
313
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
272
314
|
}
|
|
273
315
|
function getEffectiveParametersByLocation(entry, location) {
|
|
274
316
|
return (entry.operation.parameters ?? []).filter((parameter) => getEffectiveParameterLocation(entry.apiPath, parameter) === location);
|
|
@@ -662,29 +704,6 @@ function createAccessPolicyEntries(operations, securitySchemes, topLevelSecurity
|
|
|
662
704
|
}];
|
|
663
705
|
});
|
|
664
706
|
}
|
|
665
|
-
function readSecurityRequirement(entry, securitySchemes, topLevelSecurity) {
|
|
666
|
-
const security = entry.operation.security ?? topLevelSecurity;
|
|
667
|
-
if (security === void 0) return null;
|
|
668
|
-
if (!Array.isArray(security)) throw new Error(`Operation "${entry.operationId}" has invalid security`);
|
|
669
|
-
if (security.length === 0) return { kind: "public" };
|
|
670
|
-
const requirement = security[0];
|
|
671
|
-
if (!isRecord(requirement)) throw new Error(`Operation "${entry.operationId}" has an invalid security requirement`);
|
|
672
|
-
for (const [schemeName, scopes] of Object.entries(requirement)) {
|
|
673
|
-
const scheme = securitySchemes?.[schemeName];
|
|
674
|
-
if (scheme?.type === "apiKey" && scheme.in === "header") return { kind: "internal" };
|
|
675
|
-
if (scheme?.type === "http" || scheme?.type === "apiKey" && scheme.in === "cookie") {
|
|
676
|
-
const roles = Array.isArray(scopes) ? scopes.filter((scope) => typeof scope === "string") : [];
|
|
677
|
-
return roles.length === 0 ? { kind: "authenticated" } : {
|
|
678
|
-
kind: "role",
|
|
679
|
-
roles
|
|
680
|
-
};
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
throw new Error(`Operation "${entry.operationId}" has an unrecognized security scheme`);
|
|
684
|
-
}
|
|
685
|
-
function isRecord(value) {
|
|
686
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
687
|
-
}
|
|
688
707
|
function resolveChannel(channel, useTypeAliases) {
|
|
689
708
|
if (!channel.typeRef) return channel;
|
|
690
709
|
return {
|
package/dist/index.mjs
CHANGED
|
@@ -266,7 +266,49 @@ function collectOperations(spec, pathPrefix = "/api/", stripPrefix = true) {
|
|
|
266
266
|
});
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
|
-
return entries;
|
|
269
|
+
return excludeInternalOperations(entries, spec);
|
|
270
|
+
}
|
|
271
|
+
function excludeInternalOperations(entries, spec) {
|
|
272
|
+
const securitySchemes = spec.components?.securitySchemes;
|
|
273
|
+
if (!securitySchemes) return entries;
|
|
274
|
+
return entries.filter((entry) => readSecurityRequirement(entry, securitySchemes, spec.security)?.kind !== "internal");
|
|
275
|
+
}
|
|
276
|
+
function readSecurityRequirement(entry, securitySchemes, topLevelSecurity) {
|
|
277
|
+
const security = entry.operation.security ?? topLevelSecurity;
|
|
278
|
+
if (security === void 0) return null;
|
|
279
|
+
if (!Array.isArray(security)) throw new Error(`Operation "${entry.operationId}" has invalid security`);
|
|
280
|
+
if (security.length === 0) return { kind: "public" };
|
|
281
|
+
if (security.length > 1) throw new Error(`Operation "${entry.operationId}" declares ${security.length} security requirements; the backend contract emits at most one`);
|
|
282
|
+
const requirement = security[0];
|
|
283
|
+
if (!isRecord(requirement)) throw new Error(`Operation "${entry.operationId}" has an invalid security requirement`);
|
|
284
|
+
const schemeEntries = Object.entries(requirement);
|
|
285
|
+
if (schemeEntries.length > 1) throw new Error(`Operation "${entry.operationId}" declares ${schemeEntries.length} schemes in one security requirement; the backend contract emits exactly one`);
|
|
286
|
+
const schemeEntry = schemeEntries[0];
|
|
287
|
+
if (schemeEntry) {
|
|
288
|
+
const [schemeName, scopes] = schemeEntry;
|
|
289
|
+
const scheme = securitySchemes?.[schemeName];
|
|
290
|
+
if (scheme?.type === "apiKey" && scheme.in === "header") return { kind: "internal" };
|
|
291
|
+
if (scheme?.type === "http" || scheme?.type === "apiKey" && scheme.in === "cookie") {
|
|
292
|
+
const roles = readSecurityScopes(entry, schemeName, scopes);
|
|
293
|
+
return roles.length === 0 ? { kind: "authenticated" } : {
|
|
294
|
+
kind: "role",
|
|
295
|
+
roles
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
throw new Error(`Operation "${entry.operationId}" has an unrecognized security scheme`);
|
|
300
|
+
}
|
|
301
|
+
function readSecurityScopes(entry, schemeName, scopes) {
|
|
302
|
+
if (!Array.isArray(scopes)) throw new Error(`Operation "${entry.operationId}" has non-array scopes for security scheme "${schemeName}"`);
|
|
303
|
+
const roles = [];
|
|
304
|
+
for (const scope of scopes) {
|
|
305
|
+
if (typeof scope !== "string") throw new Error(`Operation "${entry.operationId}" has a non-string scope for security scheme "${schemeName}"`);
|
|
306
|
+
roles.push(scope);
|
|
307
|
+
}
|
|
308
|
+
return roles;
|
|
309
|
+
}
|
|
310
|
+
function isRecord(value) {
|
|
311
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
270
312
|
}
|
|
271
313
|
function getEffectiveParametersByLocation(entry, location) {
|
|
272
314
|
return (entry.operation.parameters ?? []).filter((parameter) => getEffectiveParameterLocation(entry.apiPath, parameter) === location);
|
|
@@ -660,29 +702,6 @@ function createAccessPolicyEntries(operations, securitySchemes, topLevelSecurity
|
|
|
660
702
|
}];
|
|
661
703
|
});
|
|
662
704
|
}
|
|
663
|
-
function readSecurityRequirement(entry, securitySchemes, topLevelSecurity) {
|
|
664
|
-
const security = entry.operation.security ?? topLevelSecurity;
|
|
665
|
-
if (security === void 0) return null;
|
|
666
|
-
if (!Array.isArray(security)) throw new Error(`Operation "${entry.operationId}" has invalid security`);
|
|
667
|
-
if (security.length === 0) return { kind: "public" };
|
|
668
|
-
const requirement = security[0];
|
|
669
|
-
if (!isRecord(requirement)) throw new Error(`Operation "${entry.operationId}" has an invalid security requirement`);
|
|
670
|
-
for (const [schemeName, scopes] of Object.entries(requirement)) {
|
|
671
|
-
const scheme = securitySchemes?.[schemeName];
|
|
672
|
-
if (scheme?.type === "apiKey" && scheme.in === "header") return { kind: "internal" };
|
|
673
|
-
if (scheme?.type === "http" || scheme?.type === "apiKey" && scheme.in === "cookie") {
|
|
674
|
-
const roles = Array.isArray(scopes) ? scopes.filter((scope) => typeof scope === "string") : [];
|
|
675
|
-
return roles.length === 0 ? { kind: "authenticated" } : {
|
|
676
|
-
kind: "role",
|
|
677
|
-
roles
|
|
678
|
-
};
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
throw new Error(`Operation "${entry.operationId}" has an unrecognized security scheme`);
|
|
682
|
-
}
|
|
683
|
-
function isRecord(value) {
|
|
684
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
685
|
-
}
|
|
686
705
|
function resolveChannel(channel, useTypeAliases) {
|
|
687
706
|
if (!channel.typeRef) return channel;
|
|
688
707
|
return {
|
|
@@ -771,7 +790,7 @@ function openapiCodegen(options) {
|
|
|
771
790
|
},
|
|
772
791
|
async buildStart() {
|
|
773
792
|
if (command === "serve" && options.generateOnDev !== false) {
|
|
774
|
-
runDevelopmentGeneration(root, options);
|
|
793
|
+
runDevelopmentGeneration(root, options, { onError: resolvePluginErrorRaiser(this) });
|
|
775
794
|
return;
|
|
776
795
|
}
|
|
777
796
|
},
|
|
@@ -781,9 +800,12 @@ function openapiCodegen(options) {
|
|
|
781
800
|
const inputPath = resolve(root, options.input);
|
|
782
801
|
if (resolve(ctx.file) !== inputPath) return;
|
|
783
802
|
console.log("[openapi-codegen] openapi.json changed, regenerating...");
|
|
784
|
-
await runDevelopmentGeneration(root, options, {
|
|
785
|
-
|
|
786
|
-
|
|
803
|
+
await runDevelopmentGeneration(root, options, {
|
|
804
|
+
onError: resolvePluginErrorRaiser(this),
|
|
805
|
+
onSuccess: () => {
|
|
806
|
+
console.log("[openapi-codegen] regeneration complete.");
|
|
807
|
+
}
|
|
808
|
+
});
|
|
787
809
|
}
|
|
788
810
|
};
|
|
789
811
|
}
|
|
@@ -792,8 +814,15 @@ async function runDevelopmentGeneration(root, options, handlers) {
|
|
|
792
814
|
await generateOpenAPIArtifacts(root, options);
|
|
793
815
|
handlers?.onSuccess?.();
|
|
794
816
|
} catch (error) {
|
|
795
|
-
|
|
817
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
818
|
+
console.error("[openapi-codegen] generation failed during dev mode.", failure);
|
|
819
|
+
handlers?.onError?.(failure);
|
|
796
820
|
}
|
|
797
821
|
}
|
|
822
|
+
function resolvePluginErrorRaiser(context) {
|
|
823
|
+
if (typeof context !== "object" || context === null || typeof context.error !== "function") return;
|
|
824
|
+
const pluginContext = context;
|
|
825
|
+
return (error) => pluginContext.error(error);
|
|
826
|
+
}
|
|
798
827
|
//#endregion
|
|
799
828
|
export { openapiCodegen, renderGeneratedArtifacts };
|