@sdk-it/spec 0.46.2 → 0.46.4
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/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +2 -2
- package/dist/lib/find-unique-schema-name.d.ts +2 -2
- package/dist/lib/find-unique-schema-name.d.ts.map +1 -1
- package/dist/lib/find-unique-schema-name.js.map +2 -2
- package/dist/lib/loaders/load-spec.d.ts.map +1 -1
- package/dist/lib/loaders/load-spec.js +13 -3
- package/dist/lib/loaders/load-spec.js.map +2 -2
- package/dist/lib/options.d.ts +3 -2
- package/dist/lib/options.d.ts.map +1 -1
- package/dist/lib/options.js +4 -1
- package/dist/lib/options.js.map +2 -2
- package/dist/lib/processing-plugins/create-default-processing-plugins.d.ts.map +1 -1
- package/dist/lib/processing-plugins/create-default-processing-plugins.js +4 -0
- package/dist/lib/processing-plugins/create-default-processing-plugins.js.map +2 -2
- package/dist/lib/processing-plugins/index.d.ts +2 -0
- package/dist/lib/processing-plugins/index.d.ts.map +1 -1
- package/dist/lib/processing-plugins/index.js +2 -0
- package/dist/lib/processing-plugins/index.js.map +2 -2
- package/dist/lib/processing-plugins/normalize-request-bodies.d.ts +2 -2
- package/dist/lib/processing-plugins/normalize-request-bodies.d.ts.map +1 -1
- package/dist/lib/processing-plugins/normalize-request-bodies.js +6 -21
- package/dist/lib/processing-plugins/normalize-request-bodies.js.map +2 -2
- package/dist/lib/processing-plugins/normalize-security.d.ts +3 -0
- package/dist/lib/processing-plugins/normalize-security.d.ts.map +1 -0
- package/dist/lib/processing-plugins/normalize-security.js +142 -0
- package/dist/lib/processing-plugins/normalize-security.js.map +7 -0
- package/dist/lib/processing-plugins/resolve-security-scheme-uris.d.ts +9 -0
- package/dist/lib/processing-plugins/resolve-security-scheme-uris.d.ts.map +1 -0
- package/dist/lib/processing-plugins/resolve-security-scheme-uris.js +139 -0
- package/dist/lib/processing-plugins/resolve-security-scheme-uris.js.map +7 -0
- package/dist/lib/processing.js.map +1 -1
- package/dist/lib/types.d.ts +6 -5
- package/dist/lib/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/lib/security.d.ts +0 -12
- package/dist/lib/security.d.ts.map +0 -1
- package/dist/lib/security.js +0 -78
- package/dist/lib/security.js.map +0 -7
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,6 @@ export * from './lib/processing-plugins/index.js';
|
|
|
16
16
|
export * from './lib/processing.js';
|
|
17
17
|
export * from './lib/overview-docs/overview-errors.js';
|
|
18
18
|
export * from './lib/reserved-keywords.js';
|
|
19
|
-
export * from './lib/security.js';
|
|
20
19
|
export * from './lib/sidebar.js';
|
|
21
20
|
export * from './lib/tag.js';
|
|
22
21
|
export * from './lib/types.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,aAAa,CAAC;AAC5B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mCAAmC,CAAC;AAClD,cAAc,qBAAqB,CAAC;AACpC,cAAc,wCAAwC,CAAC;AACvD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,aAAa,CAAC;AAC5B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mCAAmC,CAAC;AAClD,cAAc,qBAAqB,CAAC;AACpC,cAAc,wCAAwC,CAAC;AACvD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,6 @@ export * from "./lib/processing-plugins/index.js";
|
|
|
16
16
|
export * from "./lib/processing.js";
|
|
17
17
|
export * from "./lib/overview-docs/overview-errors.js";
|
|
18
18
|
export * from "./lib/reserved-keywords.js";
|
|
19
|
-
export * from "./lib/security.js";
|
|
20
19
|
export * from "./lib/sidebar.js";
|
|
21
20
|
export * from "./lib/tag.js";
|
|
22
21
|
export * from "./lib/types.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["export * from './lib/create-operation.js';\nexport * from './lib/find-polymorphic-varients.js';\nexport * from './lib/find-unique-schema-name.js';\nexport * from './lib/for-each-operation.js';\nexport * from './lib/format-name.js';\nexport * from './lib/get-ref-usage.js';\nexport * from './lib/ir.js';\nexport * from './lib/is-primitive-schema.js';\nexport * from './lib/is.js';\nexport * from './lib/loaders/load-spec.js';\nexport * from './lib/loaders/local-loader.js';\nexport * from './lib/loaders/remote-loader.js';\nexport * from './lib/metadata.js';\nexport * from './lib/options.js';\nexport * from './lib/processing-plugins/index.js';\nexport * from './lib/processing.js';\nexport * from './lib/overview-docs/overview-errors.js';\nexport * from './lib/reserved-keywords.js';\nexport * from './lib/
|
|
5
|
-
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;
|
|
4
|
+
"sourcesContent": ["export * from './lib/create-operation.js';\nexport * from './lib/find-polymorphic-varients.js';\nexport * from './lib/find-unique-schema-name.js';\nexport * from './lib/for-each-operation.js';\nexport * from './lib/format-name.js';\nexport * from './lib/get-ref-usage.js';\nexport * from './lib/ir.js';\nexport * from './lib/is-primitive-schema.js';\nexport * from './lib/is.js';\nexport * from './lib/loaders/load-spec.js';\nexport * from './lib/loaders/local-loader.js';\nexport * from './lib/loaders/remote-loader.js';\nexport * from './lib/metadata.js';\nexport * from './lib/options.js';\nexport * from './lib/processing-plugins/index.js';\nexport * from './lib/processing.js';\nexport * from './lib/overview-docs/overview-errors.js';\nexport * from './lib/reserved-keywords.js';\nexport * from './lib/sidebar.js';\nexport * from './lib/tag.js';\nexport * from './lib/types.js';\nexport * from './lib/walk-schemas.js';\n"],
|
|
5
|
+
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type
|
|
2
|
-
export declare function findUniqueSchemaName(spec:
|
|
1
|
+
import { type OpenAPIDocument } from '@sdk-it/core';
|
|
2
|
+
export declare function findUniqueSchemaName(spec: OpenAPIDocument, initialName: string, potentialSuffixList: string[], fallback?: string): string;
|
|
3
3
|
//# sourceMappingURL=find-unique-schema-name.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-unique-schema-name.d.ts","sourceRoot":"","sources":["../../src/lib/find-unique-schema-name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"find-unique-schema-name.d.ts","sourceRoot":"","sources":["../../src/lib/find-unique-schema-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAA8B,MAAM,cAAc,CAAC;AAIhF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,eAAe,EACrB,WAAW,EAAE,MAAM,EACnB,mBAAmB,EAAE,MAAM,EAAE,EAC7B,QAAQ,CAAC,EAAE,MAAM,UAUlB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/find-unique-schema-name.ts"],
|
|
4
|
-
"sourcesContent": ["import
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { type OpenAPIDocument, joinSkipDigits, pascalcase } from '@sdk-it/core';\n\nconst reservedNames = new Set(['Function', 'Error']);\n\nexport function findUniqueSchemaName(\n spec: OpenAPIDocument,\n initialName: string,\n potentialSuffixList: string[],\n fallback?: string,\n) {\n spec.components ??= {};\n spec.components.schemas ??= {};\n let name = pascalcase(initialName);\n while (spec.components.schemas[name] || reservedNames.has(name)) {\n const suffix = potentialSuffixList.shift();\n name = pascalcase(joinSkipDigits([name, suffix || ''], ' '));\n }\n return initialName === name ? (fallback ?? name) : name;\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAA+B,gBAAgB,kBAAkB;AAEjE,MAAM,gBAAgB,oBAAI,IAAI,CAAC,YAAY,OAAO,CAAC;AAE5C,SAAS,qBACd,MACA,aACA,qBACA,UACA;AACA,OAAK,eAAe,CAAC;AACrB,OAAK,WAAW,YAAY,CAAC;AAC7B,MAAI,OAAO,WAAW,WAAW;AACjC,SAAO,KAAK,WAAW,QAAQ,IAAI,KAAK,cAAc,IAAI,IAAI,GAAG;AAC/D,UAAM,SAAS,oBAAoB,MAAM;AACzC,WAAO,WAAW,eAAe,CAAC,MAAM,UAAU,EAAE,GAAG,GAAG,CAAC;AAAA,EAC7D;AACA,SAAO,gBAAgB,OAAQ,YAAY,OAAQ;AACrD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-spec.d.ts","sourceRoot":"","sources":["../../../src/lib/loaders/load-spec.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"load-spec.d.ts","sourceRoot":"","sources":["../../../src/lib/loaders/load-spec.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAuBvD,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CASvE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAKxD"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
1
3
|
import { loadLocal } from "./local-loader.js";
|
|
2
4
|
import { convertPostmanToOpenAPI } from "./postman/postman-converter.js";
|
|
3
5
|
import { loadRemote } from "./remote-loader.js";
|
|
@@ -9,15 +11,23 @@ async function loadSpec(location) {
|
|
|
9
11
|
if (isPostman(content)) {
|
|
10
12
|
content = convertPostmanToOpenAPI(content);
|
|
11
13
|
}
|
|
12
|
-
|
|
14
|
+
const spec = content;
|
|
15
|
+
spec.$self ??= documentUri(location);
|
|
16
|
+
return spec;
|
|
13
17
|
}
|
|
14
18
|
function loadFile(location) {
|
|
15
|
-
|
|
16
|
-
if (protocol === "http" || protocol === "https") {
|
|
19
|
+
if (isRemote(location)) {
|
|
17
20
|
return loadRemote(location);
|
|
18
21
|
}
|
|
19
22
|
return loadLocal(location);
|
|
20
23
|
}
|
|
24
|
+
function documentUri(location) {
|
|
25
|
+
return isRemote(location) || location.startsWith("file:") ? location : pathToFileURL(resolve(location)).href;
|
|
26
|
+
}
|
|
27
|
+
function isRemote(location) {
|
|
28
|
+
const [protocol] = location.split(":");
|
|
29
|
+
return protocol === "http" || protocol === "https";
|
|
30
|
+
}
|
|
21
31
|
export {
|
|
22
32
|
loadFile,
|
|
23
33
|
loadSpec
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/loaders/load-spec.ts"],
|
|
4
|
-
"sourcesContent": ["import type { OpenAPIObject } from 'openapi3-ts/oas31';\n\nimport { loadLocal } from './local-loader.js';\nimport { convertPostmanToOpenAPI } from './postman/postman-converter.js';\nimport type { PostmanCollection } from './postman/spec-types.js';\nimport { loadRemote } from './remote-loader.js';\n\nfunction isPostman(content: unknown): content is PostmanCollection {\n return (\n typeof content === 'object' &&\n content !== null &&\n 'info' in content &&\n typeof content.info === 'object' &&\n content.info !== null &&\n 'item' in content &&\n Array.isArray(content.item) &&\n 'schema' in content.info &&\n typeof content.info.schema === 'string' &&\n content.info.schema.includes('//schema.getpostman.com/')\n );\n}\nexport async function loadSpec(location: string): Promise<OpenAPIObject> {\n let content = await loadFile(location);\n if (isPostman(content)) {\n content = convertPostmanToOpenAPI(content);\n }\n
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { OpenAPIObject } from 'openapi3-ts/oas31';\n\nimport type { OpenAPIDocument } from '@sdk-it/core';\n\nimport { loadLocal } from './local-loader.js';\nimport { convertPostmanToOpenAPI } from './postman/postman-converter.js';\nimport type { PostmanCollection } from './postman/spec-types.js';\nimport { loadRemote } from './remote-loader.js';\n\nfunction isPostman(content: unknown): content is PostmanCollection {\n return (\n typeof content === 'object' &&\n content !== null &&\n 'info' in content &&\n typeof content.info === 'object' &&\n content.info !== null &&\n 'item' in content &&\n Array.isArray(content.item) &&\n 'schema' in content.info &&\n typeof content.info.schema === 'string' &&\n content.info.schema.includes('//schema.getpostman.com/')\n );\n}\nexport async function loadSpec(location: string): Promise<OpenAPIObject> {\n let content = await loadFile(location);\n if (isPostman(content)) {\n content = convertPostmanToOpenAPI(content);\n }\n const spec = content as OpenAPIDocument;\n // Relative references inside the document resolve against where it came from.\n spec.$self ??= documentUri(location);\n return spec as OpenAPIObject;\n}\n\nexport function loadFile<T>(location: string): Promise<T> {\n if (isRemote(location)) {\n return loadRemote(location);\n }\n return loadLocal(location);\n}\n\nfunction documentUri(location: string) {\n return isRemote(location) || location.startsWith('file:')\n ? location\n : pathToFileURL(resolve(location)).href;\n}\n\nfunction isRemote(location: string) {\n const [protocol] = location.split(':');\n return protocol === 'http' || protocol === 'https';\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAK9B,SAAS,iBAAiB;AAC1B,SAAS,+BAA+B;AAExC,SAAS,kBAAkB;AAE3B,SAAS,UAAU,SAAgD;AACjE,SACE,OAAO,YAAY,YACnB,YAAY,QACZ,UAAU,WACV,OAAO,QAAQ,SAAS,YACxB,QAAQ,SAAS,QACjB,UAAU,WACV,MAAM,QAAQ,QAAQ,IAAI,KAC1B,YAAY,QAAQ,QACpB,OAAO,QAAQ,KAAK,WAAW,YAC/B,QAAQ,KAAK,OAAO,SAAS,0BAA0B;AAE3D;AACA,eAAsB,SAAS,UAA0C;AACvE,MAAI,UAAU,MAAM,SAAS,QAAQ;AACrC,MAAI,UAAU,OAAO,GAAG;AACtB,cAAU,wBAAwB,OAAO;AAAA,EAC3C;AACA,QAAM,OAAO;AAEb,OAAK,UAAU,YAAY,QAAQ;AACnC,SAAO;AACT;AAEO,SAAS,SAAY,UAA8B;AACxD,MAAI,SAAS,QAAQ,GAAG;AACtB,WAAO,WAAW,QAAQ;AAAA,EAC5B;AACA,SAAO,UAAU,QAAQ;AAC3B;AAEA,SAAS,YAAY,UAAkB;AACrC,SAAO,SAAS,QAAQ,KAAK,SAAS,WAAW,OAAO,IACpD,WACA,cAAc,QAAQ,QAAQ,CAAC,EAAE;AACvC;AAEA,SAAS,SAAS,UAAkB;AAClC,QAAM,CAAC,QAAQ,IAAI,SAAS,MAAM,GAAG;AACrC,SAAO,aAAa,UAAU,aAAa;AAC7C;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/lib/options.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OperationObject } from 'openapi3-ts/oas31';
|
|
2
|
+
import { type OpenAPIDocument } from '@sdk-it/core';
|
|
2
3
|
import type { ProcessingDiagnostic, ProcessingPlugin } from './processing.js';
|
|
3
4
|
import type { IR } from './types.js';
|
|
4
5
|
export interface GenerateSdkConfig {
|
|
5
|
-
spec:
|
|
6
|
+
spec: OpenAPIDocument;
|
|
6
7
|
responses?: ResponsesConfig;
|
|
7
8
|
pagination?: PaginationConfig | false;
|
|
8
9
|
operationId?: (operation: OperationObject, path: string, method: string) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/lib/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/lib/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EACL,KAAK,eAAe,EAIrB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE9E,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAErC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,CAAC;IACtB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,UAAU,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC;IACtC,WAAW,CAAC,EAAE,CACZ,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,KACX,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3D,OAAO,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACtC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC3D;AACD,MAAM,WAAW,eAAe;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AACF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,UAEnD;AAED,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAC/C,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,KAAK,CAAC,CAkBxD,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB;;;;;;;6BAzCxC,eAAe,QACpB,MAAM,UACJ,MAAM,KACX,MAAM;qBACO,eAAe,QAAQ,MAAM,KAAK,MAAM;EAuE3D;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,KAAK;;;EAmB9C"}
|
package/dist/lib/options.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
camelcase,
|
|
3
|
+
resolveRef
|
|
4
|
+
} from "@sdk-it/core";
|
|
2
5
|
import { determineGenericTag, sanitizeTag } from "./tag.js";
|
|
3
6
|
function cleanOperationId(operationId) {
|
|
4
7
|
return camelcase(operationId.split("#").pop());
|
package/dist/lib/options.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/options.ts"],
|
|
4
|
-
"sourcesContent": ["import type {
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import type { OperationObject } from 'openapi3-ts/oas31';\n\nimport {\n type OpenAPIDocument,\n type OpenAPISecuritySchemeObject,\n camelcase,\n resolveRef,\n} from '@sdk-it/core';\n\nimport type { ProcessingDiagnostic, ProcessingPlugin } from './processing.js';\nimport { determineGenericTag, sanitizeTag } from './tag.js';\nimport type { IR } from './types.js';\n\nexport interface GenerateSdkConfig {\n spec: OpenAPIDocument;\n responses?: ResponsesConfig;\n pagination?: PaginationConfig | false;\n operationId?: (\n operation: OperationObject,\n path: string,\n method: string,\n ) => string;\n tag?: (operation: OperationObject, path: string) => string;\n plugins?: readonly ProcessingPlugin[];\n signal?: AbortSignal;\n onDiagnostic?: (diagnostic: ProcessingDiagnostic) => void;\n}\nexport interface ResponsesConfig {\n flattenErrorResponses?: boolean;\n}\n\nexport type PaginationConfig = {\n guess?: boolean;\n};\nexport function cleanOperationId(operationId: string) {\n return camelcase(operationId.split('#').pop()!);\n}\n\nexport const defaults: Partial<GenerateSdkConfig> &\n Required<Pick<GenerateSdkConfig, 'operationId' | 'tag'>> = {\n operationId: (operation, path, method) => {\n if (operation.operationId) {\n return cleanOperationId(operation.operationId);\n }\n\n return camelcase(\n [method, ...path.replace(/[\\\\/\\\\{\\\\}]/g, ' ').split(' ')]\n .filter(Boolean)\n .join(' ')\n .trim(),\n );\n },\n tag: (operation, path) => {\n return operation.tags?.[0]\n ? sanitizeTag(operation.tags?.[0])\n : determineGenericTag(path, operation);\n },\n};\n\nexport function coeraceConfig(config: GenerateSdkConfig) {\n const spec: IR = {\n ...config.spec,\n components: {\n ...config.spec.components,\n schemas: config.spec.components?.schemas ?? {},\n securitySchemes: Object.fromEntries(\n Object.entries(config.spec.components?.securitySchemes ?? {}).map(\n ([name, schema]) => [\n name,\n resolveRef<OpenAPISecuritySchemeObject>(config.spec, schema),\n ],\n ),\n ),\n },\n paths: config.spec.paths ?? {},\n 'x-docs': [],\n 'x-tagGroups': config.spec['x-tagGroups'] ?? [\n {\n name: 'API',\n tags: config.spec.tags?.map((tag) => tag.name) ?? [],\n },\n ],\n servers: config.spec.servers ?? [],\n tags: config.spec.tags ?? [],\n };\n\n return {\n pagination: coercePaginationConfig(config.pagination),\n responses: config.responses ?? {},\n spec,\n operationId: config.operationId ?? defaults.operationId,\n tag: config.tag ?? defaults.tag,\n };\n}\n\nexport function coercePaginationConfig(\n options: PaginationConfig | undefined | false,\n) {\n if (options === undefined) {\n return {\n guess: true,\n enabled: true,\n };\n }\n if (options === false) {\n return {\n enabled: false,\n guess: false,\n };\n }\n // If options is true, we assume pagination is enabled with guessing\n return {\n guess: options.guess ?? true,\n enabled: true,\n };\n}\n"],
|
|
5
|
+
"mappings": "AAEA;AAAA,EAGE;AAAA,EACA;AAAA,OACK;AAGP,SAAS,qBAAqB,mBAAmB;AAwB1C,SAAS,iBAAiB,aAAqB;AACpD,SAAO,UAAU,YAAY,MAAM,GAAG,EAAE,IAAI,CAAE;AAChD;AAEO,MAAM,WACgD;AAAA,EAC3D,aAAa,CAAC,WAAW,MAAM,WAAW;AACxC,QAAI,UAAU,aAAa;AACzB,aAAO,iBAAiB,UAAU,WAAW;AAAA,IAC/C;AAEA,WAAO;AAAA,MACL,CAAC,QAAQ,GAAG,KAAK,QAAQ,gBAAgB,GAAG,EAAE,MAAM,GAAG,CAAC,EACrD,OAAO,OAAO,EACd,KAAK,GAAG,EACR,KAAK;AAAA,IACV;AAAA,EACF;AAAA,EACA,KAAK,CAAC,WAAW,SAAS;AACxB,WAAO,UAAU,OAAO,CAAC,IACrB,YAAY,UAAU,OAAO,CAAC,CAAC,IAC/B,oBAAoB,MAAM,SAAS;AAAA,EACzC;AACF;AAEO,SAAS,cAAc,QAA2B;AACvD,QAAM,OAAW;AAAA,IACf,GAAG,OAAO;AAAA,IACV,YAAY;AAAA,MACV,GAAG,OAAO,KAAK;AAAA,MACf,SAAS,OAAO,KAAK,YAAY,WAAW,CAAC;AAAA,MAC7C,iBAAiB,OAAO;AAAA,QACtB,OAAO,QAAQ,OAAO,KAAK,YAAY,mBAAmB,CAAC,CAAC,EAAE;AAAA,UAC5D,CAAC,CAAC,MAAM,MAAM,MAAM;AAAA,YAClB;AAAA,YACA,WAAwC,OAAO,MAAM,MAAM;AAAA,UAC7D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,OAAO,OAAO,KAAK,SAAS,CAAC;AAAA,IAC7B,UAAU,CAAC;AAAA,IACX,eAAe,OAAO,KAAK,aAAa,KAAK;AAAA,MAC3C;AAAA,QACE,MAAM;AAAA,QACN,MAAM,OAAO,KAAK,MAAM,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,IACA,SAAS,OAAO,KAAK,WAAW,CAAC;AAAA,IACjC,MAAM,OAAO,KAAK,QAAQ,CAAC;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,YAAY,uBAAuB,OAAO,UAAU;AAAA,IACpD,WAAW,OAAO,aAAa,CAAC;AAAA,IAChC;AAAA,IACA,aAAa,OAAO,eAAe,SAAS;AAAA,IAC5C,KAAK,OAAO,OAAO,SAAS;AAAA,EAC9B;AACF;AAEO,SAAS,uBACd,SACA;AACA,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AACA,MAAI,YAAY,OAAO;AACrB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,QAAQ,SAAS;AAAA,IACxB,SAAS;AAAA,EACX;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-default-processing-plugins.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/create-default-processing-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"create-default-processing-plugins.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/create-default-processing-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAezD,wBAAgB,8BAA8B,CAC5C,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,gBAAgB,EAAE,CAgBpB"}
|
|
@@ -8,7 +8,9 @@ import { normalizePaths } from "./normalize-paths.js";
|
|
|
8
8
|
import { normalizeRequestBodies } from "./normalize-request-bodies.js";
|
|
9
9
|
import { normalizeResponses } from "./normalize-responses.js";
|
|
10
10
|
import { normalizeSchemas } from "./normalize-schemas.js";
|
|
11
|
+
import { normalizeSecurity } from "./normalize-security.js";
|
|
11
12
|
import { normalizeTags } from "./normalize-tags.js";
|
|
13
|
+
import { resolveSecuritySchemeUris } from "./resolve-security-scheme-uris.js";
|
|
12
14
|
function createDefaultProcessingPlugins(options = {}) {
|
|
13
15
|
return [
|
|
14
16
|
normalizePaths(),
|
|
@@ -16,6 +18,8 @@ function createDefaultProcessingPlugins(options = {}) {
|
|
|
16
18
|
normalizeTags(),
|
|
17
19
|
normalizeParameters(),
|
|
18
20
|
normalizeResponses(),
|
|
21
|
+
resolveSecuritySchemeUris(),
|
|
22
|
+
normalizeSecurity(),
|
|
19
23
|
normalizeRequestBodies(),
|
|
20
24
|
inferPagination(),
|
|
21
25
|
normalizeSchemas(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/processing-plugins/create-default-processing-plugins.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ProcessingPlugin } from '../processing.js';\nimport { canonicalizeSpec } from './canonicalize-spec.js';\nimport { extractInlineSchemas } from './extract-inline-schemas.js';\nimport { extractOverviewDocsPlugin } from './extract-overview-docs.js';\nimport { inferPagination } from './infer-pagination.js';\nimport { normalizeOperationIds } from './normalize-operation-ids.js';\nimport { normalizeParameters } from './normalize-parameters.js';\nimport { normalizePaths } from './normalize-paths.js';\nimport { normalizeRequestBodies } from './normalize-request-bodies.js';\nimport { normalizeResponses } from './normalize-responses.js';\nimport { normalizeSchemas } from './normalize-schemas.js';\nimport { normalizeTags } from './normalize-tags.js';\n\nexport function createDefaultProcessingPlugins(\n options: { verbose?: boolean } = {},\n): ProcessingPlugin[] {\n return [\n normalizePaths(),\n normalizeOperationIds(),\n normalizeTags(),\n normalizeParameters(),\n normalizeResponses(),\n normalizeRequestBodies(),\n inferPagination(),\n normalizeSchemas(),\n ...(options.verbose ? [extractInlineSchemas()] : []),\n extractOverviewDocsPlugin(),\n canonicalizeSpec(),\n ];\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,wBAAwB;AACjC,SAAS,4BAA4B;AACrC,SAAS,iCAAiC;AAC1C,SAAS,uBAAuB;AAChC,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AACpC,SAAS,sBAAsB;AAC/B,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,wBAAwB;AACjC,SAAS,qBAAqB;
|
|
4
|
+
"sourcesContent": ["import type { ProcessingPlugin } from '../processing.js';\nimport { canonicalizeSpec } from './canonicalize-spec.js';\nimport { extractInlineSchemas } from './extract-inline-schemas.js';\nimport { extractOverviewDocsPlugin } from './extract-overview-docs.js';\nimport { inferPagination } from './infer-pagination.js';\nimport { normalizeOperationIds } from './normalize-operation-ids.js';\nimport { normalizeParameters } from './normalize-parameters.js';\nimport { normalizePaths } from './normalize-paths.js';\nimport { normalizeRequestBodies } from './normalize-request-bodies.js';\nimport { normalizeResponses } from './normalize-responses.js';\nimport { normalizeSchemas } from './normalize-schemas.js';\nimport { normalizeSecurity } from './normalize-security.js';\nimport { normalizeTags } from './normalize-tags.js';\nimport { resolveSecuritySchemeUris } from './resolve-security-scheme-uris.js';\n\nexport function createDefaultProcessingPlugins(\n options: { verbose?: boolean } = {},\n): ProcessingPlugin[] {\n return [\n normalizePaths(),\n normalizeOperationIds(),\n normalizeTags(),\n normalizeParameters(),\n normalizeResponses(),\n resolveSecuritySchemeUris(),\n normalizeSecurity(),\n normalizeRequestBodies(),\n inferPagination(),\n normalizeSchemas(),\n ...(options.verbose ? [extractInlineSchemas()] : []),\n extractOverviewDocsPlugin(),\n canonicalizeSpec(),\n ];\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,wBAAwB;AACjC,SAAS,4BAA4B;AACrC,SAAS,iCAAiC;AAC1C,SAAS,uBAAuB;AAChC,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AACpC,SAAS,sBAAsB;AAC/B,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,iCAAiC;AAEnC,SAAS,+BACd,UAAiC,CAAC,GACd;AACpB,SAAO;AAAA,IACL,eAAe;AAAA,IACf,sBAAsB;AAAA,IACtB,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,mBAAmB;AAAA,IACnB,0BAA0B;AAAA,IAC1B,kBAAkB;AAAA,IAClB,uBAAuB;AAAA,IACvB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,GAAI,QAAQ,UAAU,CAAC,qBAAqB,CAAC,IAAI,CAAC;AAAA,IAClD,0BAA0B;AAAA,IAC1B,iBAAiB;AAAA,EACnB;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -9,6 +9,8 @@ export * from './normalize-parameters.js';
|
|
|
9
9
|
export * from './normalize-paths.js';
|
|
10
10
|
export * from './normalize-request-bodies.js';
|
|
11
11
|
export * from './normalize-responses.js';
|
|
12
|
+
export * from './normalize-security.js';
|
|
12
13
|
export * from './normalize-schemas.js';
|
|
13
14
|
export * from './normalize-tags.js';
|
|
15
|
+
export * from './resolve-security-scheme-uris.js';
|
|
14
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wCAAwC,CAAC;AACvD,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wCAAwC,CAAC;AACvD,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mCAAmC,CAAC"}
|
|
@@ -9,6 +9,8 @@ export * from "./normalize-parameters.js";
|
|
|
9
9
|
export * from "./normalize-paths.js";
|
|
10
10
|
export * from "./normalize-request-bodies.js";
|
|
11
11
|
export * from "./normalize-responses.js";
|
|
12
|
+
export * from "./normalize-security.js";
|
|
12
13
|
export * from "./normalize-schemas.js";
|
|
13
14
|
export * from "./normalize-tags.js";
|
|
15
|
+
export * from "./resolve-security-scheme-uris.js";
|
|
14
16
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/processing-plugins/index.ts"],
|
|
4
|
-
"sourcesContent": ["export * from './canonicalize-spec.js';\nexport * from './create-default-processing-plugins.js';\nexport * from './enrich-examples.js';\nexport * from './extract-inline-schemas.js';\nexport * from './extract-overview-docs.js';\nexport * from './infer-pagination.js';\nexport * from './normalize-operation-ids.js';\nexport * from './normalize-parameters.js';\nexport * from './normalize-paths.js';\nexport * from './normalize-request-bodies.js';\nexport * from './normalize-responses.js';\nexport * from './normalize-schemas.js';\nexport * from './normalize-tags.js';\n"],
|
|
5
|
-
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
4
|
+
"sourcesContent": ["export * from './canonicalize-spec.js';\nexport * from './create-default-processing-plugins.js';\nexport * from './enrich-examples.js';\nexport * from './extract-inline-schemas.js';\nexport * from './extract-overview-docs.js';\nexport * from './infer-pagination.js';\nexport * from './normalize-operation-ids.js';\nexport * from './normalize-parameters.js';\nexport * from './normalize-paths.js';\nexport * from './normalize-request-bodies.js';\nexport * from './normalize-responses.js';\nexport * from './normalize-security.js';\nexport * from './normalize-schemas.js';\nexport * from './normalize-tags.js';\nexport * from './resolve-security-scheme-uris.js';\n"],
|
|
5
|
+
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ParameterObject, SchemaObject
|
|
1
|
+
import type { ParameterObject, SchemaObject } from 'openapi3-ts/oas31';
|
|
2
2
|
import type { ProcessingPlugin } from '../processing.js';
|
|
3
3
|
import type { IR } from '../types.js';
|
|
4
|
-
export declare function patchParameters(spec: IR, schema: SchemaObject, parameters: ParameterObject[]
|
|
4
|
+
export declare function patchParameters(spec: IR, schema: SchemaObject, parameters: ParameterObject[]): void;
|
|
5
5
|
export declare function normalizeRequestBodies(): ProcessingPlugin;
|
|
6
6
|
//# sourceMappingURL=normalize-request-bodies.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-request-bodies.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/normalize-request-bodies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAEf,YAAY,
|
|
1
|
+
{"version":3,"file":"normalize-request-bodies.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/normalize-request-bodies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAEf,YAAY,EACb,MAAM,mBAAmB,CAAC;AAO3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EACV,EAAE,EAGH,MAAM,aAAa,CAAC;AAErB,wBAAgB,eAAe,CAC7B,IAAI,EAAE,EAAE,EACR,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,eAAe,EAAE,QAkB9B;AA8ED,wBAAgB,sBAAsB,IAAI,gBAAgB,CAsCzD"}
|
|
@@ -2,13 +2,7 @@ import { followRef, isRef, resolveRef } from "@sdk-it/core/ref.js";
|
|
|
2
2
|
import { isEmpty } from "@sdk-it/core/utils.js";
|
|
3
3
|
import { findUniqueSchemaName } from "../find-unique-schema-name.js";
|
|
4
4
|
import { iterateOperations } from "../for-each-operation.js";
|
|
5
|
-
|
|
6
|
-
function patchParameters(spec, schema, parameters, security) {
|
|
7
|
-
const securityOptions = securityToOptions(
|
|
8
|
-
spec,
|
|
9
|
-
security,
|
|
10
|
-
spec.components.securitySchemes
|
|
11
|
-
);
|
|
5
|
+
function patchParameters(spec, schema, parameters) {
|
|
12
6
|
const required = new Set(
|
|
13
7
|
Array.isArray(schema.required) ? schema.required : []
|
|
14
8
|
);
|
|
@@ -22,16 +16,9 @@ function patchParameters(spec, schema, parameters, security) {
|
|
|
22
16
|
...isRef(param.schema) ? followRef(spec, param.schema.$ref) : param.schema ?? { type: "string" }
|
|
23
17
|
};
|
|
24
18
|
}
|
|
25
|
-
for (const param of securityOptions) {
|
|
26
|
-
required.delete(param.name);
|
|
27
|
-
schema["x-properties"][param.name] = {
|
|
28
|
-
"x-in": "header",
|
|
29
|
-
...isRef(param.schema) ? followRef(spec, param.schema.$ref) : param.schema ?? { type: "string" }
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
19
|
schema["x-required"] = [...required];
|
|
33
20
|
}
|
|
34
|
-
function normalizeRequestBody(spec, operationId, operation, parameters
|
|
21
|
+
function normalizeRequestBody(spec, operationId, operation, parameters) {
|
|
35
22
|
const requestBodySource = isRef(operation.requestBody) ? followRef(spec, operation.requestBody.$ref) : operation.requestBody ?? {
|
|
36
23
|
content: {},
|
|
37
24
|
required: false
|
|
@@ -47,7 +34,7 @@ function normalizeRequestBody(spec, operationId, operation, parameters, security
|
|
|
47
34
|
"x-inputname": inputName,
|
|
48
35
|
"x-requestbody": true
|
|
49
36
|
};
|
|
50
|
-
patchParameters(spec, schema, parameters
|
|
37
|
+
patchParameters(spec, schema, parameters);
|
|
51
38
|
const normalized = {
|
|
52
39
|
...requestBody,
|
|
53
40
|
content: {
|
|
@@ -83,7 +70,7 @@ function normalizeRequestBody(spec, operationId, operation, parameters, security
|
|
|
83
70
|
schema = structuredClone(mediaType.schema);
|
|
84
71
|
break;
|
|
85
72
|
}
|
|
86
|
-
patchParameters(spec, schema, parameters
|
|
73
|
+
patchParameters(spec, schema, parameters);
|
|
87
74
|
spec.components.schemas[inputName] = {
|
|
88
75
|
...schema,
|
|
89
76
|
"x-requestbody": true,
|
|
@@ -114,8 +101,7 @@ function normalizeRequestBodies() {
|
|
|
114
101
|
patchParameters(
|
|
115
102
|
spec,
|
|
116
103
|
schema,
|
|
117
|
-
tunedOperation.parameters
|
|
118
|
-
operation.security ?? []
|
|
104
|
+
tunedOperation.parameters
|
|
119
105
|
);
|
|
120
106
|
}
|
|
121
107
|
continue;
|
|
@@ -125,8 +111,7 @@ function normalizeRequestBodies() {
|
|
|
125
111
|
spec,
|
|
126
112
|
tunedOperation.operationId,
|
|
127
113
|
operation,
|
|
128
|
-
tunedOperation.parameters
|
|
129
|
-
operation.security ?? []
|
|
114
|
+
tunedOperation.parameters
|
|
130
115
|
);
|
|
131
116
|
}
|
|
132
117
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/processing-plugins/normalize-request-bodies.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n OperationObject,\n ParameterObject,\n RequestBodyObject,\n SchemaObject,\n
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import type {\n OperationObject,\n ParameterObject,\n RequestBodyObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { followRef, isRef, resolveRef } from '@sdk-it/core/ref.js';\nimport { isEmpty } from '@sdk-it/core/utils.js';\n\nimport { findUniqueSchemaName } from '../find-unique-schema-name.js';\nimport { iterateOperations } from '../for-each-operation.js';\nimport type { ProcessingPlugin } from '../processing.js';\nimport type {\n IR,\n OurRequestBodyObject,\n TunedOperationObject,\n} from '../types.js';\n\nexport function patchParameters(\n spec: IR,\n schema: SchemaObject,\n parameters: ParameterObject[],\n) {\n const required = new Set(\n Array.isArray(schema.required) ? schema.required : [],\n );\n schema['x-properties'] ??= {};\n for (const param of parameters) {\n if (param.required) {\n required.add(param.name);\n }\n schema['x-properties'][param.name] = {\n 'x-in': param.in,\n ...(isRef(param.schema)\n ? followRef<SchemaObject>(spec, param.schema.$ref)\n : (param.schema ?? { type: 'string' })),\n };\n }\n schema['x-required'] = [...required];\n}\n\nfunction normalizeRequestBody(\n spec: IR,\n operationId: string,\n operation: OperationObject,\n parameters: ParameterObject[],\n): OurRequestBodyObject {\n const requestBodySource = isRef(operation.requestBody)\n ? followRef<RequestBodyObject>(spec, operation.requestBody.$ref)\n : (operation.requestBody ?? {\n content: {},\n required: false,\n });\n const requestBody = structuredClone(requestBodySource);\n if (isEmpty(requestBody.content)) {\n const inputName = findUniqueSchemaName(spec, operationId, [\n 'input',\n 'payload',\n 'request',\n ]);\n const schema: SchemaObject = {\n 'x-inputname': inputName,\n 'x-requestbody': true,\n };\n patchParameters(spec, schema, parameters);\n const normalized: OurRequestBodyObject = {\n ...requestBody,\n content: {\n 'application/empty': {\n schema: { $ref: `#/components/schemas/${inputName}` },\n },\n },\n };\n\n spec.components.schemas[inputName] = schema;\n return normalized;\n }\n for (const contentType in requestBody.content) {\n const mediaType = requestBody.content[contentType];\n const inputName = findUniqueSchemaName(spec, operationId, [\n 'input',\n 'payload',\n 'request',\n ]);\n let schema: SchemaObject | undefined;\n\n switch (true) {\n case isRef(mediaType.schema):\n schema = structuredClone(\n followRef<SchemaObject>(spec, mediaType.schema.$ref),\n );\n break;\n case isEmpty(mediaType.schema):\n schema ??= {};\n console.warn(\n `Request body schema for content type \"${contentType}\" is empty.`,\n );\n break;\n default:\n schema = structuredClone(mediaType.schema);\n break;\n }\n\n patchParameters(spec, schema, parameters);\n spec.components.schemas[inputName] = {\n ...schema,\n 'x-requestbody': true,\n 'x-inputname': inputName,\n };\n\n requestBody.content[contentType].schema = {\n $ref: `#/components/schemas/${inputName}`,\n };\n }\n return requestBody as OurRequestBodyObject;\n}\n\nexport function normalizeRequestBodies(): ProcessingPlugin {\n return {\n name: 'normalize-request-bodies',\n process({ spec }) {\n for (const { operation } of iterateOperations(spec)) {\n const tunedOperation = operation as TunedOperationObject;\n if (operation.requestBody) {\n const requestBody = resolveRef<RequestBodyObject>(\n spec,\n operation.requestBody,\n );\n const schemas = Object.values(requestBody.content).map(\n ({ schema }) =>\n schema ? resolveRef<SchemaObject>(spec, schema) : undefined,\n );\n if (\n schemas.length > 0 &&\n schemas.every((schema) => schema?.['x-requestbody'])\n ) {\n for (const schema of new Set(schemas)) {\n patchParameters(\n spec,\n schema as SchemaObject,\n tunedOperation.parameters,\n );\n }\n continue;\n }\n }\n tunedOperation.requestBody = normalizeRequestBody(\n spec,\n tunedOperation.operationId,\n operation,\n tunedOperation.parameters,\n );\n }\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-security.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/normalize-security.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,wBAAgB,iBAAiB,IAAI,gBAAgB,CAuEpD"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { iterateOperations } from "../for-each-operation.js";
|
|
2
|
+
function normalizeSecurity() {
|
|
3
|
+
return {
|
|
4
|
+
name: "normalize-security",
|
|
5
|
+
process({ spec, report }) {
|
|
6
|
+
for (const [name, scheme] of Object.entries(
|
|
7
|
+
spec.components.securitySchemes
|
|
8
|
+
)) {
|
|
9
|
+
const message = invalidSecurityScheme(scheme);
|
|
10
|
+
if (message) {
|
|
11
|
+
report({
|
|
12
|
+
code: "invalid-security-scheme",
|
|
13
|
+
severity: "error",
|
|
14
|
+
path: `components.securitySchemes.${name}`,
|
|
15
|
+
message
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
for (const { entry, operation } of iterateOperations(spec)) {
|
|
20
|
+
operation.security = structuredClone(
|
|
21
|
+
operation.security ?? spec.security ?? []
|
|
22
|
+
);
|
|
23
|
+
const path = `${entry.method.toUpperCase()} ${entry.path}`;
|
|
24
|
+
for (const requirement of operation.security) {
|
|
25
|
+
const targets = /* @__PURE__ */ new Map();
|
|
26
|
+
for (const [name, values] of Object.entries(requirement)) {
|
|
27
|
+
const scheme = spec.components.securitySchemes[name];
|
|
28
|
+
if (!scheme) {
|
|
29
|
+
report({
|
|
30
|
+
code: "unresolved-security-scheme",
|
|
31
|
+
severity: "error",
|
|
32
|
+
path,
|
|
33
|
+
message: `Security scheme ${name} must be resolved in components.securitySchemes`
|
|
34
|
+
});
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (scheme.type === "oauth2") {
|
|
38
|
+
const availableScopes = new Set(
|
|
39
|
+
Object.values(scheme.flows ?? {}).flatMap(
|
|
40
|
+
(flow) => Object.keys(flow?.scopes ?? {})
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
for (const scope of values) {
|
|
44
|
+
if (!availableScopes.has(scope)) {
|
|
45
|
+
report({
|
|
46
|
+
code: "unknown-oauth-scope",
|
|
47
|
+
severity: "error",
|
|
48
|
+
path,
|
|
49
|
+
message: `OAuth2 scheme ${name} does not declare scope ${scope}`
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const target = credentialTarget(scheme);
|
|
55
|
+
const existing = target ? targets.get(target) : void 0;
|
|
56
|
+
if (target && existing) {
|
|
57
|
+
report({
|
|
58
|
+
code: "conflicting-security-target",
|
|
59
|
+
severity: "error",
|
|
60
|
+
path,
|
|
61
|
+
message: `Security schemes ${existing} and ${name} both use ${target}`
|
|
62
|
+
});
|
|
63
|
+
} else if (target) {
|
|
64
|
+
targets.set(target, name);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function invalidSecurityScheme(scheme) {
|
|
73
|
+
const value = scheme;
|
|
74
|
+
switch (value.type) {
|
|
75
|
+
case "apiKey":
|
|
76
|
+
if (typeof value.name !== "string" || value.name.length === 0) {
|
|
77
|
+
return "apiKey security schemes require a name";
|
|
78
|
+
}
|
|
79
|
+
if (!["header", "query", "cookie"].includes(value.in)) {
|
|
80
|
+
return "apiKey security schemes require header, query, or cookie in";
|
|
81
|
+
}
|
|
82
|
+
return void 0;
|
|
83
|
+
case "http":
|
|
84
|
+
return typeof value.scheme === "string" && value.scheme.length > 0 ? void 0 : "HTTP security schemes require a scheme";
|
|
85
|
+
case "mutualTLS":
|
|
86
|
+
return void 0;
|
|
87
|
+
case "openIdConnect":
|
|
88
|
+
return typeof value.openIdConnectUrl === "string" && value.openIdConnectUrl.length > 0 ? void 0 : "OpenID Connect security schemes require openIdConnectUrl";
|
|
89
|
+
case "oauth2": {
|
|
90
|
+
if (!value.flows || typeof value.flows !== "object") {
|
|
91
|
+
return "OAuth2 security schemes require flows";
|
|
92
|
+
}
|
|
93
|
+
const flows = value.flows;
|
|
94
|
+
const requiredUrls = {
|
|
95
|
+
implicit: ["authorizationUrl"],
|
|
96
|
+
password: ["tokenUrl"],
|
|
97
|
+
clientCredentials: ["tokenUrl"],
|
|
98
|
+
authorizationCode: ["authorizationUrl", "tokenUrl"],
|
|
99
|
+
deviceAuthorization: ["deviceAuthorizationUrl", "tokenUrl"]
|
|
100
|
+
};
|
|
101
|
+
const configured = Object.entries(requiredUrls).filter(
|
|
102
|
+
([flow]) => flows[flow] !== void 0
|
|
103
|
+
);
|
|
104
|
+
if (configured.length === 0) {
|
|
105
|
+
return "OAuth2 security schemes require at least one flow";
|
|
106
|
+
}
|
|
107
|
+
for (const [flowName, fields] of configured) {
|
|
108
|
+
const flow = flows[flowName];
|
|
109
|
+
if (!flow.scopes || typeof flow.scopes !== "object") {
|
|
110
|
+
return `OAuth2 ${flowName} flow requires scopes`;
|
|
111
|
+
}
|
|
112
|
+
for (const field of fields) {
|
|
113
|
+
if (typeof flow[field] !== "string" || flow[field].length === 0) {
|
|
114
|
+
return `OAuth2 ${flowName} flow requires ${field}`;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
default:
|
|
121
|
+
return `Unsupported security scheme type ${String(value.type)}`;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function credentialTarget(scheme) {
|
|
125
|
+
switch (scheme.type) {
|
|
126
|
+
case "apiKey": {
|
|
127
|
+
if (!scheme.in || !scheme.name) return void 0;
|
|
128
|
+
const name = scheme.in === "header" ? scheme.name.toLowerCase() : scheme.name;
|
|
129
|
+
return `${scheme.in}:${name}`;
|
|
130
|
+
}
|
|
131
|
+
case "http":
|
|
132
|
+
case "oauth2":
|
|
133
|
+
case "openIdConnect":
|
|
134
|
+
return "header:authorization";
|
|
135
|
+
case "mutualTLS":
|
|
136
|
+
return "transport:client-certificate";
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export {
|
|
140
|
+
normalizeSecurity
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=normalize-security.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/processing-plugins/normalize-security.ts"],
|
|
4
|
+
"sourcesContent": ["import type { OpenAPISecuritySchemeObject } from '@sdk-it/core';\n\nimport { iterateOperations } from '../for-each-operation.js';\nimport type { ProcessingPlugin } from '../processing.js';\n\nexport function normalizeSecurity(): ProcessingPlugin {\n return {\n name: 'normalize-security',\n process({ spec, report }) {\n for (const [name, scheme] of Object.entries(\n spec.components.securitySchemes,\n )) {\n const message = invalidSecurityScheme(scheme);\n if (message) {\n report({\n code: 'invalid-security-scheme',\n severity: 'error',\n path: `components.securitySchemes.${name}`,\n message,\n });\n }\n }\n for (const { entry, operation } of iterateOperations(spec)) {\n operation.security = structuredClone(\n operation.security ?? spec.security ?? [],\n );\n const path = `${entry.method.toUpperCase()} ${entry.path}`;\n for (const requirement of operation.security) {\n const targets = new Map<string, string>();\n for (const [name, values] of Object.entries(requirement)) {\n const scheme = spec.components.securitySchemes[name];\n if (!scheme) {\n // OpenAPI 3.2 allows external URI references here, but no\n // generator can emit a credential for one.\n report({\n code: 'unresolved-security-scheme',\n severity: 'error',\n path,\n message: `Security scheme ${name} must be resolved in components.securitySchemes`,\n });\n continue;\n }\n if (scheme.type === 'oauth2') {\n const availableScopes = new Set(\n Object.values(scheme.flows ?? {}).flatMap((flow) =>\n Object.keys(flow?.scopes ?? {}),\n ),\n );\n for (const scope of values) {\n if (!availableScopes.has(scope)) {\n report({\n code: 'unknown-oauth-scope',\n severity: 'error',\n path,\n message: `OAuth2 scheme ${name} does not declare scope ${scope}`,\n });\n }\n }\n }\n const target = credentialTarget(scheme);\n const existing = target ? targets.get(target) : undefined;\n if (target && existing) {\n report({\n code: 'conflicting-security-target',\n severity: 'error',\n path,\n message: `Security schemes ${existing} and ${name} both use ${target}`,\n });\n } else if (target) {\n targets.set(target, name);\n }\n }\n }\n }\n },\n };\n}\n\nfunction invalidSecurityScheme(\n scheme: OpenAPISecuritySchemeObject,\n): string | undefined {\n const value = scheme as OpenAPISecuritySchemeObject & Record<string, unknown>;\n switch (value.type as string) {\n case 'apiKey':\n if (typeof value.name !== 'string' || value.name.length === 0) {\n return 'apiKey security schemes require a name';\n }\n if (!['header', 'query', 'cookie'].includes(value.in as string)) {\n return 'apiKey security schemes require header, query, or cookie in';\n }\n return undefined;\n case 'http':\n return typeof value.scheme === 'string' && value.scheme.length > 0\n ? undefined\n : 'HTTP security schemes require a scheme';\n case 'mutualTLS':\n return undefined;\n case 'openIdConnect':\n return typeof value.openIdConnectUrl === 'string' &&\n value.openIdConnectUrl.length > 0\n ? undefined\n : 'OpenID Connect security schemes require openIdConnectUrl';\n case 'oauth2': {\n if (!value.flows || typeof value.flows !== 'object') {\n return 'OAuth2 security schemes require flows';\n }\n const flows = value.flows as Record<\n string,\n Record<string, unknown> | undefined\n >;\n const requiredUrls: Record<string, string[]> = {\n implicit: ['authorizationUrl'],\n password: ['tokenUrl'],\n clientCredentials: ['tokenUrl'],\n authorizationCode: ['authorizationUrl', 'tokenUrl'],\n deviceAuthorization: ['deviceAuthorizationUrl', 'tokenUrl'],\n };\n const configured = Object.entries(requiredUrls).filter(\n ([flow]) => flows[flow] !== undefined,\n );\n if (configured.length === 0) {\n return 'OAuth2 security schemes require at least one flow';\n }\n for (const [flowName, fields] of configured) {\n const flow = flows[flowName]!;\n if (!flow.scopes || typeof flow.scopes !== 'object') {\n return `OAuth2 ${flowName} flow requires scopes`;\n }\n for (const field of fields) {\n if (typeof flow[field] !== 'string' || flow[field].length === 0) {\n return `OAuth2 ${flowName} flow requires ${field}`;\n }\n }\n }\n return undefined;\n }\n default:\n return `Unsupported security scheme type ${String(value.type)}`;\n }\n}\n\nfunction credentialTarget(\n scheme: OpenAPISecuritySchemeObject,\n): string | undefined {\n switch (scheme.type) {\n case 'apiKey': {\n if (!scheme.in || !scheme.name) return undefined;\n const name =\n scheme.in === 'header' ? scheme.name.toLowerCase() : scheme.name;\n return `${scheme.in}:${name}`;\n }\n case 'http':\n case 'oauth2':\n case 'openIdConnect':\n return 'header:authorization';\n case 'mutualTLS':\n return 'transport:client-certificate';\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ProcessingPlugin } from '../processing.js';
|
|
2
|
+
/**
|
|
3
|
+
* OpenAPI 3.2 lets a security requirement key be a URI of a Security Scheme
|
|
4
|
+
* Object instead of a `components.securitySchemes` name. Generators key
|
|
5
|
+
* credentials by scheme name, so each URI is fetched, registered locally, and
|
|
6
|
+
* the requirement rewritten to point at the registered name.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveSecuritySchemeUris(): ProcessingPlugin;
|
|
9
|
+
//# sourceMappingURL=resolve-security-scheme-uris.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-security-scheme-uris.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/resolve-security-scheme-uris.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,gBAAgB,CAkD5D"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import {
|
|
3
|
+
followRef,
|
|
4
|
+
isRef
|
|
5
|
+
} from "@sdk-it/core";
|
|
6
|
+
import { iterateOperations } from "../for-each-operation.js";
|
|
7
|
+
import { loadFile } from "../loaders/load-spec.js";
|
|
8
|
+
function resolveSecuritySchemeUris() {
|
|
9
|
+
return {
|
|
10
|
+
name: "resolve-security-scheme-uris",
|
|
11
|
+
async process({ spec, report }) {
|
|
12
|
+
const requirements = collectRequirements(spec);
|
|
13
|
+
const uris = new Set(
|
|
14
|
+
requirements.flatMap((requirement) => Object.keys(requirement)).filter(
|
|
15
|
+
(key) => !spec.components.securitySchemes[key] && isUriKey(key)
|
|
16
|
+
)
|
|
17
|
+
);
|
|
18
|
+
if (!uris.size) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const documents = /* @__PURE__ */ new Map();
|
|
22
|
+
const registered = /* @__PURE__ */ new Map();
|
|
23
|
+
for (const uri of uris) {
|
|
24
|
+
try {
|
|
25
|
+
const scheme = await resolveScheme(uri, spec, documents);
|
|
26
|
+
const [alias] = Object.entries(spec.components.securitySchemes).find(
|
|
27
|
+
([, registeredScheme]) => registeredScheme === scheme
|
|
28
|
+
) ?? [];
|
|
29
|
+
const name = alias ?? availableName(spec, schemeName(uri));
|
|
30
|
+
spec.components.securitySchemes[name] = scheme;
|
|
31
|
+
registered.set(uri, name);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
report({
|
|
34
|
+
code: "unresolvable-security-scheme-uri",
|
|
35
|
+
severity: "error",
|
|
36
|
+
path: uri,
|
|
37
|
+
message: `Could not resolve security scheme URI ${uri}: ${error instanceof Error ? error.message : String(error)}`
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
for (const requirement of requirements) {
|
|
42
|
+
for (const [uri, name] of registered) {
|
|
43
|
+
if (Object.hasOwn(requirement, uri)) {
|
|
44
|
+
requirement[name] = requirement[uri];
|
|
45
|
+
delete requirement[uri];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function collectRequirements(spec) {
|
|
53
|
+
const requirements = [...spec.security ?? []];
|
|
54
|
+
for (const { operation } of iterateOperations(spec)) {
|
|
55
|
+
requirements.push(...operation.security ?? []);
|
|
56
|
+
}
|
|
57
|
+
return requirements;
|
|
58
|
+
}
|
|
59
|
+
function isUriKey(key) {
|
|
60
|
+
return !/^[a-zA-Z0-9._-]+$/.test(key);
|
|
61
|
+
}
|
|
62
|
+
async function resolveScheme(uri, spec, documents) {
|
|
63
|
+
const [location, fragment] = splitFragment(uri);
|
|
64
|
+
const document = location ? await loadDocument(location, spec, documents) : spec;
|
|
65
|
+
let scheme = fragment ? readPointer(document, fragment) : document;
|
|
66
|
+
if (isRef(scheme)) {
|
|
67
|
+
scheme = followRef(document, scheme.$ref);
|
|
68
|
+
}
|
|
69
|
+
if (scheme === null || typeof scheme !== "object" || typeof scheme.type !== "string") {
|
|
70
|
+
return Promise.reject(
|
|
71
|
+
new Error("the target is not a Security Scheme Object")
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return scheme;
|
|
75
|
+
}
|
|
76
|
+
function loadDocument(location, spec, documents) {
|
|
77
|
+
const base = spec.$self;
|
|
78
|
+
if (!base && !isAbsolute(location)) {
|
|
79
|
+
return Promise.reject(
|
|
80
|
+
new Error(
|
|
81
|
+
"the document declares no $self, so a relative URI has no base to resolve against"
|
|
82
|
+
)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
const url = new URL(location, base);
|
|
86
|
+
if (url.href === base) {
|
|
87
|
+
return Promise.resolve(spec);
|
|
88
|
+
}
|
|
89
|
+
let pending = documents.get(url.href);
|
|
90
|
+
if (!pending) {
|
|
91
|
+
pending = loadFile(
|
|
92
|
+
url.protocol === "file:" ? fileURLToPath(url) : url.href
|
|
93
|
+
);
|
|
94
|
+
documents.set(url.href, pending);
|
|
95
|
+
}
|
|
96
|
+
return pending;
|
|
97
|
+
}
|
|
98
|
+
function isAbsolute(location) {
|
|
99
|
+
return URL.canParse(location);
|
|
100
|
+
}
|
|
101
|
+
function splitFragment(uri) {
|
|
102
|
+
const index = uri.indexOf("#");
|
|
103
|
+
return index === -1 ? [uri, void 0] : [uri.slice(0, index), uri.slice(index + 1)];
|
|
104
|
+
}
|
|
105
|
+
function readPointer(document, fragment) {
|
|
106
|
+
let current = document;
|
|
107
|
+
for (const segment of fragment.split("/")) {
|
|
108
|
+
if (!segment) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const key = decodeURIComponent(segment).replaceAll("~1", "/").replaceAll("~0", "~");
|
|
112
|
+
if (current === null || typeof current !== "object" || !(key in current)) {
|
|
113
|
+
throw new Error(`no value at pointer #${fragment}`);
|
|
114
|
+
}
|
|
115
|
+
current = current[key];
|
|
116
|
+
}
|
|
117
|
+
return current;
|
|
118
|
+
}
|
|
119
|
+
function schemeName(uri) {
|
|
120
|
+
const [location, fragment] = splitFragment(uri);
|
|
121
|
+
const candidate = lastSegment(fragment ?? "") ?? lastSegment(location.split("?")[0])?.replace(/\.(json|ya?ml)$/i, "");
|
|
122
|
+
const sanitized = (candidate ?? "").replace(/[^a-zA-Z0-9._-]/g, "");
|
|
123
|
+
return sanitized || "externalSecurityScheme";
|
|
124
|
+
}
|
|
125
|
+
function lastSegment(value) {
|
|
126
|
+
return value.split("/").filter(Boolean).at(-1);
|
|
127
|
+
}
|
|
128
|
+
function availableName(spec, candidate) {
|
|
129
|
+
let name = candidate;
|
|
130
|
+
let suffix = 2;
|
|
131
|
+
while (spec.components.securitySchemes[name]) {
|
|
132
|
+
name = `${candidate}${suffix++}`;
|
|
133
|
+
}
|
|
134
|
+
return name;
|
|
135
|
+
}
|
|
136
|
+
export {
|
|
137
|
+
resolveSecuritySchemeUris
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=resolve-security-scheme-uris.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/processing-plugins/resolve-security-scheme-uris.ts"],
|
|
4
|
+
"sourcesContent": ["import { fileURLToPath } from 'node:url';\nimport type { SecurityRequirementObject } from 'openapi3-ts/oas31';\n\nimport {\n type OpenAPISecuritySchemeObject,\n followRef,\n isRef,\n} from '@sdk-it/core';\n\nimport { iterateOperations } from '../for-each-operation.js';\nimport { loadFile } from '../loaders/load-spec.js';\nimport type { ProcessingPlugin } from '../processing.js';\nimport type { IR } from '../types.js';\n\n/**\n * OpenAPI 3.2 lets a security requirement key be a URI of a Security Scheme\n * Object instead of a `components.securitySchemes` name. Generators key\n * credentials by scheme name, so each URI is fetched, registered locally, and\n * the requirement rewritten to point at the registered name.\n */\nexport function resolveSecuritySchemeUris(): ProcessingPlugin {\n return {\n name: 'resolve-security-scheme-uris',\n async process({ spec, report }) {\n const requirements = collectRequirements(spec);\n const uris = new Set(\n requirements\n .flatMap((requirement) => Object.keys(requirement))\n .filter(\n (key) => !spec.components.securitySchemes[key] && isUriKey(key),\n ),\n );\n if (!uris.size) {\n return;\n }\n\n const documents = new Map<string, Promise<unknown>>();\n const registered = new Map<string, string>();\n for (const uri of uris) {\n try {\n const scheme = await resolveScheme(uri, spec, documents);\n // A same-document pointer lands on an already registered object;\n // reuse its name instead of registering a second copy.\n const [alias] =\n Object.entries(spec.components.securitySchemes).find(\n ([, registeredScheme]) => registeredScheme === scheme,\n ) ?? [];\n const name = alias ?? availableName(spec, schemeName(uri));\n spec.components.securitySchemes[name] = scheme;\n registered.set(uri, name);\n } catch (error) {\n report({\n code: 'unresolvable-security-scheme-uri',\n severity: 'error',\n path: uri,\n message: `Could not resolve security scheme URI ${uri}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n for (const requirement of requirements) {\n for (const [uri, name] of registered) {\n if (Object.hasOwn(requirement, uri)) {\n requirement[name] = requirement[uri];\n delete requirement[uri];\n }\n }\n }\n },\n };\n}\n\nfunction collectRequirements(spec: IR) {\n const requirements: SecurityRequirementObject[] = [...(spec.security ?? [])];\n for (const { operation } of iterateOperations(spec)) {\n requirements.push(...(operation.security ?? []));\n }\n return requirements;\n}\n\n/**\n * Component keys are limited to `^[a-zA-Z0-9._-]+$`, so anything else can only\n * be a URI. A bare `auth.yaml` stays a name \u2014 treating it as a document would\n * turn a typo into a file read.\n */\nfunction isUriKey(key: string) {\n return !/^[a-zA-Z0-9._-]+$/.test(key);\n}\n\nasync function resolveScheme(\n uri: string,\n spec: IR,\n documents: Map<string, Promise<unknown>>,\n): Promise<OpenAPISecuritySchemeObject> {\n const [location, fragment] = splitFragment(uri);\n const document = location\n ? await loadDocument(location, spec, documents)\n : spec;\n let scheme = fragment ? readPointer(document, fragment) : document;\n if (isRef(scheme)) {\n scheme = followRef(document as never, scheme.$ref);\n }\n if (\n scheme === null ||\n typeof scheme !== 'object' ||\n typeof (scheme as { type?: unknown }).type !== 'string'\n ) {\n return Promise.reject(\n new Error('the target is not a Security Scheme Object'),\n );\n }\n return scheme as OpenAPISecuritySchemeObject;\n}\n\nfunction loadDocument(\n location: string,\n spec: IR,\n documents: Map<string, Promise<unknown>>,\n) {\n const base = spec.$self;\n if (!base && !isAbsolute(location)) {\n return Promise.reject(\n new Error(\n 'the document declares no $self, so a relative URI has no base to resolve against',\n ),\n );\n }\n const url = new URL(location, base);\n if (url.href === base) {\n return Promise.resolve(spec);\n }\n let pending = documents.get(url.href);\n if (!pending) {\n pending = loadFile(\n url.protocol === 'file:' ? fileURLToPath(url) : url.href,\n );\n documents.set(url.href, pending);\n }\n return pending;\n}\n\nfunction isAbsolute(location: string) {\n return URL.canParse(location);\n}\n\nfunction splitFragment(uri: string): [string, string | undefined] {\n const index = uri.indexOf('#');\n return index === -1\n ? [uri, undefined]\n : [uri.slice(0, index), uri.slice(index + 1)];\n}\n\nfunction readPointer(document: unknown, fragment: string) {\n let current: unknown = document;\n for (const segment of fragment.split('/')) {\n if (!segment) {\n continue;\n }\n const key = decodeURIComponent(segment)\n .replaceAll('~1', '/')\n .replaceAll('~0', '~');\n if (\n current === null ||\n typeof current !== 'object' ||\n !(key in (current as object))\n ) {\n throw new Error(`no value at pointer #${fragment}`);\n }\n current = (current as Record<string, unknown>)[key];\n }\n return current;\n}\n\nfunction schemeName(uri: string) {\n const [location, fragment] = splitFragment(uri);\n const candidate =\n lastSegment(fragment ?? '') ??\n lastSegment(location.split('?')[0])?.replace(/\\.(json|ya?ml)$/i, '');\n const sanitized = (candidate ?? '').replace(/[^a-zA-Z0-9._-]/g, '');\n return sanitized || 'externalSecurityScheme';\n}\n\nfunction lastSegment(value: string) {\n return value.split('/').filter(Boolean).at(-1);\n}\n\nfunction availableName(spec: IR, candidate: string) {\n let name = candidate;\n let suffix = 2;\n while (spec.components.securitySchemes[name]) {\n name = `${candidate}${suffix++}`;\n }\n return name;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/processing.ts"],
|
|
4
|
-
"sourcesContent": ["import type {
|
|
4
|
+
"sourcesContent": ["import type { OpenAPIDocument } from '@sdk-it/core';\n\nimport {\n type GenerateSdkConfig,\n coeraceConfig as coerceConfig,\n} from './options.js';\nimport type { IR } from './types.js';\n\nexport type ProcessingDiagnosticSeverity = 'info' | 'warning' | 'error';\n\nexport interface ProcessingDiagnostic {\n plugin: string;\n severity: ProcessingDiagnosticSeverity;\n code: string;\n message: string;\n path?: string;\n}\n\nexport type ProcessingOptions = Omit<ReturnType<typeof coerceConfig>, 'spec'>;\n\nexport interface ProcessingContext {\n spec: IR;\n options: ProcessingOptions;\n diagnostics: ProcessingDiagnostic[];\n signal?: AbortSignal;\n report(\n diagnostic: Omit<ProcessingDiagnostic, 'plugin'>,\n ): ProcessingDiagnostic;\n}\n\nexport interface ProcessingPlugin {\n name: string;\n process(context: ProcessingContext): void | Promise<void>;\n}\n\nexport interface ProcessSpecConfig extends GenerateSdkConfig {\n plugins: readonly ProcessingPlugin[];\n signal?: AbortSignal;\n onDiagnostic?: (diagnostic: ProcessingDiagnostic) => void;\n}\n\nexport interface ProcessingResult {\n spec: IR;\n diagnostics: ProcessingDiagnostic[];\n}\n\nexport async function processSpec(\n config: ProcessSpecConfig,\n): Promise<ProcessingResult> {\n const { plugins, signal, onDiagnostic, ...generateConfig } = config;\n signal?.throwIfAborted();\n const coerced = coerceConfig({\n ...generateConfig,\n spec: structuredClone(generateConfig.spec) as OpenAPIDocument,\n });\n const { spec, ...options } = coerced;\n const diagnostics: ProcessingDiagnostic[] = [];\n const pluginNames = plugins.map((plugin) => plugin.name);\n const configuration = JSON.stringify({\n pagination: options.pagination,\n responses: options.responses,\n });\n\n for (const plugin of plugins) {\n signal?.throwIfAborted();\n const context: ProcessingContext = {\n spec,\n options,\n diagnostics,\n signal,\n report(diagnostic) {\n const reported = { ...diagnostic, plugin: plugin.name };\n diagnostics.push(reported);\n onDiagnostic?.(reported);\n return reported;\n },\n };\n await plugin.process(context);\n signal?.throwIfAborted();\n }\n\n spec['x-sdk-processing'] = { plugins: pluginNames, configuration };\n\n return { spec, diagnostics };\n}\n"],
|
|
5
5
|
"mappings": "AAEA;AAAA,EAEE,iBAAiB;AAAA,OACZ;AAyCP,eAAsB,YACpB,QAC2B;AAC3B,QAAM,EAAE,SAAS,QAAQ,cAAc,GAAG,eAAe,IAAI;AAC7D,UAAQ,eAAe;AACvB,QAAM,UAAU,aAAa;AAAA,IAC3B,GAAG;AAAA,IACH,MAAM,gBAAgB,eAAe,IAAI;AAAA,EAC3C,CAAC;AACD,QAAM,EAAE,MAAM,GAAG,QAAQ,IAAI;AAC7B,QAAM,cAAsC,CAAC;AAC7C,QAAM,cAAc,QAAQ,IAAI,CAAC,WAAW,OAAO,IAAI;AACvD,QAAM,gBAAgB,KAAK,UAAU;AAAA,IACnC,YAAY,QAAQ;AAAA,IACpB,WAAW,QAAQ;AAAA,EACrB,CAAC;AAED,aAAW,UAAU,SAAS;AAC5B,YAAQ,eAAe;AACvB,UAAM,UAA6B;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,YAAY;AACjB,cAAM,WAAW,EAAE,GAAG,YAAY,QAAQ,OAAO,KAAK;AACtD,oBAAY,KAAK,QAAQ;AACzB,uBAAe,QAAQ;AACvB,eAAO;AAAA,MACT;AAAA,IACF;AACA,UAAM,OAAO,QAAQ,OAAO;AAC5B,YAAQ,eAAe;AAAA,EACzB;AAEA,OAAK,kBAAkB,IAAI,EAAE,SAAS,aAAa,cAAc;AAEjE,SAAO,EAAE,MAAM,YAAY;AAC7B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MediaTypeObject, OperationObject, ParameterObject, PathsObject, ReferenceObject, RequestBodyObject, ResponseObject, SchemaObject, ServerObject, TagObject } from 'openapi3-ts/oas31';
|
|
2
|
+
import type { OpenAPIComponentsObject, OpenAPIDocument, OpenAPISecuritySchemeObject } from '@sdk-it/core';
|
|
2
3
|
import type { PaginationGuess } from './pagination/guess-pagination.js';
|
|
3
4
|
import type { SidebarData, TagGroups } from './sidebar.js';
|
|
4
|
-
export
|
|
5
|
+
export type IR = Omit<OpenAPIDocument, 'components' | 'paths' | 'servers' | 'tags'> & {
|
|
5
6
|
servers: ServerObject[];
|
|
6
7
|
'x-sdk-processing'?: {
|
|
7
8
|
plugins: string[];
|
|
@@ -9,13 +10,13 @@ export interface IR extends OpenAPIObject {
|
|
|
9
10
|
};
|
|
10
11
|
'x-docs': SidebarData;
|
|
11
12
|
'x-tagGroups': TagGroups[];
|
|
12
|
-
components: Omit<
|
|
13
|
+
components: Omit<OpenAPIComponentsObject, 'schemas' | 'securitySchemes'> & {
|
|
13
14
|
schemas: Record<string, SchemaObject | ReferenceObject>;
|
|
14
|
-
securitySchemes: Record<string,
|
|
15
|
+
securitySchemes: Record<string, OpenAPISecuritySchemeObject>;
|
|
15
16
|
};
|
|
16
17
|
paths: PathsObject;
|
|
17
18
|
tags: TagObject[];
|
|
18
|
-
}
|
|
19
|
+
};
|
|
19
20
|
export interface OurRequestBodyObject extends RequestBodyObject {
|
|
20
21
|
content: Record<string, Omit<MediaTypeObject, 'schema'> & {
|
|
21
22
|
schema: ReferenceObject;
|
package/dist/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,eAAe,EACf,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,SAAS,EACV,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EACV,uBAAuB,EACvB,eAAe,EACf,2BAA2B,EAC5B,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,MAAM,EAAE,GAAG,IAAI,CACnB,eAAe,EACf,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAC5C,GAAG;IACF,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,kBAAkB,CAAC,EAAE;QACnB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,QAAQ,EAAE,WAAW,CAAC;IACtB,aAAa,EAAE,SAAS,EAAE,CAAC;IAC3B,UAAU,EAAE,IAAI,CAAC,uBAAuB,EAAE,SAAS,GAAG,iBAAiB,CAAC,GAAG;QACzE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,CAAC,CAAC;QACxD,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;KAC9D,CAAC;IACF,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,SAAS,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,OAAO,EAAE,MAAM,CACb,MAAM,EACN,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,GAAG;QAAE,MAAM,EAAE,eAAe,CAAA;KAAE,CAC9D,CAAC;CACH;AAED,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,eAAe,EACf,aAAa,GAAG,MAAM,GAAG,YAAY,GAAG,WAAW,GAAG,aAAa,GAAG,MAAM,CAC7E,GAAG;IACF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IACtB,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CACf,MAAM,EACN,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,GAAG;QAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;KAC1C,CACF,CAAC;IACF,WAAW,EAAE,oBAAoB,CAAC;CACnC,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AACD,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,oBAAoB,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAAG;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdk-it/spec",
|
|
3
|
-
"version": "0.46.
|
|
3
|
+
"version": "0.46.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"!**/*.test.*"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@sdk-it/core": "0.46.
|
|
30
|
+
"@sdk-it/core": "0.46.4",
|
|
31
31
|
"openapi3-ts": "4.5.0",
|
|
32
32
|
"pluralize": "^8.0.0",
|
|
33
33
|
"stringcase": "^4.3.1",
|
package/dist/lib/security.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ParameterLocation, ParameterObject, ReferenceObject, SchemaObject, SecurityRequirementObject, SecuritySchemeObject } from 'openapi3-ts/oas31';
|
|
2
|
-
import type { IR } from './types.js';
|
|
3
|
-
type OIn = ParameterLocation | 'input';
|
|
4
|
-
export type OurParameter = Omit<ParameterObject, 'in' | 'schema'> & {
|
|
5
|
-
in: OIn;
|
|
6
|
-
'x-optionName'?: string;
|
|
7
|
-
schema: SchemaObject;
|
|
8
|
-
};
|
|
9
|
-
export declare function securityToOptions(spec: IR, security: SecurityRequirementObject[], securitySchemes: Record<string, SecuritySchemeObject | ReferenceObject>, staticIn?: OIn): OurParameter[];
|
|
10
|
-
export declare function security(spec: IR): OurParameter[];
|
|
11
|
-
export {};
|
|
12
|
-
//# sourceMappingURL=security.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/lib/security.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAErC,KAAK,GAAG,GAAG,iBAAiB,GAAG,OAAO,CAAC;AAEvC,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,QAAQ,CAAC,GAAG;IAClE,EAAE,EAAE,GAAG,CAAC;IACR,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,EAAE,EACR,QAAQ,EAAE,yBAAyB,EAAE,EACrC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,eAAe,CAAC,EACvE,QAAQ,CAAC,EAAE,GAAG,kBAkDf;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,EAAE,kBAiChC"}
|
package/dist/lib/security.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { methods } from "@sdk-it/core/paths.js";
|
|
2
|
-
import { resolveRef } from "@sdk-it/core/ref.js";
|
|
3
|
-
function securityToOptions(spec, security2, securitySchemes, staticIn) {
|
|
4
|
-
const parameters = /* @__PURE__ */ new Map();
|
|
5
|
-
for (const it of security2) {
|
|
6
|
-
const [name] = Object.keys(it);
|
|
7
|
-
if (!name) {
|
|
8
|
-
continue;
|
|
9
|
-
}
|
|
10
|
-
const schema = resolveRef(
|
|
11
|
-
spec,
|
|
12
|
-
securitySchemes[name]
|
|
13
|
-
);
|
|
14
|
-
if (schema.type === "http") {
|
|
15
|
-
parameters.set(`${staticIn ?? "header"}:authorization`, {
|
|
16
|
-
in: staticIn ?? "header",
|
|
17
|
-
name: "authorization",
|
|
18
|
-
required: false,
|
|
19
|
-
schema: { type: "string", "x-prefix": "Bearer " },
|
|
20
|
-
"x-optionName": "token",
|
|
21
|
-
example: schema.scheme === "bearer" ? '"<token>"' : `<${schema.scheme}> <token>`
|
|
22
|
-
});
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
if (schema.type === "apiKey") {
|
|
26
|
-
if (!schema.in) {
|
|
27
|
-
throw new Error(`apiKey security schema must have an "in" field`);
|
|
28
|
-
}
|
|
29
|
-
if (!schema.name) {
|
|
30
|
-
throw new Error(`apiKey security schema must have a "name" field`);
|
|
31
|
-
}
|
|
32
|
-
const paramIn = staticIn ?? schema.in;
|
|
33
|
-
parameters.set(`${paramIn}:${schema.name}`, {
|
|
34
|
-
in: paramIn,
|
|
35
|
-
name: schema.name,
|
|
36
|
-
required: false,
|
|
37
|
-
schema: { type: "string" },
|
|
38
|
-
example: `"proj-${crypto.randomUUID().slice(0, 12)}"`
|
|
39
|
-
});
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return [...parameters.values()];
|
|
44
|
-
}
|
|
45
|
-
function security(spec) {
|
|
46
|
-
const security2 = spec.security || [];
|
|
47
|
-
const paths = Object.values(spec.paths ?? {});
|
|
48
|
-
const options = /* @__PURE__ */ new Map();
|
|
49
|
-
for (const option of securityToOptions(
|
|
50
|
-
spec,
|
|
51
|
-
security2,
|
|
52
|
-
spec.components.securitySchemes
|
|
53
|
-
)) {
|
|
54
|
-
options.set(`${option.in}:${option.name}`, option);
|
|
55
|
-
}
|
|
56
|
-
for (const it of paths) {
|
|
57
|
-
for (const method of methods) {
|
|
58
|
-
const operation = it[method];
|
|
59
|
-
if (!operation) {
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
for (const option of securityToOptions(
|
|
63
|
-
spec,
|
|
64
|
-
operation.security || [],
|
|
65
|
-
spec.components.securitySchemes,
|
|
66
|
-
"input"
|
|
67
|
-
)) {
|
|
68
|
-
options.set(`${option.in}:${option.name}`, option);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return [...options.values()];
|
|
73
|
-
}
|
|
74
|
-
export {
|
|
75
|
-
security,
|
|
76
|
-
securityToOptions
|
|
77
|
-
};
|
|
78
|
-
//# sourceMappingURL=security.js.map
|
package/dist/lib/security.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/lib/security.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n ParameterLocation,\n ParameterObject,\n ReferenceObject,\n SchemaObject,\n SecurityRequirementObject,\n SecuritySchemeObject,\n} from 'openapi3-ts/oas31';\n\nimport { methods } from '@sdk-it/core/paths.js';\nimport { resolveRef } from '@sdk-it/core/ref.js';\n\nimport type { IR } from './types.js';\n\ntype OIn = ParameterLocation | 'input';\n\nexport type OurParameter = Omit<ParameterObject, 'in' | 'schema'> & {\n in: OIn;\n 'x-optionName'?: string;\n schema: SchemaObject;\n};\n\nexport function securityToOptions(\n spec: IR,\n security: SecurityRequirementObject[],\n securitySchemes: Record<string, SecuritySchemeObject | ReferenceObject>,\n staticIn?: OIn,\n) {\n // Distinct schemes can resolve to the same parameter (e.g. Figma's\n // PersonalAccessToken and PlanAccessToken both use the X-Figma-Token\n // header), so key by location + name to avoid duplicate options.\n const parameters = new Map<string, OurParameter>();\n for (const it of security) {\n const [name] = Object.keys(it);\n if (!name) {\n // this means the operation doesn't necessarily require security\n continue;\n }\n\n const schema = resolveRef<SecuritySchemeObject>(\n spec,\n securitySchemes[name],\n );\n if (schema.type === 'http') {\n parameters.set(`${staticIn ?? 'header'}:authorization`, {\n in: staticIn ?? 'header',\n name: 'authorization',\n required: false,\n schema: { type: 'string', 'x-prefix': 'Bearer ' },\n 'x-optionName': 'token',\n example:\n schema.scheme === 'bearer'\n ? '\"<token>\"'\n : `<${schema.scheme}> <token>`,\n });\n continue;\n }\n if (schema.type === 'apiKey') {\n if (!schema.in) {\n throw new Error(`apiKey security schema must have an \"in\" field`);\n }\n if (!schema.name) {\n throw new Error(`apiKey security schema must have a \"name\" field`);\n }\n const paramIn = staticIn ?? (schema.in as ParameterLocation);\n parameters.set(`${paramIn}:${schema.name}`, {\n in: paramIn,\n name: schema.name,\n required: false,\n schema: { type: 'string' },\n example: `\"proj-${crypto.randomUUID().slice(0, 12)}\"`,\n });\n continue;\n }\n }\n return [...parameters.values()];\n}\n\nexport function security(spec: IR) {\n const security = spec.security || [];\n const paths = Object.values(spec.paths ?? {});\n\n // Same keying as securityToOptions: two parameters may share a name but\n // differ in location (e.g. header vs query api keys), so name alone drops\n // credentials.\n const options = new Map<string, OurParameter>();\n for (const option of securityToOptions(\n spec,\n security,\n spec.components.securitySchemes,\n )) {\n options.set(`${option.in}:${option.name}`, option);\n }\n\n for (const it of paths) {\n for (const method of methods) {\n const operation = it[method];\n if (!operation) {\n continue;\n }\n for (const option of securityToOptions(\n spec,\n operation.security || [],\n spec.components.securitySchemes,\n 'input',\n )) {\n options.set(`${option.in}:${option.name}`, option);\n }\n }\n }\n return [...options.values()];\n}\n"],
|
|
5
|
-
"mappings": "AASA,SAAS,eAAe;AACxB,SAAS,kBAAkB;AAYpB,SAAS,kBACd,MACAA,WACA,iBACA,UACA;AAIA,QAAM,aAAa,oBAAI,IAA0B;AACjD,aAAW,MAAMA,WAAU;AACzB,UAAM,CAAC,IAAI,IAAI,OAAO,KAAK,EAAE;AAC7B,QAAI,CAAC,MAAM;AAET;AAAA,IACF;AAEA,UAAM,SAAS;AAAA,MACb;AAAA,MACA,gBAAgB,IAAI;AAAA,IACtB;AACA,QAAI,OAAO,SAAS,QAAQ;AAC1B,iBAAW,IAAI,GAAG,YAAY,QAAQ,kBAAkB;AAAA,QACtD,IAAI,YAAY;AAAA,QAChB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,QAAQ,EAAE,MAAM,UAAU,YAAY,UAAU;AAAA,QAChD,gBAAgB;AAAA,QAChB,SACE,OAAO,WAAW,WACd,cACA,IAAI,OAAO,MAAM;AAAA,MACzB,CAAC;AACD;AAAA,IACF;AACA,QAAI,OAAO,SAAS,UAAU;AAC5B,UAAI,CAAC,OAAO,IAAI;AACd,cAAM,IAAI,MAAM,gDAAgD;AAAA,MAClE;AACA,UAAI,CAAC,OAAO,MAAM;AAChB,cAAM,IAAI,MAAM,iDAAiD;AAAA,MACnE;AACA,YAAM,UAAU,YAAa,OAAO;AACpC,iBAAW,IAAI,GAAG,OAAO,IAAI,OAAO,IAAI,IAAI;AAAA,QAC1C,IAAI;AAAA,QACJ,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,QACV,QAAQ,EAAE,MAAM,SAAS;AAAA,QACzB,SAAS,SAAS,OAAO,WAAW,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,MACpD,CAAC;AACD;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAG,WAAW,OAAO,CAAC;AAChC;AAEO,SAAS,SAAS,MAAU;AACjC,QAAMA,YAAW,KAAK,YAAY,CAAC;AACnC,QAAM,QAAQ,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC;AAK5C,QAAM,UAAU,oBAAI,IAA0B;AAC9C,aAAW,UAAU;AAAA,IACnB;AAAA,IACAA;AAAA,IACA,KAAK,WAAW;AAAA,EAClB,GAAG;AACD,YAAQ,IAAI,GAAG,OAAO,EAAE,IAAI,OAAO,IAAI,IAAI,MAAM;AAAA,EACnD;AAEA,aAAW,MAAM,OAAO;AACtB,eAAW,UAAU,SAAS;AAC5B,YAAM,YAAY,GAAG,MAAM;AAC3B,UAAI,CAAC,WAAW;AACd;AAAA,MACF;AACA,iBAAW,UAAU;AAAA,QACnB;AAAA,QACA,UAAU,YAAY,CAAC;AAAA,QACvB,KAAK,WAAW;AAAA,QAChB;AAAA,MACF,GAAG;AACD,gBAAQ,IAAI,GAAG,OAAO,EAAE,IAAI,OAAO,IAAI,IAAI,MAAM;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAG,QAAQ,OAAO,CAAC;AAC7B;",
|
|
6
|
-
"names": ["security"]
|
|
7
|
-
}
|