@moonsjs/vite 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-3vdff6xf.js → index-h92zw0gs.js} +38 -2
- package/dist/{index-3vdff6xf.js.map → index-h92zw0gs.js.map} +3 -3
- package/dist/index.js +1 -1
- package/dist/server/bun-server.d.ts.map +1 -1
- package/dist/server/index.js +31 -2
- package/dist/server/index.js.map +4 -4
- package/dist/server/node-server.d.ts.map +1 -1
- package/dist/server/transport.d.ts +13 -0
- package/dist/server/transport.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/server/bun-server.ts +16 -0
- package/src/server/node-server.ts +22 -0
- package/src/server/transport.ts +51 -0
|
@@ -377,6 +377,42 @@ function textResponseWithHeaders(status, text, configured) {
|
|
|
377
377
|
applyStaticHeaders(headers, "/", configured);
|
|
378
378
|
return new Response(text, { status, headers });
|
|
379
379
|
}
|
|
380
|
+
function parseRangeHeader(value, size) {
|
|
381
|
+
if (value === null) {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
const match = /^bytes=(\d*)-(\d*)$/.exec(value.trim());
|
|
385
|
+
if (match === null) {
|
|
386
|
+
return null;
|
|
387
|
+
}
|
|
388
|
+
const rawStart = match[1] ?? "";
|
|
389
|
+
const rawEnd = match[2] ?? "";
|
|
390
|
+
if (rawStart === "" && rawEnd === "") {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
if (rawStart === "") {
|
|
394
|
+
const suffix = Number(rawEnd);
|
|
395
|
+
if (!Number.isFinite(suffix) || suffix <= 0) {
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
if (size === 0) {
|
|
399
|
+
return { kind: "unsatisfiable" };
|
|
400
|
+
}
|
|
401
|
+
return { kind: "partial", start: Math.max(0, size - suffix), end: size - 1 };
|
|
402
|
+
}
|
|
403
|
+
const start = Number(rawStart);
|
|
404
|
+
const end = rawEnd === "" ? size - 1 : Number(rawEnd);
|
|
405
|
+
if (!Number.isFinite(start) || !Number.isFinite(end)) {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
if (start >= size) {
|
|
409
|
+
return { kind: "unsatisfiable" };
|
|
410
|
+
}
|
|
411
|
+
if (start > end) {
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
return { kind: "partial", start, end: Math.min(end, size - 1) };
|
|
415
|
+
}
|
|
380
416
|
function applyStaticHeaders(target, pathname, configured) {
|
|
381
417
|
for (const [name, value] of Object.entries(configured ?? {})) {
|
|
382
418
|
if (!target.has(name)) {
|
|
@@ -921,6 +957,6 @@ function rootSpecifier(projectRoot, file) {
|
|
|
921
957
|
return rel.startsWith("/") ? rel : `/${rel}`;
|
|
922
958
|
}
|
|
923
959
|
|
|
924
|
-
export { NOT_FOUND_ROUTE_KEY, renderApiModule, renderRoutesModule, rootSpecifier, VIRTUAL_MODULES, fromNullPrefixed, ROOT_PLACEHOLDER2, DEFAULT_TEMPLATE2, injectShell2, createDevShell2, createFileShell2, scanPayloadForSecrets, MAX_TRANSPORT_BODY_BYTES, InvalidRequestError, BodyLimitError, DEFAULT_SECURITY_HEADERS, forwardedProtocol, forwardedHost, resolveClientIpValues, MIME_TYPES, COMPRESSIBLE_FILE, GZIP_MIN_BYTES, gzipCached, acceptsGzipHeader, rpcBodyTooLargeText, RequestTimeoutError, requestTimeoutText, runHandlerWithTimeout, isAbortLike, textResponseWithHeaders, applyStaticHeaders, readBodyWithLimit, resolveStaticFile2, staticFileTarget, scheduleRevalidation, resolveRequestUrl, resolveClientIp, toWebRequest2, sendNodeResponse2, installDevMiddleware2 };
|
|
960
|
+
export { NOT_FOUND_ROUTE_KEY, renderApiModule, renderRoutesModule, rootSpecifier, VIRTUAL_MODULES, fromNullPrefixed, ROOT_PLACEHOLDER2, DEFAULT_TEMPLATE2, injectShell2, createDevShell2, createFileShell2, scanPayloadForSecrets, MAX_TRANSPORT_BODY_BYTES, InvalidRequestError, BodyLimitError, DEFAULT_SECURITY_HEADERS, forwardedProtocol, forwardedHost, resolveClientIpValues, MIME_TYPES, COMPRESSIBLE_FILE, GZIP_MIN_BYTES, gzipCached, acceptsGzipHeader, rpcBodyTooLargeText, RequestTimeoutError, requestTimeoutText, runHandlerWithTimeout, isAbortLike, textResponseWithHeaders, parseRangeHeader, applyStaticHeaders, readBodyWithLimit, resolveStaticFile2, staticFileTarget, scheduleRevalidation, resolveRequestUrl, resolveClientIp, toWebRequest2, sendNodeResponse2, installDevMiddleware2 };
|
|
925
961
|
|
|
926
|
-
//# debugId=
|
|
962
|
+
//# debugId=26DA1EA083AC44E964756E2164756E21
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"sources": ["../src/server/shell.ts", "../src/server/transport.ts", "../src/server/isr.ts", "../src/payload-scan.ts", "../src/server/node.ts", "../src/virtual-modules.ts", "../src/server/dev.ts", "../src/devtools.ts", "../src/manifest.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { MoonsError } from \"@moonsjs/core\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { ViteDevServer } from \"vite\";\n\nexport type Shell = (\n markup: string,\n payload: string,\n url: string,\n meta?: Record<string, unknown>,\n) => string | Promise<string>;\n\nexport const ROOT_PLACEHOLDER = '<div id=\"root\"></div>';\n\nexport const DEFAULT_TEMPLATE = [\n \"<!doctype html>\",\n '<html lang=\"en\">',\n \"<head>\",\n ' <meta charset=\"utf-8\" />',\n ' <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />',\n \" <title>Moons</title>\",\n \"</head>\",\n \"<body>\",\n ` ${ROOT_PLACEHOLDER}`,\n ' <script type=\"module\" src=\"/src/client/main.tsx\"></script>',\n \"</body>\",\n \"</html>\",\n \"\",\n].join(\"\\n\");\n\n/** Inject markup SSR + payload devalue ke shell HTML (PRD §8.2, §17, Addendum B.1). */\nexport function injectShell(\n template: string,\n markup: string,\n payload: string,\n meta?: Record<string, unknown>,\n): string {\n if (!template.includes(ROOT_PLACEHOLDER)) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n message: `shell HTML does not contain \\`${ROOT_PLACEHOLDER}\\``,\n details: \"The app's index.html must contain that root element so SSR can inject markup.\",\n suggestions: [\n `Add ${ROOT_PLACEHOLDER} to index.html`,\n \"Or remove index.html to use the built-in shell\",\n ],\n });\n }\n const dataScript = `<script id=\"__moons_data\" type=\"application/x-moons\">${payload}</script>`;\n const withRoot = template.replace(ROOT_PLACEHOLDER, `<div id=\"root\">${markup}</div>${dataScript}`);\n return applyMeta(withRoot, meta);\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll('\"', \""\");\n}\n\n/**\n * Terapkan meta route ke `<head>` (Addendum B.1): `<title>` + description/og.\n * Tag yang sudah ada (mis. di index.html) ditimpa; yang belum ada disisipkan\n * sebelum `</head>`.\n */\nfunction applyMeta(html: string, meta: Record<string, unknown> | undefined): string {\n if (meta === undefined) {\n return html;\n }\n let out = html;\n if (typeof meta.title === \"string\") {\n const title = `<title>${escapeHtml(meta.title)}</title>`;\n out = /<title>[\\s\\S]*?<\\/title>/.test(out)\n ? out.replace(/<title>[\\s\\S]*?<\\/title>/, title)\n : out.replace(\"</head>\", ` ${title}\\n</head>`);\n }\n\n const tags: Array<{ attr: \"name\" | \"property\"; key: string; value: unknown }> = [\n { attr: \"name\", key: \"description\", value: meta.description },\n { attr: \"property\", key: \"og:title\", value: meta.title },\n { attr: \"property\", key: \"og:description\", value: meta.description },\n ];\n for (const tag of tags) {\n if (typeof tag.value !== \"string\") {\n continue;\n }\n const rendered = `<meta ${tag.attr}=\"${tag.key}\" content=\"${escapeHtml(tag.value)}\" />`;\n const pattern = new RegExp(`<meta[^>]*${tag.attr}=\"${tag.key}\"[^>]*>`);\n out = pattern.test(out)\n ? out.replace(pattern, rendered)\n : out.replace(\"</head>\", ` ${rendered}\\n</head>`);\n }\n return out;\n}\n\n/**\n * Shell untuk dev: baca `index.html` dari disk setiap request (selalu segar)\n * lalu lewatkan ke Vite `transformIndexHtml` (inject `/@vite/client`, dsb).\n */\nexport function createDevShell(server: ViteDevServer, options: { templatePath: string }): Shell {\n return async (markup, payload, url, meta) => {\n const template = existsSync(options.templatePath)\n ? readFileSync(options.templatePath, \"utf8\")\n : DEFAULT_TEMPLATE;\n const html = injectShell(template, markup, payload, meta);\n return await server.transformIndexHtml(url, html);\n };\n}\n\n/** Shell untuk produksi: baca `dist/client/index.html` sekali dari cwd. */\nexport function createFileShell(options: { clientDir?: string } = {}): Shell {\n let cached: string | null = null;\n return async (markup, payload, _url, meta) => {\n if (cached === null) {\n const clientDir = resolve(options.clientDir ?? process.cwd(), \"dist/client\");\n const file = join(clientDir, \"index.html\");\n if (!existsSync(file)) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n file,\n message: \"`dist/client/index.html` not found\",\n details: \"The client build must run before starting the production server.\",\n suggestions: [\"Run `bun run build` first\"],\n });\n }\n cached = readFileSync(file, \"utf8\");\n }\n return injectShell(cached, markup, payload, meta);\n };\n}\n",
|
|
6
|
-
"import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { extname, join, resolve, sep } from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\nimport { MoonsError, type PrerenderStorage } from \"@moonsjs/core\";\nimport { revalidatePrerendered, shouldRevalidate } from \"./isr\";\nimport type { Logger } from \"./logger\";\n\n/**\n * Addendum Q (3B): bagian transport yang tidak bergantung runtime — dipakai\n * `node-server` dan `bun-server` agar paritas bukan duplikasi.\n */\n\n/** Batas transport default (Addendum J.2); RPC punya batas lebih kecil dari config. */\nexport const MAX_TRANSPORT_BODY_BYTES = 32 * 1024 * 1024;\n\n/** Request tidak valid (Host/URL malformed) → dipetakan ke 400 oleh server. */\nexport class InvalidRequestError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidRequestError\";\n }\n}\n\n/** Body melebihi batas → dipetakan ke 413; pembacaan dihentikan saat melewati. */\nexport class BodyLimitError extends Error {\n readonly limit: number;\n constructor(limit: number) {\n super(`request body exceeds the ${limit} byte limit`);\n this.name = \"BodyLimitError\";\n this.limit = limit;\n }\n}\n\nexport interface ToWebRequestOptions {\n /** Addendum J.1: percayai `x-forwarded-proto`/`x-forwarded-host` (default false). */\n trustProxy?: boolean;\n /** Batas pembacaan body (byte). Default: `MAX_TRANSPORT_BODY_BYTES`. */\n maxBodyBytes?: number;\n /** Addendum S: header tepercaya untuk IP klien (default `x-forwarded-for`). */\n clientIpHeader?: string;\n}\n\n/** Addendum J.7: default aman runtime; `config.headers` tetap menang (cek `has`). */\nexport const DEFAULT_SECURITY_HEADERS: Record<string, string> = {\n \"x-content-type-options\": \"nosniff\",\n \"referrer-policy\": \"strict-origin-when-cross-origin\",\n};\n\nexport function firstHeaderValue(value: string | string[] | undefined): string | null {\n if (value === undefined) {\n return null;\n }\n const raw = Array.isArray(value) ? value[0] : value;\n if (raw === undefined) {\n return null;\n }\n const first = raw.split(\",\")[0]?.trim() ?? \"\";\n return first.length === 0 ? null : first;\n}\n\nexport function forwardedProtocol(\n value: string | string[] | undefined,\n): \"http\" | \"https\" | null {\n const first = firstHeaderValue(value)?.toLowerCase() ?? null;\n if (first === \"https\") {\n return \"https\";\n }\n if (first === \"http\") {\n return \"http\";\n }\n return null;\n}\n\nexport function forwardedHost(value: string | string[] | undefined): string | null {\n const first = firstHeaderValue(value);\n if (first === null || first.length === 0 || first.length > 255) {\n return null;\n }\n // hostname[:port] — tolak karakter di luar himpunan aman (spasi, CRLF, /, @, ?).\n if (!/^[A-Za-z0-9.\\-[\\]:]+$/.test(first)) {\n return null;\n }\n return first;\n}\n\nfunction isPlausibleIp(value: string): boolean {\n return value.length <= 64 && /^[0-9a-fA-F:.]+$/.test(value);\n}\n\nfunction stripZoneId(value: string): string {\n const index = value.indexOf(\"%\");\n return index === -1 ? value : value.slice(0, index);\n}\n\n/** `::ffff:127.0.0.1` → `127.0.0.1`; buang zone id (`%eth0`). */\nfunction normalizeIp(value: string): string {\n const withoutZone = stripZoneId(value);\n return withoutZone.startsWith(\"::ffff:\") ? withoutZone.slice(7) : withoutZone;\n}\n\n/**\n * IP klien tepercaya (Addendum J.1) dari nilai header mentah — inti yang sama\n * untuk Node (`IncomingMessage`) dan Bun (`Request` + `server.requestIP`).\n */\nexport function resolveClientIpValues(\n forwardedFor: string | string[] | undefined,\n remoteAddress: string | null,\n trustProxy: boolean,\n): string | null {\n if (trustProxy) {\n const forwarded = firstHeaderValue(forwardedFor);\n if (forwarded !== null && isPlausibleIp(forwarded)) {\n return normalizeIp(forwarded);\n }\n }\n return remoteAddress === null ? null : normalizeIp(remoteAddress);\n}\n\nexport const MIME_TYPES: Record<string, string> = {\n \".js\": \"text/javascript; charset=utf-8\",\n \".mjs\": \"text/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".html\": \"text/html; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".map\": \"application/json; charset=utf-8\",\n \".ico\": \"image/x-icon\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".webp\": \"image/webp\",\n \".avif\": \"image/avif\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".txt\": \"text/plain; charset=utf-8\",\n \".wasm\": \"application/wasm\",\n \".xml\": \"application/xml; charset=utf-8\",\n \".csv\": \"text/csv; charset=utf-8\",\n \".md\": \"text/markdown; charset=utf-8\",\n \".pdf\": \"application/pdf\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".zip\": \"application/zip\",\n \".gz\": \"application/gzip\",\n};\n\nexport const COMPRESSIBLE_FILE = /\\.(js|mjs|css|html|json|svg|txt|map|xml)$/i;\nexport const GZIP_MIN_BYTES = 1024;\nconst GZIP_CACHE_MAX = 64;\nconst gzipCache = new Map<string, { mtimeMs: number; gzip: Buffer }>();\n\n/** Varian gzip ter-cache per file+mtime (bounded FIFO) — Addendum K.5. */\nexport function gzipCached(file: string, mtimeMs: number, body: Buffer): Buffer {\n const cached = gzipCache.get(file);\n if (cached !== undefined && cached.mtimeMs === mtimeMs) {\n return cached.gzip;\n }\n const gzip = gzipSync(body);\n if (gzipCache.size >= GZIP_CACHE_MAX) {\n const oldest = gzipCache.keys().next().value;\n if (oldest !== undefined) {\n gzipCache.delete(oldest);\n }\n }\n gzipCache.set(file, { mtimeMs, gzip });\n return gzip;\n}\n\nexport function acceptsGzipHeader(value: string | null): boolean {\n if (value === null) {\n return false;\n }\n return value\n .toLowerCase()\n .split(\",\")\n .map((part) => part.trim())\n .some((part) => part === \"gzip\" || part === \"*\" || part.startsWith(\"gzip;\"));\n}\n\n/** 413 transport dengan format §15 yang sama seperti `rpc.ts` (Addendum J.2). */\nexport function rpcBodyTooLargeText(limit: number, size: number | null): string {\n const megabytes = (bytes: number): string => (bytes / 1_000_000).toFixed(1);\n return new MoonsError({\n code: \"E_RPC_BODY_TOO_LARGE\",\n message:\n size === null\n ? `body exceeds the ${megabytes(limit)} MB limit`\n : `body ${megabytes(size)} MB exceeds the ${megabytes(limit)} MB limit`,\n details:\n \"Body exceeds `security.bodyLimitBytes`; reading stops at the transport before the body is fully buffered.\",\n suggestions: [\n \"Reduce the payload size, or\",\n \"Increase security.bodyLimitBytes if you really need to\",\n ],\n }).format();\n}\n\n/** Handler melewati `requestTimeoutMs` → transport menjawab 504 (Addendum R). */\nexport class RequestTimeoutError extends Error {\n readonly limit: number;\n constructor(limit: number) {\n super(`handler did not respond within ${limit} ms`);\n this.name = \"RequestTimeoutError\";\n this.limit = limit;\n }\n}\n\n/** 504 dengan format §15 (dipakai kedua transport). */\nexport function requestTimeoutText(limit: number): string {\n return new MoonsError({\n code: \"E_REQUEST_TIMEOUT\",\n message: `handler did not respond within ${limit} ms`,\n details:\n \"The transport stopped waiting for the handler and answered 504. \" +\n \"The handler keeps running until it settles; JavaScript cannot cancel it.\",\n suggestions: [\n \"Make the handler faster, or move slow work out of the request path\",\n \"Raise `requestTimeoutMs`, or set it to 0 to disable the timeout\",\n ],\n }).format();\n}\n\n/**\n * Jalankan handler dengan batas waktu eksplisit (Addendum R; review G1).\n * `timeoutMs` undefined/0 → tanpa batas (perilaku lama).\n */\nexport async function runHandlerWithTimeout(\n handler: (request: Request) => Promise<Response>,\n request: Request,\n timeoutMs: number | undefined,\n): Promise<Response> {\n if (timeoutMs === undefined || timeoutMs <= 0) {\n return handler(request);\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new RequestTimeoutError(timeoutMs)), timeoutMs);\n });\n try {\n return await Promise.race([handler(request), timeout]);\n } finally {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n }\n}\n\n/** Klasifikasi abort klien / koneksi putus (review G7) — bukan error server. */\nexport function isAbortLike(error: unknown): boolean {\n if (error instanceof DOMException) {\n return error.name === \"AbortError\" || error.name === \"TimeoutError\";\n }\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n return true;\n }\n const code = (error as { code?: unknown }).code;\n if (code === \"ECONNRESET\" || code === \"EPIPE\" || code === \"ERR_STREAM_PREMATURE_CLOSE\") {\n return true;\n }\n const message = error.message.toLowerCase();\n return message === \"aborted\" || message.includes(\"aborted\") || message.includes(\"premature close\");\n }\n return false;\n}\n\n/** Respons teks transport (400/413/500/504) — tetap membawa header config + default aman (review G6). */\nexport function textResponseWithHeaders(\n status: number,\n text: string,\n configured?: Record<string, string>,\n): Response {\n const headers = new Headers({ \"content-type\": \"text/plain; charset=utf-8\" });\n applyStaticHeaders(headers, \"/\", configured);\n return new Response(text, { status, headers });\n}\n\n/** Target header minimal yang dipenuhi `ServerResponse` dan `Headers`. */\nexport interface HeaderTarget {\n has(name: string): boolean;\n set(name: string, value: string): void;\n}\n\n/**\n * Addendum J.7: header konfigurasi (menang), default aman, dan\n * `Cache-Control: immutable` untuk aset ber-hash di `/assets/*`.\n */\nexport function applyStaticHeaders(\n target: HeaderTarget,\n pathname: string,\n configured: Record<string, string> | undefined,\n): void {\n for (const [name, value] of Object.entries(configured ?? {})) {\n if (!target.has(name)) {\n target.set(name, value);\n }\n }\n for (const [name, value] of Object.entries(DEFAULT_SECURITY_HEADERS)) {\n if (!target.has(name)) {\n target.set(name, value);\n }\n }\n if (pathname.startsWith(\"/assets/\") && !target.has(\"cache-control\")) {\n target.set(\"cache-control\", \"public, max-age=31536000, immutable\");\n }\n}\n\n/**\n * Baca body Web stream dengan batas tegas (Addendum J.2): begitu melewati\n * `maxBytes`, pembacaan dihentikan dan `BodyLimitError` dilempar.\n */\nexport async function readBodyWithLimit(\n stream: ReadableStream<Uint8Array> | null,\n maxBytes: number,\n): Promise<Uint8Array> {\n if (stream === null) {\n return new Uint8Array(0);\n }\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (value !== undefined) {\n size += value.byteLength;\n if (size > maxBytes) {\n throw new BodyLimitError(maxBytes);\n }\n chunks.push(value);\n }\n }\n } finally {\n try {\n await reader.cancel();\n } catch {\n // stream sudah selesai/tertutup — abaikan\n }\n }\n const output = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n output.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return output;\n}\n\n/** Resolve file static dengan proteksi path traversal (+ manifest prerender D.5). */\nexport function resolveStaticFile(clientDir: string, pathname: string): string | null {\n const target = staticFileTarget(clientDir, pathname);\n return target !== null && isFile(target) ? target : null;\n}\n\n/**\n * Target file untuk `pathname` (tanpa cek keberadaan) — dipakai penyajian,\n * `createFileStorage().write`, dan test. Proteksi path traversal tetap.\n */\nexport function staticFileTarget(clientDir: string, pathname: string): string | null {\n let decoded: string;\n try {\n decoded = decodeURIComponent(pathname);\n } catch {\n return null;\n }\n\n // 1) File persis (aset: js/css/png/…, atau HTML yang diminta eksplisit).\n const exact = safeWithin(clientDir, `.${decoded}`);\n if (exact !== null && isFile(exact)) {\n return exact;\n }\n\n // 2) Hasil prerender: hanya path yang tercatat di manifest yang dilayani\n // statis — bukan shell `index.html` biasa (yang berarti bypass SSR).\n const normalized = decoded.length > 1 ? decoded.replace(/\\/+$/, \"\") : decoded;\n const manifest = readPrerenderManifest(clientDir);\n if (manifest.paths.has(normalized)) {\n const target = normalized === \"/\" ? \"index.html\" : `${normalized.slice(1)}/index.html`;\n return safeWithin(clientDir, `./${target}`);\n }\n\n return null;\n}\n\nfunction safeWithin(clientDir: string, relative: string): string | null {\n const candidate = resolve(clientDir, relative);\n if (candidate !== clientDir && !candidate.startsWith(clientDir + sep)) {\n return null;\n }\n return candidate;\n}\n\nfunction isFile(path: string): boolean {\n return existsSync(path) && statSync(path).isFile();\n}\n\nexport interface PrerenderManifestInfo {\n paths: Set<string>;\n revalidate: Map<string, number>;\n}\n\nlet prerenderManifestCache:\n | { file: string; mtimeMs: number; info: PrerenderManifestInfo }\n | null = null;\n\nexport function readPrerenderManifest(clientDir: string): PrerenderManifestInfo {\n const file = join(clientDir, \"_moons_prerender.json\");\n const empty: PrerenderManifestInfo = { paths: new Set(), revalidate: new Map() };\n try {\n const mtimeMs = statSync(file).mtimeMs;\n if (\n prerenderManifestCache !== null &&\n prerenderManifestCache.file === file &&\n prerenderManifestCache.mtimeMs === mtimeMs\n ) {\n return prerenderManifestCache.info;\n }\n const json = JSON.parse(readFileSync(file, \"utf8\")) as {\n paths?: unknown;\n version?: unknown;\n entries?: unknown;\n };\n const paths = new Set<string>();\n const revalidate = new Map<string, number>();\n if (Array.isArray(json.paths)) {\n // Manifest v1 (D.5) — tanpa revalidate.\n for (const path of json.paths) {\n if (typeof path === \"string\") {\n paths.add(path);\n }\n }\n }\n if (Array.isArray(json.entries)) {\n // Manifest v2 (E.1).\n for (const entry of json.entries as Array<Record<string, unknown>>) {\n if (entry === null || typeof entry !== \"object\" || typeof entry[\"path\"] !== \"string\") {\n continue;\n }\n const path = entry[\"path\"] as string;\n paths.add(path);\n const seconds = entry[\"revalidate\"];\n if (typeof seconds === \"number\" && Number.isFinite(seconds) && seconds >= 0) {\n revalidate.set(path, seconds);\n }\n }\n }\n const info = { paths, revalidate };\n prerenderManifestCache = { file, mtimeMs, info };\n return info;\n } catch {\n return empty;\n }\n}\n\n/** ISR: jika file prerender kedaluwarsa, regenerasi background (SWR). */\nexport function scheduleRevalidation(input: {\n pathname: string;\n mtimeMs: number;\n file?: string;\n storage?: PrerenderStorage;\n handler: (request: Request) => Promise<Response>;\n options: { canary?: string };\n clientDir: string;\n logger?: Logger | null;\n}): void {\n const normalized = input.pathname.length > 1 ? input.pathname.replace(/\\/+$/, \"\") : input.pathname;\n const seconds = readPrerenderManifest(input.clientDir).revalidate.get(normalized);\n if (seconds === undefined || seconds < 0) {\n return;\n }\n if (!shouldRevalidate({ mtimeMs: input.mtimeMs, revalidateSeconds: seconds })) {\n return;\n }\n const regeneratedAt = performance.now();\n const logger = input.logger ?? null;\n void revalidatePrerendered({\n pathname: normalized,\n ...(input.file === undefined ? {} : { file: input.file }),\n ...(input.storage === undefined ? {} : { storage: input.storage }),\n handler: input.handler,\n ...(input.options.canary === undefined ? {} : { canary: input.options.canary }),\n env: process.env,\n })\n .then(() => {\n logger?.({\n msg: \"isr:regenerated\",\n path: normalized,\n durationMs: Math.round(performance.now() - regeneratedAt),\n });\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n if (logger !== null) {\n logger({ msg: \"isr:revalidate-failed\", level: \"warn\", path: normalized, error: message });\n } else {\n console.error(`[moons] isr regeneration failed (${normalized}): ${message}`);\n }\n });\n}\n",
|
|
6
|
+
"import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { extname, join, resolve, sep } from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\nimport { MoonsError, type PrerenderStorage } from \"@moonsjs/core\";\nimport { revalidatePrerendered, shouldRevalidate } from \"./isr\";\nimport type { Logger } from \"./logger\";\n\n/**\n * Addendum Q (3B): bagian transport yang tidak bergantung runtime — dipakai\n * `node-server` dan `bun-server` agar paritas bukan duplikasi.\n */\n\n/** Batas transport default (Addendum J.2); RPC punya batas lebih kecil dari config. */\nexport const MAX_TRANSPORT_BODY_BYTES = 32 * 1024 * 1024;\n\n/** Request tidak valid (Host/URL malformed) → dipetakan ke 400 oleh server. */\nexport class InvalidRequestError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidRequestError\";\n }\n}\n\n/** Body melebihi batas → dipetakan ke 413; pembacaan dihentikan saat melewati. */\nexport class BodyLimitError extends Error {\n readonly limit: number;\n constructor(limit: number) {\n super(`request body exceeds the ${limit} byte limit`);\n this.name = \"BodyLimitError\";\n this.limit = limit;\n }\n}\n\nexport interface ToWebRequestOptions {\n /** Addendum J.1: percayai `x-forwarded-proto`/`x-forwarded-host` (default false). */\n trustProxy?: boolean;\n /** Batas pembacaan body (byte). Default: `MAX_TRANSPORT_BODY_BYTES`. */\n maxBodyBytes?: number;\n /** Addendum S: header tepercaya untuk IP klien (default `x-forwarded-for`). */\n clientIpHeader?: string;\n}\n\n/** Addendum J.7: default aman runtime; `config.headers` tetap menang (cek `has`). */\nexport const DEFAULT_SECURITY_HEADERS: Record<string, string> = {\n \"x-content-type-options\": \"nosniff\",\n \"referrer-policy\": \"strict-origin-when-cross-origin\",\n};\n\nexport function firstHeaderValue(value: string | string[] | undefined): string | null {\n if (value === undefined) {\n return null;\n }\n const raw = Array.isArray(value) ? value[0] : value;\n if (raw === undefined) {\n return null;\n }\n const first = raw.split(\",\")[0]?.trim() ?? \"\";\n return first.length === 0 ? null : first;\n}\n\nexport function forwardedProtocol(\n value: string | string[] | undefined,\n): \"http\" | \"https\" | null {\n const first = firstHeaderValue(value)?.toLowerCase() ?? null;\n if (first === \"https\") {\n return \"https\";\n }\n if (first === \"http\") {\n return \"http\";\n }\n return null;\n}\n\nexport function forwardedHost(value: string | string[] | undefined): string | null {\n const first = firstHeaderValue(value);\n if (first === null || first.length === 0 || first.length > 255) {\n return null;\n }\n // hostname[:port] — tolak karakter di luar himpunan aman (spasi, CRLF, /, @, ?).\n if (!/^[A-Za-z0-9.\\-[\\]:]+$/.test(first)) {\n return null;\n }\n return first;\n}\n\nfunction isPlausibleIp(value: string): boolean {\n return value.length <= 64 && /^[0-9a-fA-F:.]+$/.test(value);\n}\n\nfunction stripZoneId(value: string): string {\n const index = value.indexOf(\"%\");\n return index === -1 ? value : value.slice(0, index);\n}\n\n/** `::ffff:127.0.0.1` → `127.0.0.1`; buang zone id (`%eth0`). */\nfunction normalizeIp(value: string): string {\n const withoutZone = stripZoneId(value);\n return withoutZone.startsWith(\"::ffff:\") ? withoutZone.slice(7) : withoutZone;\n}\n\n/**\n * IP klien tepercaya (Addendum J.1) dari nilai header mentah — inti yang sama\n * untuk Node (`IncomingMessage`) dan Bun (`Request` + `server.requestIP`).\n */\nexport function resolveClientIpValues(\n forwardedFor: string | string[] | undefined,\n remoteAddress: string | null,\n trustProxy: boolean,\n): string | null {\n if (trustProxy) {\n const forwarded = firstHeaderValue(forwardedFor);\n if (forwarded !== null && isPlausibleIp(forwarded)) {\n return normalizeIp(forwarded);\n }\n }\n return remoteAddress === null ? null : normalizeIp(remoteAddress);\n}\n\nexport const MIME_TYPES: Record<string, string> = {\n \".js\": \"text/javascript; charset=utf-8\",\n \".mjs\": \"text/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".html\": \"text/html; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".map\": \"application/json; charset=utf-8\",\n \".ico\": \"image/x-icon\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".webp\": \"image/webp\",\n \".avif\": \"image/avif\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".txt\": \"text/plain; charset=utf-8\",\n \".wasm\": \"application/wasm\",\n \".xml\": \"application/xml; charset=utf-8\",\n \".csv\": \"text/csv; charset=utf-8\",\n \".md\": \"text/markdown; charset=utf-8\",\n \".pdf\": \"application/pdf\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".zip\": \"application/zip\",\n \".gz\": \"application/gzip\",\n};\n\nexport const COMPRESSIBLE_FILE = /\\.(js|mjs|css|html|json|svg|txt|map|xml)$/i;\nexport const GZIP_MIN_BYTES = 1024;\nconst GZIP_CACHE_MAX = 64;\nconst gzipCache = new Map<string, { mtimeMs: number; gzip: Buffer }>();\n\n/** Varian gzip ter-cache per file+mtime (bounded FIFO) — Addendum K.5. */\nexport function gzipCached(file: string, mtimeMs: number, body: Buffer): Buffer {\n const cached = gzipCache.get(file);\n if (cached !== undefined && cached.mtimeMs === mtimeMs) {\n return cached.gzip;\n }\n const gzip = gzipSync(body);\n if (gzipCache.size >= GZIP_CACHE_MAX) {\n const oldest = gzipCache.keys().next().value;\n if (oldest !== undefined) {\n gzipCache.delete(oldest);\n }\n }\n gzipCache.set(file, { mtimeMs, gzip });\n return gzip;\n}\n\nexport function acceptsGzipHeader(value: string | null): boolean {\n if (value === null) {\n return false;\n }\n return value\n .toLowerCase()\n .split(\",\")\n .map((part) => part.trim())\n .some((part) => part === \"gzip\" || part === \"*\" || part.startsWith(\"gzip;\"));\n}\n\n/** 413 transport dengan format §15 yang sama seperti `rpc.ts` (Addendum J.2). */\nexport function rpcBodyTooLargeText(limit: number, size: number | null): string {\n const megabytes = (bytes: number): string => (bytes / 1_000_000).toFixed(1);\n return new MoonsError({\n code: \"E_RPC_BODY_TOO_LARGE\",\n message:\n size === null\n ? `body exceeds the ${megabytes(limit)} MB limit`\n : `body ${megabytes(size)} MB exceeds the ${megabytes(limit)} MB limit`,\n details:\n \"Body exceeds `security.bodyLimitBytes`; reading stops at the transport before the body is fully buffered.\",\n suggestions: [\n \"Reduce the payload size, or\",\n \"Increase security.bodyLimitBytes if you really need to\",\n ],\n }).format();\n}\n\n/** Handler melewati `requestTimeoutMs` → transport menjawab 504 (Addendum R). */\nexport class RequestTimeoutError extends Error {\n readonly limit: number;\n constructor(limit: number) {\n super(`handler did not respond within ${limit} ms`);\n this.name = \"RequestTimeoutError\";\n this.limit = limit;\n }\n}\n\n/** 504 dengan format §15 (dipakai kedua transport). */\nexport function requestTimeoutText(limit: number): string {\n return new MoonsError({\n code: \"E_REQUEST_TIMEOUT\",\n message: `handler did not respond within ${limit} ms`,\n details:\n \"The transport stopped waiting for the handler and answered 504. \" +\n \"The handler keeps running until it settles; JavaScript cannot cancel it.\",\n suggestions: [\n \"Make the handler faster, or move slow work out of the request path\",\n \"Raise `requestTimeoutMs`, or set it to 0 to disable the timeout\",\n ],\n }).format();\n}\n\n/**\n * Jalankan handler dengan batas waktu eksplisit (Addendum R; review G1).\n * `timeoutMs` undefined/0 → tanpa batas (perilaku lama).\n */\nexport async function runHandlerWithTimeout(\n handler: (request: Request) => Promise<Response>,\n request: Request,\n timeoutMs: number | undefined,\n): Promise<Response> {\n if (timeoutMs === undefined || timeoutMs <= 0) {\n return handler(request);\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new RequestTimeoutError(timeoutMs)), timeoutMs);\n });\n try {\n return await Promise.race([handler(request), timeout]);\n } finally {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n }\n}\n\n/** Klasifikasi abort klien / koneksi putus (review G7) — bukan error server. */\nexport function isAbortLike(error: unknown): boolean {\n if (error instanceof DOMException) {\n return error.name === \"AbortError\" || error.name === \"TimeoutError\";\n }\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n return true;\n }\n const code = (error as { code?: unknown }).code;\n if (code === \"ECONNRESET\" || code === \"EPIPE\" || code === \"ERR_STREAM_PREMATURE_CLOSE\") {\n return true;\n }\n const message = error.message.toLowerCase();\n return message === \"aborted\" || message.includes(\"aborted\") || message.includes(\"premature close\");\n }\n return false;\n}\n\n/** Respons teks transport (400/413/500/504) — tetap membawa header config + default aman (review G6). */\nexport function textResponseWithHeaders(\n status: number,\n text: string,\n configured?: Record<string, string>,\n): Response {\n const headers = new Headers({ \"content-type\": \"text/plain; charset=utf-8\" });\n applyStaticHeaders(headers, \"/\", configured);\n return new Response(text, { status, headers });\n}\n\n/**\n * Addendum T (G4): `Range` single-range untuk file statik.\n * `null` = tidak ada/format tidak didukung (sajikan penuh 200);\n * `\"unsatisfiable\"` = 416; `partial` = 206 dengan `content-range`.\n */\nexport type RangeResult =\n | { kind: \"partial\"; start: number; end: number }\n | { kind: \"unsatisfiable\" }\n | null;\n\nexport function parseRangeHeader(value: string | null, size: number): RangeResult {\n if (value === null) {\n return null;\n }\n const match = /^bytes=(\\d*)-(\\d*)$/.exec(value.trim());\n if (match === null) {\n // Multi-range atau unit lain → abaikan (sajikan penuh).\n return null;\n }\n const rawStart = match[1] ?? \"\";\n const rawEnd = match[2] ?? \"\";\n if (rawStart === \"\" && rawEnd === \"\") {\n return null;\n }\n if (rawStart === \"\") {\n // Suffix: `bytes=-N` → N byte terakhir.\n const suffix = Number(rawEnd);\n if (!Number.isFinite(suffix) || suffix <= 0) {\n return null;\n }\n if (size === 0) {\n return { kind: \"unsatisfiable\" };\n }\n return { kind: \"partial\", start: Math.max(0, size - suffix), end: size - 1 };\n }\n const start = Number(rawStart);\n const end = rawEnd === \"\" ? size - 1 : Number(rawEnd);\n if (!Number.isFinite(start) || !Number.isFinite(end)) {\n return null;\n }\n // Cek \"tak terpuaskan\" SEBELUM validasi start>end: `bytes=99-` dengan\n // size kecil menghasilkan start>end karena end default size-1.\n if (start >= size) {\n return { kind: \"unsatisfiable\" };\n }\n if (start > end) {\n return null;\n }\n return { kind: \"partial\", start, end: Math.min(end, size - 1) };\n}\n\n/** Target header minimal yang dipenuhi `ServerResponse` dan `Headers`. */\nexport interface HeaderTarget {\n has(name: string): boolean;\n set(name: string, value: string): void;\n}\n\n/**\n * Addendum J.7: header konfigurasi (menang), default aman, dan\n * `Cache-Control: immutable` untuk aset ber-hash di `/assets/*`.\n */\nexport function applyStaticHeaders(\n target: HeaderTarget,\n pathname: string,\n configured: Record<string, string> | undefined,\n): void {\n for (const [name, value] of Object.entries(configured ?? {})) {\n if (!target.has(name)) {\n target.set(name, value);\n }\n }\n for (const [name, value] of Object.entries(DEFAULT_SECURITY_HEADERS)) {\n if (!target.has(name)) {\n target.set(name, value);\n }\n }\n if (pathname.startsWith(\"/assets/\") && !target.has(\"cache-control\")) {\n target.set(\"cache-control\", \"public, max-age=31536000, immutable\");\n }\n}\n\n/**\n * Baca body Web stream dengan batas tegas (Addendum J.2): begitu melewati\n * `maxBytes`, pembacaan dihentikan dan `BodyLimitError` dilempar.\n */\nexport async function readBodyWithLimit(\n stream: ReadableStream<Uint8Array> | null,\n maxBytes: number,\n): Promise<Uint8Array> {\n if (stream === null) {\n return new Uint8Array(0);\n }\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (value !== undefined) {\n size += value.byteLength;\n if (size > maxBytes) {\n throw new BodyLimitError(maxBytes);\n }\n chunks.push(value);\n }\n }\n } finally {\n try {\n await reader.cancel();\n } catch {\n // stream sudah selesai/tertutup — abaikan\n }\n }\n const output = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n output.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return output;\n}\n\n/** Resolve file static dengan proteksi path traversal (+ manifest prerender D.5). */\nexport function resolveStaticFile(clientDir: string, pathname: string): string | null {\n const target = staticFileTarget(clientDir, pathname);\n return target !== null && isFile(target) ? target : null;\n}\n\n/**\n * Target file untuk `pathname` (tanpa cek keberadaan) — dipakai penyajian,\n * `createFileStorage().write`, dan test. Proteksi path traversal tetap.\n */\nexport function staticFileTarget(clientDir: string, pathname: string): string | null {\n let decoded: string;\n try {\n decoded = decodeURIComponent(pathname);\n } catch {\n return null;\n }\n\n // 1) File persis (aset: js/css/png/…, atau HTML yang diminta eksplisit).\n const exact = safeWithin(clientDir, `.${decoded}`);\n if (exact !== null && isFile(exact)) {\n return exact;\n }\n\n // 2) Hasil prerender: hanya path yang tercatat di manifest yang dilayani\n // statis — bukan shell `index.html` biasa (yang berarti bypass SSR).\n const normalized = decoded.length > 1 ? decoded.replace(/\\/+$/, \"\") : decoded;\n const manifest = readPrerenderManifest(clientDir);\n if (manifest.paths.has(normalized)) {\n const target = normalized === \"/\" ? \"index.html\" : `${normalized.slice(1)}/index.html`;\n return safeWithin(clientDir, `./${target}`);\n }\n\n return null;\n}\n\nfunction safeWithin(clientDir: string, relative: string): string | null {\n const candidate = resolve(clientDir, relative);\n if (candidate !== clientDir && !candidate.startsWith(clientDir + sep)) {\n return null;\n }\n return candidate;\n}\n\nfunction isFile(path: string): boolean {\n return existsSync(path) && statSync(path).isFile();\n}\n\nexport interface PrerenderManifestInfo {\n paths: Set<string>;\n revalidate: Map<string, number>;\n}\n\nlet prerenderManifestCache:\n | { file: string; mtimeMs: number; info: PrerenderManifestInfo }\n | null = null;\n\nexport function readPrerenderManifest(clientDir: string): PrerenderManifestInfo {\n const file = join(clientDir, \"_moons_prerender.json\");\n const empty: PrerenderManifestInfo = { paths: new Set(), revalidate: new Map() };\n try {\n const mtimeMs = statSync(file).mtimeMs;\n if (\n prerenderManifestCache !== null &&\n prerenderManifestCache.file === file &&\n prerenderManifestCache.mtimeMs === mtimeMs\n ) {\n return prerenderManifestCache.info;\n }\n const json = JSON.parse(readFileSync(file, \"utf8\")) as {\n paths?: unknown;\n version?: unknown;\n entries?: unknown;\n };\n const paths = new Set<string>();\n const revalidate = new Map<string, number>();\n if (Array.isArray(json.paths)) {\n // Manifest v1 (D.5) — tanpa revalidate.\n for (const path of json.paths) {\n if (typeof path === \"string\") {\n paths.add(path);\n }\n }\n }\n if (Array.isArray(json.entries)) {\n // Manifest v2 (E.1).\n for (const entry of json.entries as Array<Record<string, unknown>>) {\n if (entry === null || typeof entry !== \"object\" || typeof entry[\"path\"] !== \"string\") {\n continue;\n }\n const path = entry[\"path\"] as string;\n paths.add(path);\n const seconds = entry[\"revalidate\"];\n if (typeof seconds === \"number\" && Number.isFinite(seconds) && seconds >= 0) {\n revalidate.set(path, seconds);\n }\n }\n }\n const info = { paths, revalidate };\n prerenderManifestCache = { file, mtimeMs, info };\n return info;\n } catch {\n return empty;\n }\n}\n\n/** ISR: jika file prerender kedaluwarsa, regenerasi background (SWR). */\nexport function scheduleRevalidation(input: {\n pathname: string;\n mtimeMs: number;\n file?: string;\n storage?: PrerenderStorage;\n handler: (request: Request) => Promise<Response>;\n options: { canary?: string };\n clientDir: string;\n logger?: Logger | null;\n}): void {\n const normalized = input.pathname.length > 1 ? input.pathname.replace(/\\/+$/, \"\") : input.pathname;\n const seconds = readPrerenderManifest(input.clientDir).revalidate.get(normalized);\n if (seconds === undefined || seconds < 0) {\n return;\n }\n if (!shouldRevalidate({ mtimeMs: input.mtimeMs, revalidateSeconds: seconds })) {\n return;\n }\n const regeneratedAt = performance.now();\n const logger = input.logger ?? null;\n void revalidatePrerendered({\n pathname: normalized,\n ...(input.file === undefined ? {} : { file: input.file }),\n ...(input.storage === undefined ? {} : { storage: input.storage }),\n handler: input.handler,\n ...(input.options.canary === undefined ? {} : { canary: input.options.canary }),\n env: process.env,\n })\n .then(() => {\n logger?.({\n msg: \"isr:regenerated\",\n path: normalized,\n durationMs: Math.round(performance.now() - regeneratedAt),\n });\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n if (logger !== null) {\n logger({ msg: \"isr:revalidate-failed\", level: \"warn\", path: normalized, error: message });\n } else {\n console.error(`[moons] isr regeneration failed (${normalized}): ${message}`);\n }\n });\n}\n",
|
|
7
7
|
"import { renameSync, writeFileSync } from \"node:fs\";\nimport type { PrerenderStorage } from \"@moonsjs/core\";\nimport { scanPayloadForSecrets } from \"../payload-scan\";\n\n/**\n * ISR / revalidate on-demand (PRD Addendum E.1): file prerender yang kedaluwarsa\n * disajikan apa adanya (stale-while-revalidate) sambil diregenerasi via handler\n * SSR in-process. Tulis atomik + guard kebocoran fail-closed.\n */\nexport function shouldRevalidate(input: {\n mtimeMs: number;\n revalidateSeconds: number;\n now?: number;\n}): boolean {\n const now = input.now ?? Date.now();\n return now - input.mtimeMs >= input.revalidateSeconds * 1000;\n}\n\nexport interface RevalidateOptions {\n /** Path URL ternormalisasi (mis. \"/blog/hello\"). */\n pathname: string;\n /** File HTML yang akan ditimpa (default file storage). */\n file?: string;\n /**\n * Storage alternatif (Addendum I). Bila diisi, `file` diabaikan dan hasil\n * regenerasi ditulis lewat `storage.write(pathname, body)`.\n */\n storage?: PrerenderStorage;\n handler: (request: Request) => Promise<Response>;\n canary?: string;\n env?: Record<string, string | undefined>;\n log?: (message: string) => void;\n}\n\nconst inflight = new Map<string, Promise<void>>();\n\n/** Regenerasi ter-dedupe per path (panggilan paralel berbagi promise). */\nexport function revalidatePrerendered(options: RevalidateOptions): Promise<void> {\n const existing = inflight.get(options.pathname);\n if (existing !== undefined) {\n return existing;\n }\n const task = runRevalidate(options).finally(() => {\n inflight.delete(options.pathname);\n });\n inflight.set(options.pathname, task);\n return task;\n}\n\nasync function runRevalidate(options: RevalidateOptions): Promise<void> {\n const log = options.log ?? ((message: string) => console.log(message));\n try {\n const response = await options.handler(\n new Request(`http://localhost${options.pathname}`, {\n method: \"GET\",\n headers: { \"x-moons-prerender\": \"1\" },\n }),\n );\n if (response.status !== 200) {\n log(`[moons] isr: skipped ${options.pathname} (status ${response.status})`);\n return;\n }\n const html = await response.text();\n const findings = scanPayloadForSecrets(html, {\n ...(options.canary === undefined ? {} : { canary: options.canary }),\n env: options.env ?? process.env,\n });\n if (findings.length > 0) {\n const labels = findings\n .map((finding) => (finding.kind === \"canary\" ? \"canary\" : `env(${finding.label})`))\n .join(\", \");\n // Fail-closed: tidak menimpa file statis dengan konten bocor.\n log(`[moons] isr: NOT writing ${options.pathname} — contains ${labels}`);\n return;\n }\n if (options.storage !== undefined) {\n await options.storage.write(options.pathname, new TextEncoder().encode(html));\n return;\n }\n if (options.file === undefined) {\n log(`[moons] isr: skipped ${options.pathname} — no destination file/storage`);\n return;\n }\n const tmp = `${options.file}.tmp-${process.pid}`;\n writeFileSync(tmp, html);\n renameSync(tmp, options.file);\n } catch (error) {\n log(`[moons] isr: failed to regenerate ${options.pathname}: ${String(error)}`);\n }\n}\n\n/** Test helper: bersihkan dedupe in-flight. */\nexport function __resetIsrInflight(): void {\n inflight.clear();\n}\n",
|
|
8
8
|
"/**\n * Pemindaian payload SSR (nilai A1 / PRD §2): HANYA dipakai di dev sebagai\n * peringatan — tidak ada biaya runtime di production (production tidak pernah\n * memanggil fungsi ini; lihat `RequestHandlerOptions.payloadScan`).\n */\n\nexport interface PayloadScanOptions {\n /** Canary `leakTest.canary` (bila dikonfigurasi). */\n canary?: string;\n /** Lingkungan server (biasanya `process.env`). */\n env?: Record<string, string | undefined>;\n}\n\nexport interface PayloadScanFinding {\n kind: \"canary\" | \"env\";\n /** Label untuk pesan: `canary` atau nama env var. */\n label: string;\n}\n\n/**\n * Nama env yang \"mirip rahasia\" — dideteksi lewat pola nama + panjang nilai\n * minimum 12 karakter untuk menghindari false positive (keputusan pemilik).\n */\nconst SECRET_KEY_PATTERN =\n /(SECRET|TOKEN|PASSWORD|PASSWD|PRIVATE|CREDENTIAL|AUTH|API_KEY|ACCESS_KEY|SIGNING)/i;\n\nconst MIN_SECRET_LENGTH = 12;\n\nexport function scanPayloadForSecrets(\n payload: string,\n options: PayloadScanOptions = {},\n): PayloadScanFinding[] {\n const findings: PayloadScanFinding[] = [];\n\n const canary = options.canary;\n if (canary !== undefined && canary.length > 0 && payload.includes(canary)) {\n findings.push({ kind: \"canary\", label: \"canary\" });\n }\n\n for (const [key, value] of Object.entries(options.env ?? {})) {\n if (typeof value !== \"string\" || value.length < MIN_SECRET_LENGTH) {\n continue;\n }\n if (!SECRET_KEY_PATTERN.test(key) || /PUBLIC/i.test(key)) {\n continue;\n }\n if (payload.includes(value)) {\n findings.push({ kind: \"env\", label: key });\n }\n }\n\n return findings;\n}\n",
|
|
9
9
|
"import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { Readable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { CLIENT_IP_HEADER } from \"@moonsjs/core\";\nimport {\n BodyLimitError,\n DEFAULT_SECURITY_HEADERS,\n InvalidRequestError,\n MAX_TRANSPORT_BODY_BYTES,\n forwardedHost,\n forwardedProtocol,\n resolveClientIpValues,\n type ToWebRequestOptions,\n} from \"./transport\";\n\n// Kontrak lama tetap diekspor dari sini (test & pemakai lama).\nexport {\n BodyLimitError,\n DEFAULT_SECURITY_HEADERS,\n InvalidRequestError,\n MAX_TRANSPORT_BODY_BYTES,\n} from \"./transport\";\nexport type { ToWebRequestOptions } from \"./transport\";\n\n/**\n * Rekonstruksi URL request (Addendum J.1). Tanpa `trustProxy`, origin/host\n * murni dari header `Host` (perilaku lama, kebal spoofing `x-forwarded-*`).\n * Malformed → `InvalidRequestError` (server memetakan ke 400).\n */\nexport function resolveRequestUrl(\n req: IncomingMessage,\n options: ToWebRequestOptions = {},\n): URL {\n const hostHeader = req.headers.host ?? \"localhost\";\n const trustProxy = options.trustProxy === true;\n const proto = trustProxy ? forwardedProtocol(req.headers[\"x-forwarded-proto\"]) : null;\n const forwardedHostValue = trustProxy ? forwardedHost(req.headers[\"x-forwarded-host\"]) : null;\n const host = forwardedHostValue ?? hostHeader;\n try {\n return new URL(`${proto ?? \"http\"}://${host}${req.url ?? \"/\"}`);\n } catch {\n throw new InvalidRequestError(`invalid Host header: ${JSON.stringify(hostHeader)}`);\n }\n}\n\n/**\n * IP klien tepercaya (Addendum J.1/S): header tepercaya (hanya bila trustProxy)\n * → socket. Default `x-forwarded-for`; di belakang Cloudflare pakai\n * `cf-connecting-ip` (XFF di-append CF → entri pertama bisa dipalsukan).\n */\nexport function resolveClientIp(\n req: IncomingMessage,\n trustProxy: boolean,\n headerName = \"x-forwarded-for\",\n): string | null {\n return resolveClientIpValues(\n req.headers[headerName],\n req.socket?.remoteAddress ?? null,\n trustProxy,\n );\n}\n\n/** Konversi request Node → Web `Request` (body diteruskan untuk non-GET/HEAD, §7.3 + J.1/J.2). */\nexport async function toWebRequest(\n req: IncomingMessage,\n options: ToWebRequestOptions = {},\n): Promise<Request> {\n const url = resolveRequestUrl(req, options);\n const method = req.method ?? \"GET\";\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value === undefined || key === \"content-length\" || key === CLIENT_IP_HEADER) {\n // content-length tidak disalin; fetch menghitung ulang dari body.\n // x-moons-client-ip selalu ditimpa nilai tepercaya di bawah.\n continue;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(key, item);\n }\n } else {\n headers.set(key, value);\n }\n }\n\n const clientIp = resolveClientIp(\n req,\n options.trustProxy === true,\n options.clientIpHeader ?? \"x-forwarded-for\",\n );\n if (clientIp !== null) {\n headers.set(CLIENT_IP_HEADER, clientIp);\n }\n\n if (method === \"GET\" || method === \"HEAD\") {\n return new Request(url, { method, headers });\n }\n\n const body = await readBody(req, options.maxBodyBytes ?? MAX_TRANSPORT_BODY_BYTES);\n // View zero-copy (bukan salinan) — Buffer selalu di atas ArrayBuffer biasa.\n const view = new Uint8Array(body.buffer as ArrayBuffer, body.byteOffset, body.byteLength);\n return new Request(url, { method, headers, body: view });\n}\n\n/**\n * Baca body dengan batas tegas (Addendum J.2): begitu melewati `maxBytes`,\n * pembacaan dihentikan (pause) dan `BodyLimitError` dilempar — tidak pernah\n * seluruh body besar masuk memori, dan hanya satu salinan buffer dibuat.\n */\nexport function readBody(req: IncomingMessage, maxBytes: number): Promise<Buffer> {\n return new Promise((resolvePromise, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n let settled = false;\n\n const fail = (error: Error): void => {\n if (settled) {\n return;\n }\n settled = true;\n req.pause();\n reject(error);\n };\n\n req.on(\"data\", (chunk: Buffer) => {\n if (settled) {\n return;\n }\n size += chunk.length;\n if (size > maxBytes) {\n fail(new BodyLimitError(maxBytes));\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => {\n if (!settled) {\n settled = true;\n resolvePromise(Buffer.concat(chunks));\n }\n });\n req.on(\"error\", (error) => fail(error));\n });\n}\n\n/** Tulis Web `Response` ke `ServerResponse` Node (streaming bila ada body). */\nexport async function sendNodeResponse(res: ServerResponse, response: Response): Promise<void> {\n res.statusCode = response.status;\n response.headers.forEach((value, key) => {\n // `set-cookie` ditangani terpisah: forEach menggabungkan nilai ganda\n // menjadi satu string (cookie kedua hilang — D.2).\n if (key === \"set-cookie\") {\n return;\n }\n res.setHeader(key, value);\n });\n const getSetCookie = (response.headers as { getSetCookie?: () => string[] }).getSetCookie;\n if (typeof getSetCookie === \"function\") {\n const cookies = getSetCookie.call(response.headers);\n if (cookies.length > 0) {\n res.setHeader(\"set-cookie\", cookies);\n }\n } else {\n const single = response.headers.get(\"set-cookie\");\n if (single !== null) {\n res.setHeader(\"set-cookie\", single);\n }\n }\n\n for (const [name, value] of Object.entries(DEFAULT_SECURITY_HEADERS)) {\n if (!res.hasHeader(name)) {\n res.setHeader(name, value);\n }\n }\n\n if (response.body === null || res.req?.method === \"HEAD\") {\n res.end();\n return;\n }\n\n // Addendum J.2: stream langsung — tidak ada `arrayBuffer()` penuh di memori.\n await pipeline(\n Readable.fromWeb(response.body as unknown as import(\"node:stream/web\").ReadableStream),\n res,\n );\n}\n",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"/**\n * Addendum I.4 (W4): devtools overlay dev-only — tabel route, registry\n * serverFn (hash §12), endpoint `src/api`, dan status payload-scan.\n * Renderer murni (tanpa I/O) supaya bisa diuji unit; middleware dev yang\n * menyajikannya di `/__moons/devtools`.\n */\n\nexport interface DevtoolsRoute {\n /** Path URL (bentuk PRD §6.1), mis. \"/users/:id\". */\n path: string;\n /** \"page\" | \"layout\" | \"error\" | \"404\" | \"middleware\" | \"api\". */\n kind: string;\n /** Path relatif terhadap root app (posix). */\n file: string;\n}\n\nexport interface DevtoolsFn {\n file: string;\n name: string;\n hash: string;\n}\n\nexport interface DevtoolsData {\n routes: DevtoolsRoute[];\n apiRoutes: DevtoolsRoute[];\n serverFns: DevtoolsFn[];\n /** Canary `leakTest` terpasang → payload-scan aktif (A1). */\n canary: boolean;\n version: string;\n}\n\nexport function emptyDevtoolsData(): DevtoolsData {\n return { routes: [], apiRoutes: [], serverFns: [], canary: false, version: \"\" };\n}\n\nexport function renderDevtoolsHtml(data: DevtoolsData): string {\n const rows = (items: DevtoolsRoute[]): string =>\n items.length === 0\n ? '<tr><td colspan=\"3\" class=\"muted\">(empty)</td></tr>'\n : items\n .map(\n (item) =>\n `<tr><td><code>${esc(item.path)}</code></td><td><span class=\"kind k-${esc(item.kind)}\">${esc(item.kind)}</span></td><td class=\"muted\">${esc(item.file)}</td></tr>`,\n )\n .join(\"\\n\");\n\n const fnRows =\n data.serverFns.length === 0\n ? '<tr><td colspan=\"3\" class=\"muted\">(no serverFn)</td></tr>'\n : data.serverFns\n .map(\n (fn) =>\n `<tr><td><code>${esc(fn.hash)}</code></td><td><code>${esc(fn.name)}</code></td><td class=\"muted\">${esc(fn.file)}</td></tr>`,\n )\n .join(\"\\n\");\n\n const canary = data.canary\n ? '<span class=\"ok\">enabled</span> (canary installed)'\n : '<span class=\"muted\">disabled</span> (no canary)';\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>moons devtools</title>\n<style>\n :root { color-scheme: dark; }\n body { margin: 0; padding: 2rem; background: #101418; color: #e6edf3;\n font: 14px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; }\n h1 { font-size: 1.1rem; margin: 0 0 .25rem; }\n h2 { font-size: .95rem; margin: 2rem 0 .5rem; color: #9fb0c0; }\n .muted { color: #8b98a5; }\n .ok { color: #3fb950; font-weight: 600; }\n .meta { margin-bottom: 1.5rem; }\n table { border-collapse: collapse; width: 100%; max-width: 1100px; }\n th, td { text-align: left; padding: .35rem .75rem .35rem 0; border-bottom: 1px solid #1f2630; }\n th { color: #8b98a5; font-weight: 600; font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; }\n code { color: #79c0ff; }\n .kind { border: 1px solid #30363d; border-radius: 4px; padding: 0 .35rem; font-size: .8rem; }\n .k-page { color: #d2a8ff; } .k-layout { color: #7ee787; }\n .k-error { color: #ff7b72; } .k-404 { color: #ff7b72; }\n .k-middleware { color: #e3b341; } .k-api { color: #79c0ff; }\n</style>\n</head>\n<body>\n<h1>moons devtools</h1>\n<div class=\"meta muted\">@moonsjs/vite ${esc(data.version)} · dev-only · payload-scan: ${canary}</div>\n\n<h2>Routes (${data.routes.length})</h2>\n<table><thead><tr><th>path</th><th>kind</th><th>file</th></tr></thead>\n<tbody>\n${rows(data.routes)}\n</tbody></table>\n\n<h2>API (${data.apiRoutes.length})</h2>\n<table><thead><tr><th>path</th><th>kind</th><th>file</th></tr></thead>\n<tbody>\n${rows(data.apiRoutes)}\n</tbody></table>\n\n<h2>serverFn registry (${data.serverFns.length})</h2>\n<table><thead><tr><th>hash</th><th>export</th><th>file</th></tr></thead>\n<tbody>\n${fnRows}\n</tbody></table>\n</body>\n</html>\n`;\n}\n\nfunction esc(value: string): string {\n return value.replace(/[&<>\"']/g, (char) => {\n switch (char) {\n case \"&\":\n return \"&\";\n case \"<\":\n return \"<\";\n case \">\":\n return \">\";\n case '\"':\n return \""\";\n default:\n return \"'\";\n }\n });\n}\n",
|
|
13
13
|
"import { findLayouts, routeKeyFromFile, type ApiRouteDefinition, type RouteDefinition } from \"@moonsjs/core\";\nimport { relative, sep } from \"node:path\";\n\nexport interface ClientManifestEntry {\n page: string;\n layouts: string[];\n}\n\n/** Key manifest untuk halaman kustom `_404` dan `_error` (§11.2). */\nexport const NOT_FOUND_ROUTE_KEY = \"__moons/404\";\nexport const ERROR_ROUTE_KEY = \"__moons/error\";\n\n/**\n * Manifest route untuk client (PRD §8.2): key = key route file\n * (routeKeyFromFile), nilai = page + layout chain dari root ke leaf.\n */\nexport function buildClientManifest(\n routes: RouteDefinition[],\n routesDir: string,\n): Record<string, ClientManifestEntry> {\n const manifest: Record<string, ClientManifestEntry> = {};\n for (const route of routes) {\n if (route.kind !== \"page\") {\n continue;\n }\n const key = routeKeyFromFile(routesDir, route.file);\n manifest[key] = {\n page: key,\n layouts: findLayouts(route, routes).map((layout) => routeKeyFromFile(routesDir, layout.file)),\n };\n }\n\n const notFound = routes.find((route) => route.kind === \"404\");\n if (notFound !== undefined) {\n manifest[NOT_FOUND_ROUTE_KEY] = { page: routeKeyFromFile(routesDir, notFound.file), layouts: [] };\n }\n const errorRoute = routes.find((route) => route.kind === \"error\");\n if (errorRoute !== undefined) {\n manifest[ERROR_ROUTE_KEY] = { page: routeKeyFromFile(routesDir, errorRoute.file), layouts: [] };\n }\n // D.3: semua boundary `_error` (termasuk bersarang) ikut manifest — payload\n // memakai key file boundary yang dipilih runtime.\n for (const route of routes) {\n if (route.kind !== \"error\") {\n continue;\n }\n const key = routeKeyFromFile(routesDir, route.file);\n manifest[key] = { page: key, layouts: [] };\n }\n\n return manifest;\n}\n\n/** `virtual:moons/api` (Addendum D.1 + D.3): tabel API + middleware + peta import(). */\nexport function renderApiModule(\n apiRoutes: ApiRouteDefinition[],\n apiMiddlewares: ReadonlyArray<{ file: string; dir: string }>,\n projectRoot: string,\n): string {\n const loadEntries = apiRoutes\n .map(\n (route) =>\n ` ${JSON.stringify(route.path)}: () => import(${JSON.stringify(rootSpecifier(projectRoot, route.file))}),`,\n )\n .join(\"\\n\");\n const middlewareEntries = apiMiddlewares\n .map(\n (middleware) =>\n ` ${JSON.stringify(middleware.file)}: () => import(${JSON.stringify(rootSpecifier(projectRoot, middleware.file))}),`,\n )\n .join(\"\\n\");\n return [\n \"// Generated by @moons. Do not edit manually.\",\n `export const apiRoutes = ${JSON.stringify(apiRoutes, null, 2)};`,\n `export const apiMiddlewares = ${JSON.stringify(apiMiddlewares, null, 2)};`,\n \"export const loadApi = {\",\n loadEntries,\n \"};\",\n \"export const loadApiMiddleware = {\",\n middlewareEntries,\n \"};\",\n \"\",\n ].join(\"\\n\");\n}\n\n/**\n * Isi `virtual:moons/routes`: daftar RouteDefinition, manifest client, dan\n * peta import() dinamis per file route (specifier root-relative).\n */\nexport function renderRoutesModule(\n routes: RouteDefinition[],\n routesDir: string,\n projectRoot: string,\n): string {\n const manifest = buildClientManifest(routes, routesDir);\n\n const loadEntries = routes.map((route) => {\n const key = routeKeyFromFile(routesDir, route.file);\n return ` ${JSON.stringify(key)}: () => import(${JSON.stringify(rootSpecifier(projectRoot, route.file))}),`;\n });\n\n return [\n \"// Generated by @moons. Do not edit manually.\",\n `export const routes = ${JSON.stringify(routes, null, 2)};`,\n \"\",\n `export const clientManifest = ${JSON.stringify(manifest, null, 2)};`,\n \"\",\n \"export const loadRoute = {\",\n ...loadEntries,\n \"};\",\n \"\",\n ].join(\"\\n\");\n}\n\n/** Path file absolut project → specifier root-relative yang bisa di-resolve Vite. */\nexport function rootSpecifier(projectRoot: string, file: string): string {\n let rel = relative(projectRoot, file);\n rel = sep === \"/\" ? rel : rel.split(sep).join(\"/\");\n return rel.startsWith(\"/\") ? rel : `/${rel}`;\n}\n"
|
|
14
14
|
],
|
|
15
|
-
"mappings": "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",
|
|
16
|
-
"debugId": "
|
|
15
|
+
"mappings": "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",
|
|
16
|
+
"debugId": "26DA1EA083AC44E964756E2164756E21",
|
|
17
17
|
"names": []
|
|
18
18
|
}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun-server.d.ts","sourceRoot":"","sources":["../../src/server/bun-server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bun-server.d.ts","sourceRoot":"","sources":["../../src/server/bun-server.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGvD;;;;;GAKG;AAEH,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,sBAAsB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD;AA4ID;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAChD,OAAO,GAAE,iBAAsB,GAC9B,eAAe,CA6QjB"}
|
package/dist/server/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
runHandlerWithTimeout,
|
|
25
25
|
isAbortLike,
|
|
26
26
|
textResponseWithHeaders,
|
|
27
|
+
parseRangeHeader,
|
|
27
28
|
applyStaticHeaders,
|
|
28
29
|
readBodyWithLimit,
|
|
29
30
|
resolveStaticFile2,
|
|
@@ -34,7 +35,7 @@ import {
|
|
|
34
35
|
toWebRequest2,
|
|
35
36
|
sendNodeResponse2,
|
|
36
37
|
installDevMiddleware2
|
|
37
|
-
} from "../index-
|
|
38
|
+
} from "../index-h92zw0gs.js";
|
|
38
39
|
|
|
39
40
|
// src/server/handler.ts
|
|
40
41
|
import {
|
|
@@ -769,6 +770,22 @@ function startNodeServer(handler, options = {}) {
|
|
|
769
770
|
res.end();
|
|
770
771
|
return;
|
|
771
772
|
}
|
|
773
|
+
res.setHeader("accept-ranges", "bytes");
|
|
774
|
+
const rawRange = req.headers["range"];
|
|
775
|
+
const range = parseRangeHeader(Array.isArray(rawRange) ? rawRange[0] ?? null : rawRange ?? null, stat.size);
|
|
776
|
+
if (req.method === "GET" && range !== null) {
|
|
777
|
+
if (range.kind === "unsatisfiable") {
|
|
778
|
+
res.statusCode = 416;
|
|
779
|
+
res.setHeader("content-range", `bytes */${stat.size}`);
|
|
780
|
+
res.end();
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
const slice = body.subarray(range.start, range.end + 1);
|
|
784
|
+
res.statusCode = 206;
|
|
785
|
+
res.setHeader("content-range", `bytes ${range.start}-${range.end}/${stat.size}`);
|
|
786
|
+
res.end(slice);
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
772
789
|
let payload = body;
|
|
773
790
|
const encodings = req.headers["accept-encoding"];
|
|
774
791
|
const acceptsGzip = acceptsGzipHeader(Array.isArray(encodings) ? encodings[0] ?? null : encodings ?? null);
|
|
@@ -1067,6 +1084,18 @@ function startBunServer(handler, options = {}) {
|
|
|
1067
1084
|
if (ifNoneMatch !== null && ifNoneMatch.split(",").some((value) => value.trim() === etag)) {
|
|
1068
1085
|
return new Response(null, { status: 304, headers });
|
|
1069
1086
|
}
|
|
1087
|
+
headers.set("accept-ranges", "bytes");
|
|
1088
|
+
const range = request.method === "GET" ? parseRangeHeader(request.headers.get("range"), stat.size) : null;
|
|
1089
|
+
if (range !== null) {
|
|
1090
|
+
if (range.kind === "unsatisfiable") {
|
|
1091
|
+
headers.set("content-range", `bytes */${stat.size}`);
|
|
1092
|
+
return new Response(null, { status: 416, headers });
|
|
1093
|
+
}
|
|
1094
|
+
const full = readFileSync3(staticFile);
|
|
1095
|
+
const slice = full.subarray(range.start, range.end + 1);
|
|
1096
|
+
headers.set("content-range", `bytes ${range.start}-${range.end}/${stat.size}`);
|
|
1097
|
+
return new Response(slice, { status: 206, headers });
|
|
1098
|
+
}
|
|
1070
1099
|
let payload = request.method === "HEAD" ? null : readFileSync3(staticFile);
|
|
1071
1100
|
if (payload !== null && COMPRESSIBLE_FILE.test(staticFile) && payload.byteLength >= GZIP_MIN_BYTES && acceptsGzipHeader(request.headers.get("accept-encoding"))) {
|
|
1072
1101
|
payload = gzipCached(staticFile, stat.mtimeMs, Buffer.from(payload));
|
|
@@ -1601,4 +1630,4 @@ export {
|
|
|
1601
1630
|
toWebRequest2 as toWebRequest
|
|
1602
1631
|
};
|
|
1603
1632
|
|
|
1604
|
-
//# debugId=
|
|
1633
|
+
//# debugId=01F6AD8AA11E371C64756E2164756E21
|
package/dist/server/index.js.map
CHANGED
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
"sources": ["../src/server/handler.ts", "../src/server/node-server.ts", "../src/server/storage.ts", "../src/server/logger.ts", "../src/server/shutdown.ts", "../src/server/bun-server.ts", "../src/server/server-select.ts", "../src/server/test-server.ts", "../src/server/plugins.ts", "../src/server/prerender.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import {\n MoonsError,\n composeMiddleware,\n findApiDirMiddlewares,\n findDirMiddlewares,\n findErrorBoundary,\n isNotFoundSignal,\n isRedirectSignal,\n resolveRoute,\n routeKeyFromFile,\n runLoaders,\n type ApiMethod,\n type ApiMiddlewareDefinition,\n type ApiRouteDefinition,\n type Middleware,\n type MoonsConfig,\n type ResolvedRoute,\n type RouteDefinition,\n type RouteModule,\n trailingSlashRedirect,\n} from \"@moonsjs/core\";\nimport { encodeSsrPayload, reviveError, serializeError } from \"@moonsjs/core/serialize\";\nimport { API_METHODS, resolveApiRoute } from \"@moonsjs/core\";\nimport type { renderToMarkup as RenderToMarkupFn } from \"@moonsjs/react/ssr\";\n\ntype RenderMarkup = typeof RenderToMarkupFn;\n\n/**\n * Fallback renderer for direct `createRequestHandler` users. Generated entries\n * (dev/build/prerender) and the test server inject an app-resolved renderer;\n * test preloads set `__moons_renderToMarkup` — awaiting a dynamic import inside\n * a request drops AsyncLocalStorage context in Bun, which breaks response\n * helpers. Keep this path lazy and preloaded in tests.\n */\nfunction loadDefaultRenderer(): Promise<RenderMarkup | null> {\n return import(\"@moonsjs/react/ssr\")\n .then((mod) => (mod as { renderToMarkup: RenderMarkup }).renderToMarkup)\n .catch(() => null);\n}\nlet defaultRenderer: Promise<RenderMarkup | null> | null = null;\nimport type { ClientRouteEntry, RouteModuleShape } from \"@moonsjs/react/internal\";\nimport { createRpcHandler, runWithContext, runWithRequestCache, runWithResponseCollector, takeResponseMutations } from \"@moonsjs/server\";\nimport { NOT_FOUND_ROUTE_KEY } from \"../manifest\";\nimport { scanPayloadForSecrets, type PayloadScanOptions } from \"../payload-scan\";\nimport type { Shell } from \"./shell\";\n\nconst RPC_PREFIX = \"/_moons/fn/\";\nconst HEALTH_PATH = \"/_moons/health\";\n\nexport interface RequestHandlerOptions {\n routes: RouteDefinition[];\n /** Config yang sudah divalidasi. */\n config: MoonsConfig;\n /** Direktori route absolut; dipakai untuk derivasi key stabil. */\n routesDir: string;\n /** Peta import() modul route, key = routeKeyFromFile. */\n loadRoute: Record<string, () => Promise<RouteModule>>;\n shell: Shell;\n /**\n * Dipanggil setelah `config.context` per request (Addendum B.4: extender\n * `extendContext` plugin di-merge ke ctx).\n */\n onContext?: (ctx: Ctx) => void;\n /**\n * A1: pemindaian payload SSR (dev) — peringatan sekali per label bila payload\n * memuat canary/nilai env mirip-rahasia. Production TIDAK mengisi opsi ini\n * (tanpa biaya runtime). Lihat `payload-scan.ts`.\n */\n payloadScan?: PayloadScanOptions;\n /** Endpoint API `src/api` (Addendum D.1) — hasil scan plugin. */\n apiRoutes?: ApiRouteDefinition[];\n /** Peta import() modul API, key = route.path. */\n loadApi?: Record<string, () => Promise<unknown>>;\n /** Middleware direktori pohon `src/api` (Addendum D.3). */\n apiMiddlewares?: ApiMiddlewareDefinition[];\n /** Peta import() `_middleware.ts` pohon api, key = file path. */\n loadApiMiddleware?: Record<string, () => Promise<unknown>>;\n /**\n * Addendum O: sumber `renderToMarkup`. Test server memakai loader ini untuk\n * memuat renderer dari `node_modules` app (Bun meresolusi paket registry dari\n * cache; peer `react-dom` tidak ditemukan dari sana).\n */\n renderer?: () => Promise<RenderMarkup>;\n}\n\n/**\n * Handler HTML: context → middleware global → resolve route → loader paralel\n * → render React → inject payload devalue (PRD §11.2, §14.2, §17).\n */\nexport function createRequestHandler(\n options: RequestHandlerOptions,\n): (request: Request) => Promise<Response> {\n let renderMarkup: RenderMarkup | null = null;\n const getRenderMarkup = async (): Promise<RenderMarkup> => {\n if (renderMarkup !== null) {\n return renderMarkup;\n }\n // A preloaded renderer (test preloads) avoids awaiting a pending import\n // inside a request — Bun drops AsyncLocalStorage contexts in that case.\n const injected = (globalThis as { __moons_renderToMarkup?: unknown }).__moons_renderToMarkup;\n if (typeof injected === \"function\") {\n renderMarkup = injected as RenderMarkup;\n return renderMarkup;\n }\n const resolved =\n options.renderer === undefined\n ? await (defaultRenderer ??= loadDefaultRenderer())\n : await options.renderer();\n if (resolved === null) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n message: \"SSR renderer could not be loaded\",\n details:\n \"`@moonsjs/react/ssr` is not resolvable with its peers from this process. \" +\n \"Run tests through `moons test`, which injects an app-resolved renderer.\",\n suggestions: [\n \"Use `moons test` instead of a bare `bun test`\",\n \"Ensure @moonsjs/react and react-dom are installed in the app\",\n ],\n });\n }\n renderMarkup = resolved;\n return renderMarkup;\n };\n const { routes, config, routesDir, loadRoute, shell } = options;\n const rpc = createRpcHandler(\n config.security === undefined ? {} : { security: config.security },\n );\n const notFoundRoute = routes.find((route) => route.kind === \"404\");\n const errorRoute = routes.find((route) => route.kind === \"error\");\n /** A1: dedupe peringatan payload (sekali per label). */\n const warnedPayloadLabels = new Set<string>();\n\n async function renderRoute(\n resolved: ResolvedRoute,\n request: Request,\n ctx: Ctx,\n ): Promise<Response> {\n const entries = [...resolved.layouts, resolved.route];\n const keys = entries.map((entry) => routeKeyFromFile(routesDir, entry.file));\n const modules = await loadModules(keys, loadRoute);\n\n const data = await runLoaders(\n entries.map((entry, index) => ({ file: keys[index] as string, module: modules[index] as RouteModule })),\n { params: resolved.params, ctx, req: request },\n );\n\n const pageKey = routeKeyFromFile(routesDir, resolved.route.file);\n const pageModule = modules[modules.length - 1] as RouteModule;\n const entry: ClientRouteEntry = { page: pageKey, layouts: keys.slice(0, -1) };\n // Addendum A.3: query string ikut ke payload agar server/client identik.\n const searchParams = Object.fromEntries(new URL(request.url).searchParams);\n // Addendum B.1: eksekusi `meta()` page (data = hasil loader page itu sendiri).\n const meta = await runRouteMeta(pageModule, data[pageKey], resolved.route.file);\n\n const render = await getRenderMarkup();\n const markup = render(\n entry,\n { page: pageModule as RouteModuleShape, layouts: modules.slice(0, -1) as RouteModuleShape[] },\n resolved.params,\n data,\n searchParams,\n undefined,\n config.trailingSlash,\n );\n const payload = encodeSsrPayload({\n key: pageKey,\n params: resolved.params,\n searchParams,\n data,\n ...(meta === undefined ? {} : { meta }),\n });\n\n // A1: pindai payload SSR (dev saja — `payloadScan` tidak diisi production).\n warnPayloadFindings(payload, options.payloadScan, warnedPayloadLabels);\n\n return htmlResponse(\n withTrailingSlashMeta(await shell(markup, payload, request.url, meta), config.trailingSlash),\n 200,\n );\n }\n\n /** Addendum D.1: dispatch endpoint `src/api` (405/HEAD/OPTIONS + error). */\n async function handleApiRequest(\n route: ApiRouteDefinition,\n params: Record<string, string>,\n request: Request,\n ctx: Ctx,\n ): Promise<Response> {\n const load = options.loadApi?.[route.path];\n if (load === undefined) {\n return apiErrorResponse(\n new MoonsError({\n code: \"E_API_HANDLER_INVALID\",\n file: route.file,\n message: `API module \\`${route.path}\\` could not be loaded`,\n details: \"The `loadApi` map does not contain this route (build/dev out of sync).\",\n suggestions: [\"Rebuild / restart the dev server\"],\n }),\n route,\n );\n }\n\n let mod: unknown;\n try {\n mod = await load();\n } catch (error) {\n return apiErrorResponse(error, route);\n }\n if (mod === null || typeof mod !== \"object\") {\n return apiErrorResponse(\n new MoonsError({\n code: \"E_API_HANDLER_INVALID\",\n file: route.file,\n message: \"API module does not export a handler object\",\n details: `Module \\`${route.path}\\` must export method handlers.`,\n suggestions: [\"Export `GET`/`POST`/… as `(args) => Response` functions\"],\n }),\n route,\n );\n }\n\n const record = mod as Record<string, unknown>;\n const methods: ApiMethod[] = API_METHODS.filter(\n (method) => typeof record[method] === \"function\",\n );\n const requestMethod = request.method.toUpperCase();\n type ApiHandlerFn = (args: {\n req: Request;\n params: Record<string, string>;\n ctx: Ctx;\n }) => Response | Promise<Response>;\n let handler = record[requestMethod] as ApiHandlerFn | undefined;\n let stripBody = false;\n\n // D.7 #2: HEAD otomatis dari GET; OPTIONS otomatis → 204 + Allow.\n if (typeof handler !== \"function\" && requestMethod === \"HEAD\" && typeof record[\"GET\"] === \"function\") {\n handler = record[\"GET\"] as ApiHandlerFn;\n stripBody = true;\n }\n if (typeof handler !== \"function\") {\n if (requestMethod === \"OPTIONS\") {\n return new Response(null, { status: 204, headers: { allow: methods.join(\", \") } });\n }\n return new Response(\"Method Not Allowed\", {\n status: 405,\n headers: { allow: methods.join(\", \") },\n });\n }\n\n try {\n const result = await handler({ req: request, params, ctx });\n if (!(result instanceof Response)) {\n return apiErrorResponse(\n new MoonsError({\n code: \"E_API_HANDLER_INVALID\",\n file: route.file,\n message: `handler \\`${requestMethod}\\` did not return a \\`Response\\``,\n details: \"API handlers must return `new Response(...)`.\",\n suggestions: [\"Return `new Response(body, { status, headers })`\"],\n }),\n route,\n );\n }\n if (stripBody) {\n return new Response(null, { status: result.status, headers: result.headers });\n }\n return result;\n } catch (error) {\n return apiErrorResponse(error, route);\n }\n }\n\n /** §11.2: halaman `_404.tsx` kustom (standalone), fallback bawaan. */\n async function notFoundResponse(request: Request): Promise<Response> {\n if (notFoundRoute !== undefined) {\n try {\n const key = routeKeyFromFile(routesDir, notFoundRoute.file);\n const [module] = await loadModules([key], loadRoute);\n const payload = encodeSsrPayload({ key: NOT_FOUND_ROUTE_KEY, params: {}, data: {} });\n const render = await getRenderMarkup();\n const markup = render(\n { page: key, layouts: [] },\n { page: module as RouteModuleShape, layouts: [] },\n {},\n {},\n {},\n undefined,\n config.trailingSlash,\n );\n return htmlResponse(\n withTrailingSlashMeta(await shell(markup, payload, request.url), config.trailingSlash),\n 404,\n );\n } catch (error) {\n console.error(\"[moons] failed to render custom _404:\", error);\n }\n }\n\n const payload = encodeSsrPayload({ key: \"\", params: {}, data: {} });\n const html = await shell(\"<h1>404</h1><p>Page not found.</p>\", payload, request.url);\n return htmlResponse(withTrailingSlashMeta(html, config.trailingSlash), 404);\n }\n\n /**\n * §11.2/D.3: `_error.tsx` kustom (boundary terdekat dari route; fallback\n * root). Production tidak men-serialisasi error apa pun (§16.6).\n */\n async function routeErrorResponse(\n error: unknown,\n request: Request,\n resolved?: ResolvedRoute,\n ): Promise<Response> {\n console.error(\"[moons] route error:\", error);\n\n const boundary =\n (resolved === undefined ? null : findErrorBoundary(resolved.route, routes)) ??\n errorRoute ??\n null;\n if (boundary !== null) {\n try {\n const key = routeKeyFromFile(routesDir, boundary.file);\n const [module] = await loadModules([key], loadRoute);\n const isProduction = process.env[\"NODE_ENV\"] === \"production\";\n const serialized = isProduction ? undefined : serializeError(error);\n const payload = encodeSsrPayload({\n key,\n params: {},\n data: {},\n ...(serialized === undefined ? {} : { error: serialized }),\n });\n const render = await getRenderMarkup();\n const markup = render(\n { page: key, layouts: [] },\n { page: module as RouteModuleShape, layouts: [] },\n {},\n {},\n {},\n serialized === undefined ? undefined : reviveError(serialized),\n config.trailingSlash,\n );\n return htmlResponse(\n withTrailingSlashMeta(await shell(markup, payload, request.url), config.trailingSlash),\n 500,\n );\n } catch (renderError) {\n console.error(\"[moons] failed to render custom _error:\", renderError);\n }\n }\n\n return internalErrorResponse(error, { log: false });\n }\n\n /** Muat middleware direktori (D.3) → `Middleware[]`; error bentuk jelas. */\n async function loadDirMiddlewares(chain: ReadonlyArray<RouteDefinition>): Promise<Middleware[]> {\n const result: Middleware[] = [];\n for (const definition of chain) {\n const key = routeKeyFromFile(routesDir, definition.file);\n const load = options.loadRoute?.[key];\n if (load === undefined) {\n throw new MoonsError({\n code: \"E_MIDDLEWARE_INVALID\",\n file: definition.file,\n message: \"directory middleware could not be loaded\",\n details: \"The `loadRoute` map does not contain this `_middleware.ts`.\",\n suggestions: [\"Restart the dev server / rebuild\"],\n });\n }\n const module = (await load()) as { default?: unknown };\n const handler = module.default;\n if (typeof handler !== \"function\") {\n throw new MoonsError({\n code: \"E_MIDDLEWARE_INVALID\",\n file: definition.file,\n message: \"`_middleware.ts` does not default-export a function\",\n details: \"Directory middleware follows the `(args) => Promise<Response>` shape.\",\n suggestions: [\"Export default `async ({ req, ctx, next }) => await next()`\"],\n });\n }\n result.push(handler as Middleware);\n }\n return result;\n }\n\n /** Muat middleware pohon `src/api` (D.3). */\n async function loadApiDirMiddlewares(\n chain: ReadonlyArray<ApiMiddlewareDefinition>,\n ): Promise<Middleware[]> {\n const result: Middleware[] = [];\n for (const definition of chain) {\n const load = options.loadApiMiddleware?.[definition.file];\n if (load === undefined) {\n throw new MoonsError({\n code: \"E_MIDDLEWARE_INVALID\",\n file: definition.file,\n message: \"API middleware could not be loaded\",\n details: \"The `loadApiMiddleware` map does not contain this `_middleware.ts`.\",\n suggestions: [\"Restart the dev server / rebuild\"],\n });\n }\n const module = (await load()) as { default?: unknown };\n if (typeof module.default !== \"function\") {\n throw new MoonsError({\n code: \"E_MIDDLEWARE_INVALID\",\n file: definition.file,\n message: \"`_middleware.ts` does not default-export a function\",\n details: \"Directory middleware follows the `(args) => Promise<Response>` shape.\",\n suggestions: [\"Export default `async ({ req, ctx, next }) => await next()`\"],\n });\n }\n result.push(module.default as Middleware);\n }\n return result;\n }\n\n const handleCore = async function handler(request: Request): Promise<Response> {\n try {\n const url = new URL(request.url);\n\n // §19.5: health ditangani paling awal — tetap hidup walau kode user rusak.\n if (url.pathname === HEALTH_PATH) {\n return healthResponse(request.method);\n }\n\n // `MoonsConfig.context` bertipe `unknown` (menghindari referensi sirkular\n // ke global `Ctx` — §13); kontraknya tetap `Promise<Ctx>`, jadi cast di\n // batas runtime ini. Tanpa cast, tsc app user yang memuat `@moonsjs/vite/server`\n // (mis. `createTestServer` §19.5) melihat `unknown` vs `Ctx` global app.\n const ctx = (await config.context(request)) as Ctx;\n options.onContext?.(ctx);\n // Addendum D.5: tandai request prerender build-time (aditif §13.1).\n if (request.headers.get(\"x-moons-prerender\") === \"1\") {\n (ctx as Record<string, unknown>)[\"__prerender\"] = true;\n }\n\n const respond = composeMiddleware(config.middleware ?? [], ctx, async () => {\n if (url.pathname.startsWith(RPC_PREFIX)) {\n return await rpc(request, url.pathname.slice(RPC_PREFIX.length), ctx);\n }\n // Addendum D.1: endpoint HTTP mentah `src/api` (semua method).\n if (options.apiRoutes !== undefined && options.apiRoutes.length > 0) {\n const apiMatch = resolveApiRoute(url.pathname, options.apiRoutes);\n if (apiMatch !== null) {\n // Addendum D.3: middleware direktori pohon api.\n const apiChain = findApiDirMiddlewares(\n apiMatch.route.file,\n options.apiMiddlewares ?? [],\n );\n if (apiChain.length === 0) {\n return await handleApiRequest(apiMatch.route, apiMatch.params, request, ctx);\n }\n const middlewares = await loadApiDirMiddlewares(apiChain);\n return await composeMiddleware(\n middlewares,\n ctx,\n () => handleApiRequest(apiMatch.route, apiMatch.params, request, ctx),\n { code: \"E_MIDDLEWARE_INVALID\", label: \"API middleware\" },\n )(request);\n }\n }\n const resolved = resolveRoute(url.pathname, routes);\n if (resolved === null) {\n return await notFoundResponse(request);\n }\n try {\n // Addendum D.3: middleware direktori (root→leaf) untuk page.\n const dirChain = findDirMiddlewares(resolved.route, routes);\n if (dirChain.length === 0) {\n return await renderRoute(resolved, request, ctx);\n }\n const middlewares = await loadDirMiddlewares(dirChain);\n return await composeMiddleware(\n middlewares,\n ctx,\n () => renderRoute(resolved, request, ctx),\n { code: \"E_MIDDLEWARE_INVALID\", label: \"directory middleware\" },\n )(request);\n } catch (error) {\n // Addendum B.2: sinyal routing dari loader/meta.\n if (isRedirectSignal(error)) {\n return new Response(null, {\n status: error.status,\n headers: { location: new URL(error.to, request.url).toString() },\n });\n }\n if (isNotFoundSignal(error)) {\n return await notFoundResponse(request);\n }\n return await routeErrorResponse(error, request, resolved);\n }\n });\n\n // Addendum D.2: kolektor mutasi respons aktif selama request; helper\n // (setHeader/setCookie) menulis ke store, diterapkan ke Response akhir —\n // termasuk jalur error (mutasi yang sudah dipush tetap dihormati).\n return await runWithResponseCollector(async () => {\n let response: Response;\n try {\n response = await runWithRequestCache(() => runWithContext(ctx, () => respond(request)));\n } catch (error) {\n response = internalErrorResponse(error);\n }\n return applyResponseMutations(response);\n });\n } catch (error) {\n return internalErrorResponse(error);\n }\n };\n\n // Addendum H: redirect statis + hook lifecycle + header statis.\n const staticHeaders = Object.entries(config.headers ?? {});\n const redirects = (config.redirects ?? []).map((entry) => ({\n ...entry,\n status: entry.status ?? 301,\n }));\n\n return async function handler(request: Request): Promise<Response> {\n const isPrerender = request.headers.get(\"x-moons-prerender\") === \"1\";\n const applyHeaders = (response: Response): Response => {\n for (const [name, value] of staticHeaders) {\n if (!response.headers.has(name)) {\n response.headers.set(name, value);\n }\n }\n return response;\n };\n\n try {\n // Addendum M: kanonikalisasi trailing slash sebelum routing (308,\n // query dipertahankan; `/_moons/**`, root, dan aset dikecualikan).\n if (!isPrerender && config.trailingSlash !== undefined) {\n const policyUrl = new URL(request.url);\n const canonical = trailingSlashRedirect(policyUrl.pathname, config.trailingSlash);\n if (canonical !== null) {\n policyUrl.pathname = canonical;\n return applyHeaders(\n new Response(null, { status: 308, headers: { location: policyUrl.toString() } }),\n );\n }\n }\n\n if (!isPrerender && redirects.length > 0) {\n const url = new URL(request.url);\n const path = url.pathname.replace(/\\/$/, \"\");\n for (const entry of redirects) {\n if (path === entry.from.replace(/\\/$/, \"\")) {\n const location = entry.to.startsWith(\"http\")\n ? entry.to\n : new URL(entry.to, url.origin).toString();\n return applyHeaders(\n new Response(null, { status: entry.status, headers: { location } }),\n );\n }\n }\n }\n\n await config.hooks?.onRequest?.(request);\n let response = await handleCore(request);\n const replaced = await config.hooks?.onResponse?.(response, request);\n if (replaced instanceof Response) {\n response = replaced;\n }\n return applyHeaders(response);\n } catch (error) {\n try {\n await config.hooks?.onError?.(error, request);\n } catch {\n // Kegagalan hook tidak boleh menutupi error asli.\n }\n return internalErrorResponse(error);\n }\n };\n}\n\n/** Terapkan mutasi `setHeader`/`appendHeader`/`setCookie` ke respons (D.2). */\nfunction applyResponseMutations(response: Response): Response {\n const mutations = takeResponseMutations();\n if (mutations.length === 0) {\n return response;\n }\n const headers = new Headers(response.headers);\n for (const mutation of mutations) {\n if (mutation.kind === \"header\") {\n if (mutation.append) {\n headers.append(mutation.name, mutation.value);\n } else {\n headers.set(mutation.name, mutation.value);\n }\n } else {\n headers.append(\"set-cookie\", mutation.value);\n }\n }\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nasync function loadModules(\n keys: string[],\n loadRoute: Record<string, () => Promise<RouteModule>>,\n): Promise<RouteModule[]> {\n return await Promise.all(\n keys.map(async (key) => {\n const load = loadRoute[key];\n if (load === undefined) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n message: `route module \\`${key}\\` is not registered`,\n details: \"The route registry is out of sync with the scan result.\",\n suggestions: [\"Run `bun run build` again, or restart the dev server\"],\n });\n }\n return await load();\n }),\n );\n}\n\nasync function runRouteMeta(\n pageModule: RouteModule,\n pageData: unknown,\n file: string,\n): Promise<Record<string, unknown> | undefined> {\n const meta = (pageModule as { meta?: unknown }).meta;\n if (meta === undefined) {\n return undefined;\n }\n if (typeof meta !== \"function\") {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n file,\n message: \"export `meta` must be a function `({ data }) => RouteMeta`\",\n details: \"The `meta` shape follows `RouteMeta`.\",\n suggestions: [\n \"Change it to `export const meta = ({ data }) => ({ title: \\\"...\\\" })`\",\n \"Or remove the `meta` export\",\n ],\n });\n }\n const result = await (meta as (args: { data: unknown }) => unknown)({ data: pageData });\n if (result === null || typeof result !== \"object\" || Array.isArray(result)) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n file,\n message: \"`meta()` must return a RouteMeta object\",\n details: \"The returned value is used for <title>/description/og.\",\n suggestions: [\"Return an object, e.g. `({ title: \\\"Home\\\" })`\"],\n });\n }\n return result as Record<string, unknown>;\n}\n\n/**\n * Error endpoint API (Addendum D.1): detail hanya di non-production (§16.6).\n */\nfunction apiErrorResponse(error: unknown, route: ApiRouteDefinition): Response {\n const isProduction = process.env[\"NODE_ENV\"] === \"production\";\n if (error instanceof MoonsError) {\n console.error(`[moons] API ${route.path}: ${error.format()}`);\n return new Response(isProduction ? \"Internal server error.\" : error.format(), {\n status: 500,\n headers: { \"content-type\": \"text/plain; charset=utf-8\" },\n });\n }\n console.error(`[moons] API ${route.path}:`, error);\n return new Response(isProduction ? \"Internal server error.\" : String(error), {\n status: 500,\n headers: { \"content-type\": \"text/plain; charset=utf-8\" },\n });\n}\n\nfunction internalErrorResponse(error: unknown, options: { log?: boolean } = {}): Response {\n if (options.log !== false) {\n console.error(\"[moons] request error:\", error);\n }\n\n const detail =\n process.env[\"NODE_ENV\"] !== \"production\" && error instanceof MoonsError\n ? `<pre>${escapeHtml(error.format())}</pre>`\n : \"<p>Internal server error.</p>\";\n\n return htmlResponse(\n `<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><title>500</title></head><body><h1>500</h1>${detail}</body></html>`,\n 500,\n );\n}\n\n/** Addendum O: expose the trailing-slash policy to the client runtime. */\nfunction withTrailingSlashMeta(html: string, policy?: \"never\" | \"always\"): string {\n if (policy === undefined) {\n return html;\n }\n return html.replace(\n \"</head>\",\n ` <meta name=\"moons:trailing-slash\" content=\"${policy}\" />\\n</head>`,\n );\n}\n\nfunction htmlResponse(html: string, status: number): Response {\n return new Response(html, {\n status,\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n });\n}\n\n/** §19.5: `/_moons/health` → `{ ok: true }`. */\nfunction healthResponse(method: string): Response {\n const headers = { \"content-type\": \"application/json; charset=utf-8\" };\n if (method === \"GET\" || method === \"HEAD\") {\n return new Response(method === \"HEAD\" ? null : JSON.stringify({ ok: true }), {\n status: 200,\n headers,\n });\n }\n return new Response(\"Method Not Allowed\", {\n status: 405,\n headers: { allow: \"GET, HEAD\" },\n });\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replaceAll(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll('\"', \""\");\n}\n\n/**\n * A1: peringatan dev untuk payload SSR yang memuat canary/nilai env\n * mirip-rahasia (sekali per label). Tidak pernah aktif di production karena\n * `payloadScan` hanya diisi runtime dev.\n */\nfunction warnPayloadFindings(\n payload: string,\n scan: PayloadScanOptions | undefined,\n warned: Set<string>,\n): void {\n if (scan === undefined) {\n return;\n }\n for (const finding of scanPayloadForSecrets(payload, scan)) {\n const label = finding.kind === \"canary\" ? \"canary\" : `env(${finding.label})`;\n if (warned.has(label)) {\n continue;\n }\n warned.add(label);\n console.warn(\n `[moons] dev warning: SSR payload contains ${label} — do not return secrets from loaders.`,\n );\n }\n}\n",
|
|
6
|
-
"import { readFileSync, statSync } from \"node:fs\";\nimport { createServer, type Server } from \"node:http\";\nimport { extname, join, resolve } from \"node:path\";\nimport {\n DEFAULT_BODY_LIMIT_BYTES,\n trailingSlashRedirect,\n type PrerenderStorage,\n} from \"@moonsjs/core\";\nimport { contentTypeForPathname } from \"./storage\";\nimport {\n BodyLimitError,\n COMPRESSIBLE_FILE,\n GZIP_MIN_BYTES,\n InvalidRequestError,\n MIME_TYPES,\n RequestTimeoutError,\n acceptsGzipHeader,\n applyStaticHeaders,\n gzipCached,\n isAbortLike,\n requestTimeoutText,\n resolveStaticFile,\n rpcBodyTooLargeText,\n runHandlerWithTimeout,\n scheduleRevalidation,\n} from \"./transport\";\nimport {\n resolveClientIp,\n resolveRequestUrl,\n sendNodeResponse,\n toWebRequest,\n} from \"./node\";\nimport { createLogger, type Logger } from \"./logger\";\nimport type { PluginRuntime } from \"./plugins\";\nimport { installGracefulShutdown } from \"./shutdown\";\n\n// Kontrak lama tetap diekspor dari sini (index.ts & test lama).\nexport { resolveStaticFile, staticFileTarget } from \"./transport\";\nexport type { PrerenderManifestInfo } from \"./transport\";\n\nexport interface NodeServerOptions {\n port?: number;\n clientDir?: string;\n /** Pasang handler SIGTERM/SIGINT (default true). */\n handleSignals?: boolean;\n /** Batas drain shutdown (default 10_000 ms). */\n shutdownTimeoutMs?: number;\n /** Lifecycle plugin (Addendum B.4) — onStart/onReady/onShutdown. */\n plugins?: PluginRuntime;\n /** Canary `leakTest.canary` untuk guard ISR (Addendum E.1). */\n canary?: string;\n /**\n * Header statis dari config (Addendum H). Diterapkan juga pada file\n * prerender yang disajikan langsung (static host memakai `_headers`).\n */\n headers?: Record<string, string>;\n /**\n * Storage bersama untuk file prerender (Addendum I, ISR multi-instance).\n * Bila diisi, penyajian file prerender dan penulisan hasil regenerasi\n * memakai storage ini; default: file sistem lokal.\n */\n storage?: PrerenderStorage;\n /** Addendum J.1: percayai `x-forwarded-proto`/`x-forwarded-host` (default false). */\n trustProxy?: boolean;\n /** Addendum J.2: batas body RPC di transport (default `DEFAULT_BODY_LIMIT_BYTES`). */\n bodyLimitBytes?: number;\n /** Addendum L.3: log akses terstruktur (default senyap). */\n logging?: { accessLog?: boolean; json?: boolean; redact?: string[] };\n /** Addendum M: kebijakan trailing slash (juga untuk path prerender/static). */\n trailingSlash?: \"never\" | \"always\";\n /** Addendum R: batas waktu respons handler (ms); `0` menonaktifkan. */\n requestTimeoutMs?: number;\n /** Addendum S: header tepercaya untuk IP klien (default `x-forwarded-for`). */\n clientIpHeader?: string;\n}\n\n/**\n * Serve produksi (M1 §19.2, §18): static dari `dist/client` + handler SSR.\n * Berjalan di Bun dan Node (hanya API `node:*`).\n */\nexport function startNodeServer(\n handler: (request: Request) => Promise<Response>,\n options: NodeServerOptions = {},\n): Server {\n const clientDir = resolve(options.clientDir ?? join(process.cwd(), \"dist/client\"));\n const port = options.port ?? Number(process.env[\"PORT\"] ?? 3000);\n\n const accessLogger: Logger | null =\n options.logging?.accessLog === true\n ? createLogger({\n json: options.logging.json !== false,\n redact: options.logging.redact ?? [],\n })\n : null;\n\n const server = createServer((req, res) => {\n const requestStartedAt = performance.now();\n if (accessLogger !== null) {\n res.once(\"finish\", () => {\n const ip = resolveClientIp(\n req,\n options.trustProxy === true,\n options.clientIpHeader ?? \"x-forwarded-for\",\n );\n accessLogger({\n msg: \"request\",\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n status: res.statusCode,\n durationMs: Math.round(performance.now() - requestStartedAt),\n ...(ip === null ? {} : { ip }),\n });\n });\n }\n void (async () => {\n let url: URL;\n try {\n // Addendum J.1: URL/Origin mengikuti `x-forwarded-*` bila trustProxy aktif;\n // request malformed → 400 (bukan 500 + stack).\n url = resolveRequestUrl(req, { trustProxy: options.trustProxy === true });\n } catch (error) {\n if (error instanceof InvalidRequestError) {\n console.warn(`[moons] ${error.message} — 400`);\n respondText(res, 400, \"Bad Request\", options.headers);\n return;\n }\n throw error;\n }\n\n try {\n // Addendum M: kanonikalisasi trailing slash di transport — mencakup\n // path prerender yang dilayani langsung (tidak lewat handler).\n if (options.trailingSlash !== undefined) {\n const canonical = trailingSlashRedirect(url.pathname, options.trailingSlash);\n if (canonical !== null) {\n url.pathname = canonical;\n res.statusCode = 308;\n res.setHeader(\"location\", url.toString());\n res.end();\n return;\n }\n }\n\n if (req.method === \"GET\" || req.method === \"HEAD\") {\n // Addendum I: storage bersama (bila dikonfigurasi) diutamakan.\n if (options.storage !== undefined) {\n // Addendum R (review G2): storage error = miss — aset & halaman\n // non-ISR harus tetap jalan saat store bersama outage.\n let entry: Awaited<ReturnType<PrerenderStorage[\"read\"]>> | null = null;\n try {\n entry = await options.storage.read(url.pathname);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (accessLogger !== null) {\n accessLogger({ msg: \"isr:storage-read-failed\", level: \"warn\", path: url.pathname, error: message });\n } else {\n console.warn(`[moons] isr storage read failed (${url.pathname}): ${message} — falling back to dist/client`);\n }\n }\n if (entry !== null) {\n scheduleRevalidation({\n pathname: url.pathname,\n mtimeMs: entry.mtimeMs,\n storage: options.storage,\n handler,\n options,\n clientDir,\n logger: accessLogger,\n });\n res.statusCode = 200;\n res.setHeader(\"content-type\", contentTypeForPathname(url.pathname));\n applyStaticHeaders(\n { has: (name) => res.hasHeader(name), set: (name, value) => res.setHeader(name, value) },\n url.pathname,\n options.headers,\n );\n res.end(req.method === \"HEAD\" ? undefined : Buffer.from(entry.body));\n return;\n }\n // L.2 (temuan F1): storage MISS → jatuh ke file `dist/client`\n // (aset/non-ISR); storage tetap menang untuk path yang dimilikinya.\n }\n {\n const staticFile = resolveStaticFile(clientDir, url.pathname);\n if (staticFile !== null) {\n scheduleRevalidation({\n pathname: url.pathname,\n mtimeMs: statSync(staticFile).mtimeMs,\n file: staticFile,\n // Bila storage dikonfigurasi, hasil regenerasi (walau fallback\n // dari file) tetap ditulis ke storage bersama (L.2).\n ...(options.storage === undefined ? {} : { storage: options.storage }),\n handler,\n options,\n clientDir,\n logger: accessLogger,\n });\n const body = readFileSync(staticFile);\n const stat = statSync(staticFile);\n res.statusCode = 200;\n res.setHeader(\"content-type\", MIME_TYPES[extname(staticFile).toLowerCase()] ?? \"application/octet-stream\");\n applyStaticHeaders(\n { has: (name) => res.hasHeader(name), set: (name, value) => res.setHeader(name, value) },\n url.pathname,\n options.headers,\n );\n\n // Addendum K.5: ETag + 304.\n const etag = `W/\"${stat.size}-${Math.floor(stat.mtimeMs)}\"`;\n res.setHeader(\"etag\", etag);\n const ifNoneMatch = req.headers[\"if-none-match\"];\n if (\n typeof ifNoneMatch === \"string\" &&\n ifNoneMatch.split(\",\").some((value) => value.trim() === etag)\n ) {\n res.statusCode = 304;\n res.end();\n return;\n }\n\n // Addendum K.5: gzip untuk aset teks (cache per mtime).\n let payload: Buffer = body;\n const encodings = req.headers[\"accept-encoding\"];\n const acceptsGzip = acceptsGzipHeader(\n Array.isArray(encodings) ? (encodings[0] ?? null) : (encodings ?? null),\n );\n if (\n req.method === \"GET\" &&\n COMPRESSIBLE_FILE.test(staticFile) &&\n body.byteLength >= GZIP_MIN_BYTES &&\n acceptsGzip\n ) {\n payload = gzipCached(staticFile, stat.mtimeMs, body);\n res.setHeader(\"content-encoding\", \"gzip\");\n appendVary(res, \"accept-encoding\");\n }\n res.end(req.method === \"HEAD\" ? undefined : payload);\n return;\n }\n }\n }\n\n // Addendum J.2: batas body RPC ditegakkan di transport — lebih awal dari\n // pipeline, tanpa membaca penuh; `content-length` diperiksa lebih dulu.\n const isRpc = url.pathname.startsWith(\"/_moons/fn/\");\n const rpcLimit = options.bodyLimitBytes ?? DEFAULT_BODY_LIMIT_BYTES;\n if (isRpc) {\n const contentLength = Number(req.headers[\"content-length\"] ?? \"0\");\n if (Number.isFinite(contentLength) && contentLength > rpcLimit) {\n respondText(res, 413, rpcBodyTooLargeText(rpcLimit, contentLength), options.headers);\n res.once(\"finish\", () => req.destroy());\n return;\n }\n }\n\n const request = await toWebRequest(req, {\n trustProxy: options.trustProxy === true,\n ...(options.clientIpHeader === undefined ? {} : { clientIpHeader: options.clientIpHeader }),\n ...(isRpc ? { maxBodyBytes: rpcLimit } : {}),\n });\n // Addendum R: batas waktu eksplisit; 0/undefined = tanpa batas.\n const response = await runHandlerWithTimeout(handler, request, options.requestTimeoutMs);\n await sendNodeResponse(res, response);\n } catch (error) {\n if (error instanceof BodyLimitError) {\n const isRpc = url.pathname.startsWith(\"/_moons/fn/\");\n respondText(\n res,\n 413,\n isRpc ? rpcBodyTooLargeText(error.limit, null) : \"Payload Too Large\",\n options.headers,\n );\n // Sisa body tidak perlu dibaca — putuskan setelah respons terkirim.\n res.once(\"finish\", () => req.destroy());\n return;\n }\n // Addendum R: timeout eksplisit — 504 + log terstruktur.\n if (error instanceof RequestTimeoutError) {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request-timeout\",\n level: \"warn\",\n method: req.method ?? \"GET\",\n path: url.pathname + url.search,\n limitMs: error.limit,\n });\n } else {\n console.warn(`[moons] request timed out after ${error.limit}ms — ${req.method ?? \"GET\"} ${url.pathname}`);\n }\n respondText(res, 504, requestTimeoutText(error.limit), options.headers);\n return;\n }\n // Review G7: abort klien/koneksi putus bukan error server (tanpa stack).\n if (isAbortLike(error)) {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request-aborted\",\n level: \"warn\",\n method: req.method ?? \"GET\",\n path: url.pathname + url.search,\n });\n } else {\n console.warn(`[moons] request aborted by the client — ${req.method ?? \"GET\"} ${url.pathname}`);\n }\n if (!res.headersSent && !res.writableEnded) {\n respondText(res, 499, \"Client Closed Request\", options.headers);\n }\n return;\n }\n console.error(\"[moons] server error:\", error);\n respondText(res, 500, \"Internal Server Error\", options.headers);\n }\n })();\n });\n\n // Addendum B.4: onStart sebelum listen, onReady setelah listen.\n const listenAfterStart = (): void => {\n server.listen(port, () => {\n const address = server.address();\n const boundPort = typeof address === \"object\" && address !== null ? address.port : port;\n console.log(`[moons] server listening on http://localhost:${boundPort}`);\n void options.plugins?.ready();\n });\n };\n if (options.plugins !== undefined) {\n void options.plugins.start().then(listenAfterStart);\n } else {\n listenAfterStart();\n }\n\n if (options.handleSignals !== false) {\n const shutdown = installGracefulShutdown(server, {\n ...(options.shutdownTimeoutMs === undefined ? {} : { timeoutMs: options.shutdownTimeoutMs }),\n ...(options.plugins === undefined\n ? {}\n : { onShutdown: () => options.plugins?.shutdown() }),\n });\n // `once`: sinyal kedua memakai perilaku default (proses langsung berhenti).\n process.once(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n process.once(\"SIGINT\", () => shutdown(\"SIGINT\"));\n }\n\n return server;\n}\n\nfunction appendVary(res: import(\"node:http\").ServerResponse, value: string): void {\n const existing = res.getHeader(\"vary\");\n if (typeof existing === \"string\" && existing.length > 0) {\n if (!existing.toLowerCase().includes(value)) {\n res.setHeader(\"vary\", `${existing}, ${value}`);\n }\n return;\n }\n res.setHeader(\"vary\", value);\n}\n\n/** Respons teks transport — ikut membawa header config + default aman (review G6). */\nfunction respondText(\n res: import(\"node:http\").ServerResponse,\n status: number,\n text: string,\n configured: Record<string, string> | undefined,\n): void {\n res.statusCode = status;\n res.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n applyStaticHeaders(\n { has: (name) => res.hasHeader(name), set: (name, value) => res.setHeader(name, value) },\n \"/\",\n configured,\n );\n res.end(text);\n}\n",
|
|
6
|
+
"import { readFileSync, statSync } from \"node:fs\";\nimport { createServer, type Server } from \"node:http\";\nimport { extname, join, resolve } from \"node:path\";\nimport {\n DEFAULT_BODY_LIMIT_BYTES,\n trailingSlashRedirect,\n type PrerenderStorage,\n} from \"@moonsjs/core\";\nimport { contentTypeForPathname } from \"./storage\";\nimport {\n BodyLimitError,\n COMPRESSIBLE_FILE,\n GZIP_MIN_BYTES,\n InvalidRequestError,\n MIME_TYPES,\n RequestTimeoutError,\n acceptsGzipHeader,\n applyStaticHeaders,\n gzipCached,\n isAbortLike,\n parseRangeHeader,\n requestTimeoutText,\n resolveStaticFile,\n rpcBodyTooLargeText,\n runHandlerWithTimeout,\n scheduleRevalidation,\n} from \"./transport\";\nimport {\n resolveClientIp,\n resolveRequestUrl,\n sendNodeResponse,\n toWebRequest,\n} from \"./node\";\nimport { createLogger, type Logger } from \"./logger\";\nimport type { PluginRuntime } from \"./plugins\";\nimport { installGracefulShutdown } from \"./shutdown\";\n\n// Kontrak lama tetap diekspor dari sini (index.ts & test lama).\nexport { resolveStaticFile, staticFileTarget } from \"./transport\";\nexport type { PrerenderManifestInfo } from \"./transport\";\n\nexport interface NodeServerOptions {\n port?: number;\n clientDir?: string;\n /** Pasang handler SIGTERM/SIGINT (default true). */\n handleSignals?: boolean;\n /** Batas drain shutdown (default 10_000 ms). */\n shutdownTimeoutMs?: number;\n /** Lifecycle plugin (Addendum B.4) — onStart/onReady/onShutdown. */\n plugins?: PluginRuntime;\n /** Canary `leakTest.canary` untuk guard ISR (Addendum E.1). */\n canary?: string;\n /**\n * Header statis dari config (Addendum H). Diterapkan juga pada file\n * prerender yang disajikan langsung (static host memakai `_headers`).\n */\n headers?: Record<string, string>;\n /**\n * Storage bersama untuk file prerender (Addendum I, ISR multi-instance).\n * Bila diisi, penyajian file prerender dan penulisan hasil regenerasi\n * memakai storage ini; default: file sistem lokal.\n */\n storage?: PrerenderStorage;\n /** Addendum J.1: percayai `x-forwarded-proto`/`x-forwarded-host` (default false). */\n trustProxy?: boolean;\n /** Addendum J.2: batas body RPC di transport (default `DEFAULT_BODY_LIMIT_BYTES`). */\n bodyLimitBytes?: number;\n /** Addendum L.3: log akses terstruktur (default senyap). */\n logging?: { accessLog?: boolean; json?: boolean; redact?: string[] };\n /** Addendum M: kebijakan trailing slash (juga untuk path prerender/static). */\n trailingSlash?: \"never\" | \"always\";\n /** Addendum R: batas waktu respons handler (ms); `0` menonaktifkan. */\n requestTimeoutMs?: number;\n /** Addendum S: header tepercaya untuk IP klien (default `x-forwarded-for`). */\n clientIpHeader?: string;\n}\n\n/**\n * Serve produksi (M1 §19.2, §18): static dari `dist/client` + handler SSR.\n * Berjalan di Bun dan Node (hanya API `node:*`).\n */\nexport function startNodeServer(\n handler: (request: Request) => Promise<Response>,\n options: NodeServerOptions = {},\n): Server {\n const clientDir = resolve(options.clientDir ?? join(process.cwd(), \"dist/client\"));\n const port = options.port ?? Number(process.env[\"PORT\"] ?? 3000);\n\n const accessLogger: Logger | null =\n options.logging?.accessLog === true\n ? createLogger({\n json: options.logging.json !== false,\n redact: options.logging.redact ?? [],\n })\n : null;\n\n const server = createServer((req, res) => {\n const requestStartedAt = performance.now();\n if (accessLogger !== null) {\n res.once(\"finish\", () => {\n const ip = resolveClientIp(\n req,\n options.trustProxy === true,\n options.clientIpHeader ?? \"x-forwarded-for\",\n );\n accessLogger({\n msg: \"request\",\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n status: res.statusCode,\n durationMs: Math.round(performance.now() - requestStartedAt),\n ...(ip === null ? {} : { ip }),\n });\n });\n }\n void (async () => {\n let url: URL;\n try {\n // Addendum J.1: URL/Origin mengikuti `x-forwarded-*` bila trustProxy aktif;\n // request malformed → 400 (bukan 500 + stack).\n url = resolveRequestUrl(req, { trustProxy: options.trustProxy === true });\n } catch (error) {\n if (error instanceof InvalidRequestError) {\n console.warn(`[moons] ${error.message} — 400`);\n respondText(res, 400, \"Bad Request\", options.headers);\n return;\n }\n throw error;\n }\n\n try {\n // Addendum M: kanonikalisasi trailing slash di transport — mencakup\n // path prerender yang dilayani langsung (tidak lewat handler).\n if (options.trailingSlash !== undefined) {\n const canonical = trailingSlashRedirect(url.pathname, options.trailingSlash);\n if (canonical !== null) {\n url.pathname = canonical;\n res.statusCode = 308;\n res.setHeader(\"location\", url.toString());\n res.end();\n return;\n }\n }\n\n if (req.method === \"GET\" || req.method === \"HEAD\") {\n // Addendum I: storage bersama (bila dikonfigurasi) diutamakan.\n if (options.storage !== undefined) {\n // Addendum R (review G2): storage error = miss — aset & halaman\n // non-ISR harus tetap jalan saat store bersama outage.\n let entry: Awaited<ReturnType<PrerenderStorage[\"read\"]>> | null = null;\n try {\n entry = await options.storage.read(url.pathname);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (accessLogger !== null) {\n accessLogger({ msg: \"isr:storage-read-failed\", level: \"warn\", path: url.pathname, error: message });\n } else {\n console.warn(`[moons] isr storage read failed (${url.pathname}): ${message} — falling back to dist/client`);\n }\n }\n if (entry !== null) {\n scheduleRevalidation({\n pathname: url.pathname,\n mtimeMs: entry.mtimeMs,\n storage: options.storage,\n handler,\n options,\n clientDir,\n logger: accessLogger,\n });\n res.statusCode = 200;\n res.setHeader(\"content-type\", contentTypeForPathname(url.pathname));\n applyStaticHeaders(\n { has: (name) => res.hasHeader(name), set: (name, value) => res.setHeader(name, value) },\n url.pathname,\n options.headers,\n );\n res.end(req.method === \"HEAD\" ? undefined : Buffer.from(entry.body));\n return;\n }\n // L.2 (temuan F1): storage MISS → jatuh ke file `dist/client`\n // (aset/non-ISR); storage tetap menang untuk path yang dimilikinya.\n }\n {\n const staticFile = resolveStaticFile(clientDir, url.pathname);\n if (staticFile !== null) {\n scheduleRevalidation({\n pathname: url.pathname,\n mtimeMs: statSync(staticFile).mtimeMs,\n file: staticFile,\n // Bila storage dikonfigurasi, hasil regenerasi (walau fallback\n // dari file) tetap ditulis ke storage bersama (L.2).\n ...(options.storage === undefined ? {} : { storage: options.storage }),\n handler,\n options,\n clientDir,\n logger: accessLogger,\n });\n const body = readFileSync(staticFile);\n const stat = statSync(staticFile);\n res.statusCode = 200;\n res.setHeader(\"content-type\", MIME_TYPES[extname(staticFile).toLowerCase()] ?? \"application/octet-stream\");\n applyStaticHeaders(\n { has: (name) => res.hasHeader(name), set: (name, value) => res.setHeader(name, value) },\n url.pathname,\n options.headers,\n );\n\n // Addendum K.5: ETag + 304.\n const etag = `W/\"${stat.size}-${Math.floor(stat.mtimeMs)}\"`;\n res.setHeader(\"etag\", etag);\n const ifNoneMatch = req.headers[\"if-none-match\"];\n if (\n typeof ifNoneMatch === \"string\" &&\n ifNoneMatch.split(\",\").some((value) => value.trim() === etag)\n ) {\n res.statusCode = 304;\n res.end();\n return;\n }\n\n // Addendum T (G4): Range single-range untuk file statik (media).\n res.setHeader(\"accept-ranges\", \"bytes\");\n const rawRange = req.headers[\"range\"];\n const range = parseRangeHeader(\n Array.isArray(rawRange) ? (rawRange[0] ?? null) : (rawRange ?? null),\n stat.size,\n );\n if (req.method === \"GET\" && range !== null) {\n if (range.kind === \"unsatisfiable\") {\n res.statusCode = 416;\n res.setHeader(\"content-range\", `bytes */${stat.size}`);\n res.end();\n return;\n }\n const slice = body.subarray(range.start, range.end + 1);\n res.statusCode = 206;\n res.setHeader(\"content-range\", `bytes ${range.start}-${range.end}/${stat.size}`);\n res.end(slice);\n return;\n }\n\n // Addendum K.5: gzip untuk aset teks (cache per mtime).\n let payload: Buffer = body;\n const encodings = req.headers[\"accept-encoding\"];\n const acceptsGzip = acceptsGzipHeader(\n Array.isArray(encodings) ? (encodings[0] ?? null) : (encodings ?? null),\n );\n if (\n req.method === \"GET\" &&\n COMPRESSIBLE_FILE.test(staticFile) &&\n body.byteLength >= GZIP_MIN_BYTES &&\n acceptsGzip\n ) {\n payload = gzipCached(staticFile, stat.mtimeMs, body);\n res.setHeader(\"content-encoding\", \"gzip\");\n appendVary(res, \"accept-encoding\");\n }\n res.end(req.method === \"HEAD\" ? undefined : payload);\n return;\n }\n }\n }\n\n // Addendum J.2: batas body RPC ditegakkan di transport — lebih awal dari\n // pipeline, tanpa membaca penuh; `content-length` diperiksa lebih dulu.\n const isRpc = url.pathname.startsWith(\"/_moons/fn/\");\n const rpcLimit = options.bodyLimitBytes ?? DEFAULT_BODY_LIMIT_BYTES;\n if (isRpc) {\n const contentLength = Number(req.headers[\"content-length\"] ?? \"0\");\n if (Number.isFinite(contentLength) && contentLength > rpcLimit) {\n respondText(res, 413, rpcBodyTooLargeText(rpcLimit, contentLength), options.headers);\n res.once(\"finish\", () => req.destroy());\n return;\n }\n }\n\n const request = await toWebRequest(req, {\n trustProxy: options.trustProxy === true,\n ...(options.clientIpHeader === undefined ? {} : { clientIpHeader: options.clientIpHeader }),\n ...(isRpc ? { maxBodyBytes: rpcLimit } : {}),\n });\n // Addendum R: batas waktu eksplisit; 0/undefined = tanpa batas.\n const response = await runHandlerWithTimeout(handler, request, options.requestTimeoutMs);\n await sendNodeResponse(res, response);\n } catch (error) {\n if (error instanceof BodyLimitError) {\n const isRpc = url.pathname.startsWith(\"/_moons/fn/\");\n respondText(\n res,\n 413,\n isRpc ? rpcBodyTooLargeText(error.limit, null) : \"Payload Too Large\",\n options.headers,\n );\n // Sisa body tidak perlu dibaca — putuskan setelah respons terkirim.\n res.once(\"finish\", () => req.destroy());\n return;\n }\n // Addendum R: timeout eksplisit — 504 + log terstruktur.\n if (error instanceof RequestTimeoutError) {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request-timeout\",\n level: \"warn\",\n method: req.method ?? \"GET\",\n path: url.pathname + url.search,\n limitMs: error.limit,\n });\n } else {\n console.warn(`[moons] request timed out after ${error.limit}ms — ${req.method ?? \"GET\"} ${url.pathname}`);\n }\n respondText(res, 504, requestTimeoutText(error.limit), options.headers);\n return;\n }\n // Review G7: abort klien/koneksi putus bukan error server (tanpa stack).\n if (isAbortLike(error)) {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request-aborted\",\n level: \"warn\",\n method: req.method ?? \"GET\",\n path: url.pathname + url.search,\n });\n } else {\n console.warn(`[moons] request aborted by the client — ${req.method ?? \"GET\"} ${url.pathname}`);\n }\n if (!res.headersSent && !res.writableEnded) {\n respondText(res, 499, \"Client Closed Request\", options.headers);\n }\n return;\n }\n console.error(\"[moons] server error:\", error);\n respondText(res, 500, \"Internal Server Error\", options.headers);\n }\n })();\n });\n\n // Addendum B.4: onStart sebelum listen, onReady setelah listen.\n const listenAfterStart = (): void => {\n server.listen(port, () => {\n const address = server.address();\n const boundPort = typeof address === \"object\" && address !== null ? address.port : port;\n console.log(`[moons] server listening on http://localhost:${boundPort}`);\n void options.plugins?.ready();\n });\n };\n if (options.plugins !== undefined) {\n void options.plugins.start().then(listenAfterStart);\n } else {\n listenAfterStart();\n }\n\n if (options.handleSignals !== false) {\n const shutdown = installGracefulShutdown(server, {\n ...(options.shutdownTimeoutMs === undefined ? {} : { timeoutMs: options.shutdownTimeoutMs }),\n ...(options.plugins === undefined\n ? {}\n : { onShutdown: () => options.plugins?.shutdown() }),\n });\n // `once`: sinyal kedua memakai perilaku default (proses langsung berhenti).\n process.once(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n process.once(\"SIGINT\", () => shutdown(\"SIGINT\"));\n }\n\n return server;\n}\n\nfunction appendVary(res: import(\"node:http\").ServerResponse, value: string): void {\n const existing = res.getHeader(\"vary\");\n if (typeof existing === \"string\" && existing.length > 0) {\n if (!existing.toLowerCase().includes(value)) {\n res.setHeader(\"vary\", `${existing}, ${value}`);\n }\n return;\n }\n res.setHeader(\"vary\", value);\n}\n\n/** Respons teks transport — ikut membawa header config + default aman (review G6). */\nfunction respondText(\n res: import(\"node:http\").ServerResponse,\n status: number,\n text: string,\n configured: Record<string, string> | undefined,\n): void {\n res.statusCode = status;\n res.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n applyStaticHeaders(\n { has: (name) => res.hasHeader(name), set: (name, value) => res.setHeader(name, value) },\n \"/\",\n configured,\n );\n res.end(text);\n}\n",
|
|
7
7
|
"import { mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from \"node:fs\";\nimport { dirname, extname } from \"node:path\";\nimport type { PrerenderStorage, PrerenderStorageEntry } from \"@moonsjs/core\";\nimport { resolveStaticFile, staticFileTarget } from \"./node-server\";\n\n/**\n * Addendum I: storage file sistem (default) untuk file prerender/ISR.\n * Read hanya melayani path yang benar-benar ada (manifest-aware);\n * write atomik (tmp + rename) dan membuat direktori bila perlu.\n */\nexport function createFileStorage(clientDir: string): PrerenderStorage {\n return {\n async read(pathname: string): Promise<PrerenderStorageEntry | null> {\n const file = resolveStaticFile(clientDir, pathname);\n if (file === null) {\n return null;\n }\n const stat = statSync(file);\n return { body: readFileSync(file), mtimeMs: stat.mtimeMs };\n },\n async write(pathname: string, body: Uint8Array): Promise<void> {\n const target = staticFileTarget(clientDir, pathname);\n if (target === null) {\n throw new Error(`[moons] isr: invalid path to write: ${pathname}`);\n }\n mkdirSync(dirname(target), { recursive: true });\n const tmp = `${target}.tmp-${process.pid}`;\n writeFileSync(tmp, body);\n renameSync(tmp, target);\n },\n };\n}\n\n/** Ekstensi pathname (untuk `content-type`) tanpa membaca storage. */\nexport function contentTypeForPathname(pathname: string): string {\n const ext = extname(pathname.split(\"?\")[0] ?? \"\").toLowerCase();\n return MIME[ext] ?? MIME[\".html\"] ?? \"text/html; charset=utf-8\";\n}\n\nconst MIME: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".mjs\": \"text/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".txt\": \"text/plain; charset=utf-8\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".png\": \"image/png\",\n \".webp\": \"image/webp\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".xml\": \"application/xml; charset=utf-8\",\n \".csv\": \"text/csv; charset=utf-8\",\n \".md\": \"text/markdown; charset=utf-8\",\n \".pdf\": \"application/pdf\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".zip\": \"application/zip\",\n \".gz\": \"application/gzip\",\n};\n",
|
|
8
8
|
"/**\n * Addendum L.3: logger akses terstruktur — JSON default, redaksi nilai\n * query-param (mis. `?token=…`), dan target tulis injectable (untuk test).\n * Semua field tambahan diteruskan apa adanya; `path` selalu di-redaksi.\n */\nexport interface LogEvent {\n /** Default `info`. */\n level?: \"info\" | \"warn\" | \"error\";\n /** Nama event, mis. `request` atau `isr:regenerated`. */\n msg: string;\n [field: string]: unknown;\n}\n\nexport interface LoggerOptions {\n /** Default `true` (JSON). `false` = teks ringkas. */\n json?: boolean;\n /** Nama query-param yang nilainya diganti `[redacted]`. */\n redact?: readonly string[];\n /** Tujuan tulis; default `console.log`. */\n write?: (line: string) => void;\n}\n\nexport type Logger = (event: LogEvent) => void;\n\n/** Ganti nilai query-param bernama `redact` menjadi `[redacted]`. */\nexport function redactPath(path: string, redact: readonly string[]): string {\n if (redact.length === 0 || !path.includes(\"?\")) {\n return path;\n }\n const index = path.indexOf(\"?\");\n const pathname = path.slice(0, index);\n const params = new URLSearchParams(path.slice(index + 1));\n let changed = false;\n for (const name of redact) {\n if (params.has(name)) {\n params.set(name, \"[redacted]\");\n changed = true;\n }\n }\n return changed ? `${pathname}?${params.toString()}` : path;\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const json = options.json !== false;\n const redact = options.redact ?? [];\n const write = options.write ?? ((line: string): void => console.log(line));\n\n return (event) => {\n const fields: Record<string, unknown> = { level: \"info\", ...event };\n if (typeof fields[\"path\"] === \"string\") {\n fields[\"path\"] = redactPath(fields[\"path\"], redact);\n }\n if (json) {\n write(JSON.stringify({ time: new Date().toISOString(), ...fields }));\n return;\n }\n const parts = [\"[moons]\", String(fields[\"level\"]).toUpperCase(), String(fields[\"msg\"])];\n if (fields[\"path\"] !== undefined) {\n parts.push(String(fields[\"path\"]));\n }\n if (fields[\"status\"] !== undefined) {\n parts.push(String(fields[\"status\"]));\n }\n if (fields[\"durationMs\"] !== undefined) {\n parts.push(`${String(fields[\"durationMs\"])}ms`);\n }\n write(parts.join(\" \"));\n };\n}\n",
|
|
9
9
|
"import type { Server } from \"node:http\";\n\nexport interface ShutdownOptions {\n /** Batas drain sebelum keluar paksa (default 10_000 ms). */\n timeoutMs?: number;\n log?: (message: string) => void;\n /** Injectable untuk test; default `process.exit`. */\n exit?: (code: number) => void;\n /**\n * Dipanggil setelah drain penuh, sebelum exit (Addendum B.4: onShutdown\n * plugin). Berbagi batas waktu dengan drain; error dilaporkan, tidak\n * menggagalkan shutdown.\n */\n onShutdown?: () => void | Promise<void>;\n}\n\n/**\n * Graceful shutdown (PRD §19.5): SIGTERM/SIGINT → stop menerima koneksi baru →\n * drain request berjalan → exit 0. Melewati timeout → keluar paksa exit 1.\n *\n * Handler dipasang `once` oleh pemanggil, sehingga sinyal kedua memakai\n * perilaku default (proses langsung berhenti).\n */\nexport function installGracefulShutdown(\n server: Server,\n options: ShutdownOptions = {},\n): (signal: NodeJS.Signals) => void {\n const timeoutMs = options.timeoutMs ?? 10_000;\n const log = options.log ?? ((message: string) => console.log(message));\n const exit = options.exit ?? ((code: number) => process.exit(code));\n\n let shuttingDown = false;\n\n return (signal: NodeJS.Signals): void => {\n if (shuttingDown) {\n return;\n }\n shuttingDown = true;\n log(`[moons] received ${signal} — no longer accepting connections, draining...`);\n\n const timer = setTimeout(() => {\n log(`[moons] drain exceeded ${timeoutMs}ms — forcing exit`);\n const closeAll = (server as { closeAllConnections?: () => void }).closeAllConnections;\n try {\n closeAll?.call(server);\n } catch {\n // abaikan: keluar paksa tetap jalan\n }\n exit(1);\n }, timeoutMs);\n timer.unref?.();\n\n try {\n (server as { closeIdleConnections?: () => void }).closeIdleConnections?.();\n } catch {\n // abaikan: fallback timeout tetap ada\n }\n\n server.close(async (error?: Error) => {\n if (error !== undefined) {\n clearTimeout(timer);\n log(`[moons] server close failed: ${error.message}`);\n exit(1);\n return;\n }\n if (options.onShutdown !== undefined) {\n // Tetap berbagi batas waktu dengan drain: timer di-ref kembali agar\n // proses tidak keluar sebelum hook selesai.\n (timer as { ref?: () => void }).ref?.();\n try {\n await options.onShutdown();\n } catch (hookError) {\n log(`[moons] onShutdown failed: ${String(hookError)}`);\n }\n }\n clearTimeout(timer);\n log(\"[moons] shutdown complete (full drain)\");\n exit(0);\n });\n };\n}\n",
|
|
10
|
-
"import { readFileSync, statSync } from \"node:fs\";\nimport { extname, join, resolve } from \"node:path\";\nimport { CLIENT_IP_HEADER, DEFAULT_BODY_LIMIT_BYTES, trailingSlashRedirect } from \"@moonsjs/core\";\nimport { contentTypeForPathname } from \"./storage\";\nimport {\n BodyLimitError,\n COMPRESSIBLE_FILE,\n DEFAULT_SECURITY_HEADERS,\n GZIP_MIN_BYTES,\n InvalidRequestError,\n MAX_TRANSPORT_BODY_BYTES,\n MIME_TYPES,\n RequestTimeoutError,\n acceptsGzipHeader,\n applyStaticHeaders,\n forwardedHost,\n forwardedProtocol,\n gzipCached,\n isAbortLike,\n readBodyWithLimit,\n requestTimeoutText,\n resolveClientIpValues,\n resolveStaticFile,\n rpcBodyTooLargeText,\n runHandlerWithTimeout,\n scheduleRevalidation,\n textResponseWithHeaders,\n} from \"./transport\";\nimport { createLogger, type Logger } from \"./logger\";\nimport type { NodeServerOptions } from \"./node-server\";\nimport type { PluginRuntime } from \"./plugins\";\n\n/**\n * Addendum Q (3B): host `Bun.serve` dengan perilaku paritas `node-server`:\n * static + storage/ISR + ETag/gzip + trailingSlash + body limit RPC +\n * header default + access log + drain SIGTERM. Dipilih otomatis oleh\n * `startServer` saat berjalan di Bun (override: `MOONS_SERVER=node|bun`).\n */\n\ninterface BunServerHandle {\n port: number;\n stop(closeActiveConnections?: boolean): Promise<void>;\n}\n\nfunction appendVaryHeader(headers: Headers, value: string): void {\n const existing = headers.get(\"vary\");\n if (existing !== null && existing.length > 0) {\n if (!existing.toLowerCase().includes(value)) {\n headers.set(\"vary\", `${existing}, ${value}`);\n }\n return;\n }\n headers.set(\"vary\", value);\n}\n\n/** J.7: response handler tanpa header default aman — mutasi langsung bila mungkin. */\nfunction withDefaultSecurityHeaders(response: Response): Response {\n let missing = false;\n for (const name of Object.keys(DEFAULT_SECURITY_HEADERS)) {\n if (!response.headers.has(name)) {\n missing = true;\n break;\n }\n }\n if (!missing) {\n return response;\n }\n try {\n for (const [name, value] of Object.entries(DEFAULT_SECURITY_HEADERS)) {\n if (!response.headers.has(name)) {\n response.headers.set(name, value);\n }\n }\n return response;\n } catch {\n // Header immutable (mis. dari fetch) → bungkus ulang.\n const headers = new Headers(response.headers);\n for (const [name, value] of Object.entries(DEFAULT_SECURITY_HEADERS)) {\n if (!headers.has(name)) {\n headers.set(name, value);\n }\n }\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n}\n\n/** J.1: URL dari Request Bun, mengikuti `x-forwarded-*` bila trustProxy aktif. */\nfunction resolveBunUrl(request: Request, trustProxy: boolean): URL {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch {\n throw new InvalidRequestError(`invalid request URL: ${request.url}`);\n }\n if (!trustProxy) {\n return url;\n }\n const proto = forwardedProtocol(request.headers.get(\"x-forwarded-proto\") ?? undefined);\n const host = forwardedHost(request.headers.get(\"x-forwarded-host\") ?? undefined);\n if (proto === null && host === null) {\n return url;\n }\n // Bangun URL baru (bukan mutasi `.host`): setter `host` mempertahankan port\n // lama, sehingga `internal:3000` + `x-forwarded-host: app.example.com`\n // menghasilkan origin `https://app.example.com:3000` — origin RPC meleset.\n const effectiveProto = proto ?? (url.protocol === \"https:\" ? \"https\" : \"http\");\n const effectiveHost = host ?? url.host;\n try {\n return new URL(`${effectiveProto}://${effectiveHost}${url.pathname}${url.search}${url.hash}`);\n } catch {\n throw new InvalidRequestError(`invalid forwarded host: ${JSON.stringify(effectiveHost)}`);\n }\n}\n\n/** Request Web dengan body terbatas + `x-moons-client-ip` tepercaya (J.1/J.2). */\nasync function toBoundedRequest(\n request: Request,\n url: URL,\n clientIp: string | null,\n maxBodyBytes: number,\n): Promise<Request> {\n const headers = new Headers(request.headers);\n headers.delete(\"content-length\");\n if (clientIp !== null) {\n headers.set(CLIENT_IP_HEADER, clientIp);\n }\n if (request.method === \"GET\" || request.method === \"HEAD\") {\n return new Request(url, { method: request.method, headers });\n }\n const body = await readBodyWithLimit(request.body, maxBodyBytes);\n return new Request(url, { method: request.method, headers, body: body as unknown as BodyInit });\n}\n\nfunction installBunShutdown(\n server: BunServerHandle,\n options: { timeoutMs?: number; plugins?: PluginRuntime | undefined },\n): (signal: string) => void {\n const timeoutMs = options.timeoutMs ?? 10_000;\n let shuttingDown = false;\n return (signal: string): void => {\n if (shuttingDown) {\n return;\n }\n shuttingDown = true;\n console.log(`[moons] received ${signal} — no longer accepting connections, draining...`);\n const timer = setTimeout(() => {\n console.log(`[moons] drain exceeded ${timeoutMs}ms — forcing exit`);\n void server.stop(true).catch(() => {});\n process.exit(1);\n }, timeoutMs);\n (timer as { unref?: () => void }).unref?.();\n void (async () => {\n try {\n await server.stop(false);\n } catch (error) {\n clearTimeout(timer);\n console.log(\n `[moons] server close failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n process.exit(1);\n return;\n }\n if (options.plugins !== undefined) {\n // Berbagi batas waktu dengan drain: timer di-ref kembali.\n (timer as { ref?: () => void }).ref?.();\n try {\n await options.plugins.shutdown();\n } catch (error) {\n console.log(`[moons] onShutdown failed: ${String(error)}`);\n }\n }\n clearTimeout(timer);\n console.log(\"[moons] shutdown complete (full drain)\");\n process.exit(0);\n })();\n };\n}\n\n/**\n * Serve produksi dengan `Bun.serve` (Addendum Q). API yang sama dengan\n * `startNodeServer`; hanya tersedia di runtime Bun.\n */\nexport function startBunServer(\n handler: (request: Request) => Promise<Response>,\n options: NodeServerOptions = {},\n): BunServerHandle {\n if (typeof Bun === \"undefined\") {\n throw new Error(\"[moons] startBunServer requires the Bun runtime\");\n }\n const clientDir = resolve(options.clientDir ?? join(process.cwd(), \"dist/client\"));\n const port = options.port ?? Number(process.env[\"PORT\"] ?? 3000);\n const trustProxy = options.trustProxy === true;\n const requestTimeoutMs = options.requestTimeoutMs;\n const clientIpHeader = options.clientIpHeader ?? \"x-forwarded-for\";\n // Addendum R: idleTimeout Bun diselaraskan dengan batas kita (+5 dtk grace)\n // supaya 504 dari framework yang menang, bukan koneksi diputus diam-diam.\n const idleTimeout =\n requestTimeoutMs === undefined || requestTimeoutMs <= 0\n ? 0\n : Math.ceil(requestTimeoutMs / 1000) + 5;\n const accessLogger: Logger | null =\n options.logging?.accessLog === true\n ? createLogger({\n json: options.logging.json !== false,\n redact: options.logging.redact ?? [],\n })\n : null;\n\n const serveStatic = async (\n request: Request,\n url: URL,\n ): Promise<Response | null> => {\n if (options.storage !== undefined) {\n // Addendum R (review G2): storage error = miss — aset & halaman non-ISR\n // harus tetap jalan saat store bersama outage.\n let entry: Awaited<ReturnType<NonNullable<typeof options.storage>[\"read\"]>> | null = null;\n try {\n entry = await options.storage.read(url.pathname);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (accessLogger !== null) {\n accessLogger({ msg: \"isr:storage-read-failed\", level: \"warn\", path: url.pathname, error: message });\n } else {\n console.warn(`[moons] isr storage read failed (${url.pathname}): ${message} — falling back to dist/client`);\n }\n }\n if (entry !== null) {\n scheduleRevalidation({\n pathname: url.pathname,\n mtimeMs: entry.mtimeMs,\n storage: options.storage,\n handler,\n options,\n clientDir,\n logger: accessLogger,\n });\n const headers = new Headers();\n headers.set(\"content-type\", contentTypeForPathname(url.pathname));\n applyStaticHeaders(headers, url.pathname, options.headers);\n return new Response(\n request.method === \"HEAD\" ? null : (entry.body as unknown as BodyInit),\n { status: 200, headers },\n );\n }\n // L.2 (temuan F1): storage MISS → fallback `dist/client`; storage tetap menang.\n }\n const staticFile = resolveStaticFile(clientDir, url.pathname);\n if (staticFile === null) {\n return null;\n }\n const stat = statSync(staticFile);\n scheduleRevalidation({\n pathname: url.pathname,\n mtimeMs: stat.mtimeMs,\n file: staticFile,\n ...(options.storage === undefined ? {} : { storage: options.storage }),\n handler,\n options,\n clientDir,\n logger: accessLogger,\n });\n const headers = new Headers();\n headers.set(\n \"content-type\",\n MIME_TYPES[extname(staticFile).toLowerCase()] ?? \"application/octet-stream\",\n );\n applyStaticHeaders(headers, url.pathname, options.headers);\n\n // K.5: ETag + 304.\n const etag = `W/\"${stat.size}-${Math.floor(stat.mtimeMs)}\"`;\n headers.set(\"etag\", etag);\n const ifNoneMatch = request.headers.get(\"if-none-match\");\n if (ifNoneMatch !== null && ifNoneMatch.split(\",\").some((value) => value.trim() === etag)) {\n return new Response(null, { status: 304, headers });\n }\n\n // K.5: gzip untuk aset teks (cache per mtime).\n let payload: Uint8Array | null =\n request.method === \"HEAD\" ? null : readFileSync(staticFile);\n if (\n payload !== null &&\n COMPRESSIBLE_FILE.test(staticFile) &&\n payload.byteLength >= GZIP_MIN_BYTES &&\n acceptsGzipHeader(request.headers.get(\"accept-encoding\"))\n ) {\n payload = gzipCached(staticFile, stat.mtimeMs, Buffer.from(payload));\n headers.set(\"content-encoding\", \"gzip\");\n appendVaryHeader(headers, \"accept-encoding\");\n }\n return new Response(payload as unknown as BodyInit | null, { status: 200, headers });\n };\n\n const server = Bun.serve({\n port,\n idleTimeout,\n fetch: async (request, bunServer) => {\n const requestStartedAt = performance.now();\n let url: URL;\n try {\n url = resolveBunUrl(request, trustProxy);\n } catch (error) {\n if (error instanceof InvalidRequestError) {\n console.warn(`[moons] ${error.message} — 400`);\n return textResponseWithHeaders(400, \"Bad Request\", options.headers);\n }\n throw error;\n }\n let clientIp: string | null = null;\n const finish = (response: Response): Response => {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request\",\n method: request.method,\n path: url.pathname + url.search,\n status: response.status,\n durationMs: Math.round(performance.now() - requestStartedAt),\n ...(clientIp === null ? {} : { ip: clientIp }),\n });\n }\n return response;\n };\n\n try {\n // M: kanonikalisasi trailing slash di transport (termasuk path prerender).\n if (options.trailingSlash !== undefined) {\n const canonical = trailingSlashRedirect(url.pathname, options.trailingSlash);\n if (canonical !== null) {\n url.pathname = canonical;\n return new Response(null, { status: 308, headers: { location: url.toString() } });\n }\n }\n\n if (request.method === \"GET\" || request.method === \"HEAD\") {\n const staticResponse = await serveStatic(request, url);\n if (staticResponse !== null) {\n return finish(staticResponse);\n }\n }\n\n // J.2: batas body RPC di transport — content-length diperiksa lebih dulu.\n const isRpc = url.pathname.startsWith(\"/_moons/fn/\");\n const rpcLimit = options.bodyLimitBytes ?? DEFAULT_BODY_LIMIT_BYTES;\n if (isRpc) {\n const contentLength = Number(request.headers.get(\"content-length\") ?? \"0\");\n if (Number.isFinite(contentLength) && contentLength > rpcLimit) {\n return finish(\n textResponseWithHeaders(413, rpcBodyTooLargeText(rpcLimit, contentLength), options.headers),\n );\n }\n }\n\n const remoteAddress = bunServer.requestIP(request)?.address ?? null;\n clientIp = resolveClientIpValues(\n request.headers.get(clientIpHeader) ?? undefined,\n remoteAddress,\n trustProxy,\n );\n // Fast path: GET/HEAD tanpa rewrite URL & tanpa IP tepercaya → pakai\n // Request asli (menghindari rekonstruksi + salinan header per request).\n const needsRewrite = clientIp !== null || url.toString() !== request.url;\n const webRequest =\n (request.method === \"GET\" || request.method === \"HEAD\") && !needsRewrite\n ? request\n : await toBoundedRequest(\n request,\n url,\n clientIp,\n isRpc ? rpcLimit : MAX_TRANSPORT_BODY_BYTES,\n );\n // Addendum R: batas waktu eksplisit; 0/undefined = tanpa batas.\n const response = await runHandlerWithTimeout(handler, webRequest, requestTimeoutMs);\n return finish(withDefaultSecurityHeaders(response));\n } catch (error) {\n if (error instanceof BodyLimitError) {\n const isRpc = url.pathname.startsWith(\"/_moons/fn/\");\n return finish(\n textResponseWithHeaders(\n 413,\n isRpc ? rpcBodyTooLargeText(error.limit, null) : \"Payload Too Large\",\n options.headers,\n ),\n );\n }\n // Addendum R: timeout eksplisit — 504 + log terstruktur.\n if (error instanceof RequestTimeoutError) {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request-timeout\",\n level: \"warn\",\n method: request.method,\n path: url.pathname + url.search,\n limitMs: error.limit,\n });\n } else {\n console.warn(`[moons] request timed out after ${error.limit}ms — ${request.method} ${url.pathname}`);\n }\n return finish(textResponseWithHeaders(504, requestTimeoutText(error.limit), options.headers));\n }\n // Review G7: abort klien/koneksi putus bukan error server (tanpa stack).\n if (isAbortLike(error)) {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request-aborted\",\n level: \"warn\",\n method: request.method,\n path: url.pathname + url.search,\n });\n } else {\n console.warn(`[moons] request aborted by the client — ${request.method} ${url.pathname}`);\n }\n return new Response(null, { status: 499 });\n }\n console.error(\"[moons] server error:\", error);\n return finish(textResponseWithHeaders(500, \"Internal Server Error\", options.headers));\n }\n },\n });\n\n // B.4: onStart sebelum log siap, onReady setelah server menerima koneksi.\n const listenAfterStart = (): void => {\n console.log(`[moons] server listening on http://localhost:${server.port}`);\n void options.plugins?.ready();\n };\n if (options.plugins !== undefined) {\n void options.plugins.start().then(listenAfterStart);\n } else {\n listenAfterStart();\n }\n\n if (options.handleSignals !== false) {\n const shutdown = installBunShutdown(server as unknown as BunServerHandle, {\n ...(options.shutdownTimeoutMs === undefined ? {} : { timeoutMs: options.shutdownTimeoutMs }),\n plugins: options.plugins,\n });\n process.once(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n process.once(\"SIGINT\", () => shutdown(\"SIGINT\"));\n }\n\n return server as unknown as BunServerHandle;\n}\n",
|
|
10
|
+
"import { readFileSync, statSync } from \"node:fs\";\nimport { extname, join, resolve } from \"node:path\";\nimport { CLIENT_IP_HEADER, DEFAULT_BODY_LIMIT_BYTES, trailingSlashRedirect } from \"@moonsjs/core\";\nimport { contentTypeForPathname } from \"./storage\";\nimport {\n BodyLimitError,\n COMPRESSIBLE_FILE,\n DEFAULT_SECURITY_HEADERS,\n GZIP_MIN_BYTES,\n InvalidRequestError,\n MAX_TRANSPORT_BODY_BYTES,\n MIME_TYPES,\n RequestTimeoutError,\n acceptsGzipHeader,\n applyStaticHeaders,\n forwardedHost,\n forwardedProtocol,\n gzipCached,\n isAbortLike,\n parseRangeHeader,\n readBodyWithLimit,\n requestTimeoutText,\n resolveClientIpValues,\n resolveStaticFile,\n rpcBodyTooLargeText,\n runHandlerWithTimeout,\n scheduleRevalidation,\n textResponseWithHeaders,\n} from \"./transport\";\nimport { createLogger, type Logger } from \"./logger\";\nimport type { NodeServerOptions } from \"./node-server\";\nimport type { PluginRuntime } from \"./plugins\";\n\n/**\n * Addendum Q (3B): host `Bun.serve` dengan perilaku paritas `node-server`:\n * static + storage/ISR + ETag/gzip + trailingSlash + body limit RPC +\n * header default + access log + drain SIGTERM. Dipilih otomatis oleh\n * `startServer` saat berjalan di Bun (override: `MOONS_SERVER=node|bun`).\n */\n\ninterface BunServerHandle {\n port: number;\n stop(closeActiveConnections?: boolean): Promise<void>;\n}\n\nfunction appendVaryHeader(headers: Headers, value: string): void {\n const existing = headers.get(\"vary\");\n if (existing !== null && existing.length > 0) {\n if (!existing.toLowerCase().includes(value)) {\n headers.set(\"vary\", `${existing}, ${value}`);\n }\n return;\n }\n headers.set(\"vary\", value);\n}\n\n/** J.7: response handler tanpa header default aman — mutasi langsung bila mungkin. */\nfunction withDefaultSecurityHeaders(response: Response): Response {\n let missing = false;\n for (const name of Object.keys(DEFAULT_SECURITY_HEADERS)) {\n if (!response.headers.has(name)) {\n missing = true;\n break;\n }\n }\n if (!missing) {\n return response;\n }\n try {\n for (const [name, value] of Object.entries(DEFAULT_SECURITY_HEADERS)) {\n if (!response.headers.has(name)) {\n response.headers.set(name, value);\n }\n }\n return response;\n } catch {\n // Header immutable (mis. dari fetch) → bungkus ulang.\n const headers = new Headers(response.headers);\n for (const [name, value] of Object.entries(DEFAULT_SECURITY_HEADERS)) {\n if (!headers.has(name)) {\n headers.set(name, value);\n }\n }\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n}\n\n/** J.1: URL dari Request Bun, mengikuti `x-forwarded-*` bila trustProxy aktif. */\nfunction resolveBunUrl(request: Request, trustProxy: boolean): URL {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch {\n throw new InvalidRequestError(`invalid request URL: ${request.url}`);\n }\n if (!trustProxy) {\n return url;\n }\n const proto = forwardedProtocol(request.headers.get(\"x-forwarded-proto\") ?? undefined);\n const host = forwardedHost(request.headers.get(\"x-forwarded-host\") ?? undefined);\n if (proto === null && host === null) {\n return url;\n }\n // Bangun URL baru (bukan mutasi `.host`): setter `host` mempertahankan port\n // lama, sehingga `internal:3000` + `x-forwarded-host: app.example.com`\n // menghasilkan origin `https://app.example.com:3000` — origin RPC meleset.\n const effectiveProto = proto ?? (url.protocol === \"https:\" ? \"https\" : \"http\");\n const effectiveHost = host ?? url.host;\n try {\n return new URL(`${effectiveProto}://${effectiveHost}${url.pathname}${url.search}${url.hash}`);\n } catch {\n throw new InvalidRequestError(`invalid forwarded host: ${JSON.stringify(effectiveHost)}`);\n }\n}\n\n/** Request Web dengan body terbatas + `x-moons-client-ip` tepercaya (J.1/J.2). */\nasync function toBoundedRequest(\n request: Request,\n url: URL,\n clientIp: string | null,\n maxBodyBytes: number,\n): Promise<Request> {\n const headers = new Headers(request.headers);\n headers.delete(\"content-length\");\n if (clientIp !== null) {\n headers.set(CLIENT_IP_HEADER, clientIp);\n }\n if (request.method === \"GET\" || request.method === \"HEAD\") {\n return new Request(url, { method: request.method, headers });\n }\n const body = await readBodyWithLimit(request.body, maxBodyBytes);\n return new Request(url, { method: request.method, headers, body: body as unknown as BodyInit });\n}\n\nfunction installBunShutdown(\n server: BunServerHandle,\n options: { timeoutMs?: number; plugins?: PluginRuntime | undefined },\n): (signal: string) => void {\n const timeoutMs = options.timeoutMs ?? 10_000;\n let shuttingDown = false;\n return (signal: string): void => {\n if (shuttingDown) {\n return;\n }\n shuttingDown = true;\n console.log(`[moons] received ${signal} — no longer accepting connections, draining...`);\n const timer = setTimeout(() => {\n console.log(`[moons] drain exceeded ${timeoutMs}ms — forcing exit`);\n void server.stop(true).catch(() => {});\n process.exit(1);\n }, timeoutMs);\n (timer as { unref?: () => void }).unref?.();\n void (async () => {\n try {\n await server.stop(false);\n } catch (error) {\n clearTimeout(timer);\n console.log(\n `[moons] server close failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n process.exit(1);\n return;\n }\n if (options.plugins !== undefined) {\n // Berbagi batas waktu dengan drain: timer di-ref kembali.\n (timer as { ref?: () => void }).ref?.();\n try {\n await options.plugins.shutdown();\n } catch (error) {\n console.log(`[moons] onShutdown failed: ${String(error)}`);\n }\n }\n clearTimeout(timer);\n console.log(\"[moons] shutdown complete (full drain)\");\n process.exit(0);\n })();\n };\n}\n\n/**\n * Serve produksi dengan `Bun.serve` (Addendum Q). API yang sama dengan\n * `startNodeServer`; hanya tersedia di runtime Bun.\n */\nexport function startBunServer(\n handler: (request: Request) => Promise<Response>,\n options: NodeServerOptions = {},\n): BunServerHandle {\n if (typeof Bun === \"undefined\") {\n throw new Error(\"[moons] startBunServer requires the Bun runtime\");\n }\n const clientDir = resolve(options.clientDir ?? join(process.cwd(), \"dist/client\"));\n const port = options.port ?? Number(process.env[\"PORT\"] ?? 3000);\n const trustProxy = options.trustProxy === true;\n const requestTimeoutMs = options.requestTimeoutMs;\n const clientIpHeader = options.clientIpHeader ?? \"x-forwarded-for\";\n // Addendum R: idleTimeout Bun diselaraskan dengan batas kita (+5 dtk grace)\n // supaya 504 dari framework yang menang, bukan koneksi diputus diam-diam.\n const idleTimeout =\n requestTimeoutMs === undefined || requestTimeoutMs <= 0\n ? 0\n : Math.ceil(requestTimeoutMs / 1000) + 5;\n const accessLogger: Logger | null =\n options.logging?.accessLog === true\n ? createLogger({\n json: options.logging.json !== false,\n redact: options.logging.redact ?? [],\n })\n : null;\n\n const serveStatic = async (\n request: Request,\n url: URL,\n ): Promise<Response | null> => {\n if (options.storage !== undefined) {\n // Addendum R (review G2): storage error = miss — aset & halaman non-ISR\n // harus tetap jalan saat store bersama outage.\n let entry: Awaited<ReturnType<NonNullable<typeof options.storage>[\"read\"]>> | null = null;\n try {\n entry = await options.storage.read(url.pathname);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (accessLogger !== null) {\n accessLogger({ msg: \"isr:storage-read-failed\", level: \"warn\", path: url.pathname, error: message });\n } else {\n console.warn(`[moons] isr storage read failed (${url.pathname}): ${message} — falling back to dist/client`);\n }\n }\n if (entry !== null) {\n scheduleRevalidation({\n pathname: url.pathname,\n mtimeMs: entry.mtimeMs,\n storage: options.storage,\n handler,\n options,\n clientDir,\n logger: accessLogger,\n });\n const headers = new Headers();\n headers.set(\"content-type\", contentTypeForPathname(url.pathname));\n applyStaticHeaders(headers, url.pathname, options.headers);\n return new Response(\n request.method === \"HEAD\" ? null : (entry.body as unknown as BodyInit),\n { status: 200, headers },\n );\n }\n // L.2 (temuan F1): storage MISS → fallback `dist/client`; storage tetap menang.\n }\n const staticFile = resolveStaticFile(clientDir, url.pathname);\n if (staticFile === null) {\n return null;\n }\n const stat = statSync(staticFile);\n scheduleRevalidation({\n pathname: url.pathname,\n mtimeMs: stat.mtimeMs,\n file: staticFile,\n ...(options.storage === undefined ? {} : { storage: options.storage }),\n handler,\n options,\n clientDir,\n logger: accessLogger,\n });\n const headers = new Headers();\n headers.set(\n \"content-type\",\n MIME_TYPES[extname(staticFile).toLowerCase()] ?? \"application/octet-stream\",\n );\n applyStaticHeaders(headers, url.pathname, options.headers);\n\n // K.5: ETag + 304.\n const etag = `W/\"${stat.size}-${Math.floor(stat.mtimeMs)}\"`;\n headers.set(\"etag\", etag);\n const ifNoneMatch = request.headers.get(\"if-none-match\");\n if (ifNoneMatch !== null && ifNoneMatch.split(\",\").some((value) => value.trim() === etag)) {\n return new Response(null, { status: 304, headers });\n }\n\n // Addendum T (G4): Range single-range untuk file statik (media).\n headers.set(\"accept-ranges\", \"bytes\");\n const range =\n request.method === \"GET\" ? parseRangeHeader(request.headers.get(\"range\"), stat.size) : null;\n if (range !== null) {\n if (range.kind === \"unsatisfiable\") {\n headers.set(\"content-range\", `bytes */${stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n const full = readFileSync(staticFile);\n const slice = full.subarray(range.start, range.end + 1);\n headers.set(\"content-range\", `bytes ${range.start}-${range.end}/${stat.size}`);\n return new Response(slice as unknown as BodyInit, { status: 206, headers });\n }\n\n // K.5: gzip untuk aset teks (cache per mtime).\n let payload: Uint8Array | null =\n request.method === \"HEAD\" ? null : readFileSync(staticFile);\n if (\n payload !== null &&\n COMPRESSIBLE_FILE.test(staticFile) &&\n payload.byteLength >= GZIP_MIN_BYTES &&\n acceptsGzipHeader(request.headers.get(\"accept-encoding\"))\n ) {\n payload = gzipCached(staticFile, stat.mtimeMs, Buffer.from(payload));\n headers.set(\"content-encoding\", \"gzip\");\n appendVaryHeader(headers, \"accept-encoding\");\n }\n return new Response(payload as unknown as BodyInit | null, { status: 200, headers });\n };\n\n const server = Bun.serve({\n port,\n idleTimeout,\n fetch: async (request, bunServer) => {\n const requestStartedAt = performance.now();\n let url: URL;\n try {\n url = resolveBunUrl(request, trustProxy);\n } catch (error) {\n if (error instanceof InvalidRequestError) {\n console.warn(`[moons] ${error.message} — 400`);\n return textResponseWithHeaders(400, \"Bad Request\", options.headers);\n }\n throw error;\n }\n let clientIp: string | null = null;\n const finish = (response: Response): Response => {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request\",\n method: request.method,\n path: url.pathname + url.search,\n status: response.status,\n durationMs: Math.round(performance.now() - requestStartedAt),\n ...(clientIp === null ? {} : { ip: clientIp }),\n });\n }\n return response;\n };\n\n try {\n // M: kanonikalisasi trailing slash di transport (termasuk path prerender).\n if (options.trailingSlash !== undefined) {\n const canonical = trailingSlashRedirect(url.pathname, options.trailingSlash);\n if (canonical !== null) {\n url.pathname = canonical;\n return new Response(null, { status: 308, headers: { location: url.toString() } });\n }\n }\n\n if (request.method === \"GET\" || request.method === \"HEAD\") {\n const staticResponse = await serveStatic(request, url);\n if (staticResponse !== null) {\n return finish(staticResponse);\n }\n }\n\n // J.2: batas body RPC di transport — content-length diperiksa lebih dulu.\n const isRpc = url.pathname.startsWith(\"/_moons/fn/\");\n const rpcLimit = options.bodyLimitBytes ?? DEFAULT_BODY_LIMIT_BYTES;\n if (isRpc) {\n const contentLength = Number(request.headers.get(\"content-length\") ?? \"0\");\n if (Number.isFinite(contentLength) && contentLength > rpcLimit) {\n return finish(\n textResponseWithHeaders(413, rpcBodyTooLargeText(rpcLimit, contentLength), options.headers),\n );\n }\n }\n\n const remoteAddress = bunServer.requestIP(request)?.address ?? null;\n clientIp = resolveClientIpValues(\n request.headers.get(clientIpHeader) ?? undefined,\n remoteAddress,\n trustProxy,\n );\n // Fast path: GET/HEAD tanpa rewrite URL & tanpa IP tepercaya → pakai\n // Request asli (menghindari rekonstruksi + salinan header per request).\n const needsRewrite = clientIp !== null || url.toString() !== request.url;\n const webRequest =\n (request.method === \"GET\" || request.method === \"HEAD\") && !needsRewrite\n ? request\n : await toBoundedRequest(\n request,\n url,\n clientIp,\n isRpc ? rpcLimit : MAX_TRANSPORT_BODY_BYTES,\n );\n // Addendum R: batas waktu eksplisit; 0/undefined = tanpa batas.\n const response = await runHandlerWithTimeout(handler, webRequest, requestTimeoutMs);\n return finish(withDefaultSecurityHeaders(response));\n } catch (error) {\n if (error instanceof BodyLimitError) {\n const isRpc = url.pathname.startsWith(\"/_moons/fn/\");\n return finish(\n textResponseWithHeaders(\n 413,\n isRpc ? rpcBodyTooLargeText(error.limit, null) : \"Payload Too Large\",\n options.headers,\n ),\n );\n }\n // Addendum R: timeout eksplisit — 504 + log terstruktur.\n if (error instanceof RequestTimeoutError) {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request-timeout\",\n level: \"warn\",\n method: request.method,\n path: url.pathname + url.search,\n limitMs: error.limit,\n });\n } else {\n console.warn(`[moons] request timed out after ${error.limit}ms — ${request.method} ${url.pathname}`);\n }\n return finish(textResponseWithHeaders(504, requestTimeoutText(error.limit), options.headers));\n }\n // Review G7: abort klien/koneksi putus bukan error server (tanpa stack).\n if (isAbortLike(error)) {\n if (accessLogger !== null) {\n accessLogger({\n msg: \"request-aborted\",\n level: \"warn\",\n method: request.method,\n path: url.pathname + url.search,\n });\n } else {\n console.warn(`[moons] request aborted by the client — ${request.method} ${url.pathname}`);\n }\n return new Response(null, { status: 499 });\n }\n console.error(\"[moons] server error:\", error);\n return finish(textResponseWithHeaders(500, \"Internal Server Error\", options.headers));\n }\n },\n });\n\n // B.4: onStart sebelum log siap, onReady setelah server menerima koneksi.\n const listenAfterStart = (): void => {\n console.log(`[moons] server listening on http://localhost:${server.port}`);\n void options.plugins?.ready();\n };\n if (options.plugins !== undefined) {\n void options.plugins.start().then(listenAfterStart);\n } else {\n listenAfterStart();\n }\n\n if (options.handleSignals !== false) {\n const shutdown = installBunShutdown(server as unknown as BunServerHandle, {\n ...(options.shutdownTimeoutMs === undefined ? {} : { timeoutMs: options.shutdownTimeoutMs }),\n plugins: options.plugins,\n });\n process.once(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n process.once(\"SIGINT\", () => shutdown(\"SIGINT\"));\n }\n\n return server as unknown as BunServerHandle;\n}\n",
|
|
11
11
|
"import { startBunServer } from \"./bun-server\";\nimport { startNodeServer, type NodeServerOptions } from \"./node-server\";\n\n/**\n * Addendum Q (3B): pemilih transport produksi.\n * Default: Bun.serve saat berjalan di Bun, node:http di Node.\n * Override eksplisit: `MOONS_SERVER=bun|node`.\n */\nexport function startServer(\n handler: (request: Request) => Promise<Response>,\n options: NodeServerOptions = {},\n): ReturnType<typeof startNodeServer> | ReturnType<typeof startBunServer> {\n const forced = process.env[\"MOONS_SERVER\"];\n const isBun = typeof Bun !== \"undefined\";\n\n if (forced === \"node\") {\n return startNodeServer(handler, options);\n }\n if (forced === \"bun\" && !isBun) {\n console.warn(\"[moons] MOONS_SERVER=bun requires the Bun runtime — falling back to node\");\n return startNodeServer(handler, options);\n }\n if (forced !== undefined && forced !== \"bun\" && forced !== \"node\") {\n console.warn(`[moons] unknown MOONS_SERVER=\"${forced}\" — using ${isBun ? \"bun\" : \"node\"}`);\n }\n return isBun ? startBunServer(handler, options) : startNodeServer(handler, options);\n}\n",
|
|
12
12
|
"import { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { MoonsConfig, RouteDefinition, RouteModule } from \"@moonsjs/core\";\nimport type { renderToMarkup as RenderToMarkupFn } from \"@moonsjs/react/ssr\";\nimport { createRequestHandler, type RequestHandlerOptions } from \"./handler\";\nimport { DEFAULT_TEMPLATE, injectShell, type Shell } from \"./shell\";\n\ntype RenderMarkup = typeof RenderToMarkupFn;\n\n/**\n * Addendum O: resolve the SSR renderer from the app's own `node_modules` first.\n * Bun resolves registry packages through its install cache; peer imports\n * (`react-dom/server`) are not reachable from there, but they are from the app.\n */\nasync function loadRenderer(candidates: ReadonlyArray<string>): Promise<RenderMarkup> {\n for (const root of candidates) {\n // Prefer `src/ssr.ts`: under Bun the app's own modules resolve\n // `@moonsjs/react` through the \"bun\" condition (source), so the renderer\n // must come from the same module instance.\n for (const relative of [\n \"node_modules/@moonsjs/react/src/ssr.ts\",\n \"node_modules/@moonsjs/react/dist/ssr.js\",\n \"node_modules/@moonsjs/react/dist/ssr.mjs\",\n ]) {\n const file = join(root, relative);\n if (!existsSync(file)) {\n continue;\n }\n const mod = (await import(pathToFileURL(file).href)) as {\n renderToMarkup?: RenderMarkup;\n };\n if (typeof mod.renderToMarkup === \"function\") {\n return mod.renderToMarkup;\n }\n }\n }\n const fallback = (await import(\"@moonsjs/react/ssr\")) as { renderToMarkup: RenderMarkup };\n return fallback.renderToMarkup;\n}\n\nexport interface TestServerOptions {\n routes: RouteDefinition[];\n config: MoonsConfig;\n routesDir: string;\n loadRoute: Record<string, () => Promise<RouteModule>>;\n /** Endpoint `src/api` (Addendum O) — hasil scan app. */\n apiRoutes?: RequestHandlerOptions[\"apiRoutes\"];\n loadApi?: RequestHandlerOptions[\"loadApi\"];\n apiMiddlewares?: RequestHandlerOptions[\"apiMiddlewares\"];\n loadApiMiddleware?: RequestHandlerOptions[\"loadApiMiddleware\"];\n /** Default: shell in-memory dari `DEFAULT_TEMPLATE` (tanpa file). */\n shell?: Shell;\n}\n\nexport interface TestServer {\n handler: (request: Request) => Promise<Response>;\n /** Dispatch request langsung ke handler — tanpa port/jaringan (§19.5). */\n fetch(input: string, init?: RequestInit): Promise<Response>;\n}\n\n/**\n * Utility test in-process (PRD §19.5): jalankan handler tanpa listen port.\n * Dipakai test aplikasi user maupun test internal framework.\n */\nexport function createTestServer(\n options: TestServerOptions,\n baseUrl = \"http://localhost\",\n): TestServer {\n const shell: Shell =\n options.shell ??\n ((markup, payload, _url, meta) => injectShell(DEFAULT_TEMPLATE, markup, payload, meta));\n\n const handler = createRequestHandler({\n routes: options.routes,\n config: options.config,\n routesDir: options.routesDir,\n loadRoute: options.loadRoute,\n ...(options.apiRoutes === undefined ? {} : { apiRoutes: options.apiRoutes }),\n ...(options.loadApi === undefined ? {} : { loadApi: options.loadApi }),\n ...(options.apiMiddlewares === undefined ? {} : { apiMiddlewares: options.apiMiddlewares }),\n ...(options.loadApiMiddleware === undefined\n ? {}\n : { loadApiMiddleware: options.loadApiMiddleware }),\n renderer: () =>\n loadRenderer([process.cwd(), resolve(options.routesDir, \"..\", \"..\")]),\n shell,\n });\n\n return {\n handler,\n fetch: (input: string, init?: RequestInit) =>\n handler(new Request(new URL(input, baseUrl), init)),\n };\n}\n",
|
|
13
13
|
"import { MOONS_VERSION, type App, type Middleware, type MoonsConfig, type RouteDefinition } from \"@moonsjs/core\";\n\n/**\n * Eksekusi lifecycle plugin (PRD §14.4 / Addendum B.4).\n * Urutan: registrasi (addRoute per route → addMiddleware per middleware →\n * extendContext(register)) → onStart → ready/onReady → shutdown/onShutdown.\n */\nexport interface PluginRuntime {\n readonly app: App;\n /** Registrasi + `onStart` (sebelum server siap). */\n start(): Promise<void>;\n /** Tandai `app.ready = true` lalu panggil `onReady` (server siap). */\n ready(): Promise<void>;\n /** Panggil `onShutdown` (selama drain; error dilaporkan, tidak menggagalkan). */\n shutdown(): Promise<void>;\n /** Terapkan extender `extendContext` ke ctx request (dipanggil handler). */\n applyExtensions(ctx: unknown): void;\n}\n\nexport interface PluginRuntimeOptions {\n config: MoonsConfig;\n routes: RouteDefinition[];\n /** Rantai middleware final (config.middleware). */\n middlewares: Middleware[];\n log?: (message: string) => void;\n}\n\nexport function createPluginRuntime(options: PluginRuntimeOptions): PluginRuntime {\n const log = options.log ?? ((message: string) => console.warn(message));\n const plugins = options.config.plugins ?? [];\n const state = { ready: false, version: MOONS_VERSION };\n const app = state as App;\n const extensions: Array<(ctx: unknown) => unknown> = [];\n const register = (fn: (ctx: unknown) => unknown): void => {\n extensions.push(fn);\n };\n\n // Fase registrasi (sinkron): addRoute → addMiddleware → extendContext.\n for (const plugin of plugins) {\n for (const route of options.routes) {\n // Objek beku: hook bersifat observasi di v1 (lihat docs/decisions/0022).\n const frozen = Object.freeze({\n ...route,\n params: [...route.params],\n }) as RouteDefinition;\n plugin.addRoute?.(frozen);\n }\n for (const middleware of options.middlewares) {\n plugin.addMiddleware?.(middleware);\n }\n plugin.extendContext?.(register as never);\n }\n\n return {\n app,\n async start(): Promise<void> {\n for (const plugin of plugins) {\n await plugin.onStart?.(app);\n }\n },\n async ready(): Promise<void> {\n state.ready = true;\n for (const plugin of plugins) {\n await plugin.onReady?.(app);\n }\n },\n async shutdown(): Promise<void> {\n for (const plugin of plugins) {\n try {\n await plugin.onShutdown?.(app);\n } catch (error) {\n log(`[moons] plugin \\`${plugin.name}\\` failed during onShutdown: ${String(error)}`);\n }\n }\n },\n applyExtensions(ctx: unknown): void {\n for (const extend of extensions) {\n const result = extend(ctx);\n if (result !== null && typeof result === \"object\" && !Array.isArray(result)) {\n Object.assign(ctx as Record<string, unknown>, result);\n }\n }\n },\n };\n}\n",
|
|
14
14
|
"import { MoonsError, type RouteDefinition, type RouteModule } from \"@moonsjs/core\";\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, resolve, sep } from \"node:path\";\nimport { scanPayloadForSecrets } from \"../payload-scan\";\n\n/**\n * Prerender statis (PRD Addendum D.5): render route ber-`prerender = true`\n * saat build → `dist/client/<path>/index.html` (guard: payload scan fail-mode).\n */\n/** Addendum H: config statis yang ditulis saat prerender (deploy kit). */\nexport interface PrerenderStaticConfig {\n headers?: Record<string, string>;\n redirects?: Array<{ from: string; to: string; status?: number }>;\n sitemap?: { site: string; exclude?: string[] };\n robots?: { sitemap?: boolean; disallow?: string[] };\n}\n\nexport interface PrerenderOptions {\n routes: RouteDefinition[];\n routesDir: string;\n loadRoute: Record<string, () => Promise<RouteModule>>;\n /** Handler SSR yang sudah dibuat runtime (createRequestHandler). */\n handler: (request: Request) => Promise<Response>;\n /** Tujuan file statis (biasanya `<root>/dist/client`). */\n clientDir: string;\n canary?: string;\n env?: Record<string, string | undefined>;\n log?: (message: string) => void;\n /** Addendum H: `headers`/`redirects`/`sitemap`/`robots` dari config. */\n staticConfig?: PrerenderStaticConfig;\n}\n\nexport interface PrerenderResult {\n written: number;\n skipped: number;\n}\n\n/**\n * Manifest path yang benar-benar di-prerender (dibaca static server agar hanya\n * file hasil prerender yang \"menang\" atas SSR — bukan shell index.html biasa).\n */\nexport const PRERENDER_MANIFEST_FILE = \"_moons_prerender.json\";\n\n/**\n * Addendum G: sentinel internal untuk merender halaman 404 statis. Path ini\n * tidak pernah menjadi route publik; handler merendernya seperti request tak\n * dikenal (route `_404` atau 404 bawaan).\n */\nexport const NOT_FOUND_SENTINEL = \"/_moons/404\";\n\n/** Addendum G: nama file 404 untuk static host (konvensi Cloudflare Pages/Netlify). */\nexport const NOT_FOUND_FILE = \"404.html\";\n\nexport async function runPrerender(options: PrerenderOptions): Promise<PrerenderResult> {\n const log = options.log ?? ((message: string) => console.log(message));\n const env = options.env ?? process.env;\n let written = 0;\n let skipped = 0;\n const entries: Array<{ path: string; revalidate?: number }> = [];\n\n const pages = options.routes.filter((route) => route.kind === \"page\");\n for (const route of pages) {\n const key = routeKeyOf(options.routesDir, route.file);\n const load = options.loadRoute[key];\n if (load === undefined) {\n continue;\n }\n const module = (await load()) as RouteModule;\n const prerender = module.prerender;\n const revalidate = module.revalidate;\n\n // Addendum E.1: `revalidate` hanya sah bersama `prerender`.\n if (revalidate !== undefined) {\n if (\n typeof revalidate !== \"number\" ||\n !Number.isFinite(revalidate) ||\n revalidate < 0 ||\n prerender !== true\n ) {\n throw new MoonsError({\n code: \"E_ISR_INVALID\",\n file: route.file,\n message: \"`revalidate` is invalid or used without `prerender = true`\",\n details: \"File-based ISR: `revalidate` (seconds, number >= 0) + `prerender`.\",\n suggestions: [\n \"Use a number of seconds, e.g. `export const revalidate = 60`\",\n \"Add `export const prerender = true` to the same page\",\n ],\n });\n }\n }\n\n if (prerender !== true) {\n if (prerender !== undefined && prerender !== false) {\n throw prerenderError(route, \"`prerender` must be a boolean (`true`/`false`)\");\n }\n continue;\n }\n\n const pathnames = await resolvePathnames(route, module);\n for (const pathname of pathnames) {\n const response = await options.handler(\n new Request(`http://localhost${pathname}`, {\n method: \"GET\",\n headers: { \"x-moons-prerender\": \"1\" },\n }),\n );\n\n if (response.status === 404) {\n log(`[moons] prerender: skipped ${pathname} (notFound)`);\n skipped += 1;\n continue;\n }\n if (response.status >= 300 && response.status < 400) {\n throw prerenderError(route, `\\`redirect()\\` is not supported during prerender (${pathname})`);\n }\n if (response.status !== 200) {\n throw prerenderError(route, `status ${response.status} while rendering ${pathname}`);\n }\n\n const html = await response.text();\n assertNoLeak(html, pathname, route.file, options, env);\n\n const file = outputFile(options.clientDir, pathname);\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, html);\n entries.push(\n typeof revalidate === \"number\" && revalidate >= 0\n ? { path: pathname, revalidate }\n : { path: pathname },\n );\n written += 1;\n }\n }\n\n // Addendum G: `404.html` untuk static host, bila app punya route `_404`.\n const notFound = await renderStaticNotFound(options, env, log);\n let wrote404 = false;\n if (notFound !== null) {\n writeFileSync(join(options.clientDir, NOT_FOUND_FILE), notFound);\n wrote404 = true;\n }\n\n // Manifest v2 (Addendum E.1): entries + revalidate; reader tetap menerima v1.\n writeFileSync(\n join(options.clientDir, PRERENDER_MANIFEST_FILE),\n `${JSON.stringify({ version: 2, entries }, null, 2)}\\n`,\n );\n\n // Addendum H: deploy kit statis (headers/redirects/sitemap/robots).\n const emitted = emitStaticFiles(options.clientDir, options.staticConfig, entries);\n\n const extras = [...(wrote404 ? [NOT_FOUND_FILE] : []), ...emitted];\n log(\n `[moons] prerender done: ${written} file${extras.length > 0 ? ` + ${extras.join(\" + \")}` : \"\"} (${skipped} skipped)`,\n );\n return { written, skipped };\n}\n\n/** Tulis file deploy statis dari config; mengembalikan nama file yang ditulis. */\nfunction emitStaticFiles(\n clientDir: string,\n staticConfig: PrerenderStaticConfig | undefined,\n entries: Array<{ path: string }>,\n): string[] {\n if (staticConfig === undefined) {\n return [];\n }\n const emitted: string[] = [];\n\n const headers = Object.entries(staticConfig.headers ?? {});\n if (headers.length > 0) {\n const lines = [\"/*\", ...headers.map(([name, value]) => ` ${name}: ${value}`)];\n writeFileSync(join(clientDir, \"_headers\"), `${lines.join(\"\\n\")}\\n`);\n emitted.push(\"_headers\");\n }\n\n const redirects = staticConfig.redirects ?? [];\n if (redirects.length > 0) {\n const lines = redirects.map((entry) => `${entry.from} ${entry.to} ${entry.status ?? 301}`);\n writeFileSync(join(clientDir, \"_redirects\"), `${lines.join(\"\\n\")}\\n`);\n emitted.push(\"_redirects\");\n }\n\n const sitemap = staticConfig.sitemap;\n if (sitemap !== undefined) {\n const site = sitemap.site.replace(/\\/$/, \"\");\n const exclude = sitemap.exclude ?? [];\n const paths = [...new Set(entries.map((entry) => entry.path))]\n .filter((path) => !exclude.some((prefix) => path.startsWith(prefix)))\n .sort();\n const xml = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">',\n ...paths.map((path) => ` <url><loc>${site}${path === \"/\" ? \"/\" : path}</loc></url>`),\n \"</urlset>\",\n \"\",\n ].join(\"\\n\");\n writeFileSync(join(clientDir, \"sitemap.xml\"), xml);\n emitted.push(\"sitemap.xml\");\n }\n\n const robots = staticConfig.robots;\n if (robots !== undefined) {\n const lines = [\"User-agent: *\"];\n for (const path of robots.disallow ?? []) {\n lines.push(`Disallow: ${path}`);\n }\n if ((robots.sitemap ?? true) && sitemap !== undefined) {\n lines.push(\"\", `Sitemap: ${sitemap.site.replace(/\\/$/, \"\")}/sitemap.xml`);\n }\n writeFileSync(join(clientDir, \"robots.txt\"), `${lines.join(\"\\n\")}\\n`);\n emitted.push(\"robots.txt\");\n }\n\n return emitted;\n}\n\n/**\n * Addendum G: render halaman 404 ke `dist/client/404.html` (static export).\n * Ditulis hanya bila app memiliki route `_404` dan sentinel menghasilkan 404;\n * hasilnya tetap melewati guard kebocoran (fail-mode).\n */\nasync function renderStaticNotFound(\n options: PrerenderOptions,\n env: Record<string, string | undefined>,\n log: (message: string) => void,\n): Promise<string | null> {\n if (!options.routes.some((route) => route.kind === \"404\")) {\n return null;\n }\n const response = await options.handler(\n new Request(`http://localhost${NOT_FOUND_SENTINEL}`, {\n method: \"GET\",\n headers: { \"x-moons-prerender\": \"1\" },\n }),\n );\n if (response.status !== 404) {\n log(\n `[moons] prerender: ${NOT_FOUND_FILE} skipped (sentinel \\`${NOT_FOUND_SENTINEL}\\` → ${response.status})`,\n );\n return null;\n }\n const html = await response.text();\n assertNoLeak(html, NOT_FOUND_SENTINEL, NOT_FOUND_FILE, options, env);\n return html;\n}\n\n/** Guard kebocoran fail-mode (Addendum D.5) — dipakai halaman & 404 statis. */\nfunction assertNoLeak(\n html: string,\n pathname: string,\n file: string,\n options: PrerenderOptions,\n env: Record<string, string | undefined>,\n): void {\n const findings = scanPayloadForSecrets(html, {\n ...(options.canary === undefined ? {} : { canary: options.canary }),\n env,\n });\n if (findings.length === 0) {\n return;\n }\n const labels = findings\n .map((finding) => (finding.kind === \"canary\" ? \"canary\" : `env(${finding.label})`))\n .join(\", \");\n throw new MoonsError({\n code: \"E_PRERENDER_LEAK\",\n file,\n message: `prerender output \\`${pathname}\\` contains ${labels}`,\n details: \"Static HTML is permanent — a prerendered secret cannot be retracted.\",\n suggestions: [\n \"Do not return secret env values from a loader that runs at prerender time\",\n \"Turn off `prerender` for this route or move the data to a request-time serverFn\",\n ],\n });\n}\n\nfunction routeKeyOf(routesDir: string, file: string): string {\n const relative = file.startsWith(routesDir) ? file.slice(routesDir.length + 1) : file;\n return relative.split(\"\\\\\").join(\"/\").replace(/\\.(tsx|ts)$/, \"\");\n}\n\nasync function resolvePathnames(route: RouteDefinition, module: RouteModule): Promise<string[]> {\n const isDynamic = route.params.length > 0;\n if (!isDynamic) {\n return [route.path];\n }\n const paths = module.paths;\n if (typeof paths !== \"function\") {\n throw new MoonsError({\n code: \"E_PRERENDER_NO_PATHS\",\n file: route.file,\n message: \"dynamic route with `prerender = true` without `export const paths`\",\n details: \"Prerendering needs a param list to render each path.\",\n suggestions: [\n 'Add `export const paths = () => [{ id: \"…\" }]`',\n \"Or remove `prerender` so the route renders at request time (SSR)\",\n ],\n });\n }\n\n const raw = await (paths as () => unknown | Promise<unknown>)();\n if (!Array.isArray(raw)) {\n throw prerenderError(route, \"`paths()` must return an array\");\n }\n\n const expected = new Set(route.params);\n const result: string[] = [];\n for (const item of raw as unknown[]) {\n if (item === null || typeof item !== \"object\" || Array.isArray(item)) {\n throw prerenderError(route, \"`paths()` items must be objects with string params\");\n }\n const record = item as Record<string, unknown>;\n const keys = Object.keys(record);\n for (const name of expected) {\n const value = record[name];\n if (typeof value !== \"string\" || value.length === 0) {\n throw prerenderError(route, `param \\`${name}\\` must be a non-empty string`);\n }\n }\n for (const key of keys) {\n if (!expected.has(key)) {\n throw prerenderError(route, `param \\`${key}\\` is not in the route pattern`);\n }\n }\n result.push(buildPathname(route, record as Record<string, string>));\n }\n return result;\n}\n\nfunction buildPathname(route: RouteDefinition, params: Record<string, string>): string {\n const segments = route.path.split(\"/\").filter((segment) => segment.length > 0);\n const out: string[] = [];\n let catchallName: string | null = null;\n for (const segment of segments) {\n if (segment === \"*\") {\n catchallName = route.params[route.params.length - 1] ?? null;\n const value = catchallName === null ? \"\" : (params[catchallName] ?? \"\");\n for (const part of value.split(\"/\")) {\n if (part.length === 0) {\n continue;\n }\n out.push(encodeSegment(route, part));\n }\n continue;\n }\n if (segment.startsWith(\":\")) {\n out.push(encodeSegment(route, params[segment.slice(1)] ?? \"\"));\n continue;\n }\n out.push(segment);\n }\n return `/${out.join(\"/\")}`;\n}\n\nfunction encodeSegment(route: RouteDefinition, value: string): string {\n if (value.length === 0 || /^\\.+$/.test(value)) {\n throw prerenderError(route, `param value \\`${value}\\` is not valid for a file path`);\n }\n return encodeURIComponent(value);\n}\n\nfunction outputFile(clientDir: string, pathname: string): string {\n const parts = pathname.split(\"/\").filter((part) => part.length > 0);\n const file = resolve(join(clientDir, ...parts, \"index.html\"));\n const base = resolve(clientDir);\n if (file !== base && !file.startsWith(base + sep)) {\n throw new MoonsError({\n code: \"E_PRERENDER_INVALID\",\n message: `prerender path escapes the client directory (\\`${pathname}\\`)`,\n details: \"The file name must stay inside `dist/client`.\",\n suggestions: [\"Check the `paths` param values — do not use `..`\"],\n });\n }\n return file;\n}\n\nfunction prerenderError(route: RouteDefinition, message: string): MoonsError {\n return new MoonsError({\n code: \"E_PRERENDER_INVALID\",\n file: route.file,\n message,\n details: \"The prerender contract is enforced.\",\n suggestions: [\n \"Fix the `paths`/params shape so it matches the route pattern\",\n \"Do not use `redirect()` on a prerendered route\",\n ],\n });\n}\n"
|
|
15
15
|
],
|
|
16
|
-
"mappings": "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",
|
|
17
|
-
"debugId": "
|
|
16
|
+
"mappings": "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",
|
|
17
|
+
"debugId": "01F6AD8AA11E371C64756E2164756E21",
|
|
18
18
|
"names": []
|
|
19
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-server.d.ts","sourceRoot":"","sources":["../../src/server/node-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"node-server.d.ts","sourceRoot":"","sources":["../../src/server/node-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AA2BvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAI/C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAClE,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oEAAoE;IACpE,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,qFAAqF;IACrF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sFAAsF;IACtF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACrE,+EAA+E;IAC/E,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACnC,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAChD,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAyRR"}
|
|
@@ -57,6 +57,19 @@ export declare function runHandlerWithTimeout(handler: (request: Request) => Pro
|
|
|
57
57
|
export declare function isAbortLike(error: unknown): boolean;
|
|
58
58
|
/** Respons teks transport (400/413/500/504) — tetap membawa header config + default aman (review G6). */
|
|
59
59
|
export declare function textResponseWithHeaders(status: number, text: string, configured?: Record<string, string>): Response;
|
|
60
|
+
/**
|
|
61
|
+
* Addendum T (G4): `Range` single-range untuk file statik.
|
|
62
|
+
* `null` = tidak ada/format tidak didukung (sajikan penuh 200);
|
|
63
|
+
* `"unsatisfiable"` = 416; `partial` = 206 dengan `content-range`.
|
|
64
|
+
*/
|
|
65
|
+
export type RangeResult = {
|
|
66
|
+
kind: "partial";
|
|
67
|
+
start: number;
|
|
68
|
+
end: number;
|
|
69
|
+
} | {
|
|
70
|
+
kind: "unsatisfiable";
|
|
71
|
+
} | null;
|
|
72
|
+
export declare function parseRangeHeader(value: string | null, size: number): RangeResult;
|
|
60
73
|
/** Target header minimal yang dipenuhi `ServerResponse` dan `Headers`. */
|
|
61
74
|
export interface HeaderTarget {
|
|
62
75
|
has(name: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/server/transport.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/server/transport.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/server/bun-server.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
forwardedProtocol,
|
|
18
18
|
gzipCached,
|
|
19
19
|
isAbortLike,
|
|
20
|
+
parseRangeHeader,
|
|
20
21
|
readBodyWithLimit,
|
|
21
22
|
requestTimeoutText,
|
|
22
23
|
resolveClientIpValues,
|
|
@@ -278,6 +279,21 @@ export function startBunServer(
|
|
|
278
279
|
return new Response(null, { status: 304, headers });
|
|
279
280
|
}
|
|
280
281
|
|
|
282
|
+
// Addendum T (G4): Range single-range untuk file statik (media).
|
|
283
|
+
headers.set("accept-ranges", "bytes");
|
|
284
|
+
const range =
|
|
285
|
+
request.method === "GET" ? parseRangeHeader(request.headers.get("range"), stat.size) : null;
|
|
286
|
+
if (range !== null) {
|
|
287
|
+
if (range.kind === "unsatisfiable") {
|
|
288
|
+
headers.set("content-range", `bytes */${stat.size}`);
|
|
289
|
+
return new Response(null, { status: 416, headers });
|
|
290
|
+
}
|
|
291
|
+
const full = readFileSync(staticFile);
|
|
292
|
+
const slice = full.subarray(range.start, range.end + 1);
|
|
293
|
+
headers.set("content-range", `bytes ${range.start}-${range.end}/${stat.size}`);
|
|
294
|
+
return new Response(slice as unknown as BodyInit, { status: 206, headers });
|
|
295
|
+
}
|
|
296
|
+
|
|
281
297
|
// K.5: gzip untuk aset teks (cache per mtime).
|
|
282
298
|
let payload: Uint8Array | null =
|
|
283
299
|
request.method === "HEAD" ? null : readFileSync(staticFile);
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
applyStaticHeaders,
|
|
19
19
|
gzipCached,
|
|
20
20
|
isAbortLike,
|
|
21
|
+
parseRangeHeader,
|
|
21
22
|
requestTimeoutText,
|
|
22
23
|
resolveStaticFile,
|
|
23
24
|
rpcBodyTooLargeText,
|
|
@@ -218,6 +219,27 @@ export function startNodeServer(
|
|
|
218
219
|
return;
|
|
219
220
|
}
|
|
220
221
|
|
|
222
|
+
// Addendum T (G4): Range single-range untuk file statik (media).
|
|
223
|
+
res.setHeader("accept-ranges", "bytes");
|
|
224
|
+
const rawRange = req.headers["range"];
|
|
225
|
+
const range = parseRangeHeader(
|
|
226
|
+
Array.isArray(rawRange) ? (rawRange[0] ?? null) : (rawRange ?? null),
|
|
227
|
+
stat.size,
|
|
228
|
+
);
|
|
229
|
+
if (req.method === "GET" && range !== null) {
|
|
230
|
+
if (range.kind === "unsatisfiable") {
|
|
231
|
+
res.statusCode = 416;
|
|
232
|
+
res.setHeader("content-range", `bytes */${stat.size}`);
|
|
233
|
+
res.end();
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const slice = body.subarray(range.start, range.end + 1);
|
|
237
|
+
res.statusCode = 206;
|
|
238
|
+
res.setHeader("content-range", `bytes ${range.start}-${range.end}/${stat.size}`);
|
|
239
|
+
res.end(slice);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
221
243
|
// Addendum K.5: gzip untuk aset teks (cache per mtime).
|
|
222
244
|
let payload: Buffer = body;
|
|
223
245
|
const encodings = req.headers["accept-encoding"];
|
package/src/server/transport.ts
CHANGED
|
@@ -279,6 +279,57 @@ export function textResponseWithHeaders(
|
|
|
279
279
|
return new Response(text, { status, headers });
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
/**
|
|
283
|
+
* Addendum T (G4): `Range` single-range untuk file statik.
|
|
284
|
+
* `null` = tidak ada/format tidak didukung (sajikan penuh 200);
|
|
285
|
+
* `"unsatisfiable"` = 416; `partial` = 206 dengan `content-range`.
|
|
286
|
+
*/
|
|
287
|
+
export type RangeResult =
|
|
288
|
+
| { kind: "partial"; start: number; end: number }
|
|
289
|
+
| { kind: "unsatisfiable" }
|
|
290
|
+
| null;
|
|
291
|
+
|
|
292
|
+
export function parseRangeHeader(value: string | null, size: number): RangeResult {
|
|
293
|
+
if (value === null) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
const match = /^bytes=(\d*)-(\d*)$/.exec(value.trim());
|
|
297
|
+
if (match === null) {
|
|
298
|
+
// Multi-range atau unit lain → abaikan (sajikan penuh).
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
const rawStart = match[1] ?? "";
|
|
302
|
+
const rawEnd = match[2] ?? "";
|
|
303
|
+
if (rawStart === "" && rawEnd === "") {
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
if (rawStart === "") {
|
|
307
|
+
// Suffix: `bytes=-N` → N byte terakhir.
|
|
308
|
+
const suffix = Number(rawEnd);
|
|
309
|
+
if (!Number.isFinite(suffix) || suffix <= 0) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
if (size === 0) {
|
|
313
|
+
return { kind: "unsatisfiable" };
|
|
314
|
+
}
|
|
315
|
+
return { kind: "partial", start: Math.max(0, size - suffix), end: size - 1 };
|
|
316
|
+
}
|
|
317
|
+
const start = Number(rawStart);
|
|
318
|
+
const end = rawEnd === "" ? size - 1 : Number(rawEnd);
|
|
319
|
+
if (!Number.isFinite(start) || !Number.isFinite(end)) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
// Cek "tak terpuaskan" SEBELUM validasi start>end: `bytes=99-` dengan
|
|
323
|
+
// size kecil menghasilkan start>end karena end default size-1.
|
|
324
|
+
if (start >= size) {
|
|
325
|
+
return { kind: "unsatisfiable" };
|
|
326
|
+
}
|
|
327
|
+
if (start > end) {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
return { kind: "partial", start, end: Math.min(end, size - 1) };
|
|
331
|
+
}
|
|
332
|
+
|
|
282
333
|
/** Target header minimal yang dipenuhi `ServerResponse` dan `Headers`. */
|
|
283
334
|
export interface HeaderTarget {
|
|
284
335
|
has(name: string): boolean;
|