@hey-api/openapi-ts
Version:
๐ OpenAPI to TypeScript codegen. Production-ready SDKs, Zod schemas, TanStack Query hooks, and 20+ plugins. Used by Vercel, OpenCode, and PayPal.
1,542 lines (1,502 loc) โข 681 kB
JavaScript
import { createRequire } from "node:module";
import { Project, StructureModel, fromRef, isNode, isRef, isSymbol, log, nodeBrand, ref, refs } from "@hey-api/codegen-core";
import colors from "ansi-colors";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import ts from "typescript";
import { EOL } from "node:os";
import * as semver from "semver";
import { getResolvedInput, sendRequest } from "@hey-api/json-schema-ref-parser";
//#region rolldown:runtime
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
var __require = /* @__PURE__ */ createRequire(import.meta.url);
//#endregion
//#region src/generate/tsConfig.ts
const __filename$1 = fileURLToPath(import.meta.url);
const __dirname$1 = path.dirname(__filename$1);
const findPackageJson = () => {
let dir = __dirname$1;
while (dir !== path.dirname(dir)) {
const candidates = fs.readdirSync(dir).filter((file) => file === "package.json");
if (candidates[0]) {
const packageJsonPath = path.join(dir, candidates[0]);
return JSON.parse(fs.readFileSync(packageJsonPath, { encoding: "utf8" }));
}
dir = path.dirname(dir);
}
};
const loadPackageJson = () => {
const packageJson = findPackageJson();
const safePackage = {
bugs: { url: "" },
name: "",
version: ""
};
if (packageJson && typeof packageJson === "object") {
if ("name" in packageJson && typeof packageJson.name === "string") safePackage.name = packageJson.name;
if ("version" in packageJson && typeof packageJson.version === "string") safePackage.version = packageJson.version;
if ("bugs" in packageJson && packageJson.bugs && typeof packageJson.bugs === "object") {
if ("url" in packageJson.bugs && typeof packageJson.bugs.url === "string") {
safePackage.bugs.url = packageJson.bugs.url;
if (safePackage.bugs.url && !safePackage.bugs.url.endsWith("/")) safePackage.bugs.url += "/";
}
}
}
return safePackage;
};
const findTsConfigPath = (tsConfigPath) => {
if (tsConfigPath === null) return null;
if (tsConfigPath) {
const resolved = path.isAbsolute(tsConfigPath) ? tsConfigPath : path.resolve(__dirname$1, tsConfigPath);
return fs.existsSync(resolved) ? resolved : null;
}
let dir = __dirname$1;
while (dir !== path.dirname(dir)) {
const candidates = fs.readdirSync(dir).filter((file) => file.startsWith("tsconfig") && file.endsWith(".json")).sort((file) => file === "tsconfig.json" ? -1 : 1);
if (candidates[0]) return path.join(dir, candidates[0]);
dir = path.dirname(dir);
}
return null;
};
const loadTsConfig = (configPath) => {
if (!configPath) return null;
const raw = ts.readConfigFile(configPath, ts.sys.readFile);
if (raw.error) throw new Error(`Couldn't read tsconfig from path: ${configPath}`);
return ts.parseJsonConfigFileContent(raw.config, ts.sys, path.dirname(configPath));
};
//#endregion
//#region src/generate/utils.ts
const ensureDirSync = (path$4) => {
if (!fs.existsSync(path$4)) fs.mkdirSync(path$4, { recursive: true });
};
//#endregion
//#region src/error.ts
/**
* Represents a single configuration error.
*
* Used for reporting issues with a specific config instance.
*/
var ConfigError = class extends Error {
constructor(message) {
super(message);
this.name = "ConfigError";
}
};
/**
* Aggregates multiple config errors with their job indices for reporting.
*/
var ConfigValidationError = class extends Error {
errors;
constructor(errors) {
super(`Found ${errors.length} configuration ${errors.length === 1 ? "error" : "errors"}.`);
this.name = "ConfigValidationError";
this.errors = errors;
}
};
/**
* Represents a runtime error originating from a specific job.
*
* Used for reporting job-level failures that are not config validation errors.
*/
var JobError = class extends Error {
originalError;
constructor(message, error) {
super(message);
this.name = "JobError";
this.originalError = error;
}
};
var HeyApiError = class extends Error {
args;
event;
pluginName;
constructor({ args, error, event, name, pluginName }) {
const message = error instanceof Error ? error.message : "Unknown error";
super(message);
this.args = args;
this.cause = error.cause;
this.event = event;
this.name = name || error.name;
this.pluginName = pluginName;
this.stack = error.stack;
}
};
const logCrashReport = (error, logsDir) => {
if (error instanceof ConfigError || error instanceof ConfigValidationError) return;
if (error instanceof JobError) error = error.originalError.error;
const logName = `openapi-ts-error-${Date.now()}.log`;
const fullDir = path.resolve(process.cwd(), logsDir);
ensureDirSync(fullDir);
const logPath = path.resolve(fullDir, logName);
let logContent = `[${(/* @__PURE__ */ new Date()).toISOString()}] `;
if (error instanceof HeyApiError) {
logContent += `${error.name} during event "${error.event}"\n`;
if (error.pluginName) logContent += `Plugin: ${error.pluginName}\n`;
logContent += `Arguments: ${JSON.stringify(error.args, null, 2)}\n\n`;
}
const message = error instanceof Error ? error.message : String(error);
const stack = error instanceof Error ? error.stack : void 0;
logContent += `Error: ${message}\n`;
if (stack) logContent += `Stack:\n${stack}\n`;
fs.writeFileSync(logPath, logContent);
return logPath;
};
const openGitHubIssueWithCrashReport = async (error) => {
const packageJson = loadPackageJson();
if (!packageJson.bugs.url) return;
if (error instanceof JobError) error = error.originalError.error;
let body = "";
if (error instanceof HeyApiError) {
if (error.pluginName) body += `**Plugin**: \`${error.pluginName}\`\n`;
body += `**Event**: \`${error.event}\`\n`;
body += `**Arguments**:\n\`\`\`ts\n${JSON.stringify(error.args, null, 2)}\n\`\`\`\n\n`;
}
const message = error instanceof Error ? error.message : String(error);
const stack = error instanceof Error ? error.stack : void 0;
body += `**Error**: \`${message}\`\n`;
if (stack) body += `\n**Stack Trace**:\n\`\`\`\n${stack}\n\`\`\``;
const search = new URLSearchParams({
body,
labels: "bug ๐ฅ",
title: "Crash Report"
});
const url = `${packageJson.bugs.url}new?${search.toString()}`;
const open = (await import("open")).default;
await open(url);
};
const printCrashReport = ({ error, logPath }) => {
if (error instanceof ConfigValidationError && error.errors.length) {
const groupByJob = /* @__PURE__ */ new Map();
for (const { error: err, jobIndex } of error.errors) {
if (!groupByJob.has(jobIndex)) groupByJob.set(jobIndex, []);
groupByJob.get(jobIndex).push(err);
}
for (const [jobIndex, errors] of groupByJob.entries()) {
const jobPrefix = colors.gray(`[Job ${jobIndex + 1}] `);
const count = errors.length;
const baseString = colors.red(`Found ${count} configuration ${count === 1 ? "error" : "errors"}:`);
console.error(`${jobPrefix}โ๏ธ ${baseString}`);
errors.forEach((err, index) => {
const itemPrefixStr = ` [${index + 1}] `;
const itemPrefix = colors.red(itemPrefixStr);
console.error(`${jobPrefix}${itemPrefix}${colors.white(err.message)}`);
});
}
} else {
let jobPrefix = colors.gray("[root] ");
if (error instanceof JobError) {
jobPrefix = colors.gray(`[Job ${error.originalError.jobIndex + 1}] `);
error = error.originalError.error;
}
const baseString = colors.red("Failed with the message:");
console.error(`${jobPrefix}โ ${baseString}`);
const itemPrefix = colors.red(` `);
console.error(`${jobPrefix}${itemPrefix}${typeof error === "string" ? error : error instanceof Error ? error.message : "Unknown error"}`);
}
if (logPath) {
const jobPrefix = colors.gray("[root] ");
console.error(`${jobPrefix}${colors.cyan("๐ Crash log saved to:")} ${colors.gray(logPath)}`);
}
};
const shouldReportCrash = async ({ error, isInteractive }) => {
if (!isInteractive || error instanceof ConfigError || error instanceof ConfigValidationError) return false;
return new Promise((resolve) => {
const jobPrefix = colors.gray("[root] ");
console.log(`${jobPrefix}${colors.yellow("๐ข Open a GitHub issue with crash details? (y/N):")}`);
process.stdin.setEncoding("utf8");
process.stdin.once("data", (data) => {
resolve(data.trim().toLowerCase() === "y");
});
});
};
//#endregion
//#region src/utils/input/heyApi.ts
const registryRegExp$2 = /^([\w-]+)\/([\w-]+)(?:\?([\w=&.-]*))?$/;
const heyApiRegistryBaseUrl = "https://get.heyapi.dev";
/**
* Creates a full Hey API Registry URL.
*
* @param organization - Hey API organization slug
* @param project - Hey API project slug
* @param queryParams - Optional query parameters
* @returns The full Hey API registry URL.
*/
const getRegistryUrl$2 = (organization, project, queryParams) => `${heyApiRegistryBaseUrl}/${organization}/${project}${queryParams ? `?${queryParams}` : ""}`;
/**
* Parses a Hey API input string and extracts components.
*
* @param input - Hey API configuration input
* @returns Parsed Hey API input components
* @throws Error if the input format is invalid
*/
const parseShorthand$2 = (input) => {
let organization = input.organization;
let project = input.project;
let queryParams;
if (input.path) {
const match = input.path.match(registryRegExp$2);
if (!match) throw new Error(`Invalid Hey API shorthand format. Expected "organization/project?queryParams" or "organization/project", received: ${input.path}`);
organization = match[1];
project = match[2];
queryParams = match[3];
}
if (!organization) throw new Error("The Hey API organization cannot be empty.");
if (!project) throw new Error("The Hey API project cannot be empty.");
return {
organization,
project,
queryParams
};
};
/**
* Transforms a Hey API shorthand string to the corresponding API URL.
*
* @param input - Hey API configuration input
* @returns The Hey API Registry URL
*/
const inputToHeyApiPath = (input) => {
const parsed = parseShorthand$2(input);
return {
path: getRegistryUrl$2(parsed.organization, parsed.project, parsed.queryParams),
registry: "hey-api"
};
};
//#endregion
//#region src/utils/input/readme.ts
const registryRegExp$1 = /^(@([\w-]+)\/([\w\-.]+)#)?([\w-]+)$/;
/**
* Creates a full ReadMe API Registry URL.
*
* @param uuid - ReadMe UUID
* @returns The full ReadMe API registry URL.
*/
const getRegistryUrl$1 = (uuid) => `https://dash.readme.com/api/v1/api-registry/${uuid}`;
const namespace$1 = "readme";
/**
* Parses a ReadMe input string and extracts components.
*
* @param shorthand - ReadMe format string (@org/project#uuid or uuid)
* @returns Parsed ReadMe input components
* @throws Error if the input format is invalid
*/
const parseShorthand$1 = (shorthand) => {
const match = shorthand.match(registryRegExp$1);
if (!match) throw new Error(`Invalid ReadMe shorthand format. Expected "${namespace$1}:@organization/project#uuid" or "${namespace$1}:uuid", received: ${namespace$1}:${shorthand}`);
const [, , organization, project, uuid] = match;
if (!uuid) throw new Error("The ReadMe UUID cannot be empty.");
return {
organization,
project,
uuid
};
};
/**
* Transforms a ReadMe shorthand string to the corresponding API URL.
*
* @param input - ReadMe format string
* @returns The ReadMe API Registry URL
*/
const inputToReadmePath = (input) => {
const parsed = parseShorthand$1(input.slice(`${namespace$1}:`.length));
return {
...parsed,
path: getRegistryUrl$1(parsed.uuid),
registry: "readme"
};
};
//#endregion
//#region src/utils/input/scalar.ts
const registryRegExp = /^(@[\w-]+)\/([\w.-]+)$/;
/**
* Creates a full Scalar API Registry URL.
*
* @param organization - Scalar organization slug
* @param project - Scalar project slug
* @returns The full Scalar API registry URL.
*/
const getRegistryUrl = (organization, project) => `https://registry.scalar.com/${organization}/apis/${project}/latest?format=json`;
const namespace = "scalar";
/**
* Parses a Scalar input string and extracts components.
*
* @param shorthand - Scalar format string (@org/project)
* @returns Parsed Scalar input components
* @throws Error if the input format is invalid
*/
const parseShorthand = (shorthand) => {
const match = shorthand.match(registryRegExp);
if (!match) throw new Error(`Invalid Scalar shorthand format. Expected "${namespace}:@organization/project", received: ${namespace}:${shorthand}`);
const [, organization, project] = match;
if (!organization) throw new Error("The Scalar organization cannot be empty.");
if (!project) throw new Error("The Scalar project cannot be empty.");
return {
organization,
project
};
};
/**
* Transforms a Scalar shorthand string to the corresponding API URL.
*
* @param input - Scalar format string
* @returns The Scalar API Registry URL
*/
const inputToScalarPath = (input) => {
const parsed = parseShorthand(input.slice(`${namespace}:`.length));
return {
...parsed,
path: getRegistryUrl(parsed.organization, parsed.project),
registry: "scalar"
};
};
//#endregion
//#region src/utils/input/index.ts
const inputToApiRegistry = (input) => {
if (input.path.startsWith("readme:")) {
Object.assign(input, inputToReadmePath(input.path));
return;
}
if (input.path.startsWith("scalar:")) {
Object.assign(input, inputToScalarPath(input.path));
return;
}
if (input.path.startsWith(".")) return;
if (input.path.startsWith(heyApiRegistryBaseUrl)) {
input.path = input.path.slice(heyApiRegistryBaseUrl.length + 1);
Object.assign(input, inputToHeyApiPath(input));
return;
}
const parts = input.path.split("/");
if (parts.length === 2 && parts.filter(Boolean).length === 2) {
Object.assign(input, inputToHeyApiPath(input));
return;
}
};
//#endregion
//#region src/config/input.ts
const defaultWatch = {
enabled: false,
interval: 1e3,
timeout: 6e4
};
const getWatch = (input) => {
let watch = { ...defaultWatch };
if (typeof input.path !== "string") return watch;
if (typeof input.watch === "boolean") watch.enabled = input.watch;
else if (typeof input.watch === "number") {
watch.enabled = true;
watch.interval = input.watch;
} else if (input.watch) watch = {
...watch,
...input.watch
};
return watch;
};
const getInput = (userConfig) => {
const userInputs = userConfig.input instanceof Array ? userConfig.input : [userConfig.input];
const inputs = [];
for (const userInput of userInputs) {
let input = {
path: "",
watch: defaultWatch
};
if (typeof userInput === "string") input.path = userInput;
else if (userInput && (userInput.path !== void 0 || userInput.organization !== void 0)) {
input = {
...input,
path: heyApiRegistryBaseUrl,
...userInput
};
if (input.watch !== void 0) input.watch = getWatch(input);
} else input = {
...input,
path: userInput
};
if (typeof input.path === "string") inputToApiRegistry(input);
if (userConfig.watch !== void 0 && input.watch.enabled === defaultWatch.enabled && input.watch.interval === defaultWatch.interval && input.watch.timeout === defaultWatch.timeout) input.watch = getWatch({
path: input.path,
watch: userConfig.watch
});
if (input.path) inputs.push(input);
}
return inputs;
};
//#endregion
//#region src/config/logs.ts
const getLogs = (userConfig) => {
let logs = {
file: true,
level: "info",
path: process.cwd()
};
if (typeof userConfig?.logs === "string") logs.path = userConfig.logs;
else logs = {
...logs,
...userConfig?.logs
};
return logs;
};
//#endregion
//#region src/config/merge.ts
const mergeObjects = (objA, objB) => {
const a = objA || {};
const b = objB || {};
return {
...a,
...b
};
};
const mergeConfigs = (configA, configB) => {
const a = configA || {};
const b = configB || {};
const merged = {
...a,
...b
};
if (typeof merged.logs === "object") merged.logs = mergeObjects(a.logs, b.logs);
return merged;
};
//#endregion
//#region src/config/utils/config.ts
const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && typeof value !== "function";
const mergeResult = (result, mapped) => {
for (const [key, value] of Object.entries(mapped)) if (value !== void 0 && value !== "") result[key] = value;
return result;
};
const valueToObject = ({ defaultValue, mappers: mappers$1, value }) => {
let result = { ...defaultValue };
switch (typeof value) {
case "boolean":
if (mappers$1 && "boolean" in mappers$1) {
const mapper = mappers$1.boolean;
result = mergeResult(result, mapper(value));
}
break;
case "function":
if (mappers$1 && "function" in mappers$1) {
const mapper = mappers$1.function;
result = mergeResult(result, mapper(value));
}
break;
case "number":
if (mappers$1 && "number" in mappers$1) {
const mapper = mappers$1.number;
result = mergeResult(result, mapper(value));
}
break;
case "string":
if (mappers$1 && "string" in mappers$1) {
const mapper = mappers$1.string;
result = mergeResult(result, mapper(value));
}
break;
case "object":
if (isPlainObject(value)) if (mappers$1 && "object" in mappers$1 && typeof mappers$1.object === "function") {
const mapper = mappers$1.object;
result = mergeResult(result, mapper(value, defaultValue));
} else result = mergeResult(result, value);
break;
}
return result;
};
//#endregion
//#region ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js
var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = isexe;
isexe.sync = sync;
var fs$3 = __require("fs");
function checkPathExt(path$4, options) {
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
if (!pathext) return true;
pathext = pathext.split(";");
if (pathext.indexOf("") !== -1) return true;
for (var i = 0; i < pathext.length; i++) {
var p = pathext[i].toLowerCase();
if (p && path$4.substr(-p.length).toLowerCase() === p) return true;
}
return false;
}
function checkStat(stat, path$4, options) {
if (!stat.isSymbolicLink() && !stat.isFile()) return false;
return checkPathExt(path$4, options);
}
function isexe(path$4, options, cb) {
fs$3.stat(path$4, function(er, stat) {
cb(er, er ? false : checkStat(stat, path$4, options));
});
}
function sync(path$4, options) {
return checkStat(fs$3.statSync(path$4), path$4, options);
}
}));
//#endregion
//#region ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js
var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = isexe;
isexe.sync = sync;
var fs$2 = __require("fs");
function isexe(path$4, options, cb) {
fs$2.stat(path$4, function(er, stat) {
cb(er, er ? false : checkStat(stat, options));
});
}
function sync(path$4, options) {
return checkStat(fs$2.statSync(path$4), options);
}
function checkStat(stat, options) {
return stat.isFile() && checkMode(stat, options);
}
function checkMode(stat, options) {
var mod = stat.mode;
var uid = stat.uid;
var gid = stat.gid;
var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
var u = parseInt("100", 8);
var g = parseInt("010", 8);
var o = parseInt("001", 8);
var ug = u | g;
return mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
}
}));
//#endregion
//#region ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
var require_isexe = /* @__PURE__ */ __commonJSMin(((exports, module) => {
__require("fs");
var core;
if (process.platform === "win32" || global.TESTING_WINDOWS) core = require_windows();
else core = require_mode();
module.exports = isexe;
isexe.sync = sync;
function isexe(path$4, options, cb) {
if (typeof options === "function") {
cb = options;
options = {};
}
if (!cb) {
if (typeof Promise !== "function") throw new TypeError("callback not provided");
return new Promise(function(resolve, reject) {
isexe(path$4, options || {}, function(er, is) {
if (er) reject(er);
else resolve(is);
});
});
}
core(path$4, options || {}, function(er, is) {
if (er) {
if (er.code === "EACCES" || options && options.ignoreErrors) {
er = null;
is = false;
}
}
cb(er, is);
});
}
function sync(path$4, options) {
try {
return core.sync(path$4, options || {});
} catch (er) {
if (options && options.ignoreErrors || er.code === "EACCES") return false;
else throw er;
}
}
}));
//#endregion
//#region ../../node_modules/.pnpm/which@2.0.2/node_modules/which/which.js
var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
const path$3 = __require("path");
const COLON = isWindows ? ";" : ":";
const isexe = require_isexe();
const getNotFoundError = (cmd) => Object.assign(/* @__PURE__ */ new Error(`not found: ${cmd}`), { code: "ENOENT" });
const getPathInfo = (cmd, opt) => {
const colon = opt.colon || COLON;
const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [...isWindows ? [process.cwd()] : [], ...(opt.path || process.env.PATH || "").split(colon)];
const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
const pathExt = isWindows ? pathExtExe.split(colon) : [""];
if (isWindows) {
if (cmd.indexOf(".") !== -1 && pathExt[0] !== "") pathExt.unshift("");
}
return {
pathEnv,
pathExt,
pathExtExe
};
};
const which = (cmd, opt, cb) => {
if (typeof opt === "function") {
cb = opt;
opt = {};
}
if (!opt) opt = {};
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
const found = [];
const step = (i) => new Promise((resolve, reject) => {
if (i === pathEnv.length) return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
const ppRaw = pathEnv[i];
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
const pCmd = path$3.join(pathPart, cmd);
resolve(subStep(!pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd, i, 0));
});
const subStep = (p, i, ii) => new Promise((resolve, reject) => {
if (ii === pathExt.length) return resolve(step(i + 1));
const ext = pathExt[ii];
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
if (!er && is) if (opt.all) found.push(p + ext);
else return resolve(p + ext);
return resolve(subStep(p, i, ii + 1));
});
});
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
};
const whichSync = (cmd, opt) => {
opt = opt || {};
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
const found = [];
for (let i = 0; i < pathEnv.length; i++) {
const ppRaw = pathEnv[i];
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
const pCmd = path$3.join(pathPart, cmd);
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
for (let j = 0; j < pathExt.length; j++) {
const cur = p + pathExt[j];
try {
if (isexe.sync(cur, { pathExt: pathExtExe })) if (opt.all) found.push(cur);
else return cur;
} catch (ex) {}
}
}
if (opt.all && found.length) return found;
if (opt.nothrow) return null;
throw getNotFoundError(cmd);
};
module.exports = which;
which.sync = whichSync;
}));
//#endregion
//#region ../../node_modules/.pnpm/path-key@3.1.1/node_modules/path-key/index.js
var require_path_key = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const pathKey = (options = {}) => {
const environment = options.env || process.env;
if ((options.platform || process.platform) !== "win32") return "PATH";
return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
};
module.exports = pathKey;
module.exports.default = pathKey;
}));
//#endregion
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const path$2 = __require("path");
const which = require_which();
const getPathKey = require_path_key();
function resolveCommandAttempt(parsed, withoutPathExt) {
const env = parsed.options.env || process.env;
const cwd = process.cwd();
const hasCustomCwd = parsed.options.cwd != null;
const shouldSwitchCwd = hasCustomCwd && process.chdir !== void 0 && !process.chdir.disabled;
if (shouldSwitchCwd) try {
process.chdir(parsed.options.cwd);
} catch (err) {}
let resolved;
try {
resolved = which.sync(parsed.command, {
path: env[getPathKey({ env })],
pathExt: withoutPathExt ? path$2.delimiter : void 0
});
} catch (e) {} finally {
if (shouldSwitchCwd) process.chdir(cwd);
}
if (resolved) resolved = path$2.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
return resolved;
}
function resolveCommand(parsed) {
return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
}
module.exports = resolveCommand;
}));
//#endregion
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/escape.js
var require_escape = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
function escapeCommand(arg) {
arg = arg.replace(metaCharsRegExp, "^$1");
return arg;
}
function escapeArgument(arg, doubleEscapeMetaChars) {
arg = `${arg}`;
arg = arg.replace(/(?=(\\+?)?)\1"/g, "$1$1\\\"");
arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
arg = `"${arg}"`;
arg = arg.replace(metaCharsRegExp, "^$1");
if (doubleEscapeMetaChars) arg = arg.replace(metaCharsRegExp, "^$1");
return arg;
}
module.exports.command = escapeCommand;
module.exports.argument = escapeArgument;
}));
//#endregion
//#region ../../node_modules/.pnpm/shebang-regex@3.0.0/node_modules/shebang-regex/index.js
var require_shebang_regex = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = /^#!(.*)/;
}));
//#endregion
//#region ../../node_modules/.pnpm/shebang-command@2.0.0/node_modules/shebang-command/index.js
var require_shebang_command = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const shebangRegex = require_shebang_regex();
module.exports = (string = "") => {
const match = string.match(shebangRegex);
if (!match) return null;
const [path$4, argument] = match[0].replace(/#! ?/, "").split(" ");
const binary = path$4.split("/").pop();
if (binary === "env") return argument;
return argument ? `${binary} ${argument}` : binary;
};
}));
//#endregion
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const fs$1 = __require("fs");
const shebangCommand = require_shebang_command();
function readShebang(command) {
const size = 150;
const buffer = Buffer.alloc(size);
let fd;
try {
fd = fs$1.openSync(command, "r");
fs$1.readSync(fd, buffer, 0, size, 0);
fs$1.closeSync(fd);
} catch (e) {}
return shebangCommand(buffer.toString());
}
module.exports = readShebang;
}));
//#endregion
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const path$1 = __require("path");
const resolveCommand = require_resolveCommand();
const escape = require_escape();
const readShebang = require_readShebang();
const isWin = process.platform === "win32";
const isExecutableRegExp = /\.(?:com|exe)$/i;
const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
function detectShebang(parsed) {
parsed.file = resolveCommand(parsed);
const shebang = parsed.file && readShebang(parsed.file);
if (shebang) {
parsed.args.unshift(parsed.file);
parsed.command = shebang;
return resolveCommand(parsed);
}
return parsed.file;
}
function parseNonShell(parsed) {
if (!isWin) return parsed;
const commandFile = detectShebang(parsed);
const needsShell = !isExecutableRegExp.test(commandFile);
if (parsed.options.forceShell || needsShell) {
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
parsed.command = path$1.normalize(parsed.command);
parsed.command = escape.command(parsed.command);
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
parsed.args = [
"/d",
"/s",
"/c",
`"${[parsed.command].concat(parsed.args).join(" ")}"`
];
parsed.command = process.env.comspec || "cmd.exe";
parsed.options.windowsVerbatimArguments = true;
}
return parsed;
}
function parse(command, args, options) {
if (args && !Array.isArray(args)) {
options = args;
args = null;
}
args = args ? args.slice(0) : [];
options = Object.assign({}, options);
const parsed = {
command,
args,
options,
file: void 0,
original: {
command,
args
}
};
return options.shell ? parsed : parseNonShell(parsed);
}
module.exports = parse;
}));
//#endregion
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/enoent.js
var require_enoent = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const isWin = process.platform === "win32";
function notFoundError(original, syscall) {
return Object.assign(/* @__PURE__ */ new Error(`${syscall} ${original.command} ENOENT`), {
code: "ENOENT",
errno: "ENOENT",
syscall: `${syscall} ${original.command}`,
path: original.command,
spawnargs: original.args
});
}
function hookChildProcess(cp$1, parsed) {
if (!isWin) return;
const originalEmit = cp$1.emit;
cp$1.emit = function(name, arg1) {
if (name === "exit") {
const err = verifyENOENT(arg1, parsed);
if (err) return originalEmit.call(cp$1, "error", err);
}
return originalEmit.apply(cp$1, arguments);
};
}
function verifyENOENT(status, parsed) {
if (isWin && status === 1 && !parsed.file) return notFoundError(parsed.original, "spawn");
return null;
}
function verifyENOENTSync(status, parsed) {
if (isWin && status === 1 && !parsed.file) return notFoundError(parsed.original, "spawnSync");
return null;
}
module.exports = {
hookChildProcess,
verifyENOENT,
verifyENOENTSync,
notFoundError
};
}));
//#endregion
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/index.js
var require_cross_spawn = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const cp = __require("child_process");
const parse = require_parse();
const enoent = require_enoent();
function spawn(command, args, options) {
const parsed = parse(command, args, options);
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
enoent.hookChildProcess(spawned, parsed);
return spawned;
}
function spawnSync(command, args, options) {
const parsed = parse(command, args, options);
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
return result;
}
module.exports = spawn;
module.exports.spawn = spawn;
module.exports.sync = spawnSync;
module.exports._parse = parse;
module.exports._enoent = enoent;
}));
//#endregion
//#region src/config/output/postprocess.ts
var import_cross_spawn = require_cross_spawn();
const postProcessors = {
"biome:format": {
args: [
"format",
"--write",
"{{path}}"
],
command: "biome",
name: "Biome (Format)"
},
"biome:lint": {
args: [
"lint",
"--apply",
"{{path}}"
],
command: "biome",
name: "Biome (Lint)"
},
eslint: {
args: ["{{path}}", "--fix"],
command: "eslint",
name: "ESLint"
},
oxfmt: {
args: ["{{path}}"],
command: "oxfmt",
name: "Oxfmt"
},
oxlint: {
args: ["--fix", "{{path}}"],
command: "oxlint",
name: "Oxlint"
},
prettier: {
args: [
"--ignore-unknown",
"{{path}}",
"--write",
"--ignore-path",
"./.prettierignore"
],
command: "prettier",
name: "Prettier"
}
};
const postprocessOutput = (config, jobPrefix) => {
for (const processor of config.postProcess) {
const resolved = typeof processor === "string" ? postProcessors[processor] : processor;
const name = resolved.name ?? resolved.command;
const args = resolved.args.map((arg) => arg.replace("{{path}}", config.path));
console.log(`${jobPrefix}๐งน Running ${colors.cyanBright(name)}`);
(0, import_cross_spawn.sync)(resolved.command, args);
}
};
//#endregion
//#region src/config/output/source/config.ts
function resolveSource(config) {
const source$2 = valueToObject({
defaultValue: {
enabled: Boolean(config.source),
extension: "json",
fileName: "source",
serialize: (input) => JSON.stringify(input, null, 2)
},
mappers: { boolean: (enabled) => ({ enabled }) },
value: config.source
});
if (source$2.path === void 0 || source$2.path === true) source$2.path = "";
else if (source$2.path === false) source$2.path = null;
return source$2;
}
//#endregion
//#region src/config/output/config.ts
function getOutput(userConfig) {
if (userConfig.output instanceof Array) throw new Error("Unexpected array of outputs in user configuration. This should have been expanded already.");
const userOutput = typeof userConfig.output === "string" ? { path: userConfig.output } : userConfig.output ?? {};
const legacyPostProcess = resolveLegacyPostProcess(userOutput);
const output = valueToObject({
defaultValue: {
clean: true,
fileName: {
case: "preserve",
name: "{{name}}",
suffix: ".gen"
},
format: null,
header: "// This file is auto-generated by @hey-api/openapi-ts",
indexFile: true,
lint: null,
path: "",
postProcess: [],
preferExportAll: false
},
mappers: { object: (fields, defaultValue) => ({
...fields,
fileName: valueToObject({
defaultValue: { ...defaultValue.fileName },
mappers: {
function: (name) => ({ name }),
string: (name) => ({ name })
},
value: fields.fileName
})
}) },
value: userOutput
});
output.tsConfig = loadTsConfig(findTsConfigPath(output.tsConfigPath));
if (output.importFileExtension === void 0 && (output.tsConfig?.options.moduleResolution === ts.ModuleResolutionKind.NodeNext || output.tsConfig?.options.moduleResolution === ts.ModuleResolutionKind.Node16)) output.importFileExtension = ".js";
if (output.importFileExtension && !output.importFileExtension.startsWith(".")) output.importFileExtension = `.${output.importFileExtension}`;
output.postProcess = normalizePostProcess(userOutput.postProcess ?? legacyPostProcess);
output.source = resolveSource(output);
return output;
}
function resolveLegacyPostProcess(config) {
const result = [];
if (config.lint !== void 0) {
let processor;
let preset;
if (config.lint) {
preset = config.lint === "biome" ? "biome:lint" : config.lint;
processor = postProcessors[preset];
if (processor) result.push(processor);
}
log.warnDeprecated({
context: "output",
field: "lint",
replacement: `postProcess: [${processor && preset ? `'${preset}'` : ""}]`
});
}
if (config.format !== void 0) {
let processor;
let preset;
if (config.format) {
preset = config.format === "biome" ? "biome:format" : config.format;
processor = postProcessors[preset];
if (processor) result.push(processor);
}
log.warnDeprecated({
context: "output",
field: "format",
replacement: `postProcess: [${processor && preset ? `'${preset}'` : ""}]`
});
}
return result;
}
function normalizePostProcess(input) {
if (!input) return [];
return input.map((item) => {
if (typeof item === "string") {
const preset = postProcessors[item];
if (!preset) throw new Error(`Unknown post-processor preset: "${item}"`);
return preset;
}
return {
name: item.name ?? item.command,
...item
};
});
}
//#endregion
//#region src/config/packages.ts
/**
* Finds and reads the project's package.json file by searching upwards from the config file location,
* or from process.cwd() if no config file is provided.
* This ensures we get the correct dependencies even in monorepo setups.
*
* @param configFilePath - The path to the configuration file (e.g., openapi-ts.config.ts)
* @returns An object containing all project dependencies (dependencies, devDependencies, peerDependencies, optionalDependencies)
*/
const getProjectDependencies = (configFilePath) => {
let currentDir = configFilePath ? path.dirname(configFilePath) : process.cwd();
while (currentDir !== path.dirname(currentDir)) {
const packageJsonPath = path.join(currentDir, "package.json");
if (fs.existsSync(packageJsonPath)) try {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
return {
...packageJson.dependencies,
...packageJson.devDependencies,
...packageJson.peerDependencies,
...packageJson.optionalDependencies
};
} catch {}
const parentDir = path.dirname(currentDir);
if (parentDir === currentDir) break;
currentDir = parentDir;
}
return {};
};
//#endregion
//#region src/config/parser.ts
const defaultPaginationKeywords = [
"after",
"before",
"cursor",
"offset",
"page",
"start"
];
const getParser = (userConfig) => {
return valueToObject({
defaultValue: {
hooks: {},
pagination: { keywords: defaultPaginationKeywords },
transforms: {
enums: {
case: "PascalCase",
enabled: false,
mode: "root",
name: "{{name}}Enum"
},
propertiesRequiredByDefault: false,
readWrite: {
enabled: true,
requests: {
case: "preserve",
name: "{{name}}Writable"
},
responses: {
case: "preserve",
name: "{{name}}"
}
}
},
validate_EXPERIMENTAL: false
},
mappers: { object: (fields, defaultValue) => ({
...fields,
pagination: valueToObject({
defaultValue: { ...defaultValue.pagination },
value: fields.pagination
}),
transforms: valueToObject({
defaultValue: { ...defaultValue.transforms },
mappers: { object: (fields$1, defaultValue$1) => ({
...fields$1,
enums: valueToObject({
defaultValue: {
...defaultValue$1.enums,
enabled: fields$1.enums !== void 0 ? Boolean(fields$1.enums) : defaultValue$1.enums.enabled
},
mappers: {
boolean: (enabled) => ({ enabled }),
string: (mode) => ({ mode })
},
value: fields$1.enums
}),
propertiesRequiredByDefault: fields$1.propertiesRequiredByDefault !== void 0 ? fields$1.propertiesRequiredByDefault : defaultValue$1.propertiesRequiredByDefault,
readWrite: valueToObject({
defaultValue: {
...defaultValue$1.readWrite,
enabled: fields$1.readWrite !== void 0 ? Boolean(fields$1.readWrite) : defaultValue$1.readWrite.enabled
},
mappers: {
boolean: (enabled) => ({ enabled }),
object: (fields$2, defaultValue$2) => ({
...fields$2,
requests: valueToObject({
defaultValue: { ...defaultValue$2.requests },
mappers: {
function: (name) => ({ name }),
string: (name) => ({ name })
},
value: fields$2.requests
}),
responses: valueToObject({
defaultValue: { ...defaultValue$2.responses },
mappers: {
function: (name) => ({ name }),
string: (name) => ({ name })
},
value: fields$2.responses
})
})
},
value: fields$1.readWrite
})
}) },
value: fields.transforms
}),
validate_EXPERIMENTAL: fields.validate_EXPERIMENTAL === true ? "warn" : fields.validate_EXPERIMENTAL
}) },
value: userConfig.parser
});
};
//#endregion
//#region src/plugins/shared/utils/config.ts
const definePluginConfig = (defaultConfig$24) => (userConfig) => ({
...defaultConfig$24,
config: {
...defaultConfig$24.config,
...userConfig
}
});
/**
* Reusable mappers for `enabled` and `name` fields.
*/
const mappers = {
boolean: (enabled) => ({ enabled }),
function: (name) => ({ name }),
string: (name) => ({ name })
};
//#endregion
//#region src/plugins/@angular/common/httpRequests/config.ts
function resolveHttpRequests(config, context) {
let input = config.httpRequests;
if (typeof input === "string" || typeof input === "function") input = { strategy: input };
else if (typeof input === "boolean" || !input) input = { enabled: Boolean(input) };
const strategy = input.strategy ?? "flat";
return context.valueToObject({
defaultValue: {
container: "class",
enabled: true,
methods: "instance",
nesting: "operationId",
nestingDelimiters: /[./]/,
strategy,
strategyDefaultTag: "default"
},
mappers: { object(value) {
value.containerName = context.valueToObject({
defaultValue: strategy === "single" ? {
casing: "PascalCase",
name: "HttpRequests"
} : { casing: "PascalCase" },
mappers: {
function: (name) => ({ name }),
string: (name) => ({ name })
},
value: value.containerName
});
value.methodName = context.valueToObject({
defaultValue: strategy === "flat" ? {
casing: "camelCase",
name: "{{name}}Request"
} : { casing: "camelCase" },
mappers: {
function: (name) => ({ name }),
string: (name) => ({ name })
},
value: value.methodName
});
value.segmentName = context.valueToObject({
defaultValue: {
casing: "PascalCase",
name: "{{name}}Requests"
},
mappers: {
function: (name) => ({ name }),
string: (name) => ({ name })
},
value: value.segmentName
});
return value;
} },
value: input
});
}
//#endregion
//#region src/openApi/shared/locations/operation.ts
/**
* Built-in strategies for operations.
*/
const OperationStrategy = {
byTags: (config) => (operation) => {
const tags = operation.tags && operation.tags.length > 0 ? operation.tags : [config.fallback];
const pathSegments = (config.path ?? OperationPath.id())(operation);
return tags.map((tag) => [tag, ...pathSegments]);
},
flat: (config) => (operation) => {
const pathSegments = (config?.path ?? OperationPath.id())(operation);
return [[pathSegments[pathSegments.length - 1]]];
},
single: (config) => (operation) => {
const pathSegments = (config.path ?? OperationPath.id())(operation);
return [[config.root, ...pathSegments]];
}
};
/**
* Built-in path derivation helpers for operations.
*/
const OperationPath = {
fromOperationId: (config) => (operation) => {
const fallback = config?.fallback ?? OperationPath.id();
if (!operation.operationId) return fallback(operation);
const delimiters = config?.delimiters ?? /[./]/;
const segments = operation.operationId.split(delimiters).filter(Boolean);
return segments.length === 0 ? fallback(operation) : segments;
},
fromPath: (config) => (operation) => {
const delimiters = config?.delimiters ?? /[./]/;
const segments = operation.path.split(delimiters).filter(Boolean);
switch (config?.methodPosition) {
case "prefix":
segments.unshift(operation.method.toLowerCase());
break;
case "suffix":
segments.push(operation.method.toLowerCase());
break;
default: break;
}
return segments;
},
id: () => (operation) => [operation.id]
};
//#endregion
//#region src/plugins/@angular/common/httpRequests/resolve.ts
function resolvePath$2(plugin) {
if (plugin.config.httpRequests.nesting === "id") return OperationPath.id();
if (plugin.config.httpRequests.nesting === "operationId") return OperationPath.fromOperationId({
delimiters: plugin.config.httpRequests.nestingDelimiters,
fallback: OperationPath.id()
});
return plugin.config.httpRequests.nesting;
}
function resolveHttpRequestsStrategy(plugin) {
if (plugin.config.httpRequests.strategy === "flat") return OperationStrategy.flat({ path: (operation) => [resolvePath$2(plugin)(operation).join(".")] });
if (plugin.config.httpRequests.strategy === "single") {
const root = plugin.config.httpRequests.containerName;
return OperationStrategy.single({
path: resolvePath$2(plugin),
root: typeof root.name === "string" ? root.name : root.name?.("") ?? ""
});
}
if (plugin.config.httpRequests.strategy === "byTags") return OperationStrategy.byTags({
fallback: plugin.config.httpRequests.strategyDefaultTag,
path: resolvePath$2(plugin)
});
return plugin.config.httpRequests.strategy;
}
//#endregion
//#region src/plugins/@angular/common/httpResources/config.ts
function resolveHttpResources(config, context) {
let input = config.httpResources;
if (typeof input === "string" || typeof input === "function") input = { strategy: input };
else if (typeof input === "boolean" || !input) input = { enabled: Boolean(input) };
const strategy = input.strategy ?? "flat";
return context.valueToObject({
defaultValue: {
container: "class",
enabled: true,
methods: "instance",
nesting: "operationId",
nestingDelimiters: /[./]/,
strategy,
strategyDefaultTag: "default"
},
mappers: { object(value) {
value.containerName = context.valueToObject({
defaultValue: strategy === "single" ? {
casing: "PascalCase",
name: "HttpResources"
} : { casing: "PascalCase" },
mappers: {
function: (name) => ({ name }),
string: (name) => ({ name })
},
value: value.containerName
});
value.methodName = context.valueToObject({
defaultValue: strategy === "flat" ? {
casing: "camelCase",
name: "{{name}}Resource"
} : { casing: "camelCase" },
mappers: {
function: (name) => ({ name }),
string: (name) => ({ name })
},
value: value.methodName
});
value.segmentName = context.valueToObject({
defaultValue: {
casing: "PascalCase",
name: "{{name}}Resources"
},
mappers: {
function: (name) => ({ name }),
string: (name) => ({ name })
},
value: value.segmentName
});
return value;
} },
value: input
});
}
//#endregion
//#region src/plugins/@angular/common/httpResources/resolve.ts
function resolvePath$1(plugin) {
if (plugin.config.httpResources.nesting === "id") return OperationPath.id();
if (plugin.config.httpResources.nesting === "operationId") return OperationPath.fromOperationId({
delimiters: plugin.config.httpResources.nestingDelimiters,
fallback: OperationPath.id()
});
return plugin.config.httpResources.nesting;
}
function resolveHttpResourcesStrategy(plugin) {
if (plugin.config.httpResources.strategy === "flat") return OperationStrategy.flat({ path: (operation) => [resolvePath$1(plugin)(operation).join(".")] });
if (plugin.config.httpResources.strategy === "single") {
const root = plugin.config.httpResources.containerName;
return OperationStrategy.single({
path: resolvePath$1(plugin),
root: typeof root.name === "string" ? root.name : root.name?.("") ?? ""
});
}
if (plugin.config.httpResources.strategy === "byTags") return OperationStrategy.byTags({
fallback: plugin.config.httpResources.strategyDefaultTag,
path: resolvePath$1(plugin)
});
return plugin.config.httpResources.strategy;
}
//#endregion
//#region src/plugins/@hey-api/client-core/utils.ts
const getClientBaseUrlKey = (config) => {
const client = getClientPlugin(config);
if (client.name === "@hey-api/client-axios" || client.name === "@hey-api/client-nuxt") return "baseURL";
return "baseUrl";
};
const getClientPlugin = (config) => {
for (const name of config.pluginOrder) {
const plugin = config.plugins[name];
if (plugin?.tags?.includes("client")) return plugin;
}
return {
config: { name: "" },
name: ""
};
};
//#endregion
//#region src/ir/parameter.ts
const getPaginationSchema = ({ context, parameter }) => {
if (!parameter.pagination) return;
if (parameter.pagination === true) return parameter.schema;
let schema = parameter.schema;
if (schema.$ref) schema = context.resolveIrRef(schema.$ref);
return schema.properties[parameter.pagination];
};
const hasParameterGroupObjectRequired = (parameterGroup) => {
for (const name in parameterGroup) if (parameterGroup[name].required) return true;
return false;
};
const hasParametersObjectRequired = (parameters) => {
if (!parameters) return false;
if (hasParameterGroupObjectRequired(parameters.cookie)) return true;
if (hasParameterGroupObjectRequired(parameters.header)) return true;
if (hasParameterGroupObjectRequired(parameters.path)) return true;
if (hasParameterGroupObjectRequired(parameters.query)) return true;
return false;
};
const parameterWithPagination = ({ context, parameters }) => {
if (!parameters) return;
for (const name in parameters.cookie) {
const parameter = parameters.cookie[name];
if (parameter.pagination) return {
in: parameter.location,
name: parameter.pagination === true ? parameter.name : `${parameter.name}.${parameter.pagination}`,
schema: getPaginationSchema({
context,
parameter
})
};
}
for (const name in parameters.header) {
const parameter = parameters.header[name];
if (parameter.pagination) return {
in: parameter.location,
name: parameter.pagination === true ? parameter.name : `${parameter.name}.${parameter.pagination}`,
schema: getPaginationSchema({
context,
parameter
})
};
}
for (const name in parameters.path) {
const parameter = parameters.path[name];
if (parameter.pagination) return {
in: parameter.location,
name: parameter.pagination === true ? parameter.name : `${parameter.name}.${parameter.pagination}`,
schema: getPaginationSchema({
context,
parameter
})
};
}
for (const name in parameters.query) {
const parameter = parameters.query[name];
if (parameter.pagination) return {
in: parameter.location,
name: parameter.pagination === true ? parameter.name : `${parameter.name}.${parameter.pagination}`,
schema: getPaginationSchema({
context,
parameter
})
};
}
};
//#endregion
//#region src/ir/schema.ts
/**
* Ensure we don't produce redundant types, e.g. string | string.
*/
const dedupl