support arm64 reactive resume image layout
This commit is contained in:
4
dist/SHA256SUMS
vendored
4
dist/SHA256SUMS
vendored
@@ -1,3 +1,3 @@
|
|||||||
fa3b2b64a9afd7af60f57cfda8431af4e171cc1cdba4a6a2b89d50000a574f54 reactive-resume-clean-install-20260520.zip
|
fa3b2b64a9afd7af60f57cfda8431af4e171cc1cdba4a6a2b89d50000a574f54 reactive-resume-clean-install-20260520.zip
|
||||||
d76b4920388fac71edcc6d84e1db609f62c4c2b7a3aa34f5fe3bad33813d9cba reactive-resume-personal-direct-20260520.zip
|
6724400586b14de9a954dcb22e1b7150d8339b3ebf07bb5b0685a5aa60009bc9 reactive-resume-personal-direct-20260520.zip
|
||||||
c949c68c6c3343c3d6db6ee13deb49c0a575ee9c758fac75ff647c6ff93e8da3 reactive-resume-personal-qnap-nas-20260520.zip
|
21e588dc25e90e358f823175cfab7ef4b4880fed959bab8d9d7c65200848b6d0 reactive-resume-personal-qnap-nas-20260520.zip
|
||||||
|
|||||||
4
dist/SHA256SUMS-20260520
vendored
4
dist/SHA256SUMS-20260520
vendored
@@ -1,3 +1,3 @@
|
|||||||
fa3b2b64a9afd7af60f57cfda8431af4e171cc1cdba4a6a2b89d50000a574f54 reactive-resume-clean-install-20260520.zip
|
fa3b2b64a9afd7af60f57cfda8431af4e171cc1cdba4a6a2b89d50000a574f54 reactive-resume-clean-install-20260520.zip
|
||||||
d76b4920388fac71edcc6d84e1db609f62c4c2b7a3aa34f5fe3bad33813d9cba reactive-resume-personal-direct-20260520.zip
|
6724400586b14de9a954dcb22e1b7150d8339b3ebf07bb5b0685a5aa60009bc9 reactive-resume-personal-direct-20260520.zip
|
||||||
c949c68c6c3343c3d6db6ee13deb49c0a575ee9c758fac75ff647c6ff93e8da3 reactive-resume-personal-qnap-nas-20260520.zip
|
21e588dc25e90e358f823175cfab7ef4b4880fed959bab8d9d7c65200848b6d0 reactive-resume-personal-qnap-nas-20260520.zip
|
||||||
|
|||||||
BIN
dist/reactive-resume-personal-direct-20260520.zip
vendored
BIN
dist/reactive-resume-personal-direct-20260520.zip
vendored
Binary file not shown.
BIN
dist/reactive-resume-personal-qnap-nas-20260520.zip
vendored
BIN
dist/reactive-resume-personal-qnap-nas-20260520.zip
vendored
Binary file not shown.
@@ -21,16 +21,7 @@ services:
|
|||||||
reactive-resume:
|
reactive-resume:
|
||||||
image: amruthpillai/reactive-resume:latest
|
image: amruthpillai/reactive-resume:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint: ["/bin/sh", "-c"]
|
entrypoint: ["/bin/sh", "/opt/reactive-resume-patches/reactive-resume-entrypoint.sh"]
|
||||||
command:
|
|
||||||
- |
|
|
||||||
sh /opt/reactive-resume-patches/reactive-resume-runtime-patch.sh
|
|
||||||
APP_DIR="$(cat /tmp/reactive-resume-app-dir 2>/dev/null || true)"
|
|
||||||
if [ -z "$$APP_DIR" ]; then
|
|
||||||
APP_DIR="$(find /app -path '*/.output/server/index.mjs' -type f 2>/dev/null | head -n 1 | sed 's#/.output/server/index.mjs##')"
|
|
||||||
fi
|
|
||||||
cd "$${APP_DIR:-/app/apps/web}"
|
|
||||||
exec node .output/server/index.mjs
|
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
ports:
|
ports:
|
||||||
@@ -38,6 +29,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- reactive_resume_data:/app/data
|
- reactive_resume_data:/app/data
|
||||||
- ./patches/reactive-resume-runtime-patch.sh:/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh:ro
|
- ./patches/reactive-resume-runtime-patch.sh:/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh:ro
|
||||||
|
- ./patches/reactive-resume-entrypoint.sh:/opt/reactive-resume-patches/reactive-resume-entrypoint.sh:ro
|
||||||
networks:
|
networks:
|
||||||
- resume_net
|
- resume_net
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
PATCH_SCRIPT="/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh"
|
||||||
|
|
||||||
|
if [ -f "$PATCH_SCRIPT" ]; then
|
||||||
|
sh "$PATCH_SCRIPT" || echo "Reactive Resume runtime patch failed, continuing with the image default startup" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ]; then
|
||||||
|
if [ -f /app/apps/server/dist/index.mjs ]; then
|
||||||
|
cd /app
|
||||||
|
set -- node apps/server/dist/index.mjs
|
||||||
|
elif [ -f /app/apps/web/.output/server/index.mjs ]; then
|
||||||
|
cd /app/apps/web
|
||||||
|
set -- node .output/server/index.mjs
|
||||||
|
else
|
||||||
|
server_entry="$(cat /tmp/reactive-resume-server-entry 2>/dev/null || true)"
|
||||||
|
if [ -n "$server_entry" ] && [ -f "$server_entry" ]; then
|
||||||
|
cd "$(dirname "$server_entry")"
|
||||||
|
set -- node "$(basename "$server_entry")"
|
||||||
|
else
|
||||||
|
echo "Reactive Resume startup failed: no known server entry found" >&2
|
||||||
|
find /app -maxdepth 5 \( -name index.mjs -o -name server.js -o -name main.js \) 2>/dev/null | head -50 >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v docker-entrypoint.sh >/dev/null 2>&1; then
|
||||||
|
exec docker-entrypoint.sh "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$@"
|
||||||
@@ -2,40 +2,64 @@
|
|||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
APP_DIR="${REACTIVE_RESUME_APP_DIR:-}"
|
APP_DIR="${REACTIVE_RESUME_APP_DIR:-}"
|
||||||
|
SERVER_ENTRY=""
|
||||||
|
ASSETS_DIR=""
|
||||||
|
SSR_DIR=""
|
||||||
|
SERVER_INDEX_FILE=""
|
||||||
|
SSR_FILE=""
|
||||||
|
|
||||||
if [ -z "$APP_DIR" ]; then
|
if [ -z "$APP_DIR" ]; then
|
||||||
for candidate in /app/apps/web /app; do
|
for candidate in /app/apps/web /app; do
|
||||||
if [ -f "$candidate/.output/server/index.mjs" ]; then
|
if [ -f "$candidate/.output/server/index.mjs" ]; then
|
||||||
APP_DIR="$candidate"
|
APP_DIR="$candidate"
|
||||||
|
SERVER_ENTRY="$candidate/.output/server/index.mjs"
|
||||||
|
ASSETS_DIR="$candidate/.output/public/assets"
|
||||||
|
SSR_DIR="$candidate/.output/server/_ssr"
|
||||||
|
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$APP_DIR" ]; then
|
if [ -z "$SERVER_ENTRY" ]; then
|
||||||
index_file="$(find /app -path "*/.output/server/index.mjs" -type f 2>/dev/null | head -n 1 || true)"
|
index_file="$(find /app -path "*/.output/server/index.mjs" -type f 2>/dev/null | head -n 1 || true)"
|
||||||
if [ -n "$index_file" ]; then
|
if [ -n "$index_file" ]; then
|
||||||
APP_DIR="${index_file%/.output/server/index.mjs}"
|
APP_DIR="${index_file%/.output/server/index.mjs}"
|
||||||
|
SERVER_ENTRY="$index_file"
|
||||||
|
ASSETS_DIR="$APP_DIR/.output/public/assets"
|
||||||
|
SSR_DIR="$APP_DIR/.output/server/_ssr"
|
||||||
|
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$APP_DIR" ] || [ ! -f "$APP_DIR/.output/server/index.mjs" ]; then
|
if [ -z "$SERVER_ENTRY" ] && [ -f /app/apps/server/dist/index.mjs ]; then
|
||||||
echo "Reactive Resume runtime patch skipped: .output/server/index.mjs not found under /app" >&2
|
APP_DIR="/app"
|
||||||
|
SERVER_ENTRY="/app/apps/server/dist/index.mjs"
|
||||||
|
ASSETS_DIR="/app/apps/web/dist/assets"
|
||||||
|
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||||
|
SSR_FILE="$SERVER_ENTRY"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$SERVER_ENTRY" ] || [ ! -f "$SERVER_ENTRY" ]; then
|
||||||
|
echo "Reactive Resume runtime patch skipped: server entry not found under /app" >&2
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf "%s" "$APP_DIR" > /tmp/reactive-resume-app-dir
|
printf "%s" "$APP_DIR" > /tmp/reactive-resume-app-dir
|
||||||
export APP_DIR
|
printf "%s" "$SERVER_ENTRY" > /tmp/reactive-resume-server-entry
|
||||||
|
export APP_DIR ASSETS_DIR SSR_DIR SERVER_INDEX_FILE SSR_FILE SERVER_ENTRY
|
||||||
|
|
||||||
node - <<'NODE'
|
node - <<'NODE'
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
|
|
||||||
const appDir = process.env.APP_DIR;
|
const appDir = process.env.APP_DIR || "/app";
|
||||||
const outputDir = path.join(appDir, ".output");
|
const outputDir = path.join(appDir, ".output");
|
||||||
const assetsDir = path.join(outputDir, "public/assets");
|
const assetsDir = process.env.ASSETS_DIR || path.join(outputDir, "public/assets");
|
||||||
const ssrDir = path.join(outputDir, "server/_ssr");
|
const ssrDir = process.env.SSR_DIR || "";
|
||||||
const serverIndexFile = path.join(outputDir, "server/index.mjs");
|
const explicitSsrFile = process.env.SSR_FILE || "";
|
||||||
|
const serverIndexFile = process.env.SERVER_INDEX_FILE || path.join(outputDir, "server/index.mjs");
|
||||||
const filenameCacheBust = "rr-filename-title-20260520";
|
const filenameCacheBust = "rr-filename-title-20260520";
|
||||||
const pdfCacheBust = "rr-glalie-layout-20260520";
|
const pdfCacheBust = "rr-glalie-layout-20260520";
|
||||||
const browserBufferPolyfill = "var Buffer=globalThis.Buffer??{isBuffer:()=>false,allocUnsafe:e=>new Uint8Array(e),alloc:e=>new Uint8Array(e)};/* rr-browser-buffer-polyfill */";
|
const browserBufferPolyfill = "var Buffer=globalThis.Buffer??{isBuffer:()=>false,allocUnsafe:e=>new Uint8Array(e),alloc:e=>new Uint8Array(e)};/* rr-browser-buffer-polyfill */";
|
||||||
@@ -117,6 +141,10 @@ function patchSsr(source) {
|
|||||||
|
|
||||||
const filenameReplacement = `function generateFilename(prefix, extension) {\n\tlet filename = (prefix || "resume").toString().trim() || "resume";\n\tfilename = filename.replace(/[\\\\/:*?"<>|]/g, "-").replace(/\\s+/g, " ").replace(/\\.+$/, "").trim() || "resume";\n\treturn extension && filename.toLowerCase().endsWith(\`.\${extension.toLowerCase()}\`) ? filename : \`\${filename}\${extension ? \`.\${extension}\` : ""}\`;\n}`;
|
const filenameReplacement = `function generateFilename(prefix, extension) {\n\tlet filename = (prefix || "resume").toString().trim() || "resume";\n\tfilename = filename.replace(/[\\\\/:*?"<>|]/g, "-").replace(/\\s+/g, " ").replace(/\\.+$/, "").trim() || "resume";\n\treturn extension && filename.toLowerCase().endsWith(\`.\${extension.toLowerCase()}\`) ? filename : \`\${filename}\${extension ? \`.\${extension}\` : ""}\`;\n}`;
|
||||||
if (!source.includes(filenameReplacement)) {
|
if (!source.includes(filenameReplacement)) {
|
||||||
|
const slugifiedPattern = /function generateFilename\(prefix, extension\) \{\s*return `\$\{slugify\(prefix\)\}\$\{extension \? `\.\$\{extension\}` : ""\}`;\s*\}/;
|
||||||
|
if (slugifiedPattern.test(source)) {
|
||||||
|
source = source.replace(slugifiedPattern, filenameReplacement);
|
||||||
|
} else {
|
||||||
const start = source.indexOf("function generateFilename(");
|
const start = source.indexOf("function generateFilename(");
|
||||||
const end = source.indexOf("\nfunction downloadWithAnchor(", start);
|
const end = source.indexOf("\nfunction downloadWithAnchor(", start);
|
||||||
if (start !== -1 && end !== -1) {
|
if (start !== -1 && end !== -1) {
|
||||||
@@ -125,6 +153,7 @@ function patchSsr(source) {
|
|||||||
warn("SSR generateFilename marker not found, skipped");
|
warn("SSR generateFilename marker not found, skipped");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
source = source
|
source = source
|
||||||
.replace(/const sideMargin = bodyLineHeight \* \.(?:2|08);/, "const sideMargin = bodyLineHeight * .08;")
|
.replace(/const sideMargin = bodyLineHeight \* \.(?:2|08);/, "const sideMargin = bodyLineHeight * .08;")
|
||||||
@@ -155,7 +184,8 @@ function patchSsr(source) {
|
|||||||
|
|
||||||
function patchPublicPdf(source) {
|
function patchPublicPdf(source) {
|
||||||
if (!source.includes("rr-browser-buffer-polyfill")) {
|
if (!source.includes("rr-browser-buffer-polyfill")) {
|
||||||
const insertAt = source.indexOf(";") + 1;
|
const importPrelude = source.match(/^(?:import[^;]+;)+/);
|
||||||
|
const insertAt = importPrelude ? importPrelude[0].length : source.indexOf(";") + 1;
|
||||||
if (insertAt > 0 && source.startsWith("import")) {
|
if (insertAt > 0 && source.startsWith("import")) {
|
||||||
source = source.slice(0, insertAt) + browserBufferPolyfill + source.slice(insertAt);
|
source = source.slice(0, insertAt) + browserBufferPolyfill + source.slice(insertAt);
|
||||||
} else {
|
} else {
|
||||||
@@ -193,7 +223,9 @@ for (const file of filenameFiles) {
|
|||||||
if (patchedFilenameFiles.length === 0) warn("no filename bundle patched");
|
if (patchedFilenameFiles.length === 0) warn("no filename bundle patched");
|
||||||
|
|
||||||
let ssrFile = "";
|
let ssrFile = "";
|
||||||
if (fs.existsSync(ssrDir)) {
|
if (explicitSsrFile && fs.existsSync(explicitSsrFile) && read(explicitSsrFile).includes("function generateFilename(")) {
|
||||||
|
ssrFile = explicitSsrFile;
|
||||||
|
} else if (ssrDir && fs.existsSync(ssrDir)) {
|
||||||
ssrFile = fs.readdirSync(ssrDir)
|
ssrFile = fs.readdirSync(ssrDir)
|
||||||
.filter((name) => name.endsWith(".mjs"))
|
.filter((name) => name.endsWith(".mjs"))
|
||||||
.map((name) => path.join(ssrDir, name))
|
.map((name) => path.join(ssrDir, name))
|
||||||
|
|||||||
@@ -44,16 +44,7 @@ services:
|
|||||||
reactive_resume_app:
|
reactive_resume_app:
|
||||||
image: amruthpillai/reactive-resume:latest
|
image: amruthpillai/reactive-resume:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint: ["/bin/sh", "-c"]
|
entrypoint: ["/bin/sh", "/opt/reactive-resume-patches/reactive-resume-entrypoint.sh"]
|
||||||
command:
|
|
||||||
- |
|
|
||||||
sh /opt/reactive-resume-patches/reactive-resume-runtime-patch.sh
|
|
||||||
APP_DIR="$(cat /tmp/reactive-resume-app-dir 2>/dev/null || true)"
|
|
||||||
if [ -z "$$APP_DIR" ]; then
|
|
||||||
APP_DIR="$(find /app -path '*/.output/server/index.mjs' -type f 2>/dev/null | head -n 1 | sed 's#/.output/server/index.mjs##')"
|
|
||||||
fi
|
|
||||||
cd "$${APP_DIR:-/app/apps/web}"
|
|
||||||
exec node .output/server/index.mjs
|
|
||||||
depends_on:
|
depends_on:
|
||||||
reactive_resume_permissions:
|
reactive_resume_permissions:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
@@ -64,6 +55,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- /share/Container/reactive_resume/data/uploads:/app/data
|
- /share/Container/reactive_resume/data/uploads:/app/data
|
||||||
- /share/Container/reactive_resume/patches/reactive-resume-runtime-patch.sh:/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh:ro
|
- /share/Container/reactive_resume/patches/reactive-resume-runtime-patch.sh:/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh:ro
|
||||||
|
- /share/Container/reactive_resume/patches/reactive-resume-entrypoint.sh:/opt/reactive-resume-patches/reactive-resume-entrypoint.sh:ro
|
||||||
environment:
|
environment:
|
||||||
HTTP_PROXY: http://192.168.3.12:7893
|
HTTP_PROXY: http://192.168.3.12:7893
|
||||||
HTTPS_PROXY: http://192.168.3.12:7893
|
HTTPS_PROXY: http://192.168.3.12:7893
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
PATCH_SCRIPT="/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh"
|
||||||
|
|
||||||
|
if [ -f "$PATCH_SCRIPT" ]; then
|
||||||
|
sh "$PATCH_SCRIPT" || echo "Reactive Resume runtime patch failed, continuing with the image default startup" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ]; then
|
||||||
|
if [ -f /app/apps/server/dist/index.mjs ]; then
|
||||||
|
cd /app
|
||||||
|
set -- node apps/server/dist/index.mjs
|
||||||
|
elif [ -f /app/apps/web/.output/server/index.mjs ]; then
|
||||||
|
cd /app/apps/web
|
||||||
|
set -- node .output/server/index.mjs
|
||||||
|
else
|
||||||
|
server_entry="$(cat /tmp/reactive-resume-server-entry 2>/dev/null || true)"
|
||||||
|
if [ -n "$server_entry" ] && [ -f "$server_entry" ]; then
|
||||||
|
cd "$(dirname "$server_entry")"
|
||||||
|
set -- node "$(basename "$server_entry")"
|
||||||
|
else
|
||||||
|
echo "Reactive Resume startup failed: no known server entry found" >&2
|
||||||
|
find /app -maxdepth 5 \( -name index.mjs -o -name server.js -o -name main.js \) 2>/dev/null | head -50 >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v docker-entrypoint.sh >/dev/null 2>&1; then
|
||||||
|
exec docker-entrypoint.sh "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$@"
|
||||||
@@ -2,40 +2,64 @@
|
|||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
APP_DIR="${REACTIVE_RESUME_APP_DIR:-}"
|
APP_DIR="${REACTIVE_RESUME_APP_DIR:-}"
|
||||||
|
SERVER_ENTRY=""
|
||||||
|
ASSETS_DIR=""
|
||||||
|
SSR_DIR=""
|
||||||
|
SERVER_INDEX_FILE=""
|
||||||
|
SSR_FILE=""
|
||||||
|
|
||||||
if [ -z "$APP_DIR" ]; then
|
if [ -z "$APP_DIR" ]; then
|
||||||
for candidate in /app/apps/web /app; do
|
for candidate in /app/apps/web /app; do
|
||||||
if [ -f "$candidate/.output/server/index.mjs" ]; then
|
if [ -f "$candidate/.output/server/index.mjs" ]; then
|
||||||
APP_DIR="$candidate"
|
APP_DIR="$candidate"
|
||||||
|
SERVER_ENTRY="$candidate/.output/server/index.mjs"
|
||||||
|
ASSETS_DIR="$candidate/.output/public/assets"
|
||||||
|
SSR_DIR="$candidate/.output/server/_ssr"
|
||||||
|
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$APP_DIR" ]; then
|
if [ -z "$SERVER_ENTRY" ]; then
|
||||||
index_file="$(find /app -path "*/.output/server/index.mjs" -type f 2>/dev/null | head -n 1 || true)"
|
index_file="$(find /app -path "*/.output/server/index.mjs" -type f 2>/dev/null | head -n 1 || true)"
|
||||||
if [ -n "$index_file" ]; then
|
if [ -n "$index_file" ]; then
|
||||||
APP_DIR="${index_file%/.output/server/index.mjs}"
|
APP_DIR="${index_file%/.output/server/index.mjs}"
|
||||||
|
SERVER_ENTRY="$index_file"
|
||||||
|
ASSETS_DIR="$APP_DIR/.output/public/assets"
|
||||||
|
SSR_DIR="$APP_DIR/.output/server/_ssr"
|
||||||
|
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$APP_DIR" ] || [ ! -f "$APP_DIR/.output/server/index.mjs" ]; then
|
if [ -z "$SERVER_ENTRY" ] && [ -f /app/apps/server/dist/index.mjs ]; then
|
||||||
echo "Reactive Resume runtime patch skipped: .output/server/index.mjs not found under /app" >&2
|
APP_DIR="/app"
|
||||||
|
SERVER_ENTRY="/app/apps/server/dist/index.mjs"
|
||||||
|
ASSETS_DIR="/app/apps/web/dist/assets"
|
||||||
|
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||||
|
SSR_FILE="$SERVER_ENTRY"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$SERVER_ENTRY" ] || [ ! -f "$SERVER_ENTRY" ]; then
|
||||||
|
echo "Reactive Resume runtime patch skipped: server entry not found under /app" >&2
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf "%s" "$APP_DIR" > /tmp/reactive-resume-app-dir
|
printf "%s" "$APP_DIR" > /tmp/reactive-resume-app-dir
|
||||||
export APP_DIR
|
printf "%s" "$SERVER_ENTRY" > /tmp/reactive-resume-server-entry
|
||||||
|
export APP_DIR ASSETS_DIR SSR_DIR SERVER_INDEX_FILE SSR_FILE SERVER_ENTRY
|
||||||
|
|
||||||
node - <<'NODE'
|
node - <<'NODE'
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
|
|
||||||
const appDir = process.env.APP_DIR;
|
const appDir = process.env.APP_DIR || "/app";
|
||||||
const outputDir = path.join(appDir, ".output");
|
const outputDir = path.join(appDir, ".output");
|
||||||
const assetsDir = path.join(outputDir, "public/assets");
|
const assetsDir = process.env.ASSETS_DIR || path.join(outputDir, "public/assets");
|
||||||
const ssrDir = path.join(outputDir, "server/_ssr");
|
const ssrDir = process.env.SSR_DIR || "";
|
||||||
const serverIndexFile = path.join(outputDir, "server/index.mjs");
|
const explicitSsrFile = process.env.SSR_FILE || "";
|
||||||
|
const serverIndexFile = process.env.SERVER_INDEX_FILE || path.join(outputDir, "server/index.mjs");
|
||||||
const filenameCacheBust = "rr-filename-title-20260520";
|
const filenameCacheBust = "rr-filename-title-20260520";
|
||||||
const pdfCacheBust = "rr-glalie-layout-20260520";
|
const pdfCacheBust = "rr-glalie-layout-20260520";
|
||||||
const browserBufferPolyfill = "var Buffer=globalThis.Buffer??{isBuffer:()=>false,allocUnsafe:e=>new Uint8Array(e),alloc:e=>new Uint8Array(e)};/* rr-browser-buffer-polyfill */";
|
const browserBufferPolyfill = "var Buffer=globalThis.Buffer??{isBuffer:()=>false,allocUnsafe:e=>new Uint8Array(e),alloc:e=>new Uint8Array(e)};/* rr-browser-buffer-polyfill */";
|
||||||
@@ -117,6 +141,10 @@ function patchSsr(source) {
|
|||||||
|
|
||||||
const filenameReplacement = `function generateFilename(prefix, extension) {\n\tlet filename = (prefix || "resume").toString().trim() || "resume";\n\tfilename = filename.replace(/[\\\\/:*?"<>|]/g, "-").replace(/\\s+/g, " ").replace(/\\.+$/, "").trim() || "resume";\n\treturn extension && filename.toLowerCase().endsWith(\`.\${extension.toLowerCase()}\`) ? filename : \`\${filename}\${extension ? \`.\${extension}\` : ""}\`;\n}`;
|
const filenameReplacement = `function generateFilename(prefix, extension) {\n\tlet filename = (prefix || "resume").toString().trim() || "resume";\n\tfilename = filename.replace(/[\\\\/:*?"<>|]/g, "-").replace(/\\s+/g, " ").replace(/\\.+$/, "").trim() || "resume";\n\treturn extension && filename.toLowerCase().endsWith(\`.\${extension.toLowerCase()}\`) ? filename : \`\${filename}\${extension ? \`.\${extension}\` : ""}\`;\n}`;
|
||||||
if (!source.includes(filenameReplacement)) {
|
if (!source.includes(filenameReplacement)) {
|
||||||
|
const slugifiedPattern = /function generateFilename\(prefix, extension\) \{\s*return `\$\{slugify\(prefix\)\}\$\{extension \? `\.\$\{extension\}` : ""\}`;\s*\}/;
|
||||||
|
if (slugifiedPattern.test(source)) {
|
||||||
|
source = source.replace(slugifiedPattern, filenameReplacement);
|
||||||
|
} else {
|
||||||
const start = source.indexOf("function generateFilename(");
|
const start = source.indexOf("function generateFilename(");
|
||||||
const end = source.indexOf("\nfunction downloadWithAnchor(", start);
|
const end = source.indexOf("\nfunction downloadWithAnchor(", start);
|
||||||
if (start !== -1 && end !== -1) {
|
if (start !== -1 && end !== -1) {
|
||||||
@@ -125,6 +153,7 @@ function patchSsr(source) {
|
|||||||
warn("SSR generateFilename marker not found, skipped");
|
warn("SSR generateFilename marker not found, skipped");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
source = source
|
source = source
|
||||||
.replace(/const sideMargin = bodyLineHeight \* \.(?:2|08);/, "const sideMargin = bodyLineHeight * .08;")
|
.replace(/const sideMargin = bodyLineHeight \* \.(?:2|08);/, "const sideMargin = bodyLineHeight * .08;")
|
||||||
@@ -155,7 +184,8 @@ function patchSsr(source) {
|
|||||||
|
|
||||||
function patchPublicPdf(source) {
|
function patchPublicPdf(source) {
|
||||||
if (!source.includes("rr-browser-buffer-polyfill")) {
|
if (!source.includes("rr-browser-buffer-polyfill")) {
|
||||||
const insertAt = source.indexOf(";") + 1;
|
const importPrelude = source.match(/^(?:import[^;]+;)+/);
|
||||||
|
const insertAt = importPrelude ? importPrelude[0].length : source.indexOf(";") + 1;
|
||||||
if (insertAt > 0 && source.startsWith("import")) {
|
if (insertAt > 0 && source.startsWith("import")) {
|
||||||
source = source.slice(0, insertAt) + browserBufferPolyfill + source.slice(insertAt);
|
source = source.slice(0, insertAt) + browserBufferPolyfill + source.slice(insertAt);
|
||||||
} else {
|
} else {
|
||||||
@@ -193,7 +223,9 @@ for (const file of filenameFiles) {
|
|||||||
if (patchedFilenameFiles.length === 0) warn("no filename bundle patched");
|
if (patchedFilenameFiles.length === 0) warn("no filename bundle patched");
|
||||||
|
|
||||||
let ssrFile = "";
|
let ssrFile = "";
|
||||||
if (fs.existsSync(ssrDir)) {
|
if (explicitSsrFile && fs.existsSync(explicitSsrFile) && read(explicitSsrFile).includes("function generateFilename(")) {
|
||||||
|
ssrFile = explicitSsrFile;
|
||||||
|
} else if (ssrDir && fs.existsSync(ssrDir)) {
|
||||||
ssrFile = fs.readdirSync(ssrDir)
|
ssrFile = fs.readdirSync(ssrDir)
|
||||||
.filter((name) => name.endsWith(".mjs"))
|
.filter((name) => name.endsWith(".mjs"))
|
||||||
.map((name) => path.join(ssrDir, name))
|
.map((name) => path.join(ssrDir, name))
|
||||||
|
|||||||
Reference in New Issue
Block a user