@moonsjs/vite 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -564,7 +564,7 @@ function renderServerEntryBuild(routesDir, eagerImports, canary) {
564
564
  " onContext: (ctx) => plugins.applyExtensions(ctx),",
565
565
  "});",
566
566
  "",
567
- `startNodeServer(handler, { plugins${canary === undefined ? "" : `, canary: ${JSON.stringify(canary)}`} });`,
567
+ `startNodeServer(handler, { plugins, headers: config.headers, storage: config.isr?.storage${canary === undefined ? "" : `, canary: ${JSON.stringify(canary)}`} });`,
568
568
  ""
569
569
  ].join(`
570
570
  `);
@@ -623,4 +623,4 @@ export {
623
623
  moons as default
624
624
  };
625
625
 
626
- //# debugId=C19ACBFCC6A7B10A64756E2164756E21
626
+ //# debugId=94F8A2FD2129167C64756E2164756E21
package/dist/index.js.map CHANGED
@@ -2,11 +2,11 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/plugin.ts", "../src/api.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 scanApiMiddlewares,\n scanApiRoutes,\n scanRoutes,\n validateConfig,\n type ApiMiddlewareDefinition,\n type ApiRouteDefinition,\n type RouteDefinition,\n} from \"@moonsjs/core\";\nimport { loadConfigFromFile, type Plugin, type ViteDevServer } from \"vite\";\nimport { assertApiModuleExports, assertMiddlewareExports } from \"./api\";\nimport { findLeak } from \"./leak-check\";\nimport type { PackageJsonInfo } from \"./server-only\";\nimport { renderApiModule, 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 serverOnlyPackages: ReadonlyArray<string> = [];\n let apiDir = \"\";\n let apiRoutes: ApiRouteDefinition[] = [];\n let apiMiddlewares: ApiMiddlewareDefinition[] = [];\n /** Cache package.json untuk gate Addendum C (dibagi lintas modul). */\n const packageCache = new Map<string, PackageJsonInfo | null>(); 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.\",\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 // D.5: dua entry — server (index) + prerender runner.\n ssr: true,\n rollupOptions: {\n input: {\n index: \".moons/server-entry.ts\",\n prerender: \".moons/prerender-entry.ts\",\n },\n output: {\n entryFileNames: \"[name].js\",\n chunkFileNames: \"chunks/[name]-[hash].js\",\n },\n },\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.\",\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 serverOnlyPackages = config.security?.serverOnlyPackages ?? [];\n\n // Addendum D.1: scan + validasi statis modul `src/api`.\n apiDir = resolvePath(root, config.apiDir ?? \"src/api\");\n if (existsSync(apiDir)) {\n apiRoutes = scanApiRoutes(apiDir);\n for (const route of apiRoutes) {\n assertApiModuleExports(readFileSync(route.file, \"utf8\"), route.file);\n }\n apiMiddlewares = scanApiMiddlewares(apiDir);\n for (const middleware of apiMiddlewares) {\n assertMiddlewareExports(readFileSync(middleware.file, \"utf8\"), middleware.file);\n }\n } else {\n apiRoutes = [];\n apiMiddlewares = [];\n }\n },\n\n async buildStart() {\n routes = scanRoutes(routesDir);\n // D.3: validasi statis `_middleware.ts` pohon routes.\n for (const middleware of routes.filter((route) => route.kind === \"middleware\")) {\n assertMiddlewareExports(readFileSync(middleware.file, \"utf8\"), middleware.file);\n }\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(), options.leakTest?.canary),\n \"utf8\",\n );\n writeFileSync(\n resolvePath(root, \".moons/prerender-entry.ts\"),\n renderPrerenderEntry(routesDir, root, options.leakTest?.canary),\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.api:\n return renderApiModule(apiRoutes, apiMiddlewares, 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 apiDir,\n serverOnlyPackages,\n packageCache,\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 gagal: kode server bocor ke output client. Build dihentikan.\",\n suggestions: [\n \"Periksa transform `*.server.ts`\",\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: setiap `*.server.ts` di bundle client wajib berupa stub RPC hasil transform.\",\n suggestions: [\n \"Pastikan transform zero-trust berjalan untuk modul ini\",\n \"Laporkan ini sebagai bug framework jika berulang\",\n ],\n });\n }\n }\n },\n\n configureServer(server) {\n installDevMiddleware(server, {\n templatePath: resolvePath(root, \"index.html\"),\n // A1: pemindaian payload SSR hanya di dev (warning), tanpa biaya di production.\n payloadScan: {\n ...(options.leakTest?.canary === undefined ? {} : { canary: options.leakTest.canary }),\n env: process.env,\n },\n // D.1: request ke prefix API (semua method) dirutekan ke runtime.\n ...(apiRoutes.length === 0\n ? {}\n : { apiPrefix: `/${apiDir.split(/[\\\\/]/).filter((part) => part.length > 0).pop() ?? \"api\"}` }),\n });\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(apiDir) && existsSync(apiDir)) {\n try {\n apiRoutes = scanApiRoutes(apiDir);\n for (const route of apiRoutes) {\n assertApiModuleExports(readFileSync(route.file, \"utf8\"), route.file);\n }\n apiMiddlewares = scanApiMiddlewares(apiDir);\n for (const middleware of apiMiddlewares) {\n assertMiddlewareExports(readFileSync(middleware.file, \"utf8\"), middleware.file);\n }\n } catch (error) {\n context.server.config.logger.error(String(error));\n return;\n }\n invalidateVirtualModules(context.server);\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 for (const middleware of routes.filter((route) => route.kind === \"middleware\")) {\n assertMiddlewareExports(readFileSync(middleware.file, \"utf8\"), middleware.file);\n }\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 { createPluginRuntime, createRequestHandler } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n 'import { apiRoutes, apiMiddlewares, loadApi, loadApiMiddleware } from \"virtual:moons/api\";',\n ...eagerImports.map((specifier) => `import ${JSON.stringify(specifier)};`),\n \"\",\n \"export function createDevApp(shell, payloadScan) {\",\n \" const plugins = createPluginRuntime({ config, routes, middlewares: config.middleware ?? [] });\",\n ` const handler = createRequestHandler({ routes, apiRoutes, apiMiddlewares, loadApi, loadApiMiddleware, config, routesDir: ${JSON.stringify(routesDir)}, loadRoute, shell, onContext: (ctx) => plugins.applyExtensions(ctx), ...(payloadScan === undefined ? {} : { payloadScan }) });`,\n \" return { handler, plugins };\",\n \"}\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction renderServerEntryBuild(\n routesDir: string,\n eagerImports: string[],\n canary: string | undefined,\n): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n 'import { createFileShell, createPluginRuntime, createRequestHandler, startNodeServer } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n 'import { apiRoutes, apiMiddlewares, loadApi, loadApiMiddleware } from \"virtual:moons/api\";',\n ...eagerImports.map((specifier) => `import ${JSON.stringify(specifier)};`),\n \"\",\n \"const plugins = createPluginRuntime({ config, routes, middlewares: config.middleware ?? [] });\",\n \"const handler = createRequestHandler({\",\n \" routes,\",\n \" apiRoutes,\",\n \" apiMiddlewares,\",\n \" loadApi,\",\n \" loadApiMiddleware,\",\n \" config,\",\n ` routesDir: ${JSON.stringify(routesDir)},`,\n \" loadRoute,\",\n \" shell: createFileShell(),\",\n \" onContext: (ctx) => plugins.applyExtensions(ctx),\",\n \"});\",\n \"\",\n `startNodeServer(handler, { plugins${canary === undefined ? \"\" : `, canary: ${JSON.stringify(canary)}`} });`,\n \"\",\n ].join(\"\\n\");\n}\n\ninterface ModuleGraphLike {\n getModulesByFile(file: string): Iterable<{ id?: string | null }> | undefined;\n invalidateModule(module: unknown): void;\n}\n\n/** Entry D.5: runner prerender (dijalankan CLI setelah build server). */\nfunction renderPrerenderEntry(\n routesDir: string,\n projectRoot: string,\n canary: string | undefined,\n): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n 'import { createFileShell, createRequestHandler, runPrerender } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n \"\",\n \"const handler = createRequestHandler({\",\n \" routes,\",\n \" config,\",\n ` routesDir: ${JSON.stringify(routesDir)},`,\n \" loadRoute,\",\n \" shell: createFileShell(),\",\n \"});\",\n \"\",\n \"await runPrerender({\",\n \" routes,\",\n ` routesDir: ${JSON.stringify(routesDir)},`,\n \" loadRoute,\",\n \" handler,\",\n \" staticConfig: config,\",\n ` clientDir: ${JSON.stringify(resolvePath(projectRoot, \"dist/client\"))},`,\n ...(canary === undefined ? [] : [` canary: ${JSON.stringify(canary)},`]),\n \"});\",\n \"\",\n ].join(\"\\n\");\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 scanApiMiddlewares,\n scanApiRoutes,\n scanRoutes,\n validateConfig,\n type ApiMiddlewareDefinition,\n type ApiRouteDefinition,\n type RouteDefinition,\n} from \"@moonsjs/core\";\nimport { loadConfigFromFile, type Plugin, type ViteDevServer } from \"vite\";\nimport { assertApiModuleExports, assertMiddlewareExports } from \"./api\";\nimport { findLeak } from \"./leak-check\";\nimport type { PackageJsonInfo } from \"./server-only\";\nimport { renderApiModule, 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 serverOnlyPackages: ReadonlyArray<string> = [];\n let apiDir = \"\";\n let apiRoutes: ApiRouteDefinition[] = [];\n let apiMiddlewares: ApiMiddlewareDefinition[] = [];\n /** Cache package.json untuk gate Addendum C (dibagi lintas modul). */\n const packageCache = new Map<string, PackageJsonInfo | null>(); 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.\",\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 // D.5: dua entry — server (index) + prerender runner.\n ssr: true,\n rollupOptions: {\n input: {\n index: \".moons/server-entry.ts\",\n prerender: \".moons/prerender-entry.ts\",\n },\n output: {\n entryFileNames: \"[name].js\",\n chunkFileNames: \"chunks/[name]-[hash].js\",\n },\n },\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.\",\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 serverOnlyPackages = config.security?.serverOnlyPackages ?? [];\n\n // Addendum D.1: scan + validasi statis modul `src/api`.\n apiDir = resolvePath(root, config.apiDir ?? \"src/api\");\n if (existsSync(apiDir)) {\n apiRoutes = scanApiRoutes(apiDir);\n for (const route of apiRoutes) {\n assertApiModuleExports(readFileSync(route.file, \"utf8\"), route.file);\n }\n apiMiddlewares = scanApiMiddlewares(apiDir);\n for (const middleware of apiMiddlewares) {\n assertMiddlewareExports(readFileSync(middleware.file, \"utf8\"), middleware.file);\n }\n } else {\n apiRoutes = [];\n apiMiddlewares = [];\n }\n },\n\n async buildStart() {\n routes = scanRoutes(routesDir);\n // D.3: validasi statis `_middleware.ts` pohon routes.\n for (const middleware of routes.filter((route) => route.kind === \"middleware\")) {\n assertMiddlewareExports(readFileSync(middleware.file, \"utf8\"), middleware.file);\n }\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(), options.leakTest?.canary),\n \"utf8\",\n );\n writeFileSync(\n resolvePath(root, \".moons/prerender-entry.ts\"),\n renderPrerenderEntry(routesDir, root, options.leakTest?.canary),\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.api:\n return renderApiModule(apiRoutes, apiMiddlewares, 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 apiDir,\n serverOnlyPackages,\n packageCache,\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 gagal: kode server bocor ke output client. Build dihentikan.\",\n suggestions: [\n \"Periksa transform `*.server.ts`\",\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: setiap `*.server.ts` di bundle client wajib berupa stub RPC hasil transform.\",\n suggestions: [\n \"Pastikan transform zero-trust berjalan untuk modul ini\",\n \"Laporkan ini sebagai bug framework jika berulang\",\n ],\n });\n }\n }\n },\n\n configureServer(server) {\n installDevMiddleware(server, {\n templatePath: resolvePath(root, \"index.html\"),\n // A1: pemindaian payload SSR hanya di dev (warning), tanpa biaya di production.\n payloadScan: {\n ...(options.leakTest?.canary === undefined ? {} : { canary: options.leakTest.canary }),\n env: process.env,\n },\n // D.1: request ke prefix API (semua method) dirutekan ke runtime.\n ...(apiRoutes.length === 0\n ? {}\n : { apiPrefix: `/${apiDir.split(/[\\\\/]/).filter((part) => part.length > 0).pop() ?? \"api\"}` }),\n });\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(apiDir) && existsSync(apiDir)) {\n try {\n apiRoutes = scanApiRoutes(apiDir);\n for (const route of apiRoutes) {\n assertApiModuleExports(readFileSync(route.file, \"utf8\"), route.file);\n }\n apiMiddlewares = scanApiMiddlewares(apiDir);\n for (const middleware of apiMiddlewares) {\n assertMiddlewareExports(readFileSync(middleware.file, \"utf8\"), middleware.file);\n }\n } catch (error) {\n context.server.config.logger.error(String(error));\n return;\n }\n invalidateVirtualModules(context.server);\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 for (const middleware of routes.filter((route) => route.kind === \"middleware\")) {\n assertMiddlewareExports(readFileSync(middleware.file, \"utf8\"), middleware.file);\n }\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 { createPluginRuntime, createRequestHandler } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n 'import { apiRoutes, apiMiddlewares, loadApi, loadApiMiddleware } from \"virtual:moons/api\";',\n ...eagerImports.map((specifier) => `import ${JSON.stringify(specifier)};`),\n \"\",\n \"export function createDevApp(shell, payloadScan) {\",\n \" const plugins = createPluginRuntime({ config, routes, middlewares: config.middleware ?? [] });\",\n ` const handler = createRequestHandler({ routes, apiRoutes, apiMiddlewares, loadApi, loadApiMiddleware, config, routesDir: ${JSON.stringify(routesDir)}, loadRoute, shell, onContext: (ctx) => plugins.applyExtensions(ctx), ...(payloadScan === undefined ? {} : { payloadScan }) });`,\n \" return { handler, plugins };\",\n \"}\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction renderServerEntryBuild(\n routesDir: string,\n eagerImports: string[],\n canary: string | undefined,\n): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n 'import { createFileShell, createPluginRuntime, createRequestHandler, startNodeServer } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n 'import { apiRoutes, apiMiddlewares, loadApi, loadApiMiddleware } from \"virtual:moons/api\";',\n ...eagerImports.map((specifier) => `import ${JSON.stringify(specifier)};`),\n \"\",\n \"const plugins = createPluginRuntime({ config, routes, middlewares: config.middleware ?? [] });\",\n \"const handler = createRequestHandler({\",\n \" routes,\",\n \" apiRoutes,\",\n \" apiMiddlewares,\",\n \" loadApi,\",\n \" loadApiMiddleware,\",\n \" config,\",\n ` routesDir: ${JSON.stringify(routesDir)},`,\n \" loadRoute,\",\n \" shell: createFileShell(),\",\n \" onContext: (ctx) => plugins.applyExtensions(ctx),\",\n \"});\",\n \"\",\n `startNodeServer(handler, { plugins, headers: config.headers, storage: config.isr?.storage${canary === undefined ? \"\" : `, canary: ${JSON.stringify(canary)}`} });`,\n \"\",\n ].join(\"\\n\");\n}\n\ninterface ModuleGraphLike {\n getModulesByFile(file: string): Iterable<{ id?: string | null }> | undefined;\n invalidateModule(module: unknown): void;\n}\n\n/** Entry D.5: runner prerender (dijalankan CLI setelah build server). */\nfunction renderPrerenderEntry(\n routesDir: string,\n projectRoot: string,\n canary: string | undefined,\n): string {\n return [\n \"// Generated by @moons. Jangan diubah manual.\",\n 'import { createFileShell, createRequestHandler, runPrerender } from \"@moonsjs/vite/server\";',\n 'import config from \"virtual:moons/config\";',\n 'import { routes, loadRoute } from \"virtual:moons/routes\";',\n \"\",\n \"const handler = createRequestHandler({\",\n \" routes,\",\n \" config,\",\n ` routesDir: ${JSON.stringify(routesDir)},`,\n \" loadRoute,\",\n \" shell: createFileShell(),\",\n \"});\",\n \"\",\n \"await runPrerender({\",\n \" routes,\",\n ` routesDir: ${JSON.stringify(routesDir)},`,\n \" loadRoute,\",\n \" handler,\",\n \" staticConfig: config,\",\n ` clientDir: ${JSON.stringify(resolvePath(projectRoot, \"dist/client\"))},`,\n ...(canary === undefined ? [] : [` canary: ${JSON.stringify(canary)},`]),\n \"});\",\n \"\",\n ].join(\"\\n\");\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
  "import { parse } from \"@babel/parser\";\nimport { API_METHODS, MoonsError } from \"@moonsjs/core\";\n\n/**\n * Validasi statis export modul `src/api` (PRD Addendum D.1):\n * hanya handler method `GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS` sebagai fungsi;\n * `default`/export lain ditolak → `E_API_HANDLER_INVALID`.\n */\nexport function assertApiModuleExports(code: string, file: string): string[] {\n let ast: unknown;\n try {\n ast = parse(code, {\n sourceType: \"module\",\n plugins: file.endsWith(\".tsx\") ? [\"typescript\", \"jsx\"] : [\"typescript\"],\n });\n } catch {\n return []; // biarkan bundler melaporkan syntax error\n }\n\n const program = (ast as { program?: { body?: Array<Record<string, unknown>> } }).program;\n const body = program?.body ?? [];\n const methods: string[] = [];\n\n for (const statement of body) {\n if (statement[\"type\"] === \"ExportDefaultDeclaration\") {\n throw apiError(\n file,\n \"export `default` tidak didukung di modul API\",\n \"Modul `src/api` hanya mengekspor handler method bernama.\",\n [\"Ganti menjadi `export const GET = (args) => …`\", \"Hapus export default\"],\n );\n }\n if (statement[\"type\"] !== \"ExportNamedDeclaration\") {\n continue;\n }\n if (statement[\"source\"] !== undefined) {\n // re-export `export { X } from \"...\"` — nama tetap dicek di bawah.\n }\n const declaration = statement[\"declaration\"] as Record<string, unknown> | undefined;\n if (declaration !== undefined) {\n if (declaration[\"type\"] === \"VariableDeclaration\") {\n for (const declarator of (declaration[\"declarations\"] ?? []) as Array<Record<string, unknown>>) {\n const id = declarator[\"id\"] as Record<string, unknown> | undefined;\n if (id?.[\"type\"] === \"Identifier\") {\n methods.push(id[\"name\"] as string);\n }\n }\n } else if (declaration[\"type\"] === \"FunctionDeclaration\") {\n const id = declaration[\"id\"] as Record<string, unknown> | undefined;\n if (id?.[\"type\"] === \"Identifier\") {\n methods.push(id[\"name\"] as string);\n }\n }\n continue;\n }\n for (const specifier of (statement[\"specifiers\"] ?? []) as Array<Record<string, unknown>>) {\n const exported = specifier[\"exported\"] as Record<string, unknown> | undefined;\n if (exported?.[\"type\"] === \"Identifier\") {\n methods.push(exported[\"name\"] as string);\n }\n }\n }\n\n const illegal = methods.filter((name) => !API_METHODS.includes(name as never));\n if (illegal.length > 0) {\n throw apiError(\n file,\n `export \\`${illegal[0]}\\` bukan handler method yang dikenal`,\n `Handler yang legal: ${API_METHODS.join(\", \")}.`,\n [\n \"Ganti nama export menjadi salah satu method HTTP\",\n \"Pindahkan helper ke modul lain (mis. `src/server/…`)\",\n ],\n );\n }\n if (methods.length === 0) {\n throw apiError(\n file,\n \"modul API tanpa handler method\",\n `Wajib ada minimal satu dari ${API_METHODS.join(\", \")}.`,\n [`Tambahkan \\`export const GET = (args) => new Response(…)\\``],\n );\n }\n\n return methods;\n}\n\nexport function assertMiddlewareExports(code: string, file: string): void {\n let ast: unknown;\n try {\n ast = parse(code, {\n sourceType: \"module\",\n plugins: file.endsWith(\".tsx\") ? [\"typescript\", \"jsx\"] : [\"typescript\"],\n });\n } catch {\n return;\n }\n const program = (ast as { program?: { body?: Array<Record<string, unknown>> } }).program;\n const hasDefault = (program?.body ?? []).some(\n (statement) => statement[\"type\"] === \"ExportDefaultDeclaration\",\n );\n if (!hasDefault) {\n throw new MoonsError({\n code: \"E_MIDDLEWARE_INVALID\",\n file,\n message: \"`_middleware.ts` tanpa `export default`\",\n details: \"Middleware direktori mengikuti bentuk `Middleware`: `(args) => Promise<Response>`.\",\n suggestions: [\n \"Tambahkan `export default async ({ req, ctx, next }) => await next()`\",\n \"Hapus file bila tidak dipakai\",\n ],\n });\n }\n}\n\nfunction apiError(file: string, message: string, details: string, suggestions: string[]): MoonsError {\n return new MoonsError({\n code: \"E_API_HANDLER_INVALID\",\n file,\n message,\n details,\n suggestions,\n });\n}\n",
7
7
  "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"
8
8
  ],
9
- "mappings": "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",
10
- "debugId": "C19ACBFCC6A7B10A64756E2164756E21",
9
+ "mappings": "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",
10
+ "debugId": "94F8A2FD2129167C64756E2164756E21",
11
11
  "names": []
12
12
  }
@@ -16,4 +16,5 @@ export { runPrerender } from "./prerender";
16
16
  export type { PrerenderOptions, PrerenderResult } from "./prerender";
17
17
  export type { PayloadScanOptions } from "../payload-scan";
18
18
  export type { ApiHandlerArgs, ApiMethod, ApiRouteDefinition } from "@moonsjs/core";
19
+ export { createFileStorage, contentTypeForPathname } from "./storage";
19
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3G,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3G,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC"}
@@ -467,9 +467,9 @@ function warnPayloadFindings(payload, scan, warned) {
467
467
  }
468
468
  }
469
469
  // src/server/node-server.ts
470
- import { existsSync, readFileSync, statSync } from "node:fs";
470
+ import { existsSync, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
471
471
  import { createServer } from "node:http";
472
- import { extname, join, resolve, sep } from "node:path";
472
+ import { extname as extname2, join, resolve, sep } from "node:path";
473
473
 
474
474
  // src/server/isr.ts
475
475
  import { renameSync, writeFileSync } from "node:fs";
@@ -510,6 +510,14 @@ async function runRevalidate(options) {
510
510
  log(`[moons] isr: TIDAK menulis ${options.pathname} — memuat ${labels}`);
511
511
  return;
512
512
  }
513
+ if (options.storage !== undefined) {
514
+ await options.storage.write(options.pathname, new TextEncoder().encode(html));
515
+ return;
516
+ }
517
+ if (options.file === undefined) {
518
+ log(`[moons] isr: lewati ${options.pathname} — tanpa file/storage tujuan`);
519
+ return;
520
+ }
513
521
  const tmp = `${options.file}.tmp-${process.pid}`;
514
522
  writeFileSync(tmp, html);
515
523
  renameSync(tmp, options.file);
@@ -518,6 +526,50 @@ async function runRevalidate(options) {
518
526
  }
519
527
  }
520
528
 
529
+ // src/server/storage.ts
530
+ import { mkdirSync, readFileSync, renameSync as renameSync2, statSync, writeFileSync as writeFileSync2 } from "node:fs";
531
+ import { dirname, extname } from "node:path";
532
+ function createFileStorage(clientDir) {
533
+ return {
534
+ async read(pathname) {
535
+ const file = resolveStaticFile(clientDir, pathname);
536
+ if (file === null) {
537
+ return null;
538
+ }
539
+ const stat = statSync(file);
540
+ return { body: readFileSync(file), mtimeMs: stat.mtimeMs };
541
+ },
542
+ async write(pathname, body) {
543
+ const target = staticFileTarget(clientDir, pathname);
544
+ if (target === null) {
545
+ throw new Error(`[moons] isr: path tidak valid untuk ditulis: ${pathname}`);
546
+ }
547
+ mkdirSync(dirname(target), { recursive: true });
548
+ const tmp = `${target}.tmp-${process.pid}`;
549
+ writeFileSync2(tmp, body);
550
+ renameSync2(tmp, target);
551
+ }
552
+ };
553
+ }
554
+ function contentTypeForPathname(pathname) {
555
+ const ext = extname(pathname.split("?")[0] ?? "").toLowerCase();
556
+ return MIME[ext] ?? MIME[".html"] ?? "text/html; charset=utf-8";
557
+ }
558
+ var MIME = {
559
+ ".html": "text/html; charset=utf-8",
560
+ ".js": "text/javascript; charset=utf-8",
561
+ ".mjs": "text/javascript; charset=utf-8",
562
+ ".css": "text/css; charset=utf-8",
563
+ ".json": "application/json; charset=utf-8",
564
+ ".txt": "text/plain; charset=utf-8",
565
+ ".svg": "image/svg+xml",
566
+ ".ico": "image/x-icon",
567
+ ".png": "image/png",
568
+ ".webp": "image/webp",
569
+ ".woff": "font/woff",
570
+ ".woff2": "font/woff2"
571
+ };
572
+
521
573
  // src/server/shutdown.ts
522
574
  function installGracefulShutdown(server, options = {}) {
523
575
  const timeoutMs = options.timeoutMs ?? 1e4;
@@ -594,14 +646,49 @@ function startNodeServer(handler, options = {}) {
594
646
  try {
595
647
  const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
596
648
  if (req.method === "GET" || req.method === "HEAD") {
597
- const staticFile = resolveStaticFile(clientDir, url.pathname);
598
- if (staticFile !== null) {
599
- scheduleRevalidation(staticFile, url.pathname, handler, options, clientDir);
600
- const body = readFileSync(staticFile);
601
- res.statusCode = 200;
602
- res.setHeader("content-type", MIME_TYPES[extname(staticFile).toLowerCase()] ?? "application/octet-stream");
603
- res.end(req.method === "HEAD" ? undefined : body);
604
- return;
649
+ if (options.storage !== undefined) {
650
+ const entry = await options.storage.read(url.pathname);
651
+ if (entry !== null) {
652
+ scheduleRevalidation({
653
+ pathname: url.pathname,
654
+ mtimeMs: entry.mtimeMs,
655
+ storage: options.storage,
656
+ handler,
657
+ options,
658
+ clientDir
659
+ });
660
+ res.statusCode = 200;
661
+ res.setHeader("content-type", contentTypeForPathname(url.pathname));
662
+ for (const [name, value] of Object.entries(options.headers ?? {})) {
663
+ if (!res.hasHeader(name)) {
664
+ res.setHeader(name, value);
665
+ }
666
+ }
667
+ res.end(req.method === "HEAD" ? undefined : Buffer.from(entry.body));
668
+ return;
669
+ }
670
+ } else {
671
+ const staticFile = resolveStaticFile(clientDir, url.pathname);
672
+ if (staticFile !== null) {
673
+ scheduleRevalidation({
674
+ pathname: url.pathname,
675
+ mtimeMs: statSync2(staticFile).mtimeMs,
676
+ file: staticFile,
677
+ handler,
678
+ options,
679
+ clientDir
680
+ });
681
+ const body = readFileSync2(staticFile);
682
+ res.statusCode = 200;
683
+ res.setHeader("content-type", MIME_TYPES[extname2(staticFile).toLowerCase()] ?? "application/octet-stream");
684
+ for (const [name, value] of Object.entries(options.headers ?? {})) {
685
+ if (!res.hasHeader(name)) {
686
+ res.setHeader(name, value);
687
+ }
688
+ }
689
+ res.end(req.method === "HEAD" ? undefined : body);
690
+ return;
691
+ }
605
692
  }
606
693
  }
607
694
  const response = await handler(await toWebRequest2(req));
@@ -638,6 +725,10 @@ function startNodeServer(handler, options = {}) {
638
725
  return server;
639
726
  }
640
727
  function resolveStaticFile(clientDir, pathname) {
728
+ const target = staticFileTarget(clientDir, pathname);
729
+ return target !== null && isFile(target) ? target : null;
730
+ }
731
+ function staticFileTarget(clientDir, pathname) {
641
732
  let decoded;
642
733
  try {
643
734
  decoded = decodeURIComponent(pathname);
@@ -652,10 +743,7 @@ function resolveStaticFile(clientDir, pathname) {
652
743
  const manifest = readPrerenderManifest(clientDir);
653
744
  if (manifest.paths.has(normalized)) {
654
745
  const target = normalized === "/" ? "index.html" : `${normalized.slice(1)}/index.html`;
655
- const candidate = safeWithin(clientDir, `./${target}`);
656
- if (candidate !== null && isFile(candidate)) {
657
- return candidate;
658
- }
746
+ return safeWithin(clientDir, `./${target}`);
659
747
  }
660
748
  return null;
661
749
  }
@@ -667,18 +755,18 @@ function safeWithin(clientDir, relative) {
667
755
  return candidate;
668
756
  }
669
757
  function isFile(path) {
670
- return existsSync(path) && statSync(path).isFile();
758
+ return existsSync(path) && statSync2(path).isFile();
671
759
  }
672
760
  var prerenderManifestCache = null;
673
761
  function readPrerenderManifest(clientDir) {
674
762
  const file = join(clientDir, "_moons_prerender.json");
675
763
  const empty = { paths: new Set, revalidate: new Map };
676
764
  try {
677
- const mtimeMs = statSync(file).mtimeMs;
765
+ const mtimeMs = statSync2(file).mtimeMs;
678
766
  if (prerenderManifestCache !== null && prerenderManifestCache.file === file && prerenderManifestCache.mtimeMs === mtimeMs) {
679
767
  return prerenderManifestCache.info;
680
768
  }
681
- const json = JSON.parse(readFileSync(file, "utf8"));
769
+ const json = JSON.parse(readFileSync2(file, "utf8"));
682
770
  const paths = new Set;
683
771
  const revalidate = new Map;
684
772
  if (Array.isArray(json.paths)) {
@@ -708,26 +796,22 @@ function readPrerenderManifest(clientDir) {
708
796
  return empty;
709
797
  }
710
798
  }
711
- function scheduleRevalidation(staticFile, pathname, handler, options, clientDir) {
712
- const normalized = pathname.length > 1 ? pathname.replace(/\/+$/, "") : pathname;
713
- const seconds = readPrerenderManifest(clientDir).revalidate.get(normalized);
799
+ function scheduleRevalidation(input) {
800
+ const normalized = input.pathname.length > 1 ? input.pathname.replace(/\/+$/, "") : input.pathname;
801
+ const seconds = readPrerenderManifest(input.clientDir).revalidate.get(normalized);
714
802
  if (seconds === undefined || seconds < 0) {
715
803
  return;
716
804
  }
717
- let mtimeMs;
718
- try {
719
- mtimeMs = statSync(staticFile).mtimeMs;
720
- } catch {
721
- return;
722
- }
723
- if (!shouldRevalidate({ mtimeMs, revalidateSeconds: seconds })) {
805
+ if (!shouldRevalidate({ mtimeMs: input.mtimeMs, revalidateSeconds: seconds })) {
724
806
  return;
725
807
  }
726
808
  revalidatePrerendered({
727
809
  pathname: normalized,
728
- file: staticFile,
729
- handler,
730
- ...options.canary === undefined ? {} : { canary: options.canary }
810
+ ...input.file === undefined ? {} : { file: input.file },
811
+ ...input.storage === undefined ? {} : { storage: input.storage },
812
+ handler: input.handler,
813
+ ...input.options.canary === undefined ? {} : { canary: input.options.canary },
814
+ env: process.env
731
815
  });
732
816
  }
733
817
  // src/server/test-server.ts
@@ -803,8 +887,8 @@ function createPluginRuntime(options) {
803
887
  }
804
888
  // src/server/prerender.ts
805
889
  import { MoonsError as MoonsError2 } from "@moonsjs/core";
806
- import { mkdirSync, writeFileSync as writeFileSync2 } from "node:fs";
807
- import { dirname, join as join2, resolve as resolve2, sep as sep2 } from "node:path";
890
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
891
+ import { dirname as dirname2, join as join2, resolve as resolve2, sep as sep2 } from "node:path";
808
892
  var PRERENDER_MANIFEST_FILE = "_moons_prerender.json";
809
893
  var NOT_FOUND_SENTINEL = "/_moons/404";
810
894
  var NOT_FOUND_FILE = "404.html";
@@ -864,8 +948,8 @@ async function runPrerender(options) {
864
948
  const html = await response.text();
865
949
  assertNoLeak(html, pathname, route.file, options, env);
866
950
  const file = outputFile(options.clientDir, pathname);
867
- mkdirSync(dirname(file), { recursive: true });
868
- writeFileSync2(file, html);
951
+ mkdirSync2(dirname2(file), { recursive: true });
952
+ writeFileSync3(file, html);
869
953
  entries.push(typeof revalidate === "number" && revalidate >= 0 ? { path: pathname, revalidate } : { path: pathname });
870
954
  written += 1;
871
955
  }
@@ -873,10 +957,10 @@ async function runPrerender(options) {
873
957
  const notFound = await renderStaticNotFound(options, env, log);
874
958
  let wrote404 = false;
875
959
  if (notFound !== null) {
876
- writeFileSync2(join2(options.clientDir, NOT_FOUND_FILE), notFound);
960
+ writeFileSync3(join2(options.clientDir, NOT_FOUND_FILE), notFound);
877
961
  wrote404 = true;
878
962
  }
879
- writeFileSync2(join2(options.clientDir, PRERENDER_MANIFEST_FILE), `${JSON.stringify({ version: 2, entries }, null, 2)}
963
+ writeFileSync3(join2(options.clientDir, PRERENDER_MANIFEST_FILE), `${JSON.stringify({ version: 2, entries }, null, 2)}
880
964
  `);
881
965
  const emitted = emitStaticFiles(options.clientDir, options.staticConfig, entries);
882
966
  const extras = [...wrote404 ? [NOT_FOUND_FILE] : [], ...emitted];
@@ -891,7 +975,7 @@ function emitStaticFiles(clientDir, staticConfig, entries) {
891
975
  const headers = Object.entries(staticConfig.headers ?? {});
892
976
  if (headers.length > 0) {
893
977
  const lines = ["/*", ...headers.map(([name, value]) => ` ${name}: ${value}`)];
894
- writeFileSync2(join2(clientDir, "_headers"), `${lines.join(`
978
+ writeFileSync3(join2(clientDir, "_headers"), `${lines.join(`
895
979
  `)}
896
980
  `);
897
981
  emitted.push("_headers");
@@ -899,7 +983,7 @@ function emitStaticFiles(clientDir, staticConfig, entries) {
899
983
  const redirects = staticConfig.redirects ?? [];
900
984
  if (redirects.length > 0) {
901
985
  const lines = redirects.map((entry) => `${entry.from} ${entry.to} ${entry.status ?? 301}`);
902
- writeFileSync2(join2(clientDir, "_redirects"), `${lines.join(`
986
+ writeFileSync3(join2(clientDir, "_redirects"), `${lines.join(`
903
987
  `)}
904
988
  `);
905
989
  emitted.push("_redirects");
@@ -917,7 +1001,7 @@ function emitStaticFiles(clientDir, staticConfig, entries) {
917
1001
  ""
918
1002
  ].join(`
919
1003
  `);
920
- writeFileSync2(join2(clientDir, "sitemap.xml"), xml);
1004
+ writeFileSync3(join2(clientDir, "sitemap.xml"), xml);
921
1005
  emitted.push("sitemap.xml");
922
1006
  }
923
1007
  const robots = staticConfig.robots;
@@ -929,7 +1013,7 @@ function emitStaticFiles(clientDir, staticConfig, entries) {
929
1013
  if ((robots.sitemap ?? true) && sitemap !== undefined) {
930
1014
  lines.push("", `Sitemap: ${sitemap.site.replace(/\/$/, "")}/sitemap.xml`);
931
1015
  }
932
- writeFileSync2(join2(clientDir, "robots.txt"), `${lines.join(`
1016
+ writeFileSync3(join2(clientDir, "robots.txt"), `${lines.join(`
933
1017
  `)}
934
1018
  `);
935
1019
  emitted.push("robots.txt");
@@ -1080,8 +1164,10 @@ function prerenderError(route, message) {
1080
1164
  export {
1081
1165
  DEFAULT_TEMPLATE2 as DEFAULT_TEMPLATE,
1082
1166
  ROOT_PLACEHOLDER2 as ROOT_PLACEHOLDER,
1167
+ contentTypeForPathname,
1083
1168
  createDevShell2 as createDevShell,
1084
1169
  createFileShell2 as createFileShell,
1170
+ createFileStorage,
1085
1171
  createPluginRuntime,
1086
1172
  createRequestHandler,
1087
1173
  createTestServer,
@@ -1095,4 +1181,4 @@ export {
1095
1181
  toWebRequest2 as toWebRequest
1096
1182
  };
1097
1183
 
1098
- //# debugId=52F0831250D554E464756E2164756E21
1184
+ //# debugId=9A8636F992D1AC9F64756E2164756E21