unplugin-isolated-decl
Version:
A blazing-fast tool for generating isolated declarations.
103 lines (101 loc) • 2.96 kB
JavaScript
import path from "node:path";
//#region src/core/transformer.ts
function tryImport(pkg) {
return import(pkg).catch(() => null);
}
async function oxcTransform(id, code, transformOptions) {
const oxc = await tryImport("oxc-transform");
if (!oxc) return {
code: "",
errors: ["oxc-transform is required for transforming TypeScript, please install `oxc-transform`."]
};
const result = oxc.isolatedDeclaration(id, code, transformOptions);
return {
...result,
map: result.map?.mappings,
errors: result.errors.map((error) => error.message)
};
}
async function swcTransform(id, code) {
const swc = await tryImport("@swc/core");
if (!swc) return {
code: "",
errors: ["SWC is required for transforming TypeScript, please install `@swc/core`."]
};
try {
const result = await swc.transform(code, {
filename: id,
jsc: {
parser: {
syntax: "typescript",
tsx: false
},
experimental: { emitIsolatedDts: true }
}
});
const output = JSON.parse(result.output);
return {
code: output.__swc_isolated_declarations__,
errors: []
};
} catch (error) {
return {
code: "",
errors: [error.toString()]
};
}
}
async function tsTransform(id, code, transformOptions, sourceMap) {
const ts = await tryImport("typescript");
if (!ts) return {
code: "",
errors: ["TypeScript is required for transforming TypeScript, please install `typescript`."]
};
if (!ts.transpileDeclaration) return {
code: "",
errors: ["TypeScript version is too low, please upgrade to TypeScript 5.5.2+."]
};
const compilerOptions = {
declarationMap: sourceMap,
...transformOptions?.compilerOptions
};
let { outputText, diagnostics, sourceMapText } = ts.transpileDeclaration(code, {
fileName: id,
reportDiagnostics: true,
...transformOptions,
compilerOptions
});
if (compilerOptions.declarationMap) outputText = stripMapUrl(outputText);
const errors = diagnostics?.length ? [ts.formatDiagnostics(diagnostics, {
getCanonicalFileName: (fileName) => ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(),
getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
getNewLine: () => ts.sys.newLine
})] : [];
if (sourceMapText) sourceMapText = JSON.parse(sourceMapText).mappings;
return {
code: outputText,
errors,
map: sourceMapText
};
}
function stripMapUrl(code) {
const lines = code.split("\n");
const lastLine = lines.at(-1);
if (lastLine?.startsWith("//# sourceMappingURL=")) return lines.slice(0, -1).join("\n");
return code;
}
function appendMapUrl(map, filename) {
return `${map}\n//# sourceMappingURL=${path.basename(filename)}.map`;
}
function generateDtsMap(mappings, src, dts) {
return JSON.stringify({
version: 3,
file: path.basename(dts),
sourceRoot: "",
sources: [path.relative(path.dirname(dts), src).replaceAll("\\", "/")],
names: [],
mappings
});
}
//#endregion
export { appendMapUrl, generateDtsMap, oxcTransform, swcTransform, tsTransform };