import { n as toNullable, t as toFormatFileResult } from "./napi-callbacks-Sb-usWTs.js";
import { n as runCli } from "./bindings-BmQGGjRm.js";
import Tinypool from "tinypool";
import { fileURLToPath, pathToFileURL } from "node:url";
import { extname } from "node:path";
//#region src-js/cli/worker-proxy.ts
let pool = null;
async function initExternalFormatter(numThreads) {
	if (pool !== null) return;
	pool = new Tinypool({
		filename: new URL("./cli-worker.js", import.meta.url).href,
		minThreads: numThreads,
		maxThreads: numThreads,
		runtime: "child_process",
		env: process.env
	});
}
async function disposeExternalFormatter() {
	await pool?.destroy();
	pool = null;
}
function formatFile(options, code) {
	return toFormatFileResult(pool.run({
		options,
		code
	}, { name: "formatFile" }));
}
function formatEmbeddedCode(options, code) {
	return toNullable(pool.run({
		options,
		code
	}, { name: "formatEmbeddedCode" }));
}
function formatEmbeddedDoc(options, texts) {
	return toNullable(pool.run({
		options,
		texts
	}, { name: "formatEmbeddedDoc" }));
}
function sortTailwindClasses(options, classes) {
	return toNullable(pool.run({
		classes,
		options
	}, { name: "sortTailwindClasses" }));
}
//#endregion
//#region ../shared/src-js/utils.ts
const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
//#endregion
//#region ../shared/src-js/js_config/node_version.ts
const NODE_TYPESCRIPT_SUPPORT_RANGE = "^20.19.0 || >=22.18.0";
const TS_MODULE_EXTENSIONS = /* @__PURE__ */ new Set([
	".ts",
	".mts",
	".cts"
]);
function normalizeModuleSpecifierPath(specifier) {
	if (!specifier.startsWith("file:")) return specifier;
	try {
		return fileURLToPath(specifier);
	} catch {
		return specifier;
	}
}
function isTypeScriptModuleSpecifier(specifier) {
	const ext = extname(normalizeModuleSpecifierPath(specifier)).toLowerCase();
	return TS_MODULE_EXTENSIONS.has(ext);
}
function isUnknownFileExtensionError(err) {
	if (err?.code === "ERR_UNKNOWN_FILE_EXTENSION") return true;
	const message = err?.message;
	return typeof message === "string" && /unknown(?: or unsupported)? file extension/i.test(message);
}
function getErrorMessage(err) {
	if (err instanceof Error) return err.message;
	return String(err);
}
/**
* Returns a complete replacement string suitable for `Error.message` assignment
* (includes the original error message + appended hint), or `null` when the
* error is unrelated to TS module loading. Callers should overwrite, not append.
*/
function getUnsupportedTypeScriptModuleLoadHintForError(err, specifier, nodeVersion = process.version) {
	if (!isTypeScriptModuleSpecifier(specifier) || !isUnknownFileExtensionError(err)) return null;
	return `${getErrorMessage(err)}\n\nTypeScript config files require Node.js ${NODE_TYPESCRIPT_SUPPORT_RANGE}.\nDetected Node.js ${nodeVersion}.\nPlease upgrade Node.js or use a JSON config file instead.`;
}
//#endregion
//#region ../shared/src-js/js_config/index.ts
/**
* Import a JS/TS config file and return its `default` export as a plain object.
*
* - Bypasses Node.js module cache (uses `?cache=<key>`) so changed files reload (used for LSP).
* - On `ERR_UNKNOWN_FILE_EXTENSION` for TS specifiers, wraps the error with a Node.js upgrade hint message;
*   The original error is preserved via `Error.cause`.
*
* @param path - Absolute path to the JS/TS config file
* @param cacheKey - Cache-busting key.
*   Callers decide whether to use a fresh value per call or share one across a batch.
* @throws When the file has no `default` export, the export is not a plain object,
*   or import fails (wrapped with hint message for unsupported TS module load).
*/
async function importJsConfig(path, cacheKey) {
	const fileUrl = pathToFileURL(path);
	fileUrl.searchParams.set("cache", cacheKey.toString());
	let module;
	try {
		module = await import(fileUrl.href);
	} catch (err) {
		const hint = getUnsupportedTypeScriptModuleLoadHintForError(err, path);
		if (hint) throw new Error(hint, { cause: err });
		throw err;
	}
	if (module.default === void 0) throw new Error("Configuration file has no default export.");
	if (!isObject(module.default)) throw new Error("Configuration file must have a default export that is an object.");
	return module.default;
}
//#endregion
//#region ../shared/src-js/vite_plus_config.ts
let vitePlusCache = null;
/**
* Resolve a Vite+ config via `vite-plus`'s `resolveConfig` and extract the given field.
*
* `vite-plus` is loaded lazily and memoized for the process.
* Consumers declare it as an optional peer dependency; tsdown leaves the specifier external
* so the user-installed copy is used at runtime.
*
* @param path - Absolute path to the Vite config file
* @param fieldName - Field name to extract from the resolved config (e.g. `"fmt"`, `"lint"`)
* @returns The field as an object, or `null` when the field is missing (signals "skip")
* @throws When the field exists but is not a plain object
*/
async function loadViteConfigField(path, fieldName) {
	vitePlusCache ??= import("vite-plus");
	const { resolveConfig } = await vitePlusCache;
	const config = await resolveConfig({ configFile: path }, "build");
	if (!(fieldName in config)) return null;
	const fieldValue = config[fieldName];
	if (!isObject(fieldValue)) throw new Error(`The \`${fieldName}\` field in the default export must be an object.`);
	return fieldValue;
}
//#endregion
//#region src-js/cli/js_config.ts
/**
* Load and validate a standard oxfmt JS/TS config file.
* The default export must be a plain object containing oxfmt options.
*
* @param path - Absolute path to the JavaScript/TypeScript config file
* @returns Config object
*/
function loadJsConfig(path) {
	return importJsConfig(path, Date.now());
}
/**
* Load a Vite+ config file (`vite.config.ts`) via `vite-plus`'s `resolveConfig` and extract the `.fmt` field.
*
* @param path - Absolute path to the Vite config file
* @returns Config object from `.fmt` field, or `null` to signal "skip"
*/
async function loadVitePlusConfig(path) {
	return loadViteConfigField(path, "fmt");
}
//#endregion
//#region src-js/cli.ts
(async () => {
	const args = process.argv.slice(2);
	if (!process.stdout.isTTY) process.stdout._handle?.setBlocking?.(true);
	if (!process.stdin.isTTY) process.stdin._handle?.setBlocking?.(true);
	if (args.includes("--lsp")) process.stdout.write = process.stderr.write.bind(process.stderr);
	const [mode, exitCode] = await runCli(args, process.env.VP_VERSION ? loadVitePlusConfig : loadJsConfig, initExternalFormatter, formatFile, formatEmbeddedCode, formatEmbeddedDoc, sortTailwindClasses);
	if (mode === "init") {
		await import("./init-DGfXRYLw.js").then((m) => m.runInit());
		return;
	}
	if (mode === "migrate:prettier") {
		await import("./migrate-prettier-ljWDi0MO.js").then((m) => m.runMigratePrettier());
		return;
	}
	if (mode === "migrate:biome") {
		await import("./migrate-biome-P928W9-y.js").then((m) => m.runMigrateBiome());
		return;
	}
	await disposeExternalFormatter();
	process.exitCode = exitCode;
	const [major, minor] = process.versions.node.split(".").map(Number);
	if (major < 25 || major === 25 && minor < 4) setTimeout(() => process.exit(), 50);
})();
//#endregion
export {};
