import { _ as postProcessors, c as TypeScriptRenderer, g as getTypedConfig, h as getClientPlugin, i as generateClientBundle, t as resolveJobs } from "./init-Bi6_Uyy_.mjs";
import { Logger, Logger as Logger$1, Project } from "@hey-api/codegen-core";
import { ConfigValidationError, Context, InputError, IntentContext, JobError, OperationPath as OperationPath$1, OperationStrategy as OperationStrategy$1, applyNaming, buildGraph, checkNodeVersion, compileInputPath, defaultPaginationKeywords, definePluginConfig as definePluginConfig$1, getInputError, getLogs, getSpec, logCrashReport, logInputPaths, openGitHubIssueWithCrashReport, parseOpenApiSpec, patchOpenApiSpec, postprocessOutput, printCliIntro, printCrashReport, shouldReportCrash, utils } from "@hey-api/shared";
import colors from "ansi-colors";
import colorSupport from "color-support";
import path from "node:path";
import { fileURLToPath } from "node:url";
import fs from "node:fs";
import { $RefParser, ResolverError } from "@hey-api/json-schema-ref-parser";
import { format } from "@lukeed/ms";
import fsPromises from "node:fs/promises";
//#region src/generate/output.ts
async function generateOutput(context) {
	const outputPath = path.resolve(context.config.output.path);
	if (context.config.output.clean) {
		if (fs.existsSync(outputPath)) fs.rmSync(outputPath, {
			force: true,
			recursive: true
		});
	}
	const config = getTypedConfig(context);
	const client = getClientPlugin(config);
	if ("bundle" in client.config && client.config.bundle && !config.dryRun) config._FRAGILE_CLIENT_BUNDLE_RENAMED = generateClientBundle({
		header: config.output.header,
		module: config.output.module,
		outputPath,
		plugin: client,
		project: context.gen
	});
	for (const plugin of context.registerPlugins()) await plugin.run();
	context.gen.plan();
	const ctx = new IntentContext(context.spec);
	for (const intent of context.intents) await intent.run(ctx);
	let fileCount = 0;
	const writes = [];
	for (const file of context.gen.render()) {
		const filePath = path.resolve(outputPath, file.path);
		const dir = path.dirname(filePath);
		if (!context.config.dryRun) writes.push(fsPromises.mkdir(dir, { recursive: true }).then(() => fsPromises.writeFile(filePath, file.content, { encoding: "utf8" })));
		fileCount++;
	}
	await Promise.all(writes);
	const { source } = context.config.output;
	if (source.enabled) {
		const sourcePath = source.path === null ? void 0 : path.resolve(outputPath, source.path);
		if (!context.config.dryRun && sourcePath && sourcePath !== outputPath) await fsPromises.mkdir(sourcePath, { recursive: true });
		const serialized = await source.serialize(context.spec);
		if (!context.config.dryRun && sourcePath) {
			await fsPromises.writeFile(path.resolve(sourcePath, `${source.fileName}.${source.extension}`), serialized, { encoding: "utf8" });
			fileCount++;
		}
		if (source.callback) await source.callback(serialized);
	}
	return { fileCount };
}
//#endregion
//#region src/createClient.ts
async function createClient$1({ config, dependencies, jobIndex, logger, watches: _watches }) {
	const watches = _watches || Array.from({ length: config.input.length }, () => ({ headers: new Headers() }));
	const jobStart = Date.now();
	const inputPaths = config.input.map((input) => compileInputPath(input));
	if (config.logs.level !== "silent" && !_watches) logInputPaths(inputPaths, jobIndex);
	const getSpecData = async (input, index) => {
		const eventSpec = logger.timeEvent("spec");
		const { arrayBuffer, error, resolvedInput, response } = await getSpec({
			fetchOptions: input.fetch,
			inputPath: inputPaths[index].path,
			timeout: input.watch.timeout,
			watch: watches[index]
		});
		eventSpec.timeEnd();
		if (error && !_watches) {
			const text = await response.text().catch(() => "");
			const message = `Request failed with status ${response.status}: ${text || response.statusText}`;
			if (response.status >= 400 && response.status < 500) {
				const statusText = response.statusText || "Unknown";
				const originalError = new Error(message);
				originalError.source = String(inputPaths[index].path);
				throw new InputError(`Input request failed: ${response.status} ${statusText}`, originalError);
			}
			throw new Error(message);
		}
		return {
			arrayBuffer,
			resolvedInput
		};
	};
	const specData = (await Promise.all(config.input.map((input, index) => getSpecData(input, index)))).filter((data) => data.arrayBuffer || data.resolvedInput);
	let context;
	if (specData.length) {
		const refParser = new $RefParser();
		let data;
		try {
			data = specData.length > 1 ? await refParser.bundleMany({
				arrayBuffer: specData.map((data) => data.arrayBuffer),
				pathOrUrlOrSchemas: [],
				resolvedInputs: specData.map((data) => data.resolvedInput)
			}) : await refParser.bundle({
				arrayBuffer: specData[0].arrayBuffer,
				pathOrUrlOrSchema: void 0,
				resolvedInput: specData[0].resolvedInput
			});
		} catch (err) {
			if (err instanceof ResolverError && err.ioErrorCode === "ENOENT") throw new InputError("Input file not found", err);
			throw err;
		}
		if (config.logs.level !== "silent" && _watches) {
			console.clear();
			logInputPaths(inputPaths, jobIndex);
		}
		const eventInputPatch = logger.timeEvent("input.patch");
		await patchOpenApiSpec({
			patchOptions: config.parser.patch,
			spec: data
		});
		eventInputPatch.timeEnd();
		const eventParser = logger.timeEvent("parser");
		const header = config.output.header;
		context = new Context({
			config,
			dependencies,
			logger,
			project: new Project({
				defaultFileName: "index",
				fileName: (base) => {
					const name = applyNaming(base, config.output.fileName);
					const { suffix } = config.output.fileName;
					if (!suffix) return name;
					return name === "index" || name.endsWith(suffix) ? name : `${name}${suffix}`;
				},
				nameConflictResolvers: config.output.nameConflictResolver ? { typescript: config.output.nameConflictResolver } : void 0,
				renderers: [new TypeScriptRenderer({
					header: (ctx) => {
						const defaultValue = ["// This file is auto-generated by @hey-api/openapi-ts"];
						const result = typeof header === "function" ? header({
							...ctx,
							defaultValue
						}) : header;
						return result === void 0 ? defaultValue : result;
					},
					module: config.output.module,
					preferExportAll: config.output.preferExportAll
				})],
				root: config.output.path
			}),
			spec: data
		});
		parseOpenApiSpec(context);
		context.graph = buildGraph(context.ir, logger).graph;
		eventParser.timeEnd();
		const eventGenerator = logger.timeEvent("generator");
		const { fileCount } = await generateOutput(context);
		eventGenerator.timeEnd();
		const totalMs = Date.now() - jobStart;
		const eventPostprocess = logger.timeEvent("postprocess");
		if (!config.dryRun) {
			const jobPrefix = colors.gray(`[Job ${jobIndex + 1}] `);
			postprocessOutput(config.output, postProcessors, jobPrefix);
			if (config.logs.level !== "silent") {
				const outputPath = process.env.INIT_CWD ? `./${path.relative(process.env.INIT_CWD, config.output.path)}` : config.output.path;
				console.log(`${jobPrefix}${colors.green("✅ Done!")} Your output is in ${colors.cyanBright(outputPath)} ${colors.gray(`(${fileCount} ${fileCount === 1 ? "file" : "files"} in ${format(totalMs)})`)}`);
			}
		}
		eventPostprocess.timeEnd();
	}
	const watchedInput = config.input.find((input, index) => input.watch.enabled && typeof inputPaths[index].path === "string");
	if (watchedInput) setTimeout(() => {
		createClient$1({
			config,
			dependencies,
			jobIndex,
			logger,
			watches
		});
	}, watchedInput.watch.interval);
	return context;
}
//#endregion
//#region src/generate.ts
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/**
* Generate a client from the provided configuration.
*
* @param userConfig User provided {@link UserConfig} configuration(s).
*/
async function createClient(userConfig, logger = new Logger()) {
	const resolvedConfig = typeof userConfig === "function" ? await userConfig() : userConfig;
	const userConfigs = resolvedConfig ? resolvedConfig instanceof Array ? resolvedConfig : [resolvedConfig] : [];
	let rawLogs = userConfigs.find((config) => getLogs(config.logs).level !== "silent")?.logs;
	if (typeof rawLogs === "string") rawLogs = getLogs(rawLogs);
	let jobs = [];
	try {
		checkNodeVersion();
		const eventCreateClient = logger.timeEvent("createClient");
		const eventConfig = logger.timeEvent("config");
		const resolved = await resolveJobs({
			logger,
			userConfigs
		});
		const dependencies = resolved.dependencies;
		jobs = resolved.jobs;
		if (jobs.some((job) => job.config.logs.level !== "silent")) printCliIntro(__dirname);
		eventConfig.timeEnd();
		const configErrors = jobs.flatMap((job) => job.errors.map((error) => ({
			error,
			jobIndex: job.index
		})));
		if (configErrors.length) throw new ConfigValidationError(configErrors);
		const contexts = (await Promise.all(jobs.map(async (job) => {
			try {
				return await createClient$1({
					config: job.config,
					dependencies,
					jobIndex: job.index,
					logger
				});
			} catch (error) {
				if (error instanceof Error) throw new JobError("", {
					error,
					jobIndex: job.index
				});
			}
		}))).filter((ctx) => ctx !== void 0);
		eventCreateClient.timeEnd();
		logger.report(jobs.some((job) => job.config.logs.level === "debug"));
		return contexts;
	} catch (error) {
		const logs = jobs.find((job) => job.config.logs.level !== "silent")?.config.logs ?? jobs[0]?.config.logs ?? rawLogs;
		const dryRun = jobs.some((job) => job.config.dryRun) ?? userConfigs.some((config) => config.dryRun) ?? false;
		const inputError = getInputError(error);
		const normalizedError = inputError ?? error;
		const logPath = logs?.file && !dryRun ? logCrashReport(normalizedError, logs.path ?? "") : void 0;
		if (!logs || logs.level !== "silent") {
			printCrashReport({
				error,
				logPath
			});
			if (await shouldReportCrash({
				error: normalizedError,
				isInteractive: jobs.some((job) => job.config.interactive) ?? userConfigs.some((config) => config.interactive) ?? false
			})) await openGitHubIssueWithCrashReport(error, __dirname);
		}
		if (inputError) return [];
		throw error;
	}
}
//#endregion
//#region src/index.ts
colors.enabled = colorSupport().hasBasic;
async function defineConfig(config) {
	return typeof config === "function" ? await config() : config;
}
//#endregion
export { defineConfig as a, createClient as c, defaultPaginationKeywords as i, OperationPath$1 as n, definePluginConfig$1 as o, OperationStrategy$1 as r, utils as s, Logger$1 as t };

//# sourceMappingURL=src-CSz9FXkH.mjs.map