195 lines
4.6 KiB
TypeScript
195 lines
4.6 KiB
TypeScript
import globalExternals from "@fal-works/esbuild-plugin-global-externals";
|
|
import { style } from "@hyrious/esbuild-plugin-style";
|
|
import { npm_page, npm_site } from "dbgen";
|
|
import { dir } from "dir";
|
|
import { build } from "esbuild";
|
|
import { $ } from "execa";
|
|
import { dirAsync, writeAsync } from "fs-jetpack";
|
|
import { stat } from "fs/promises";
|
|
import { g } from "utils/global";
|
|
import { validate } from "uuid";
|
|
import { glb } from "../global";
|
|
import { eg } from "../ws/edit/edit-global";
|
|
|
|
export type NPMImportAs = {
|
|
main: { mode: "default" | "*"; name: string };
|
|
names: string[];
|
|
custom?: string;
|
|
};
|
|
|
|
export const buildNpm = async ({
|
|
id,
|
|
mode,
|
|
_items,
|
|
}: {
|
|
id: string;
|
|
mode: "site" | "page";
|
|
_items?: npm_page[] | npm_site[];
|
|
}) => {
|
|
if (!validate(id)) return "-";
|
|
|
|
let items = _items;
|
|
if (!items) {
|
|
if (mode === "site") {
|
|
items = await db.npm_site.findMany({ where: { id_site: id } });
|
|
} else {
|
|
items = await db.npm_page.findMany({ where: { id_page: id } });
|
|
}
|
|
}
|
|
const packages: Record<string, string> = {};
|
|
|
|
const imports = items
|
|
.map((e) => {
|
|
const import_as = e.import_as as NPMImportAs;
|
|
|
|
packages[e.module] = e.version;
|
|
if (import_as.main.name || import_as.names.length > 0) {
|
|
let main = "";
|
|
let names = import_as.names.map((e) => `${e} as __${e}`);
|
|
|
|
if (import_as.main.name) {
|
|
main =
|
|
import_as.main.mode === "default"
|
|
? `__${import_as.main.name}`
|
|
: `* as __${import_as.main.name}`;
|
|
}
|
|
|
|
const imports = [
|
|
main.trim(),
|
|
(names.length > 0 ? `{ ${names.join(",")} }` : "").trim(),
|
|
].filter((e) => e);
|
|
|
|
let final = "";
|
|
if (imports.length > 0) {
|
|
final = `import ${imports.join(",")} from "${e.module}";`;
|
|
}
|
|
|
|
if (import_as.custom) {
|
|
final = final + "\n" + import_as.custom;
|
|
}
|
|
return final;
|
|
}
|
|
return "";
|
|
})
|
|
.filter((e) => !!e)
|
|
.join("\n");
|
|
|
|
const exports = items
|
|
.map((e) => {
|
|
const import_as = e.import_as as NPMImportAs;
|
|
const res: string[] = [];
|
|
|
|
if (import_as.main.name || import_as.names.length > 0) {
|
|
let main = "";
|
|
let names = import_as.names;
|
|
|
|
if (import_as.main.name) {
|
|
main = import_as.main.name;
|
|
}
|
|
|
|
if (main) {
|
|
res.push(`window.exports.${main} = __${main};`);
|
|
}
|
|
|
|
if (names.length > 0) {
|
|
names.forEach((e) => {
|
|
res.push(`window.exports.${e} = __${e};`);
|
|
});
|
|
}
|
|
}
|
|
|
|
return res.join("\n").trim();
|
|
})
|
|
.filter((e) => !!e)
|
|
.join("\n");
|
|
|
|
const src = `\
|
|
${imports}
|
|
${exports}
|
|
`.trim();
|
|
await dirAsync(dir.path(`${g.datadir}/npm/${mode}/${id}`));
|
|
await writeAsync(dir.path(`${g.datadir}/npm/${mode}/${id}/input.js`), src);
|
|
packages["react"] = "18.2.0";
|
|
packages["react-dom"] = "18.2.0";
|
|
await writeAsync(dir.path(`${g.datadir}/npm/${mode}/${id}/package.json`), {
|
|
dependencies: packages,
|
|
});
|
|
await writeAsync(
|
|
dir.path(`${g.datadir}/npm/${mode}/${id}/pnpm-workspace.yaml`),
|
|
`\
|
|
packages:
|
|
- ./*`
|
|
);
|
|
try {
|
|
await $({
|
|
cwd: dir.path(`${g.datadir}/npm/${mode}/${id}`),
|
|
})`pnpm i`;
|
|
|
|
await build({
|
|
absWorkingDir: dir.path(`${g.datadir}/npm/${mode}/${id}`),
|
|
entryPoints: ["input.js"],
|
|
bundle: true,
|
|
outfile: "index.js",
|
|
minify: true,
|
|
treeShaking: true,
|
|
sourcemap: true,
|
|
plugins: [
|
|
style(),
|
|
globalExternals({
|
|
react: {
|
|
varName: "window.React",
|
|
type: "cjs",
|
|
},
|
|
"react-dom": {
|
|
varName: "window.ReactDOM",
|
|
type: "cjs",
|
|
},
|
|
}),
|
|
],
|
|
logLevel: "silent",
|
|
});
|
|
} catch (e) {
|
|
return e;
|
|
}
|
|
|
|
try {
|
|
const s = await stat(dir.path(`${g.datadir}/npm/${mode}/${id}/index.js`));
|
|
|
|
if (mode === "page") {
|
|
delete glb.npm.page[id];
|
|
await db.npm_page.updateMany({
|
|
where: {
|
|
id_page: id,
|
|
},
|
|
data: { bundled: true },
|
|
});
|
|
const p = eg.edit.page[id];
|
|
if (p) {
|
|
await db.page.update({
|
|
where: {
|
|
id,
|
|
},
|
|
data: {
|
|
updated_at: new Date(),
|
|
},
|
|
});
|
|
p.doc.getMap("map").set("updated_at", new Date().toISOString());
|
|
}
|
|
} else if (mode === "site") {
|
|
delete glb.npm.site[id];
|
|
|
|
await db.npm_site.updateMany({
|
|
where: {
|
|
id_site: id,
|
|
},
|
|
data: { bundled: true },
|
|
});
|
|
}
|
|
|
|
return s.size.toString();
|
|
} catch (e) {
|
|
console.error(e);
|
|
return "-";
|
|
}
|
|
};
|