UNPKG

openapi-typescript

Version:

Convert OpenAPI 3.0 & 3.1 schemas to TypeScript

1,401 lines (1,387 loc) 81.9 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // ../../node_modules/.pnpm/ansi-colors@4.1.3/node_modules/ansi-colors/symbols.js var require_symbols = __commonJS({ "../../node_modules/.pnpm/ansi-colors@4.1.3/node_modules/ansi-colors/symbols.js"(exports, module2) { "use strict"; var isHyper = typeof process !== "undefined" && process.env.TERM_PROGRAM === "Hyper"; var isWindows = typeof process !== "undefined" && process.platform === "win32"; var isLinux = typeof process !== "undefined" && process.platform === "linux"; var common = { ballotDisabled: "\u2612", ballotOff: "\u2610", ballotOn: "\u2611", bullet: "\u2022", bulletWhite: "\u25E6", fullBlock: "\u2588", heart: "\u2764", identicalTo: "\u2261", line: "\u2500", mark: "\u203B", middot: "\xB7", minus: "\uFF0D", multiplication: "\xD7", obelus: "\xF7", pencilDownRight: "\u270E", pencilRight: "\u270F", pencilUpRight: "\u2710", percent: "%", pilcrow2: "\u2761", pilcrow: "\xB6", plusMinus: "\xB1", question: "?", section: "\xA7", starsOff: "\u2606", starsOn: "\u2605", upDownArrow: "\u2195" }; var windows = Object.assign({}, common, { check: "\u221A", cross: "\xD7", ellipsisLarge: "...", ellipsis: "...", info: "i", questionSmall: "?", pointer: ">", pointerSmall: "\xBB", radioOff: "( )", radioOn: "(*)", warning: "\u203C" }); var other = Object.assign({}, common, { ballotCross: "\u2718", check: "\u2714", cross: "\u2716", ellipsisLarge: "\u22EF", ellipsis: "\u2026", info: "\u2139", questionFull: "\uFF1F", questionSmall: "\uFE56", pointer: isLinux ? "\u25B8" : "\u276F", pointerSmall: isLinux ? "\u2023" : "\u203A", radioOff: "\u25EF", radioOn: "\u25C9", warning: "\u26A0" }); module2.exports = isWindows && !isHyper ? windows : other; Reflect.defineProperty(module2.exports, "common", { enumerable: false, value: common }); Reflect.defineProperty(module2.exports, "windows", { enumerable: false, value: windows }); Reflect.defineProperty(module2.exports, "other", { enumerable: false, value: other }); } }); // ../../node_modules/.pnpm/ansi-colors@4.1.3/node_modules/ansi-colors/index.js var require_ansi_colors = __commonJS({ "../../node_modules/.pnpm/ansi-colors@4.1.3/node_modules/ansi-colors/index.js"(exports, module2) { "use strict"; var isObject = (val) => val !== null && typeof val === "object" && !Array.isArray(val); var ANSI_REGEX = /[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g; var hasColor = () => { if (typeof process !== "undefined") { return process.env.FORCE_COLOR !== "0"; } return false; }; var create = () => { const colors = { enabled: hasColor(), visible: true, styles: {}, keys: {} }; const ansi = (style2) => { let open = style2.open = `\x1B[${style2.codes[0]}m`; let close = style2.close = `\x1B[${style2.codes[1]}m`; let regex = style2.regex = new RegExp(`\\u001b\\[${style2.codes[1]}m`, "g"); style2.wrap = (input, newline) => { if (input.includes(close)) input = input.replace(regex, close + open); let output = open + input + close; return newline ? output.replace(/\r*\n/g, `${close}$&${open}`) : output; }; return style2; }; const wrap = (style2, input, newline) => { return typeof style2 === "function" ? style2(input) : style2.wrap(input, newline); }; const style = (input, stack) => { if (input === "" || input == null) return ""; if (colors.enabled === false) return input; if (colors.visible === false) return ""; let str = "" + input; let nl = str.includes("\n"); let n = stack.length; if (n > 0 && stack.includes("unstyle")) { stack = [.../* @__PURE__ */ new Set(["unstyle", ...stack])].reverse(); } while (n-- > 0) str = wrap(colors.styles[stack[n]], str, nl); return str; }; const define = (name, codes, type) => { colors.styles[name] = ansi({ name, codes }); let keys = colors.keys[type] || (colors.keys[type] = []); keys.push(name); Reflect.defineProperty(colors, name, { configurable: true, enumerable: true, set(value) { colors.alias(name, value); }, get() { let color = (input) => style(input, color.stack); Reflect.setPrototypeOf(color, colors); color.stack = this.stack ? this.stack.concat(name) : [name]; return color; } }); }; define("reset", [0, 0], "modifier"); define("bold", [1, 22], "modifier"); define("dim", [2, 22], "modifier"); define("italic", [3, 23], "modifier"); define("underline", [4, 24], "modifier"); define("inverse", [7, 27], "modifier"); define("hidden", [8, 28], "modifier"); define("strikethrough", [9, 29], "modifier"); define("black", [30, 39], "color"); define("red", [31, 39], "color"); define("green", [32, 39], "color"); define("yellow", [33, 39], "color"); define("blue", [34, 39], "color"); define("magenta", [35, 39], "color"); define("cyan", [36, 39], "color"); define("white", [37, 39], "color"); define("gray", [90, 39], "color"); define("grey", [90, 39], "color"); define("bgBlack", [40, 49], "bg"); define("bgRed", [41, 49], "bg"); define("bgGreen", [42, 49], "bg"); define("bgYellow", [43, 49], "bg"); define("bgBlue", [44, 49], "bg"); define("bgMagenta", [45, 49], "bg"); define("bgCyan", [46, 49], "bg"); define("bgWhite", [47, 49], "bg"); define("blackBright", [90, 39], "bright"); define("redBright", [91, 39], "bright"); define("greenBright", [92, 39], "bright"); define("yellowBright", [93, 39], "bright"); define("blueBright", [94, 39], "bright"); define("magentaBright", [95, 39], "bright"); define("cyanBright", [96, 39], "bright"); define("whiteBright", [97, 39], "bright"); define("bgBlackBright", [100, 49], "bgBright"); define("bgRedBright", [101, 49], "bgBright"); define("bgGreenBright", [102, 49], "bgBright"); define("bgYellowBright", [103, 49], "bgBright"); define("bgBlueBright", [104, 49], "bgBright"); define("bgMagentaBright", [105, 49], "bgBright"); define("bgCyanBright", [106, 49], "bgBright"); define("bgWhiteBright", [107, 49], "bgBright"); colors.ansiRegex = ANSI_REGEX; colors.hasColor = colors.hasAnsi = (str) => { colors.ansiRegex.lastIndex = 0; return typeof str === "string" && str !== "" && colors.ansiRegex.test(str); }; colors.alias = (name, color) => { let fn = typeof color === "string" ? colors[color] : color; if (typeof fn !== "function") { throw new TypeError("Expected alias to be the name of an existing color (string) or a function"); } if (!fn.stack) { Reflect.defineProperty(fn, "name", { value: name }); colors.styles[name] = fn; fn.stack = [name]; } Reflect.defineProperty(colors, name, { configurable: true, enumerable: true, set(value) { colors.alias(name, value); }, get() { let color2 = (input) => style(input, color2.stack); Reflect.setPrototypeOf(color2, colors); color2.stack = this.stack ? this.stack.concat(fn.stack) : fn.stack; return color2; } }); }; colors.theme = (custom) => { if (!isObject(custom)) throw new TypeError("Expected theme to be an object"); for (let name of Object.keys(custom)) { colors.alias(name, custom[name]); } return colors; }; colors.alias("unstyle", (str) => { if (typeof str === "string" && str !== "") { colors.ansiRegex.lastIndex = 0; return str.replace(colors.ansiRegex, ""); } return ""; }); colors.alias("noop", (str) => str); colors.none = colors.clear = colors.noop; colors.stripColor = colors.unstyle; colors.symbols = require_symbols(); colors.define = define; return colors; }; module2.exports = create(); module2.exports.create = create; } }); // src/index.ts var src_exports = {}; __export(src_exports, { BOOLEAN: () => BOOLEAN, COMMENT_HEADER: () => COMMENT_HEADER, FALSE: () => FALSE, JS_ENUM_INVALID_CHARS_RE: () => JS_ENUM_INVALID_CHARS_RE, JS_PROPERTY_INDEX_INVALID_CHARS_RE: () => JS_PROPERTY_INDEX_INVALID_CHARS_RE, JS_PROPERTY_INDEX_RE: () => JS_PROPERTY_INDEX_RE, NEVER: () => NEVER, NULL: () => NULL, NUMBER: () => NUMBER, QUESTION_TOKEN: () => QUESTION_TOKEN, STRING: () => STRING, TRUE: () => TRUE, UNDEFINED: () => UNDEFINED, UNKNOWN: () => UNKNOWN, addJSDocComment: () => addJSDocComment, astToString: () => astToString, c: () => import_ansi_colors.default, createDiscriminatorProperty: () => createDiscriminatorProperty, createRef: () => createRef, debug: () => debug, default: () => openapiTS, error: () => error, formatTime: () => formatTime, getEntries: () => getEntries, injectOperationObject: () => injectOperationObject, oapiRef: () => oapiRef, resolveRef: () => resolveRef, scanDiscriminators: () => scanDiscriminators, stringToAST: () => stringToAST, transformSchemaObjectWithComposition: () => transformSchemaObjectWithComposition, tsDedupe: () => tsDedupe, tsEnum: () => tsEnum, tsEnumMember: () => tsEnumMember, tsIntersection: () => tsIntersection, tsIsPrimitive: () => tsIsPrimitive, tsLiteral: () => tsLiteral, tsModifiers: () => tsModifiers, tsNullable: () => tsNullable, tsOmit: () => tsOmit, tsPropertyIndex: () => tsPropertyIndex, tsRecord: () => tsRecord, tsUnion: () => tsUnion, tsWithRequired: () => tsWithRequired, walk: () => walk, warn: () => warn }); module.exports = __toCommonJS(src_exports); var import_openapi_core2 = require("@redocly/openapi-core"); // src/lib/redoc.ts var import_openapi_core = require("@redocly/openapi-core"); var import_node_stream = require("stream"); var import_node_url = require("url"); // src/lib/utils.ts var import_ref_utils2 = require("@redocly/openapi-core/lib/ref-utils.js"); var import_ansi_colors = __toESM(require_ansi_colors(), 1); // ../../node_modules/.pnpm/supports-color@9.4.0/node_modules/supports-color/index.js var import_node_process = __toESM(require("process"), 1); var import_node_os = __toESM(require("os"), 1); var import_node_tty = __toESM(require("tty"), 1); function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) { const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--"; const position = argv.indexOf(prefix + flag); const terminatorPosition = argv.indexOf("--"); return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); } var { env } = import_node_process.default; var flagForceColor; if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) { flagForceColor = 0; } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) { flagForceColor = 1; } function envForceColor() { if ("FORCE_COLOR" in env) { if (env.FORCE_COLOR === "true") { return 1; } if (env.FORCE_COLOR === "false") { return 0; } return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); } } function translateLevel(level) { if (level === 0) { return false; } return { level, hasBasic: true, has256: level >= 2, has16m: level >= 3 }; } function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) { const noFlagForceColor = envForceColor(); if (noFlagForceColor !== void 0) { flagForceColor = noFlagForceColor; } const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; if (forceColor === 0) { return 0; } if (sniffFlags) { if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) { return 3; } if (hasFlag("color=256")) { return 2; } } if ("TF_BUILD" in env && "AGENT_NAME" in env) { return 1; } if (haveStream && !streamIsTTY && forceColor === void 0) { return 0; } const min = forceColor || 0; if (env.TERM === "dumb") { return min; } if (import_node_process.default.platform === "win32") { const osRelease = import_node_os.default.release().split("."); if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) { return Number(osRelease[2]) >= 14931 ? 3 : 2; } return 1; } if ("CI" in env) { if ("GITHUB_ACTIONS" in env || "GITEA_ACTIONS" in env) { return 3; } if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") { return 1; } return min; } if ("TEAMCITY_VERSION" in env) { return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; } if (env.COLORTERM === "truecolor") { return 3; } if (env.TERM === "xterm-kitty") { return 3; } if ("TERM_PROGRAM" in env) { const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10); switch (env.TERM_PROGRAM) { case "iTerm.app": { return version >= 3 ? 3 : 2; } case "Apple_Terminal": { return 2; } } } if (/-256(color)?$/i.test(env.TERM)) { return 2; } if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { return 1; } if ("COLORTERM" in env) { return 1; } return min; } function createSupportsColor(stream, options = {}) { const level = _supportsColor(stream, { streamIsTTY: stream && stream.isTTY, ...options }); return translateLevel(level); } var supportsColor = { stdout: createSupportsColor({ isTTY: import_node_tty.default.isatty(1) }), stderr: createSupportsColor({ isTTY: import_node_tty.default.isatty(2) }) }; var supports_color_default = supportsColor; // src/lib/utils.ts var import_typescript2 = __toESM(require("typescript"), 1); // src/lib/ts.ts var import_ref_utils = require("@redocly/openapi-core/lib/ref-utils.js"); var import_typescript = __toESM(require("typescript"), 1); var JS_PROPERTY_INDEX_RE = /^[A-Za-z_$][A-Za-z_$0-9]*$/; var JS_ENUM_INVALID_CHARS_RE = /[^A-Za-z_$0-9]+(.)?/g; var JS_PROPERTY_INDEX_INVALID_CHARS_RE = /[^A-Za-z_$0-9]+/g; var BOOLEAN = import_typescript.default.factory.createKeywordTypeNode( import_typescript.default.SyntaxKind.BooleanKeyword ); var FALSE = import_typescript.default.factory.createLiteralTypeNode(import_typescript.default.factory.createFalse()); var NEVER = import_typescript.default.factory.createKeywordTypeNode( import_typescript.default.SyntaxKind.NeverKeyword ); var NULL = import_typescript.default.factory.createLiteralTypeNode(import_typescript.default.factory.createNull()); var NUMBER = import_typescript.default.factory.createKeywordTypeNode( import_typescript.default.SyntaxKind.NumberKeyword ); var QUESTION_TOKEN = import_typescript.default.factory.createToken( import_typescript.default.SyntaxKind.QuestionToken ); var STRING = import_typescript.default.factory.createKeywordTypeNode( import_typescript.default.SyntaxKind.StringKeyword ); var TRUE = import_typescript.default.factory.createLiteralTypeNode(import_typescript.default.factory.createTrue()); var UNDEFINED = import_typescript.default.factory.createKeywordTypeNode( import_typescript.default.SyntaxKind.UndefinedKeyword ); var UNKNOWN = import_typescript.default.factory.createKeywordTypeNode( import_typescript.default.SyntaxKind.UnknownKeyword ); var LB_RE = /\r?\n/g; var COMMENT_RE = /\*\//g; function addJSDocComment(schemaObject, node) { if (!schemaObject || typeof schemaObject !== "object" || Array.isArray(schemaObject)) { return; } const output = []; if (schemaObject.title) { output.push(schemaObject.title.replace(LB_RE, "\n * ")); } if (schemaObject.summary) { output.push(schemaObject.summary.replace(LB_RE, "\n * ")); } if (schemaObject.format) { output.push(`Format: ${schemaObject.format}`); } if (schemaObject.deprecated) { output.push("@deprecated"); } const supportedJsDocTags = ["description", "default", "example"]; for (const field of supportedJsDocTags) { const allowEmptyString = field === "default" || field === "example"; if (schemaObject[field] === void 0) { continue; } if (schemaObject[field] === "" && !allowEmptyString) { continue; } const serialized = typeof schemaObject[field] === "object" ? JSON.stringify(schemaObject[field], null, 2) : schemaObject[field]; output.push(`@${field} ${String(serialized).replace(LB_RE, "\n * ")}`); } if ("const" in schemaObject) { output.push("@constant"); } if (schemaObject.enum) { let type = "unknown"; if (Array.isArray(schemaObject.type)) { type = schemaObject.type.join("|"); } else if (typeof schemaObject.type === "string") { type = schemaObject.type; } output.push(`@enum {${type}${schemaObject.nullable ? `|null` : ""}}`); } if (output.length) { let text = output.length === 1 ? `* ${output.join("\n")} ` : `* * ${output.join("\n * ")} `; text = text.replace(COMMENT_RE, "*\\/"); import_typescript.default.addSyntheticLeadingComment( /* node */ node, /* kind */ import_typescript.default.SyntaxKind.MultiLineCommentTrivia, // note: MultiLine just refers to a "/* */" comment /* text */ text, /* hasTrailingNewLine */ true ); } } function oapiRef(path) { const { pointer } = (0, import_ref_utils.parseRef)(path); if (pointer.length === 0) { throw new Error(`Error parsing $ref: ${path}. Is this a valid $ref?`); } let t = import_typescript.default.factory.createTypeReferenceNode( import_typescript.default.factory.createIdentifier(String(pointer[0])) ); if (pointer.length > 1) { for (let i = 1; i < pointer.length; i++) { t = import_typescript.default.factory.createIndexedAccessTypeNode( t, import_typescript.default.factory.createLiteralTypeNode( typeof pointer[i] === "number" ? import_typescript.default.factory.createNumericLiteral(pointer[i]) : import_typescript.default.factory.createStringLiteral(pointer[i]) ) ); } } return t; } function astToString(ast, options) { var _a, _b; const sourceFile = import_typescript.default.createSourceFile( (_a = options == null ? void 0 : options.fileName) != null ? _a : "openapi-ts.ts", (_b = options == null ? void 0 : options.sourceText) != null ? _b : "", import_typescript.default.ScriptTarget.ESNext, false, import_typescript.default.ScriptKind.TS ); sourceFile.statements = import_typescript.default.factory.createNodeArray( Array.isArray(ast) ? ast : [ast] ); const printer = import_typescript.default.createPrinter({ newLine: import_typescript.default.NewLineKind.LineFeed, removeComments: false, ...options == null ? void 0 : options.formatOptions }); return printer.printFile(sourceFile); } function stringToAST(source) { return import_typescript.default.createSourceFile( /* fileName */ "stringInput", /* sourceText */ source, /* languageVersion */ import_typescript.default.ScriptTarget.ESNext, /* setParentNodes */ void 0, /* scriptKind */ void 0 ).statements; } function tsDedupe(types) { var _a, _b; const encounteredTypes = /* @__PURE__ */ new Set(); const filteredTypes = []; for (const t of types) { if (!("text" in ((_a = t.literal) != null ? _a : t))) { const { kind } = (_b = t.literal) != null ? _b : t; if (encounteredTypes.has(kind)) { continue; } if (tsIsPrimitive(t)) { encounteredTypes.add(kind); } } filteredTypes.push(t); } return filteredTypes; } function tsEnum(name, members, metadata, options) { var _a, _b; let enumName = name.replace(JS_ENUM_INVALID_CHARS_RE, (c2) => { const last = c2[c2.length - 1]; return JS_PROPERTY_INDEX_INVALID_CHARS_RE.test(last) ? "" : last.toUpperCase(); }); if (Number(name[0]) >= 0) { enumName = `Value${name}`; } enumName = `${enumName[0].toUpperCase()}${enumName.substring(1)}`; return import_typescript.default.factory.createEnumDeclaration( /* modifiers */ options ? tsModifiers({ readonly: (_a = options.readonly) != null ? _a : false, export: (_b = options.export) != null ? _b : false }) : void 0, /* name */ enumName, /* members */ members.map( (value, i) => tsEnumMember(value, metadata == null ? void 0 : metadata[i]) ) ); } function tsEnumMember(value, metadata = {}) { var _a; let name = (_a = metadata.name) != null ? _a : String(value); if (!JS_PROPERTY_INDEX_RE.test(name)) { if (Number(name[0]) >= 0) { name = `Value${name}`.replace(".", "_"); } name = name.replace(JS_PROPERTY_INDEX_INVALID_CHARS_RE, "_"); } let member; if (typeof value === "number") { member = import_typescript.default.factory.createEnumMember( name, import_typescript.default.factory.createNumericLiteral(value) ); } else { member = import_typescript.default.factory.createEnumMember( name, import_typescript.default.factory.createStringLiteral(value) ); } if (metadata.description == void 0) { return member; } return import_typescript.default.addSyntheticLeadingComment( member, import_typescript.default.SyntaxKind.SingleLineCommentTrivia, " ".concat(metadata.description.trim()), true ); } function tsIntersection(types) { if (types.length === 0) { return NEVER; } if (types.length === 1) { return types[0]; } return import_typescript.default.factory.createIntersectionTypeNode(tsDedupe(types)); } function tsIsPrimitive(type) { if (!type) { return true; } return import_typescript.default.SyntaxKind[type.kind] === "BooleanKeyword" || import_typescript.default.SyntaxKind[type.kind] === "NeverKeyword" || import_typescript.default.SyntaxKind[type.kind] === "NullKeyword" || import_typescript.default.SyntaxKind[type.kind] === "NumberKeyword" || import_typescript.default.SyntaxKind[type.kind] === "StringKeyword" || import_typescript.default.SyntaxKind[type.kind] === "UndefinedKeyword" || "literal" in type && tsIsPrimitive(type.literal); } function tsLiteral(value) { if (typeof value === "string") { return import_typescript.default.factory.createLiteralTypeNode( import_typescript.default.factory.createStringLiteral(value) ); } if (typeof value === "number") { return import_typescript.default.factory.createLiteralTypeNode( import_typescript.default.factory.createNumericLiteral(value) ); } if (typeof value === "boolean") { return value === true ? TRUE : FALSE; } if (value === null) { return NULL; } if (Array.isArray(value)) { if (value.length === 0) { return import_typescript.default.factory.createArrayTypeNode(NEVER); } return import_typescript.default.factory.createTupleTypeNode( value.map((v) => tsLiteral(v)) ); } if (typeof value === "object") { const keys = []; for (const [k, v] of Object.entries(value)) { keys.push( import_typescript.default.factory.createPropertySignature( /* modifiers */ void 0, /* name */ tsPropertyIndex(k), /* questionToken */ void 0, /* type */ tsLiteral(v) ) ); } return keys.length ? import_typescript.default.factory.createTypeLiteralNode(keys) : tsRecord(STRING, NEVER); } return UNKNOWN; } function tsModifiers(modifiers) { const typeMods = []; if (modifiers.export) { typeMods.push(import_typescript.default.factory.createModifier(import_typescript.default.SyntaxKind.ExportKeyword)); } if (modifiers.readonly) { typeMods.push(import_typescript.default.factory.createModifier(import_typescript.default.SyntaxKind.ReadonlyKeyword)); } return typeMods; } function tsNullable(types) { return import_typescript.default.factory.createUnionTypeNode([...types, NULL]); } function tsOmit(type, keys) { return import_typescript.default.factory.createTypeReferenceNode( import_typescript.default.factory.createIdentifier("Omit"), [type, import_typescript.default.factory.createUnionTypeNode(keys.map((k) => tsLiteral(k)))] ); } function tsRecord(key, value) { return import_typescript.default.factory.createTypeReferenceNode( import_typescript.default.factory.createIdentifier("Record"), [key, value] ); } function tsPropertyIndex(index) { if (typeof index === "number" && !(index < 0) || typeof index === "string" && String(Number(index)) === index && index[0] !== "-") { return import_typescript.default.factory.createNumericLiteral(index); } return typeof index === "string" && JS_PROPERTY_INDEX_RE.test(index) ? import_typescript.default.factory.createIdentifier(index) : import_typescript.default.factory.createStringLiteral(String(index)); } function tsUnion(types) { if (types.length === 0) { return NEVER; } if (types.length === 1) { return types[0]; } return import_typescript.default.factory.createUnionTypeNode(tsDedupe(types)); } function tsWithRequired(type, keys, injectFooter) { if (keys.length === 0) { return type; } if (!injectFooter.some( (node) => { var _a; return import_typescript.default.isTypeAliasDeclaration(node) && ((_a = node == null ? void 0 : node.name) == null ? void 0 : _a.escapedText) === "WithRequired"; } )) { const helper = stringToAST( `type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };` )[0]; injectFooter.push(helper); } return import_typescript.default.factory.createTypeReferenceNode( import_typescript.default.factory.createIdentifier("WithRequired"), [type, tsUnion(keys.map((k) => tsLiteral(k)))] ); } // src/lib/utils.ts if (!supports_color_default.stdout || supports_color_default.stdout.hasBasic === false) { import_ansi_colors.default.enabled = false; } var DEBUG_GROUPS = { redoc: import_ansi_colors.default.cyanBright, lint: import_ansi_colors.default.yellowBright, bundle: import_ansi_colors.default.magentaBright, ts: import_ansi_colors.default.blueBright }; function createDiscriminatorProperty(discriminator, { path, readonly = false }) { let value = (0, import_ref_utils2.parseRef)(path).pointer.pop(); if (discriminator.mapping) { const matchedValue = Object.entries(discriminator.mapping).find( ([, v]) => !v.startsWith("#") && v === value || v.startsWith("#") && (0, import_ref_utils2.parseRef)(v).pointer.pop() === value ); if (matchedValue) { value = matchedValue[0]; } } return import_typescript2.default.factory.createPropertySignature( /* modifiers */ tsModifiers({ readonly }), /* name */ tsPropertyIndex(discriminator.propertyName), /* questionToken */ void 0, /* type */ tsLiteral(value) ); } function createRef(parts) { let pointer = "#"; for (const part of parts) { if (!part) { continue; } const maybeRef = (0, import_ref_utils2.parseRef)(String(part)).pointer; if (maybeRef.length) { for (const refPart of maybeRef) { pointer += `/${(0, import_ref_utils2.escapePointer)(refPart)}`; } } else { pointer += `/${(0, import_ref_utils2.escapePointer)(part)}`; } } return pointer; } function debug(msg, group, time) { if (process.env.DEBUG && (!group || process.env.DEBUG === "*" || process.env.DEBUG === "openapi-ts:*" || process.env.DEBUG.toLocaleLowerCase() === `openapi-ts:${group.toLocaleLowerCase()}`)) { const groupColor = group && DEBUG_GROUPS[group] || import_ansi_colors.default.whiteBright; const groupName = groupColor(`openapi-ts:${group != null ? group : "info"}`); let timeFormatted = ""; if (typeof time === "number") { timeFormatted = import_ansi_colors.default.green(` ${formatTime(time)} `); } console.debug(` ${import_ansi_colors.default.bold(groupName)}${timeFormatted}${msg}`); } } function error(msg) { console.error(import_ansi_colors.default.red(` \u2718 ${msg}`)); } function formatTime(t) { if (typeof t === "number") { if (t < 1e3) { return `${Math.round(10 * t) / 10}ms`; } else if (t < 6e4) { return `${Math.round(t / 100) / 10}s`; } return `${Math.round(t / 6e3) / 10}m`; } return t; } function getEntries(obj, options) { let entries = Object.entries(obj); if (options == null ? void 0 : options.alphabetize) { entries.sort(([a], [b]) => a.localeCompare(b, "en-us", { numeric: true })); } if (options == null ? void 0 : options.excludeDeprecated) { entries = entries.filter( ([, v]) => !(v && typeof v === "object" && "deprecated" in v && v.deprecated) ); } return entries; } function resolveRef(schema, $ref, { silent = false, visited = [] }) { const { pointer } = (0, import_ref_utils2.parseRef)($ref); if (!pointer.length) { return void 0; } let node = schema; for (const key of pointer) { if (node && typeof node === "object" && node[key]) { node = node[key]; } else { warn(`Could not resolve $ref "${$ref}"`, silent); return void 0; } } if (node && typeof node === "object" && node.$ref) { if (visited.includes(node.$ref)) { warn(`Could not resolve circular $ref "${$ref}"`, silent); return void 0; } return resolveRef(schema, node.$ref, { silent, visited: [...visited, node.$ref] }); } return node; } function scanDiscriminators(schema) { const discriminators = {}; walk(schema, (obj, path) => { var _a; if ((_a = obj == null ? void 0 : obj.discriminator) == null ? void 0 : _a.propertyName) { discriminators[createRef(path)] = obj.discriminator; } }); walk(schema, (obj, path) => { var _a; for (const key of ["oneOf", "anyOf", "allOf"]) { if (obj && Array.isArray(obj[key])) { for (const item of obj[key]) { if ("$ref" in item) { if (discriminators[item.$ref]) { discriminators[createRef(path)] = { ...discriminators[item.$ref] }; } } else if ((_a = item.discriminator) == null ? void 0 : _a.propertyName) { discriminators[createRef(path)] = { ...item.discriminator }; } } } } }); return discriminators; } function walk(obj, cb, path = []) { if (!obj || typeof obj !== "object") { return; } if (Array.isArray(obj)) { for (let i = 0; i < obj.length; i++) { walk(obj[i], cb, path.concat(i)); } return; } cb(obj, path); for (const k of Object.keys(obj)) { walk(obj[k], cb, path.concat(k)); } } function warn(msg, silent = false) { if (!silent) { console.warn(import_ansi_colors.default.yellow(` \u26A0 ${msg}`)); } } // src/lib/redoc.ts async function parseSchema(schema, { absoluteRef, resolver }) { if (!schema) { throw new Error(`Can\u2019t parse empty schema`); } if (schema instanceof URL) { const result = await resolver.resolveDocument(null, absoluteRef, true); if ("parsed" in result) { return result; } throw result.originalError; } if (schema instanceof import_node_stream.Readable) { const contents = await new Promise((resolve) => { schema.resume(); schema.setEncoding("utf8"); let content = ""; schema.on("data", (chunk) => { content += chunk; }); schema.on("end", () => { resolve(content.trim()); }); }); return parseSchema(contents, { absoluteRef, resolver }); } if (schema instanceof Buffer) { return parseSchema(schema.toString("utf8"), { absoluteRef, resolver }); } if (typeof schema === "string") { if (schema.startsWith("http://") || schema.startsWith("https://") || schema.startsWith("file://")) { const url = new URL(schema); return parseSchema(url, { absoluteRef: url.protocol === "file:" ? (0, import_node_url.fileURLToPath)(url) : url.href, resolver }); } if (schema[0] === "{") { return { source: new import_openapi_core.Source(absoluteRef, schema, "application/json"), parsed: JSON.parse(schema) }; } return (0, import_openapi_core.makeDocumentFromString)(schema, absoluteRef); } if (typeof schema === "object" && !Array.isArray(schema)) { return { source: new import_openapi_core.Source( absoluteRef, JSON.stringify(schema), "application/json" ), parsed: schema }; } throw new Error( `Expected string, object, or Buffer. Got ${Array.isArray(schema) ? "Array" : typeof schema}` ); } async function validateAndBundle(source, options) { var _a; const redocConfigT = performance.now(); debug("Loaded Redoc config", "redoc", performance.now() - redocConfigT); const redocParseT = performance.now(); let absoluteRef = (0, import_node_url.fileURLToPath)( new URL((_a = options == null ? void 0 : options.cwd) != null ? _a : `file://${process.cwd()}/`) ); if (source instanceof URL) { absoluteRef = source.protocol === "file:" ? (0, import_node_url.fileURLToPath)(source) : source.href; } const resolver = new import_openapi_core.BaseResolver(options.redoc.resolve); const document = await parseSchema(source, { absoluteRef, resolver }); debug("Parsed schema", "redoc", performance.now() - redocParseT); const openapiVersion = parseFloat(document.parsed.openapi); if (document.parsed.swagger || !document.parsed.openapi || Number.isNaN(openapiVersion) || openapiVersion < 3 || openapiVersion >= 4) { if (document.parsed.swagger) { throw new Error( "Unsupported Swagger version: 2.x. Use OpenAPI 3.x instead." ); } else if (document.parsed.openapi || openapiVersion < 3 || openapiVersion >= 4) { throw new Error( `Unsupported OpenAPI version: ${document.parsed.openapi}` ); } throw new Error("Unsupported schema format, expected `openapi: 3.x`"); } const redocLintT = performance.now(); const problems = await (0, import_openapi_core.lintDocument)({ document, config: options.redoc.styleguide, externalRefResolver: resolver }); if (problems.length) { let errorMessage = void 0; for (const problem of problems) { if (problem.severity === "error") { errorMessage = problem.message; error(problem.message); } else { warn(problem.message, options.silent); } } if (errorMessage) { throw new Error(errorMessage); } } debug("Linted schema", "lint", performance.now() - redocLintT); const redocBundleT = performance.now(); const bundled = await (0, import_openapi_core.bundle)({ config: options.redoc, dereference: false, doc: document }); if (bundled.problems.length) { let errorMessage = void 0; for (const problem of bundled.problems) { if (problem.severity === "error") { errorMessage = problem.message; error(problem.message); throw new Error(problem.message); } else { warn(problem.message, options.silent); } } if (errorMessage) { throw new Error(errorMessage); } } debug("Bundled schema", "bundle", performance.now() - redocBundleT); return bundled.bundle.parsed; } // src/transform/index.ts var import_typescript14 = __toESM(require("typescript"), 1); // src/transform/components-object.ts var import_typescript11 = __toESM(require("typescript"), 1); // src/transform/header-object.ts var import_ref_utils4 = require("@redocly/openapi-core/lib/ref-utils.js"); var import_typescript4 = __toESM(require("typescript"), 1); // src/transform/schema-object.ts var import_ref_utils3 = require("@redocly/openapi-core/lib/ref-utils.js"); var import_typescript3 = __toESM(require("typescript"), 1); function transformSchemaObject(schemaObject, options) { const type = transformSchemaObjectWithComposition(schemaObject, options); if (typeof options.ctx.postTransform === "function") { const postTransformResult = options.ctx.postTransform(type, options); if (postTransformResult) { return postTransformResult; } } return type; } function transformSchemaObjectWithComposition(schemaObject, options) { var _a, _b, _c; if (!schemaObject) { return NEVER; } if (schemaObject === true) { return UNKNOWN; } if (Array.isArray(schemaObject) || typeof schemaObject !== "object") { throw new Error( `Expected SchemaObject, received ${Array.isArray(schemaObject) ? "Array" : typeof schemaObject}` ); } if ("$ref" in schemaObject) { return oapiRef(schemaObject.$ref); } if (schemaObject.const !== null && schemaObject.const !== void 0) { return tsLiteral(schemaObject.const); } if (Array.isArray(schemaObject.enum) && (!("type" in schemaObject) || schemaObject.type !== "object") && !("properties" in schemaObject) && !("additionalProperties" in schemaObject)) { if (options.ctx.enum && schemaObject.enum.every( (v) => typeof v === "string" || typeof v === "number" )) { let enumName = (0, import_ref_utils3.parseRef)((_a = options.path) != null ? _a : "").pointer.join("/"); enumName = enumName.replace("components/schemas", ""); const metadata = schemaObject.enum.map((_, i) => { var _a2, _b2; return { name: (_a2 = schemaObject["x-enum-varnames"]) == null ? void 0 : _a2[i], description: (_b2 = schemaObject["x-enum-descriptions"]) == null ? void 0 : _b2[i] }; }); const enumType = tsEnum( enumName, schemaObject.enum, metadata, { export: true, readonly: options.ctx.immutable } ); options.ctx.injectFooter.push(enumType); return import_typescript3.default.factory.createTypeReferenceNode(enumType.name); } return tsUnion(schemaObject.enum.map(tsLiteral)); } function collectCompositions(items, required) { const output = []; for (const item of items) { let itemType; if ("$ref" in item) { itemType = transformSchemaObject(item, options); const resolved = options.ctx.resolve(item.$ref); if (resolved && typeof resolved === "object" && "properties" in resolved) { const validRequired = (required != null ? required : []).filter( (key) => !!resolved.properties[key] ); if (validRequired.length) { itemType = tsWithRequired( itemType, validRequired, options.ctx.injectFooter ); } } } else { const itemRequired = [...required != null ? required : []]; if (typeof item === "object" && Array.isArray(item.required)) { itemRequired.push(...item.required); } itemType = transformSchemaObject( { ...item, required: itemRequired }, options ); } const discriminator = "$ref" in item && options.ctx.discriminators[item.$ref] || item.discriminator; if (discriminator) { output.push(tsOmit(itemType, [discriminator.propertyName])); } else { output.push(itemType); } } return output; } let finalType = void 0; const coreObjectType = transformSchemaObjectCore(schemaObject, options); const allOfType = collectCompositions( (_b = schemaObject.allOf) != null ? _b : [], schemaObject.required ); if (coreObjectType || allOfType.length) { const allOf = allOfType.length ? tsIntersection(allOfType) : void 0; finalType = tsIntersection([ ...coreObjectType ? [coreObjectType] : [], ...allOf ? [allOf] : [] ]); } const anyOfType = collectCompositions( (_c = schemaObject.anyOf) != null ? _c : [], schemaObject.required ); if (anyOfType.length) { finalType = tsUnion([...finalType ? [finalType] : [], ...anyOfType]); } const oneOfType = collectCompositions( schemaObject.oneOf || "type" in schemaObject && schemaObject.type === "object" && schemaObject.enum || [], schemaObject.required ); if (oneOfType.length) { if (oneOfType.every(tsIsPrimitive)) { finalType = tsUnion([...finalType ? [finalType] : [], ...oneOfType]); } else { finalType = tsIntersection([ ...finalType ? [finalType] : [], tsUnion(oneOfType) ]); } } if (finalType) { if (schemaObject.nullable) { return tsNullable([finalType]); } return finalType; } else { if (!("type" in schemaObject)) { return UNKNOWN; } return tsRecord(STRING, options.ctx.emptyObjectsUnknown ? UNKNOWN : NEVER); } } function transformSchemaObjectCore(schemaObject, options) { var _a, _b, _c, _d, _e, _f, _g; if ("type" in schemaObject && schemaObject.type) { if (schemaObject.type === "null") { return NULL; } if (schemaObject.type === "string") { return STRING; } if (schemaObject.type === "number" || schemaObject.type === "integer") { return NUMBER; } if (schemaObject.type === "boolean") { return BOOLEAN; } if (schemaObject.type === "array") { let itemType = UNKNOWN; if (schemaObject.prefixItems || Array.isArray(schemaObject.items)) { const prefixItems = (_a = schemaObject.prefixItems) != null ? _a : schemaObject.items; itemType = import_typescript3.default.factory.createTupleTypeNode( prefixItems.map((item) => transformSchemaObject(item, options)) ); } else if (schemaObject.items) { itemType = transformSchemaObject(schemaObject.items, options); } const min = typeof schemaObject.minItems === "number" && schemaObject.minItems >= 0 ? schemaObject.minItems : 0; const max = typeof schemaObject.maxItems === "number" && schemaObject.maxItems >= 0 && min <= schemaObject.maxItems ? schemaObject.maxItems : void 0; const estimateCodeSize = typeof max !== "number" ? min : (max * (max + 1) - min * (min - 1)) / 2; if (options.ctx.arrayLength && (min !== 0 || max !== void 0) && estimateCodeSize < 30) { if (schemaObject.maxItems > 0) { const members = []; for (let i = 0; i <= (max != null ? max : 0) - min; i++) { const elements = []; for (let j = min; j < i + min; j++) { elements.push(itemType); } members.push(import_typescript3.default.factory.createTupleTypeNode(elements)); } return tsUnion(members); } else { const elements = []; for (let i = 0; i < min; i++) { elements.push(itemType); } elements.push( import_typescript3.default.factory.createRestTypeNode( import_typescript3.default.factory.createArrayTypeNode(itemType) ) ); return import_typescript3.default.factory.createTupleTypeNode(elements); } } return import_typescript3.default.isTupleTypeNode(itemType) ? itemType : import_typescript3.default.factory.createArrayTypeNode(itemType); } if (Array.isArray(schemaObject.type) && !Array.isArray(schemaObject)) { let uniqueTypes = []; if (Array.isArray(schemaObject.oneOf)) { for (const t of schemaObject.type) { if ((t === "boolean" || t === "string" || t === "number" || t === "integer" || t === "null") && schemaObject.oneOf.find( (o) => typeof o === "object" && "type" in o && o.type === t )) { continue; } uniqueTypes.push( t === "null" || t === null ? NULL : transformSchemaObject( { ...schemaObject, type: t, oneOf: void 0 }, // don’t stack oneOf transforms options ) ); } } else { uniqueTypes = schemaObject.type.map( (t) => t === "null" || t === null ? NULL : transformSchemaObject({ ...schemaObject, type: t }, options) ); } return tsUnion(uniqueTypes); } } const coreObjectType = []; for (const k of ["oneOf", "allOf", "anyOf"]) { if (!schemaObject[k]) { continue; } const discriminator = !schemaObject.discriminator && options.ctx.discriminators[options.path]; if (discriminator) { coreObjectType.unshift( createDiscriminatorProperty(discriminator, { path: options.path, readonly: options.ctx.immutable }) ); break; } } if ("properties" in schemaObject && schemaObject.properties && Object.keys(schemaObject.properties).length || "additionalProperties" in schemaObject && schemaObject.additionalProperties || "$defs" in schemaObject && schemaObject.$defs) { if (Object.keys((_b = schemaObject.properties) != null ? _b : {}).length) { for (const [k, v] of getEntries( (_c = schemaObject.properties) != null ? _c : {}, options.ctx )) { if (typeof v !== "object" || Array.isArray(v)) { throw new Error( `${options.path}: invalid property ${k}. Expected Schema Object, got ${Array.isArray(v) ? "Array" : typeof v}` ); } if (options.ctx.excludeDeprecated) { const resolved = "$ref" in v ? options.ctx.resolve(v.$ref) : v; if (resolved == null ? void 0 : resolved.deprecated) { continue; } } let optional = ((_d = schemaObject.required) == null ? void 0 : _d.includes(k)) || "default" in v && options.ctx.defaultNonNullable && !((_e = options.path) == null ? void 0 : _e.includes("parameters")) ? void 0 : QUESTION_TOKEN; let type = "$ref" in v ? oapiRef(v.$ref) : transformSchemaObject(v, { ...options, path: createRef([(_f = options.path) != null ? _f : "", k]) }); if (typeof options.ctx.transform === "function") { const result = options.ctx.transform(v, options); if (result) { if ("schema" in result) { type = result.schema; optional = result.questionToken ? QUESTION_TOKEN : optional; } else { type = result; } } } const property = import_typescript3.default.factory.createPropertySignature( /* modifiers */ tsModifiers({ readonly: options.ctx.immutable || "readOnly" in v && !!v.readOnly }), /* name */ tsPropertyIndex(k), /* questionToken */ optional, /* type */ type ); addJSDocComment(v, property); coreObjectType.push(property); } } if (schemaObject.$defs && typeof schemaObject.$defs === "object" && Object.keys(schemaObject.$defs).length) { const defKeys = []; for (const [k, v] of Object.entries(schemaObject.$defs)) { const property = import_typescript3.default.factory.createPropertySignature( /* modifiers */ tsModifiers({ readonly: options.ctx.immutable || "readonly" in v && !!v.readOnly }), /* name */ tsPropertyIndex(k), /* questionToken */ void 0, /* type