@moonsjs/vite 0.1.4 → 0.1.5

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.
Files changed (49) hide show
  1. package/dist/api.d.ts +8 -0
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/{index-33p1r65s.js → index-1fnt137k.js} +50 -5
  4. package/dist/index-1fnt137k.js.map +14 -0
  5. package/dist/{index-3ec9vpek.js → index-e7qz0epf.js} +232 -24
  6. package/dist/index-e7qz0epf.js.map +11 -0
  7. package/dist/index.js +213 -16
  8. package/dist/index.js.map +5 -4
  9. package/dist/manifest.d.ts +6 -1
  10. package/dist/manifest.d.ts.map +1 -1
  11. package/dist/payload-scan.d.ts +18 -0
  12. package/dist/payload-scan.d.ts.map +1 -0
  13. package/dist/plugin.d.ts.map +1 -1
  14. package/dist/server/dev.d.ts +3 -0
  15. package/dist/server/dev.d.ts.map +1 -1
  16. package/dist/server/handler.d.ts +16 -1
  17. package/dist/server/handler.d.ts.map +1 -1
  18. package/dist/server/index.d.ts +4 -0
  19. package/dist/server/index.d.ts.map +1 -1
  20. package/dist/server/index.js +453 -17
  21. package/dist/server/index.js.map +8 -6
  22. package/dist/server/node-server.d.ts +1 -1
  23. package/dist/server/node-server.d.ts.map +1 -1
  24. package/dist/server/node.d.ts.map +1 -1
  25. package/dist/server/prerender.d.ts +28 -0
  26. package/dist/server/prerender.d.ts.map +1 -0
  27. package/dist/server-only.d.ts +57 -0
  28. package/dist/server-only.d.ts.map +1 -0
  29. package/dist/transform.d.ts +9 -1
  30. package/dist/transform.d.ts.map +1 -1
  31. package/dist/transform.js +1 -1
  32. package/dist/virtual-modules.d.ts +1 -0
  33. package/dist/virtual-modules.d.ts.map +1 -1
  34. package/package.json +1 -1
  35. package/src/api.ts +124 -0
  36. package/src/manifest.ts +42 -1
  37. package/src/payload-scan.ts +53 -0
  38. package/src/plugin.ts +130 -7
  39. package/src/server/dev.ts +14 -5
  40. package/src/server/handler.ts +317 -13
  41. package/src/server/index.ts +4 -0
  42. package/src/server/node-server.ts +47 -7
  43. package/src/server/node.ts +17 -0
  44. package/src/server/prerender.ts +230 -0
  45. package/src/server-only.ts +220 -0
  46. package/src/transform.ts +138 -8
  47. package/src/virtual-modules.ts +1 -0
  48. package/dist/index-33p1r65s.js.map +0 -14
  49. package/dist/index-3ec9vpek.js.map +0 -10
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/server/handler.ts", "../src/server/node-server.ts", "../src/server/shutdown.ts", "../src/server/test-server.ts", "../src/server/plugins.ts"],
3
+ "sources": ["../src/server/handler.ts", "../src/payload-scan.ts", "../src/server/node-server.ts", "../src/server/shutdown.ts", "../src/server/test-server.ts", "../src/server/plugins.ts", "../src/server/prerender.ts"],
4
4
  "sourcesContent": [
5
- "import {\n MoonsError,\n composeMiddleware,\n isNotFoundSignal,\n isRedirectSignal,\n resolveRoute,\n routeKeyFromFile,\n runLoaders,\n type MoonsConfig,\n type ResolvedRoute,\n type RouteDefinition,\n type RouteModule,\n} from \"@moonsjs/core\";\nimport { encodeSsrPayload, reviveError, serializeError } from \"@moonsjs/core/serialize\";\nimport { renderToMarkup } from \"@moonsjs/react/ssr\";\nimport type { ClientRouteEntry, RouteModuleShape } from \"@moonsjs/react/internal\";\nimport { createRpcHandler, runWithContext, runWithRequestCache } from \"@moonsjs/server\";\nimport { ERROR_ROUTE_KEY, NOT_FOUND_ROUTE_KEY } from \"../manifest\";\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\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 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\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 markup = renderToMarkup(\n entry,\n { page: pageModule as RouteModuleShape, layouts: modules.slice(0, -1) as RouteModuleShape[] },\n resolved.params,\n data,\n searchParams,\n );\n const payload = encodeSsrPayload({\n key: pageKey,\n params: resolved.params,\n searchParams,\n data,\n ...(meta === undefined ? {} : { meta }),\n });\n\n return htmlResponse(await shell(markup, payload, request.url, meta), 200);\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 markup = renderToMarkup(\n { page: key, layouts: [] },\n { page: module as RouteModuleShape, layouts: [] },\n {},\n {},\n );\n return htmlResponse(await shell(markup, payload, request.url), 404);\n } catch (error) {\n console.error(\"[moons] gagal merender _404 kustom:\", error);\n }\n }\n\n const payload = encodeSsrPayload({ key: \"\", params: {}, data: {} });\n const html = await shell(\n \"<h1>404</h1><p>Halaman tidak ditemukan.</p>\",\n payload,\n request.url,\n );\n return htmlResponse(html, 404);\n }\n\n /**\n * §11.2: halaman `_error.tsx` kustom dengan `RouteErrorProvider`.\n * Production tidak men-serialisasi error apa pun (§16.6); dev mengirim aslinya.\n */\n async function routeErrorResponse(error: unknown, request: Request): Promise<Response> {\n console.error(\"[moons] route error:\", error);\n\n if (errorRoute !== undefined) {\n try {\n const key = routeKeyFromFile(routesDir, errorRoute.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: ERROR_ROUTE_KEY,\n params: {},\n data: {},\n ...(serialized === undefined ? {} : { error: serialized }),\n });\n const markup = renderToMarkup(\n { page: key, layouts: [] },\n { page: module as RouteModuleShape, layouts: [] },\n {},\n {},\n {},\n serialized === undefined ? undefined : reviveError(serialized),\n );\n return htmlResponse(await shell(markup, payload, request.url), 500);\n } catch (renderError) {\n console.error(\"[moons] gagal merender _error kustom:\", renderError);\n }\n }\n\n return internalErrorResponse(error, { log: false });\n }\n\n return 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\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 const resolved = resolveRoute(url.pathname, routes);\n if (resolved === null) {\n return await notFoundResponse(request);\n }\n try {\n return await renderRoute(resolved, request, ctx);\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);\n }\n });\n\n return await runWithRequestCache(() => runWithContext(ctx, () => respond(request)));\n } catch (error) {\n return internalErrorResponse(error);\n }\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: `modul route \\`${key}\\` tidak terdaftar`,\n details: \"Registry route tidak sinkron dengan hasil scan.\",\n suggestions: [\"Jalankan ulang `bun run build`, atau restart 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` harus berupa fungsi `({ data }) => RouteMeta`\",\n details: \"Bentuk `meta` mengikuti PRD §11.2 (Addendum B.1).\",\n suggestions: [\n \"Ubah menjadi `export const meta = ({ data }) => ({ title: \\\"...\\\" })`\",\n \"Atau hapus export `meta`\",\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()` harus mengembalikan objek RouteMeta\",\n details: \"Nilai yang dikembalikan dipakai untuk <title>/description/og (Addendum B.1).\",\n suggestions: [\"Kembalikan objek, mis. `({ title: \\\"Halaman\\\" })`\"],\n });\n }\n return result as Record<string, unknown>;\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>Terjadi kesalahan internal.</p>\";\n\n return htmlResponse(\n `<!doctype html><html lang=\"id\"><head><meta charset=\"utf-8\"><title>500</title></head><body><h1>500</h1>${detail}</body></html>`,\n 500,\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(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\");\n}\n",
6
- "import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { createServer, type Server } from \"node:http\";\nimport { extname, join, resolve, sep } from \"node:path\";\nimport { sendNodeResponse, toWebRequest } from \"./node\";\nimport type { PluginRuntime } from \"./plugins\";\nimport { installGracefulShutdown } from \"./shutdown\";\n\nconst 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};\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}\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 server = createServer((req, res) => {\n void (async () => {\n try {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n\n if (req.method === \"GET\" || req.method === \"HEAD\") {\n const staticFile = resolveStaticFile(clientDir, url.pathname);\n if (staticFile !== null) {\n const body = readFileSync(staticFile);\n res.statusCode = 200;\n res.setHeader(\"content-type\", MIME_TYPES[extname(staticFile).toLowerCase()] ?? \"application/octet-stream\");\n res.end(req.method === \"HEAD\" ? undefined : body);\n return;\n }\n }\n\n const response = await handler(await toWebRequest(req));\n await sendNodeResponse(res, response);\n } catch (error) {\n console.error(\"[moons] server error:\", error);\n res.statusCode = 500;\n res.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n res.end(\"Internal Server Error\");\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\n/** Resolve file static dengan proteksi path traversal. */\nexport function resolveStaticFile(clientDir: string, pathname: string): string | null {\n let decoded: string;\n try {\n decoded = decodeURIComponent(pathname);\n } catch {\n return null;\n }\n\n const candidate = resolve(clientDir, `.${decoded}`);\n if (candidate !== clientDir && !candidate.startsWith(clientDir + sep)) {\n return null;\n }\n if (!existsSync(candidate)) {\n return null;\n }\n if (!statSync(candidate).isFile()) {\n return null;\n }\n return candidate;\n}\n",
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} from \"@moonsjs/core\";\nimport { encodeSsrPayload, reviveError, serializeError } from \"@moonsjs/core/serialize\";\nimport { API_METHODS, resolveApiRoute } from \"@moonsjs/core\";\nimport { renderToMarkup } from \"@moonsjs/react/ssr\";\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\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> { 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 markup = renderToMarkup(\n entry,\n { page: pageModule as RouteModuleShape, layouts: modules.slice(0, -1) as RouteModuleShape[] },\n resolved.params,\n data,\n searchParams,\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(await shell(markup, payload, request.url, meta), 200);\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: `modul API \\`${route.path}\\` tidak bisa dimuat`,\n details: \"Peta `loadApi` tidak memuat route ini (build/dev tidak sinkron).\",\n suggestions: [\"Jalankan ulang build / restart 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: \"modul API tidak mengekspor objek handler\",\n details: `Modul \\`${route.path}\\` harus mengekspor handler method (PRD Addendum D.1).`,\n suggestions: [\"Export `GET`/`POST`/… sebagai fungsi `(args) => Response`\"],\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}\\` tidak mengembalikan \\`Response\\``,\n details: \"Handler API wajib mengembalikan `new Response(...)` (PRD Addendum D.1).\",\n suggestions: [\"Kembalikan `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 markup = renderToMarkup(\n { page: key, layouts: [] },\n { page: module as RouteModuleShape, layouts: [] },\n {},\n {},\n );\n return htmlResponse(await shell(markup, payload, request.url), 404);\n } catch (error) {\n console.error(\"[moons] gagal merender _404 kustom:\", error);\n }\n }\n\n const payload = encodeSsrPayload({ key: \"\", params: {}, data: {} });\n const html = await shell(\n \"<h1>404</h1><p>Halaman tidak ditemukan.</p>\",\n payload,\n request.url,\n );\n return htmlResponse(html, 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 markup = renderToMarkup(\n { page: key, layouts: [] },\n { page: module as RouteModuleShape, layouts: [] },\n {},\n {},\n {},\n serialized === undefined ? undefined : reviveError(serialized),\n );\n return htmlResponse(await shell(markup, payload, request.url), 500);\n } catch (renderError) {\n console.error(\"[moons] gagal merender _error kustom:\", 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: \"middleware direktori tidak bisa dimuat\",\n details: \"Peta `loadRoute` tidak memuat `_middleware.ts` ini.\",\n suggestions: [\"Restart dev server / jalankan ulang build\"],\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` tidak meng-export default fungsi\",\n details: \"Middleware direktori mengikuti bentuk `(args) => Promise<Response>` (Addendum D.3).\",\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: \"middleware API tidak bisa dimuat\",\n details: \"Peta `loadApiMiddleware` tidak memuat `_middleware.ts` ini.\",\n suggestions: [\"Restart dev server / jalankan ulang build\"],\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` tidak meng-export default fungsi\",\n details: \"Middleware direktori mengikuti bentuk `(args) => Promise<Response>` (Addendum D.3).\",\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 return 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: \"middleware API\" },\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: \"middleware direktori\" },\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\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: `modul route \\`${key}\\` tidak terdaftar`,\n details: \"Registry route tidak sinkron dengan hasil scan.\",\n suggestions: [\"Jalankan ulang `bun run build`, atau restart 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` harus berupa fungsi `({ data }) => RouteMeta`\",\n details: \"Bentuk `meta` mengikuti PRD §11.2 (Addendum B.1).\",\n suggestions: [\n \"Ubah menjadi `export const meta = ({ data }) => ({ title: \\\"...\\\" })`\",\n \"Atau hapus export `meta`\",\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()` harus mengembalikan objek RouteMeta\",\n details: \"Nilai yang dikembalikan dipakai untuk <title>/description/og (Addendum B.1).\",\n suggestions: [\"Kembalikan objek, mis. `({ title: \\\"Halaman\\\" })`\"],\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 ? \"Terjadi kesalahan internal.\" : 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 ? \"Terjadi kesalahan internal.\" : 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>Terjadi kesalahan internal.</p>\";\n\n return htmlResponse(\n `<!doctype html><html lang=\"id\"><head><meta charset=\"utf-8\"><title>500</title></head><body><h1>500</h1>${detail}</body></html>`,\n 500,\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(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\");\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] peringatan dev: payload SSR memuat ${label} — jangan mengembalikan rahasia dari loader (PRD §2/§16.6).`,\n );\n }\n}\n",
6
+ "/**\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",
7
+ "import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { createServer, type Server } from \"node:http\";\nimport { extname, join, resolve, sep } from \"node:path\";\nimport { sendNodeResponse, toWebRequest } from \"./node\";\nimport type { PluginRuntime } from \"./plugins\";\nimport { installGracefulShutdown } from \"./shutdown\";\n\nconst 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};\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}\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 server = createServer((req, res) => {\n void (async () => {\n try {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n\n if (req.method === \"GET\" || req.method === \"HEAD\") {\n const staticFile = resolveStaticFile(clientDir, url.pathname);\n if (staticFile !== null) {\n const body = readFileSync(staticFile);\n res.statusCode = 200;\n res.setHeader(\"content-type\", MIME_TYPES[extname(staticFile).toLowerCase()] ?? \"application/octet-stream\");\n res.end(req.method === \"HEAD\" ? undefined : body);\n return;\n }\n }\n\n const response = await handler(await toWebRequest(req));\n await sendNodeResponse(res, response);\n } catch (error) {\n console.error(\"[moons] server error:\", error);\n res.statusCode = 500;\n res.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n res.end(\"Internal Server Error\");\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\n/** Resolve file static dengan proteksi path traversal (+ manifest prerender D.5). */\nexport function resolveStaticFile(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.has(normalized)) {\n const target = normalized === \"/\" ? \"index.html\" : `${normalized.slice(1)}/index.html`;\n const candidate = safeWithin(clientDir, `./${target}`);\n if (candidate !== null && isFile(candidate)) {\n return candidate;\n }\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\nlet prerenderManifestCache: { file: string; mtimeMs: number; paths: Set<string> } | null = null;\n\nfunction readPrerenderManifest(clientDir: string): Set<string> {\n const file = join(clientDir, \"_moons_prerender.json\");\n try {\n const mtimeMs = statSync(file).mtimeMs;\n if (prerenderManifestCache !== null && prerenderManifestCache.file === file && prerenderManifestCache.mtimeMs === mtimeMs) {\n return prerenderManifestCache.paths;\n }\n const json = JSON.parse(readFileSync(file, \"utf8\")) as { paths?: unknown };\n const paths = new Set(\n Array.isArray(json.paths) ? json.paths.filter((path): path is string => typeof path === \"string\") : [],\n );\n prerenderManifestCache = { file, mtimeMs, paths };\n return paths;\n } catch {\n return new Set();\n }\n}\n",
7
8
  "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] menerima ${signal} — berhenti menerima koneksi, drain...`);\n\n const timer = setTimeout(() => {\n log(`[moons] drain melewati ${timeoutMs}ms — keluar paksa`);\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] penutupan server gagal: ${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 gagal: ${String(hookError)}`);\n }\n }\n clearTimeout(timer);\n log(\"[moons] shutdown selesai (drain penuh)\");\n exit(0);\n });\n };\n}\n",
8
9
  "import type { MoonsConfig, RouteDefinition, RouteModule } from \"@moonsjs/core\";\nimport { createRequestHandler } from \"./handler\";\nimport { DEFAULT_TEMPLATE, injectShell, type Shell } from \"./shell\";\n\nexport interface TestServerOptions {\n routes: RouteDefinition[];\n config: MoonsConfig;\n routesDir: string;\n loadRoute: Record<string, () => Promise<RouteModule>>;\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 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",
9
- "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}\\` gagal saat 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"
10
+ "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}\\` gagal saat 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",
11
+ "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 */\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}\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\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 writtenPaths: string[] = [];\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\n if (prerender !== true) {\n if (prerender !== undefined && prerender !== false) {\n throw prerenderError(route, \"`prerender` harus 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: lewati ${pathname} (notFound)`);\n skipped += 1;\n continue;\n }\n if (response.status >= 300 && response.status < 400) {\n throw prerenderError(route, `\\`redirect()\\` tidak didukung saat prerender (${pathname})`);\n }\n if (response.status !== 200) {\n throw prerenderError(route, `status ${response.status} saat merender ${pathname}`);\n }\n\n const html = await response.text();\n const findings = scanPayloadForSecrets(html, {\n ...(options.canary === undefined ? {} : { canary: options.canary }),\n env,\n });\n if (findings.length > 0) {\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: route.file,\n message: `hasil prerender \\`${pathname}\\` memuat ${labels}`,\n details:\n \"HTML statis permanen — rahasia yang ter-prerender tidak bisa ditarik kembali (PRD Addendum D.5).\",\n suggestions: [\n \"Jangan mengembalikan nilai env rahasia dari loader yang di-prerender\",\n \"Matikan `prerender` untuk route ini atau pindahkan datanya ke serverFn request-time\",\n ],\n });\n }\n\n const file = outputFile(options.clientDir, pathname);\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, html);\n writtenPaths.push(pathname);\n written += 1;\n }\n }\n\n // Manifest agar static server tahu path mana yang boleh dilayani statis.\n writeFileSync(\n join(options.clientDir, PRERENDER_MANIFEST_FILE),\n `${JSON.stringify({ paths: writtenPaths }, null, 2)}\\n`,\n );\n\n log(`[moons] prerender selesai: ${written} file (${skipped} dilewati)`);\n return { written, skipped };\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: \"route dynamic ber-`prerender = true` tanpa `export const paths`\",\n details: \"Prerender butuh daftar param untuk merender tiap path (PRD Addendum D.5).\",\n suggestions: [\n 'Tambahkan `export const paths = () => [{ id: \"…\" }]`',\n \"Atau hapus `prerender` agar dirender SSR saat request\",\n ],\n });\n }\n\n const raw = await (paths as () => unknown | Promise<unknown>)();\n if (!Array.isArray(raw)) {\n throw prerenderError(route, \"`paths()` harus mengembalikan 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, \"item `paths()` harus objek param string\");\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}\\` wajib string non-kosong`);\n }\n }\n for (const key of keys) {\n if (!expected.has(key)) {\n throw prerenderError(route, `param \\`${key}\\` tidak ada di pola route`);\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, `nilai param \\`${value}\\` tidak valid untuk path file`);\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: `path prerender keluar dari direktori client (\\`${pathname}\\`)`,\n details: \"Nama file harus berada di dalam `dist/client`.\",\n suggestions: [\"Periksa nilai param `paths` — jangan memakai `..`\"],\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: \"Kontrak prerender mengikuti PRD Addendum D.5.\",\n suggestions: [\n \"Perbaiki bentuk `paths`/param agar cocok dengan pola route\",\n \"Jangan memakai `redirect()` pada route yang di-prerender\",\n ],\n });\n}\n"
10
12
  ],
11
- "mappings": "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",
12
- "debugId": "871C5ACF2A35737064756E2164756E21",
13
+ "mappings": "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",
14
+ "debugId": "C7C001D56BF6021C64756E2164756E21",
13
15
  "names": []
14
16
  }
@@ -15,6 +15,6 @@ export interface NodeServerOptions {
15
15
  * Berjalan di Bun dan Node (hanya API `node:*`).
16
16
  */
17
17
  export declare function startNodeServer(handler: (request: Request) => Promise<Response>, options?: NodeServerOptions): Server;
18
- /** Resolve file static dengan proteksi path traversal. */
18
+ /** Resolve file static dengan proteksi path traversal (+ manifest prerender D.5). */
19
19
  export declare function resolveStaticFile(clientDir: string, pathname: string): string | null;
20
20
  //# sourceMappingURL=node-server.d.ts.map
@@ -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;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAyB/C,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;CACzB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAChD,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CA2DR;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBpF"}
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;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAyB/C,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;CACzB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAChD,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CA2DR;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2BpF"}
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,wFAAwF;AACxF,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CA0BzE;AAqBD,qDAAqD;AACrD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAO7F"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,wFAAwF;AACxF,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CA0BzE;AAqBD,qDAAqD;AACrD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB7F"}
@@ -0,0 +1,28 @@
1
+ import { type RouteDefinition, type RouteModule } from "@moonsjs/core";
2
+ /**
3
+ * Prerender statis (PRD Addendum D.5): render route ber-`prerender = true`
4
+ * saat build → `dist/client/<path>/index.html` (guard: payload scan fail-mode).
5
+ */
6
+ export interface PrerenderOptions {
7
+ routes: RouteDefinition[];
8
+ routesDir: string;
9
+ loadRoute: Record<string, () => Promise<RouteModule>>;
10
+ /** Handler SSR yang sudah dibuat runtime (createRequestHandler). */
11
+ handler: (request: Request) => Promise<Response>;
12
+ /** Tujuan file statis (biasanya `<root>/dist/client`). */
13
+ clientDir: string;
14
+ canary?: string;
15
+ env?: Record<string, string | undefined>;
16
+ log?: (message: string) => void;
17
+ }
18
+ export interface PrerenderResult {
19
+ written: number;
20
+ skipped: number;
21
+ }
22
+ /**
23
+ * Manifest path yang benar-benar di-prerender (dibaca static server agar hanya
24
+ * file hasil prerender yang "menang" atas SSR — bukan shell index.html biasa).
25
+ */
26
+ export declare const PRERENDER_MANIFEST_FILE = "_moons_prerender.json";
27
+ export declare function runPrerender(options: PrerenderOptions): Promise<PrerenderResult>;
28
+ //# sourceMappingURL=prerender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prerender.d.ts","sourceRoot":"","sources":["../../src/server/prerender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAKnF;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IACtD,oEAAoE;IACpE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,0BAA0B,CAAC;AAE/D,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmFtF"}
@@ -0,0 +1,57 @@
1
+ import { MoonsError } from "@moonsjs/core";
2
+ /**
3
+ * Gate paket server-only (PRD Addendum C): paket npm yang tidak boleh masuk
4
+ * graph client — di-import dari route/client/shared → build gagal.
5
+ *
6
+ * Daftar bawaan adalah **minimum normatif** dan TIDAK dapat dihapus app:
7
+ * gate kebocoran tidak boleh bisa dilonggarkan (prinsip "batas lebih ketat
8
+ * menang"); salah-tangkap diperbaiki lewat rilis framework.
9
+ */
10
+ export declare const DEFAULT_SERVER_ONLY_PACKAGES: ReadonlyArray<string>;
11
+ export type ServerOnlyMatchSource = "builtin" | "config" | "marker";
12
+ export interface PackageJsonInfo {
13
+ /** Direktori package (tempat package.json berada). */
14
+ dir: string;
15
+ name: string;
16
+ serverOnlyMarker: boolean;
17
+ }
18
+ export interface ServerOnlyMatch {
19
+ packageName: string;
20
+ source: ServerOnlyMatchSource;
21
+ packageDir: string;
22
+ }
23
+ export interface ServerOnlyClassifier {
24
+ check(input: {
25
+ specifier: string;
26
+ resolvedFile: string | null;
27
+ importerFile: string;
28
+ }): ServerOnlyMatch | null;
29
+ }
30
+ export interface ServerOnlyClassifierOptions {
31
+ /** `security.serverOnlyPackages` — tambahan milik app (tidak menghapus bawaan). */
32
+ configured?: ReadonlyArray<string>;
33
+ /** Cache package.json per-direktori; bagikan lintas modul demi performa. */
34
+ cache?: Map<string, PackageJsonInfo | null>;
35
+ }
36
+ /** Nama paket dari specifier bare (dipakai sebagai info pelengkap; pencocokan utama lewat resolve). */
37
+ export declare function packageNameFromSpecifier(specifier: string): string | null;
38
+ /** Baca package.json pada direktori tertentu (null bila tidak ada/gagal). */
39
+ export declare function tryReadPackageJson(dir: string): PackageJsonInfo | null;
40
+ /** Baca package.json terdekat dari sebuah file absolut (menelusuri ke atas). */
41
+ export declare function readPackageJsonFrom(file: string): PackageJsonInfo | null;
42
+ export declare function createServerOnlyClassifier(options?: ServerOnlyClassifierOptions): ServerOnlyClassifier;
43
+ /**
44
+ * Error §15 untuk import paket server-only (kode tetap
45
+ * `E_FORBIDDEN_SERVER_IMPORT`, PRD Addendum C.3).
46
+ */
47
+ export declare function serverOnlyImportError(input: {
48
+ relativeFile: string;
49
+ line: number;
50
+ specifier: string;
51
+ packageName: string;
52
+ source: ServerOnlyMatchSource;
53
+ /** Path package.json relatif project — untuk sumber kecocokan "marker". */
54
+ markerPath?: string;
55
+ dynamic?: boolean;
56
+ }): MoonsError;
57
+ //# sourceMappingURL=server-only.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-only.d.ts","sourceRoot":"","sources":["../src/server-only.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI3C;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,EAAE,aAAa,CAAC,MAAM,CA2B9D,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,KAAK,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,YAAY,EAAE,MAAM,CAAC;KACtB,GAAG,eAAe,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,2BAA2B;IAC1C,mFAAmF;IACnF,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACnC,4EAA4E;IAC5E,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC,CAAC;CAC7C;AAED,uGAAuG;AACvG,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBzE;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAmBtE;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAcxE;AAED,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,2BAAgC,GACxC,oBAAoB,CAqDtB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,UAAU,CAkBb"}
@@ -1,4 +1,5 @@
1
1
  import { MoonsError } from "@moonsjs/core";
2
+ import { type PackageJsonInfo } from "./server-only";
2
3
  /**
3
4
  * Spec §12: analisis `.server.ts` + stub client + injeksi meta server +
4
5
  * penolakan import (E_SERVER_IMPORT_IN_CLIENT / E_FORBIDDEN_SERVER_IMPORT).
@@ -76,6 +77,12 @@ export interface ClientImportCheckContext {
76
77
  resolve: (specifier: string, importer: string) => string | null | Promise<string | null>;
77
78
  /** Analysis untuk file server (hasil cache plugin). */
78
79
  analyze: (absoluteFile: string) => ServerFileAnalysis | null;
80
+ /** Direktori `src/api` (absolut) — modul API server-only (Addendum D.1). */
81
+ apiDir?: string;
82
+ /** Paket server-only tambahan dari `security.serverOnlyPackages` (Addendum C). */
83
+ serverOnlyPackages?: ReadonlyArray<string>;
84
+ /** Cache package.json lintas modul (performa; dikelola plugin). */
85
+ packageCache?: Map<string, PackageJsonInfo | null>;
79
86
  }
80
87
  export declare function nonContractServerFileError(file: string, projectRoot: string): MoonsError;
81
88
  /** Periksa import modul client terhadap §12.4/§12.7/§12.8 — berbasis hasil resolve. */
@@ -88,7 +95,8 @@ export interface RouteExportCheckContext {
88
95
  }
89
96
  /**
90
97
  * §11.2 + §12.4: export legal per jenis modul route.
91
- * page: `default|loader|meta`; layout: `default|loader`; `_error`/`_404`: `default`.
98
+ * page: `default|loader|meta|prerender|paths` (D.5); layout: `default|loader`;
99
+ * `_error`/`_404`: `default`.
92
100
  */
93
101
  export declare function checkRouteModuleExports(context: RouteExportCheckContext): void;
94
102
  /** Scan semua `*.server.{ts,tsx}` di bawah root (exclude direktori build/dependency). */
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"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"}
package/dist/transform.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  checkRouteModuleExports2,
14
14
  scanServerFiles2,
15
15
  buildFnRegistry2
16
- } from "./index-3ec9vpek.js";
16
+ } from "./index-e7qz0epf.js";
17
17
  export {
18
18
  analyzeServerFile2 as analyzeServerFile,
19
19
  buildFnRegistry2 as buildFnRegistry,
@@ -1,6 +1,7 @@
1
1
  /** Nama virtual module PRD §9.4. Semua di-resolve ke id `\0`-prefix. */
2
2
  export declare const VIRTUAL_MODULES: {
3
3
  readonly routes: "virtual:moons/routes";
4
+ readonly api: "virtual:moons/api";
4
5
  readonly config: "virtual:moons/config";
5
6
  readonly clientEntry: "virtual:moons/client-entry";
6
7
  readonly serverEntry: "virtual:moons/server-entry";
@@ -1 +1 @@
1
- {"version":3,"file":"virtual-modules.d.ts","sourceRoot":"","sources":["../src/virtual-modules.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,eAAe;aAC1B,MAAM,EAAE,sBAAsB;aAC9B,MAAM,EAAE,sBAAsB;aAC9B,WAAW,EAAE,4BAA4B;aACzC,WAAW,EAAE,4BAA4B;CACjC,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEvF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,iBAAiB,CAGrE;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,iBAAiB,GAAG,KAAK,MAAM,EAAE,CAEnE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAGrE"}
1
+ {"version":3,"file":"virtual-modules.d.ts","sourceRoot":"","sources":["../src/virtual-modules.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,eAAe;aAC1B,MAAM,EAAE,sBAAsB;aAC9B,GAAG,EAAE,mBAAmB;aACxB,MAAM,EAAE,sBAAsB;aAC9B,WAAW,EAAE,4BAA4B;aACzC,WAAW,EAAE,4BAA4B;CACjC,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEvF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,iBAAiB,CAGrE;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,iBAAiB,GAAG,KAAK,MAAM,EAAE,CAEnE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAGrE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moonsjs/vite",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
package/src/api.ts ADDED
@@ -0,0 +1,124 @@
1
+ import { parse } from "@babel/parser";
2
+ import { API_METHODS, MoonsError } from "@moonsjs/core";
3
+
4
+ /**
5
+ * Validasi statis export modul `src/api` (PRD Addendum D.1):
6
+ * hanya handler method `GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS` sebagai fungsi;
7
+ * `default`/export lain ditolak → `E_API_HANDLER_INVALID`.
8
+ */
9
+ export function assertApiModuleExports(code: string, file: string): string[] {
10
+ let ast: unknown;
11
+ try {
12
+ ast = parse(code, {
13
+ sourceType: "module",
14
+ plugins: file.endsWith(".tsx") ? ["typescript", "jsx"] : ["typescript"],
15
+ });
16
+ } catch {
17
+ return []; // biarkan bundler melaporkan syntax error
18
+ }
19
+
20
+ const program = (ast as { program?: { body?: Array<Record<string, unknown>> } }).program;
21
+ const body = program?.body ?? [];
22
+ const methods: string[] = [];
23
+
24
+ for (const statement of body) {
25
+ if (statement["type"] === "ExportDefaultDeclaration") {
26
+ throw apiError(
27
+ file,
28
+ "export `default` tidak didukung di modul API",
29
+ "Modul `src/api` hanya mengekspor handler method bernama (PRD Addendum D.1).",
30
+ ["Ganti menjadi `export const GET = (args) => …`", "Hapus export default"],
31
+ );
32
+ }
33
+ if (statement["type"] !== "ExportNamedDeclaration") {
34
+ continue;
35
+ }
36
+ if (statement["source"] !== undefined) {
37
+ // re-export `export { X } from "..."` — nama tetap dicek di bawah.
38
+ }
39
+ const declaration = statement["declaration"] as Record<string, unknown> | undefined;
40
+ if (declaration !== undefined) {
41
+ if (declaration["type"] === "VariableDeclaration") {
42
+ for (const declarator of (declaration["declarations"] ?? []) as Array<Record<string, unknown>>) {
43
+ const id = declarator["id"] as Record<string, unknown> | undefined;
44
+ if (id?.["type"] === "Identifier") {
45
+ methods.push(id["name"] as string);
46
+ }
47
+ }
48
+ } else if (declaration["type"] === "FunctionDeclaration") {
49
+ const id = declaration["id"] as Record<string, unknown> | undefined;
50
+ if (id?.["type"] === "Identifier") {
51
+ methods.push(id["name"] as string);
52
+ }
53
+ }
54
+ continue;
55
+ }
56
+ for (const specifier of (statement["specifiers"] ?? []) as Array<Record<string, unknown>>) {
57
+ const exported = specifier["exported"] as Record<string, unknown> | undefined;
58
+ if (exported?.["type"] === "Identifier") {
59
+ methods.push(exported["name"] as string);
60
+ }
61
+ }
62
+ }
63
+
64
+ const illegal = methods.filter((name) => !API_METHODS.includes(name as never));
65
+ if (illegal.length > 0) {
66
+ throw apiError(
67
+ file,
68
+ `export \`${illegal[0]}\` bukan handler method yang dikenal`,
69
+ `Handler yang legal: ${API_METHODS.join(", ")} (PRD Addendum D.1).`,
70
+ [
71
+ "Ganti nama export menjadi salah satu method HTTP",
72
+ "Pindahkan helper ke modul lain (mis. `src/server/…`)",
73
+ ],
74
+ );
75
+ }
76
+ if (methods.length === 0) {
77
+ throw apiError(
78
+ file,
79
+ "modul API tanpa handler method",
80
+ `Wajib ada minimal satu dari ${API_METHODS.join(", ")} (PRD Addendum D.1).`,
81
+ [`Tambahkan \`export const GET = (args) => new Response(…)\``],
82
+ );
83
+ }
84
+
85
+ return methods;
86
+ }
87
+
88
+ export function assertMiddlewareExports(code: string, file: string): void {
89
+ let ast: unknown;
90
+ try {
91
+ ast = parse(code, {
92
+ sourceType: "module",
93
+ plugins: file.endsWith(".tsx") ? ["typescript", "jsx"] : ["typescript"],
94
+ });
95
+ } catch {
96
+ return;
97
+ }
98
+ const program = (ast as { program?: { body?: Array<Record<string, unknown>> } }).program;
99
+ const hasDefault = (program?.body ?? []).some(
100
+ (statement) => statement["type"] === "ExportDefaultDeclaration",
101
+ );
102
+ if (!hasDefault) {
103
+ throw new MoonsError({
104
+ code: "E_MIDDLEWARE_INVALID",
105
+ file,
106
+ message: "`_middleware.ts` tanpa `export default`",
107
+ details: "Middleware direktori mengikuti bentuk `Middleware`: `(args) => Promise<Response>` (PRD Addendum D.3).",
108
+ suggestions: [
109
+ "Tambahkan `export default async ({ req, ctx, next }) => await next()`",
110
+ "Hapus file bila tidak dipakai",
111
+ ],
112
+ });
113
+ }
114
+ }
115
+
116
+ function apiError(file: string, message: string, details: string, suggestions: string[]): MoonsError {
117
+ return new MoonsError({
118
+ code: "E_API_HANDLER_INVALID",
119
+ file,
120
+ message,
121
+ details,
122
+ suggestions,
123
+ });
124
+ }