Files
test-repo/scripts/vendors/bundle-vendors.mjs
T

128 lines
3.2 KiB
JavaScript

#!/usr/bin/env node
import fs from "node:fs/promises";
import path from "node:path";
import assert from "node:assert";
import createEsmUtils from "esm-utils";
import esbuild from "esbuild";
import { outdent } from "outdent";
import { PROJECT_ROOT, writeJson } from "../utils/index.mjs";
import esbuildPluginLicense from "../build/esbuild-plugins/license.mjs";
import vendors from "./vendors.mjs";
import {
vendorsDirectory,
vendorMetaFile,
saveVendorLicenses,
saveVendorEntry,
} from "./utils.mjs";
import esbuildPluginTsNocheck from "./esbuild-plugin-ts-nocheck.mjs";
const { require } = createEsmUtils(import.meta);
// prettier/vendors/*.js
const getVendorFilePath = (vendorName, extension = "js") =>
path.join(vendorsDirectory, `${vendorName}.${extension}`);
// Unsafe, but good enough for now.
const isJson = (value) => {
try {
assert.deepStrictEqual(JSON.parse(JSON.stringify(value)), { ...value });
return true;
} catch {
return false;
}
};
async function clean() {
for (const directoryOrFile of [vendorsDirectory, vendorMetaFile]) {
try {
await fs.rm(directoryOrFile, { recursive: true, force: true });
} catch {
// No op
}
}
}
async function generateDts({ vendor, module }) {
const hasDefault = Boolean(module.default);
await fs.writeFile(
path.join(vendorsDirectory, `${vendor}.d.ts`),
[
"// This file is generated automatically.",
hasDefault ? `export {default} from "${vendor}";` : null,
`export * from "${vendor}";`,
"",
]
.filter((line) => line !== null)
.join("\n"),
"utf8"
);
}
async function bundle(vendor, options) {
const outfile = getVendorFilePath(vendor);
/** @type {import("esbuild").CommonOptions} */
const esbuildOption = {
entryPoints: [require.resolve(vendor)],
bundle: true,
target: ["node12.17.0"],
platform: "node",
plugins: [
esbuildPluginTsNocheck(),
esbuildPluginLicense({
cwd: PROJECT_ROOT,
thirdParty: {
includePrivate: true,
output: options.onLicenseFound,
},
}),
],
outfile,
};
await esbuild.build(esbuildOption);
// Still running esbuild, because we want collect license
const module = await import(vendor);
if (isJson(module)) {
await fs.rm(outfile);
const file = getVendorFilePath(vendor, "json");
await writeJson(file, module);
saveVendorEntry(vendor, file);
return;
}
await generateDts({ vendor, module });
saveVendorEntry(vendor, outfile);
}
async function main() {
await clean();
const licenses = [];
for (const vendor of vendors) {
await bundle(vendor, {
onLicenseFound(dependencies) {
licenses.push(...dependencies);
},
});
console.log(`Bundled: ${vendor}`);
}
await saveVendorLicenses(licenses);
console.log("Vendor licenses saved");
await fs.writeFile(
path.join(vendorsDirectory, "README.md"),
outdent`
# \`./vendors\`
**JavaScript Files that included in this directory are auto generated by [\`/scripts/vendor/bundle-vendors.mjs\`](../scripts/vendors/bundle-vendors.mjs).**
See [\`/scripts/vendors/README.md\`](../scripts/vendors/README.md) for the context.
` + "\n"
);
console.log("`README.md` file saved");
}
await main();