@depup/openapi-typescript 7.13.0-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1162 -0
- package/CONTRIBUTING.md +149 -0
- package/LICENSE +21 -0
- package/README.md +32 -0
- package/bin/cli.js +297 -0
- package/changes.json +14 -0
- package/dist/index.cjs +152 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +517 -0
- package/dist/index.d.mts +515 -0
- package/dist/index.d.ts +517 -0
- package/dist/index.mjs +85 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/redoc.cjs +129 -0
- package/dist/lib/redoc.cjs.map +1 -0
- package/dist/lib/redoc.mjs +122 -0
- package/dist/lib/redoc.mjs.map +1 -0
- package/dist/lib/ts.cjs +470 -0
- package/dist/lib/ts.cjs.map +1 -0
- package/dist/lib/ts.mjs +431 -0
- package/dist/lib/ts.mjs.map +1 -0
- package/dist/lib/utils.cjs +295 -0
- package/dist/lib/utils.cjs.map +1 -0
- package/dist/lib/utils.mjs +278 -0
- package/dist/lib/utils.mjs.map +1 -0
- package/dist/transform/components-object.cjs +150 -0
- package/dist/transform/components-object.cjs.map +1 -0
- package/dist/transform/components-object.mjs +127 -0
- package/dist/transform/components-object.mjs.map +1 -0
- package/dist/transform/header-object.cjs +48 -0
- package/dist/transform/header-object.cjs.map +1 -0
- package/dist/transform/header-object.mjs +42 -0
- package/dist/transform/header-object.mjs.map +1 -0
- package/dist/transform/index.cjs +124 -0
- package/dist/transform/index.cjs.map +1 -0
- package/dist/transform/index.mjs +118 -0
- package/dist/transform/index.mjs.map +1 -0
- package/dist/transform/media-type-object.cjs +14 -0
- package/dist/transform/media-type-object.cjs.map +1 -0
- package/dist/transform/media-type-object.mjs +12 -0
- package/dist/transform/media-type-object.mjs.map +1 -0
- package/dist/transform/operation-object.cjs +105 -0
- package/dist/transform/operation-object.cjs.map +1 -0
- package/dist/transform/operation-object.mjs +96 -0
- package/dist/transform/operation-object.mjs.map +1 -0
- package/dist/transform/parameter-object.cjs +11 -0
- package/dist/transform/parameter-object.cjs.map +1 -0
- package/dist/transform/parameter-object.mjs +9 -0
- package/dist/transform/parameter-object.mjs.map +1 -0
- package/dist/transform/parameters-array.cjs +120 -0
- package/dist/transform/parameters-array.cjs.map +1 -0
- package/dist/transform/parameters-array.mjs +114 -0
- package/dist/transform/parameters-array.mjs.map +1 -0
- package/dist/transform/path-item-object.cjs +84 -0
- package/dist/transform/path-item-object.cjs.map +1 -0
- package/dist/transform/path-item-object.mjs +78 -0
- package/dist/transform/path-item-object.mjs.map +1 -0
- package/dist/transform/paths-enum.cjs +35 -0
- package/dist/transform/paths-enum.cjs.map +1 -0
- package/dist/transform/paths-enum.mjs +33 -0
- package/dist/transform/paths-enum.mjs.map +1 -0
- package/dist/transform/paths-object.cjs +134 -0
- package/dist/transform/paths-object.cjs.map +1 -0
- package/dist/transform/paths-object.mjs +128 -0
- package/dist/transform/paths-object.mjs.map +1 -0
- package/dist/transform/request-body-object.cjs +68 -0
- package/dist/transform/request-body-object.cjs.map +1 -0
- package/dist/transform/request-body-object.mjs +62 -0
- package/dist/transform/request-body-object.mjs.map +1 -0
- package/dist/transform/response-object.cjs +123 -0
- package/dist/transform/response-object.cjs.map +1 -0
- package/dist/transform/response-object.mjs +117 -0
- package/dist/transform/response-object.mjs.map +1 -0
- package/dist/transform/responses-object.cjs +36 -0
- package/dist/transform/responses-object.cjs.map +1 -0
- package/dist/transform/responses-object.mjs +30 -0
- package/dist/transform/responses-object.mjs.map +1 -0
- package/dist/transform/schema-object.cjs +502 -0
- package/dist/transform/schema-object.cjs.map +1 -0
- package/dist/transform/schema-object.mjs +493 -0
- package/dist/transform/schema-object.mjs.map +1 -0
- package/dist/transform/webhooks-object.cjs +37 -0
- package/dist/transform/webhooks-object.cjs.map +1 -0
- package/dist/transform/webhooks-object.mjs +31 -0
- package/dist/transform/webhooks-object.mjs.map +1 -0
- package/package.json +102 -0
- package/src/index.ts +108 -0
- package/src/lib/redoc.ts +164 -0
- package/src/lib/ts.ts +616 -0
- package/src/lib/utils.ts +394 -0
- package/src/transform/components-object.ts +161 -0
- package/src/transform/header-object.ts +45 -0
- package/src/transform/index.ts +116 -0
- package/src/transform/media-type-object.ts +18 -0
- package/src/transform/operation-object.ts +104 -0
- package/src/transform/parameter-object.ts +15 -0
- package/src/transform/parameters-array.ts +129 -0
- package/src/transform/path-item-object.ts +102 -0
- package/src/transform/paths-enum.ts +43 -0
- package/src/transform/paths-object.ts +134 -0
- package/src/transform/request-body-object.ts +59 -0
- package/src/transform/response-object.ts +112 -0
- package/src/transform/responses-object.ts +36 -0
- package/src/transform/schema-object.ts +737 -0
- package/src/transform/webhooks-object.ts +27 -0
- package/src/types.ts +735 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { tsModifiers, tsPropertyIndex } from '../lib/ts.mjs';
|
|
3
|
+
import { getEntries, createRef } from '../lib/utils.mjs';
|
|
4
|
+
import transformPathItemObject from './path-item-object.mjs';
|
|
5
|
+
|
|
6
|
+
function transformWebhooksObject(webhooksObject, options) {
|
|
7
|
+
const type = [];
|
|
8
|
+
for (const [name, pathItemObject] of getEntries(webhooksObject, options)) {
|
|
9
|
+
type.push(
|
|
10
|
+
ts.factory.createPropertySignature(
|
|
11
|
+
/* modifiers */
|
|
12
|
+
tsModifiers({
|
|
13
|
+
readonly: options.immutable
|
|
14
|
+
}),
|
|
15
|
+
/* name */
|
|
16
|
+
tsPropertyIndex(name),
|
|
17
|
+
/* questionToken */
|
|
18
|
+
void 0,
|
|
19
|
+
/* type */
|
|
20
|
+
transformPathItemObject(pathItemObject, {
|
|
21
|
+
path: createRef(["webhooks", name]),
|
|
22
|
+
ctx: options
|
|
23
|
+
})
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return ts.factory.createTypeLiteralNode(type);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { transformWebhooksObject as default };
|
|
31
|
+
//# sourceMappingURL=webhooks-object.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks-object.mjs","sources":["../../src/transform/webhooks-object.ts"],"sourcesContent":["import ts from \"typescript\";\nimport { tsModifiers, tsPropertyIndex } from \"../lib/ts.js\";\nimport { createRef, getEntries } from \"../lib/utils.js\";\nimport type { GlobalContext, WebhooksObject } from \"../types.js\";\nimport transformPathItemObject from \"./path-item-object.js\";\n\nexport default function transformWebhooksObject(webhooksObject: WebhooksObject, options: GlobalContext): ts.TypeNode {\n const type: ts.TypeElement[] = [];\n\n for (const [name, pathItemObject] of getEntries(webhooksObject, options)) {\n type.push(\n ts.factory.createPropertySignature(\n /* modifiers */ tsModifiers({\n readonly: options.immutable,\n }),\n /* name */ tsPropertyIndex(name),\n /* questionToken */ undefined,\n /* type */ transformPathItemObject(pathItemObject, {\n path: createRef([\"webhooks\", name]),\n ctx: options,\n }),\n ),\n );\n }\n\n return ts.factory.createTypeLiteralNode(type);\n}\n"],"names":[],"mappings":";;;;;AAMA,SAAwB,uBAAA,CAAwB,gBAAgC,OAAA,EAAqC;AACnH,EAAA,MAAM,OAAyB,EAAC;AAEhC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,cAAc,KAAK,UAAA,CAAW,cAAA,EAAgB,OAAO,CAAA,EAAG;AACxE,IAAA,IAAA,CAAK,IAAA;AAAA,MACH,GAAG,OAAA,CAAQ,uBAAA;AAAA;AAAA,QACW,WAAA,CAAY;AAAA,UAC9B,UAAU,OAAA,CAAQ;AAAA,SACnB,CAAA;AAAA;AAAA,QACmB,gBAAgB,IAAI,CAAA;AAAA;AAAA,QACpB,MAAA;AAAA;AAAA,QACA,wBAAwB,cAAA,EAAgB;AAAA,UAC1D,IAAA,EAAM,SAAA,CAAU,CAAC,UAAA,EAAY,IAAI,CAAC,CAAA;AAAA,UAClC,GAAA,EAAK;AAAA,SACN;AAAA;AACH,KACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAA,CAAG,OAAA,CAAQ,qBAAA,CAAsB,IAAI,CAAA;AAC9C;;;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@depup/openapi-typescript",
|
|
3
|
+
"description": "Convert OpenAPI 3.0 & 3.1 schemas to TypeScript (with updated dependencies)",
|
|
4
|
+
"version": "7.13.0-depup.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Drew Powers",
|
|
7
|
+
"email": "drew@pow.rs"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"bin": {
|
|
11
|
+
"openapi-typescript": "bin/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.mjs",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./dist/index.mjs",
|
|
18
|
+
"require": "./dist/index.cjs",
|
|
19
|
+
"default": "./dist/index.mjs"
|
|
20
|
+
},
|
|
21
|
+
"./*.js": "./*.mjs",
|
|
22
|
+
"./*": "./*"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://openapi-ts.dev",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/openapi-ts/openapi-typescript",
|
|
28
|
+
"directory": "packages/openapi-typescript"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"openapi-typescript",
|
|
32
|
+
"depup",
|
|
33
|
+
"updated-dependencies",
|
|
34
|
+
"security",
|
|
35
|
+
"latest",
|
|
36
|
+
"patched",
|
|
37
|
+
"swagger",
|
|
38
|
+
"typescript",
|
|
39
|
+
"ts",
|
|
40
|
+
"dts",
|
|
41
|
+
"openapi",
|
|
42
|
+
"codegen",
|
|
43
|
+
"generation",
|
|
44
|
+
"openapi 3",
|
|
45
|
+
"node"
|
|
46
|
+
],
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/openapi-ts/openapi-typescript/issues"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"typescript": "^5.x"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@redocly/openapi-core": "^2.24.1",
|
|
55
|
+
"ansi-colors": "^4.1.3",
|
|
56
|
+
"change-case": "^5.4.4",
|
|
57
|
+
"parse-json": "^8.3.0",
|
|
58
|
+
"supports-color": "^10.2.2",
|
|
59
|
+
"yargs-parser": "^22.0.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/degit": "2.8.6",
|
|
63
|
+
"@types/js-yaml": "4.0.9",
|
|
64
|
+
"degit": "2.8.4",
|
|
65
|
+
"execa": "^9.6.1",
|
|
66
|
+
"strip-ansi": "7.1.2",
|
|
67
|
+
"typescript": "^5.9.3",
|
|
68
|
+
"vite-node": "5.3.0"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "unbuild",
|
|
72
|
+
"dev": "tsc -p tsconfig.build.json --watch",
|
|
73
|
+
"download:schemas": "vite-node ./scripts/download-schemas.ts",
|
|
74
|
+
"format": "biome format . --write",
|
|
75
|
+
"lint": "pnpm run lint:js && pnpm run lint:ts",
|
|
76
|
+
"lint:js": "biome check .",
|
|
77
|
+
"lint:ts": "tsc --noEmit",
|
|
78
|
+
"test": "pnpm run test:js && pnpm run test:examples && pnpm run test:exports",
|
|
79
|
+
"test:js": "vitest run",
|
|
80
|
+
"test:exports": "pnpm run build && attw --pack .",
|
|
81
|
+
"test:examples": "tsc -p tsconfig.examples.json --noEmit",
|
|
82
|
+
"update:examples": "pnpm run build && pnpm run download:schemas && vite-node ./scripts/update-examples.ts",
|
|
83
|
+
"version": "pnpm run build"
|
|
84
|
+
},
|
|
85
|
+
"depup": {
|
|
86
|
+
"changes": {
|
|
87
|
+
"@redocly/openapi-core": {
|
|
88
|
+
"from": "^1.34.6",
|
|
89
|
+
"to": "^2.24.1"
|
|
90
|
+
},
|
|
91
|
+
"yargs-parser": {
|
|
92
|
+
"from": "^21.1.1",
|
|
93
|
+
"to": "^22.0.0"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"depsUpdated": 2,
|
|
97
|
+
"originalPackage": "openapi-typescript",
|
|
98
|
+
"originalVersion": "7.13.0",
|
|
99
|
+
"processedAt": "2026-03-22T00:40:17.761Z",
|
|
100
|
+
"smokeTest": "failed"
|
|
101
|
+
}
|
|
102
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { performance } from "node:perf_hooks";
|
|
2
|
+
import type { Readable } from "node:stream";
|
|
3
|
+
import { createConfig } from "@redocly/openapi-core";
|
|
4
|
+
import type ts from "typescript";
|
|
5
|
+
import { validateAndBundle } from "./lib/redoc.js";
|
|
6
|
+
import { debug, resolveRef, scanDiscriminators } from "./lib/utils.js";
|
|
7
|
+
import transformSchema from "./transform/index.js";
|
|
8
|
+
import type { GlobalContext, OpenAPI3, OpenAPITSOptions } from "./types.js";
|
|
9
|
+
|
|
10
|
+
export * from "./lib/ts.js";
|
|
11
|
+
export * from "./lib/utils.js";
|
|
12
|
+
export { default as transformComponentsObject } from "./transform/components-object.js";
|
|
13
|
+
export { default as transformHeaderObject } from "./transform/header-object.js";
|
|
14
|
+
export { default as transformSchema } from "./transform/index.js";
|
|
15
|
+
export { default as transformMediaTypeObject } from "./transform/media-type-object.js";
|
|
16
|
+
export * from "./transform/operation-object.js";
|
|
17
|
+
export { default as transformOperationObject } from "./transform/operation-object.js";
|
|
18
|
+
export { default as transformParameterObject } from "./transform/parameter-object.js";
|
|
19
|
+
export * from "./transform/path-item-object.js";
|
|
20
|
+
export { default as transformPathItemObject } from "./transform/path-item-object.js";
|
|
21
|
+
export { default as transformPathsObject } from "./transform/paths-object.js";
|
|
22
|
+
export { default as transformRequestBodyObject } from "./transform/request-body-object.js";
|
|
23
|
+
export { default as transformResponseObject } from "./transform/response-object.js";
|
|
24
|
+
export { default as transformResponsesObject } from "./transform/responses-object.js";
|
|
25
|
+
export * from "./transform/schema-object.js";
|
|
26
|
+
export { default as transformSchemaObject } from "./transform/schema-object.js";
|
|
27
|
+
export * from "./types.js";
|
|
28
|
+
|
|
29
|
+
export const COMMENT_HEADER = `/**
|
|
30
|
+
* This file was auto-generated by openapi-typescript.
|
|
31
|
+
* Do not make direct changes to the file.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Convert an OpenAPI schema to TypesScript AST
|
|
38
|
+
* @param {string|URL|object|Readable} source OpenAPI schema source:
|
|
39
|
+
* - YAML: string
|
|
40
|
+
* - JSON: parsed object
|
|
41
|
+
* - URL: URL to a YAML or JSON file (local or remote)
|
|
42
|
+
* - Readable: Readable stream of YAML or JSON
|
|
43
|
+
*/
|
|
44
|
+
export default async function openapiTS(
|
|
45
|
+
source: string | URL | OpenAPI3 | Buffer | Readable,
|
|
46
|
+
options: OpenAPITSOptions = {} as Partial<OpenAPITSOptions>,
|
|
47
|
+
): Promise<ts.Node[]> {
|
|
48
|
+
if (!source) {
|
|
49
|
+
throw new Error("Empty schema. Please specify a URL, file path, or Redocly Config");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const redoc =
|
|
53
|
+
options.redocly ??
|
|
54
|
+
(await createConfig(
|
|
55
|
+
{
|
|
56
|
+
rules: {
|
|
57
|
+
"operation-operationId-unique": { severity: "error" }, // throw error on duplicate operationIDs
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{ extends: ["minimal"] },
|
|
61
|
+
));
|
|
62
|
+
|
|
63
|
+
const schema = await validateAndBundle(source, {
|
|
64
|
+
redoc,
|
|
65
|
+
cwd: options.cwd instanceof URL ? options.cwd : new URL(`file://${options.cwd ?? process.cwd()}/`),
|
|
66
|
+
silent: options.silent ?? false,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const ctx: GlobalContext = {
|
|
70
|
+
additionalProperties: options.additionalProperties ?? false,
|
|
71
|
+
alphabetize: options.alphabetize ?? false,
|
|
72
|
+
arrayLength: options.arrayLength ?? false,
|
|
73
|
+
defaultNonNullable: options.defaultNonNullable ?? true,
|
|
74
|
+
discriminators: scanDiscriminators(schema, options),
|
|
75
|
+
emptyObjectsUnknown: options.emptyObjectsUnknown ?? false,
|
|
76
|
+
enum: options.enum ?? false,
|
|
77
|
+
enumValues: options.enumValues ?? false,
|
|
78
|
+
conditionalEnums: options.conditionalEnums ?? false,
|
|
79
|
+
dedupeEnums: options.dedupeEnums ?? false,
|
|
80
|
+
excludeDeprecated: options.excludeDeprecated ?? false,
|
|
81
|
+
exportType: options.exportType ?? false,
|
|
82
|
+
immutable: options.immutable ?? false,
|
|
83
|
+
rootTypes: options.rootTypes ?? false,
|
|
84
|
+
rootTypesNoSchemaPrefix: options.rootTypesNoSchemaPrefix ?? false,
|
|
85
|
+
rootTypesKeepCasing: options.rootTypesKeepCasing ?? false,
|
|
86
|
+
injectFooter: [],
|
|
87
|
+
pathParamsAsTypes: options.pathParamsAsTypes ?? false,
|
|
88
|
+
postTransform: typeof options.postTransform === "function" ? options.postTransform : undefined,
|
|
89
|
+
propertiesRequiredByDefault: options.propertiesRequiredByDefault ?? false,
|
|
90
|
+
redoc,
|
|
91
|
+
silent: options.silent ?? false,
|
|
92
|
+
inject: options.inject ?? undefined,
|
|
93
|
+
transform: typeof options.transform === "function" ? options.transform : undefined,
|
|
94
|
+
transformProperty: typeof options.transformProperty === "function" ? options.transformProperty : undefined,
|
|
95
|
+
makePathsEnum: options.makePathsEnum ?? false,
|
|
96
|
+
generatePathParams: options.generatePathParams ?? false,
|
|
97
|
+
readWriteMarkers: options.readWriteMarkers ?? false,
|
|
98
|
+
resolve($ref) {
|
|
99
|
+
return resolveRef(schema, $ref, { silent: options.silent ?? false });
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const transformT = performance.now();
|
|
104
|
+
const result = transformSchema(schema, ctx);
|
|
105
|
+
debug("Completed AST transformation for entire document", "ts", performance.now() - transformT);
|
|
106
|
+
|
|
107
|
+
return result;
|
|
108
|
+
}
|
package/src/lib/redoc.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { performance } from "node:perf_hooks";
|
|
2
|
+
import { Readable } from "node:stream";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import {
|
|
5
|
+
BaseResolver,
|
|
6
|
+
bundle,
|
|
7
|
+
type Document,
|
|
8
|
+
lintDocument,
|
|
9
|
+
makeDocumentFromString,
|
|
10
|
+
type NormalizedProblem,
|
|
11
|
+
type Config as RedoclyConfig,
|
|
12
|
+
Source,
|
|
13
|
+
} from "@redocly/openapi-core";
|
|
14
|
+
import parseJson from "parse-json";
|
|
15
|
+
import type { OpenAPI3 } from "../types.js";
|
|
16
|
+
import { debug, error, warn } from "./utils.js";
|
|
17
|
+
|
|
18
|
+
export interface ValidateAndBundleOptions {
|
|
19
|
+
redoc: RedoclyConfig;
|
|
20
|
+
silent: boolean;
|
|
21
|
+
cwd?: URL;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface ParseSchemaOptions {
|
|
25
|
+
absoluteRef: string;
|
|
26
|
+
resolver: BaseResolver;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function parseSchema(schema: unknown, { absoluteRef, resolver }: ParseSchemaOptions): Promise<Document> {
|
|
30
|
+
if (!schema) {
|
|
31
|
+
throw new Error("Can’t parse empty schema");
|
|
32
|
+
}
|
|
33
|
+
if (schema instanceof URL) {
|
|
34
|
+
const result = await resolver.resolveDocument(null, absoluteRef, true);
|
|
35
|
+
if ("parsed" in result) {
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
throw result.originalError;
|
|
39
|
+
}
|
|
40
|
+
if (schema instanceof Readable) {
|
|
41
|
+
const contents = await new Promise<string>((resolve) => {
|
|
42
|
+
schema.resume();
|
|
43
|
+
schema.setEncoding("utf8");
|
|
44
|
+
let content = "";
|
|
45
|
+
schema.on("data", (chunk: string) => {
|
|
46
|
+
content += chunk;
|
|
47
|
+
});
|
|
48
|
+
schema.on("end", () => {
|
|
49
|
+
resolve(content.trim());
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
return parseSchema(contents, { absoluteRef, resolver });
|
|
53
|
+
}
|
|
54
|
+
if (schema instanceof Buffer) {
|
|
55
|
+
return parseSchema(schema.toString("utf8"), { absoluteRef, resolver });
|
|
56
|
+
}
|
|
57
|
+
if (typeof schema === "string") {
|
|
58
|
+
// URL
|
|
59
|
+
if (schema.startsWith("http://") || schema.startsWith("https://") || schema.startsWith("file://")) {
|
|
60
|
+
const url = new URL(schema);
|
|
61
|
+
return parseSchema(url, {
|
|
62
|
+
absoluteRef: url.protocol === "file:" ? fileURLToPath(url) : url.href,
|
|
63
|
+
resolver,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// JSON
|
|
67
|
+
if (schema[0] === "{") {
|
|
68
|
+
return {
|
|
69
|
+
source: new Source(absoluteRef, schema, "application/json"),
|
|
70
|
+
parsed: parseJson(schema),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// YAML
|
|
74
|
+
return makeDocumentFromString(schema, absoluteRef);
|
|
75
|
+
}
|
|
76
|
+
if (typeof schema === "object" && !Array.isArray(schema)) {
|
|
77
|
+
return {
|
|
78
|
+
source: new Source(absoluteRef, JSON.stringify(schema), "application/json"),
|
|
79
|
+
parsed: schema,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
throw new Error(`Expected string, object, or Buffer. Got ${Array.isArray(schema) ? "Array" : typeof schema}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function _processProblems(problems: NormalizedProblem[], options: { silent: boolean }) {
|
|
86
|
+
if (problems.length) {
|
|
87
|
+
let errorMessage: string | undefined;
|
|
88
|
+
for (const problem of problems) {
|
|
89
|
+
const problemLocation = problem.location?.[0].pointer;
|
|
90
|
+
const problemMessage = problemLocation ? `${problem.message} at ${problemLocation}` : problem.message;
|
|
91
|
+
if (problem.severity === "error") {
|
|
92
|
+
errorMessage = problemMessage;
|
|
93
|
+
error(problemMessage);
|
|
94
|
+
} else {
|
|
95
|
+
warn(problemMessage, options.silent);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (errorMessage) {
|
|
99
|
+
throw new Error(errorMessage);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Validate an OpenAPI schema and flatten into a single schema using Redocly CLI
|
|
106
|
+
*/
|
|
107
|
+
export async function validateAndBundle(
|
|
108
|
+
source: string | URL | OpenAPI3 | Readable | Buffer,
|
|
109
|
+
options: ValidateAndBundleOptions,
|
|
110
|
+
) {
|
|
111
|
+
const redocConfigT = performance.now();
|
|
112
|
+
debug("Loaded Redoc config", "redoc", performance.now() - redocConfigT);
|
|
113
|
+
const redocParseT = performance.now();
|
|
114
|
+
let absoluteRef = fileURLToPath(new URL(options?.cwd ?? `file://${process.cwd()}/`));
|
|
115
|
+
if (source instanceof URL) {
|
|
116
|
+
absoluteRef = source.protocol === "file:" ? fileURLToPath(source) : source.href;
|
|
117
|
+
}
|
|
118
|
+
const resolver = new BaseResolver(options.redoc.resolve);
|
|
119
|
+
const document = await parseSchema(source, {
|
|
120
|
+
absoluteRef,
|
|
121
|
+
resolver,
|
|
122
|
+
});
|
|
123
|
+
debug("Parsed schema", "redoc", performance.now() - redocParseT);
|
|
124
|
+
|
|
125
|
+
// 1. check for OpenAPI 3 or greater
|
|
126
|
+
const openapiVersion = Number.parseFloat(document.parsed.openapi);
|
|
127
|
+
if (
|
|
128
|
+
document.parsed.swagger ||
|
|
129
|
+
!document.parsed.openapi ||
|
|
130
|
+
Number.isNaN(openapiVersion) ||
|
|
131
|
+
openapiVersion < 3 ||
|
|
132
|
+
openapiVersion >= 4
|
|
133
|
+
) {
|
|
134
|
+
if (document.parsed.swagger) {
|
|
135
|
+
throw new Error("Unsupported Swagger version: 2.x. Use OpenAPI 3.x instead.");
|
|
136
|
+
}
|
|
137
|
+
if (document.parsed.openapi || openapiVersion < 3 || openapiVersion >= 4) {
|
|
138
|
+
throw new Error(`Unsupported OpenAPI version: ${document.parsed.openapi}`);
|
|
139
|
+
}
|
|
140
|
+
throw new Error("Unsupported schema format, expected `openapi: 3.x`");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 2. lint
|
|
144
|
+
const redocLintT = performance.now();
|
|
145
|
+
const problems = await lintDocument({
|
|
146
|
+
document,
|
|
147
|
+
config: options.redoc.styleguide,
|
|
148
|
+
externalRefResolver: resolver,
|
|
149
|
+
});
|
|
150
|
+
_processProblems(problems, options);
|
|
151
|
+
debug("Linted schema", "lint", performance.now() - redocLintT);
|
|
152
|
+
|
|
153
|
+
// 3. bundle
|
|
154
|
+
const redocBundleT = performance.now();
|
|
155
|
+
const bundled = await bundle({
|
|
156
|
+
config: options.redoc,
|
|
157
|
+
dereference: false,
|
|
158
|
+
doc: document,
|
|
159
|
+
});
|
|
160
|
+
_processProblems(bundled.problems, options);
|
|
161
|
+
debug("Bundled schema", "bundle", performance.now() - redocBundleT);
|
|
162
|
+
|
|
163
|
+
return bundled.bundle.parsed;
|
|
164
|
+
}
|