UNPKG

@plugjs/plug

Version:
101 lines (100 loc) 4.4 kB
// plugs/exports.ts import { EOL } from "node:os"; import { sep } from "node:path"; import { assert } from "../asserts.mjs"; import { Files } from "../files.mjs"; import { readFile, writeFile } from "../fs.mjs"; import { $p } from "../logging.mjs"; import { assertRelativeChildPath, getAbsoluteParent } from "../paths.mjs"; import { install } from "../pipe.mjs"; install("exports", class Exports { _packageJson; _outputPackageJson; _cjsExtension; _esmExtension; constructor(...args) { const options = args[0] || {}; const { packageJson = "package.json", outputPackageJson = packageJson, cjsExtension, esmExtension } = options; this._packageJson = packageJson; this._outputPackageJson = outputPackageJson; this._cjsExtension = cjsExtension; this._esmExtension = esmExtension; } async pipe(files, context) { const incomingFile = context.resolve(this._packageJson); const incomingData = await readFile(incomingFile, "utf8"); const packageData = JSON.parse(incomingData); const outgoingFile = context.resolve(this._outputPackageJson); const outgoingDirectory = getAbsoluteParent(outgoingFile); const type = packageData.type === "module" ? "module" : packageData.type === "commonjs" ? "commonjs" : packageData.type == null ? "commonjs" : void 0; assert(type, `Unknown module type "${packageData.type}" in ${$p(incomingFile)}`); context.log.debug(`Package file ${$p(incomingFile)} declares module type "${type}"`); const cjsExtension = this._cjsExtension || (type === "commonjs" ? ".js" : ".cjs"); const esmExtension = this._esmExtension || (type === "module" ? ".js" : ".mjs"); assert(cjsExtension !== esmExtension, `CommonJS and EcmaScript modules both resolve to same extension "${cjsExtension}"`); const exports = {}; function addExport(name, type2, kind, file) { if (!exports[name]) exports[name] = {}; if (!exports[name][type2]) exports[name][type2] = {}; exports[name][type2][kind] = file; } const exts = [".d.mts", ".d.cts", ".d.ts", cjsExtension, esmExtension]; for (const [name, absolute] of files.pathMappings()) { const relative = assertRelativeChildPath(outgoingDirectory, absolute); for (const ext of exts) { if (!relative.endsWith(ext)) continue; const base = `.${sep}${name.slice(0, -ext.length)}`; const exp = base.endsWith(`${sep}index`) ? base.slice(0, -6) : base; switch (ext) { case cjsExtension: addExport(exp, "require", "default", `.${sep}${relative}`); break; case esmExtension: addExport(exp, "import", "default", `.${sep}${relative}`); break; case ".d.cts": addExport(exp, "require", "types", `.${sep}${relative}`); break; case ".d.mts": addExport(exp, "import", "types", `.${sep}${relative}`); break; case ".d.ts": addExport(exp, "require", "types", `.${sep}${relative}`); addExport(exp, "import", "types", `.${sep}${relative}`); break; } } } if ("." in exports) { const rootExport = exports["."]; packageData["main"] = rootExport?.require?.default; packageData["module"] = rootExport?.import?.default; packageData["types"] = packageData["type"] === "module" ? rootExport?.import?.types : rootExport?.require?.types; } packageData["exports"] = Object.keys(exports).sort().reduce((obj, name) => { const current = exports[name]; if (!current) return obj; obj[name] = current.require?.default || current.import?.default ? { require: current.require?.default ? { types: current.require.types || void 0, default: current.require.default || void 0 } : void 0, import: current.import?.default ? { types: current.import.types || void 0, default: current.import.default || void 0 } : void 0 } : void 0; return obj; }, {}); const outgoingData = JSON.stringify(packageData, null, 2); context.log.info(`Writing new ${$p(outgoingFile)}`, outgoingData); await writeFile(outgoingFile, outgoingData + EOL, "utf8"); return Files.builder(getAbsoluteParent(outgoingFile)).add(outgoingFile).build(); } }); //# sourceMappingURL=exports.mjs.map