@plugjs/plug
Version:
PlugJS Build System ===================
101 lines (100 loc) • 4.4 kB
JavaScript
// 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