@sdk-it/spec 0.46.0 → 0.46.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -6
- package/dist/index.js.map +2 -2
- package/dist/lib/find-polymorphic-varients.js +1 -1
- package/dist/lib/find-polymorphic-varients.js.map +1 -1
- package/dist/lib/is-primitive-schema.js +1 -1
- package/dist/lib/is-primitive-schema.js.map +1 -1
- package/dist/lib/is.d.ts +2 -0
- package/dist/lib/is.d.ts.map +1 -1
- package/dist/lib/is.js +5 -0
- package/dist/lib/is.js.map +2 -2
- package/dist/lib/pagination/guess-pagination.js +1 -1
- package/dist/lib/pagination/guess-pagination.js.map +1 -1
- package/dist/lib/processing-plugins/extract-inline-schemas.d.ts.map +1 -1
- package/dist/lib/processing-plugins/extract-inline-schemas.js +151 -3
- package/dist/lib/processing-plugins/extract-inline-schemas.js.map +2 -2
- package/dist/lib/processing-plugins/normalize-request-bodies.d.ts +3 -0
- package/dist/lib/processing-plugins/normalize-request-bodies.d.ts.map +1 -1
- package/dist/lib/processing-plugins/normalize-request-bodies.js +99 -4
- package/dist/lib/processing-plugins/normalize-request-bodies.js.map +2 -2
- package/dist/lib/processing-plugins/normalize-responses.d.ts.map +1 -1
- package/dist/lib/processing-plugins/normalize-responses.js +126 -3
- package/dist/lib/processing-plugins/normalize-responses.js.map +2 -2
- package/dist/lib/processing-plugins/normalize-schemas.d.ts.map +1 -1
- package/dist/lib/processing-plugins/normalize-schemas.js +159 -2
- package/dist/lib/processing-plugins/normalize-schemas.js.map +3 -3
- package/package.json +2 -2
- package/dist/lib/tune-request-body.d.ts +0 -5
- package/dist/lib/tune-request-body.d.ts.map +0 -1
- package/dist/lib/tune-request-body.js +0 -101
- package/dist/lib/tune-request-body.js.map +0 -7
- package/dist/lib/tune-response.d.ts +0 -5
- package/dist/lib/tune-response.d.ts.map +0 -1
- package/dist/lib/tune-response.js +0 -135
- package/dist/lib/tune-response.js.map +0 -7
- package/dist/lib/tune.d.ts +0 -11
- package/dist/lib/tune.d.ts.map +0 -1
- package/dist/lib/tune.js +0 -315
- package/dist/lib/tune.js.map +0 -7
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { followRef, isRef } from "@sdk-it/core/ref.js";
|
|
2
|
-
import { isEmpty } from "@sdk-it/core/utils.js";
|
|
3
|
-
import { findUniqueSchemaName } from "./find-unique-schema-name.js";
|
|
4
|
-
import { securityToOptions } from "./security.js";
|
|
5
|
-
function patchParameters(spec, schema, parameters, security) {
|
|
6
|
-
const securityOptions = securityToOptions(
|
|
7
|
-
spec,
|
|
8
|
-
security,
|
|
9
|
-
spec.components.securitySchemes
|
|
10
|
-
);
|
|
11
|
-
const required = new Set(
|
|
12
|
-
Array.isArray(schema.required) ? schema.required : []
|
|
13
|
-
);
|
|
14
|
-
schema["x-properties"] ??= {};
|
|
15
|
-
for (const param of parameters) {
|
|
16
|
-
if (param.required) {
|
|
17
|
-
required.add(param.name);
|
|
18
|
-
}
|
|
19
|
-
schema["x-properties"][param.name] = {
|
|
20
|
-
"x-in": param.in,
|
|
21
|
-
...isRef(param.schema) ? followRef(spec, param.schema.$ref) : param.schema ?? { type: "string" }
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
for (const param of securityOptions) {
|
|
25
|
-
required.delete(param.name);
|
|
26
|
-
schema["x-properties"][param.name] = {
|
|
27
|
-
"x-in": "header",
|
|
28
|
-
...isRef(param.schema) ? followRef(spec, param.schema.$ref) : param.schema ?? { type: "string" }
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
schema["x-required"] = [...required];
|
|
32
|
-
}
|
|
33
|
-
function tuneRequestBody(spec, operationId, operation, parameters, security) {
|
|
34
|
-
const requestBodySource = isRef(operation.requestBody) ? followRef(spec, operation.requestBody.$ref) : operation.requestBody ?? {
|
|
35
|
-
content: {},
|
|
36
|
-
required: false
|
|
37
|
-
};
|
|
38
|
-
const requestBody = structuredClone(requestBodySource);
|
|
39
|
-
if (isEmpty(requestBody.content)) {
|
|
40
|
-
const inputName = findUniqueSchemaName(spec, operationId, [
|
|
41
|
-
"input",
|
|
42
|
-
"payload",
|
|
43
|
-
"request"
|
|
44
|
-
]);
|
|
45
|
-
const schema = {
|
|
46
|
-
"x-inputname": inputName,
|
|
47
|
-
"x-requestbody": true
|
|
48
|
-
};
|
|
49
|
-
patchParameters(spec, schema, parameters, security);
|
|
50
|
-
const tuned = {
|
|
51
|
-
...requestBody,
|
|
52
|
-
content: {
|
|
53
|
-
"application/empty": {
|
|
54
|
-
schema: { $ref: `#/components/schemas/${inputName}` }
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
spec.components.schemas[inputName] = schema;
|
|
59
|
-
return tuned;
|
|
60
|
-
}
|
|
61
|
-
for (const contentType in requestBody.content) {
|
|
62
|
-
const mediaType = requestBody.content[contentType];
|
|
63
|
-
const inputName = findUniqueSchemaName(spec, operationId, [
|
|
64
|
-
"input",
|
|
65
|
-
"payload",
|
|
66
|
-
"request"
|
|
67
|
-
]);
|
|
68
|
-
let schema;
|
|
69
|
-
switch (true) {
|
|
70
|
-
case isRef(mediaType.schema):
|
|
71
|
-
schema = structuredClone(
|
|
72
|
-
followRef(spec, mediaType.schema.$ref)
|
|
73
|
-
);
|
|
74
|
-
break;
|
|
75
|
-
case isEmpty(mediaType.schema):
|
|
76
|
-
schema ??= {};
|
|
77
|
-
console.warn(
|
|
78
|
-
`Request body schema for content type "${contentType}" is empty.`
|
|
79
|
-
);
|
|
80
|
-
break;
|
|
81
|
-
default:
|
|
82
|
-
schema = structuredClone(mediaType.schema);
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
patchParameters(spec, schema, parameters, security);
|
|
86
|
-
spec.components.schemas[inputName] = {
|
|
87
|
-
...schema,
|
|
88
|
-
"x-requestbody": true,
|
|
89
|
-
"x-inputname": inputName
|
|
90
|
-
};
|
|
91
|
-
requestBody.content[contentType].schema = {
|
|
92
|
-
$ref: `#/components/schemas/${inputName}`
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
return requestBody;
|
|
96
|
-
}
|
|
97
|
-
export {
|
|
98
|
-
patchParameters,
|
|
99
|
-
tuneRequestBody
|
|
100
|
-
};
|
|
101
|
-
//# sourceMappingURL=tune-request-body.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/lib/tune-request-body.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n OperationObject,\n ParameterObject,\n RequestBodyObject,\n SchemaObject,\n SecurityRequirementObject,\n} from 'openapi3-ts/oas31';\n\nimport { followRef, isRef } from '@sdk-it/core/ref.js';\nimport { isEmpty } from '@sdk-it/core/utils.js';\n\nimport { findUniqueSchemaName } from './find-unique-schema-name.js';\nimport { securityToOptions } from './security.js';\nimport type { IR, OurRequestBodyObject } from './types.js';\n\nexport function patchParameters(\n spec: IR,\n schema: SchemaObject,\n parameters: ParameterObject[],\n security: SecurityRequirementObject[],\n) {\n const securityOptions = securityToOptions(\n spec,\n security,\n spec.components.securitySchemes,\n );\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 for (const param of securityOptions) {\n required.delete(param.name);\n schema['x-properties'][param.name] = {\n 'x-in': 'header',\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\nexport function tuneRequestBody(\n spec: IR,\n operationId: string,\n operation: OperationObject,\n parameters: ParameterObject[],\n security: SecurityRequirementObject[],\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, security);\n const tuned: 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 tuned;\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 // we cannot use the model name as inputName as it might be used in other places that are not request bodies\n // inputName = parseRef(mediaType.schema.$ref).model;\n break;\n case isEmpty(mediaType.schema):\n schema ??= {}; // default to empty schema if not defined\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, security);\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"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { OperationObject } from 'openapi3-ts/oas31';
|
|
2
|
-
import { type ResponsesConfig } from './options.js';
|
|
3
|
-
import type { IR } from './types.js';
|
|
4
|
-
export declare function resolveResponses(spec: IR, operationId: string, operation: OperationObject, responsesConfig?: ResponsesConfig): import("openapi3-ts/oas31").ResponsesObject;
|
|
5
|
-
//# sourceMappingURL=tune-response.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tune-response.d.ts","sourceRoot":"","sources":["../../src/lib/tune-response.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAc3B,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAErC,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,EAAE,EACR,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,eAAe,EAC1B,eAAe,CAAC,EAAE,eAAe,+CAyIlC"}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { parse as parseContentType } from "fast-content-type-parse";
|
|
2
|
-
import { isRef, parseRef, resolveRef } from "@sdk-it/core/ref.js";
|
|
3
|
-
import { isEmpty, pascalcase } from "@sdk-it/core/utils.js";
|
|
4
|
-
import { findUniqueSchemaName } from "./find-unique-schema-name.js";
|
|
5
|
-
import {
|
|
6
|
-
isBinaryContentType,
|
|
7
|
-
isSseContentType,
|
|
8
|
-
isStreamingContentType,
|
|
9
|
-
isSuccessStatusCode,
|
|
10
|
-
isTextContentType,
|
|
11
|
-
parseJsonContentType
|
|
12
|
-
} from "./is.js";
|
|
13
|
-
import {} from "./options.js";
|
|
14
|
-
function resolveResponses(spec, operationId, operation, responsesConfig) {
|
|
15
|
-
const responses = operation.responses ?? {};
|
|
16
|
-
operation.responses ??= {};
|
|
17
|
-
let foundSuccessResponse = false;
|
|
18
|
-
for (const status in responses) {
|
|
19
|
-
operation.responses[status] = structuredClone(
|
|
20
|
-
resolveRef(spec, responses[status])
|
|
21
|
-
);
|
|
22
|
-
if (status !== "default" && isSuccessStatusCode(status)) {
|
|
23
|
-
foundSuccessResponse = true;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (!foundSuccessResponse) {
|
|
27
|
-
operation.responses["200"] = {
|
|
28
|
-
description: "OK",
|
|
29
|
-
content: {
|
|
30
|
-
"application/json": {
|
|
31
|
-
schema: {}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
for (const status in operation.responses) {
|
|
37
|
-
const response = operation.responses[status];
|
|
38
|
-
const statusCode = +status;
|
|
39
|
-
if (!responsesConfig?.flattenErrorResponses) {
|
|
40
|
-
if (!isSuccessStatusCode(status)) {
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (isEmpty(response.content)) {
|
|
45
|
-
response.content = {
|
|
46
|
-
"application/octet-stream": {}
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
let responseName;
|
|
50
|
-
for (const [contentType, mediaType] of Object.entries(
|
|
51
|
-
response.content
|
|
52
|
-
)) {
|
|
53
|
-
if (isRef(mediaType.schema)) {
|
|
54
|
-
const { model } = parseRef(mediaType.schema.$ref);
|
|
55
|
-
Object.assign(spec.components.schemas[model], {
|
|
56
|
-
"x-responsebody": true
|
|
57
|
-
// do not assign response ref to a group
|
|
58
|
-
// because they are supposed to be in a separate file only inlined
|
|
59
|
-
// schemas are grouped by operationId
|
|
60
|
-
});
|
|
61
|
-
responseName ??= model;
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
const outputName = statusCode !== 200 ? findUniqueSchemaName(spec, `${pascalcase(operationId)}${status}`, [
|
|
65
|
-
"output",
|
|
66
|
-
"payload",
|
|
67
|
-
"result"
|
|
68
|
-
]) : findUniqueSchemaName(spec, operationId, [
|
|
69
|
-
"output",
|
|
70
|
-
"payload",
|
|
71
|
-
"result"
|
|
72
|
-
]);
|
|
73
|
-
responseName ??= outputName;
|
|
74
|
-
const isSse = isSseContentType(contentType);
|
|
75
|
-
const normalizedContentType = normalizeContentType(contentType);
|
|
76
|
-
const hasContentDisposition = hasHeader(
|
|
77
|
-
response.headers,
|
|
78
|
-
"Content-Disposition"
|
|
79
|
-
);
|
|
80
|
-
const isBinary = isBinaryContentType(contentType) || isStreamingContentType(normalizedContentType) && hasContentDisposition;
|
|
81
|
-
const isText = isTextContentType(contentType);
|
|
82
|
-
if (parseJsonContentType(contentType)) {
|
|
83
|
-
if (isEmpty(mediaType.schema)) {
|
|
84
|
-
spec.components.schemas[outputName] = {
|
|
85
|
-
type: "object",
|
|
86
|
-
additionalProperties: true
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
} else {
|
|
90
|
-
if (isEmpty(mediaType.schema) && (isText || isBinary)) {
|
|
91
|
-
mediaType.schema = {
|
|
92
|
-
type: "string",
|
|
93
|
-
...isBinary ? { format: "binary" } : {}
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
spec.components.schemas[outputName] = {
|
|
97
|
-
...spec.components.schemas[outputName],
|
|
98
|
-
"x-stream": isSse || !isText && !isBinary,
|
|
99
|
-
...isSse ? { "x-sse": true } : {}
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
spec.components.schemas[outputName] = {
|
|
103
|
-
...spec.components.schemas[outputName],
|
|
104
|
-
...mediaType.schema,
|
|
105
|
-
"x-responsebody": true,
|
|
106
|
-
"x-response-group": operationId
|
|
107
|
-
};
|
|
108
|
-
operation.responses[status].content[contentType].schema = {
|
|
109
|
-
$ref: `#/components/schemas/${outputName}`
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
if (responseName) {
|
|
113
|
-
response["x-response-name"] = responseName;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return operation.responses;
|
|
117
|
-
}
|
|
118
|
-
function normalizeContentType(contentType) {
|
|
119
|
-
try {
|
|
120
|
-
return parseContentType(contentType)?.type?.toLowerCase();
|
|
121
|
-
} catch {
|
|
122
|
-
return contentType.split(";")[0]?.trim().toLowerCase();
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
function hasHeader(headers, name) {
|
|
126
|
-
if (!headers) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
const target = name.toLowerCase();
|
|
130
|
-
return Object.keys(headers).some((key) => key.toLowerCase() === target);
|
|
131
|
-
}
|
|
132
|
-
export {
|
|
133
|
-
resolveResponses
|
|
134
|
-
};
|
|
135
|
-
//# sourceMappingURL=tune-response.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/lib/tune-response.ts"],
|
|
4
|
-
"sourcesContent": ["import { parse as parseContentType } from 'fast-content-type-parse';\nimport type {\n MediaTypeObject,\n OperationObject,\n ResponseObject,\n} from 'openapi3-ts/oas31';\n\nimport { isRef, parseRef, resolveRef } from '@sdk-it/core/ref.js';\nimport { isEmpty, pascalcase } from '@sdk-it/core/utils.js';\n\nimport { findUniqueSchemaName } from './find-unique-schema-name.js';\nimport {\n isBinaryContentType,\n isSseContentType,\n isStreamingContentType,\n isSuccessStatusCode,\n isTextContentType,\n parseJsonContentType,\n} from './is.js';\nimport { type ResponsesConfig } from './options.js';\nimport type { IR } from './types.js';\n\nexport function resolveResponses(\n spec: IR,\n operationId: string,\n operation: OperationObject,\n responsesConfig?: ResponsesConfig,\n) {\n const responses = operation.responses ?? {};\n operation.responses ??= {};\n let foundSuccessResponse = false;\n for (const status in responses) {\n // use structuredClone to avoid mutating a response object\n // that is referenced by multiple operations\n operation.responses[status] = structuredClone(\n resolveRef<ResponseObject>(spec, responses[status]),\n );\n\n if (status !== 'default' && isSuccessStatusCode(status)) {\n foundSuccessResponse = true;\n }\n }\n\n if (!foundSuccessResponse) {\n operation.responses['200'] = {\n description: 'OK',\n content: {\n 'application/json': {\n schema: {},\n },\n },\n };\n }\n\n for (const status in operation.responses) {\n const response = operation.responses[status] as ResponseObject;\n const statusCode = +status;\n\n if (!responsesConfig?.flattenErrorResponses) {\n if (!isSuccessStatusCode(status)) {\n continue;\n }\n }\n\n if (isEmpty(response.content)) {\n response.content = {\n 'application/octet-stream': {},\n };\n }\n\n // if (isErrorStatusCode(status)) {\n // const mediaType = response.content?.['application/json'];\n // if (mediaType && isRef(mediaType.schema)) {\n // const { model } = parseRef(mediaType.schema.$ref);\n // Object.assign(config.spec.components.schemas[model], {\n // 'x-responsebody': true,\n // // do not assign response ref to a group\n // // because they are supposed to be in a separate file only inlined\n // // schemas are grouped by operationId\n // });\n // response['x-response-name'] = model;\n // }\n // continue;\n // }\n\n let responseName: string | undefined;\n for (const [contentType, mediaType] of Object.entries(\n response.content as Record<string, MediaTypeObject>,\n )) {\n if (isRef(mediaType.schema)) {\n const { model } = parseRef(mediaType.schema.$ref);\n Object.assign(spec.components.schemas[model], {\n 'x-responsebody': true,\n // do not assign response ref to a group\n // because they are supposed to be in a separate file only inlined\n // schemas are grouped by operationId\n });\n responseName ??= model;\n continue;\n }\n const outputName =\n statusCode !== 200\n ? findUniqueSchemaName(spec, `${pascalcase(operationId)}${status}`, [\n 'output',\n 'payload',\n 'result',\n ])\n : findUniqueSchemaName(spec, operationId, [\n 'output',\n 'payload',\n 'result',\n ]);\n responseName ??= outputName;\n const isSse = isSseContentType(contentType);\n const normalizedContentType = normalizeContentType(contentType);\n const hasContentDisposition = hasHeader(\n response.headers,\n 'Content-Disposition',\n );\n const isBinary =\n isBinaryContentType(contentType) ||\n (isStreamingContentType(normalizedContentType) &&\n hasContentDisposition);\n const isText = isTextContentType(contentType);\n\n if (parseJsonContentType(contentType)) {\n if (isEmpty(mediaType.schema)) {\n // add \"additionalProperties\" because we're certain this is a response body is of json type\n spec.components.schemas[outputName] = {\n type: 'object',\n additionalProperties: true,\n };\n }\n } else {\n if (isEmpty(mediaType.schema) && (isText || isBinary)) {\n mediaType.schema = {\n type: 'string',\n ...(isBinary ? { format: 'binary' } : {}),\n };\n }\n spec.components.schemas[outputName] = {\n ...spec.components.schemas[outputName],\n 'x-stream': isSse || (!isText && !isBinary),\n ...(isSse ? { 'x-sse': true } : {}),\n };\n }\n\n spec.components.schemas[outputName] = {\n ...spec.components.schemas[outputName],\n ...mediaType.schema,\n 'x-responsebody': true,\n 'x-response-group': operationId,\n };\n operation.responses[status].content[contentType].schema = {\n $ref: `#/components/schemas/${outputName}`,\n };\n }\n if (responseName) {\n response['x-response-name'] = responseName;\n }\n }\n\n return operation.responses;\n}\n\nfunction normalizeContentType(contentType: string) {\n try {\n return parseContentType(contentType)?.type?.toLowerCase();\n } catch {\n return contentType.split(';')[0]?.trim().toLowerCase();\n }\n}\n\nfunction hasHeader(headers: ResponseObject['headers'], name: string) {\n if (!headers) {\n return false;\n }\n const target = name.toLowerCase();\n return Object.keys(headers).some((key) => key.toLowerCase() === target);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/lib/tune.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { ReferenceObject, SchemaObject, SchemaObjectType } from 'openapi3-ts/oas31';
|
|
2
|
-
import type { IR } from './types.js';
|
|
3
|
-
export declare function fixSpec(spec: IR, schemas: (SchemaObject | ReferenceObject)[], visited?: Set<string>): void;
|
|
4
|
-
type Refs = {
|
|
5
|
-
name: string;
|
|
6
|
-
value: SchemaObject;
|
|
7
|
-
}[];
|
|
8
|
-
export declare function expandSpec(spec: IR, schemas: Record<string, SchemaObject | ReferenceObject>, refs: Refs): void;
|
|
9
|
-
export declare function coerceTypes(schema: SchemaObject, excludeNull?: boolean): SchemaObjectType[];
|
|
10
|
-
export {};
|
|
11
|
-
//# sourceMappingURL=tune.d.ts.map
|
package/dist/lib/tune.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tune.d.ts","sourceRoot":"","sources":["../../src/lib/tune.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAgB3B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAErC,wBAAgB,OAAO,CACrB,IAAI,EAAE,EAAE,EACR,OAAO,EAAE,CAAC,YAAY,GAAG,eAAe,CAAC,EAAE,EAC3C,OAAO,cAAoB,QAqL5B;AAED,KAAK,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,EAAE,CAAC;AAEpD,wBAAgB,UAAU,CACxB,IAAI,EAAE,EAAE,EACR,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,CAAC,EACvD,IAAI,EAAE,IAAI,QA4JX;AA2CD,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,WAAW,UAAO,GACjB,gBAAgB,EAAE,CAUpB"}
|
package/dist/lib/tune.js
DELETED
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
import { merge, uniq } from "lodash-es";
|
|
2
|
-
import assert from "node:assert";
|
|
3
|
-
import {
|
|
4
|
-
isEmpty,
|
|
5
|
-
isRef,
|
|
6
|
-
joinSkipDigits,
|
|
7
|
-
notRef,
|
|
8
|
-
pascalcase,
|
|
9
|
-
resolveRef,
|
|
10
|
-
snakecase
|
|
11
|
-
} from "@sdk-it/core";
|
|
12
|
-
import { findVarients } from "./find-polymorphic-varients.js";
|
|
13
|
-
import { findUniqueSchemaName } from "./find-unique-schema-name.js";
|
|
14
|
-
import { formatName } from "./format-name.js";
|
|
15
|
-
import { isPrimitiveSchema } from "./is-primitive-schema.js";
|
|
16
|
-
function fixSpec(spec, schemas, visited = /* @__PURE__ */ new Set()) {
|
|
17
|
-
for (const schema of schemas) {
|
|
18
|
-
if (isRef(schema)) continue;
|
|
19
|
-
if (!isEmpty(schema.properties)) {
|
|
20
|
-
schema.type = "object";
|
|
21
|
-
delete schema.oneOf;
|
|
22
|
-
delete schema.anyOf;
|
|
23
|
-
fixSpec(spec, Object.values(schema.properties), visited);
|
|
24
|
-
for (const [key, value] of Object.entries(schema.properties)) {
|
|
25
|
-
if (notRef(value) && isPrimitiveSchema(value)) {
|
|
26
|
-
value.default ??= schema.default?.[key];
|
|
27
|
-
delete schema.default?.[key];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
delete schema.default;
|
|
31
|
-
}
|
|
32
|
-
if (!isEmpty(schema["x-properties"])) {
|
|
33
|
-
fixSpec(spec, Object.values(schema["x-properties"]), visited);
|
|
34
|
-
}
|
|
35
|
-
if (!isEmpty(schema.items)) {
|
|
36
|
-
delete schema.oneOf;
|
|
37
|
-
delete schema.anyOf;
|
|
38
|
-
schema.type = "array";
|
|
39
|
-
fixSpec(spec, [schema.items], visited);
|
|
40
|
-
const items = resolveRef(spec, schema.items);
|
|
41
|
-
if (Array.isArray(items.default)) {
|
|
42
|
-
schema.default ??= structuredClone(items.default);
|
|
43
|
-
}
|
|
44
|
-
delete items.default;
|
|
45
|
-
}
|
|
46
|
-
if (!isEmpty(schema.anyOf) && !isEmpty(schema.oneOf)) {
|
|
47
|
-
delete schema.anyOf;
|
|
48
|
-
}
|
|
49
|
-
if (isEmpty(schema.enum)) {
|
|
50
|
-
delete schema.enum;
|
|
51
|
-
}
|
|
52
|
-
if (!isEmpty(schema.enum)) {
|
|
53
|
-
if (schema.enum.length === 1) {
|
|
54
|
-
schema.const = schema.enum[0];
|
|
55
|
-
delete schema.enum;
|
|
56
|
-
} else {
|
|
57
|
-
const valuesSet = /* @__PURE__ */ new Set();
|
|
58
|
-
const valuesList = [];
|
|
59
|
-
for (const it of schema.enum) {
|
|
60
|
-
const formattedValue = formatName(snakecase(formatName(it)));
|
|
61
|
-
if (!valuesSet.has(formattedValue)) {
|
|
62
|
-
valuesSet.add(formattedValue);
|
|
63
|
-
valuesList.push(it);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
schema.enum = valuesList;
|
|
67
|
-
}
|
|
68
|
-
delete schema.allOf;
|
|
69
|
-
}
|
|
70
|
-
if (schema.const !== void 0) {
|
|
71
|
-
schema.default = schema.const;
|
|
72
|
-
}
|
|
73
|
-
if (!isEmpty(schema.allOf)) {
|
|
74
|
-
const schemas2 = schema.allOf;
|
|
75
|
-
const resolved = schemas2.map((it) => resolveRef(spec, it));
|
|
76
|
-
const hasObjects = resolved.some((it) => it.type === "object");
|
|
77
|
-
const hasOtherTypes = resolved.some(
|
|
78
|
-
(it) => it.type && it.type !== "object"
|
|
79
|
-
);
|
|
80
|
-
if (hasObjects && hasOtherTypes) {
|
|
81
|
-
assert(false, `allOf must be an object`);
|
|
82
|
-
}
|
|
83
|
-
merge(
|
|
84
|
-
schema,
|
|
85
|
-
...resolved.map((resolvedSchema, index) => {
|
|
86
|
-
const sourceSchema = schemas2[index];
|
|
87
|
-
if (isRef(sourceSchema)) {
|
|
88
|
-
if (visited.has(sourceSchema.$ref)) {
|
|
89
|
-
throw new Error(
|
|
90
|
-
`Circular allOf reference detected: ${[
|
|
91
|
-
...visited,
|
|
92
|
-
sourceSchema.$ref
|
|
93
|
-
].join(" -> ")}`
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
fixSpec(
|
|
97
|
-
spec,
|
|
98
|
-
[resolvedSchema],
|
|
99
|
-
new Set(visited).add(sourceSchema.$ref)
|
|
100
|
-
);
|
|
101
|
-
} else {
|
|
102
|
-
fixSpec(spec, [resolvedSchema], visited);
|
|
103
|
-
}
|
|
104
|
-
return resolvedSchema;
|
|
105
|
-
})
|
|
106
|
-
);
|
|
107
|
-
delete schema.allOf;
|
|
108
|
-
} else {
|
|
109
|
-
delete schema.allOf;
|
|
110
|
-
}
|
|
111
|
-
if (schema.type === "object" && isEmpty(schema.properties) && typeof schema.additionalProperties === "object" && !isEmpty(schema.additionalProperties) && notRef(schema.additionalProperties) && !isEmpty(schema.additionalProperties.properties)) {
|
|
112
|
-
fixSpec(
|
|
113
|
-
spec,
|
|
114
|
-
Object.values(schema.additionalProperties.properties),
|
|
115
|
-
visited
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
for (const kind of ["oneOf", "anyOf"]) {
|
|
119
|
-
if (!isEmpty(schema[kind])) {
|
|
120
|
-
delete schema.type;
|
|
121
|
-
fixSpec(spec, schema[kind], visited);
|
|
122
|
-
if (isEmpty(schema[kind])) {
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
let enumSchemaIndex = -1;
|
|
126
|
-
const enumValues = [];
|
|
127
|
-
for (let idx = 0; idx < schema[kind].length; idx++) {
|
|
128
|
-
const item = schema[kind][idx];
|
|
129
|
-
if (notRef(item) && item.type === "string") {
|
|
130
|
-
if (item.enum && item.enum.length > 1) {
|
|
131
|
-
enumValues.push(...item.enum);
|
|
132
|
-
if (enumSchemaIndex === -1) {
|
|
133
|
-
enumSchemaIndex = idx;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
if (enumSchemaIndex !== -1) {
|
|
139
|
-
const enumSchema = schema[kind][enumSchemaIndex];
|
|
140
|
-
if (notRef(enumSchema)) {
|
|
141
|
-
enumSchema.enum = uniq(enumValues);
|
|
142
|
-
}
|
|
143
|
-
schema[kind] = schema[kind].filter(
|
|
144
|
-
(it, idx) => idx === enumSchemaIndex || isRef(it)
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
const otherTypes = schema[kind].filter(
|
|
148
|
-
(it) => resolveRef(spec, it).type !== "null"
|
|
149
|
-
);
|
|
150
|
-
if (otherTypes.length === 1) {
|
|
151
|
-
Object.assign(schema, otherTypes[0]);
|
|
152
|
-
delete schema[kind];
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
schema["x-varients"] = findVarients(spec, schema[kind]);
|
|
156
|
-
} else {
|
|
157
|
-
delete schema[kind];
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
function expandSpec(spec, schemas, refs) {
|
|
163
|
-
for (const [name, schema] of Object.entries(schemas)) {
|
|
164
|
-
if (isRef(schema)) continue;
|
|
165
|
-
if (!isEmpty(schema.properties)) {
|
|
166
|
-
if (!isEmpty(schema.oneOf)) {
|
|
167
|
-
for (const oneOfIdx in schema.oneOf) {
|
|
168
|
-
const oneOf = schema.oneOf[oneOfIdx];
|
|
169
|
-
if (isRef(oneOf)) continue;
|
|
170
|
-
for (const key of ["properties", "x-properties"]) {
|
|
171
|
-
if (!isEmpty(oneOf.required) && schema[key]) {
|
|
172
|
-
schema.oneOf[oneOfIdx] = schema[key][oneOf.required[0]];
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
delete schema.type;
|
|
177
|
-
expandSpec(spec, schemas, refs);
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
if (schema.additionalProperties) {
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
spec.components.schemas[name] = schema;
|
|
184
|
-
const properties = schema.properties;
|
|
185
|
-
for (const [propName, value] of Object.entries(properties)) {
|
|
186
|
-
if (isRef(value)) continue;
|
|
187
|
-
const fixedPropName = propName.replace("[]", "");
|
|
188
|
-
const refName = findUniqueSchemaName(
|
|
189
|
-
spec,
|
|
190
|
-
pascalcase(joinSkipDigits([name, fixedPropName], " ")),
|
|
191
|
-
["Property", "Field", "Attribute"]
|
|
192
|
-
);
|
|
193
|
-
if (!isEmpty(value.properties)) {
|
|
194
|
-
spec.components.schemas[refName] = value;
|
|
195
|
-
properties[propName] = { $ref: `#/components/schemas/${refName}` };
|
|
196
|
-
expandSpec(spec, { [refName]: value }, refs);
|
|
197
|
-
} else if (!isEmpty(value.oneOf)) {
|
|
198
|
-
expandOneOf(spec, name, value, refs, "oneOf");
|
|
199
|
-
spec.components.schemas[refName] = value;
|
|
200
|
-
properties[propName] = { $ref: `#/components/schemas/${refName}` };
|
|
201
|
-
expandSpec(spec, { [refName]: value }, refs);
|
|
202
|
-
} else if (!isEmpty(value.anyOf)) {
|
|
203
|
-
expandOneOf(spec, name, value, refs, "anyOf");
|
|
204
|
-
spec.components.schemas[refName] = value;
|
|
205
|
-
properties[propName] = { $ref: `#/components/schemas/${refName}` };
|
|
206
|
-
expandSpec(spec, { [refName]: value }, refs);
|
|
207
|
-
} else {
|
|
208
|
-
expandSpec(spec, { [refName]: value }, refs);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
if (!isEmpty(schema["x-properties"])) {
|
|
214
|
-
spec.components.schemas[name] = schema;
|
|
215
|
-
const properties = schema["x-properties"];
|
|
216
|
-
for (const [propName, value] of Object.entries(properties)) {
|
|
217
|
-
if (isRef(value)) continue;
|
|
218
|
-
const fixedPropName = propName.replace("[]", "");
|
|
219
|
-
const refName = findUniqueSchemaName(
|
|
220
|
-
spec,
|
|
221
|
-
pascalcase(joinSkipDigits([name, fixedPropName], " ")),
|
|
222
|
-
["Property", "Field", "Attribute"]
|
|
223
|
-
);
|
|
224
|
-
if (!isEmpty(value.properties)) {
|
|
225
|
-
spec.components.schemas[refName] = value;
|
|
226
|
-
properties[propName] = { $ref: `#/components/schemas/${refName}` };
|
|
227
|
-
expandSpec(spec, { [refName]: value }, refs);
|
|
228
|
-
} else if (!isEmpty(value.oneOf)) {
|
|
229
|
-
expandOneOf(spec, name, value, refs, "oneOf");
|
|
230
|
-
spec.components.schemas[refName] = value;
|
|
231
|
-
properties[propName] = { $ref: `#/components/schemas/${refName}` };
|
|
232
|
-
expandSpec(spec, { [refName]: value }, refs);
|
|
233
|
-
} else if (!isEmpty(value.anyOf)) {
|
|
234
|
-
expandOneOf(spec, name, value, refs, "anyOf");
|
|
235
|
-
spec.components.schemas[refName] = value;
|
|
236
|
-
properties[propName] = { $ref: `#/components/schemas/${refName}` };
|
|
237
|
-
expandSpec(spec, { [refName]: value }, refs);
|
|
238
|
-
} else {
|
|
239
|
-
expandSpec(spec, { [refName]: value }, refs);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
if (schema.type === "array") {
|
|
245
|
-
if (isRef(schema.items)) continue;
|
|
246
|
-
if (isEmpty(schema.items)) continue;
|
|
247
|
-
const refName = findUniqueSchemaName(spec, name, ["Item", "Entry"]);
|
|
248
|
-
if (schema.items.type === "object") {
|
|
249
|
-
spec.components.schemas[refName] = schema.items;
|
|
250
|
-
expandSpec(spec, { [refName]: schema.items }, refs);
|
|
251
|
-
schema.items = { $ref: `#/components/schemas/${refName}` };
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
if (schema.items.type === "array") {
|
|
255
|
-
expandSpec(spec, { [refName]: schema.items }, refs);
|
|
256
|
-
continue;
|
|
257
|
-
}
|
|
258
|
-
if (!isEmpty(schema.items.oneOf)) {
|
|
259
|
-
expandOneOf(spec, refName, schema.items, refs, "oneOf");
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
if (!isEmpty(schema.items.anyOf)) {
|
|
263
|
-
expandOneOf(spec, refName, schema.items, refs, "anyOf");
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
if (!isEmpty(schema.oneOf)) {
|
|
268
|
-
expandOneOf(spec, name, schema, refs, "oneOf");
|
|
269
|
-
continue;
|
|
270
|
-
}
|
|
271
|
-
if (!isEmpty(schema.anyOf)) {
|
|
272
|
-
expandOneOf(spec, name, schema, refs, "anyOf");
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
function expandOneOf(spec, name, schema, refs, kind) {
|
|
278
|
-
const varients = schema["x-varients"];
|
|
279
|
-
if (!varients || varients.length === 0) {
|
|
280
|
-
console.warn(
|
|
281
|
-
`No varients found for ${name}. This might be an error in the OpenAPI spec.`
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
varients.forEach((varient) => {
|
|
285
|
-
const varientSchema = schema[kind][varient.position];
|
|
286
|
-
if (isRef(varientSchema)) return;
|
|
287
|
-
const refName = findUniqueSchemaName(
|
|
288
|
-
spec,
|
|
289
|
-
pascalcase(`${name} ${varient.name}`),
|
|
290
|
-
["Varient"]
|
|
291
|
-
);
|
|
292
|
-
if (varientSchema.type === "object") {
|
|
293
|
-
spec.components.schemas[refName] = varientSchema;
|
|
294
|
-
expandSpec(spec, { [refName]: varientSchema }, refs);
|
|
295
|
-
schema[kind][varient.position] = {
|
|
296
|
-
$ref: `#/components/schemas/${refName}`
|
|
297
|
-
};
|
|
298
|
-
} else {
|
|
299
|
-
expandSpec(spec, { [refName]: varientSchema }, refs);
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
function coerceTypes(schema, excludeNull = true) {
|
|
304
|
-
const types = Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : [];
|
|
305
|
-
if (excludeNull) {
|
|
306
|
-
return types.filter((type) => type !== "null");
|
|
307
|
-
}
|
|
308
|
-
return types;
|
|
309
|
-
}
|
|
310
|
-
export {
|
|
311
|
-
coerceTypes,
|
|
312
|
-
expandSpec,
|
|
313
|
-
fixSpec
|
|
314
|
-
};
|
|
315
|
-
//# sourceMappingURL=tune.js.map
|