jsr-exports-lint
Version:
JSR exports field lint for bundlers
48 lines (45 loc) • 1.82 kB
JavaScript
import fs from "node:fs";
import path from "node:path";
import pc from "picocolors";
//#region src/validator.ts
function validateJsrExports(entries, jsr, cwd = ".") {
const result = {};
for (const [key, value] of Object.entries(entries)) {
const exportKey = key === "index" ? "." : `./${key}`;
if (jsr[exportKey]) result[exportKey] = path.resolve(cwd, jsr[exportKey]) === value ? true : `jsr.exports["${exportKey}"] is ${jsr[exportKey]}, but it's miss-matched in your tsdown entry.`;
else result[exportKey] = `jsr.exports["${exportKey}"] does not define.`;
}
return result;
}
//#endregion
//#region src/lint.ts
/**
* Lint the `exports` field of the JSR manifest file.
* @param options An lint options, about details, see {@link LintOptions}
*/
async function lint({ jsrPath = path.resolve(process.cwd(), "jsr.json"), entries = {}, cwd = ".", silent = false } = {}) {
if (!fs.existsSync(jsrPath)) throw new Error(`jsr manifest file not found at ${jsrPath}`);
const jsr = await import(jsrPath, { with: { type: "json" } }).then((m) => m.default || m);
if (!jsr.exports) {
error(pc.dim("No jsr.exports found in jsr.json"));
process.exit(1);
}
const startTime = performance.now();
const result = validateJsrExports(entries, jsr.exports, cwd);
const endTime = performance.now();
const messages = [];
for (const [_, value] of Object.entries(result)) if (typeof value === "string") messages.push(value);
if (messages.length > 0) {
for (const msg of messages) {
console.log("");
error(pc.whiteBright(msg));
console.log("");
}
process.exit(1);
} else if (!silent) console.log(pc.green("✔"), "No JSR exports issues found", pc.dim(`(${(endTime - startTime).toFixed(2)}ms)`));
}
function error(message) {
console.error(pc.bgRed(pc.black(" ERROR ")), message);
}
//#endregion
export { lint };