Files
oxc-project__oxc/apps/shared/src-js/js_config/node_version.ts
leaysgur 1ccaf767d6 refactor(oxlint,oxfmt): Fix up apps/shared usage (#22457)
Final clean up.

- Share `isObject()` function
- Clean up directory structure
- Use `Error.cause` for TS hint error
2026-05-20 08:21:39 +00:00

51 lines
1.8 KiB
TypeScript

import { extname as pathExtname } from "node:path";
import { fileURLToPath } from "node:url";
export const NODE_TYPESCRIPT_SUPPORT_RANGE = "^20.19.0 || >=22.18.0";
const TS_MODULE_EXTENSIONS = new Set([".ts", ".mts", ".cts"]);
function normalizeModuleSpecifierPath(specifier: string): string {
if (!specifier.startsWith("file:")) return specifier;
try {
return fileURLToPath(specifier);
} catch {
return specifier;
}
}
export function isTypeScriptModuleSpecifier(specifier: string): boolean {
const ext = pathExtname(normalizeModuleSpecifierPath(specifier)).toLowerCase();
return TS_MODULE_EXTENSIONS.has(ext);
}
function isUnknownFileExtensionError(err: unknown): boolean {
if ((err as { code?: unknown })?.code === "ERR_UNKNOWN_FILE_EXTENSION") return true;
const message = (err as { message?: unknown })?.message;
return typeof message === "string" && /unknown(?: or unsupported)? file extension/i.test(message);
}
function getErrorMessage(err: unknown): string {
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.
*/
export function getUnsupportedTypeScriptModuleLoadHintForError(
err: unknown,
specifier: string,
nodeVersion: string = process.version,
): string | null {
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.`;
}