@moonsjs/vite 0.1.0 → 0.1.2

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.
@@ -132,7 +132,7 @@ function fromNullPrefixed(id) {
132
132
  // src/server/dev.ts
133
133
  function installDevMiddleware2(server, options) {
134
134
  server.middlewares.use((req, res, next) => {
135
- if (!isHtmlRequest(req)) {
135
+ if (!shouldHandle(req)) {
136
136
  next();
137
137
  return;
138
138
  }
@@ -149,11 +149,14 @@ function handleRequest(server, options) {
149
149
  await sendNodeResponse2(res, response);
150
150
  };
151
151
  }
152
- function isHtmlRequest(req) {
152
+ function shouldHandle(req) {
153
+ const path = new URL(req.url ?? "/", "http://localhost").pathname;
154
+ if (path.startsWith("/_moons/fn/")) {
155
+ return true;
156
+ }
153
157
  if (req.method !== "GET" && req.method !== "HEAD") {
154
158
  return false;
155
159
  }
156
- const path = new URL(req.url ?? "/", "http://localhost").pathname;
157
160
  if (path.startsWith("/@") || path.startsWith("/node_modules/") || path.startsWith("/__")) {
158
161
  return false;
159
162
  }
@@ -219,4 +222,4 @@ function rootSpecifier(projectRoot, file) {
219
222
 
220
223
  export { NOT_FOUND_ROUTE_KEY, ERROR_ROUTE_KEY, renderRoutesModule, rootSpecifier, VIRTUAL_MODULES, fromNullPrefixed, ROOT_PLACEHOLDER2, DEFAULT_TEMPLATE2, injectShell2, createDevShell2, createFileShell2, toWebRequest2, sendNodeResponse2, installDevMiddleware2 };
221
224
 
222
- //# debugId=47C888724E7211AE64756E2164756E21
225
+ //# debugId=6E6FBA2917FCE4BD64756E2164756E21
@@ -5,10 +5,10 @@
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 = (markup: string, payload: string, url: string) => string | Promise<string>;\n\nexport const ROOT_PLACEHOLDER = '<div id=\"root\"></div>';\n\nexport const DEFAULT_TEMPLATE = [\n \"<!doctype html>\",\n '<html lang=\"id\">',\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). */\nexport function injectShell(template: string, markup: string, payload: string): string {\n if (!template.includes(ROOT_PLACEHOLDER)) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n message: `shell HTML tidak memuat \\`${ROOT_PLACEHOLDER}\\``,\n details: \"index.html aplikasi wajib memuat elemen root tersebut agar SSR bisa meng-inject markup.\",\n suggestions: [\n `Tambahkan ${ROOT_PLACEHOLDER} ke index.html`,\n \"Atau hapus index.html untuk memakai shell bawaan\",\n ],\n });\n }\n const dataScript = `<script id=\"__moons_data\" type=\"application/x-moons\">${payload}</script>`;\n return template.replace(ROOT_PLACEHOLDER, `<div id=\"root\">${markup}</div>${dataScript}`);\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) => {\n const template = existsSync(options.templatePath)\n ? readFileSync(options.templatePath, \"utf8\")\n : DEFAULT_TEMPLATE;\n const html = injectShell(template, markup, payload);\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) => {\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` tidak ditemukan\",\n details: \"Build client harus dijalankan sebelum server produksi dinyalakan (PRD §18).\",\n suggestions: [\"Jalankan `bun run build` lebih dulu\"],\n });\n }\n cached = readFileSync(file, \"utf8\");\n }\n return injectShell(cached, markup, payload);\n };\n}\n",
6
6
  "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nconst MAX_BODY_BYTES = 32 * 1024 * 1024; // batas defensif transport; limit RPC §7.3 tetap berlaku\n\n/** Konversi request Node → Web `Request` (body diteruskan untuk non-GET/HEAD, §7.3). */\nexport async function toWebRequest(req: IncomingMessage): Promise<Request> {\n const host = req.headers.host ?? \"localhost\";\n const url = `http://${host}${req.url ?? \"/\"}`;\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\") {\n // content-length tidak disalin; fetch menghitung ulang dari body.\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 if (method === \"GET\" || method === \"HEAD\") {\n return new Request(url, { method, headers });\n }\n\n const body = await readBody(req);\n return new Request(url, { method, headers, body: new Uint8Array(body) });\n}\n\nfunction readBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolvePromise, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n\n req.on(\"data\", (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_BODY_BYTES) {\n req.destroy();\n reject(new Error(\"request body melebihi batas transport\"));\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => resolvePromise(Buffer.concat(chunks)));\n req.on(\"error\", (error) => reject(error));\n });\n}\n\n/** Tulis Web `Response` ke `ServerResponse` Node. */\nexport async function sendNodeResponse(res: ServerResponse, response: Response): Promise<void> {\n res.statusCode = response.status;\n response.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n const body = Buffer.from(await response.arrayBuffer());\n res.end(body);\n}\n",
7
7
  "/** Nama virtual module PRD §9.4. Semua di-resolve ke id `\\0`-prefix. */\nexport const VIRTUAL_MODULES = {\n routes: \"virtual:moons/routes\",\n config: \"virtual:moons/config\",\n clientEntry: \"virtual:moons/client-entry\",\n serverEntry: \"virtual:moons/server-entry\",\n} as const;\n\nexport type VirtualModuleName = (typeof VIRTUAL_MODULES)[keyof typeof VIRTUAL_MODULES];\n\nexport function isVirtualModuleId(id: string): id is VirtualModuleName {\n const clean = id.startsWith(\"\\0\") ? id.slice(1) : id;\n return (Object.values(VIRTUAL_MODULES) as string[]).includes(clean);\n}\n\nexport function toNullPrefixed(id: VirtualModuleName): `\\0${string}` {\n return `\\0${id}`;\n}\n\nexport function fromNullPrefixed(id: string): VirtualModuleName | null {\n const clean = id.startsWith(\"\\0\") ? id.slice(1) : id;\n return isVirtualModuleId(clean) ? (clean as VirtualModuleName) : null;\n}\n",
8
- "import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { ViteDevServer } from \"vite\";\nimport { VIRTUAL_MODULES } from \"../virtual-modules\";\nimport type { Shell } from \"./shell\";\nimport { createDevShell } from \"./shell\";\nimport { sendNodeResponse, toWebRequest } from \"./node\";\n\ntype DevServerEntry = {\n createDevHandler: (shell: Shell) => (request: Request) => Promise<Response>;\n};\n\n/**\n * Middleware SSR dev: dipasang sebelum middleware internal Vite, hanya\n * menangani request HTML (modul/aset tetap dilayani Vite).\n */\nexport function installDevMiddleware(\n server: ViteDevServer,\n options: { templatePath: string },\n): void {\n server.middlewares.use((req, res, next) => {\n if (!isHtmlRequest(req)) {\n next();\n return;\n }\n void handleRequest(server, options)(req, res).catch((error: unknown) => {\n next(error as Error);\n });\n });\n}\n\nfunction handleRequest(server: ViteDevServer, options: { templatePath: string }) {\n return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const entry = (await server.ssrLoadModule(VIRTUAL_MODULES.serverEntry)) as DevServerEntry;\n const handler = entry.createDevHandler(createDevShell(server, options));\n const response = await handler(await toWebRequest(req));\n await sendNodeResponse(res, response);\n };\n}\n\nfunction isHtmlRequest(req: IncomingMessage): boolean {\n if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n return false;\n }\n const path = new URL(req.url ?? \"/\", \"http://localhost\").pathname;\n if (path.startsWith(\"/@\") || path.startsWith(\"/node_modules/\") || path.startsWith(\"/__\")) {\n return false;\n }\n const lastSegment = path.split(\"/\").pop() ?? \"\";\n if (lastSegment.includes(\".\")) {\n return false;\n }\n const accept = req.headers.accept ?? \"\";\n return accept.includes(\"text/html\") || accept.includes(\"*/*\");\n}\n",
8
+ "import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { ViteDevServer } from \"vite\";\nimport { VIRTUAL_MODULES } from \"../virtual-modules\";\nimport type { Shell } from \"./shell\";\nimport { createDevShell } from \"./shell\";\nimport { sendNodeResponse, toWebRequest } from \"./node\";\n\ntype DevServerEntry = {\n createDevHandler: (shell: Shell) => (request: Request) => Promise<Response>;\n};\n\n/**\n * Middleware SSR dev: dipasang sebelum middleware internal Vite, menangani\n * request HTML dan RPC serverFn (`/_moons/fn/*`) — modul/aset tetap Vite.\n */\nexport function installDevMiddleware(\n server: ViteDevServer,\n options: { templatePath: string },\n): void {\n server.middlewares.use((req, res, next) => {\n if (!shouldHandle(req)) {\n next();\n return;\n }\n void handleRequest(server, options)(req, res).catch((error: unknown) => {\n next(error as Error);\n });\n });\n}\n\nfunction handleRequest(server: ViteDevServer, options: { templatePath: string }) {\n return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const entry = (await server.ssrLoadModule(VIRTUAL_MODULES.serverEntry)) as DevServerEntry;\n const handler = entry.createDevHandler(createDevShell(server, options));\n const response = await handler(await toWebRequest(req));\n await sendNodeResponse(res, response);\n };\n}\n\nfunction shouldHandle(req: IncomingMessage): boolean {\n const path = new URL(req.url ?? \"/\", \"http://localhost\").pathname;\n\n // RPC serverFn (semua method): dulu hanya GET/HEAD HTML yang dirutekan,\n // sehingga `POST /_moons/fn/<hash>` jatuh ke Vite (\"Cannot POST\", 404) dan\n // serverFn tidak bisa dipakai di dev (temuan eval T2 ronde 2; decisions/0016).\n if (path.startsWith(\"/_moons/fn/\")) {\n return true;\n }\n\n if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n return false;\n }\n if (path.startsWith(\"/@\") || path.startsWith(\"/node_modules/\") || path.startsWith(\"/__\")) {\n return false;\n }\n const lastSegment = path.split(\"/\").pop() ?? \"\";\n if (lastSegment.includes(\".\")) {\n return false;\n }\n const accept = req.headers.accept ?? \"\";\n return accept.includes(\"text/html\") || accept.includes(\"*/*\");\n}\n",
9
9
  "import { findLayouts, routeKeyFromFile, 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\n return manifest;\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. Jangan diubah manual.\",\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"
10
10
  ],
11
- "mappings": "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",
12
- "debugId": "47C888724E7211AE64756E2164756E21",
11
+ "mappings": "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",
12
+ "debugId": "6E6FBA2917FCE4BD64756E2164756E21",
13
13
  "names": []
14
14
  }
@@ -1,6 +1,6 @@
1
1
  // src/transform.ts
2
2
  import { MoonsError, computeFnHash, fnRegistryKey } from "@moonsjs/core";
3
- import { parse } from "@babel/parser";
3
+ import { parse, parseExpression } from "@babel/parser";
4
4
  import { existsSync, readdirSync, readFileSync, realpathSync } from "node:fs";
5
5
  import { dirname, isAbsolute, join, resolve } from "node:path";
6
6
  var SERVER_SPECIFIER = /\.server(\.(ts|tsx|js|jsx|mts|cts|mjs|cjs))?$/i;
@@ -214,9 +214,94 @@ function isUsed(name, retainedText) {
214
214
  function escapeRegExp(text) {
215
215
  return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
216
216
  }
217
+ function collectPatternNames(node, into) {
218
+ if (node === undefined) {
219
+ return;
220
+ }
221
+ switch (node.type) {
222
+ case "Identifier": {
223
+ const name = node["name"];
224
+ if (name !== undefined) {
225
+ into.add(name);
226
+ }
227
+ return;
228
+ }
229
+ case "ObjectPattern":
230
+ for (const property of node["properties"] ?? []) {
231
+ collectPatternNames(property.type === "RestElement" ? property["argument"] : property["value"], into);
232
+ }
233
+ return;
234
+ case "ArrayPattern":
235
+ for (const element of node["elements"] ?? []) {
236
+ collectPatternNames(element, into);
237
+ }
238
+ return;
239
+ case "AssignmentPattern":
240
+ collectPatternNames(node["left"], into);
241
+ return;
242
+ case "RestElement":
243
+ collectPatternNames(node["argument"], into);
244
+ return;
245
+ default:
246
+ return;
247
+ }
248
+ }
249
+ function localTopLevelNames(ast) {
250
+ const names = new Set;
251
+ const declare = (decl) => {
252
+ if (decl === undefined || decl === null) {
253
+ return;
254
+ }
255
+ if (decl.type === "VariableDeclaration") {
256
+ for (const declarator of decl["declarations"] ?? []) {
257
+ collectPatternNames(declarator["id"], names);
258
+ }
259
+ return;
260
+ }
261
+ if (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration") {
262
+ const name = decl["id"]?.["name"] ?? "";
263
+ if (name.length > 0) {
264
+ names.add(name);
265
+ }
266
+ }
267
+ };
268
+ for (const statement of topLevelStatements(ast)) {
269
+ if (statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration") {
270
+ declare(statement["declaration"]);
271
+ } else {
272
+ declare(statement);
273
+ }
274
+ }
275
+ return names;
276
+ }
277
+ function referencedIdentifiers(expression, filename) {
278
+ const ast = parseExpression(expression, {
279
+ plugins: filename.endsWith(".tsx") ? ["typescript", "jsx"] : ["typescript"]
280
+ });
281
+ const names = new Set;
282
+ walk(ast, (node, ancestors) => {
283
+ if (node.type !== "Identifier") {
284
+ return;
285
+ }
286
+ const parent = ancestors[ancestors.length - 1];
287
+ if (parent !== undefined) {
288
+ const parentType = parent.type;
289
+ const nonComputed = parent["computed"] !== true;
290
+ if (nonComputed && (parentType === "MemberExpression" || parentType === "OptionalMemberExpression") && parent["property"] === node) {
291
+ return;
292
+ }
293
+ if (nonComputed && (parentType === "ObjectProperty" || parentType === "ObjectMethod" || parentType === "ClassProperty" || parentType === "TSPropertySignature") && parent["key"] === node) {
294
+ return;
295
+ }
296
+ }
297
+ names.add(node["name"] ?? "");
298
+ });
299
+ return names;
300
+ }
217
301
  function renderServerFnStub2(source, filename, analysis, dependencies) {
218
302
  const ast = parseModule(source, filename);
219
303
  const retainedText = collectRetainedText(source, analysis);
304
+ const localNames = localTopLevelNames(ast);
220
305
  const importLines = [];
221
306
  const referenced = [];
222
307
  let needsCreateStub = analysis.serverFns.length > 0;
@@ -266,6 +351,28 @@ function renderServerFnStub2(source, filename, analysis, dependencies) {
266
351
  for (const fn of analysis.serverFns) {
267
352
  const input = source.slice(fn.input.start, fn.input.end);
268
353
  const output = source.slice(fn.output.start, fn.output.end);
354
+ for (const [kind, slice] of [
355
+ ["input", input],
356
+ ["output", output]
357
+ ]) {
358
+ for (const reference of referencedIdentifiers(slice, filename)) {
359
+ if (reference.length === 0 || !localNames.has(reference)) {
360
+ continue;
361
+ }
362
+ throw new MoonsError({
363
+ code: "E_SCHEMA_LOCAL_REF",
364
+ file: filename,
365
+ line: fn.line,
366
+ annotation: fn.name,
367
+ message: `schema ${kind} serverFn \`${fn.name}\` merujuk deklarasi lokal \`${reference}\``,
368
+ details: "Stub client (PRD §12.2/§12.3) hanya membawa import dan ekspresi schema; " + "deklarasi lokal dibuang sehingga referensi menjadi `undefined` di browser (crash hydration).",
369
+ suggestions: [
370
+ "Inline schema langsung di argumen `serverFn({ input, output })`, atau",
371
+ "Impor schema dari modul lain (mis. `src/shared/schemas.ts`)"
372
+ ]
373
+ });
374
+ }
375
+ }
269
376
  exportLines.push(`export const ${fn.name} = __moons_createStub({ hash: ${JSON.stringify(fn.hash)}, input: ${input}, output: ${output} });`);
270
377
  }
271
378
  for (const reExport of analysis.reExports) {
@@ -409,7 +516,7 @@ async function checkClientModuleImports2(context) {
409
516
  details,
410
517
  suggestions: [
411
518
  "Buat server function yang mengembalikan data yang dibutuhkan, atau",
412
- "Pindahkan nilai itu ke file yang tidak berakhiran .server.ts"
519
+ "Jika nilainya memang publik, definisikan ulang konstanta itu di modul yang boleh masuk client (jangan memindahkan nilai rahasia)"
413
520
  ]
414
521
  });
415
522
  };
@@ -773,4 +880,4 @@ function buildFnRegistry2(projectRoot, files) {
773
880
 
774
881
  export { isServerFilePath2, isNonContractServerFile2, isServerSpecifier2, resolveServerSpecifierSync2, stripQuery2, analyzeServerFile2, serverFnExportNames2, renderServerFnStub2, injectServerFnMeta2, nonContractServerFileError2, checkClientModuleImports2, checkRouteModuleExports2, scanServerFiles2, buildFnRegistry2 };
775
882
 
776
- //# debugId=A2B4D23CAFD2B11164756E2164756E21
883
+ //# debugId=6E8CE67B8B7578C064756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/transform.ts"],
4
+ "sourcesContent": [
5
+ "import { MoonsError, computeFnHash, fnRegistryKey } from \"@moonsjs/core\";\nimport { parse, parseExpression } from \"@babel/parser\";\nimport { existsSync, readdirSync, readFileSync, realpathSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\n\n/**\n * Spec §12: analisis `.server.ts` + stub client + injeksi meta server +\n * penolakan import (E_SERVER_IMPORT_IN_CLIENT / E_FORBIDDEN_SERVER_IMPORT).\n */\n\nexport interface ServerFnInfo {\n name: string;\n hash: string;\n line: number;\n input: { start: number; end: number };\n output: { start: number; end: number };\n objectStart: number;\n}\n\nexport interface ServerFileAnalysis {\n /** Absolute path. */\n file: string;\n serverFns: ServerFnInfo[];\n /** Semua nama export top-level (langsung). */\n exportNames: string[];\n /** Pernyataan `export { X as Y } from \"./z.server\"` (untuk resolusi re-export). */\n reExports: Array<{ source: string; names: Array<{ local: string; exported: string }> }>;\n /** `export * from \"./z.server\"`. */\n exportAllFrom: string[];\n}\n\ninterface AstNode {\n type: string;\n start: number | null;\n end: number | null;\n loc?: { start: { line: number } } | null;\n [key: string]: unknown;\n}\n\nconst SERVER_SPECIFIER = /\\.server(\\.(ts|tsx|js|jsx|mts|cts|mjs|cjs))?$/i;\nconst CONTRACT_SERVER_FILE = /\\.server\\.(ts|tsx)$/i;\nconst NON_CONTRACT_SERVER_FILE = /\\.server\\.(js|jsx|mts|cts|mjs|cjs)$/i;\n\nexport function isServerFilePath(path: string): boolean {\n return CONTRACT_SERVER_FILE.test(stripQuery(path));\n}\n\n/** File server dengan ekstensi di luar kontrak §12 (tidak bisa di-stub). */\nexport function isNonContractServerFile(path: string): boolean {\n return NON_CONTRACT_SERVER_FILE.test(stripQuery(path));\n}\n\nexport function isServerSpecifier(specifier: string): boolean {\n return SERVER_SPECIFIER.test(specifier);\n}\n\n/**\n * Resolusi sinkron untuk specifier `*.server` (relatif/absolut).\n * Import alias/virtual untuk file server tidak didukung — tidak dibutuhkan app.\n */\nexport function resolveServerSpecifierSync(importerFile: string, specifier: string): string | null {\n if (!isServerSpecifier(specifier)) {\n return null;\n }\n const base = specifier.startsWith(\".\")\n ? resolve(dirname(importerFile), specifier)\n : isAbsolute(specifier)\n ? specifier\n : null;\n if (base === null) {\n return null;\n }\n for (const candidate of [base, `${base}.ts`, `${base}.tsx`]) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n return null;\n}\n\nexport function stripQuery(id: string): string {\n const queryIndex = id.indexOf(\"?\");\n return queryIndex === -1 ? id : id.slice(0, queryIndex);\n}\n\nfunction parseModule(code: string, filename: string): AstNode {\n return parse(code, {\n sourceType: \"module\",\n plugins: filename.endsWith(\".tsx\") ? [\"typescript\", \"jsx\"] : [\"typescript\"],\n errorRecovery: false,\n }) as unknown as AstNode;\n}\n\nfunction walk(\n node: unknown,\n visit: (node: AstNode, ancestors: AstNode[]) => void,\n ancestors: AstNode[] = [],\n): void {\n if (node === null || typeof node !== \"object\") {\n return;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n walk(item, visit, ancestors);\n }\n return;\n }\n const candidate = node as AstNode;\n if (typeof candidate.type !== \"string\" || typeof candidate.start !== \"number\") {\n return;\n }\n visit(candidate, ancestors);\n const nextAncestors = [...ancestors, candidate];\n for (const key of Object.keys(candidate)) {\n if (key === \"loc\" || key === \"start\" || key === \"end\" || key === \"extra\") {\n continue;\n }\n walk(candidate[key], visit, nextAncestors);\n }\n}\n\nfunction topLevelStatements(ast: AstNode): AstNode[] {\n const program = ast[\"program\"] as { body?: AstNode[] } | undefined;\n return program?.body ?? [];\n}\n\nfunction keyName(node: unknown): string | null {\n const key = node as AstNode | undefined;\n if (key?.type === \"Identifier\") {\n return key[\"name\"] as string;\n }\n if (key?.type === \"StringLiteral\") {\n return key[\"value\"] as string;\n }\n return null;\n}\n\nfunction extractServerFnInit(init: unknown): {\n input: { start: number; end: number };\n output: { start: number; end: number };\n line: number;\n objectStart: number;\n} | null {\n const call = init as AstNode | undefined;\n if (call?.type !== \"CallExpression\") {\n return null;\n }\n const callee = call[\"callee\"] as AstNode | undefined;\n if (callee?.type !== \"Identifier\" || callee[\"name\"] !== \"serverFn\") {\n return null;\n }\n const args = (call[\"arguments\"] ?? []) as AstNode[];\n const first = args[0];\n if (first?.type !== \"ObjectExpression\") {\n return null;\n }\n\n const properties = new Map<string, AstNode>();\n for (const property of (first[\"properties\"] ?? []) as AstNode[]) {\n if (property.type !== \"ObjectProperty\") {\n continue;\n }\n const name = keyName(property[\"key\"]);\n if (name !== null) {\n properties.set(name, property);\n }\n }\n\n const input = properties.get(\"input\")?.[\"value\"] as AstNode | undefined;\n const output = properties.get(\"output\")?.[\"value\"] as AstNode | undefined;\n if (\n input?.start == null ||\n input.end == null ||\n output?.start == null ||\n output.end == null\n ) {\n return null;\n }\n\n return {\n input: { start: input.start, end: input.end },\n output: { start: output.start, end: output.end },\n line: call.loc?.start.line ?? 1,\n objectStart: first.start ?? 0,\n };\n}\n\nexport function analyzeServerFile(\n source: string,\n filename: string,\n projectRoot: string,\n): ServerFileAnalysis {\n const ast = parseModule(source, filename);\n const serverFns: ServerFnInfo[] = [];\n const exportNames: string[] = [];\n const reExports: ServerFileAnalysis[\"reExports\"] = [];\n const exportAllFrom: string[] = [];\n\n for (const statement of topLevelStatements(ast)) {\n if (statement.type === \"ExportNamedDeclaration\") {\n const declaration = statement[\"declaration\"] as AstNode | null | undefined;\n\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of (declaration[\"declarations\"] ?? []) as AstNode[]) {\n const id = declarator[\"id\"] as AstNode | undefined;\n if (id?.type !== \"Identifier\") {\n continue;\n }\n const name = id[\"name\"] as string;\n exportNames.push(name);\n const info = extractServerFnInit(declarator[\"init\"]);\n if (info !== null) {\n serverFns.push({\n name,\n hash: computeFnHash(projectRoot, filename, name),\n line: info.line,\n input: info.input,\n output: info.output,\n objectStart: info.objectStart,\n });\n }\n }\n } else if (declaration?.type === \"FunctionDeclaration\") {\n const id = declaration[\"id\"] as AstNode | undefined;\n if (id?.type === \"Identifier\") {\n exportNames.push(id[\"name\"] as string);\n }\n }\n\n for (const specifier of (statement[\"specifiers\"] ?? []) as AstNode[]) {\n const exported = specifier[\"exported\"] as AstNode | undefined;\n if (exported?.type === \"Identifier\") {\n exportNames.push(exported[\"name\"] as string);\n }\n }\n\n const sourceNode = statement[\"source\"] as AstNode | undefined;\n if (sourceNode?.type === \"StringLiteral\" && isServerSpecifier(sourceNode[\"value\"] as string)) {\n reExports.push({\n source: sourceNode[\"value\"] as string,\n names: ((statement[\"specifiers\"] ?? []) as AstNode[]).map((specifier) => ({\n local: ((specifier[\"local\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\",\n exported: (((specifier[\"exported\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\"),\n })),\n });\n }\n } else if (statement.type === \"ExportDefaultDeclaration\") {\n exportNames.push(\"default\");\n } else if (statement.type === \"ExportAllDeclaration\") {\n const sourceNode = statement[\"source\"] as AstNode | undefined;\n if (sourceNode?.type === \"StringLiteral\" && isServerSpecifier(sourceNode[\"value\"] as string)) {\n exportAllFrom.push(sourceNode[\"value\"] as string);\n }\n }\n }\n\n return { file: filename, serverFns, exportNames, reExports, exportAllFrom };\n}\n\n/** Nama-nama yang diekspor sebagai serverFn stub dari file (langsung atau via re-export). */\nexport function serverFnExportNames(\n analysis: ServerFileAnalysis,\n analyzeTarget: (specifier: string) => ServerFileAnalysis | null,\n seen = new Set<string>(),\n): Set<string> {\n const names = new Set(analysis.serverFns.map((fn) => fn.name));\n\n for (const reExport of analysis.reExports) {\n const target = analyzeTarget(reExport.source);\n if (target === null || seen.has(reExport.source)) {\n continue;\n }\n seen.add(reExport.source);\n const targetNames = serverFnExportNames(target, analyzeTarget, seen);\n for (const { local, exported } of reExport.names) {\n if (local === \"*\" || targetNames.has(local)) {\n names.add(exported);\n }\n }\n }\n\n for (const specifier of analysis.exportAllFrom) {\n const target = analyzeTarget(specifier);\n if (target === null || seen.has(specifier)) {\n continue;\n }\n seen.add(specifier);\n for (const name of serverFnExportNames(target, analyzeTarget, seen)) {\n names.add(name);\n }\n }\n\n return names;\n}\n\nfunction collectRetainedText(source: string, analysis: ServerFileAnalysis): string {\n return analysis.serverFns\n .map((fn) => `${source.slice(fn.input.start, fn.input.end)}\\n${source.slice(fn.output.start, fn.output.end)}`)\n .join(\"\\n\");\n}\n\nfunction isUsed(name: string, retainedText: string): boolean {\n return new RegExp(`(^|[^\\\\w$])${escapeRegExp(name)}([^\\\\w$]|$)`).test(retainedText);\n}\n\nfunction escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction collectPatternNames(node: AstNode | undefined, into: Set<string>): void {\n if (node === undefined) {\n return;\n }\n switch (node.type) {\n case \"Identifier\": {\n const name = node[\"name\"] as string | undefined;\n if (name !== undefined) {\n into.add(name);\n }\n return;\n }\n case \"ObjectPattern\":\n for (const property of (node[\"properties\"] ?? []) as AstNode[]) {\n collectPatternNames(\n (property.type === \"RestElement\" ? property[\"argument\"] : property[\"value\"]) as\n | AstNode\n | undefined,\n into,\n );\n }\n return;\n case \"ArrayPattern\":\n for (const element of (node[\"elements\"] ?? []) as AstNode[]) {\n collectPatternNames(element, into);\n }\n return;\n case \"AssignmentPattern\":\n collectPatternNames(node[\"left\"] as AstNode | undefined, into);\n return;\n case \"RestElement\":\n collectPatternNames(node[\"argument\"] as AstNode | undefined, into);\n return;\n default:\n return;\n }\n}\n\n/** Nama deklarasi nilai top-level (bukan import) — yang DIBUANG dari stub §12.3. */\nfunction localTopLevelNames(ast: AstNode): Set<string> {\n const names = new Set<string>();\n const declare = (decl: AstNode | null | undefined): void => {\n if (decl === undefined || decl === null) {\n return;\n }\n if (decl.type === \"VariableDeclaration\") {\n for (const declarator of (decl[\"declarations\"] ?? []) as AstNode[]) {\n collectPatternNames(declarator[\"id\"] as AstNode | undefined, names);\n }\n return;\n }\n if (decl.type === \"FunctionDeclaration\" || decl.type === \"ClassDeclaration\") {\n const name = ((decl[\"id\"] as AstNode | undefined)?.[\"name\"] as string | undefined) ?? \"\";\n if (name.length > 0) {\n names.add(name);\n }\n }\n };\n\n for (const statement of topLevelStatements(ast)) {\n if (statement.type === \"ExportNamedDeclaration\" || statement.type === \"ExportDefaultDeclaration\") {\n declare(statement[\"declaration\"] as AstNode | null | undefined);\n } else {\n declare(statement);\n }\n }\n return names;\n}\n\n/** Identifier posisi-nilai yang direferensikan di dalam ekspresi (key/member di-skip). */\nfunction referencedIdentifiers(expression: string, filename: string): Set<string> {\n const ast = parseExpression(expression, {\n plugins: filename.endsWith(\".tsx\") ? [\"typescript\", \"jsx\"] : [\"typescript\"],\n }) as unknown as AstNode;\n const names = new Set<string>();\n\n walk(ast, (node, ancestors) => {\n if (node.type !== \"Identifier\") {\n return;\n }\n const parent = ancestors[ancestors.length - 1];\n if (parent !== undefined) {\n const parentType = parent.type as string;\n const nonComputed = parent[\"computed\"] !== true;\n if (\n nonComputed &&\n (parentType === \"MemberExpression\" || parentType === \"OptionalMemberExpression\") &&\n parent[\"property\"] === node\n ) {\n return;\n }\n if (\n nonComputed &&\n (parentType === \"ObjectProperty\" ||\n parentType === \"ObjectMethod\" ||\n parentType === \"ClassProperty\" ||\n parentType === \"TSPropertySignature\") &&\n parent[\"key\"] === node\n ) {\n return;\n }\n }\n names.add((node[\"name\"] as string | undefined) ?? \"\");\n });\n\n return names;\n}\n\nexport interface StubDependencies {\n /** Resolve specifier relatif file sumber → analysis (null bila tidak bisa). */\n analyzeSpecifier: (sourceFile: string, specifier: string) => ServerFileAnalysis | null;\n}\n\nexport interface RenderStubResult {\n code: string;\n /** Specifier server file yang di-referensikan (untuk keperluan cache/diagnostik). */\n referenced: string[];\n}\n\n/**\n * Bangun stub client §12.2/§12.3 dari sumber `.server.ts`:\n * hanya import yang dipakai schema + `__moons_createStub` per serverFn.\n */\nexport function renderServerFnStub(\n source: string,\n filename: string,\n analysis: ServerFileAnalysis,\n dependencies: StubDependencies,\n): RenderStubResult {\n const ast = parseModule(source, filename);\n const retainedText = collectRetainedText(source, analysis);\n const localNames = localTopLevelNames(ast);\n const importLines: string[] = [];\n const referenced: string[] = [];\n let needsCreateStub = analysis.serverFns.length > 0;\n\n for (const statement of topLevelStatements(ast)) {\n if (statement.type !== \"ImportDeclaration\") {\n continue;\n }\n const sourceNode = statement[\"source\"] as AstNode;\n const specifier = sourceNode[\"value\"] as string;\n\n if (/^@moons\\/server(\\/|$)/.test(specifier)) {\n continue; // serverFn/env tidak dibawa ke client (§12.2)\n }\n if (specifier.startsWith(\"node:\") || specifier.startsWith(\"bun:\")) {\n continue; // import server-only dibuang\n }\n\n const specifiers = (statement[\"specifiers\"] ?? []) as AstNode[];\n const kept: AstNode[] = [];\n\n if (isServerSpecifier(specifier)) {\n referenced.push(specifier);\n for (const item of specifiers) {\n if (item.type === \"ImportDefaultSpecifier\" || item.type === \"ImportNamespaceSpecifier\") {\n continue; // default / * as dari *.server → dibuang (§12.2)\n }\n const local = ((item[\"local\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\";\n if (local.length > 0 && isUsed(local, retainedText)) {\n kept.push(item);\n }\n }\n } else {\n for (const item of specifiers) {\n const local = ((item[\"local\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\";\n if (local.length > 0 && isUsed(local, retainedText)) {\n kept.push(item);\n }\n }\n }\n\n if (kept.length === 0) {\n continue; // import tak terpakai → dipangkas (§12.3)\n }\n\n const keptText = kept\n .map((item) => source.slice(item.start ?? 0, item.end ?? 0))\n .join(\", \");\n importLines.push(`import { ${keptText} } from ${JSON.stringify(specifier)};`);\n }\n\n if (needsCreateStub) {\n importLines.push('import { __moons_createStub } from \"@moonsjs/server/client\";');\n }\n\n const exportLines: string[] = [];\n for (const fn of analysis.serverFns) {\n const input = source.slice(fn.input.start, fn.input.end);\n const output = source.slice(fn.output.start, fn.output.end);\n\n // E_SCHEMA_LOCAL_REF: deklarasi lokal dibuang dari stub, jadi referensinya\n // menjadi `undefined` di browser (crash hydration — dulu lolos build).\n for (const [kind, slice] of [\n [\"input\", input],\n [\"output\", output],\n ] as const) {\n for (const reference of referencedIdentifiers(slice, filename)) {\n if (reference.length === 0 || !localNames.has(reference)) {\n continue;\n }\n throw new MoonsError({\n code: \"E_SCHEMA_LOCAL_REF\",\n file: filename,\n line: fn.line,\n annotation: fn.name,\n message: `schema ${kind} serverFn \\`${fn.name}\\` merujuk deklarasi lokal \\`${reference}\\``,\n details:\n \"Stub client (PRD §12.2/§12.3) hanya membawa import dan ekspresi schema; \" +\n \"deklarasi lokal dibuang sehingga referensi menjadi `undefined` di browser (crash hydration).\",\n suggestions: [\n \"Inline schema langsung di argumen `serverFn({ input, output })`, atau\",\n \"Impor schema dari modul lain (mis. `src/shared/schemas.ts`)\",\n ],\n });\n }\n }\n\n exportLines.push(\n `export const ${fn.name} = __moons_createStub({ hash: ${JSON.stringify(fn.hash)}, input: ${input}, output: ${output} });`,\n );\n }\n\n for (const reExport of analysis.reExports) {\n const target = dependencies.analyzeSpecifier(filename, reExport.source);\n if (target === null) {\n throw new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: filename,\n message: `tidak bisa me-resolve \\`${reExport.source}\\` untuk re-export`,\n details: \"Re-export dari `*.server.ts` harus bisa di-resolve statis (PRD §12.6).\",\n suggestions: [\"Perbaiki path re-export\", \"Hindari re-export dinamis dari file server\"],\n });\n }\n const targetNames = serverFnExportNames(target, (specifier) =>\n dependencies.analyzeSpecifier(filename, specifier),\n );\n const keptNames = reExport.names.filter(({ local }) => local !== \"\" && targetNames.has(local));\n if (keptNames.length > 0) {\n const specifiers = keptNames\n .map(({ local, exported }) => (local === exported ? local : `${local} as ${exported}`))\n .join(\", \");\n exportLines.push(`export { ${specifiers} } from ${JSON.stringify(reExport.source)};`);\n }\n }\n\n for (const specifier of analysis.exportAllFrom) {\n const target = dependencies.analyzeSpecifier(filename, specifier);\n if (target === null) {\n throw new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: filename,\n message: `\\`export *\\` dari \\`${specifier}\\` tidak bisa di-resolve`,\n details: \"`export *` dari `*.server.ts` wajib bisa di-expand statis (PRD §12.6).\",\n suggestions: [\"Perbaiki path re-export\", \"Ganti menjadi named re-export\"],\n });\n }\n const targetNames = serverFnExportNames(target, (nested) =>\n dependencies.analyzeSpecifier(filename, nested),\n );\n if (targetNames.size > 0) {\n exportLines.push(\n `export { ${[...targetNames].join(\", \")} } from ${JSON.stringify(specifier)};`,\n );\n }\n }\n\n if (importLines.length === 0 && exportLines.length === 0) {\n return { code: \"// @moons: tidak ada serverFn yang di-export\\nexport {};\\n\", referenced };\n }\n\n return { code: `${[...importLines, \"\", ...exportLines].join(\"\\n\")}\\n`, referenced };\n}\n\n/** Inject meta §7.2 ke deklarasi serverFn (env ssr; handler tetap utuh). */\nexport function injectServerFnMeta(\n source: string,\n analysis: ServerFileAnalysis,\n projectRoot: string,\n): string {\n let output = source;\n const inserts = [...analysis.serverFns].sort((a, b) => b.objectStart - a.objectStart);\n\n for (const fn of inserts) {\n const meta =\n ` __hash: ${JSON.stringify(fn.hash)},` +\n ` __file: ${JSON.stringify(fnRegistryKey(projectRoot, analysis.file, fn.name).split(\"#\")[0] as string)},` +\n ` __line: ${fn.line},` +\n ` __exportName: ${JSON.stringify(fn.name)},`;\n const at = fn.objectStart + 1;\n output = output.slice(0, at) + meta + output.slice(at);\n }\n\n return output;\n}\n\nexport interface ClientImportCheckContext {\n /** Absolute path file yang sedang diperiksa. */\n file: string;\n code: string;\n projectRoot: string;\n /**\n * Resolve specifier dengan importer tertentu → absolute path (null bila tidak\n * ada). Boleh sinkron maupun async (plugin memakai `this.resolve`, sehingga\n * alias Vite & `tsconfig paths` ikut terperiksa — audit ronde 2).\n */\n resolve: (specifier: string, importer: string) => string | null | Promise<string | null>;\n /** Analysis untuk file server (hasil cache plugin). */\n analyze: (absoluteFile: string) => ServerFileAnalysis | null;\n}\n\n/** Nama serverFn (langsung atau via re-export) — versi async untuk pemeriksaan resolve. */\nasync function serverFnExportNamesAsync(\n analysis: ServerFileAnalysis,\n analyzeSpecifier: (specifier: string, importer: string) => Promise<ServerFileAnalysis | null>,\n seen = new Set<string>(),\n): Promise<Set<string>> {\n const names = new Set(analysis.serverFns.map((fn) => fn.name));\n\n for (const reExport of analysis.reExports) {\n const key = `${analysis.file}\\0${reExport.source}`;\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n const target = await analyzeSpecifier(reExport.source, analysis.file);\n if (target === null) {\n continue;\n }\n const targetNames = await serverFnExportNamesAsync(target, analyzeSpecifier, seen);\n for (const { local, exported } of reExport.names) {\n if (local === \"*\" || targetNames.has(local)) {\n names.add(exported);\n }\n }\n }\n\n for (const specifier of analysis.exportAllFrom) {\n const key = `${analysis.file}\\0${specifier}`;\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n const target = await analyzeSpecifier(specifier, analysis.file);\n if (target === null) {\n continue;\n }\n for (const name of await serverFnExportNamesAsync(target, analyzeSpecifier, seen)) {\n names.add(name);\n }\n }\n\n return names;\n}\n\nexport function nonContractServerFileError(file: string, projectRoot: string): MoonsError {\n return new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: toRelative(projectRoot, file),\n message: \"file server memakai ekstensi di luar kontrak §12\",\n details:\n \"Transform zero-trust hanya menangani `*.server.ts`/`*.server.tsx`; file server dengan ekstensi lain tidak bisa di-stub dan tidak boleh masuk graph client.\",\n suggestions: [\n \"Ganti nama file menjadi `*.server.ts`/`*.server.tsx` dan taruh `serverFn` di dalamnya\",\n \"Atau pindahkan nilai yang dibutuhkan ke file non-server\",\n ],\n });\n}\n\n/** Periksa import modul client terhadap §12.4/§12.7/§12.8 — berbasis hasil resolve. */\nexport async function checkClientModuleImports(\n context: ClientImportCheckContext,\n): Promise<void> {\n const { file, code, projectRoot, resolve, analyze } = context;\n const ast = parseModule(code, file);\n const relativeFile = toRelative(projectRoot, file);\n\n const resolveSafe = async (specifier: string, importer: string): Promise<string | null> => {\n try {\n const result = await resolve(specifier, importer);\n if (result === null) {\n return null;\n }\n const clean = stripQuery(result);\n // Audit ronde 2: normalisasi realpath — symlink ke `*.server.ts` harus\n // tertangkap walau resolver mengembalikan path link.\n try {\n return realpathSync(clean);\n } catch {\n return clean;\n }\n } catch {\n return null;\n }\n };\n\n const analyzeResolved = async (\n specifier: string,\n importer: string,\n ): Promise<ServerFileAnalysis | null> => {\n const absolute = await resolveSafe(specifier, importer);\n return absolute === null ? null : analyze(absolute);\n };\n\n const isAllowedServerFnImport = async (\n resolvedTarget: string | null,\n specifier: string,\n name: string,\n ): Promise<boolean> => {\n const target =\n resolvedTarget === null ? await analyzeResolved(specifier, file) : analyze(resolvedTarget);\n if (target === null) {\n return false;\n }\n const names = await serverFnExportNamesAsync(target, (nested, importer) =>\n analyzeResolved(nested, importer),\n );\n return names.has(name);\n };\n\n const reject = (line: number, message: string, details: string): never => {\n throw new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: relativeFile,\n line,\n message,\n details,\n suggestions: [\n \"Buat server function yang mengembalikan data yang dibutuhkan, atau\",\n \"Jika nilainya memang publik, definisikan ulang konstanta itu di modul yang boleh masuk client (jangan memindahkan nilai rahasia)\",\n ],\n });\n };\n\n const rejectForbidden = (line: number, specifier: string): never => {\n throw new MoonsError({\n code: \"E_FORBIDDEN_SERVER_IMPORT\",\n file: relativeFile,\n line,\n message: `mengimpor \\`${specifier}\\` di modul client`,\n details: \"Modul server-only hanya boleh di-import dari *.server.ts.\",\n suggestions: [\n \"Pindahkan operasi tersebut ke serverFn, atau\",\n \"Hapus import tersebut\",\n ],\n });\n };\n\n for (const statement of topLevelStatements(ast)) {\n if (statement.type === \"ImportDeclaration\" || statement.type === \"ExportNamedDeclaration\" || statement.type === \"ExportAllDeclaration\") {\n const sourceNode = statement[\"source\"] as AstNode | null | undefined;\n if (sourceNode?.type !== \"StringLiteral\") {\n continue;\n }\n const rawSpecifier = sourceNode[\"value\"] as string;\n // Query Vite (`?raw`, `?url`, `?inline`, dst.) dinormalisasi untuk\n // pencocokan & resolusi (audit adversarial M6).\n const specifier = stripQuery(rawSpecifier);\n const line = statement.loc?.start.line ?? 1;\n\n if (specifier.startsWith(\"node:\") || specifier.startsWith(\"bun:\")) {\n rejectForbidden(line, specifier);\n }\n\n const resolvedTarget = await resolveSafe(specifier, file);\n\n // Audit ronde 2: file server di luar kontrak §12 ditolak (tidak bisa di-stub).\n if (resolvedTarget !== null && isNonContractServerFile(resolvedTarget)) {\n throw nonContractServerFileError(resolvedTarget, projectRoot);\n }\n\n // Audit ronde 2: keputusan berbasis hasil resolve — menangkap alias Vite,\n // `tsconfig paths`, dan symlink (realpath) yang menunjuk `*.server.ts`.\n const serverBySpecifier = isServerSpecifier(specifier);\n const serverByResolve = resolvedTarget !== null && isServerFilePath(resolvedTarget);\n if (!serverBySpecifier && !serverByResolve) {\n continue;\n }\n\n const targetRelative =\n resolvedTarget === null ? rawSpecifier : toRelative(projectRoot, resolvedTarget);\n\n if (statement.type === \"ExportAllDeclaration\") {\n if (resolvedTarget === null) {\n reject(line, `\\`export *\\` dari \\`${targetRelative}\\` tidak bisa di-resolve`, \"Re-export dari `*.server.ts` wajib bisa di-resolve statis (PRD §12.6).\");\n }\n continue; // aman: target menjadi stub\n }\n\n const specifiers = (statement[\"specifiers\"] ?? []) as AstNode[];\n for (const item of specifiers) {\n if (item.type === \"ImportDefaultSpecifier\") {\n reject(line, `mengimpor default dari ${targetRelative}`, \"Default export dari file server tidak boleh menyeberang ke client.\");\n }\n if (item.type === \"ImportNamespaceSpecifier\") {\n reject(line, `mengimpor namespace (\\`* as\\`) dari ${targetRelative}`, \"Import namespace dari file server tidak boleh menyeberang ke client.\");\n }\n const name = ((item[\"local\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\";\n const kind = (item[\"importKind\"] as string | undefined) ?? (statement[\"importKind\"] as string | undefined);\n if (kind === \"type\") {\n reject(line, `mengimpor type \\`${name}\\` dari ${targetRelative}`, \"Import dari file server tidak diizinkan di modul client (PRD §12.4).\");\n }\n if (name.length > 0 && !(await isAllowedServerFnImport(resolvedTarget, specifier, name))) {\n reject(\n line,\n `mengimpor \\`${name}\\` dari ${targetRelative}`,\n \"Kode server tidak boleh muncul di client.\\nHanya `serverFn` yang diizinkan menyeberang.\",\n );\n }\n }\n }\n }\n\n // §12.4: pemanggilan env() di modul client (juga @moonsjs/server import env).\n const envBindings = new Set<string>();\n for (const statement of topLevelStatements(ast)) {\n if (statement.type !== \"ImportDeclaration\") {\n continue;\n }\n const sourceNode = statement[\"source\"] as AstNode | undefined;\n const specifier = sourceNode?.type === \"StringLiteral\" ? (sourceNode[\"value\"] as string) : \"\";\n if (specifier !== \"@moonsjs/server\" && !specifier.startsWith(\"@moonsjs/server/\")) {\n continue;\n }\n for (const item of (statement[\"specifiers\"] ?? []) as AstNode[]) {\n if (item.type !== \"ImportSpecifier\") {\n continue;\n }\n const imported = item[\"imported\"] as AstNode | undefined;\n const local = item[\"local\"] as AstNode | undefined;\n if (imported?.type === \"Identifier\" && imported[\"name\"] === \"env\" && local?.type === \"Identifier\") {\n envBindings.add(local[\"name\"] as string);\n }\n }\n }\n\n if (envBindings.size > 0) {\n walk(ast, (node) => {\n if (node.type !== \"CallExpression\") {\n return;\n }\n const callee = node[\"callee\"] as AstNode | undefined;\n if (callee?.type !== \"Identifier\" || !envBindings.has(callee[\"name\"] as string)) {\n return;\n }\n const callText = code\n .slice(node.start ?? 0, node.end ?? 0)\n .replace(/\\s+/g, \" \")\n .slice(0, 80);\n throw new MoonsError({\n code: \"E_ENV_IN_CLIENT\",\n file: relativeFile,\n line: node.loc?.start.line ?? 1,\n message: `memanggil \\`${callText}\\` di modul yang masuk client`,\n details: \"`env()` hanya legal di server.\",\n suggestions: [\n \"Pindahkan pemanggilan ke dalam serverFn, atau\",\n \"Gunakan import.meta.env untuk nilai publik\",\n ],\n });\n });\n }\n\n // Dynamic import (§12.7/§12.8) — literal maupun template dengan teks `.server`,\n // plus resolusi (alias/tsconfig paths/symlink) — audit ronde 2.\n const dynamicRequests: Array<{ request: DynamicImportRequest; guarded: boolean }> = [];\n walk(ast, (node, ancestors) => {\n const request = dynamicImportRequest(node);\n if (request !== null) {\n dynamicRequests.push({\n request,\n guarded: ancestors.some((ancestor) => isDevGuard(ancestor)),\n });\n }\n });\n\n for (const { request, guarded } of dynamicRequests) {\n if (guarded) {\n continue; // §12.8: branch DEV/PROD mati saat build → tidak perlu diperiksa\n }\n\n const specifier = stripQuery(request.text);\n const resolvedTarget = await resolveSafe(specifier, file);\n\n if (resolvedTarget !== null && isNonContractServerFile(resolvedTarget)) {\n throw nonContractServerFileError(resolvedTarget, projectRoot);\n }\n\n const serverBySpecifier = isServerSpecifier(specifier);\n const serverByResolve = resolvedTarget !== null && isServerFilePath(resolvedTarget);\n if (!serverBySpecifier && !serverByResolve) {\n continue;\n }\n\n const targetRelative =\n resolvedTarget === null ? request.text : toRelative(projectRoot, resolvedTarget);\n reject(request.node.loc?.start.line ?? 1, `mengimpor (dynamic) \\`${request.text}\\` dari ${targetRelative}`, \"Client tidak boleh melakukan dynamic import ke `*.server.ts` (PRD §12.7).\");\n }\n\n // `import.meta.glob` yang mencakup `*.server.ts` (§12.7) — audit adversarial M6.\n walk(ast, (node) => {\n if (node.type !== \"CallExpression\") {\n return;\n }\n const callee = node[\"callee\"] as AstNode | undefined;\n if (callee?.type !== \"MemberExpression\") {\n return;\n }\n const object = callee[\"object\"] as AstNode | undefined;\n const property = callee[\"property\"] as AstNode | undefined;\n if (\n object?.type !== \"MetaProperty\" ||\n property?.type !== \"Identifier\" ||\n property[\"name\"] !== \"glob\"\n ) {\n return;\n }\n\n for (const pattern of globPatterns(((node[\"arguments\"] ?? []) as AstNode[])[0])) {\n if (!isServerSpecifier(pattern)) {\n continue;\n }\n throw new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: relativeFile,\n line: node.loc?.start.line ?? 1,\n message: `mengimpor (glob) \\`${pattern}\\` di modul client`,\n details: \"`import.meta.glob` yang mencakup `*.server.ts` dilarang di client (PRD §12.7).\",\n suggestions: [\n \"Import statis `serverFn` dari `*.server.ts` (hanya itu yang boleh menyeberang), atau\",\n \"Pindahkan kebutuhan data ke dalam server function\",\n ],\n });\n }\n });\n}\n\ninterface DynamicImportRequest {\n /** Teks specifier literal, atau gabungan quasi template (`*` untuk ekspresi). */\n text: string;\n node: AstNode;\n}\n\n/** Dukung Babel 8 (`ImportExpression`) dan bentuk lama (`CallExpression` + callee `Import`). */\nfunction dynamicImportRequest(node: AstNode): DynamicImportRequest | null {\n let sourceNode: AstNode | null = null;\n\n if (node.type === \"ImportExpression\") {\n sourceNode = (node[\"source\"] as AstNode | undefined) ?? null;\n } else if (node.type === \"CallExpression\") {\n const callee = node[\"callee\"] as AstNode | undefined;\n if (callee?.type !== \"Import\") {\n return null;\n }\n sourceNode = ((node[\"arguments\"] ?? []) as AstNode[])[0] ?? null;\n }\n\n if (sourceNode === null) {\n return null;\n }\n if (sourceNode.type === \"StringLiteral\") {\n return { text: sourceNode[\"value\"] as string, node: sourceNode };\n }\n if (sourceNode.type === \"TemplateLiteral\") {\n const text = ((sourceNode[\"quasis\"] ?? []) as AstNode[])\n .map((quasi) => ((quasi[\"value\"] as { cooked?: string | null } | undefined)?.cooked ?? \"\"))\n .join(\"*\");\n return { text, node: sourceNode };\n }\n return null;\n}\n\nfunction globPatterns(node: AstNode | undefined): string[] {\n if (node?.type === \"StringLiteral\") {\n return [node[\"value\"] as string];\n }\n if (node?.type === \"ArrayExpression\") {\n return ((node[\"elements\"] ?? []) as Array<AstNode | null>)\n .filter((element): element is AstNode => element?.type === \"StringLiteral\")\n .map((element) => element[\"value\"] as string);\n }\n return [];\n}\n\nfunction isDevGuard(node: AstNode): boolean {\n if (node.type !== \"IfStatement\") {\n return false;\n }\n const test = node[\"test\"] as AstNode | undefined;\n return isImportMetaFlag(test, \"DEV\") || isNegatedImportMetaFlag(test, \"PROD\");\n}\n\nfunction isImportMetaFlag(node: AstNode | undefined, flag: string): boolean {\n const member = node;\n if (member?.type !== \"MemberExpression\") {\n return false;\n }\n const property = member[\"property\"] as AstNode | undefined;\n if (property?.type !== \"Identifier\" || property[\"name\"] !== flag) {\n return false;\n }\n const object = member[\"object\"] as AstNode | undefined;\n return isImportMetaEnv(object);\n}\n\nfunction isNegatedImportMetaFlag(node: AstNode | undefined, flag: string): boolean {\n if (node?.type !== \"UnaryExpression\" || node[\"operator\"] !== \"!\") {\n return false;\n }\n return isImportMetaFlag(node[\"argument\"] as AstNode | undefined, flag);\n}\n\nfunction isImportMetaEnv(node: AstNode | undefined): boolean {\n if (node?.type !== \"MemberExpression\") {\n return false;\n }\n const property = node[\"property\"] as AstNode | undefined;\n if (property?.type !== \"Identifier\" || property[\"name\"] !== \"env\") {\n return false;\n }\n const object = node[\"object\"] as AstNode | undefined;\n return object?.type === \"MetaProperty\";\n}\n\nfunction toRelative(projectRoot: string, file: string): string {\n const relative = file.startsWith(projectRoot)\n ? file.slice(projectRoot.length).replace(/^[/\\\\]/, \"\")\n : file;\n return relative.split(\"\\\\\").join(\"/\");\n}\n\nexport interface RouteExportCheckContext {\n file: string;\n code: string;\n routesDir: string;\n projectRoot: string;\n}\n\n/**\n * §11.2 + §12.4: export legal per jenis modul route.\n * page: `default|loader|meta`; layout: `default|loader`; `_error`/`_404`: `default`.\n */\nexport function checkRouteModuleExports(context: RouteExportCheckContext): void {\n const { file, code, routesDir, projectRoot } = context;\n if (!file.startsWith(routesDir) || !file.endsWith(\".tsx\")) {\n return;\n }\n\n const base = file.slice(file.lastIndexOf(\"/\") + 1);\n if (base.startsWith(\"_\") && base !== \"_layout.tsx\" && base !== \"_error.tsx\" && base !== \"_404.tsx\") {\n return; // bukan route (diabaikan scanner)\n }\n\n const allowed =\n base === \"_layout.tsx\"\n ? [\"default\", \"loader\"]\n : base === \"_error.tsx\" || base === \"_404.tsx\"\n ? [\"default\"]\n : [\"default\", \"loader\", \"meta\"];\n const allowedText = `Hanya ${allowed.map((name) => `\\`${name}\\``).join(\", \")} yang boleh di-export.`;\n const relativeFile = toRelative(projectRoot, file);\n const ast = parseModule(code, file);\n\n const declarations: Array<{ name: string; line: number }> = [];\n let hasDefault = false;\n\n for (const statement of topLevelStatements(ast)) {\n if (statement.type === \"ExportDefaultDeclaration\") {\n hasDefault = true;\n continue;\n }\n\n if (statement.type === \"ExportAllDeclaration\") {\n throw new MoonsError({\n code: \"E_ROUTE_EXPORT_INVALID\",\n file: relativeFile,\n line: statement.loc?.start.line ?? 1,\n message: \"`export *` tidak diizinkan di modul route\",\n details: allowedText,\n suggestions: [\n `Pindahkan isi file ke luar ${toRelative(projectRoot, routesDir)}/, atau`,\n \"Hapus `export *` tersebut\",\n ],\n });\n }\n\n if (statement.type !== \"ExportNamedDeclaration\") {\n continue;\n }\n\n const declaration = statement[\"declaration\"] as AstNode | null | undefined;\n if (declaration !== null && declaration !== undefined) {\n for (const name of declarationNames(declaration)) {\n declarations.push({ name, line: declaration.loc?.start.line ?? 1 });\n }\n }\n\n for (const item of (statement[\"specifiers\"] ?? []) as AstNode[]) {\n const exported = item[\"exported\"] as AstNode | undefined;\n const name =\n exported?.type === \"Identifier\"\n ? (exported[\"name\"] as string)\n : exported?.type === \"StringLiteral\"\n ? (exported[\"value\"] as string)\n : null;\n if (name !== null) {\n declarations.push({ name, line: item.loc?.start.line ?? statement.loc?.start.line ?? 1 });\n }\n }\n }\n\n for (const entry of declarations) {\n if (!allowed.includes(entry.name)) {\n throw new MoonsError({\n code: \"E_ROUTE_EXPORT_INVALID\",\n file: relativeFile,\n line: entry.line,\n message: `export \\`${entry.name}\\` tidak diizinkan di modul route`,\n details: allowedText,\n suggestions: [\n `Pindahkan \\`${entry.name}\\` ke file di luar ${toRelative(projectRoot, routesDir)}/, atau`,\n \"Hapus export tersebut\",\n ],\n });\n }\n }\n\n if (!hasDefault) {\n throw new MoonsError({\n code: \"E_ROUTE_EXPORT_INVALID\",\n file: relativeFile,\n message: \"modul route wajib mengekspor `default`\",\n details: \"Setiap file route harus punya `export default` berupa komponen React (PRD §11.2).\",\n suggestions: [\"Tambahkan `export default function Page() { ... }`\"],\n });\n }\n}\n\nfunction declarationNames(declaration: AstNode): string[] {\n switch (declaration.type) {\n case \"VariableDeclaration\":\n return ((declaration[\"declarations\"] ?? []) as AstNode[])\n .map((declarator) => ((declarator[\"id\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\")\n .filter((name) => name.length > 0);\n case \"FunctionDeclaration\":\n case \"ClassDeclaration\":\n case \"TSInterfaceDeclaration\":\n case \"TSTypeAliasDeclaration\":\n case \"TSEnumDeclaration\":\n return [((declaration[\"id\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\"].filter(\n (name) => name.length > 0,\n );\n default:\n return [];\n }\n}\n\n/** Scan semua `*.server.{ts,tsx}` di bawah root (exclude direktori build/dependency). */\nexport function scanServerFiles(projectRoot: string): string[] {\n const excluded = new Set([\"node_modules\", \"dist\", \".moons\", \".git\"]);\n const result: string[] = [];\n\n const walkDir = (dir: string): void => {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n if (excluded.has(entry.name)) {\n continue;\n }\n walkDir(join(dir, entry.name));\n } else if (entry.isFile() && isServerFilePath(entry.name)) {\n result.push(join(dir, entry.name));\n }\n }\n };\n\n walkDir(projectRoot);\n return result.sort();\n}\n\nexport interface FnRegistryJson {\n [key: string]: string;\n}\n\n/** Bangun isi `fn-registry.json` (bentuk yang dibaca §21.3). */\nexport function buildFnRegistry(projectRoot: string, files: string[]): FnRegistryJson {\n const registry: FnRegistryJson = {};\n for (const file of files) {\n let source: string;\n try {\n source = readFileSync(file, \"utf8\");\n } catch {\n continue;\n }\n const analysis = analyzeServerFile(source, file, projectRoot);\n for (const fn of analysis.serverFns) {\n registry[fnRegistryKey(projectRoot, file, fn.name)] = fn.hash;\n }\n }\n return registry;\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "6E8CE67B8B7578C064756E2164756E21",
9
+ "names": []
10
+ }
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  VIRTUAL_MODULES,
5
5
  fromNullPrefixed,
6
6
  installDevMiddleware2
7
- } from "./index-8xq8fcgq.js";
7
+ } from "./index-1sm9pvvd.js";
8
8
  import {
9
9
  isServerFilePath2,
10
10
  isNonContractServerFile2,
@@ -17,7 +17,7 @@ import {
17
17
  checkClientModuleImports2,
18
18
  checkRouteModuleExports2,
19
19
  scanServerFiles2
20
- } from "./index-fg6nqart.js";
20
+ } from "./index-3ec9vpek.js";
21
21
 
22
22
  // src/plugin.ts
23
23
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
@@ -161,7 +161,8 @@ function moons(options = {}) {
161
161
  }
162
162
  return {
163
163
  ...common,
164
- build: { outDir: "dist/client", emptyOutDir: true }
164
+ build: { outDir: "dist/client", emptyOutDir: true },
165
+ ssr: { noExternal: [/^@moonsjs\//] }
165
166
  };
166
167
  },
167
168
  async configResolved(resolved) {
@@ -420,4 +421,4 @@ export {
420
421
  moons as default
421
422
  };
422
423
 
423
- //# debugId=B0BD6103F707A0BE64756E2164756E21
424
+ //# debugId=A336EA74F6CC12EF64756E2164756E21
package/dist/index.js.map CHANGED
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/plugin.ts", "../src/leak-check.ts"],
4
4
  "sourcesContent": [
5
- "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport { resolve as resolvePath } from \"node:path\";\nimport {\n MoonsError,\n fnRegistryKey,\n generateTypes,\n scanRoutes,\n validateConfig,\n type RouteDefinition,\n} from \"@moonsjs/core\";\nimport { loadConfigFromFile, type Plugin, type ViteDevServer } from \"vite\";\nimport { findLeak } from \"./leak-check\";\nimport { renderRoutesModule, rootSpecifier } from \"./manifest\";\nimport { installDevMiddleware } from \"./server/dev\";\nimport {\n analyzeServerFile,\n checkClientModuleImports,\n checkRouteModuleExports,\n injectServerFnMeta,\n isNonContractServerFile,\n isServerFilePath,\n nonContractServerFileError,\n renderServerFnStub,\n resolveServerSpecifierSync,\n scanServerFiles,\n stripQuery,\n type ServerFileAnalysis,\n} from \"./transform\";\nimport { fromNullPrefixed, VIRTUAL_MODULES } from \"./virtual-modules\";\n\nexport interface MoonsVitePluginOptions {\n /** Default: \"moons.config.ts\". */\n configPath?: string;\n /** Hanya dipakai di CI (M2 §21). */\n leakTest?: { canary?: string };\n /** Default: root Vite. */\n projectRoot?: string;\n}\n\n/**\n * Plugin `@moonsjs/vite` (PRD §9): scan route, typegen, virtual module,\n * dev SSR middleware, build client + server.\n */\nconst CODE_FILE_PATTERN = /\\.(ts|tsx|js|jsx|mjs|cjs|mts|cts)$/;\n\nexport default function moons(options: MoonsVitePluginOptions = {}): Plugin {\n let root = options.projectRoot ?? process.cwd();\n let isSsrBuild = false;\n let configFilePath = \"\";\n let routesDir = \"\";\n let routes: RouteDefinition[] = [];\n let analysisCache = new Map<string, ServerFileAnalysis>();\n const stubTransformed = new Set<string>();\n\n function analyzeFile(absoluteFile: string): ServerFileAnalysis | null {\n const cached = analysisCache.get(absoluteFile);\n if (cached !== undefined) {\n return cached;\n }\n let source: string;\n try {\n source = readFileSync(absoluteFile, \"utf8\");\n } catch {\n return null;\n }\n const analysis = analyzeServerFile(source, absoluteFile, root);\n analysisCache.set(absoluteFile, analysis);\n return analysis;\n }\n\n function refreshServerFns(): void {\n const next = new Map<string, ServerFileAnalysis>();\n const registry: Record<string, string> = {};\n\n for (const file of scanServerFiles(root)) {\n let source: string;\n try {\n source = readFileSync(file, \"utf8\");\n } catch {\n continue;\n }\n const analysis = analyzeServerFile(source, file, root);\n next.set(file, analysis);\n for (const fn of analysis.serverFns) {\n registry[fnRegistryKey(root, file, fn.name)] = fn.hash;\n }\n }\n\n analysisCache = next;\n const outDir = resolvePath(root, \".moons\");\n mkdirSync(outDir, { recursive: true });\n writeFileSync(\n resolvePath(outDir, \"fn-registry.json\"),\n `${JSON.stringify(registry, null, 2)}\\n`,\n \"utf8\",\n );\n }\n\n /** Semua specifier file `.server.ts` yang punya serverFn (untuk eager import di entry server). */\n function serverFnFileSpecifiers(): string[] {\n const specifiers: string[] = [];\n for (const [file, analysis] of analysisCache) {\n if (analysis.serverFns.length > 0) {\n specifiers.push(rootSpecifier(root, file));\n }\n }\n return specifiers.sort();\n }\n\n /** Stub client §12.2 + cache §12.2.5. */\n function transformServerFileClient(code: string, id: string): string {\n const relativePath = id.startsWith(root)\n ? id.slice(root.length).split(\"\\\\\").join(\"/\")\n : id;\n const cacheKey = createHash(\"sha256\").update(`${relativePath}\\0${code}`).digest(\"hex\");\n const cacheFile = resolvePath(root, \".moons/cache\", `${cacheKey}.js`);\n\n if (existsSync(cacheFile)) {\n stubTransformed.add(id);\n return readFileSync(cacheFile, \"utf8\");\n }\n\n const analysis = analyzeFile(id);\n if (analysis === null) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n file: id,\n message: \"gagal membaca file server untuk transform\",\n details: \"File `.server.ts` harus bisa dibaca saat transform (PRD §12.2).\",\n suggestions: [\"Periksa path dan izin file\"],\n });\n }\n\n const stub = renderServerFnStub(code, id, analysis, {\n analyzeSpecifier: (sourceFile, specifier) => {\n const resolved = resolveServerSpecifierSync(sourceFile, specifier);\n return resolved === null ? null : analyzeFile(resolved);\n },\n });\n\n mkdirSync(resolvePath(root, \".moons/cache\"), { recursive: true });\n writeFileSync(cacheFile, stub.code, \"utf8\");\n stubTransformed.add(id);\n return stub.code;\n }\n\n return {\n name: \"moons\",\n enforce: \"pre\",\n\n config(_config, env) {\n isSsrBuild = env.isSsrBuild === true;\n const common = {\n appType: \"custom\" as const,\n };\n\n if (isSsrBuild) {\n return {\n ...common,\n build: {\n outDir: \"dist/server\",\n emptyOutDir: true,\n // Entry nyata yang di-generate saat buildStart (Rolldown butuh file,\n // entry virtual tidak di-resolve lewat plugin container).\n ssr: \".moons/server-entry.ts\",\n rollupOptions: { output: { entryFileNames: \"index.js\", codeSplitting: false } },\n },\n ssr: { noExternal: true, target: \"node\" as const },\n };\n }\n\n return {\n ...common,\n build: { outDir: \"dist/client\", emptyOutDir: true },\n };\n },\n\n async configResolved(resolved) {\n root = options.projectRoot ?? resolved.root;\n configFilePath = resolvePath(root, options.configPath ?? \"moons.config.ts\");\n\n if (!existsSync(configFilePath)) {\n throw new MoonsError({\n code: \"E_CONFIG_INVALID\",\n file: configFilePath,\n message: \"`moons.config.ts` tidak ditemukan\",\n details: \"Framework membutuhkan file config di root project (PRD §14.3).\",\n suggestions: [\n \"Buat `moons.config.ts` dengan `export default defineConfig({ context: async (req) => ({}) })`\",\n ],\n });\n }\n\n let raw: unknown;\n try {\n const loaded = await loadConfigFromFile(\n { command: resolved.command, mode: resolved.mode },\n configFilePath,\n root,\n );\n raw = loaded?.config;\n } catch (error) {\n if (error instanceof MoonsError) {\n throw error;\n }\n throw new MoonsError({\n code: \"E_CONFIG_INVALID\",\n file: configFilePath,\n message: \"gagal memuat `moons.config.ts`\",\n details: error instanceof Error ? error.message : String(error),\n suggestions: [\"Periksa sintaks dan import di `moons.config.ts`\"],\n });\n }\n\n const config = validateConfig(raw, { file: configFilePath, projectRoot: root });\n routesDir = resolvePath(root, config.routesDir);\n },\n\n async buildStart() {\n routes = scanRoutes(routesDir);\n await generateTypes({\n routesDir,\n configPath: configFilePath,\n outDir: resolvePath(root, \".moons\"),\n });\n refreshServerFns();\n if (isSsrBuild) {\n writeFileSync(\n resolvePath(root, \".moons/server-entry.ts\"),\n renderServerEntryBuild(routesDir, serverFnFileSpecifiers()),\n \"utf8\",\n );\n }\n },\n\n resolveId(id) {\n const clean = id.startsWith(\"\\0\") ? id.slice(1) : id;\n if ((Object.values(VIRTUAL_MODULES) as string[]).includes(clean)) {\n return `\\0${clean}`;\n }\n return undefined;\n },\n\n load(id) {\n const name = fromNullPrefixed(id);\n if (name === null) {\n return undefined;\n }\n switch (name) {\n case VIRTUAL_MODULES.routes:\n return renderRoutesModule(routes, routesDir, root);\n case VIRTUAL_MODULES.clientEntry:\n return '// Generated by @moons. Jangan diubah manual.\\nexport { clientManifest, loadRoute } from \"virtual:moons/routes\";\\n';\n case VIRTUAL_MODULES.config:\n return renderConfigModule(root, configFilePath);\n case VIRTUAL_MODULES.serverEntry:\n // Hanya dipakai dev (ssrLoadModule); build memakai .moons/server-entry.ts.\n return renderServerEntryDev(routesDir, serverFnFileSpecifiers());\n }\n },\n\n async transform(code, id) {\n const cleanId = stripQuery(id);\n if (cleanId.startsWith(\"\\0\") || cleanId.includes(\"/node_modules/\")) {\n return undefined;\n }\n\n const environment = environmentName(this);\n\n if (isServerFilePath(cleanId)) {\n if (environment === \"ssr\") {\n const analysis = analysisCache.get(cleanId) ?? analyzeFile(cleanId);\n if (analysis === null || analysis.serverFns.length === 0) {\n return undefined;\n }\n return injectServerFnMeta(code, analysis, root);\n }\n return transformServerFileClient(code, cleanId);\n }\n\n // Audit ronde 2: file server di luar kontrak §12 tidak bisa di-stub —\n // jangan pernah biarkan masuk graph client.\n if (environment !== \"ssr\" && isNonContractServerFile(cleanId)) {\n throw nonContractServerFileError(cleanId, root);\n }\n\n if (environment !== \"ssr\" && CODE_FILE_PATTERN.test(cleanId)) {\n if (cleanId.startsWith(routesDir) && cleanId.endsWith(\".tsx\")) {\n checkRouteModuleExports({\n file: cleanId,\n code,\n routesDir,\n projectRoot: root,\n });\n }\n await checkClientModuleImports({\n file: cleanId,\n code,\n projectRoot: root,\n // Resolusi penuh (alias Vite, tsconfig paths, symlink) — audit ronde 2.\n resolve: async (specifier, importer) => {\n try {\n const resolved = await this.resolve(specifier, importer);\n return resolved === null ? null : stripQuery(resolved.id);\n } catch {\n return null;\n }\n },\n analyze: (absoluteFile) => analysisCache.get(absoluteFile) ?? analyzeFile(absoluteFile),\n });\n }\n\n return undefined;\n },\n\n generateBundle(_options, bundle) {\n if (environmentName(this) === \"ssr\") {\n return;\n }\n\n const canary = options.leakTest?.canary;\n if (canary !== undefined && canary.length > 0) {\n const leak = findLeak(Object.values(bundle), canary);\n if (leak !== null) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n message: `canary \\`${canary}\\` ditemukan di bundle client (${leak.fileName})`,\n details:\n \"Verifikasi kebocoran §2/§9.2.8 gagal: kode server bocor ke output client. Build dihentikan.\",\n suggestions: [\n \"Periksa transform `*.server.ts` (§12)\",\n \"Jalankan `./scripts/m2/test-leak.sh` untuk audit\",\n ],\n });\n }\n }\n\n for (const output of Object.values(bundle)) {\n if (output.type !== \"chunk\") {\n continue;\n }\n for (const moduleId of Object.keys(output.modules)) {\n const cleanId = stripQuery(moduleId);\n if (!isServerFilePath(cleanId) || stubTransformed.has(cleanId)) {\n continue;\n }\n throw new MoonsError({\n code: \"E_FORBIDDEN_SERVER_IMPORT\",\n file: cleanId,\n message: \"modul server ikut ter-bundle di client tanpa melewati transform\",\n details:\n \"Verifikasi build §9.2: setiap `*.server.ts` di bundle client wajib berupa stub RPC hasil transform.\",\n suggestions: [\n \"Pastikan transform zero-trust (§12) berjalan untuk modul ini\",\n \"Laporkan ini sebagai bug framework jika berulang\",\n ],\n });\n }\n }\n },\n\n configureServer(server) {\n installDevMiddleware(server, { templatePath: resolvePath(root, \"index.html\") });\n },\n\n async handleHotUpdate(context) {\n if (isServerFilePath(context.file)) {\n refreshServerFns();\n context.server.ws.send({ type: \"full-reload\" });\n return;\n }\n\n if (!context.file.startsWith(routesDir)) {\n return;\n }\n\n try {\n routes = scanRoutes(routesDir);\n await generateTypes({\n routesDir,\n configPath: configFilePath,\n outDir: resolvePath(root, \".moons\"),\n });\n } catch (error) {\n context.server.config.logger.error(String(error));\n return;\n }\n\n invalidateVirtualModules(context.server);\n context.server.ws.send({ type: \"full-reload\" });\n },\n };\n}\n\nfunction renderConfigModule(root: string, configFilePath: string): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n `import raw from ${JSON.stringify(rootSpecifier(root, configFilePath))};`,\n 'import { validateConfig } from \"@moonsjs/core\";',\n `export default validateConfig(raw, { file: ${JSON.stringify(configFilePath)} });`,\n \"\",\n ].join(\"\\n\");\n}\n\nfunction renderServerEntryDev(routesDir: string, eagerImports: string[]): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n 'import { createRequestHandler } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n ...eagerImports.map((specifier) => `import ${JSON.stringify(specifier)};`),\n \"\",\n \"export function createDevHandler(shell) {\",\n ` return createRequestHandler({ routes, config, routesDir: ${JSON.stringify(routesDir)}, loadRoute, shell });`,\n \"}\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction renderServerEntryBuild(routesDir: string, eagerImports: string[]): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n 'import { createFileShell, createRequestHandler, startNodeServer } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n ...eagerImports.map((specifier) => `import ${JSON.stringify(specifier)};`),\n \"\",\n \"const handler = createRequestHandler({\",\n \" routes,\",\n \" config,\",\n ` routesDir: ${JSON.stringify(routesDir)},`,\n \" loadRoute,\",\n \" shell: createFileShell(),\",\n \"});\",\n \"\",\n \"startNodeServer(handler);\",\n \"\",\n ].join(\"\\n\");\n}\n\ninterface ModuleGraphLike {\n getModulesByFile(file: string): Iterable<{ id?: string | null }> | undefined;\n invalidateModule(module: unknown): void;\n}\n\nfunction environmentName(context: unknown): string {\n const environment = (context as { environment?: { name?: string } } | undefined)?.environment;\n return environment?.name ?? \"client\";\n}\n\nfunction invalidateVirtualModules(server: ViteDevServer): void {\n const graphs: ModuleGraphLike[] = [server.moduleGraph as unknown as ModuleGraphLike];\n const environments = (server as unknown as { environments?: Record<string, { moduleGraph?: unknown }> })\n .environments;\n if (environments !== undefined) {\n for (const environment of Object.values(environments)) {\n if (environment.moduleGraph !== undefined) {\n graphs.push(environment.moduleGraph as ModuleGraphLike);\n }\n }\n }\n\n for (const graph of graphs) {\n for (const name of Object.values(VIRTUAL_MODULES)) {\n for (const module of graph.getModulesByFile(`\\0${name}`) ?? []) {\n graph.invalidateModule(module);\n }\n }\n }\n}\n",
5
+ "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport { resolve as resolvePath } from \"node:path\";\nimport {\n MoonsError,\n fnRegistryKey,\n generateTypes,\n scanRoutes,\n validateConfig,\n type RouteDefinition,\n} from \"@moonsjs/core\";\nimport { loadConfigFromFile, type Plugin, type ViteDevServer } from \"vite\";\nimport { findLeak } from \"./leak-check\";\nimport { renderRoutesModule, rootSpecifier } from \"./manifest\";\nimport { installDevMiddleware } from \"./server/dev\";\nimport {\n analyzeServerFile,\n checkClientModuleImports,\n checkRouteModuleExports,\n injectServerFnMeta,\n isNonContractServerFile,\n isServerFilePath,\n nonContractServerFileError,\n renderServerFnStub,\n resolveServerSpecifierSync,\n scanServerFiles,\n stripQuery,\n type ServerFileAnalysis,\n} from \"./transform\";\nimport { fromNullPrefixed, VIRTUAL_MODULES } from \"./virtual-modules\";\n\nexport interface MoonsVitePluginOptions {\n /** Default: \"moons.config.ts\". */\n configPath?: string;\n /** Hanya dipakai di CI (M2 §21). */\n leakTest?: { canary?: string };\n /** Default: root Vite. */\n projectRoot?: string;\n}\n\n/**\n * Plugin `@moonsjs/vite` (PRD §9): scan route, typegen, virtual module,\n * dev SSR middleware, build client + server.\n */\nconst CODE_FILE_PATTERN = /\\.(ts|tsx|js|jsx|mjs|cjs|mts|cts)$/;\n\nexport default function moons(options: MoonsVitePluginOptions = {}): Plugin {\n let root = options.projectRoot ?? process.cwd();\n let isSsrBuild = false;\n let configFilePath = \"\";\n let routesDir = \"\";\n let routes: RouteDefinition[] = [];\n let analysisCache = new Map<string, ServerFileAnalysis>();\n const stubTransformed = new Set<string>();\n\n function analyzeFile(absoluteFile: string): ServerFileAnalysis | null {\n const cached = analysisCache.get(absoluteFile);\n if (cached !== undefined) {\n return cached;\n }\n let source: string;\n try {\n source = readFileSync(absoluteFile, \"utf8\");\n } catch {\n return null;\n }\n const analysis = analyzeServerFile(source, absoluteFile, root);\n analysisCache.set(absoluteFile, analysis);\n return analysis;\n }\n\n function refreshServerFns(): void {\n const next = new Map<string, ServerFileAnalysis>();\n const registry: Record<string, string> = {};\n\n for (const file of scanServerFiles(root)) {\n let source: string;\n try {\n source = readFileSync(file, \"utf8\");\n } catch {\n continue;\n }\n const analysis = analyzeServerFile(source, file, root);\n next.set(file, analysis);\n for (const fn of analysis.serverFns) {\n registry[fnRegistryKey(root, file, fn.name)] = fn.hash;\n }\n }\n\n analysisCache = next;\n const outDir = resolvePath(root, \".moons\");\n mkdirSync(outDir, { recursive: true });\n writeFileSync(\n resolvePath(outDir, \"fn-registry.json\"),\n `${JSON.stringify(registry, null, 2)}\\n`,\n \"utf8\",\n );\n }\n\n /** Semua specifier file `.server.ts` yang punya serverFn (untuk eager import di entry server). */\n function serverFnFileSpecifiers(): string[] {\n const specifiers: string[] = [];\n for (const [file, analysis] of analysisCache) {\n if (analysis.serverFns.length > 0) {\n specifiers.push(rootSpecifier(root, file));\n }\n }\n return specifiers.sort();\n }\n\n /** Stub client §12.2 + cache §12.2.5. */\n function transformServerFileClient(code: string, id: string): string {\n const relativePath = id.startsWith(root)\n ? id.slice(root.length).split(\"\\\\\").join(\"/\")\n : id;\n const cacheKey = createHash(\"sha256\").update(`${relativePath}\\0${code}`).digest(\"hex\");\n const cacheFile = resolvePath(root, \".moons/cache\", `${cacheKey}.js`);\n\n if (existsSync(cacheFile)) {\n stubTransformed.add(id);\n return readFileSync(cacheFile, \"utf8\");\n }\n\n const analysis = analyzeFile(id);\n if (analysis === null) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n file: id,\n message: \"gagal membaca file server untuk transform\",\n details: \"File `.server.ts` harus bisa dibaca saat transform (PRD §12.2).\",\n suggestions: [\"Periksa path dan izin file\"],\n });\n }\n\n const stub = renderServerFnStub(code, id, analysis, {\n analyzeSpecifier: (sourceFile, specifier) => {\n const resolved = resolveServerSpecifierSync(sourceFile, specifier);\n return resolved === null ? null : analyzeFile(resolved);\n },\n });\n\n mkdirSync(resolvePath(root, \".moons/cache\"), { recursive: true });\n writeFileSync(cacheFile, stub.code, \"utf8\");\n stubTransformed.add(id);\n return stub.code;\n }\n\n return {\n name: \"moons\",\n enforce: \"pre\",\n\n config(_config, env) {\n isSsrBuild = env.isSsrBuild === true;\n const common = {\n appType: \"custom\" as const,\n };\n\n if (isSsrBuild) {\n return {\n ...common,\n build: {\n outDir: \"dist/server\",\n emptyOutDir: true,\n // Entry nyata yang di-generate saat buildStart (Rolldown butuh file,\n // entry virtual tidak di-resolve lewat plugin container).\n ssr: \".moons/server-entry.ts\",\n rollupOptions: { output: { entryFileNames: \"index.js\", codeSplitting: false } },\n },\n ssr: { noExternal: true, target: \"node\" as const },\n };\n }\n\n return {\n ...common,\n build: { outDir: \"dist/client\", emptyOutDir: true },\n // Dev SSR: paket framework WAJIB di-inline ke pipeline Vite. Sejak\n // dipublikasikan, `@moonsjs/*` adalah package node_modules biasa (bukan\n // workspace-link) sehingga default Vite mengeksternalnya; import runtime\n // (bun) menyelesaikannya lewat kondisi `bun` → `src`, sedangkan modul\n // route diselesaikan Vite → `dist` — dua instans React context →\n // \"useLoaderData dipanggil di luar render route\" (temuan eval T4;\n // docs/decisions/0015). Inline → semua konsisten lewat Vite.\n ssr: { noExternal: [/^@moonsjs\\//] },\n };\n },\n\n async configResolved(resolved) {\n root = options.projectRoot ?? resolved.root;\n configFilePath = resolvePath(root, options.configPath ?? \"moons.config.ts\");\n\n if (!existsSync(configFilePath)) {\n throw new MoonsError({\n code: \"E_CONFIG_INVALID\",\n file: configFilePath,\n message: \"`moons.config.ts` tidak ditemukan\",\n details: \"Framework membutuhkan file config di root project (PRD §14.3).\",\n suggestions: [\n \"Buat `moons.config.ts` dengan `export default defineConfig({ context: async (req) => ({}) })`\",\n ],\n });\n }\n\n let raw: unknown;\n try {\n const loaded = await loadConfigFromFile(\n { command: resolved.command, mode: resolved.mode },\n configFilePath,\n root,\n );\n raw = loaded?.config;\n } catch (error) {\n if (error instanceof MoonsError) {\n throw error;\n }\n throw new MoonsError({\n code: \"E_CONFIG_INVALID\",\n file: configFilePath,\n message: \"gagal memuat `moons.config.ts`\",\n details: error instanceof Error ? error.message : String(error),\n suggestions: [\"Periksa sintaks dan import di `moons.config.ts`\"],\n });\n }\n\n const config = validateConfig(raw, { file: configFilePath, projectRoot: root });\n routesDir = resolvePath(root, config.routesDir);\n },\n\n async buildStart() {\n routes = scanRoutes(routesDir);\n await generateTypes({\n routesDir,\n configPath: configFilePath,\n outDir: resolvePath(root, \".moons\"),\n });\n refreshServerFns();\n if (isSsrBuild) {\n writeFileSync(\n resolvePath(root, \".moons/server-entry.ts\"),\n renderServerEntryBuild(routesDir, serverFnFileSpecifiers()),\n \"utf8\",\n );\n }\n },\n\n resolveId(id) {\n const clean = id.startsWith(\"\\0\") ? id.slice(1) : id;\n if ((Object.values(VIRTUAL_MODULES) as string[]).includes(clean)) {\n return `\\0${clean}`;\n }\n return undefined;\n },\n\n load(id) {\n const name = fromNullPrefixed(id);\n if (name === null) {\n return undefined;\n }\n switch (name) {\n case VIRTUAL_MODULES.routes:\n return renderRoutesModule(routes, routesDir, root);\n case VIRTUAL_MODULES.clientEntry:\n return '// Generated by @moons. Jangan diubah manual.\\nexport { clientManifest, loadRoute } from \"virtual:moons/routes\";\\n';\n case VIRTUAL_MODULES.config:\n return renderConfigModule(root, configFilePath);\n case VIRTUAL_MODULES.serverEntry:\n // Hanya dipakai dev (ssrLoadModule); build memakai .moons/server-entry.ts.\n return renderServerEntryDev(routesDir, serverFnFileSpecifiers());\n }\n },\n\n async transform(code, id) {\n const cleanId = stripQuery(id);\n if (cleanId.startsWith(\"\\0\") || cleanId.includes(\"/node_modules/\")) {\n return undefined;\n }\n\n const environment = environmentName(this);\n\n if (isServerFilePath(cleanId)) {\n if (environment === \"ssr\") {\n const analysis = analysisCache.get(cleanId) ?? analyzeFile(cleanId);\n if (analysis === null || analysis.serverFns.length === 0) {\n return undefined;\n }\n return injectServerFnMeta(code, analysis, root);\n }\n return transformServerFileClient(code, cleanId);\n }\n\n // Audit ronde 2: file server di luar kontrak §12 tidak bisa di-stub —\n // jangan pernah biarkan masuk graph client.\n if (environment !== \"ssr\" && isNonContractServerFile(cleanId)) {\n throw nonContractServerFileError(cleanId, root);\n }\n\n if (environment !== \"ssr\" && CODE_FILE_PATTERN.test(cleanId)) {\n if (cleanId.startsWith(routesDir) && cleanId.endsWith(\".tsx\")) {\n checkRouteModuleExports({\n file: cleanId,\n code,\n routesDir,\n projectRoot: root,\n });\n }\n await checkClientModuleImports({\n file: cleanId,\n code,\n projectRoot: root,\n // Resolusi penuh (alias Vite, tsconfig paths, symlink) — audit ronde 2.\n resolve: async (specifier, importer) => {\n try {\n const resolved = await this.resolve(specifier, importer);\n return resolved === null ? null : stripQuery(resolved.id);\n } catch {\n return null;\n }\n },\n analyze: (absoluteFile) => analysisCache.get(absoluteFile) ?? analyzeFile(absoluteFile),\n });\n }\n\n return undefined;\n },\n\n generateBundle(_options, bundle) {\n if (environmentName(this) === \"ssr\") {\n return;\n }\n\n const canary = options.leakTest?.canary;\n if (canary !== undefined && canary.length > 0) {\n const leak = findLeak(Object.values(bundle), canary);\n if (leak !== null) {\n throw new MoonsError({\n code: \"E_INTERNAL\",\n message: `canary \\`${canary}\\` ditemukan di bundle client (${leak.fileName})`,\n details:\n \"Verifikasi kebocoran §2/§9.2.8 gagal: kode server bocor ke output client. Build dihentikan.\",\n suggestions: [\n \"Periksa transform `*.server.ts` (§12)\",\n \"Jalankan `./scripts/m2/test-leak.sh` untuk audit\",\n ],\n });\n }\n }\n\n for (const output of Object.values(bundle)) {\n if (output.type !== \"chunk\") {\n continue;\n }\n for (const moduleId of Object.keys(output.modules)) {\n const cleanId = stripQuery(moduleId);\n if (!isServerFilePath(cleanId) || stubTransformed.has(cleanId)) {\n continue;\n }\n throw new MoonsError({\n code: \"E_FORBIDDEN_SERVER_IMPORT\",\n file: cleanId,\n message: \"modul server ikut ter-bundle di client tanpa melewati transform\",\n details:\n \"Verifikasi build §9.2: setiap `*.server.ts` di bundle client wajib berupa stub RPC hasil transform.\",\n suggestions: [\n \"Pastikan transform zero-trust (§12) berjalan untuk modul ini\",\n \"Laporkan ini sebagai bug framework jika berulang\",\n ],\n });\n }\n }\n },\n\n configureServer(server) {\n installDevMiddleware(server, { templatePath: resolvePath(root, \"index.html\") });\n },\n\n async handleHotUpdate(context) {\n if (isServerFilePath(context.file)) {\n refreshServerFns();\n context.server.ws.send({ type: \"full-reload\" });\n return;\n }\n\n if (!context.file.startsWith(routesDir)) {\n return;\n }\n\n try {\n routes = scanRoutes(routesDir);\n await generateTypes({\n routesDir,\n configPath: configFilePath,\n outDir: resolvePath(root, \".moons\"),\n });\n } catch (error) {\n context.server.config.logger.error(String(error));\n return;\n }\n\n invalidateVirtualModules(context.server);\n context.server.ws.send({ type: \"full-reload\" });\n },\n };\n}\n\nfunction renderConfigModule(root: string, configFilePath: string): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n `import raw from ${JSON.stringify(rootSpecifier(root, configFilePath))};`,\n 'import { validateConfig } from \"@moonsjs/core\";',\n `export default validateConfig(raw, { file: ${JSON.stringify(configFilePath)} });`,\n \"\",\n ].join(\"\\n\");\n}\n\nfunction renderServerEntryDev(routesDir: string, eagerImports: string[]): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n 'import { createRequestHandler } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n ...eagerImports.map((specifier) => `import ${JSON.stringify(specifier)};`),\n \"\",\n \"export function createDevHandler(shell) {\",\n ` return createRequestHandler({ routes, config, routesDir: ${JSON.stringify(routesDir)}, loadRoute, shell });`,\n \"}\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction renderServerEntryBuild(routesDir: string, eagerImports: string[]): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n 'import { createFileShell, createRequestHandler, startNodeServer } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n ...eagerImports.map((specifier) => `import ${JSON.stringify(specifier)};`),\n \"\",\n \"const handler = createRequestHandler({\",\n \" routes,\",\n \" config,\",\n ` routesDir: ${JSON.stringify(routesDir)},`,\n \" loadRoute,\",\n \" shell: createFileShell(),\",\n \"});\",\n \"\",\n \"startNodeServer(handler);\",\n \"\",\n ].join(\"\\n\");\n}\n\ninterface ModuleGraphLike {\n getModulesByFile(file: string): Iterable<{ id?: string | null }> | undefined;\n invalidateModule(module: unknown): void;\n}\n\nfunction environmentName(context: unknown): string {\n const environment = (context as { environment?: { name?: string } } | undefined)?.environment;\n return environment?.name ?? \"client\";\n}\n\nfunction invalidateVirtualModules(server: ViteDevServer): void {\n const graphs: ModuleGraphLike[] = [server.moduleGraph as unknown as ModuleGraphLike];\n const environments = (server as unknown as { environments?: Record<string, { moduleGraph?: unknown }> })\n .environments;\n if (environments !== undefined) {\n for (const environment of Object.values(environments)) {\n if (environment.moduleGraph !== undefined) {\n graphs.push(environment.moduleGraph as ModuleGraphLike);\n }\n }\n }\n\n for (const graph of graphs) {\n for (const name of Object.values(VIRTUAL_MODULES)) {\n for (const module of graph.getModulesByFile(`\\0${name}`) ?? []) {\n graph.invalidateModule(module);\n }\n }\n }\n}\n",
6
6
  "export interface BundleOutputLike {\n type: string;\n fileName?: string;\n code?: string;\n source?: string | Uint8Array;\n}\n\n/**\n * §9.1 (`leakTest.canary`) / §10.4: cari canary pada output bundle client.\n * Dipakai `generateBundle` plugin — build gagal bila canary ditemukan.\n */\nexport function findLeak(\n outputs: Iterable<BundleOutputLike>,\n canary: string,\n decode: (source: Uint8Array) => string = defaultDecode,\n): { fileName: string } | null {\n for (const output of outputs) {\n const fileName = output.fileName ?? \"(unknown)\";\n let text = \"\";\n if (typeof output.code === \"string\") {\n text = output.code;\n } else if (typeof output.source === \"string\") {\n text = output.source;\n } else if (output.source instanceof Uint8Array) {\n text = decode(output.source);\n }\n if (text.includes(canary)) {\n return { fileName };\n }\n }\n return null;\n}\n\nfunction defaultDecode(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n"
7
7
  ],
8
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA,oBAAS;AACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;;;ACAO,SAAS,QAAQ,CACtB,SACA,QACA,SAAyC,eACZ;AAAA,EAC7B,WAAW,UAAU,SAAS;AAAA,IAC5B,MAAM,WAAW,OAAO,YAAY;AAAA,IACpC,IAAI,OAAO;AAAA,IACX,IAAI,OAAO,OAAO,SAAS,UAAU;AAAA,MACnC,OAAO,OAAO;AAAA,IAChB,EAAO,SAAI,OAAO,OAAO,WAAW,UAAU;AAAA,MAC5C,OAAO,OAAO;AAAA,IAChB,EAAO,SAAI,OAAO,kBAAkB,YAAY;AAAA,MAC9C,OAAO,OAAO,OAAO,MAAM;AAAA,IAC7B;AAAA,IACA,IAAI,KAAK,SAAS,MAAM,GAAG;AAAA,MACzB,OAAO,EAAE,SAAS;AAAA,IACpB;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,aAAa,CAAC,OAA2B;AAAA,EAChD,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA;;;ADUvC,IAAM,oBAAoB;AAE1B,SAAwB,KAAK,CAAC,UAAkC,CAAC,GAAW;AAAA,EAC1E,IAAI,OAAO,QAAQ,eAAe,QAAQ,IAAI;AAAA,EAC9C,IAAI,aAAa;AAAA,EACjB,IAAI,iBAAiB;AAAA,EACrB,IAAI,YAAY;AAAA,EAChB,IAAI,SAA4B,CAAC;AAAA,EACjC,IAAI,gBAAgB,IAAI;AAAA,EACxB,MAAM,kBAAkB,IAAI;AAAA,EAE5B,SAAS,WAAW,CAAC,cAAiD;AAAA,IACpE,MAAM,SAAS,cAAc,IAAI,YAAY;AAAA,IAC7C,IAAI,WAAW,WAAW;AAAA,MACxB,OAAO;AAAA,IACT;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,SAAS,aAAa,cAAc,MAAM;AAAA,MAC1C,MAAM;AAAA,MACN,OAAO;AAAA;AAAA,IAET,MAAM,WAAW,mBAAkB,QAAQ,cAAc,IAAI;AAAA,IAC7D,cAAc,IAAI,cAAc,QAAQ;AAAA,IACxC,OAAO;AAAA;AAAA,EAGT,SAAS,gBAAgB,GAAS;AAAA,IAChC,MAAM,OAAO,IAAI;AAAA,IACjB,MAAM,WAAmC,CAAC;AAAA,IAE1C,WAAW,QAAQ,iBAAgB,IAAI,GAAG;AAAA,MACxC,IAAI;AAAA,MACJ,IAAI;AAAA,QACF,SAAS,aAAa,MAAM,MAAM;AAAA,QAClC,MAAM;AAAA,QACN;AAAA;AAAA,MAEF,MAAM,WAAW,mBAAkB,QAAQ,MAAM,IAAI;AAAA,MACrD,KAAK,IAAI,MAAM,QAAQ;AAAA,MACvB,WAAW,MAAM,SAAS,WAAW;AAAA,QACnC,SAAS,cAAc,MAAM,MAAM,GAAG,IAAI,KAAK,GAAG;AAAA,MACpD;AAAA,IACF;AAAA,IAEA,gBAAgB;AAAA,IAChB,MAAM,SAAS,YAAY,MAAM,QAAQ;AAAA,IACzC,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,IACrC,cACE,YAAY,QAAQ,kBAAkB,GACtC,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC;AAAA,GACnC,MACF;AAAA;AAAA,EAIF,SAAS,sBAAsB,GAAa;AAAA,IAC1C,MAAM,aAAuB,CAAC;AAAA,IAC9B,YAAY,MAAM,aAAa,eAAe;AAAA,MAC5C,IAAI,SAAS,UAAU,SAAS,GAAG;AAAA,QACjC,WAAW,KAAK,cAAc,MAAM,IAAI,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,IACA,OAAO,WAAW,KAAK;AAAA;AAAA,EAIzB,SAAS,yBAAyB,CAAC,MAAc,IAAoB;AAAA,IACnE,MAAM,eAAe,GAAG,WAAW,IAAI,IACnC,GAAG,MAAM,KAAK,MAAM,EAAE,MAAM,IAAI,EAAE,KAAK,GAAG,IAC1C;AAAA,IACJ,MAAM,WAAW,WAAW,QAAQ,EAAE,OAAO,GAAG,mBAAiB,MAAM,EAAE,OAAO,KAAK;AAAA,IACrF,MAAM,YAAY,YAAY,MAAM,gBAAgB,GAAG,aAAa;AAAA,IAEpE,IAAI,WAAW,SAAS,GAAG;AAAA,MACzB,gBAAgB,IAAI,EAAE;AAAA,MACtB,OAAO,aAAa,WAAW,MAAM;AAAA,IACvC;AAAA,IAEA,MAAM,WAAW,YAAY,EAAE;AAAA,IAC/B,IAAI,aAAa,MAAM;AAAA,MACrB,MAAM,IAAI,WAAW;AAAA,QACnB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,aAAa,CAAC,4BAA4B;AAAA,MAC5C,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,OAAO,oBAAmB,MAAM,IAAI,UAAU;AAAA,MAClD,kBAAkB,CAAC,YAAY,cAAc;AAAA,QAC3C,MAAM,WAAW,4BAA2B,YAAY,SAAS;AAAA,QACjE,OAAO,aAAa,OAAO,OAAO,YAAY,QAAQ;AAAA;AAAA,IAE1D,CAAC;AAAA,IAED,UAAU,YAAY,MAAM,cAAc,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,IAChE,cAAc,WAAW,KAAK,MAAM,MAAM;AAAA,IAC1C,gBAAgB,IAAI,EAAE;AAAA,IACtB,OAAO,KAAK;AAAA;AAAA,EAGd,OAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,MAAM,CAAC,SAAS,KAAK;AAAA,MACnB,aAAa,IAAI,eAAe;AAAA,MAChC,MAAM,SAAS;AAAA,QACb,SAAS;AAAA,MACX;AAAA,MAEA,IAAI,YAAY;AAAA,QACd,OAAO;AAAA,aACF;AAAA,UACH,OAAO;AAAA,YACL,QAAQ;AAAA,YACR,aAAa;AAAA,YAGb,KAAK;AAAA,YACL,eAAe,EAAE,QAAQ,EAAE,gBAAgB,YAAY,eAAe,MAAM,EAAE;AAAA,UAChF;AAAA,UACA,KAAK,EAAE,YAAY,MAAM,QAAQ,OAAgB;AAAA,QACnD;AAAA,MACF;AAAA,MAEA,OAAO;AAAA,WACF;AAAA,QACH,OAAO,EAAE,QAAQ,eAAe,aAAa,KAAK;AAAA,MACpD;AAAA;AAAA,SAGI,eAAc,CAAC,UAAU;AAAA,MAC7B,OAAO,QAAQ,eAAe,SAAS;AAAA,MACvC,iBAAiB,YAAY,MAAM,QAAQ,cAAc,iBAAiB;AAAA,MAE1E,IAAI,CAAC,WAAW,cAAc,GAAG;AAAA,QAC/B,MAAM,IAAI,WAAW;AAAA,UACnB,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,UACT,aAAa;AAAA,YACX;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA,IAAI;AAAA,MACJ,IAAI;AAAA,QACF,MAAM,SAAS,MAAM,mBACnB,EAAE,SAAS,SAAS,SAAS,MAAM,SAAS,KAAK,GACjD,gBACA,IACF;AAAA,QACA,MAAM,QAAQ;AAAA,QACd,OAAO,OAAO;AAAA,QACd,IAAI,iBAAiB,YAAY;AAAA,UAC/B,MAAM;AAAA,QACR;AAAA,QACA,MAAM,IAAI,WAAW;AAAA,UACnB,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC9D,aAAa,CAAC,iDAAiD;AAAA,QACjE,CAAC;AAAA;AAAA,MAGH,MAAM,SAAS,eAAe,KAAK,EAAE,MAAM,gBAAgB,aAAa,KAAK,CAAC;AAAA,MAC9E,YAAY,YAAY,MAAM,OAAO,SAAS;AAAA;AAAA,SAG1C,WAAU,GAAG;AAAA,MACjB,SAAS,WAAW,SAAS;AAAA,MAC7B,MAAM,cAAc;AAAA,QAClB;AAAA,QACA,YAAY;AAAA,QACZ,QAAQ,YAAY,MAAM,QAAQ;AAAA,MACpC,CAAC;AAAA,MACD,iBAAiB;AAAA,MACjB,IAAI,YAAY;AAAA,QACd,cACE,YAAY,MAAM,wBAAwB,GAC1C,uBAAuB,WAAW,uBAAuB,CAAC,GAC1D,MACF;AAAA,MACF;AAAA;AAAA,IAGF,SAAS,CAAC,IAAI;AAAA,MACZ,MAAM,QAAQ,GAAG,WAAW,MAAI,IAAI,GAAG,MAAM,CAAC,IAAI;AAAA,MAClD,IAAK,OAAO,OAAO,eAAe,EAAe,SAAS,KAAK,GAAG;AAAA,QAChE,OAAO,OAAK;AAAA,MACd;AAAA,MACA;AAAA;AAAA,IAGF,IAAI,CAAC,IAAI;AAAA,MACP,MAAM,OAAO,iBAAiB,EAAE;AAAA,MAChC,IAAI,SAAS,MAAM;AAAA,QACjB;AAAA,MACF;AAAA,MACA,QAAQ;AAAA,aACD,gBAAgB;AAAA,UACnB,OAAO,mBAAmB,QAAQ,WAAW,IAAI;AAAA,aAC9C,gBAAgB;AAAA,UACnB,OAAO;AAAA;AAAA;AAAA,aACJ,gBAAgB;AAAA,UACnB,OAAO,mBAAmB,MAAM,cAAc;AAAA,aAC3C,gBAAgB;AAAA,UAEnB,OAAO,qBAAqB,WAAW,uBAAuB,CAAC;AAAA;AAAA;AAAA,SAI/D,UAAS,CAAC,MAAM,IAAI;AAAA,MACxB,MAAM,UAAU,YAAW,EAAE;AAAA,MAC7B,IAAI,QAAQ,WAAW,MAAI,KAAK,QAAQ,SAAS,gBAAgB,GAAG;AAAA,QAClE;AAAA,MACF;AAAA,MAEA,MAAM,cAAc,gBAAgB,IAAI;AAAA,MAExC,IAAI,kBAAiB,OAAO,GAAG;AAAA,QAC7B,IAAI,gBAAgB,OAAO;AAAA,UACzB,MAAM,WAAW,cAAc,IAAI,OAAO,KAAK,YAAY,OAAO;AAAA,UAClE,IAAI,aAAa,QAAQ,SAAS,UAAU,WAAW,GAAG;AAAA,YACxD;AAAA,UACF;AAAA,UACA,OAAO,oBAAmB,MAAM,UAAU,IAAI;AAAA,QAChD;AAAA,QACA,OAAO,0BAA0B,MAAM,OAAO;AAAA,MAChD;AAAA,MAIA,IAAI,gBAAgB,SAAS,yBAAwB,OAAO,GAAG;AAAA,QAC7D,MAAM,4BAA2B,SAAS,IAAI;AAAA,MAChD;AAAA,MAEA,IAAI,gBAAgB,SAAS,kBAAkB,KAAK,OAAO,GAAG;AAAA,QAC5D,IAAI,QAAQ,WAAW,SAAS,KAAK,QAAQ,SAAS,MAAM,GAAG;AAAA,UAC7D,yBAAwB;AAAA,YACtB,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,QACA,MAAM,0BAAyB;AAAA,UAC7B,MAAM;AAAA,UACN;AAAA,UACA,aAAa;AAAA,UAEb,SAAS,OAAO,WAAW,aAAa;AAAA,YACtC,IAAI;AAAA,cACF,MAAM,WAAW,MAAM,KAAK,QAAQ,WAAW,QAAQ;AAAA,cACvD,OAAO,aAAa,OAAO,OAAO,YAAW,SAAS,EAAE;AAAA,cACxD,MAAM;AAAA,cACN,OAAO;AAAA;AAAA;AAAA,UAGX,SAAS,CAAC,iBAAiB,cAAc,IAAI,YAAY,KAAK,YAAY,YAAY;AAAA,QACxF,CAAC;AAAA,MACH;AAAA,MAEA;AAAA;AAAA,IAGF,cAAc,CAAC,UAAU,QAAQ;AAAA,MAC/B,IAAI,gBAAgB,IAAI,MAAM,OAAO;AAAA,QACnC;AAAA,MACF;AAAA,MAEA,MAAM,SAAS,QAAQ,UAAU;AAAA,MACjC,IAAI,WAAW,aAAa,OAAO,SAAS,GAAG;AAAA,QAC7C,MAAM,OAAO,SAAS,OAAO,OAAO,MAAM,GAAG,MAAM;AAAA,QACnD,IAAI,SAAS,MAAM;AAAA,UACjB,MAAM,IAAI,WAAW;AAAA,YACnB,MAAM;AAAA,YACN,SAAS,YAAY,wCAAwC,KAAK;AAAA,YAClE,SACE;AAAA,YACF,aAAa;AAAA,cACX;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MAEA,WAAW,UAAU,OAAO,OAAO,MAAM,GAAG;AAAA,QAC1C,IAAI,OAAO,SAAS,SAAS;AAAA,UAC3B;AAAA,QACF;AAAA,QACA,WAAW,YAAY,OAAO,KAAK,OAAO,OAAO,GAAG;AAAA,UAClD,MAAM,UAAU,YAAW,QAAQ;AAAA,UACnC,IAAI,CAAC,kBAAiB,OAAO,KAAK,gBAAgB,IAAI,OAAO,GAAG;AAAA,YAC9D;AAAA,UACF;AAAA,UACA,MAAM,IAAI,WAAW;AAAA,YACnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SACE;AAAA,YACF,aAAa;AAAA,cACX;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA,IAGF,eAAe,CAAC,QAAQ;AAAA,MACtB,sBAAqB,QAAQ,EAAE,cAAc,YAAY,MAAM,YAAY,EAAE,CAAC;AAAA;AAAA,SAG1E,gBAAe,CAAC,SAAS;AAAA,MAC7B,IAAI,kBAAiB,QAAQ,IAAI,GAAG;AAAA,QAClC,iBAAiB;AAAA,QACjB,QAAQ,OAAO,GAAG,KAAK,EAAE,MAAM,cAAc,CAAC;AAAA,QAC9C;AAAA,MACF;AAAA,MAEA,IAAI,CAAC,QAAQ,KAAK,WAAW,SAAS,GAAG;AAAA,QACvC;AAAA,MACF;AAAA,MAEA,IAAI;AAAA,QACF,SAAS,WAAW,SAAS;AAAA,QAC7B,MAAM,cAAc;AAAA,UAClB;AAAA,UACA,YAAY;AAAA,UACZ,QAAQ,YAAY,MAAM,QAAQ;AAAA,QACpC,CAAC;AAAA,QACD,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO,OAAO,OAAO,MAAM,OAAO,KAAK,CAAC;AAAA,QAChD;AAAA;AAAA,MAGF,yBAAyB,QAAQ,MAAM;AAAA,MACvC,QAAQ,OAAO,GAAG,KAAK,EAAE,MAAM,cAAc,CAAC;AAAA;AAAA,EAElD;AAAA;AAGF,SAAS,kBAAkB,CAAC,MAAc,gBAAgC;AAAA,EACxE,OAAO;AAAA,IACL;AAAA,IACA,mBAAmB,KAAK,UAAU,cAAc,MAAM,cAAc,CAAC;AAAA,IACrE;AAAA,IACA,8CAA8C,KAAK,UAAU,cAAc;AAAA,IAC3E;AAAA,EACF,EAAE,KAAK;AAAA,CAAI;AAAA;AAGb,SAAS,oBAAoB,CAAC,WAAmB,cAAgC;AAAA,EAC/E,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,aAAa,IAAI,CAAC,cAAc,UAAU,KAAK,UAAU,SAAS,IAAI;AAAA,IACzE;AAAA,IACA;AAAA,IACA,8DAA8D,KAAK,UAAU,SAAS;AAAA,IACtF;AAAA,IACA;AAAA,EACF,EAAE,KAAK;AAAA,CAAI;AAAA;AAGb,SAAS,sBAAsB,CAAC,WAAmB,cAAgC;AAAA,EACjF,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,aAAa,IAAI,CAAC,cAAc,UAAU,KAAK,UAAU,SAAS,IAAI;AAAA,IACzE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB,KAAK,UAAU,SAAS;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK;AAAA,CAAI;AAAA;AAQb,SAAS,eAAe,CAAC,SAA0B;AAAA,EACjD,MAAM,cAAe,SAA6D;AAAA,EAClF,OAAO,aAAa,QAAQ;AAAA;AAG9B,SAAS,wBAAwB,CAAC,QAA6B;AAAA,EAC7D,MAAM,SAA4B,CAAC,OAAO,WAAyC;AAAA,EACnF,MAAM,eAAgB,OACnB;AAAA,EACH,IAAI,iBAAiB,WAAW;AAAA,IAC9B,WAAW,eAAe,OAAO,OAAO,YAAY,GAAG;AAAA,MACrD,IAAI,YAAY,gBAAgB,WAAW;AAAA,QACzC,OAAO,KAAK,YAAY,WAA8B;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,SAAS,QAAQ;AAAA,IAC1B,WAAW,QAAQ,OAAO,OAAO,eAAe,GAAG;AAAA,MACjD,WAAW,UAAU,MAAM,iBAAiB,OAAK,MAAM,KAAK,CAAC,GAAG;AAAA,QAC9D,MAAM,iBAAiB,MAAM;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA;",
9
- "debugId": "B0BD6103F707A0BE64756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "A336EA74F6CC12EF64756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAWA,OAAO,EAAsB,KAAK,MAAM,EAAsB,MAAM,MAAM,CAAC;AAoB3E,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,QAAQ,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAQD,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CA2V1E"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAWA,OAAO,EAAsB,KAAK,MAAM,EAAsB,MAAM,MAAM,CAAC;AAoB3E,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,QAAQ,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAQD,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAmW1E"}
@@ -1,7 +1,7 @@
1
1
  import type { ViteDevServer } from "vite";
2
2
  /**
3
- * Middleware SSR dev: dipasang sebelum middleware internal Vite, hanya
4
- * menangani request HTML (modul/aset tetap dilayani Vite).
3
+ * Middleware SSR dev: dipasang sebelum middleware internal Vite, menangani
4
+ * request HTML dan RPC serverFn (`/_moons/fn/*`) — modul/aset tetap Vite.
5
5
  */
6
6
  export declare function installDevMiddleware(server: ViteDevServer, options: {
7
7
  templatePath: string;
@@ -9,7 +9,7 @@ import {
9
9
  toWebRequest2,
10
10
  sendNodeResponse2,
11
11
  installDevMiddleware2
12
- } from "../index-8xq8fcgq.js";
12
+ } from "../index-1sm9pvvd.js";
13
13
 
14
14
  // src/server/handler.ts
15
15
  import {
@@ -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-fg6nqart.js";
16
+ } from "./index-3ec9vpek.js";
17
17
  export {
18
18
  analyzeServerFile2 as analyzeServerFile,
19
19
  buildFnRegistry2 as buildFnRegistry,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moonsjs/vite",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
package/src/plugin.ts CHANGED
@@ -173,6 +173,14 @@ export default function moons(options: MoonsVitePluginOptions = {}): Plugin {
173
173
  return {
174
174
  ...common,
175
175
  build: { outDir: "dist/client", emptyOutDir: true },
176
+ // Dev SSR: paket framework WAJIB di-inline ke pipeline Vite. Sejak
177
+ // dipublikasikan, `@moonsjs/*` adalah package node_modules biasa (bukan
178
+ // workspace-link) sehingga default Vite mengeksternalnya; import runtime
179
+ // (bun) menyelesaikannya lewat kondisi `bun` → `src`, sedangkan modul
180
+ // route diselesaikan Vite → `dist` — dua instans React context →
181
+ // "useLoaderData dipanggil di luar render route" (temuan eval T4;
182
+ // docs/decisions/0015). Inline → semua konsisten lewat Vite.
183
+ ssr: { noExternal: [/^@moonsjs\//] },
176
184
  };
177
185
  },
178
186
 
package/src/server/dev.ts CHANGED
@@ -10,15 +10,15 @@ type DevServerEntry = {
10
10
  };
11
11
 
12
12
  /**
13
- * Middleware SSR dev: dipasang sebelum middleware internal Vite, hanya
14
- * menangani request HTML (modul/aset tetap dilayani Vite).
13
+ * Middleware SSR dev: dipasang sebelum middleware internal Vite, menangani
14
+ * request HTML dan RPC serverFn (`/_moons/fn/*`) — modul/aset tetap Vite.
15
15
  */
16
16
  export function installDevMiddleware(
17
17
  server: ViteDevServer,
18
18
  options: { templatePath: string },
19
19
  ): void {
20
20
  server.middlewares.use((req, res, next) => {
21
- if (!isHtmlRequest(req)) {
21
+ if (!shouldHandle(req)) {
22
22
  next();
23
23
  return;
24
24
  }
@@ -37,11 +37,19 @@ function handleRequest(server: ViteDevServer, options: { templatePath: string })
37
37
  };
38
38
  }
39
39
 
40
- function isHtmlRequest(req: IncomingMessage): boolean {
40
+ function shouldHandle(req: IncomingMessage): boolean {
41
+ const path = new URL(req.url ?? "/", "http://localhost").pathname;
42
+
43
+ // RPC serverFn (semua method): dulu hanya GET/HEAD HTML yang dirutekan,
44
+ // sehingga `POST /_moons/fn/<hash>` jatuh ke Vite ("Cannot POST", 404) dan
45
+ // serverFn tidak bisa dipakai di dev (temuan eval T2 ronde 2; decisions/0016).
46
+ if (path.startsWith("/_moons/fn/")) {
47
+ return true;
48
+ }
49
+
41
50
  if (req.method !== "GET" && req.method !== "HEAD") {
42
51
  return false;
43
52
  }
44
- const path = new URL(req.url ?? "/", "http://localhost").pathname;
45
53
  if (path.startsWith("/@") || path.startsWith("/node_modules/") || path.startsWith("/__")) {
46
54
  return false;
47
55
  }
package/src/transform.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MoonsError, computeFnHash, fnRegistryKey } from "@moonsjs/core";
2
- import { parse } from "@babel/parser";
2
+ import { parse, parseExpression } from "@babel/parser";
3
3
  import { existsSync, readdirSync, readFileSync, realpathSync } from "node:fs";
4
4
  import { dirname, isAbsolute, join, resolve } from "node:path";
5
5
 
@@ -307,6 +307,114 @@ function escapeRegExp(text: string): string {
307
307
  return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
308
308
  }
309
309
 
310
+ function collectPatternNames(node: AstNode | undefined, into: Set<string>): void {
311
+ if (node === undefined) {
312
+ return;
313
+ }
314
+ switch (node.type) {
315
+ case "Identifier": {
316
+ const name = node["name"] as string | undefined;
317
+ if (name !== undefined) {
318
+ into.add(name);
319
+ }
320
+ return;
321
+ }
322
+ case "ObjectPattern":
323
+ for (const property of (node["properties"] ?? []) as AstNode[]) {
324
+ collectPatternNames(
325
+ (property.type === "RestElement" ? property["argument"] : property["value"]) as
326
+ | AstNode
327
+ | undefined,
328
+ into,
329
+ );
330
+ }
331
+ return;
332
+ case "ArrayPattern":
333
+ for (const element of (node["elements"] ?? []) as AstNode[]) {
334
+ collectPatternNames(element, into);
335
+ }
336
+ return;
337
+ case "AssignmentPattern":
338
+ collectPatternNames(node["left"] as AstNode | undefined, into);
339
+ return;
340
+ case "RestElement":
341
+ collectPatternNames(node["argument"] as AstNode | undefined, into);
342
+ return;
343
+ default:
344
+ return;
345
+ }
346
+ }
347
+
348
+ /** Nama deklarasi nilai top-level (bukan import) — yang DIBUANG dari stub §12.3. */
349
+ function localTopLevelNames(ast: AstNode): Set<string> {
350
+ const names = new Set<string>();
351
+ const declare = (decl: AstNode | null | undefined): void => {
352
+ if (decl === undefined || decl === null) {
353
+ return;
354
+ }
355
+ if (decl.type === "VariableDeclaration") {
356
+ for (const declarator of (decl["declarations"] ?? []) as AstNode[]) {
357
+ collectPatternNames(declarator["id"] as AstNode | undefined, names);
358
+ }
359
+ return;
360
+ }
361
+ if (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration") {
362
+ const name = ((decl["id"] as AstNode | undefined)?.["name"] as string | undefined) ?? "";
363
+ if (name.length > 0) {
364
+ names.add(name);
365
+ }
366
+ }
367
+ };
368
+
369
+ for (const statement of topLevelStatements(ast)) {
370
+ if (statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration") {
371
+ declare(statement["declaration"] as AstNode | null | undefined);
372
+ } else {
373
+ declare(statement);
374
+ }
375
+ }
376
+ return names;
377
+ }
378
+
379
+ /** Identifier posisi-nilai yang direferensikan di dalam ekspresi (key/member di-skip). */
380
+ function referencedIdentifiers(expression: string, filename: string): Set<string> {
381
+ const ast = parseExpression(expression, {
382
+ plugins: filename.endsWith(".tsx") ? ["typescript", "jsx"] : ["typescript"],
383
+ }) as unknown as AstNode;
384
+ const names = new Set<string>();
385
+
386
+ walk(ast, (node, ancestors) => {
387
+ if (node.type !== "Identifier") {
388
+ return;
389
+ }
390
+ const parent = ancestors[ancestors.length - 1];
391
+ if (parent !== undefined) {
392
+ const parentType = parent.type as string;
393
+ const nonComputed = parent["computed"] !== true;
394
+ if (
395
+ nonComputed &&
396
+ (parentType === "MemberExpression" || parentType === "OptionalMemberExpression") &&
397
+ parent["property"] === node
398
+ ) {
399
+ return;
400
+ }
401
+ if (
402
+ nonComputed &&
403
+ (parentType === "ObjectProperty" ||
404
+ parentType === "ObjectMethod" ||
405
+ parentType === "ClassProperty" ||
406
+ parentType === "TSPropertySignature") &&
407
+ parent["key"] === node
408
+ ) {
409
+ return;
410
+ }
411
+ }
412
+ names.add((node["name"] as string | undefined) ?? "");
413
+ });
414
+
415
+ return names;
416
+ }
417
+
310
418
  export interface StubDependencies {
311
419
  /** Resolve specifier relatif file sumber → analysis (null bila tidak bisa). */
312
420
  analyzeSpecifier: (sourceFile: string, specifier: string) => ServerFileAnalysis | null;
@@ -330,6 +438,7 @@ export function renderServerFnStub(
330
438
  ): RenderStubResult {
331
439
  const ast = parseModule(source, filename);
332
440
  const retainedText = collectRetainedText(source, analysis);
441
+ const localNames = localTopLevelNames(ast);
333
442
  const importLines: string[] = [];
334
443
  const referenced: string[] = [];
335
444
  let needsCreateStub = analysis.serverFns.length > 0;
@@ -389,6 +498,34 @@ export function renderServerFnStub(
389
498
  for (const fn of analysis.serverFns) {
390
499
  const input = source.slice(fn.input.start, fn.input.end);
391
500
  const output = source.slice(fn.output.start, fn.output.end);
501
+
502
+ // E_SCHEMA_LOCAL_REF: deklarasi lokal dibuang dari stub, jadi referensinya
503
+ // menjadi `undefined` di browser (crash hydration — dulu lolos build).
504
+ for (const [kind, slice] of [
505
+ ["input", input],
506
+ ["output", output],
507
+ ] as const) {
508
+ for (const reference of referencedIdentifiers(slice, filename)) {
509
+ if (reference.length === 0 || !localNames.has(reference)) {
510
+ continue;
511
+ }
512
+ throw new MoonsError({
513
+ code: "E_SCHEMA_LOCAL_REF",
514
+ file: filename,
515
+ line: fn.line,
516
+ annotation: fn.name,
517
+ message: `schema ${kind} serverFn \`${fn.name}\` merujuk deklarasi lokal \`${reference}\``,
518
+ details:
519
+ "Stub client (PRD §12.2/§12.3) hanya membawa import dan ekspresi schema; " +
520
+ "deklarasi lokal dibuang sehingga referensi menjadi `undefined` di browser (crash hydration).",
521
+ suggestions: [
522
+ "Inline schema langsung di argumen `serverFn({ input, output })`, atau",
523
+ "Impor schema dari modul lain (mis. `src/shared/schemas.ts`)",
524
+ ],
525
+ });
526
+ }
527
+ }
528
+
392
529
  exportLines.push(
393
530
  `export const ${fn.name} = __moons_createStub({ hash: ${JSON.stringify(fn.hash)}, input: ${input}, output: ${output} });`,
394
531
  );
@@ -600,7 +737,7 @@ export async function checkClientModuleImports(
600
737
  details,
601
738
  suggestions: [
602
739
  "Buat server function yang mengembalikan data yang dibutuhkan, atau",
603
- "Pindahkan nilai itu ke file yang tidak berakhiran .server.ts",
740
+ "Jika nilainya memang publik, definisikan ulang konstanta itu di modul yang boleh masuk client (jangan memindahkan nilai rahasia)",
604
741
  ],
605
742
  });
606
743
  };
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/transform.ts"],
4
- "sourcesContent": [
5
- "import { MoonsError, computeFnHash, fnRegistryKey } from \"@moonsjs/core\";\nimport { parse } from \"@babel/parser\";\nimport { existsSync, readdirSync, readFileSync, realpathSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\n\n/**\n * Spec §12: analisis `.server.ts` + stub client + injeksi meta server +\n * penolakan import (E_SERVER_IMPORT_IN_CLIENT / E_FORBIDDEN_SERVER_IMPORT).\n */\n\nexport interface ServerFnInfo {\n name: string;\n hash: string;\n line: number;\n input: { start: number; end: number };\n output: { start: number; end: number };\n objectStart: number;\n}\n\nexport interface ServerFileAnalysis {\n /** Absolute path. */\n file: string;\n serverFns: ServerFnInfo[];\n /** Semua nama export top-level (langsung). */\n exportNames: string[];\n /** Pernyataan `export { X as Y } from \"./z.server\"` (untuk resolusi re-export). */\n reExports: Array<{ source: string; names: Array<{ local: string; exported: string }> }>;\n /** `export * from \"./z.server\"`. */\n exportAllFrom: string[];\n}\n\ninterface AstNode {\n type: string;\n start: number | null;\n end: number | null;\n loc?: { start: { line: number } } | null;\n [key: string]: unknown;\n}\n\nconst SERVER_SPECIFIER = /\\.server(\\.(ts|tsx|js|jsx|mts|cts|mjs|cjs))?$/i;\nconst CONTRACT_SERVER_FILE = /\\.server\\.(ts|tsx)$/i;\nconst NON_CONTRACT_SERVER_FILE = /\\.server\\.(js|jsx|mts|cts|mjs|cjs)$/i;\n\nexport function isServerFilePath(path: string): boolean {\n return CONTRACT_SERVER_FILE.test(stripQuery(path));\n}\n\n/** File server dengan ekstensi di luar kontrak §12 (tidak bisa di-stub). */\nexport function isNonContractServerFile(path: string): boolean {\n return NON_CONTRACT_SERVER_FILE.test(stripQuery(path));\n}\n\nexport function isServerSpecifier(specifier: string): boolean {\n return SERVER_SPECIFIER.test(specifier);\n}\n\n/**\n * Resolusi sinkron untuk specifier `*.server` (relatif/absolut).\n * Import alias/virtual untuk file server tidak didukung — tidak dibutuhkan app.\n */\nexport function resolveServerSpecifierSync(importerFile: string, specifier: string): string | null {\n if (!isServerSpecifier(specifier)) {\n return null;\n }\n const base = specifier.startsWith(\".\")\n ? resolve(dirname(importerFile), specifier)\n : isAbsolute(specifier)\n ? specifier\n : null;\n if (base === null) {\n return null;\n }\n for (const candidate of [base, `${base}.ts`, `${base}.tsx`]) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n return null;\n}\n\nexport function stripQuery(id: string): string {\n const queryIndex = id.indexOf(\"?\");\n return queryIndex === -1 ? id : id.slice(0, queryIndex);\n}\n\nfunction parseModule(code: string, filename: string): AstNode {\n return parse(code, {\n sourceType: \"module\",\n plugins: filename.endsWith(\".tsx\") ? [\"typescript\", \"jsx\"] : [\"typescript\"],\n errorRecovery: false,\n }) as unknown as AstNode;\n}\n\nfunction walk(\n node: unknown,\n visit: (node: AstNode, ancestors: AstNode[]) => void,\n ancestors: AstNode[] = [],\n): void {\n if (node === null || typeof node !== \"object\") {\n return;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n walk(item, visit, ancestors);\n }\n return;\n }\n const candidate = node as AstNode;\n if (typeof candidate.type !== \"string\" || typeof candidate.start !== \"number\") {\n return;\n }\n visit(candidate, ancestors);\n const nextAncestors = [...ancestors, candidate];\n for (const key of Object.keys(candidate)) {\n if (key === \"loc\" || key === \"start\" || key === \"end\" || key === \"extra\") {\n continue;\n }\n walk(candidate[key], visit, nextAncestors);\n }\n}\n\nfunction topLevelStatements(ast: AstNode): AstNode[] {\n const program = ast[\"program\"] as { body?: AstNode[] } | undefined;\n return program?.body ?? [];\n}\n\nfunction keyName(node: unknown): string | null {\n const key = node as AstNode | undefined;\n if (key?.type === \"Identifier\") {\n return key[\"name\"] as string;\n }\n if (key?.type === \"StringLiteral\") {\n return key[\"value\"] as string;\n }\n return null;\n}\n\nfunction extractServerFnInit(init: unknown): {\n input: { start: number; end: number };\n output: { start: number; end: number };\n line: number;\n objectStart: number;\n} | null {\n const call = init as AstNode | undefined;\n if (call?.type !== \"CallExpression\") {\n return null;\n }\n const callee = call[\"callee\"] as AstNode | undefined;\n if (callee?.type !== \"Identifier\" || callee[\"name\"] !== \"serverFn\") {\n return null;\n }\n const args = (call[\"arguments\"] ?? []) as AstNode[];\n const first = args[0];\n if (first?.type !== \"ObjectExpression\") {\n return null;\n }\n\n const properties = new Map<string, AstNode>();\n for (const property of (first[\"properties\"] ?? []) as AstNode[]) {\n if (property.type !== \"ObjectProperty\") {\n continue;\n }\n const name = keyName(property[\"key\"]);\n if (name !== null) {\n properties.set(name, property);\n }\n }\n\n const input = properties.get(\"input\")?.[\"value\"] as AstNode | undefined;\n const output = properties.get(\"output\")?.[\"value\"] as AstNode | undefined;\n if (\n input?.start == null ||\n input.end == null ||\n output?.start == null ||\n output.end == null\n ) {\n return null;\n }\n\n return {\n input: { start: input.start, end: input.end },\n output: { start: output.start, end: output.end },\n line: call.loc?.start.line ?? 1,\n objectStart: first.start ?? 0,\n };\n}\n\nexport function analyzeServerFile(\n source: string,\n filename: string,\n projectRoot: string,\n): ServerFileAnalysis {\n const ast = parseModule(source, filename);\n const serverFns: ServerFnInfo[] = [];\n const exportNames: string[] = [];\n const reExports: ServerFileAnalysis[\"reExports\"] = [];\n const exportAllFrom: string[] = [];\n\n for (const statement of topLevelStatements(ast)) {\n if (statement.type === \"ExportNamedDeclaration\") {\n const declaration = statement[\"declaration\"] as AstNode | null | undefined;\n\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of (declaration[\"declarations\"] ?? []) as AstNode[]) {\n const id = declarator[\"id\"] as AstNode | undefined;\n if (id?.type !== \"Identifier\") {\n continue;\n }\n const name = id[\"name\"] as string;\n exportNames.push(name);\n const info = extractServerFnInit(declarator[\"init\"]);\n if (info !== null) {\n serverFns.push({\n name,\n hash: computeFnHash(projectRoot, filename, name),\n line: info.line,\n input: info.input,\n output: info.output,\n objectStart: info.objectStart,\n });\n }\n }\n } else if (declaration?.type === \"FunctionDeclaration\") {\n const id = declaration[\"id\"] as AstNode | undefined;\n if (id?.type === \"Identifier\") {\n exportNames.push(id[\"name\"] as string);\n }\n }\n\n for (const specifier of (statement[\"specifiers\"] ?? []) as AstNode[]) {\n const exported = specifier[\"exported\"] as AstNode | undefined;\n if (exported?.type === \"Identifier\") {\n exportNames.push(exported[\"name\"] as string);\n }\n }\n\n const sourceNode = statement[\"source\"] as AstNode | undefined;\n if (sourceNode?.type === \"StringLiteral\" && isServerSpecifier(sourceNode[\"value\"] as string)) {\n reExports.push({\n source: sourceNode[\"value\"] as string,\n names: ((statement[\"specifiers\"] ?? []) as AstNode[]).map((specifier) => ({\n local: ((specifier[\"local\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\",\n exported: (((specifier[\"exported\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\"),\n })),\n });\n }\n } else if (statement.type === \"ExportDefaultDeclaration\") {\n exportNames.push(\"default\");\n } else if (statement.type === \"ExportAllDeclaration\") {\n const sourceNode = statement[\"source\"] as AstNode | undefined;\n if (sourceNode?.type === \"StringLiteral\" && isServerSpecifier(sourceNode[\"value\"] as string)) {\n exportAllFrom.push(sourceNode[\"value\"] as string);\n }\n }\n }\n\n return { file: filename, serverFns, exportNames, reExports, exportAllFrom };\n}\n\n/** Nama-nama yang diekspor sebagai serverFn stub dari file (langsung atau via re-export). */\nexport function serverFnExportNames(\n analysis: ServerFileAnalysis,\n analyzeTarget: (specifier: string) => ServerFileAnalysis | null,\n seen = new Set<string>(),\n): Set<string> {\n const names = new Set(analysis.serverFns.map((fn) => fn.name));\n\n for (const reExport of analysis.reExports) {\n const target = analyzeTarget(reExport.source);\n if (target === null || seen.has(reExport.source)) {\n continue;\n }\n seen.add(reExport.source);\n const targetNames = serverFnExportNames(target, analyzeTarget, seen);\n for (const { local, exported } of reExport.names) {\n if (local === \"*\" || targetNames.has(local)) {\n names.add(exported);\n }\n }\n }\n\n for (const specifier of analysis.exportAllFrom) {\n const target = analyzeTarget(specifier);\n if (target === null || seen.has(specifier)) {\n continue;\n }\n seen.add(specifier);\n for (const name of serverFnExportNames(target, analyzeTarget, seen)) {\n names.add(name);\n }\n }\n\n return names;\n}\n\nfunction collectRetainedText(source: string, analysis: ServerFileAnalysis): string {\n return analysis.serverFns\n .map((fn) => `${source.slice(fn.input.start, fn.input.end)}\\n${source.slice(fn.output.start, fn.output.end)}`)\n .join(\"\\n\");\n}\n\nfunction isUsed(name: string, retainedText: string): boolean {\n return new RegExp(`(^|[^\\\\w$])${escapeRegExp(name)}([^\\\\w$]|$)`).test(retainedText);\n}\n\nfunction escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nexport interface StubDependencies {\n /** Resolve specifier relatif file sumber → analysis (null bila tidak bisa). */\n analyzeSpecifier: (sourceFile: string, specifier: string) => ServerFileAnalysis | null;\n}\n\nexport interface RenderStubResult {\n code: string;\n /** Specifier server file yang di-referensikan (untuk keperluan cache/diagnostik). */\n referenced: string[];\n}\n\n/**\n * Bangun stub client §12.2/§12.3 dari sumber `.server.ts`:\n * hanya import yang dipakai schema + `__moons_createStub` per serverFn.\n */\nexport function renderServerFnStub(\n source: string,\n filename: string,\n analysis: ServerFileAnalysis,\n dependencies: StubDependencies,\n): RenderStubResult {\n const ast = parseModule(source, filename);\n const retainedText = collectRetainedText(source, analysis);\n const importLines: string[] = [];\n const referenced: string[] = [];\n let needsCreateStub = analysis.serverFns.length > 0;\n\n for (const statement of topLevelStatements(ast)) {\n if (statement.type !== \"ImportDeclaration\") {\n continue;\n }\n const sourceNode = statement[\"source\"] as AstNode;\n const specifier = sourceNode[\"value\"] as string;\n\n if (/^@moons\\/server(\\/|$)/.test(specifier)) {\n continue; // serverFn/env tidak dibawa ke client (§12.2)\n }\n if (specifier.startsWith(\"node:\") || specifier.startsWith(\"bun:\")) {\n continue; // import server-only dibuang\n }\n\n const specifiers = (statement[\"specifiers\"] ?? []) as AstNode[];\n const kept: AstNode[] = [];\n\n if (isServerSpecifier(specifier)) {\n referenced.push(specifier);\n for (const item of specifiers) {\n if (item.type === \"ImportDefaultSpecifier\" || item.type === \"ImportNamespaceSpecifier\") {\n continue; // default / * as dari *.server → dibuang (§12.2)\n }\n const local = ((item[\"local\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\";\n if (local.length > 0 && isUsed(local, retainedText)) {\n kept.push(item);\n }\n }\n } else {\n for (const item of specifiers) {\n const local = ((item[\"local\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\";\n if (local.length > 0 && isUsed(local, retainedText)) {\n kept.push(item);\n }\n }\n }\n\n if (kept.length === 0) {\n continue; // import tak terpakai → dipangkas (§12.3)\n }\n\n const keptText = kept\n .map((item) => source.slice(item.start ?? 0, item.end ?? 0))\n .join(\", \");\n importLines.push(`import { ${keptText} } from ${JSON.stringify(specifier)};`);\n }\n\n if (needsCreateStub) {\n importLines.push('import { __moons_createStub } from \"@moonsjs/server/client\";');\n }\n\n const exportLines: string[] = [];\n for (const fn of analysis.serverFns) {\n const input = source.slice(fn.input.start, fn.input.end);\n const output = source.slice(fn.output.start, fn.output.end);\n exportLines.push(\n `export const ${fn.name} = __moons_createStub({ hash: ${JSON.stringify(fn.hash)}, input: ${input}, output: ${output} });`,\n );\n }\n\n for (const reExport of analysis.reExports) {\n const target = dependencies.analyzeSpecifier(filename, reExport.source);\n if (target === null) {\n throw new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: filename,\n message: `tidak bisa me-resolve \\`${reExport.source}\\` untuk re-export`,\n details: \"Re-export dari `*.server.ts` harus bisa di-resolve statis (PRD §12.6).\",\n suggestions: [\"Perbaiki path re-export\", \"Hindari re-export dinamis dari file server\"],\n });\n }\n const targetNames = serverFnExportNames(target, (specifier) =>\n dependencies.analyzeSpecifier(filename, specifier),\n );\n const keptNames = reExport.names.filter(({ local }) => local !== \"\" && targetNames.has(local));\n if (keptNames.length > 0) {\n const specifiers = keptNames\n .map(({ local, exported }) => (local === exported ? local : `${local} as ${exported}`))\n .join(\", \");\n exportLines.push(`export { ${specifiers} } from ${JSON.stringify(reExport.source)};`);\n }\n }\n\n for (const specifier of analysis.exportAllFrom) {\n const target = dependencies.analyzeSpecifier(filename, specifier);\n if (target === null) {\n throw new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: filename,\n message: `\\`export *\\` dari \\`${specifier}\\` tidak bisa di-resolve`,\n details: \"`export *` dari `*.server.ts` wajib bisa di-expand statis (PRD §12.6).\",\n suggestions: [\"Perbaiki path re-export\", \"Ganti menjadi named re-export\"],\n });\n }\n const targetNames = serverFnExportNames(target, (nested) =>\n dependencies.analyzeSpecifier(filename, nested),\n );\n if (targetNames.size > 0) {\n exportLines.push(\n `export { ${[...targetNames].join(\", \")} } from ${JSON.stringify(specifier)};`,\n );\n }\n }\n\n if (importLines.length === 0 && exportLines.length === 0) {\n return { code: \"// @moons: tidak ada serverFn yang di-export\\nexport {};\\n\", referenced };\n }\n\n return { code: `${[...importLines, \"\", ...exportLines].join(\"\\n\")}\\n`, referenced };\n}\n\n/** Inject meta §7.2 ke deklarasi serverFn (env ssr; handler tetap utuh). */\nexport function injectServerFnMeta(\n source: string,\n analysis: ServerFileAnalysis,\n projectRoot: string,\n): string {\n let output = source;\n const inserts = [...analysis.serverFns].sort((a, b) => b.objectStart - a.objectStart);\n\n for (const fn of inserts) {\n const meta =\n ` __hash: ${JSON.stringify(fn.hash)},` +\n ` __file: ${JSON.stringify(fnRegistryKey(projectRoot, analysis.file, fn.name).split(\"#\")[0] as string)},` +\n ` __line: ${fn.line},` +\n ` __exportName: ${JSON.stringify(fn.name)},`;\n const at = fn.objectStart + 1;\n output = output.slice(0, at) + meta + output.slice(at);\n }\n\n return output;\n}\n\nexport interface ClientImportCheckContext {\n /** Absolute path file yang sedang diperiksa. */\n file: string;\n code: string;\n projectRoot: string;\n /**\n * Resolve specifier dengan importer tertentu → absolute path (null bila tidak\n * ada). Boleh sinkron maupun async (plugin memakai `this.resolve`, sehingga\n * alias Vite & `tsconfig paths` ikut terperiksa — audit ronde 2).\n */\n resolve: (specifier: string, importer: string) => string | null | Promise<string | null>;\n /** Analysis untuk file server (hasil cache plugin). */\n analyze: (absoluteFile: string) => ServerFileAnalysis | null;\n}\n\n/** Nama serverFn (langsung atau via re-export) — versi async untuk pemeriksaan resolve. */\nasync function serverFnExportNamesAsync(\n analysis: ServerFileAnalysis,\n analyzeSpecifier: (specifier: string, importer: string) => Promise<ServerFileAnalysis | null>,\n seen = new Set<string>(),\n): Promise<Set<string>> {\n const names = new Set(analysis.serverFns.map((fn) => fn.name));\n\n for (const reExport of analysis.reExports) {\n const key = `${analysis.file}\\0${reExport.source}`;\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n const target = await analyzeSpecifier(reExport.source, analysis.file);\n if (target === null) {\n continue;\n }\n const targetNames = await serverFnExportNamesAsync(target, analyzeSpecifier, seen);\n for (const { local, exported } of reExport.names) {\n if (local === \"*\" || targetNames.has(local)) {\n names.add(exported);\n }\n }\n }\n\n for (const specifier of analysis.exportAllFrom) {\n const key = `${analysis.file}\\0${specifier}`;\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n const target = await analyzeSpecifier(specifier, analysis.file);\n if (target === null) {\n continue;\n }\n for (const name of await serverFnExportNamesAsync(target, analyzeSpecifier, seen)) {\n names.add(name);\n }\n }\n\n return names;\n}\n\nexport function nonContractServerFileError(file: string, projectRoot: string): MoonsError {\n return new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: toRelative(projectRoot, file),\n message: \"file server memakai ekstensi di luar kontrak §12\",\n details:\n \"Transform zero-trust hanya menangani `*.server.ts`/`*.server.tsx`; file server dengan ekstensi lain tidak bisa di-stub dan tidak boleh masuk graph client.\",\n suggestions: [\n \"Ganti nama file menjadi `*.server.ts`/`*.server.tsx` dan taruh `serverFn` di dalamnya\",\n \"Atau pindahkan nilai yang dibutuhkan ke file non-server\",\n ],\n });\n}\n\n/** Periksa import modul client terhadap §12.4/§12.7/§12.8 — berbasis hasil resolve. */\nexport async function checkClientModuleImports(\n context: ClientImportCheckContext,\n): Promise<void> {\n const { file, code, projectRoot, resolve, analyze } = context;\n const ast = parseModule(code, file);\n const relativeFile = toRelative(projectRoot, file);\n\n const resolveSafe = async (specifier: string, importer: string): Promise<string | null> => {\n try {\n const result = await resolve(specifier, importer);\n if (result === null) {\n return null;\n }\n const clean = stripQuery(result);\n // Audit ronde 2: normalisasi realpath — symlink ke `*.server.ts` harus\n // tertangkap walau resolver mengembalikan path link.\n try {\n return realpathSync(clean);\n } catch {\n return clean;\n }\n } catch {\n return null;\n }\n };\n\n const analyzeResolved = async (\n specifier: string,\n importer: string,\n ): Promise<ServerFileAnalysis | null> => {\n const absolute = await resolveSafe(specifier, importer);\n return absolute === null ? null : analyze(absolute);\n };\n\n const isAllowedServerFnImport = async (\n resolvedTarget: string | null,\n specifier: string,\n name: string,\n ): Promise<boolean> => {\n const target =\n resolvedTarget === null ? await analyzeResolved(specifier, file) : analyze(resolvedTarget);\n if (target === null) {\n return false;\n }\n const names = await serverFnExportNamesAsync(target, (nested, importer) =>\n analyzeResolved(nested, importer),\n );\n return names.has(name);\n };\n\n const reject = (line: number, message: string, details: string): never => {\n throw new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: relativeFile,\n line,\n message,\n details,\n suggestions: [\n \"Buat server function yang mengembalikan data yang dibutuhkan, atau\",\n \"Pindahkan nilai itu ke file yang tidak berakhiran .server.ts\",\n ],\n });\n };\n\n const rejectForbidden = (line: number, specifier: string): never => {\n throw new MoonsError({\n code: \"E_FORBIDDEN_SERVER_IMPORT\",\n file: relativeFile,\n line,\n message: `mengimpor \\`${specifier}\\` di modul client`,\n details: \"Modul server-only hanya boleh di-import dari *.server.ts.\",\n suggestions: [\n \"Pindahkan operasi tersebut ke serverFn, atau\",\n \"Hapus import tersebut\",\n ],\n });\n };\n\n for (const statement of topLevelStatements(ast)) {\n if (statement.type === \"ImportDeclaration\" || statement.type === \"ExportNamedDeclaration\" || statement.type === \"ExportAllDeclaration\") {\n const sourceNode = statement[\"source\"] as AstNode | null | undefined;\n if (sourceNode?.type !== \"StringLiteral\") {\n continue;\n }\n const rawSpecifier = sourceNode[\"value\"] as string;\n // Query Vite (`?raw`, `?url`, `?inline`, dst.) dinormalisasi untuk\n // pencocokan & resolusi (audit adversarial M6).\n const specifier = stripQuery(rawSpecifier);\n const line = statement.loc?.start.line ?? 1;\n\n if (specifier.startsWith(\"node:\") || specifier.startsWith(\"bun:\")) {\n rejectForbidden(line, specifier);\n }\n\n const resolvedTarget = await resolveSafe(specifier, file);\n\n // Audit ronde 2: file server di luar kontrak §12 ditolak (tidak bisa di-stub).\n if (resolvedTarget !== null && isNonContractServerFile(resolvedTarget)) {\n throw nonContractServerFileError(resolvedTarget, projectRoot);\n }\n\n // Audit ronde 2: keputusan berbasis hasil resolve — menangkap alias Vite,\n // `tsconfig paths`, dan symlink (realpath) yang menunjuk `*.server.ts`.\n const serverBySpecifier = isServerSpecifier(specifier);\n const serverByResolve = resolvedTarget !== null && isServerFilePath(resolvedTarget);\n if (!serverBySpecifier && !serverByResolve) {\n continue;\n }\n\n const targetRelative =\n resolvedTarget === null ? rawSpecifier : toRelative(projectRoot, resolvedTarget);\n\n if (statement.type === \"ExportAllDeclaration\") {\n if (resolvedTarget === null) {\n reject(line, `\\`export *\\` dari \\`${targetRelative}\\` tidak bisa di-resolve`, \"Re-export dari `*.server.ts` wajib bisa di-resolve statis (PRD §12.6).\");\n }\n continue; // aman: target menjadi stub\n }\n\n const specifiers = (statement[\"specifiers\"] ?? []) as AstNode[];\n for (const item of specifiers) {\n if (item.type === \"ImportDefaultSpecifier\") {\n reject(line, `mengimpor default dari ${targetRelative}`, \"Default export dari file server tidak boleh menyeberang ke client.\");\n }\n if (item.type === \"ImportNamespaceSpecifier\") {\n reject(line, `mengimpor namespace (\\`* as\\`) dari ${targetRelative}`, \"Import namespace dari file server tidak boleh menyeberang ke client.\");\n }\n const name = ((item[\"local\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\";\n const kind = (item[\"importKind\"] as string | undefined) ?? (statement[\"importKind\"] as string | undefined);\n if (kind === \"type\") {\n reject(line, `mengimpor type \\`${name}\\` dari ${targetRelative}`, \"Import dari file server tidak diizinkan di modul client (PRD §12.4).\");\n }\n if (name.length > 0 && !(await isAllowedServerFnImport(resolvedTarget, specifier, name))) {\n reject(\n line,\n `mengimpor \\`${name}\\` dari ${targetRelative}`,\n \"Kode server tidak boleh muncul di client.\\nHanya `serverFn` yang diizinkan menyeberang.\",\n );\n }\n }\n }\n }\n\n // §12.4: pemanggilan env() di modul client (juga @moonsjs/server import env).\n const envBindings = new Set<string>();\n for (const statement of topLevelStatements(ast)) {\n if (statement.type !== \"ImportDeclaration\") {\n continue;\n }\n const sourceNode = statement[\"source\"] as AstNode | undefined;\n const specifier = sourceNode?.type === \"StringLiteral\" ? (sourceNode[\"value\"] as string) : \"\";\n if (specifier !== \"@moonsjs/server\" && !specifier.startsWith(\"@moonsjs/server/\")) {\n continue;\n }\n for (const item of (statement[\"specifiers\"] ?? []) as AstNode[]) {\n if (item.type !== \"ImportSpecifier\") {\n continue;\n }\n const imported = item[\"imported\"] as AstNode | undefined;\n const local = item[\"local\"] as AstNode | undefined;\n if (imported?.type === \"Identifier\" && imported[\"name\"] === \"env\" && local?.type === \"Identifier\") {\n envBindings.add(local[\"name\"] as string);\n }\n }\n }\n\n if (envBindings.size > 0) {\n walk(ast, (node) => {\n if (node.type !== \"CallExpression\") {\n return;\n }\n const callee = node[\"callee\"] as AstNode | undefined;\n if (callee?.type !== \"Identifier\" || !envBindings.has(callee[\"name\"] as string)) {\n return;\n }\n const callText = code\n .slice(node.start ?? 0, node.end ?? 0)\n .replace(/\\s+/g, \" \")\n .slice(0, 80);\n throw new MoonsError({\n code: \"E_ENV_IN_CLIENT\",\n file: relativeFile,\n line: node.loc?.start.line ?? 1,\n message: `memanggil \\`${callText}\\` di modul yang masuk client`,\n details: \"`env()` hanya legal di server.\",\n suggestions: [\n \"Pindahkan pemanggilan ke dalam serverFn, atau\",\n \"Gunakan import.meta.env untuk nilai publik\",\n ],\n });\n });\n }\n\n // Dynamic import (§12.7/§12.8) — literal maupun template dengan teks `.server`,\n // plus resolusi (alias/tsconfig paths/symlink) — audit ronde 2.\n const dynamicRequests: Array<{ request: DynamicImportRequest; guarded: boolean }> = [];\n walk(ast, (node, ancestors) => {\n const request = dynamicImportRequest(node);\n if (request !== null) {\n dynamicRequests.push({\n request,\n guarded: ancestors.some((ancestor) => isDevGuard(ancestor)),\n });\n }\n });\n\n for (const { request, guarded } of dynamicRequests) {\n if (guarded) {\n continue; // §12.8: branch DEV/PROD mati saat build → tidak perlu diperiksa\n }\n\n const specifier = stripQuery(request.text);\n const resolvedTarget = await resolveSafe(specifier, file);\n\n if (resolvedTarget !== null && isNonContractServerFile(resolvedTarget)) {\n throw nonContractServerFileError(resolvedTarget, projectRoot);\n }\n\n const serverBySpecifier = isServerSpecifier(specifier);\n const serverByResolve = resolvedTarget !== null && isServerFilePath(resolvedTarget);\n if (!serverBySpecifier && !serverByResolve) {\n continue;\n }\n\n const targetRelative =\n resolvedTarget === null ? request.text : toRelative(projectRoot, resolvedTarget);\n reject(request.node.loc?.start.line ?? 1, `mengimpor (dynamic) \\`${request.text}\\` dari ${targetRelative}`, \"Client tidak boleh melakukan dynamic import ke `*.server.ts` (PRD §12.7).\");\n }\n\n // `import.meta.glob` yang mencakup `*.server.ts` (§12.7) — audit adversarial M6.\n walk(ast, (node) => {\n if (node.type !== \"CallExpression\") {\n return;\n }\n const callee = node[\"callee\"] as AstNode | undefined;\n if (callee?.type !== \"MemberExpression\") {\n return;\n }\n const object = callee[\"object\"] as AstNode | undefined;\n const property = callee[\"property\"] as AstNode | undefined;\n if (\n object?.type !== \"MetaProperty\" ||\n property?.type !== \"Identifier\" ||\n property[\"name\"] !== \"glob\"\n ) {\n return;\n }\n\n for (const pattern of globPatterns(((node[\"arguments\"] ?? []) as AstNode[])[0])) {\n if (!isServerSpecifier(pattern)) {\n continue;\n }\n throw new MoonsError({\n code: \"E_SERVER_IMPORT_IN_CLIENT\",\n file: relativeFile,\n line: node.loc?.start.line ?? 1,\n message: `mengimpor (glob) \\`${pattern}\\` di modul client`,\n details: \"`import.meta.glob` yang mencakup `*.server.ts` dilarang di client (PRD §12.7).\",\n suggestions: [\n \"Import statis `serverFn` dari `*.server.ts` (hanya itu yang boleh menyeberang), atau\",\n \"Pindahkan kebutuhan data ke dalam server function\",\n ],\n });\n }\n });\n}\n\ninterface DynamicImportRequest {\n /** Teks specifier literal, atau gabungan quasi template (`*` untuk ekspresi). */\n text: string;\n node: AstNode;\n}\n\n/** Dukung Babel 8 (`ImportExpression`) dan bentuk lama (`CallExpression` + callee `Import`). */\nfunction dynamicImportRequest(node: AstNode): DynamicImportRequest | null {\n let sourceNode: AstNode | null = null;\n\n if (node.type === \"ImportExpression\") {\n sourceNode = (node[\"source\"] as AstNode | undefined) ?? null;\n } else if (node.type === \"CallExpression\") {\n const callee = node[\"callee\"] as AstNode | undefined;\n if (callee?.type !== \"Import\") {\n return null;\n }\n sourceNode = ((node[\"arguments\"] ?? []) as AstNode[])[0] ?? null;\n }\n\n if (sourceNode === null) {\n return null;\n }\n if (sourceNode.type === \"StringLiteral\") {\n return { text: sourceNode[\"value\"] as string, node: sourceNode };\n }\n if (sourceNode.type === \"TemplateLiteral\") {\n const text = ((sourceNode[\"quasis\"] ?? []) as AstNode[])\n .map((quasi) => ((quasi[\"value\"] as { cooked?: string | null } | undefined)?.cooked ?? \"\"))\n .join(\"*\");\n return { text, node: sourceNode };\n }\n return null;\n}\n\nfunction globPatterns(node: AstNode | undefined): string[] {\n if (node?.type === \"StringLiteral\") {\n return [node[\"value\"] as string];\n }\n if (node?.type === \"ArrayExpression\") {\n return ((node[\"elements\"] ?? []) as Array<AstNode | null>)\n .filter((element): element is AstNode => element?.type === \"StringLiteral\")\n .map((element) => element[\"value\"] as string);\n }\n return [];\n}\n\nfunction isDevGuard(node: AstNode): boolean {\n if (node.type !== \"IfStatement\") {\n return false;\n }\n const test = node[\"test\"] as AstNode | undefined;\n return isImportMetaFlag(test, \"DEV\") || isNegatedImportMetaFlag(test, \"PROD\");\n}\n\nfunction isImportMetaFlag(node: AstNode | undefined, flag: string): boolean {\n const member = node;\n if (member?.type !== \"MemberExpression\") {\n return false;\n }\n const property = member[\"property\"] as AstNode | undefined;\n if (property?.type !== \"Identifier\" || property[\"name\"] !== flag) {\n return false;\n }\n const object = member[\"object\"] as AstNode | undefined;\n return isImportMetaEnv(object);\n}\n\nfunction isNegatedImportMetaFlag(node: AstNode | undefined, flag: string): boolean {\n if (node?.type !== \"UnaryExpression\" || node[\"operator\"] !== \"!\") {\n return false;\n }\n return isImportMetaFlag(node[\"argument\"] as AstNode | undefined, flag);\n}\n\nfunction isImportMetaEnv(node: AstNode | undefined): boolean {\n if (node?.type !== \"MemberExpression\") {\n return false;\n }\n const property = node[\"property\"] as AstNode | undefined;\n if (property?.type !== \"Identifier\" || property[\"name\"] !== \"env\") {\n return false;\n }\n const object = node[\"object\"] as AstNode | undefined;\n return object?.type === \"MetaProperty\";\n}\n\nfunction toRelative(projectRoot: string, file: string): string {\n const relative = file.startsWith(projectRoot)\n ? file.slice(projectRoot.length).replace(/^[/\\\\]/, \"\")\n : file;\n return relative.split(\"\\\\\").join(\"/\");\n}\n\nexport interface RouteExportCheckContext {\n file: string;\n code: string;\n routesDir: string;\n projectRoot: string;\n}\n\n/**\n * §11.2 + §12.4: export legal per jenis modul route.\n * page: `default|loader|meta`; layout: `default|loader`; `_error`/`_404`: `default`.\n */\nexport function checkRouteModuleExports(context: RouteExportCheckContext): void {\n const { file, code, routesDir, projectRoot } = context;\n if (!file.startsWith(routesDir) || !file.endsWith(\".tsx\")) {\n return;\n }\n\n const base = file.slice(file.lastIndexOf(\"/\") + 1);\n if (base.startsWith(\"_\") && base !== \"_layout.tsx\" && base !== \"_error.tsx\" && base !== \"_404.tsx\") {\n return; // bukan route (diabaikan scanner)\n }\n\n const allowed =\n base === \"_layout.tsx\"\n ? [\"default\", \"loader\"]\n : base === \"_error.tsx\" || base === \"_404.tsx\"\n ? [\"default\"]\n : [\"default\", \"loader\", \"meta\"];\n const allowedText = `Hanya ${allowed.map((name) => `\\`${name}\\``).join(\", \")} yang boleh di-export.`;\n const relativeFile = toRelative(projectRoot, file);\n const ast = parseModule(code, file);\n\n const declarations: Array<{ name: string; line: number }> = [];\n let hasDefault = false;\n\n for (const statement of topLevelStatements(ast)) {\n if (statement.type === \"ExportDefaultDeclaration\") {\n hasDefault = true;\n continue;\n }\n\n if (statement.type === \"ExportAllDeclaration\") {\n throw new MoonsError({\n code: \"E_ROUTE_EXPORT_INVALID\",\n file: relativeFile,\n line: statement.loc?.start.line ?? 1,\n message: \"`export *` tidak diizinkan di modul route\",\n details: allowedText,\n suggestions: [\n `Pindahkan isi file ke luar ${toRelative(projectRoot, routesDir)}/, atau`,\n \"Hapus `export *` tersebut\",\n ],\n });\n }\n\n if (statement.type !== \"ExportNamedDeclaration\") {\n continue;\n }\n\n const declaration = statement[\"declaration\"] as AstNode | null | undefined;\n if (declaration !== null && declaration !== undefined) {\n for (const name of declarationNames(declaration)) {\n declarations.push({ name, line: declaration.loc?.start.line ?? 1 });\n }\n }\n\n for (const item of (statement[\"specifiers\"] ?? []) as AstNode[]) {\n const exported = item[\"exported\"] as AstNode | undefined;\n const name =\n exported?.type === \"Identifier\"\n ? (exported[\"name\"] as string)\n : exported?.type === \"StringLiteral\"\n ? (exported[\"value\"] as string)\n : null;\n if (name !== null) {\n declarations.push({ name, line: item.loc?.start.line ?? statement.loc?.start.line ?? 1 });\n }\n }\n }\n\n for (const entry of declarations) {\n if (!allowed.includes(entry.name)) {\n throw new MoonsError({\n code: \"E_ROUTE_EXPORT_INVALID\",\n file: relativeFile,\n line: entry.line,\n message: `export \\`${entry.name}\\` tidak diizinkan di modul route`,\n details: allowedText,\n suggestions: [\n `Pindahkan \\`${entry.name}\\` ke file di luar ${toRelative(projectRoot, routesDir)}/, atau`,\n \"Hapus export tersebut\",\n ],\n });\n }\n }\n\n if (!hasDefault) {\n throw new MoonsError({\n code: \"E_ROUTE_EXPORT_INVALID\",\n file: relativeFile,\n message: \"modul route wajib mengekspor `default`\",\n details: \"Setiap file route harus punya `export default` berupa komponen React (PRD §11.2).\",\n suggestions: [\"Tambahkan `export default function Page() { ... }`\"],\n });\n }\n}\n\nfunction declarationNames(declaration: AstNode): string[] {\n switch (declaration.type) {\n case \"VariableDeclaration\":\n return ((declaration[\"declarations\"] ?? []) as AstNode[])\n .map((declarator) => ((declarator[\"id\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\")\n .filter((name) => name.length > 0);\n case \"FunctionDeclaration\":\n case \"ClassDeclaration\":\n case \"TSInterfaceDeclaration\":\n case \"TSTypeAliasDeclaration\":\n case \"TSEnumDeclaration\":\n return [((declaration[\"id\"] as AstNode | undefined)?.[\"name\"] as string) ?? \"\"].filter(\n (name) => name.length > 0,\n );\n default:\n return [];\n }\n}\n\n/** Scan semua `*.server.{ts,tsx}` di bawah root (exclude direktori build/dependency). */\nexport function scanServerFiles(projectRoot: string): string[] {\n const excluded = new Set([\"node_modules\", \"dist\", \".moons\", \".git\"]);\n const result: string[] = [];\n\n const walkDir = (dir: string): void => {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n if (excluded.has(entry.name)) {\n continue;\n }\n walkDir(join(dir, entry.name));\n } else if (entry.isFile() && isServerFilePath(entry.name)) {\n result.push(join(dir, entry.name));\n }\n }\n };\n\n walkDir(projectRoot);\n return result.sort();\n}\n\nexport interface FnRegistryJson {\n [key: string]: string;\n}\n\n/** Bangun isi `fn-registry.json` (bentuk yang dibaca §21.3). */\nexport function buildFnRegistry(projectRoot: string, files: string[]): FnRegistryJson {\n const registry: FnRegistryJson = {};\n for (const file of files) {\n let source: string;\n try {\n source = readFileSync(file, \"utf8\");\n } catch {\n continue;\n }\n const analysis = analyzeServerFile(source, file, projectRoot);\n for (const fn of analysis.serverFns) {\n registry[fnRegistryKey(projectRoot, file, fn.name)] = fn.hash;\n }\n }\n return registry;\n}\n"
6
- ],
7
- "mappings": "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",
8
- "debugId": "A2B4D23CAFD2B11164756E2164756E21",
9
- "names": []
10
- }