vite-plugin-openapi-codegen 3.0.0 → 3.1.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 +21 -25
- package/dist/index.d.mts +9 -5
- package/dist/index.mjs +21 -25
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -647,15 +647,9 @@ function createClientRenderModel(model, useTypeAliases) {
|
|
|
647
647
|
}))
|
|
648
648
|
};
|
|
649
649
|
}
|
|
650
|
-
|
|
651
|
-
"authenticated",
|
|
652
|
-
"internal",
|
|
653
|
-
"public",
|
|
654
|
-
"role"
|
|
655
|
-
]);
|
|
656
|
-
function createAccessPolicyEntries(operations) {
|
|
650
|
+
function createAccessPolicyEntries(operations, securitySchemes, topLevelSecurity) {
|
|
657
651
|
return operations.flatMap((entry) => {
|
|
658
|
-
const accessPolicy =
|
|
652
|
+
const accessPolicy = readSecurityRequirement(entry, securitySchemes, topLevelSecurity);
|
|
659
653
|
if (!accessPolicy) return [];
|
|
660
654
|
return [{
|
|
661
655
|
apiPath: entry.apiPath,
|
|
@@ -668,23 +662,25 @@ function createAccessPolicyEntries(operations) {
|
|
|
668
662
|
}];
|
|
669
663
|
});
|
|
670
664
|
}
|
|
671
|
-
function
|
|
672
|
-
const
|
|
673
|
-
if (
|
|
674
|
-
if (!
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
return { kind };
|
|
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
|
+
}
|
|
681
682
|
}
|
|
682
|
-
|
|
683
|
-
if (kind !== "role") throw new Error(`Operation "${entry.operationId}" non-role access must not include roles`);
|
|
684
|
-
return {
|
|
685
|
-
kind,
|
|
686
|
-
roles: rolesValue
|
|
687
|
-
};
|
|
683
|
+
throw new Error(`Operation "${entry.operationId}" has an unrecognized security scheme`);
|
|
688
684
|
}
|
|
689
685
|
function isRecord(value) {
|
|
690
686
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -710,7 +706,7 @@ function renderGeneratedArtifacts(spec, options, preCollectedOperations) {
|
|
|
710
706
|
void: httpClient.voidFunction
|
|
711
707
|
});
|
|
712
708
|
if (clientModel.operations.length === 0) throw new Error(`No paths matching prefix "${pathPrefix}" found in openapi.json`);
|
|
713
|
-
const accessPolicies = renderAccessPoliciesSource(createAccessPolicyEntries(operations), GENERATED_HEADER);
|
|
709
|
+
const accessPolicies = renderAccessPoliciesSource(createAccessPolicyEntries(operations, spec.components?.securitySchemes, spec.security), GENERATED_HEADER);
|
|
714
710
|
return {
|
|
715
711
|
api: renderApiSource(createApiEntries(clientModel.operations, useTypeAliases), GENERATED_HEADER),
|
|
716
712
|
client: renderClientSource(createClientRenderModel(clientModel, useTypeAliases), GENERATED_HEADER, httpClient),
|
package/dist/index.d.mts
CHANGED
|
@@ -26,10 +26,12 @@ interface OpenAPIResponse {
|
|
|
26
26
|
content?: Record<string, OpenAPIContent>;
|
|
27
27
|
description?: string;
|
|
28
28
|
}
|
|
29
|
-
type
|
|
30
|
-
interface
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
type OpenAPISecurityRequirement = Record<string, string[]>;
|
|
30
|
+
interface OpenAPISecurityScheme {
|
|
31
|
+
type?: string;
|
|
32
|
+
scheme?: string;
|
|
33
|
+
in?: string;
|
|
34
|
+
name?: string;
|
|
33
35
|
}
|
|
34
36
|
interface OpenAPIOperation {
|
|
35
37
|
operationId?: string;
|
|
@@ -37,7 +39,7 @@ interface OpenAPIOperation {
|
|
|
37
39
|
requestBody?: OpenAPIRequestBody;
|
|
38
40
|
responses?: Record<string, OpenAPIResponse>;
|
|
39
41
|
tags?: string[];
|
|
40
|
-
|
|
42
|
+
security?: OpenAPISecurityRequirement[];
|
|
41
43
|
}
|
|
42
44
|
type OpenAPIPathItem = Partial<Record<HttpMethod, OpenAPIOperation>>;
|
|
43
45
|
interface OpenAPISchema {
|
|
@@ -48,8 +50,10 @@ interface OpenAPISchema {
|
|
|
48
50
|
}
|
|
49
51
|
interface OpenAPISpec {
|
|
50
52
|
paths?: Record<string, OpenAPIPathItem>;
|
|
53
|
+
security?: OpenAPISecurityRequirement[];
|
|
51
54
|
components?: {
|
|
52
55
|
schemas?: Record<string, OpenAPISchema>;
|
|
56
|
+
securitySchemes?: Record<string, OpenAPISecurityScheme>;
|
|
53
57
|
};
|
|
54
58
|
}
|
|
55
59
|
interface OperationEntry {
|
package/dist/index.mjs
CHANGED
|
@@ -645,15 +645,9 @@ function createClientRenderModel(model, useTypeAliases) {
|
|
|
645
645
|
}))
|
|
646
646
|
};
|
|
647
647
|
}
|
|
648
|
-
|
|
649
|
-
"authenticated",
|
|
650
|
-
"internal",
|
|
651
|
-
"public",
|
|
652
|
-
"role"
|
|
653
|
-
]);
|
|
654
|
-
function createAccessPolicyEntries(operations) {
|
|
648
|
+
function createAccessPolicyEntries(operations, securitySchemes, topLevelSecurity) {
|
|
655
649
|
return operations.flatMap((entry) => {
|
|
656
|
-
const accessPolicy =
|
|
650
|
+
const accessPolicy = readSecurityRequirement(entry, securitySchemes, topLevelSecurity);
|
|
657
651
|
if (!accessPolicy) return [];
|
|
658
652
|
return [{
|
|
659
653
|
apiPath: entry.apiPath,
|
|
@@ -666,23 +660,25 @@ function createAccessPolicyEntries(operations) {
|
|
|
666
660
|
}];
|
|
667
661
|
});
|
|
668
662
|
}
|
|
669
|
-
function
|
|
670
|
-
const
|
|
671
|
-
if (
|
|
672
|
-
if (!
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
return { kind };
|
|
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
|
+
}
|
|
679
680
|
}
|
|
680
|
-
|
|
681
|
-
if (kind !== "role") throw new Error(`Operation "${entry.operationId}" non-role access must not include roles`);
|
|
682
|
-
return {
|
|
683
|
-
kind,
|
|
684
|
-
roles: rolesValue
|
|
685
|
-
};
|
|
681
|
+
throw new Error(`Operation "${entry.operationId}" has an unrecognized security scheme`);
|
|
686
682
|
}
|
|
687
683
|
function isRecord(value) {
|
|
688
684
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -708,7 +704,7 @@ function renderGeneratedArtifacts(spec, options, preCollectedOperations) {
|
|
|
708
704
|
void: httpClient.voidFunction
|
|
709
705
|
});
|
|
710
706
|
if (clientModel.operations.length === 0) throw new Error(`No paths matching prefix "${pathPrefix}" found in openapi.json`);
|
|
711
|
-
const accessPolicies = renderAccessPoliciesSource(createAccessPolicyEntries(operations), GENERATED_HEADER);
|
|
707
|
+
const accessPolicies = renderAccessPoliciesSource(createAccessPolicyEntries(operations, spec.components?.securitySchemes, spec.security), GENERATED_HEADER);
|
|
712
708
|
return {
|
|
713
709
|
api: renderApiSource(createApiEntries(clientModel.operations, useTypeAliases), GENERATED_HEADER),
|
|
714
710
|
client: renderClientSource(createClientRenderModel(clientModel, useTypeAliases), GENERATED_HEADER, httpClient),
|