mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-10-03 18:23:47 +10:00
The conversion of stored legacy style rules to Semantic CSS no longer runs when the server starts. The image now ships apps/server/dist/migrate-legacy-styles.mjs, run by hand against DATABASE_URL: - without flags it's a dry run that converts in memory and reports counts - --apply --backup <file> converts, appending every replaced stylesheet to the backup file before its row is written - --restore <file> puts those stylesheets back, except on rows edited since Each table is scanned once for the rows that need converting, then they're converted in batches with progress logged. Only metadata.stylesheet is rewritten, a row whose stylesheet changed after it was read is left alone, and running it again skips what's converted. The data_migration table that recorded the startup run is gone. The self-hosting guide explains the one-time run.
91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
import type { TsdownPlugin } from "tsdown";
|
|
import { readdirSync, readFileSync } from "node:fs";
|
|
import { dirname, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { defineConfig } from "tsdown";
|
|
|
|
const rootPackageJson = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url), "utf-8")) as {
|
|
version?: string;
|
|
};
|
|
|
|
// Lambda disables require(ESM) and uses stricter CJS export detection than standalone Node.
|
|
const bundledInteropPackages = new Set([
|
|
"@uiw/color-convert",
|
|
"@babel/runtime",
|
|
"sanitize-html",
|
|
"htmlparser2",
|
|
"domhandler",
|
|
"domutils",
|
|
"domelementtype",
|
|
"dom-serializer",
|
|
"entities",
|
|
"deepmerge",
|
|
"escape-string-regexp",
|
|
"is-plain-object",
|
|
"parse-srcset",
|
|
"postcss",
|
|
"nanoid",
|
|
"picocolors",
|
|
"source-map-js",
|
|
"launder",
|
|
"dayjs",
|
|
]);
|
|
|
|
const shouldExternalizeThirdParty = (id: string) => {
|
|
const packageName = id
|
|
.split("/")
|
|
.slice(0, id.startsWith("@") ? 2 : 1)
|
|
.join("/");
|
|
if (id.startsWith("@reactive-resume/") || bundledInteropPackages.has(packageName)) return false;
|
|
// Subpath imports (`#…`) are resolved by the workspace package that declares them, so they're bundled with it.
|
|
if (id.startsWith("@/") || id.startsWith("#") || id.startsWith(".") || id.startsWith("/") || id.startsWith("\0"))
|
|
return false;
|
|
|
|
return true;
|
|
};
|
|
|
|
const aiPromptsDir = resolve(dirname(fileURLToPath(import.meta.url)), "../../packages/ai/src/prompts");
|
|
|
|
const promptAssetsPlugin: TsdownPlugin = {
|
|
name: "prompt-assets",
|
|
buildStart() {
|
|
for (const filename of readdirSync(aiPromptsDir)) {
|
|
if (!filename.endsWith(".md")) continue;
|
|
|
|
this.emitFile({
|
|
type: "asset",
|
|
fileName: `prompts/${filename}`,
|
|
source: readFileSync(resolve(aiPromptsDir, filename), "utf-8"),
|
|
});
|
|
}
|
|
},
|
|
};
|
|
|
|
export default defineConfig({
|
|
entry: {
|
|
index: "src/index.ts",
|
|
vercel: "src/vercel.ts",
|
|
"prepare-deployment": "src/prepare-deployment.ts",
|
|
"migrate-legacy-styles": "src/migrate-legacy-styles.ts",
|
|
},
|
|
// Keep import.meta.url-based asset lookup adjacent to the entrypoints.
|
|
outputOptions: { chunkFileNames: "[name]-[hash].mjs" },
|
|
format: "esm",
|
|
platform: "node",
|
|
target: "node24",
|
|
outDir: "dist",
|
|
clean: true,
|
|
shims: true,
|
|
dts: false,
|
|
define: { __APP_VERSION__: JSON.stringify(rootPackageJson.version ?? "0.0.0") },
|
|
// The flagged dynamic imports are deliberate: they defer evaluation of env-dependent
|
|
// modules so tests can run without env vars, not to split chunks.
|
|
suppressWarnings: [/dynamic import will not move module into another chunk/],
|
|
outExtensions: () => ({ js: ".mjs" }),
|
|
deps: {
|
|
alwaysBundle: [/^@reactive-resume\//, ...bundledInteropPackages],
|
|
neverBundle: shouldExternalizeThirdParty,
|
|
},
|
|
plugins: [promptAssetsPlugin],
|
|
});
|