heliumts 0.8.7 → 0.8.9
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/server/prodServer.d.ts.map +1 -1
- package/dist/server/prodServer.js +3 -0
- package/dist/server/prodServer.js.map +1 -1
- package/dist/utils/envLoader.d.ts +27 -0
- package/dist/utils/envLoader.d.ts.map +1 -1
- package/dist/utils/envLoader.js +56 -1
- package/dist/utils/envLoader.js.map +1 -1
- package/dist/vite/heliumPlugin.d.ts.map +1 -1
- package/dist/vite/heliumPlugin.js +12 -4
- package/dist/vite/heliumPlugin.js.map +1 -1
- package/dist/vite/virtualServerModule.d.ts.map +1 -1
- package/dist/vite/virtualServerModule.js +8 -1
- package/dist/vite/virtualServerModule.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prodServer.d.ts","sourceRoot":"","sources":["../../src/server/prodServer.ts"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"prodServer.d.ts","sourceRoot":"","sources":["../../src/server/prodServer.ts"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAUtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAAuD,UAAU,EAAE,MAAM,UAAU,CAAC;AAM3F,UAAU,WAAW;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;CAC3B;AAED,UAAU,iBAAiB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACxG,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,aAAa,CAAC;QAAE,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CACrK;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,wEAmjBzD;AAqBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CA4BtF"}
|
|
@@ -8,6 +8,7 @@ import { brotliCompress, deflate, gzip } from "zlib";
|
|
|
8
8
|
import { SEO_METADATA_RPC_METHOD } from "../runtime/internalMethods.js";
|
|
9
9
|
import { extractClientIP } from "../utils/ipExtractor.js";
|
|
10
10
|
import { log } from "../utils/logger.js";
|
|
11
|
+
import { injectPublicEnvIntoHtml } from "../utils/envLoader.js";
|
|
11
12
|
import { getRpcConfig, getRpcSecurityConfig, getTrustProxyDepth } from "./config.js";
|
|
12
13
|
import { startWorker, stopAllWorkers } from "./defineWorker.js";
|
|
13
14
|
import { HTTPRouter } from "./httpRouter.js";
|
|
@@ -364,6 +365,8 @@ export function startProdServer(options) {
|
|
|
364
365
|
if (metadata) {
|
|
365
366
|
html = injectSocialMetaIntoHtml(html, metadata);
|
|
366
367
|
}
|
|
368
|
+
// Inject runtime public env vars (for platform deployments like Render, DO Apps)
|
|
369
|
+
html = injectPublicEnvIntoHtml(html);
|
|
367
370
|
responseBody = Buffer.from(html, "utf-8");
|
|
368
371
|
}
|
|
369
372
|
// Set status code to 404 if serving the 404 page
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prodServer.js","sourceRoot":"","sources":["../../src/server/prodServer.ts"],"names":[],"mappings":"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","sourcesContent":["import { encode as msgpackEncode } from \"@msgpack/msgpack\";\nimport fs from \"fs\";\nimport http from \"http\";\nimport path from \"path\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport { promisify } from \"util\";\nimport type WebSocket from \"ws\";\nimport { WebSocketServer } from \"ws\";\nimport { brotliCompress, deflate, gzip } from \"zlib\";\n\nimport { SEO_METADATA_RPC_METHOD } from \"../runtime/internalMethods.js\";\nimport { extractClientIP } from \"../utils/ipExtractor.js\";\nimport { log } from \"../utils/logger.js\";\nimport type { HeliumConfig } from \"./config.js\";\nimport { getRpcConfig, getRpcSecurityConfig, getTrustProxyDepth } from \"./config.js\";\nimport type { HeliumContext } from \"./context.js\";\nimport type { HeliumWorkerDef } from \"./defineWorker.js\";\nimport { startWorker, stopAllWorkers } from \"./defineWorker.js\";\nimport { HTTPRouter } from \"./httpRouter.js\";\nimport { injectSocialMetaIntoHtml, loadDefaultSocialMetaFromHtmlFile } from \"./meta.js\";\nimport { RateLimiter } from \"./rateLimiter.js\";\nimport { RpcRegistry } from \"./rpcRegistry.js\";\nimport { generateConnectionToken, initializeSecurity, verifyConnectionToken } from \"./security.js\";\nimport { SEOMetadataRouter } from \"./seoMetadataRouter.js\";\nimport { prepareForMsgpack } from \"./serializer.js\";\nimport { matchSSRPage, renderSSRHTML, resolveServerSideProps, SSRPageDef } from \"./ssr.js\";\n\nconst gzipAsync = promisify(gzip);\nconst deflateAsync = promisify(deflate);\nconst brotliCompressAsync = promisify(brotliCompress);\n\ninterface WorkerEntry {\n name: string;\n worker: HeliumWorkerDef;\n}\n\ninterface ProdServerOptions {\n port?: number;\n distDir?: string;\n staticDir?: string;\n registerHandlers: (registry: RpcRegistry, httpRouter: HTTPRouter, seoRouter: SEOMetadataRouter) => void;\n config?: HeliumConfig;\n workers?: WorkerEntry[];\n ssrPages?: SSRPageDef[];\n appShell?: (() => Promise<ComponentType<{ Component: ComponentType<Record<string, unknown>>; pageProps: Record<string, unknown>; children?: ReactNode }>>) | null;\n}\n\n/**\n * Starts a production HTTP server that:\n * - Serves static files from the dist directory\n * - Supports SSG (Static Site Generation) by serving .html files for routes (e.g., /about -> about.html)\n * - Falls back to index.html for client-side routing (SPA)\n * - Handles custom HTTP endpoints (webhooks, auth, etc.)\n * - Hosts WebSocket RPC server\n * - Starts background workers\n *\n * SSG Behavior:\n * - Production correctly serves SSG pages (e.g., /about serves about.html with pre-rendered content)\n * - This ensures search engines and social media crawlers see the correct content\n * - Client-side navigation between pages still works via React Router\n */\nexport function startProdServer(options: ProdServerOptions) {\n const {\n port = Number(process.env.PORT || 3000),\n distDir = \"dist\",\n staticDir = path.resolve(process.cwd(), distDir),\n registerHandlers,\n config = {},\n workers = [],\n ssrPages = [],\n appShell = null,\n } = options;\n\n // Load configuration\n const trustProxyDepth = getTrustProxyDepth(config);\n const rpcSecurity = getRpcSecurityConfig(config);\n const rpcConfig = getRpcConfig(config);\n const compressionConfig = rpcConfig.compression;\n initializeSecurity(rpcSecurity);\n\n // Initialize rate limiter\n const rateLimiter = new RateLimiter(rpcSecurity.maxMessagesPerWindow, rpcSecurity.rateLimitWindowMs, rpcSecurity.maxConnectionsPerIP);\n\n const registry = new RpcRegistry();\n const httpRouter = new HTTPRouter({ maxBodySize: rpcConfig.maxBodySize });\n const seoRouter = new SEOMetadataRouter();\n httpRouter.setTrustProxyDepth(trustProxyDepth);\n registerHandlers(registry, httpRouter, seoRouter);\n registry.setRateLimiter(rateLimiter);\n registry.setMaxBatchSize(rpcConfig.maxBatchSize);\n\n // Security: max body size for HTTP requests (1 MB default)\n const maxBodySize = rpcConfig.maxBodySize ?? 1_048_576;\n let cachedDefaultMeta: Awaited<ReturnType<typeof loadDefaultSocialMetaFromHtmlFile>> | undefined;\n\n const getDefaultMeta = async () => {\n if (cachedDefaultMeta !== undefined) {\n return cachedDefaultMeta;\n }\n\n cachedDefaultMeta = await loadDefaultSocialMetaFromHtmlFile(path.join(staticDir, \"index.html\"));\n return cachedDefaultMeta;\n };\n\n registry.register(SEO_METADATA_RPC_METHOD, {\n __kind: \"method\",\n __id: SEO_METADATA_RPC_METHOD,\n handler: async (args: { path?: string } | undefined, ctx: HeliumContext) => {\n const requestedPath = typeof args?.path === \"string\" ? args.path : \"/\";\n const targetPath = requestedPath.startsWith(\"/\") ? requestedPath : `/${requestedPath}`;\n const metadata = await seoRouter.resolve(ctx.req.raw, ctx, targetPath);\n return metadata ?? (await getDefaultMeta());\n },\n });\n\n // Create HTTP server\n const server = http.createServer(async (req, res) => {\n // Apply security headers to all responses\n setSecurityHeaders(res, config);\n\n // Handle CORS preflight\n if (req.method === \"OPTIONS\") {\n handleCorsHeaders(req, res, config);\n res.writeHead(204);\n res.end();\n return;\n }\n handleCorsHeaders(req, res, config);\n\n // Handle token refresh endpoint\n const requestUrl = new URL(req.url || \"/\", \"http://localhost\");\n const requestPathname = requestUrl.pathname;\n\n if (requestPathname === \"/__helium__/page-props\" && req.method === \"GET\") {\n const pathQuery = requestUrl.searchParams.get(\"path\") || \"/\";\n const targetUrl = new URL(pathQuery, \"http://localhost\");\n const targetPathname = targetUrl.pathname;\n const ssrMatch = matchSSRPage(targetPathname, ssrPages);\n\n if (!ssrMatch) {\n res.writeHead(200, { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\" });\n res.end(JSON.stringify({ ssr: false, props: null }));\n return;\n }\n\n const ip = extractClientIP(req, trustProxyDepth);\n const httpCtx: HeliumContext = {\n req: {\n ip,\n headers: req.headers,\n url: req.url,\n method: req.method,\n raw: req,\n },\n };\n\n try {\n const ssrResult = await resolveServerSideProps({\n req,\n pathname: targetPathname,\n params: ssrMatch.params,\n page: ssrMatch.page,\n ctx: httpCtx,\n });\n\n if (ssrResult.kind === \"redirect\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\" });\n res.end(JSON.stringify({ ssr: true, redirect: ssrResult.redirect }));\n return;\n }\n\n res.writeHead(200, { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\" });\n res.end(JSON.stringify({ ssr: true, props: ssrResult.props }));\n } catch (error) {\n log(\"error\", \"Failed to resolve SSR page props:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\" });\n res.end(JSON.stringify({ ssr: true, props: null, error: \"Internal server error\" }));\n }\n\n return;\n }\n\n if (req.url === \"/__helium__/refresh-token\") {\n // Security: only allow POST to prevent CSRF via <img>/<script> tags\n if (req.method !== \"POST\") {\n res.writeHead(405, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Method not allowed\" }));\n return;\n }\n // Security: require custom header to prevent cross-origin requests\n if (!req.headers[\"x-requested-with\"]) {\n res.writeHead(403, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Forbidden\" }));\n return;\n }\n const token = generateConnectionToken();\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ token }));\n return;\n }\n\n // Handle HTTP-based RPC endpoint (alternative to WebSocket for mobile networks)\n if (req.url === \"/__helium__/rpc\" && req.method === \"POST\") {\n // Security: verify connection token for HTTP RPC\n const authToken = req.headers[\"x-helium-token\"] as string | undefined;\n if (!authToken || !verifyConnectionToken(authToken)) {\n res.writeHead(401, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: false, error: \"Unauthorized\" }));\n return;\n }\n\n // Security: check Content-Length before reading body\n const contentLength = parseInt(req.headers[\"content-length\"] || \"0\", 10);\n if (contentLength > maxBodySize) {\n res.writeHead(413, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: false, error: \"Request entity too large\" }));\n return;\n }\n\n const chunks: Buffer[] = [];\n let totalSize = 0;\n let aborted = false;\n req.on(\"data\", (chunk: Buffer) => {\n totalSize += chunk.length;\n if (totalSize > maxBodySize) {\n aborted = true;\n req.destroy();\n res.writeHead(413, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: false, error: \"Request entity too large\" }));\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", async () => {\n if (aborted) {\n return;\n }\n try {\n const body = Buffer.concat(chunks);\n const ip = extractClientIP(req, trustProxyDepth);\n const result = await registry.handleHttpRequest(body, ip, req);\n\n const encoded = msgpackEncode(prepareForMsgpack(result.response));\n let responseBody = Buffer.from(encoded as Uint8Array);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/msgpack\",\n \"Cache-Control\": \"no-store\",\n };\n\n // Handle compression\n const acceptEncoding = req.headers[\"accept-encoding\"] as string;\n if (acceptEncoding && responseBody.length > 1024) {\n if (acceptEncoding.includes(\"br\")) {\n responseBody = await brotliCompressAsync(responseBody);\n headers[\"Content-Encoding\"] = \"br\";\n } else if (acceptEncoding.includes(\"gzip\")) {\n responseBody = await gzipAsync(responseBody);\n headers[\"Content-Encoding\"] = \"gzip\";\n } else if (acceptEncoding.includes(\"deflate\")) {\n responseBody = await deflateAsync(responseBody);\n headers[\"Content-Encoding\"] = \"deflate\";\n }\n }\n\n res.writeHead(200, headers);\n res.end(responseBody);\n } catch (error) {\n log(\"error\", \"HTTP RPC error:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: false, error: \"Internal server error\" }));\n }\n });\n return;\n }\n\n // Try HTTP handlers first (webhooks, auth, etc.)\n const handled = await httpRouter.handleRequest(req, res);\n if (handled) {\n return;\n }\n\n // Serve static files\n const url = req.url || \"/\";\n\n // Block access to sensitive configuration and server files\n const blockedFiles = [\"helium.config.js\", \"helium.config.mjs\", \"helium.config.ts\", \"server.js\", \".env\", \".env.local\", \".env.production\"];\n\n const requestedFile = path.basename(url.split(\"?\")[0]);\n let filePath: string = path.join(staticDir, \"index.html\");\n let is404 = false;\n\n if (blockedFiles.some((blocked) => requestedFile === blocked || requestedFile.startsWith(\".env\"))) {\n // Serve index.html so the SPA router can render the 404 page\n filePath = path.join(staticDir, \"index.html\");\n is404 = true;\n } else {\n // Clean URL (remove query params and trailing slash)\n const cleanUrl = url.split(\"?\")[0].replace(/\\/$/, \"\") || \"/\";\n\n // Security: path traversal prevention — resolve and verify\n const resolvedStaticDir = path.resolve(staticDir);\n const candidatePath = path.resolve(staticDir, \".\" + cleanUrl);\n if (!candidatePath.startsWith(resolvedStaticDir + path.sep) && candidatePath !== resolvedStaticDir) {\n filePath = path.join(staticDir, \"index.html\");\n is404 = true;\n }\n\n // Try different file paths for SSG support\n if (!is404 && cleanUrl === \"/\") {\n // Try index.ssg.html first (if root page has SSG)\n const ssgIndexPath = path.join(staticDir, \"index.ssg.html\");\n if (fs.existsSync(ssgIndexPath)) {\n filePath = ssgIndexPath;\n } else {\n filePath = path.join(staticDir, \"index.html\");\n }\n } else if (!is404) {\n // If cleanUrl has no extension, prioritize .html files for SSG pages\n if (!path.extname(cleanUrl)) {\n const htmlPath = path.join(staticDir, cleanUrl + \".html\");\n if (fs.existsSync(htmlPath)) {\n filePath = htmlPath;\n } else {\n // Fall back to exact path (for assets or directories)\n filePath = path.join(staticDir, cleanUrl);\n }\n } else {\n // Has an extension, try exact path (for assets like /assets/main.js)\n filePath = path.join(staticDir, cleanUrl);\n }\n }\n\n // If file doesn't exist or is a directory, fall back to index.html for SPA routing\n const isFileOrExists = !is404 && filePath && fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n if (!isFileOrExists && !url.startsWith(\"/api\") && !url.startsWith(\"/webhooks\") && !url.startsWith(\"/auth\")) {\n // Fall back to index.html for SPA routing\n // Note: We don't set is404 here because the client-side router will determine\n // if the route exists. If it doesn't, the router will render the 404 page.\n filePath = path.join(staticDir, \"index.html\");\n // Don't set is404 = true here - let the client-side router handle it\n }\n }\n\n // Check if file exists (should always exist now since we fallback to index.html)\n if (!fs.existsSync(filePath)) {\n // This should rarely happen - only if index.html itself is missing\n res.writeHead(404, { \"Content-Type\": \"text/html\" });\n res.end(\"Not found\");\n return;\n }\n\n // Determine content type\n const ext = path.extname(filePath);\n const contentTypes: Record<string, string> = {\n \".html\": \"text/html\",\n \".js\": \"application/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".eot\": \"application/vnd.ms-fontobject\",\n };\n const contentType = contentTypes[ext] || \"application/octet-stream\";\n\n try {\n const content = fs.readFileSync(filePath);\n let responseBody = content;\n const cleanedPathname = (req.url || \"/\").split(\"?\")[0].replace(/\\/$/, \"\") || \"/\";\n const htmlSsrMatch = req.method === \"GET\" && contentType === \"text/html\" ? matchSSRPage(cleanedPathname, ssrPages) : null;\n\n if (!is404 && contentType === \"text/html\") {\n const ip = extractClientIP(req, trustProxyDepth);\n const httpCtx: HeliumContext = {\n req: {\n ip,\n headers: req.headers,\n url: req.url,\n method: req.method,\n raw: req,\n },\n };\n\n const metadata = await seoRouter.resolve(req, httpCtx);\n let html = content.toString(\"utf-8\");\n\n if (htmlSsrMatch) {\n try {\n const rendered = await renderSSRHTML({\n htmlTemplate: html,\n pathname: cleanedPathname,\n search: requestUrl.search,\n params: htmlSsrMatch.params,\n page: htmlSsrMatch.page,\n req,\n ctx: httpCtx,\n loadAppShell: appShell,\n });\n\n if (\"redirect\" in rendered) {\n res.writeHead(rendered.redirect.statusCode, {\n Location: rendered.redirect.destination,\n \"Cache-Control\": \"no-store\",\n });\n res.end();\n return;\n }\n\n html = rendered.html;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const isBrowserGlobalError = /\\bwindow is not defined\\b|\\bdocument is not defined\\b|\\bnavigator is not defined\\b/i.test(message);\n\n if (isBrowserGlobalError) {\n log(\n \"warn\",\n `SSR disabled for ${cleanedPathname} due to browser-only import. Render map/browser-only modules on client only (e.g. dynamic import inside useEffect).`\n );\n } else {\n log(\"error\", `Failed to render SSR page for ${cleanedPathname}:`, error);\n }\n }\n }\n\n if (metadata) {\n html = injectSocialMetaIntoHtml(html, metadata);\n }\n\n responseBody = Buffer.from(html, \"utf-8\");\n }\n\n // Set status code to 404 if serving the 404 page\n const statusCode = is404 ? 404 : 200;\n res.writeHead(statusCode, { \"Content-Type\": contentType });\n res.end(responseBody);\n } catch (error) {\n log(\"error\", \"Error serving file:\", error);\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(\"Internal server error\");\n }\n });\n\n // Setup WebSocket server for RPC\n const wss = new WebSocketServer({\n noServer: true,\n maxPayload: rpcConfig.maxWsPayload,\n perMessageDeflate: compressionConfig.enabled\n ? {\n zlibDeflateOptions: {\n chunkSize: 1024,\n memLevel: 7,\n level: 9, // 6 is default compression level (balanced)\n },\n zlibInflateOptions: {\n chunkSize: 10 * 1024,\n },\n threshold: compressionConfig.threshold,\n }\n : false,\n });\n\n wss.on(\"connection\", (socket: WebSocket, req: http.IncomingMessage) => {\n // Extract client IP with proxy configuration\n const ip = extractClientIP(req, trustProxyDepth);\n\n // Store connection metadata for RPC context\n registry.setSocketMetadata(socket, ip, req);\n\n // Track connection and check IP limit\n if (!rateLimiter.trackConnection(socket, ip)) {\n socket.close(1008, \"Too many connections from your IP\");\n return;\n }\n\n // Prevent unhandled errors from crashing the process (e.g. maxPayload exceeded)\n socket.on(\"error\", (err) => {\n log(\"warn\", \"WebSocket error:\", err);\n if (socket.readyState === socket.OPEN || socket.readyState === socket.CLOSING) {\n socket.close(1009, \"Message too large\");\n }\n });\n\n socket.on(\"message\", (msg: WebSocket.RawData, _isBinary: boolean) => {\n // Check rate limit\n if (!rateLimiter.checkRateLimit(socket)) {\n // Parse request to get the ID for proper error response\n try {\n let req: any;\n // Always expect MessagePack\n const buffer = Buffer.isBuffer(msg) ? msg : Buffer.from(msg as any);\n const { decode: msgpackDecode } = require(\"@msgpack/msgpack\");\n req = msgpackDecode(buffer);\n\n const stats = rateLimiter.getConnectionStats(socket);\n const now = Date.now();\n const resetInSeconds = stats ? Math.ceil((stats.resetTimeMs - now) / 1000) : 0;\n\n const createError = (id: string) => ({\n id,\n ok: false,\n stats: {\n remainingRequests: stats ? stats.remainingMessages : 0,\n resetInSeconds,\n },\n error: \"Rate limit exceeded\",\n });\n\n let errorResponse: any;\n if (Array.isArray(req)) {\n errorResponse = req.map((r: any) => createError(r.id));\n } else {\n errorResponse = createError(req.id);\n }\n\n log(\"warn\", `Rate limit exceeded for IP ${ip}, resets in ${resetInSeconds} seconds`);\n socket.send(msgpackEncode(errorResponse) as Buffer);\n } catch {\n // If we can't parse the request, just close the connection\n socket.close();\n }\n return;\n }\n\n registry.handleMessage(socket, Buffer.isBuffer(msg) ? msg : Buffer.from(msg as any));\n });\n });\n\n // Handle WebSocket upgrade requests\n server.on(\"upgrade\", (req, socket, head) => {\n if (req.url?.startsWith(\"/rpc\")) {\n // Security: read token from Sec-WebSocket-Protocol header instead of query string\n const protocols = req.headers[\"sec-websocket-protocol\"];\n const token =\n typeof protocols === \"string\"\n ? protocols\n .split(\",\")\n .map((p) => p.trim())\n .find((p) => p.includes(\".\"))\n : undefined;\n\n if (!token || !verifyConnectionToken(token)) {\n log(\"warn\", \"WebSocket connection rejected - invalid token\");\n socket.write(\"HTTP/1.1 401 Unauthorized\\r\\n\\r\\n\");\n socket.destroy();\n return;\n }\n\n // Check IP connection limit before upgrading\n const ip = extractClientIP(req, trustProxyDepth);\n if (rpcSecurity.maxConnectionsPerIP > 0) {\n const currentConnections = rateLimiter.getIPConnectionCount(ip);\n if (currentConnections >= rpcSecurity.maxConnectionsPerIP) {\n log(\"warn\", `WebSocket connection rejected - IP ${ip} has ${currentConnections} connections`);\n socket.write(\"HTTP/1.1 429 Too Many Requests\\r\\n\\r\\n\");\n socket.destroy();\n return;\n }\n }\n\n wss.handleUpgrade(req, socket, head, (ws) => {\n wss.emit(\"connection\", ws, req);\n });\n } else {\n socket.destroy();\n }\n });\n\n // Start server\n server.listen(port, () => {\n log(\"info\", `Production server listening on http://localhost:${port}`);\n log(\"info\", `Serving static files from ${staticDir}`);\n log(\"info\", `WebSocket RPC available at ws://localhost:${port}/rpc`);\n\n // Start workers\n if (workers.length > 0) {\n log(\"info\", `Starting ${workers.length} worker(s)...`);\n for (const { name, worker } of workers) {\n // Use export name if worker name is anonymous\n if (worker.name === \"anonymous\") {\n worker.name = name;\n worker.__id = name;\n worker.options.name = name;\n }\n if (worker.options.autoStart) {\n const createContext = (): HeliumContext => ({\n req: {\n ip: \"127.0.0.1\",\n headers: {},\n url: undefined,\n method: undefined,\n raw: {} as http.IncomingMessage,\n },\n });\n startWorker(worker, createContext).catch((err) => {\n log(\"error\", `Failed to start worker '${worker.name}':`, err);\n });\n }\n }\n }\n });\n\n // Handle graceful shutdown\n const shutdown = async () => {\n log(\"info\", \"Shutting down...\");\n await stopAllWorkers();\n server.close(() => {\n log(\"info\", \"Server closed\");\n process.exit(0);\n });\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n return server;\n}\n\n// ============================================================================\n// Security helper functions\n// ============================================================================\n\n/**\n * Set default security headers on every HTTP response.\n */\nfunction setSecurityHeaders(res: http.ServerResponse, config: HeliumConfig): void {\n const headers = getSecurityHeaders(config);\n\n for (const [name, value] of Object.entries(headers)) {\n if (value === null) {\n res.removeHeader(name);\n continue;\n }\n res.setHeader(name, value);\n }\n}\n\n/**\n * Resolve security headers for the current request from config.\n * Returns a final header map where `null` indicates the header should be removed.\n *\n * @internal\n */\nexport function getSecurityHeaders(config: HeliumConfig): Record<string, string | null> {\n const headers: Record<string, string | null> = {};\n const securityConfig = config.security;\n\n if (securityConfig?.defaultHeaders !== false) {\n headers[\"X-Content-Type-Options\"] = \"nosniff\";\n headers[\"X-Frame-Options\"] = \"DENY\";\n headers[\"X-XSS-Protection\"] = \"0\";\n headers[\"Referrer-Policy\"] = \"strict-origin-when-cross-origin\";\n headers[\"Permissions-Policy\"] = \"camera=(), microphone=(), geolocation=()\";\n\n const csp = securityConfig?.contentSecurityPolicy;\n if (csp) {\n headers[\"Content-Security-Policy\"] = csp;\n }\n\n if (securityConfig?.hsts !== false) {\n headers[\"Strict-Transport-Security\"] = \"max-age=31536000; includeSubDomains\";\n }\n }\n\n if (securityConfig?.headerOverrides) {\n for (const [name, value] of Object.entries(securityConfig.headerOverrides)) {\n headers[name] = value;\n }\n }\n\n return headers;\n}\n\n/**\n * Handle CORS headers based on configuration.\n * Default: restrict to same-origin (no CORS header = browser blocks cross-origin).\n */\nfunction handleCorsHeaders(req: http.IncomingMessage, res: http.ServerResponse, config: HeliumConfig): void {\n const allowedOrigins = config.security?.corsOrigins;\n if (!allowedOrigins || allowedOrigins.length === 0) {\n // No CORS configured — same-origin only by default\n return;\n }\n\n const origin = req.headers.origin;\n if (!origin) {\n return;\n }\n\n const isAllowed = allowedOrigins.includes(\"*\") || allowedOrigins.includes(origin);\n if (isAllowed) {\n res.setHeader(\"Access-Control-Allow-Origin\", allowedOrigins.includes(\"*\") ? \"*\" : origin);\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type, X-Requested-With, X-Helium-Token\");\n res.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\n if (!allowedOrigins.includes(\"*\")) {\n res.setHeader(\"Vary\", \"Origin\");\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"prodServer.js","sourceRoot":"","sources":["../../src/server/prodServer.ts"],"names":[],"mappings":"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","sourcesContent":["import { encode as msgpackEncode } from \"@msgpack/msgpack\";\nimport fs from \"fs\";\nimport http from \"http\";\nimport path from \"path\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport { promisify } from \"util\";\nimport type WebSocket from \"ws\";\nimport { WebSocketServer } from \"ws\";\nimport { brotliCompress, deflate, gzip } from \"zlib\";\n\nimport { SEO_METADATA_RPC_METHOD } from \"../runtime/internalMethods.js\";\nimport { extractClientIP } from \"../utils/ipExtractor.js\";\nimport { log } from \"../utils/logger.js\";\nimport { injectPublicEnvIntoHtml } from \"../utils/envLoader.js\";\nimport type { HeliumConfig } from \"./config.js\";\nimport { getRpcConfig, getRpcSecurityConfig, getTrustProxyDepth } from \"./config.js\";\nimport type { HeliumContext } from \"./context.js\";\nimport type { HeliumWorkerDef } from \"./defineWorker.js\";\nimport { startWorker, stopAllWorkers } from \"./defineWorker.js\";\nimport { HTTPRouter } from \"./httpRouter.js\";\nimport { injectSocialMetaIntoHtml, loadDefaultSocialMetaFromHtmlFile } from \"./meta.js\";\nimport { RateLimiter } from \"./rateLimiter.js\";\nimport { RpcRegistry } from \"./rpcRegistry.js\";\nimport { generateConnectionToken, initializeSecurity, verifyConnectionToken } from \"./security.js\";\nimport { SEOMetadataRouter } from \"./seoMetadataRouter.js\";\nimport { prepareForMsgpack } from \"./serializer.js\";\nimport { matchSSRPage, renderSSRHTML, resolveServerSideProps, SSRPageDef } from \"./ssr.js\";\n\nconst gzipAsync = promisify(gzip);\nconst deflateAsync = promisify(deflate);\nconst brotliCompressAsync = promisify(brotliCompress);\n\ninterface WorkerEntry {\n name: string;\n worker: HeliumWorkerDef;\n}\n\ninterface ProdServerOptions {\n port?: number;\n distDir?: string;\n staticDir?: string;\n registerHandlers: (registry: RpcRegistry, httpRouter: HTTPRouter, seoRouter: SEOMetadataRouter) => void;\n config?: HeliumConfig;\n workers?: WorkerEntry[];\n ssrPages?: SSRPageDef[];\n appShell?: (() => Promise<ComponentType<{ Component: ComponentType<Record<string, unknown>>; pageProps: Record<string, unknown>; children?: ReactNode }>>) | null;\n}\n\n/**\n * Starts a production HTTP server that:\n * - Serves static files from the dist directory\n * - Supports SSG (Static Site Generation) by serving .html files for routes (e.g., /about -> about.html)\n * - Falls back to index.html for client-side routing (SPA)\n * - Handles custom HTTP endpoints (webhooks, auth, etc.)\n * - Hosts WebSocket RPC server\n * - Starts background workers\n *\n * SSG Behavior:\n * - Production correctly serves SSG pages (e.g., /about serves about.html with pre-rendered content)\n * - This ensures search engines and social media crawlers see the correct content\n * - Client-side navigation between pages still works via React Router\n */\nexport function startProdServer(options: ProdServerOptions) {\n const {\n port = Number(process.env.PORT || 3000),\n distDir = \"dist\",\n staticDir = path.resolve(process.cwd(), distDir),\n registerHandlers,\n config = {},\n workers = [],\n ssrPages = [],\n appShell = null,\n } = options;\n\n // Load configuration\n const trustProxyDepth = getTrustProxyDepth(config);\n const rpcSecurity = getRpcSecurityConfig(config);\n const rpcConfig = getRpcConfig(config);\n const compressionConfig = rpcConfig.compression;\n initializeSecurity(rpcSecurity);\n\n // Initialize rate limiter\n const rateLimiter = new RateLimiter(rpcSecurity.maxMessagesPerWindow, rpcSecurity.rateLimitWindowMs, rpcSecurity.maxConnectionsPerIP);\n\n const registry = new RpcRegistry();\n const httpRouter = new HTTPRouter({ maxBodySize: rpcConfig.maxBodySize });\n const seoRouter = new SEOMetadataRouter();\n httpRouter.setTrustProxyDepth(trustProxyDepth);\n registerHandlers(registry, httpRouter, seoRouter);\n registry.setRateLimiter(rateLimiter);\n registry.setMaxBatchSize(rpcConfig.maxBatchSize);\n\n // Security: max body size for HTTP requests (1 MB default)\n const maxBodySize = rpcConfig.maxBodySize ?? 1_048_576;\n let cachedDefaultMeta: Awaited<ReturnType<typeof loadDefaultSocialMetaFromHtmlFile>> | undefined;\n\n const getDefaultMeta = async () => {\n if (cachedDefaultMeta !== undefined) {\n return cachedDefaultMeta;\n }\n\n cachedDefaultMeta = await loadDefaultSocialMetaFromHtmlFile(path.join(staticDir, \"index.html\"));\n return cachedDefaultMeta;\n };\n\n registry.register(SEO_METADATA_RPC_METHOD, {\n __kind: \"method\",\n __id: SEO_METADATA_RPC_METHOD,\n handler: async (args: { path?: string } | undefined, ctx: HeliumContext) => {\n const requestedPath = typeof args?.path === \"string\" ? args.path : \"/\";\n const targetPath = requestedPath.startsWith(\"/\") ? requestedPath : `/${requestedPath}`;\n const metadata = await seoRouter.resolve(ctx.req.raw, ctx, targetPath);\n return metadata ?? (await getDefaultMeta());\n },\n });\n\n // Create HTTP server\n const server = http.createServer(async (req, res) => {\n // Apply security headers to all responses\n setSecurityHeaders(res, config);\n\n // Handle CORS preflight\n if (req.method === \"OPTIONS\") {\n handleCorsHeaders(req, res, config);\n res.writeHead(204);\n res.end();\n return;\n }\n handleCorsHeaders(req, res, config);\n\n // Handle token refresh endpoint\n const requestUrl = new URL(req.url || \"/\", \"http://localhost\");\n const requestPathname = requestUrl.pathname;\n\n if (requestPathname === \"/__helium__/page-props\" && req.method === \"GET\") {\n const pathQuery = requestUrl.searchParams.get(\"path\") || \"/\";\n const targetUrl = new URL(pathQuery, \"http://localhost\");\n const targetPathname = targetUrl.pathname;\n const ssrMatch = matchSSRPage(targetPathname, ssrPages);\n\n if (!ssrMatch) {\n res.writeHead(200, { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\" });\n res.end(JSON.stringify({ ssr: false, props: null }));\n return;\n }\n\n const ip = extractClientIP(req, trustProxyDepth);\n const httpCtx: HeliumContext = {\n req: {\n ip,\n headers: req.headers,\n url: req.url,\n method: req.method,\n raw: req,\n },\n };\n\n try {\n const ssrResult = await resolveServerSideProps({\n req,\n pathname: targetPathname,\n params: ssrMatch.params,\n page: ssrMatch.page,\n ctx: httpCtx,\n });\n\n if (ssrResult.kind === \"redirect\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\" });\n res.end(JSON.stringify({ ssr: true, redirect: ssrResult.redirect }));\n return;\n }\n\n res.writeHead(200, { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\" });\n res.end(JSON.stringify({ ssr: true, props: ssrResult.props }));\n } catch (error) {\n log(\"error\", \"Failed to resolve SSR page props:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\" });\n res.end(JSON.stringify({ ssr: true, props: null, error: \"Internal server error\" }));\n }\n\n return;\n }\n\n if (req.url === \"/__helium__/refresh-token\") {\n // Security: only allow POST to prevent CSRF via <img>/<script> tags\n if (req.method !== \"POST\") {\n res.writeHead(405, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Method not allowed\" }));\n return;\n }\n // Security: require custom header to prevent cross-origin requests\n if (!req.headers[\"x-requested-with\"]) {\n res.writeHead(403, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Forbidden\" }));\n return;\n }\n const token = generateConnectionToken();\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ token }));\n return;\n }\n\n // Handle HTTP-based RPC endpoint (alternative to WebSocket for mobile networks)\n if (req.url === \"/__helium__/rpc\" && req.method === \"POST\") {\n // Security: verify connection token for HTTP RPC\n const authToken = req.headers[\"x-helium-token\"] as string | undefined;\n if (!authToken || !verifyConnectionToken(authToken)) {\n res.writeHead(401, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: false, error: \"Unauthorized\" }));\n return;\n }\n\n // Security: check Content-Length before reading body\n const contentLength = parseInt(req.headers[\"content-length\"] || \"0\", 10);\n if (contentLength > maxBodySize) {\n res.writeHead(413, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: false, error: \"Request entity too large\" }));\n return;\n }\n\n const chunks: Buffer[] = [];\n let totalSize = 0;\n let aborted = false;\n req.on(\"data\", (chunk: Buffer) => {\n totalSize += chunk.length;\n if (totalSize > maxBodySize) {\n aborted = true;\n req.destroy();\n res.writeHead(413, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: false, error: \"Request entity too large\" }));\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", async () => {\n if (aborted) {\n return;\n }\n try {\n const body = Buffer.concat(chunks);\n const ip = extractClientIP(req, trustProxyDepth);\n const result = await registry.handleHttpRequest(body, ip, req);\n\n const encoded = msgpackEncode(prepareForMsgpack(result.response));\n let responseBody = Buffer.from(encoded as Uint8Array);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/msgpack\",\n \"Cache-Control\": \"no-store\",\n };\n\n // Handle compression\n const acceptEncoding = req.headers[\"accept-encoding\"] as string;\n if (acceptEncoding && responseBody.length > 1024) {\n if (acceptEncoding.includes(\"br\")) {\n responseBody = await brotliCompressAsync(responseBody);\n headers[\"Content-Encoding\"] = \"br\";\n } else if (acceptEncoding.includes(\"gzip\")) {\n responseBody = await gzipAsync(responseBody);\n headers[\"Content-Encoding\"] = \"gzip\";\n } else if (acceptEncoding.includes(\"deflate\")) {\n responseBody = await deflateAsync(responseBody);\n headers[\"Content-Encoding\"] = \"deflate\";\n }\n }\n\n res.writeHead(200, headers);\n res.end(responseBody);\n } catch (error) {\n log(\"error\", \"HTTP RPC error:\", error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: false, error: \"Internal server error\" }));\n }\n });\n return;\n }\n\n // Try HTTP handlers first (webhooks, auth, etc.)\n const handled = await httpRouter.handleRequest(req, res);\n if (handled) {\n return;\n }\n\n // Serve static files\n const url = req.url || \"/\";\n\n // Block access to sensitive configuration and server files\n const blockedFiles = [\"helium.config.js\", \"helium.config.mjs\", \"helium.config.ts\", \"server.js\", \".env\", \".env.local\", \".env.production\"];\n\n const requestedFile = path.basename(url.split(\"?\")[0]);\n let filePath: string = path.join(staticDir, \"index.html\");\n let is404 = false;\n\n if (blockedFiles.some((blocked) => requestedFile === blocked || requestedFile.startsWith(\".env\"))) {\n // Serve index.html so the SPA router can render the 404 page\n filePath = path.join(staticDir, \"index.html\");\n is404 = true;\n } else {\n // Clean URL (remove query params and trailing slash)\n const cleanUrl = url.split(\"?\")[0].replace(/\\/$/, \"\") || \"/\";\n\n // Security: path traversal prevention — resolve and verify\n const resolvedStaticDir = path.resolve(staticDir);\n const candidatePath = path.resolve(staticDir, \".\" + cleanUrl);\n if (!candidatePath.startsWith(resolvedStaticDir + path.sep) && candidatePath !== resolvedStaticDir) {\n filePath = path.join(staticDir, \"index.html\");\n is404 = true;\n }\n\n // Try different file paths for SSG support\n if (!is404 && cleanUrl === \"/\") {\n // Try index.ssg.html first (if root page has SSG)\n const ssgIndexPath = path.join(staticDir, \"index.ssg.html\");\n if (fs.existsSync(ssgIndexPath)) {\n filePath = ssgIndexPath;\n } else {\n filePath = path.join(staticDir, \"index.html\");\n }\n } else if (!is404) {\n // If cleanUrl has no extension, prioritize .html files for SSG pages\n if (!path.extname(cleanUrl)) {\n const htmlPath = path.join(staticDir, cleanUrl + \".html\");\n if (fs.existsSync(htmlPath)) {\n filePath = htmlPath;\n } else {\n // Fall back to exact path (for assets or directories)\n filePath = path.join(staticDir, cleanUrl);\n }\n } else {\n // Has an extension, try exact path (for assets like /assets/main.js)\n filePath = path.join(staticDir, cleanUrl);\n }\n }\n\n // If file doesn't exist or is a directory, fall back to index.html for SPA routing\n const isFileOrExists = !is404 && filePath && fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n if (!isFileOrExists && !url.startsWith(\"/api\") && !url.startsWith(\"/webhooks\") && !url.startsWith(\"/auth\")) {\n // Fall back to index.html for SPA routing\n // Note: We don't set is404 here because the client-side router will determine\n // if the route exists. If it doesn't, the router will render the 404 page.\n filePath = path.join(staticDir, \"index.html\");\n // Don't set is404 = true here - let the client-side router handle it\n }\n }\n\n // Check if file exists (should always exist now since we fallback to index.html)\n if (!fs.existsSync(filePath)) {\n // This should rarely happen - only if index.html itself is missing\n res.writeHead(404, { \"Content-Type\": \"text/html\" });\n res.end(\"Not found\");\n return;\n }\n\n // Determine content type\n const ext = path.extname(filePath);\n const contentTypes: Record<string, string> = {\n \".html\": \"text/html\",\n \".js\": \"application/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".eot\": \"application/vnd.ms-fontobject\",\n };\n const contentType = contentTypes[ext] || \"application/octet-stream\";\n\n try {\n const content = fs.readFileSync(filePath);\n let responseBody = content;\n const cleanedPathname = (req.url || \"/\").split(\"?\")[0].replace(/\\/$/, \"\") || \"/\";\n const htmlSsrMatch = req.method === \"GET\" && contentType === \"text/html\" ? matchSSRPage(cleanedPathname, ssrPages) : null;\n\n if (!is404 && contentType === \"text/html\") {\n const ip = extractClientIP(req, trustProxyDepth);\n const httpCtx: HeliumContext = {\n req: {\n ip,\n headers: req.headers,\n url: req.url,\n method: req.method,\n raw: req,\n },\n };\n\n const metadata = await seoRouter.resolve(req, httpCtx);\n let html = content.toString(\"utf-8\");\n\n if (htmlSsrMatch) {\n try {\n const rendered = await renderSSRHTML({\n htmlTemplate: html,\n pathname: cleanedPathname,\n search: requestUrl.search,\n params: htmlSsrMatch.params,\n page: htmlSsrMatch.page,\n req,\n ctx: httpCtx,\n loadAppShell: appShell,\n });\n\n if (\"redirect\" in rendered) {\n res.writeHead(rendered.redirect.statusCode, {\n Location: rendered.redirect.destination,\n \"Cache-Control\": \"no-store\",\n });\n res.end();\n return;\n }\n\n html = rendered.html;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const isBrowserGlobalError = /\\bwindow is not defined\\b|\\bdocument is not defined\\b|\\bnavigator is not defined\\b/i.test(message);\n\n if (isBrowserGlobalError) {\n log(\n \"warn\",\n `SSR disabled for ${cleanedPathname} due to browser-only import. Render map/browser-only modules on client only (e.g. dynamic import inside useEffect).`\n );\n } else {\n log(\"error\", `Failed to render SSR page for ${cleanedPathname}:`, error);\n }\n }\n }\n\n if (metadata) {\n html = injectSocialMetaIntoHtml(html, metadata);\n }\n\n // Inject runtime public env vars (for platform deployments like Render, DO Apps)\n html = injectPublicEnvIntoHtml(html);\n\n responseBody = Buffer.from(html, \"utf-8\");\n }\n\n // Set status code to 404 if serving the 404 page\n const statusCode = is404 ? 404 : 200;\n res.writeHead(statusCode, { \"Content-Type\": contentType });\n res.end(responseBody);\n } catch (error) {\n log(\"error\", \"Error serving file:\", error);\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(\"Internal server error\");\n }\n });\n\n // Setup WebSocket server for RPC\n const wss = new WebSocketServer({\n noServer: true,\n maxPayload: rpcConfig.maxWsPayload,\n perMessageDeflate: compressionConfig.enabled\n ? {\n zlibDeflateOptions: {\n chunkSize: 1024,\n memLevel: 7,\n level: 9, // 6 is default compression level (balanced)\n },\n zlibInflateOptions: {\n chunkSize: 10 * 1024,\n },\n threshold: compressionConfig.threshold,\n }\n : false,\n });\n\n wss.on(\"connection\", (socket: WebSocket, req: http.IncomingMessage) => {\n // Extract client IP with proxy configuration\n const ip = extractClientIP(req, trustProxyDepth);\n\n // Store connection metadata for RPC context\n registry.setSocketMetadata(socket, ip, req);\n\n // Track connection and check IP limit\n if (!rateLimiter.trackConnection(socket, ip)) {\n socket.close(1008, \"Too many connections from your IP\");\n return;\n }\n\n // Prevent unhandled errors from crashing the process (e.g. maxPayload exceeded)\n socket.on(\"error\", (err) => {\n log(\"warn\", \"WebSocket error:\", err);\n if (socket.readyState === socket.OPEN || socket.readyState === socket.CLOSING) {\n socket.close(1009, \"Message too large\");\n }\n });\n\n socket.on(\"message\", (msg: WebSocket.RawData, _isBinary: boolean) => {\n // Check rate limit\n if (!rateLimiter.checkRateLimit(socket)) {\n // Parse request to get the ID for proper error response\n try {\n let req: any;\n // Always expect MessagePack\n const buffer = Buffer.isBuffer(msg) ? msg : Buffer.from(msg as any);\n const { decode: msgpackDecode } = require(\"@msgpack/msgpack\");\n req = msgpackDecode(buffer);\n\n const stats = rateLimiter.getConnectionStats(socket);\n const now = Date.now();\n const resetInSeconds = stats ? Math.ceil((stats.resetTimeMs - now) / 1000) : 0;\n\n const createError = (id: string) => ({\n id,\n ok: false,\n stats: {\n remainingRequests: stats ? stats.remainingMessages : 0,\n resetInSeconds,\n },\n error: \"Rate limit exceeded\",\n });\n\n let errorResponse: any;\n if (Array.isArray(req)) {\n errorResponse = req.map((r: any) => createError(r.id));\n } else {\n errorResponse = createError(req.id);\n }\n\n log(\"warn\", `Rate limit exceeded for IP ${ip}, resets in ${resetInSeconds} seconds`);\n socket.send(msgpackEncode(errorResponse) as Buffer);\n } catch {\n // If we can't parse the request, just close the connection\n socket.close();\n }\n return;\n }\n\n registry.handleMessage(socket, Buffer.isBuffer(msg) ? msg : Buffer.from(msg as any));\n });\n });\n\n // Handle WebSocket upgrade requests\n server.on(\"upgrade\", (req, socket, head) => {\n if (req.url?.startsWith(\"/rpc\")) {\n // Security: read token from Sec-WebSocket-Protocol header instead of query string\n const protocols = req.headers[\"sec-websocket-protocol\"];\n const token =\n typeof protocols === \"string\"\n ? protocols\n .split(\",\")\n .map((p) => p.trim())\n .find((p) => p.includes(\".\"))\n : undefined;\n\n if (!token || !verifyConnectionToken(token)) {\n log(\"warn\", \"WebSocket connection rejected - invalid token\");\n socket.write(\"HTTP/1.1 401 Unauthorized\\r\\n\\r\\n\");\n socket.destroy();\n return;\n }\n\n // Check IP connection limit before upgrading\n const ip = extractClientIP(req, trustProxyDepth);\n if (rpcSecurity.maxConnectionsPerIP > 0) {\n const currentConnections = rateLimiter.getIPConnectionCount(ip);\n if (currentConnections >= rpcSecurity.maxConnectionsPerIP) {\n log(\"warn\", `WebSocket connection rejected - IP ${ip} has ${currentConnections} connections`);\n socket.write(\"HTTP/1.1 429 Too Many Requests\\r\\n\\r\\n\");\n socket.destroy();\n return;\n }\n }\n\n wss.handleUpgrade(req, socket, head, (ws) => {\n wss.emit(\"connection\", ws, req);\n });\n } else {\n socket.destroy();\n }\n });\n\n // Start server\n server.listen(port, () => {\n log(\"info\", `Production server listening on http://localhost:${port}`);\n log(\"info\", `Serving static files from ${staticDir}`);\n log(\"info\", `WebSocket RPC available at ws://localhost:${port}/rpc`);\n\n // Start workers\n if (workers.length > 0) {\n log(\"info\", `Starting ${workers.length} worker(s)...`);\n for (const { name, worker } of workers) {\n // Use export name if worker name is anonymous\n if (worker.name === \"anonymous\") {\n worker.name = name;\n worker.__id = name;\n worker.options.name = name;\n }\n if (worker.options.autoStart) {\n const createContext = (): HeliumContext => ({\n req: {\n ip: \"127.0.0.1\",\n headers: {},\n url: undefined,\n method: undefined,\n raw: {} as http.IncomingMessage,\n },\n });\n startWorker(worker, createContext).catch((err) => {\n log(\"error\", `Failed to start worker '${worker.name}':`, err);\n });\n }\n }\n }\n });\n\n // Handle graceful shutdown\n const shutdown = async () => {\n log(\"info\", \"Shutting down...\");\n await stopAllWorkers();\n server.close(() => {\n log(\"info\", \"Server closed\");\n process.exit(0);\n });\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n return server;\n}\n\n// ============================================================================\n// Security helper functions\n// ============================================================================\n\n/**\n * Set default security headers on every HTTP response.\n */\nfunction setSecurityHeaders(res: http.ServerResponse, config: HeliumConfig): void {\n const headers = getSecurityHeaders(config);\n\n for (const [name, value] of Object.entries(headers)) {\n if (value === null) {\n res.removeHeader(name);\n continue;\n }\n res.setHeader(name, value);\n }\n}\n\n/**\n * Resolve security headers for the current request from config.\n * Returns a final header map where `null` indicates the header should be removed.\n *\n * @internal\n */\nexport function getSecurityHeaders(config: HeliumConfig): Record<string, string | null> {\n const headers: Record<string, string | null> = {};\n const securityConfig = config.security;\n\n if (securityConfig?.defaultHeaders !== false) {\n headers[\"X-Content-Type-Options\"] = \"nosniff\";\n headers[\"X-Frame-Options\"] = \"DENY\";\n headers[\"X-XSS-Protection\"] = \"0\";\n headers[\"Referrer-Policy\"] = \"strict-origin-when-cross-origin\";\n headers[\"Permissions-Policy\"] = \"camera=(), microphone=(), geolocation=()\";\n\n const csp = securityConfig?.contentSecurityPolicy;\n if (csp) {\n headers[\"Content-Security-Policy\"] = csp;\n }\n\n if (securityConfig?.hsts !== false) {\n headers[\"Strict-Transport-Security\"] = \"max-age=31536000; includeSubDomains\";\n }\n }\n\n if (securityConfig?.headerOverrides) {\n for (const [name, value] of Object.entries(securityConfig.headerOverrides)) {\n headers[name] = value;\n }\n }\n\n return headers;\n}\n\n/**\n * Handle CORS headers based on configuration.\n * Default: restrict to same-origin (no CORS header = browser blocks cross-origin).\n */\nfunction handleCorsHeaders(req: http.IncomingMessage, res: http.ServerResponse, config: HeliumConfig): void {\n const allowedOrigins = config.security?.corsOrigins;\n if (!allowedOrigins || allowedOrigins.length === 0) {\n // No CORS configured — same-origin only by default\n return;\n }\n\n const origin = req.headers.origin;\n if (!origin) {\n return;\n }\n\n const isAllowed = allowedOrigins.includes(\"*\") || allowedOrigins.includes(origin);\n if (isAllowed) {\n res.setHeader(\"Access-Control-Allow-Origin\", allowedOrigins.includes(\"*\") ? \"*\" : origin);\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type, X-Requested-With, X-Helium-Token\");\n res.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\n if (!allowedOrigins.includes(\"*\")) {\n res.setHeader(\"Vary\", \"Origin\");\n }\n }\n}\n"]}
|
|
@@ -2,6 +2,12 @@ export interface EnvLoadOptions {
|
|
|
2
2
|
root?: string;
|
|
3
3
|
mode?: string;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* Collects HELIUM_PUBLIC_ prefixed variables from process.env.
|
|
7
|
+
* Used as a fallback for platform environments (Render, DigitalOcean Apps, etc.)
|
|
8
|
+
* where env vars are set as platform variables rather than .env files.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getPublicEnvFromProcess(prefix?: string): Record<string, string>;
|
|
5
11
|
/**
|
|
6
12
|
* Loads environment variables from .env files with priority.
|
|
7
13
|
* Similar to Next.js, supports:
|
|
@@ -9,6 +15,12 @@ export interface EnvLoadOptions {
|
|
|
9
15
|
* - .env.local (not loaded in test mode)
|
|
10
16
|
* - .env.{mode}
|
|
11
17
|
* - .env
|
|
18
|
+
* - process.env HELIUM_PUBLIC_* variables (lowest priority fallback)
|
|
19
|
+
*
|
|
20
|
+
* Platform environment variables (process.env) are used as the base layer,
|
|
21
|
+
* so .env file values always take precedence. This ensures compatibility
|
|
22
|
+
* with platforms like Render, DigitalOcean Apps, and Railway where env vars
|
|
23
|
+
* are set as platform variables rather than .env files.
|
|
12
24
|
*/
|
|
13
25
|
export declare function loadEnvFiles(options?: EnvLoadOptions): Record<string, string>;
|
|
14
26
|
/**
|
|
@@ -24,4 +36,19 @@ export declare function filterClientEnv(env: Record<string, string>, prefix?: st
|
|
|
24
36
|
* Creates Vite define config for injecting env variables into the client bundle.
|
|
25
37
|
*/
|
|
26
38
|
export declare function createEnvDefines(env: Record<string, string>, prefix?: string): Record<string, string>;
|
|
39
|
+
/**
|
|
40
|
+
* Generates an inline <script> tag that injects HELIUM_PUBLIC_ env vars
|
|
41
|
+
* into import.meta.env at runtime. This is used by the production server
|
|
42
|
+
* to ensure platform environment variables are available even if they
|
|
43
|
+
* weren't present at build time.
|
|
44
|
+
*
|
|
45
|
+
* The script is injected before module scripts in <head>, so the values
|
|
46
|
+
* are available when application code runs.
|
|
47
|
+
*/
|
|
48
|
+
export declare function buildPublicEnvScript(prefix?: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Injects the public env script into an HTML string, placing it
|
|
51
|
+
* at the beginning of <head> so it runs before any module scripts.
|
|
52
|
+
*/
|
|
53
|
+
export declare function injectPublicEnvIntoHtml(html: string, prefix?: string): string;
|
|
27
54
|
//# sourceMappingURL=envLoader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envLoader.d.ts","sourceRoot":"","sources":["../../src/utils/envLoader.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED
|
|
1
|
+
{"version":3,"file":"envLoader.d.ts","sourceRoot":"","sources":["../../src/utils/envLoader.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,GAAE,MAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUjG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,cAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA0BjF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAOpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAE,MAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUtH;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAE,MAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASvH;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,GAAE,MAAyB,GAAG,MAAM,CAS9E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAyB,GAAG,MAAM,CAe/F"}
|
package/dist/utils/envLoader.js
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import dotenv from "dotenv";
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
+
/**
|
|
5
|
+
* Collects HELIUM_PUBLIC_ prefixed variables from process.env.
|
|
6
|
+
* Used as a fallback for platform environments (Render, DigitalOcean Apps, etc.)
|
|
7
|
+
* where env vars are set as platform variables rather than .env files.
|
|
8
|
+
*/
|
|
9
|
+
export function getPublicEnvFromProcess(prefix = "HELIUM_PUBLIC_") {
|
|
10
|
+
const publicEnv = {};
|
|
11
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
12
|
+
if (key.startsWith(prefix) && value !== undefined) {
|
|
13
|
+
publicEnv[key] = value;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return publicEnv;
|
|
17
|
+
}
|
|
4
18
|
/**
|
|
5
19
|
* Loads environment variables from .env files with priority.
|
|
6
20
|
* Similar to Next.js, supports:
|
|
@@ -8,6 +22,12 @@ import path from "path";
|
|
|
8
22
|
* - .env.local (not loaded in test mode)
|
|
9
23
|
* - .env.{mode}
|
|
10
24
|
* - .env
|
|
25
|
+
* - process.env HELIUM_PUBLIC_* variables (lowest priority fallback)
|
|
26
|
+
*
|
|
27
|
+
* Platform environment variables (process.env) are used as the base layer,
|
|
28
|
+
* so .env file values always take precedence. This ensures compatibility
|
|
29
|
+
* with platforms like Render, DigitalOcean Apps, and Railway where env vars
|
|
30
|
+
* are set as platform variables rather than .env files.
|
|
11
31
|
*/
|
|
12
32
|
export function loadEnvFiles(options = {}) {
|
|
13
33
|
const { root = process.cwd(), mode = process.env.NODE_ENV || "development" } = options;
|
|
@@ -18,7 +38,8 @@ export function loadEnvFiles(options = {}) {
|
|
|
18
38
|
`.env.${mode}`,
|
|
19
39
|
`.env`,
|
|
20
40
|
].filter(Boolean);
|
|
21
|
-
|
|
41
|
+
// Start with platform env vars as the lowest-priority base layer
|
|
42
|
+
const loadedEnv = getPublicEnvFromProcess();
|
|
22
43
|
// Load in reverse order so earlier files override later ones
|
|
23
44
|
for (let i = envFiles.length - 1; i >= 0; i--) {
|
|
24
45
|
const envFile = envFiles[i];
|
|
@@ -65,4 +86,38 @@ export function createEnvDefines(env, prefix = "HELIUM_PUBLIC_") {
|
|
|
65
86
|
}
|
|
66
87
|
return defines;
|
|
67
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Generates an inline <script> tag that injects HELIUM_PUBLIC_ env vars
|
|
91
|
+
* into import.meta.env at runtime. This is used by the production server
|
|
92
|
+
* to ensure platform environment variables are available even if they
|
|
93
|
+
* weren't present at build time.
|
|
94
|
+
*
|
|
95
|
+
* The script is injected before module scripts in <head>, so the values
|
|
96
|
+
* are available when application code runs.
|
|
97
|
+
*/
|
|
98
|
+
export function buildPublicEnvScript(prefix = "HELIUM_PUBLIC_") {
|
|
99
|
+
const publicEnv = getPublicEnvFromProcess(prefix);
|
|
100
|
+
if (Object.keys(publicEnv).length === 0) {
|
|
101
|
+
return "";
|
|
102
|
+
}
|
|
103
|
+
const envJson = JSON.stringify(publicEnv);
|
|
104
|
+
return `<script>window.__HELIUM_PUBLIC_ENV__=${envJson}</script>`;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Injects the public env script into an HTML string, placing it
|
|
108
|
+
* at the beginning of <head> so it runs before any module scripts.
|
|
109
|
+
*/
|
|
110
|
+
export function injectPublicEnvIntoHtml(html, prefix = "HELIUM_PUBLIC_") {
|
|
111
|
+
const script = buildPublicEnvScript(prefix);
|
|
112
|
+
if (!script) {
|
|
113
|
+
return html;
|
|
114
|
+
}
|
|
115
|
+
// Inject at the start of <head> so it runs before module scripts
|
|
116
|
+
const headMatch = html.match(/<head[^>]*>/i);
|
|
117
|
+
if (headMatch) {
|
|
118
|
+
return html.replace(headMatch[0], `${headMatch[0]}\n${script}`);
|
|
119
|
+
}
|
|
120
|
+
// Fallback: prepend to HTML
|
|
121
|
+
return `${script}\n${html}`;
|
|
122
|
+
}
|
|
68
123
|
//# sourceMappingURL=envLoader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envLoader.js","sourceRoot":"","sources":["../../src/utils/envLoader.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAOxB
|
|
1
|
+
{"version":3,"file":"envLoader.js","sourceRoot":"","sources":["../../src/utils/envLoader.ts"],"names":[],"mappings":"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","sourcesContent":["import dotenv from \"dotenv\";\nimport fs from \"fs\";\nimport path from \"path\";\n\nexport interface EnvLoadOptions {\n root?: string;\n mode?: string;\n}\n\n/**\n * Collects HELIUM_PUBLIC_ prefixed variables from process.env.\n * Used as a fallback for platform environments (Render, DigitalOcean Apps, etc.)\n * where env vars are set as platform variables rather than .env files.\n */\nexport function getPublicEnvFromProcess(prefix: string = \"HELIUM_PUBLIC_\"): Record<string, string> {\n const publicEnv: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(process.env)) {\n if (key.startsWith(prefix) && value !== undefined) {\n publicEnv[key] = value;\n }\n }\n\n return publicEnv;\n}\n\n/**\n * Loads environment variables from .env files with priority.\n * Similar to Next.js, supports:\n * - .env.{mode}.local (highest priority)\n * - .env.local (not loaded in test mode)\n * - .env.{mode}\n * - .env\n * - process.env HELIUM_PUBLIC_* variables (lowest priority fallback)\n *\n * Platform environment variables (process.env) are used as the base layer,\n * so .env file values always take precedence. This ensures compatibility\n * with platforms like Render, DigitalOcean Apps, and Railway where env vars\n * are set as platform variables rather than .env files.\n */\nexport function loadEnvFiles(options: EnvLoadOptions = {}): Record<string, string> {\n const { root = process.cwd(), mode = process.env.NODE_ENV || \"development\" } = options;\n\n const envFiles = [\n `.env.${mode}.local`,\n // Don't load .env.local in test mode\n mode !== \"test\" ? `.env.local` : null,\n `.env.${mode}`,\n `.env`,\n ].filter(Boolean) as string[];\n\n // Start with platform env vars as the lowest-priority base layer\n const loadedEnv: Record<string, string> = getPublicEnvFromProcess();\n\n // Load in reverse order so earlier files override later ones\n for (let i = envFiles.length - 1; i >= 0; i--) {\n const envFile = envFiles[i];\n const envPath = path.resolve(root, envFile);\n\n if (fs.existsSync(envPath)) {\n const parsed = dotenv.parse(fs.readFileSync(envPath, \"utf-8\"));\n Object.assign(loadedEnv, parsed);\n }\n }\n\n return loadedEnv;\n}\n\n/**\n * Injects env variables into process.env\n */\nexport function injectEnvToProcess(env: Record<string, string>): void {\n for (const [key, value] of Object.entries(env)) {\n // Don't override existing process.env values\n if (process.env[key] === undefined) {\n process.env[key] = value;\n }\n }\n}\n\n/**\n * Filters env variables that should be exposed to the client.\n * By default, only HELIUM_PUBLIC_ prefixed variables are exposed.\n */\nexport function filterClientEnv(env: Record<string, string>, prefix: string = \"HELIUM_PUBLIC_\"): Record<string, string> {\n const clientEnv: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(env)) {\n if (key.startsWith(prefix)) {\n clientEnv[key] = value;\n }\n }\n\n return clientEnv;\n}\n\n/**\n * Creates Vite define config for injecting env variables into the client bundle.\n */\nexport function createEnvDefines(env: Record<string, string>, prefix: string = \"HELIUM_PUBLIC_\"): Record<string, string> {\n const defines: Record<string, string> = {};\n const clientEnv = filterClientEnv(env, prefix);\n\n for (const [key, value] of Object.entries(clientEnv)) {\n defines[`import.meta.env.${key}`] = JSON.stringify(value);\n }\n\n return defines;\n}\n\n/**\n * Generates an inline <script> tag that injects HELIUM_PUBLIC_ env vars\n * into import.meta.env at runtime. This is used by the production server\n * to ensure platform environment variables are available even if they\n * weren't present at build time.\n *\n * The script is injected before module scripts in <head>, so the values\n * are available when application code runs.\n */\nexport function buildPublicEnvScript(prefix: string = \"HELIUM_PUBLIC_\"): string {\n const publicEnv = getPublicEnvFromProcess(prefix);\n\n if (Object.keys(publicEnv).length === 0) {\n return \"\";\n }\n\n const envJson = JSON.stringify(publicEnv);\n return `<script>window.__HELIUM_PUBLIC_ENV__=${envJson}</script>`;\n}\n\n/**\n * Injects the public env script into an HTML string, placing it\n * at the beginning of <head> so it runs before any module scripts.\n */\nexport function injectPublicEnvIntoHtml(html: string, prefix: string = \"HELIUM_PUBLIC_\"): string {\n const script = buildPublicEnvScript(prefix);\n\n if (!script) {\n return html;\n }\n\n // Inject at the start of <head> so it runs before module scripts\n const headMatch = html.match(/<head[^>]*>/i);\n if (headMatch) {\n return html.replace(headMatch[0], `${headMatch[0]}\\n${script}`);\n }\n\n // Fallback: prepend to HTML\n return `${script}\\n${html}`;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heliumPlugin.d.ts","sourceRoot":"","sources":["../../src/vite/heliumPlugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAkBnC,MAAM,CAAC,OAAO,UAAU,MAAM,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"heliumPlugin.d.ts","sourceRoot":"","sources":["../../src/vite/heliumPlugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAkBnC,MAAM,CAAC,OAAO,UAAU,MAAM,IAAI,MAAM,CAievC;AAmHD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAiBrG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAUhD"}
|
|
@@ -21,10 +21,6 @@ export default function helium() {
|
|
|
21
21
|
enforce: "pre",
|
|
22
22
|
configResolved(config) {
|
|
23
23
|
root = config.root;
|
|
24
|
-
// Load and inject environment variables
|
|
25
|
-
const mode = config.mode || "development";
|
|
26
|
-
const envVars = loadEnvFiles({ root, mode });
|
|
27
|
-
injectEnvToProcess(envVars);
|
|
28
24
|
},
|
|
29
25
|
transformIndexHtml: {
|
|
30
26
|
order: "pre",
|
|
@@ -62,14 +58,26 @@ export default function helium() {
|
|
|
62
58
|
// Load environment variables before config is finalized
|
|
63
59
|
const mode = config.mode || "development";
|
|
64
60
|
const envVars = loadEnvFiles({ root, mode });
|
|
61
|
+
// Inject env vars into process.env BEFORE Vite's own env resolution.
|
|
62
|
+
// This ensures platform-set env vars (Render, DigitalOcean Apps, etc.)
|
|
63
|
+
// are picked up by Vite's envPrefix matching and included in all
|
|
64
|
+
// import.meta.env object references throughout the bundle.
|
|
65
|
+
injectEnvToProcess(envVars);
|
|
65
66
|
// Create defines for client-side env variables
|
|
66
67
|
const envDefines = createEnvDefines(envVars);
|
|
67
68
|
// Load helium config to get client-side RPC transport settings
|
|
68
69
|
const heliumConfig = await loadConfig(root);
|
|
69
70
|
const rpcClientConfig = getRpcClientConfig(heliumConfig);
|
|
71
|
+
// Merge user-configured envPrefix with HELIUM_PUBLIC_
|
|
72
|
+
const userPrefix = config.envPrefix ?? "VITE_";
|
|
73
|
+
const prefixArray = Array.isArray(userPrefix) ? userPrefix : [userPrefix];
|
|
74
|
+
if (!prefixArray.includes("HELIUM_PUBLIC_")) {
|
|
75
|
+
prefixArray.push("HELIUM_PUBLIC_");
|
|
76
|
+
}
|
|
70
77
|
// Provide default index.html if none exists
|
|
71
78
|
return {
|
|
72
79
|
appType: "spa",
|
|
80
|
+
envPrefix: prefixArray,
|
|
73
81
|
optimizeDeps: {
|
|
74
82
|
include: ["react-dom/client"],
|
|
75
83
|
// Exclude helium from pre-bundling since it's the framework itself
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heliumPlugin.js","sourceRoot":"","sources":["../../src/vite/heliumPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport type { Plugin } from \"vite\";\n\nimport { clearConfigCache, getRpcClientConfig, loadConfig } from \"../server/config.js\";\nimport { attachToDevServer } from \"../server/devServer.js\";\nimport { createEnvDefines, injectEnvToProcess, loadEnvFiles } from \"../utils/envLoader.js\";\nimport { log } from \"../utils/logger.js\";\nimport {\n RESOLVED_VIRTUAL_CLIENT_MODULE_ID,\n RESOLVED_VIRTUAL_ENTRY_MODULE_ID,\n RESOLVED_VIRTUAL_SERVER_MANIFEST_ID,\n SERVER_DIR,\n VIRTUAL_CLIENT_MODULE_ID,\n VIRTUAL_ENTRY_MODULE_ID,\n VIRTUAL_SERVER_MANIFEST_ID,\n} from \"./paths.js\";\nimport { checkRouteCollisions, scanAppShell, scanPageRoutePatterns, scanServerExports, scanSSRPages } from \"./scanner.js\";\nimport { generateClientModule, generateEntryModule, generateServerManifest, generateTypeDefinitions } from \"./virtualServerModule.js\";\n\nexport default function helium(): Plugin {\n let root = process.cwd();\n const serverDir = normalizeToPosix(SERVER_DIR);\n const VIRTUAL_SSR_CLIENT_MODULE_ID = \"heliumts/__ssr_client\";\n const RESOLVED_VIRTUAL_SSR_CLIENT_MODULE_ID = \"\\0heliumts:ssr-client\";\n const VIRTUAL_SSR_TRANSITIONS_MODULE_ID = \"heliumts/__ssr_transitions\";\n const RESOLVED_VIRTUAL_SSR_TRANSITIONS_MODULE_ID = \"\\0heliumts:ssr-transitions\";\n const VIRTUAL_SSR_PREFETCH_MODULE_ID = \"heliumts/__ssr_prefetch\";\n const RESOLVED_VIRTUAL_SSR_PREFETCH_MODULE_ID = \"\\0heliumts:ssr-prefetch\";\n\n return {\n name: \"vite-plugin-helium\",\n enforce: \"pre\",\n configResolved(config) {\n root = config.root;\n\n // Load and inject environment variables\n const mode = config.mode || \"development\";\n const envVars = loadEnvFiles({ root, mode });\n injectEnvToProcess(envVars);\n },\n transformIndexHtml: {\n order: \"pre\",\n handler(html, _ctx) {\n // Check if HTML already has a script tag for entry\n if (html.includes(\"src/main.tsx\") || html.includes(\"src/main.ts\")) {\n return html; // User has their own entry, don't modify\n }\n\n // Ensure root div exists\n let modifiedHtml = html;\n if (!modifiedHtml.includes('id=\"root\"')) {\n modifiedHtml = modifiedHtml.replace(\"<body>\", '<body>\\n <div id=\"root\"></div>');\n }\n\n // Generate physical entry file\n const heliumDir = path.join(root, \"node_modules\", \".heliumts\");\n if (!fs.existsSync(heliumDir)) {\n fs.mkdirSync(heliumDir, { recursive: true });\n }\n const entryPath = path.join(heliumDir, \"entry.tsx\");\n fs.writeFileSync(entryPath, generateEntryModule());\n\n // Return with tags to inject the entry (runtime config is fetched by the client)\n return [\n {\n tag: \"script\",\n attrs: {\n type: \"module\",\n src: \"/node_modules/.heliumts/entry.tsx\",\n },\n injectTo: \"body\",\n },\n ];\n },\n },\n async config(config) {\n // Load environment variables before config is finalized\n const mode = config.mode || \"development\";\n const envVars = loadEnvFiles({ root, mode });\n\n // Create defines for client-side env variables\n const envDefines = createEnvDefines(envVars);\n\n // Load helium config to get client-side RPC transport settings\n const heliumConfig = await loadConfig(root);\n const rpcClientConfig = getRpcClientConfig(heliumConfig);\n\n // Provide default index.html if none exists\n return {\n appType: \"spa\",\n optimizeDeps: {\n include: [\"react-dom/client\"],\n // Exclude helium from pre-bundling since it's the framework itself\n // This ensures changes to helium are picked up immediately\n exclude: [\"heliumts\", \"heliumts/client\", \"heliumts/server\", \"heliumts/vite\"],\n },\n // SSR configuration to properly isolate server-only code\n ssr: {\n // Externalize Node.js built-in modules - these should never be bundled\n external: [\"util\", \"zlib\", \"http\", \"https\", \"http2\", \"fs\", \"path\", \"crypto\", \"stream\", \"os\", \"url\", \"net\", \"tls\", \"child_process\", \"worker_threads\"],\n // Don't externalize heliumts - let the plugin handle the client/server split\n noExternal: [\"heliumts\"],\n },\n // Ensure Node.js built-ins are not bundled for client\n build: {\n rollupOptions: {\n external: [\n // Node.js built-in modules should never be in client bundle\n /^node:/,\n \"util\",\n \"zlib\",\n \"http\",\n \"https\",\n \"http2\",\n \"fs\",\n \"path\",\n \"crypto\",\n \"stream\",\n \"os\",\n \"url\",\n \"net\",\n \"tls\",\n \"child_process\",\n \"worker_threads\",\n ],\n },\n },\n define: {\n ...envDefines,\n __HELIUM_DEV__: JSON.stringify(mode !== \"production\"),\n __HELIUM_RPC_TRANSPORT__: JSON.stringify(rpcClientConfig.transport),\n __HELIUM_RPC_AUTO_HTTP_ON_MOBILE__: JSON.stringify(rpcClientConfig.autoHttpOnMobile),\n __HELIUM_RPC_TOKEN_VALIDITY_MS__: JSON.stringify(rpcClientConfig.tokenValidityMs),\n },\n };\n },\n resolveId(id, importer, options) {\n if (options?.ssr && id === \"heliumts/client\") {\n return RESOLVED_VIRTUAL_SSR_CLIENT_MODULE_ID;\n }\n if (options?.ssr && id === \"heliumts/client/transitions\") {\n return RESOLVED_VIRTUAL_SSR_TRANSITIONS_MODULE_ID;\n }\n if (options?.ssr && id === \"heliumts/client/prefetch\") {\n return RESOLVED_VIRTUAL_SSR_PREFETCH_MODULE_ID;\n }\n if (id === VIRTUAL_CLIENT_MODULE_ID) {\n if (isServerModule(importer, root, serverDir)) {\n return null;\n }\n return RESOLVED_VIRTUAL_CLIENT_MODULE_ID;\n }\n if (id === VIRTUAL_SERVER_MANIFEST_ID) {\n return RESOLVED_VIRTUAL_SERVER_MANIFEST_ID;\n }\n if (id === VIRTUAL_ENTRY_MODULE_ID) {\n // Add .tsx extension so Vite knows it contains JSX\n return RESOLVED_VIRTUAL_ENTRY_MODULE_ID + \".tsx\";\n }\n // Intercept heliumts/server imports from client code\n if (id === \"heliumts/server\") {\n // If imported from server code, let it resolve normally\n if (isServerModule(importer, root, serverDir)) {\n return null;\n }\n // For client code, redirect to virtual client module\n return RESOLVED_VIRTUAL_CLIENT_MODULE_ID;\n }\n return null;\n },\n transform(code, id, options) {\n // Prevent .server.ts/.server.js sidecar files from being bundled in client code.\n // These files contain server-only logic (e.g. DB queries) and must never run in the browser.\n if (!options?.ssr && /\\.server\\.(ts|js|tsx|jsx|mts|mjs)$/.test(id)) {\n return { code: \"export default null;\", map: null };\n }\n },\n load(id) {\n if (id === RESOLVED_VIRTUAL_SSR_CLIENT_MODULE_ID) {\n return generateSSRClientStubModule();\n }\n if (id === RESOLVED_VIRTUAL_SSR_TRANSITIONS_MODULE_ID) {\n return generateSSRTransitionsStubModule();\n }\n if (id === RESOLVED_VIRTUAL_SSR_PREFETCH_MODULE_ID) {\n return generateSSRPrefetchStubModule();\n }\n if (id === RESOLVED_VIRTUAL_CLIENT_MODULE_ID) {\n const { methods } = scanServerExports(root);\n return generateClientModule(methods);\n }\n if (id === RESOLVED_VIRTUAL_SERVER_MANIFEST_ID) {\n const { methods, httpHandlers, seoMetadata, middleware, workers } = scanServerExports(root);\n const pageRoutePatterns = scanPageRoutePatterns(root);\n const ssrPages = scanSSRPages(root);\n const appShell = scanAppShell(root);\n return generateServerManifest(methods, httpHandlers, seoMetadata, pageRoutePatterns, ssrPages, appShell, middleware, workers);\n }\n if (id === RESOLVED_VIRTUAL_ENTRY_MODULE_ID + \".tsx\") {\n return generateEntryModule();\n }\n },\n buildStart() {\n const { methods } = scanServerExports(root);\n const dts = generateTypeDefinitions(methods, root);\n const typesDir = path.join(root, \"src\", \"types\");\n const dtsPath = path.join(typesDir, \"heliumts-server.d.ts\");\n\n // Ensure src/types exists\n if (!fs.existsSync(typesDir)) {\n fs.mkdirSync(typesDir, { recursive: true });\n }\n\n // At build start we always allow writing the canonical set.\n // Only skip if content is identical to avoid needless TS invalidation.\n if (!fs.existsSync(dtsPath) || fs.readFileSync(dtsPath, \"utf-8\") !== dts) {\n fs.writeFileSync(dtsPath, dts);\n touchTsConfig(root);\n }\n\n // Check for route collisions in pages directory\n checkRouteCollisions(root);\n },\n configureServer(server) {\n // Add middleware to handle HTML fallback for nested routes\n // This ensures that routes like /docs/guides/auth properly serve index.html\n // so the client-side router can handle them\n server.middlewares.use((req, res, next) => {\n const url = req.url || \"\";\n const cleanUrl = url.split(\"?\")[0];\n\n // Skip if:\n // - Has file extension (asset request)\n // - Is an API/special endpoint\n // - Is a dev server endpoint\n if (\n path.extname(cleanUrl) !== \"\" ||\n cleanUrl.startsWith(\"/api\") ||\n cleanUrl.startsWith(\"/webhooks\") ||\n cleanUrl.startsWith(\"/auth\") ||\n cleanUrl.startsWith(\"/@\") ||\n cleanUrl.startsWith(\"/__helium__\")\n ) {\n return next();\n }\n\n // For all other routes (including nested paths like /docs/guides/auth),\n // rewrite to index.html so Vite serves it and the client-side router handles routing\n req.url = \"/index.html\";\n next();\n });\n\n /**\n * Write type definitions only if content has changed.\n * This prevents unnecessary TypeScript recompilation.\n *\n * When `allowFewer` is false (default) the file will NOT be\n * overwritten if the new content has fewer method declarations\n * than the existing file — this guards against writing a\n * degraded .d.ts while the user's file is only partially saved.\n */\n const writeTypesIfChanged = (dts: string, allowFewer = false): boolean => {\n const typesDir = path.join(root, \"src\", \"types\");\n const dtsPath = path.join(typesDir, \"heliumts-server.d.ts\");\n\n if (!fs.existsSync(typesDir)) {\n fs.mkdirSync(typesDir, { recursive: true });\n }\n\n // Check if file exists and content is the same\n if (fs.existsSync(dtsPath)) {\n const existing = fs.readFileSync(dtsPath, \"utf-8\");\n if (existing === dts) {\n return false; // No change needed\n }\n\n // Guard: don't overwrite with fewer methods unless explicitly allowed\n // (e.g. on unlink). This prevents losing types during partial saves.\n if (!allowFewer) {\n const countExports = (s: string) => (s.match(/export const \\w+:/g) || []).length;\n const existingCount = countExports(existing);\n const newCount = countExports(dts);\n if (newCount < existingCount) {\n log(\"info\", `Skipping type generation: found ${newCount} methods, existing has ${existingCount} (likely partial save)`);\n return false;\n }\n }\n }\n\n fs.writeFileSync(dtsPath, dts);\n\n // Touch tsconfig.json to force the TypeScript language server\n // to reload the project. Without this, TS may cache stale\n // module augmentations and autocomplete won't reflect the\n // new methods until a manual restart.\n touchTsConfig(root);\n\n return true; // File was written\n };\n\n const regenerateTypes = (allowFewer = false): boolean => {\n try {\n const { methods } = scanServerExports(root);\n const dts = generateTypeDefinitions(methods, root);\n return writeTypesIfChanged(dts, allowFewer);\n } catch (e) {\n log(\"error\", \"Failed to regenerate types\", e);\n return false;\n }\n };\n\n // Debounce timer for file changes\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n const DEBOUNCE_DELAY = 300; // ms — long enough for format-on-save to finish\n\n const handleServerFileChange = async (allowFewer = false) => {\n // Regenerate type definitions\n regenerateTypes(allowFewer);\n\n // Invalidate the virtual modules so they get regenerated\n const clientModule = server.environments.client?.moduleGraph.getModuleById(RESOLVED_VIRTUAL_CLIENT_MODULE_ID);\n const serverModule = server.environments.ssr?.moduleGraph.getModuleById(RESOLVED_VIRTUAL_SERVER_MANIFEST_ID);\n\n if (clientModule) {\n server.environments.client?.moduleGraph.invalidateModule(clientModule);\n }\n if (serverModule) {\n server.environments.ssr?.moduleGraph.invalidateModule(serverModule);\n }\n\n // Reload the server manifest and re-register methods\n try {\n // Clear config cache to ensure fresh config is loaded\n clearConfigCache();\n const config = await loadConfig(root);\n const mod = await server.ssrLoadModule(VIRTUAL_SERVER_MANIFEST_ID);\n const registerAll = mod.registerAll;\n const httpHandlers = mod.httpHandlers || [];\n const seoMetadataHandlers = mod.seoMetadataHandlers || [];\n const pageRoutePatterns = mod.pageRoutePatterns || [];\n const middlewareHandler = mod.middlewareHandler || null;\n const workers = mod.workers || [];\n const ssrPages = mod.ssrPages || [];\n const appShell = mod.appShell || null;\n\n // Update the dev server registry with new methods and HTTP handlers\n if (server.httpServer) {\n attachToDevServer(\n server.httpServer,\n (registry, httpRouter, seoRouter) => {\n registerAll(registry);\n httpRouter.registerRoutes(httpHandlers);\n seoRouter.registerRoutes(seoMetadataHandlers);\n seoRouter.setPageRoutePatterns(pageRoutePatterns);\n if (middlewareHandler) {\n registry.setMiddleware(middlewareHandler);\n httpRouter.setMiddleware(middlewareHandler);\n }\n },\n config,\n workers,\n ssrPages,\n appShell\n );\n }\n } catch (e) {\n log(\"error\", \"Failed to reload Helium server manifest\", e);\n }\n\n // Trigger HMR for any client code that imports heliumts/server\n server.ws.send({\n type: \"full-reload\",\n path: \"*\",\n });\n };\n\n // Watch server directory for changes\n const serverPath = path.join(root, serverDir);\n server.watcher.add(serverPath);\n\n // Watch config files for changes\n const configFiles = [\"helium.config.ts\", \"helium.config.js\", \"helium.config.mjs\"];\n for (const configFile of configFiles) {\n const configPath = path.join(root, configFile);\n if (fs.existsSync(configPath)) {\n server.watcher.add(configPath);\n }\n }\n\n /**\n * Debounced handler for server file changes.\n * This prevents multiple rapid regenerations during file saves.\n * @param allowFewer - pass true when files are deleted, so the\n * method count is allowed to decrease.\n */\n let pendingAllowFewer = false;\n const debouncedHandleServerFileChange = (allowFewer = false) => {\n // If any event in the batch is an unlink, honour it\n if (allowFewer) {\n pendingAllowFewer = true;\n }\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(() => {\n debounceTimer = null;\n const shouldAllowFewer = pendingAllowFewer;\n pendingAllowFewer = false;\n handleServerFileChange(shouldAllowFewer);\n }, DEBOUNCE_DELAY);\n };\n\n server.watcher.on(\"change\", (file) => {\n const relative = path.relative(root, file);\n const normalized = normalizeToPosix(relative);\n\n // If a server file changed, regenerate everything\n if (normalized.startsWith(`${serverDir}/`)) {\n debouncedHandleServerFileChange();\n }\n\n // If config file changed, reload config and regenerate\n if (configFiles.some((cf) => normalized === cf)) {\n log(\"info\", `Config file changed: ${normalized}`);\n debouncedHandleServerFileChange();\n }\n });\n\n server.watcher.on(\"add\", (file) => {\n const relative = path.relative(root, file);\n const normalized = normalizeToPosix(relative);\n\n // If a server file was added, regenerate everything\n if (normalized.startsWith(`${serverDir}/`)) {\n debouncedHandleServerFileChange();\n }\n });\n\n server.watcher.on(\"unlink\", (file) => {\n const relative = path.relative(root, file);\n const normalized = normalizeToPosix(relative);\n\n // If a server file was removed, regenerate (allow fewer methods)\n if (normalized.startsWith(`${serverDir}/`)) {\n debouncedHandleServerFileChange(true);\n }\n });\n\n // We hook into the server start to attach our RPC server\n server.httpServer?.on(\"listening\", async () => {\n try {\n // Load config\n const config = await loadConfig(root);\n\n // Load the manifest using Vite's SSR loader\n // This allows us to load TS files directly and handle dependencies\n const mod = await server.ssrLoadModule(VIRTUAL_SERVER_MANIFEST_ID);\n const registerAll = mod.registerAll;\n const httpHandlers = mod.httpHandlers || [];\n const seoMetadataHandlers = mod.seoMetadataHandlers || [];\n const pageRoutePatterns = mod.pageRoutePatterns || [];\n const middlewareHandler = mod.middlewareHandler || null;\n const workers = mod.workers || [];\n const ssrPages = mod.ssrPages || [];\n const appShell = mod.appShell || null;\n\n if (server.httpServer) {\n attachToDevServer(\n server.httpServer,\n (registry, httpRouter, seoRouter) => {\n registerAll(registry);\n httpRouter.registerRoutes(httpHandlers);\n seoRouter.registerRoutes(seoMetadataHandlers);\n seoRouter.setPageRoutePatterns(pageRoutePatterns);\n if (middlewareHandler) {\n registry.setMiddleware(middlewareHandler);\n httpRouter.setMiddleware(middlewareHandler);\n }\n },\n config,\n workers,\n ssrPages,\n appShell\n );\n }\n } catch (e) {\n log(\"error\", \"Failed to attach Helium RPC server\", e);\n }\n });\n },\n };\n}\n\nfunction generateSSRClientStubModule(): string {\n return `\nimport React from 'react';\n\nexport const RouterContext = React.createContext(null);\n\nfunction getSSRRouterSnapshot() {\n const snapshot = globalThis.__HELIUM_SSR_ROUTER__;\n if (!snapshot || typeof snapshot !== 'object') {\n return {\n path: '/',\n params: {},\n search: '',\n };\n }\n\n return {\n path: typeof snapshot.path === 'string' ? snapshot.path : '/',\n params: snapshot.params && typeof snapshot.params === 'object' ? snapshot.params : {},\n search: typeof snapshot.search === 'string' ? snapshot.search : '',\n };\n}\n\nexport function useRouter() {\n const snapshot = getSSRRouterSnapshot();\n return {\n path: snapshot.path,\n params: snapshot.params,\n searchParams: new URLSearchParams(snapshot.search),\n push: () => {},\n replace: () => {},\n on: () => () => {},\n status: 200,\n isNavigating: false,\n isPending: false,\n };\n}\n\nexport function Link(props) {\n const { href = '#', children, ...rest } = props || {};\n return React.createElement('a', { href, ...rest }, children);\n}\n\nexport function Redirect() {\n return null;\n}\n\nexport function AppRouter() {\n return null;\n}\n\nexport function useCall() {\n return {\n call: async () => null,\n isCalling: false,\n error: null,\n };\n}\n\nexport function useFetch() {\n return {\n data: null,\n isLoading: false,\n error: null,\n refetch: async () => undefined,\n };\n}\n\nexport class RpcError extends Error {}\n\nexport function getRpcTransport() {\n return 'websocket';\n}\n\nexport function isAutoHttpOnMobileEnabled() {\n return false;\n}\n\nexport function preconnect() {}\n\nexport function isSSR() {\n return true;\n}\n`;\n}\n\nfunction generateSSRTransitionsStubModule(): string {\n return `\nimport React from 'react';\n\nexport function useDeferredNavigation() {\n return {\n path: '/',\n deferredPath: '/',\n isStale: false,\n isPending: false,\n isTransitioning: false,\n };\n}\n\nexport function PageTransition({ children }) {\n return React.createElement(React.Fragment, null, children);\n}\n`;\n}\n\nfunction generateSSRPrefetchStubModule(): string {\n return `\nexport function prefetchRoute() {}\nexport function clearPrefetchCache() {}\n`;\n}\n\n/**\n * Convert file path to POSIX format\n * @internal Exported for testing\n */\nexport function normalizeToPosix(filePath: string): string {\n return filePath.split(path.sep).join(\"/\");\n}\n\n/**\n * Check if an importer is a server module\n * @internal Exported for testing\n */\nexport function isServerModule(importer: string | undefined, root: string, serverDir: string): boolean {\n if (!importer || importer.startsWith(\"\\0\")) {\n return false;\n }\n\n const [importerPath] = importer.split(\"?\");\n if (!importerPath) {\n return false;\n }\n\n const relative = path.relative(root, importerPath);\n if (!relative || relative.startsWith(\"..\")) {\n return false;\n }\n\n const normalized = normalizeToPosix(relative);\n return normalized === serverDir || normalized.startsWith(`${serverDir}/`);\n}\n\n/**\n * Touch the project's tsconfig.json to force the TypeScript language server\n * to reload the project and pick up changed module augmentations.\n *\n * TS language server watches tsconfig.json for changes. When a `.d.ts` file\n * with `declare module` augmentations is regenerated, TS doesn't always\n * detect the new content — leading to stale autocomplete. By updating\n * tsconfig.json's mtime we trigger a full project reload.\n *\n * The file content is NOT modified; only the filesystem timestamp changes.\n *\n * @internal Exported for testing\n */\nexport function touchTsConfig(root: string): void {\n const tsconfigPath = path.join(root, \"tsconfig.json\");\n try {\n if (fs.existsSync(tsconfigPath)) {\n const now = new Date();\n fs.utimesSync(tsconfigPath, now, now);\n }\n } catch {\n // Non-critical: if we can't touch the file, TS may just need a manual reload\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"heliumPlugin.js","sourceRoot":"","sources":["../../src/vite/heliumPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport type { Plugin } from \"vite\";\n\nimport { clearConfigCache, getRpcClientConfig, loadConfig } from \"../server/config.js\";\nimport { attachToDevServer } from \"../server/devServer.js\";\nimport { createEnvDefines, injectEnvToProcess, loadEnvFiles } from \"../utils/envLoader.js\";\nimport { log } from \"../utils/logger.js\";\nimport {\n RESOLVED_VIRTUAL_CLIENT_MODULE_ID,\n RESOLVED_VIRTUAL_ENTRY_MODULE_ID,\n RESOLVED_VIRTUAL_SERVER_MANIFEST_ID,\n SERVER_DIR,\n VIRTUAL_CLIENT_MODULE_ID,\n VIRTUAL_ENTRY_MODULE_ID,\n VIRTUAL_SERVER_MANIFEST_ID,\n} from \"./paths.js\";\nimport { checkRouteCollisions, scanAppShell, scanPageRoutePatterns, scanServerExports, scanSSRPages } from \"./scanner.js\";\nimport { generateClientModule, generateEntryModule, generateServerManifest, generateTypeDefinitions } from \"./virtualServerModule.js\";\n\nexport default function helium(): Plugin {\n let root = process.cwd();\n const serverDir = normalizeToPosix(SERVER_DIR);\n const VIRTUAL_SSR_CLIENT_MODULE_ID = \"heliumts/__ssr_client\";\n const RESOLVED_VIRTUAL_SSR_CLIENT_MODULE_ID = \"\\0heliumts:ssr-client\";\n const VIRTUAL_SSR_TRANSITIONS_MODULE_ID = \"heliumts/__ssr_transitions\";\n const RESOLVED_VIRTUAL_SSR_TRANSITIONS_MODULE_ID = \"\\0heliumts:ssr-transitions\";\n const VIRTUAL_SSR_PREFETCH_MODULE_ID = \"heliumts/__ssr_prefetch\";\n const RESOLVED_VIRTUAL_SSR_PREFETCH_MODULE_ID = \"\\0heliumts:ssr-prefetch\";\n\n return {\n name: \"vite-plugin-helium\",\n enforce: \"pre\",\n configResolved(config) {\n root = config.root;\n },\n transformIndexHtml: {\n order: \"pre\",\n handler(html, _ctx) {\n // Check if HTML already has a script tag for entry\n if (html.includes(\"src/main.tsx\") || html.includes(\"src/main.ts\")) {\n return html; // User has their own entry, don't modify\n }\n\n // Ensure root div exists\n let modifiedHtml = html;\n if (!modifiedHtml.includes('id=\"root\"')) {\n modifiedHtml = modifiedHtml.replace(\"<body>\", '<body>\\n <div id=\"root\"></div>');\n }\n\n // Generate physical entry file\n const heliumDir = path.join(root, \"node_modules\", \".heliumts\");\n if (!fs.existsSync(heliumDir)) {\n fs.mkdirSync(heliumDir, { recursive: true });\n }\n const entryPath = path.join(heliumDir, \"entry.tsx\");\n fs.writeFileSync(entryPath, generateEntryModule());\n\n // Return with tags to inject the entry (runtime config is fetched by the client)\n return [\n {\n tag: \"script\",\n attrs: {\n type: \"module\",\n src: \"/node_modules/.heliumts/entry.tsx\",\n },\n injectTo: \"body\",\n },\n ];\n },\n },\n async config(config) {\n // Load environment variables before config is finalized\n const mode = config.mode || \"development\";\n const envVars = loadEnvFiles({ root, mode });\n\n // Inject env vars into process.env BEFORE Vite's own env resolution.\n // This ensures platform-set env vars (Render, DigitalOcean Apps, etc.)\n // are picked up by Vite's envPrefix matching and included in all\n // import.meta.env object references throughout the bundle.\n injectEnvToProcess(envVars);\n\n // Create defines for client-side env variables\n const envDefines = createEnvDefines(envVars);\n\n // Load helium config to get client-side RPC transport settings\n const heliumConfig = await loadConfig(root);\n const rpcClientConfig = getRpcClientConfig(heliumConfig);\n\n // Merge user-configured envPrefix with HELIUM_PUBLIC_\n const userPrefix = config.envPrefix ?? \"VITE_\";\n const prefixArray = Array.isArray(userPrefix) ? userPrefix : [userPrefix];\n if (!prefixArray.includes(\"HELIUM_PUBLIC_\")) {\n prefixArray.push(\"HELIUM_PUBLIC_\");\n }\n\n // Provide default index.html if none exists\n return {\n appType: \"spa\",\n envPrefix: prefixArray,\n optimizeDeps: {\n include: [\"react-dom/client\"],\n // Exclude helium from pre-bundling since it's the framework itself\n // This ensures changes to helium are picked up immediately\n exclude: [\"heliumts\", \"heliumts/client\", \"heliumts/server\", \"heliumts/vite\"],\n },\n // SSR configuration to properly isolate server-only code\n ssr: {\n // Externalize Node.js built-in modules - these should never be bundled\n external: [\"util\", \"zlib\", \"http\", \"https\", \"http2\", \"fs\", \"path\", \"crypto\", \"stream\", \"os\", \"url\", \"net\", \"tls\", \"child_process\", \"worker_threads\"],\n // Don't externalize heliumts - let the plugin handle the client/server split\n noExternal: [\"heliumts\"],\n },\n // Ensure Node.js built-ins are not bundled for client\n build: {\n rollupOptions: {\n external: [\n // Node.js built-in modules should never be in client bundle\n /^node:/,\n \"util\",\n \"zlib\",\n \"http\",\n \"https\",\n \"http2\",\n \"fs\",\n \"path\",\n \"crypto\",\n \"stream\",\n \"os\",\n \"url\",\n \"net\",\n \"tls\",\n \"child_process\",\n \"worker_threads\",\n ],\n },\n },\n define: {\n ...envDefines,\n __HELIUM_DEV__: JSON.stringify(mode !== \"production\"),\n __HELIUM_RPC_TRANSPORT__: JSON.stringify(rpcClientConfig.transport),\n __HELIUM_RPC_AUTO_HTTP_ON_MOBILE__: JSON.stringify(rpcClientConfig.autoHttpOnMobile),\n __HELIUM_RPC_TOKEN_VALIDITY_MS__: JSON.stringify(rpcClientConfig.tokenValidityMs),\n },\n };\n },\n resolveId(id, importer, options) {\n if (options?.ssr && id === \"heliumts/client\") {\n return RESOLVED_VIRTUAL_SSR_CLIENT_MODULE_ID;\n }\n if (options?.ssr && id === \"heliumts/client/transitions\") {\n return RESOLVED_VIRTUAL_SSR_TRANSITIONS_MODULE_ID;\n }\n if (options?.ssr && id === \"heliumts/client/prefetch\") {\n return RESOLVED_VIRTUAL_SSR_PREFETCH_MODULE_ID;\n }\n if (id === VIRTUAL_CLIENT_MODULE_ID) {\n if (isServerModule(importer, root, serverDir)) {\n return null;\n }\n return RESOLVED_VIRTUAL_CLIENT_MODULE_ID;\n }\n if (id === VIRTUAL_SERVER_MANIFEST_ID) {\n return RESOLVED_VIRTUAL_SERVER_MANIFEST_ID;\n }\n if (id === VIRTUAL_ENTRY_MODULE_ID) {\n // Add .tsx extension so Vite knows it contains JSX\n return RESOLVED_VIRTUAL_ENTRY_MODULE_ID + \".tsx\";\n }\n // Intercept heliumts/server imports from client code\n if (id === \"heliumts/server\") {\n // If imported from server code, let it resolve normally\n if (isServerModule(importer, root, serverDir)) {\n return null;\n }\n // For client code, redirect to virtual client module\n return RESOLVED_VIRTUAL_CLIENT_MODULE_ID;\n }\n return null;\n },\n transform(code, id, options) {\n // Prevent .server.ts/.server.js sidecar files from being bundled in client code.\n // These files contain server-only logic (e.g. DB queries) and must never run in the browser.\n if (!options?.ssr && /\\.server\\.(ts|js|tsx|jsx|mts|mjs)$/.test(id)) {\n return { code: \"export default null;\", map: null };\n }\n },\n load(id) {\n if (id === RESOLVED_VIRTUAL_SSR_CLIENT_MODULE_ID) {\n return generateSSRClientStubModule();\n }\n if (id === RESOLVED_VIRTUAL_SSR_TRANSITIONS_MODULE_ID) {\n return generateSSRTransitionsStubModule();\n }\n if (id === RESOLVED_VIRTUAL_SSR_PREFETCH_MODULE_ID) {\n return generateSSRPrefetchStubModule();\n }\n if (id === RESOLVED_VIRTUAL_CLIENT_MODULE_ID) {\n const { methods } = scanServerExports(root);\n return generateClientModule(methods);\n }\n if (id === RESOLVED_VIRTUAL_SERVER_MANIFEST_ID) {\n const { methods, httpHandlers, seoMetadata, middleware, workers } = scanServerExports(root);\n const pageRoutePatterns = scanPageRoutePatterns(root);\n const ssrPages = scanSSRPages(root);\n const appShell = scanAppShell(root);\n return generateServerManifest(methods, httpHandlers, seoMetadata, pageRoutePatterns, ssrPages, appShell, middleware, workers);\n }\n if (id === RESOLVED_VIRTUAL_ENTRY_MODULE_ID + \".tsx\") {\n return generateEntryModule();\n }\n },\n buildStart() {\n const { methods } = scanServerExports(root);\n const dts = generateTypeDefinitions(methods, root);\n const typesDir = path.join(root, \"src\", \"types\");\n const dtsPath = path.join(typesDir, \"heliumts-server.d.ts\");\n\n // Ensure src/types exists\n if (!fs.existsSync(typesDir)) {\n fs.mkdirSync(typesDir, { recursive: true });\n }\n\n // At build start we always allow writing the canonical set.\n // Only skip if content is identical to avoid needless TS invalidation.\n if (!fs.existsSync(dtsPath) || fs.readFileSync(dtsPath, \"utf-8\") !== dts) {\n fs.writeFileSync(dtsPath, dts);\n touchTsConfig(root);\n }\n\n // Check for route collisions in pages directory\n checkRouteCollisions(root);\n },\n configureServer(server) {\n // Add middleware to handle HTML fallback for nested routes\n // This ensures that routes like /docs/guides/auth properly serve index.html\n // so the client-side router can handle them\n server.middlewares.use((req, res, next) => {\n const url = req.url || \"\";\n const cleanUrl = url.split(\"?\")[0];\n\n // Skip if:\n // - Has file extension (asset request)\n // - Is an API/special endpoint\n // - Is a dev server endpoint\n if (\n path.extname(cleanUrl) !== \"\" ||\n cleanUrl.startsWith(\"/api\") ||\n cleanUrl.startsWith(\"/webhooks\") ||\n cleanUrl.startsWith(\"/auth\") ||\n cleanUrl.startsWith(\"/@\") ||\n cleanUrl.startsWith(\"/__helium__\")\n ) {\n return next();\n }\n\n // For all other routes (including nested paths like /docs/guides/auth),\n // rewrite to index.html so Vite serves it and the client-side router handles routing\n req.url = \"/index.html\";\n next();\n });\n\n /**\n * Write type definitions only if content has changed.\n * This prevents unnecessary TypeScript recompilation.\n *\n * When `allowFewer` is false (default) the file will NOT be\n * overwritten if the new content has fewer method declarations\n * than the existing file — this guards against writing a\n * degraded .d.ts while the user's file is only partially saved.\n */\n const writeTypesIfChanged = (dts: string, allowFewer = false): boolean => {\n const typesDir = path.join(root, \"src\", \"types\");\n const dtsPath = path.join(typesDir, \"heliumts-server.d.ts\");\n\n if (!fs.existsSync(typesDir)) {\n fs.mkdirSync(typesDir, { recursive: true });\n }\n\n // Check if file exists and content is the same\n if (fs.existsSync(dtsPath)) {\n const existing = fs.readFileSync(dtsPath, \"utf-8\");\n if (existing === dts) {\n return false; // No change needed\n }\n\n // Guard: don't overwrite with fewer methods unless explicitly allowed\n // (e.g. on unlink). This prevents losing types during partial saves.\n if (!allowFewer) {\n const countExports = (s: string) => (s.match(/export const \\w+:/g) || []).length;\n const existingCount = countExports(existing);\n const newCount = countExports(dts);\n if (newCount < existingCount) {\n log(\"info\", `Skipping type generation: found ${newCount} methods, existing has ${existingCount} (likely partial save)`);\n return false;\n }\n }\n }\n\n fs.writeFileSync(dtsPath, dts);\n\n // Touch tsconfig.json to force the TypeScript language server\n // to reload the project. Without this, TS may cache stale\n // module augmentations and autocomplete won't reflect the\n // new methods until a manual restart.\n touchTsConfig(root);\n\n return true; // File was written\n };\n\n const regenerateTypes = (allowFewer = false): boolean => {\n try {\n const { methods } = scanServerExports(root);\n const dts = generateTypeDefinitions(methods, root);\n return writeTypesIfChanged(dts, allowFewer);\n } catch (e) {\n log(\"error\", \"Failed to regenerate types\", e);\n return false;\n }\n };\n\n // Debounce timer for file changes\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n const DEBOUNCE_DELAY = 300; // ms — long enough for format-on-save to finish\n\n const handleServerFileChange = async (allowFewer = false) => {\n // Regenerate type definitions\n regenerateTypes(allowFewer);\n\n // Invalidate the virtual modules so they get regenerated\n const clientModule = server.environments.client?.moduleGraph.getModuleById(RESOLVED_VIRTUAL_CLIENT_MODULE_ID);\n const serverModule = server.environments.ssr?.moduleGraph.getModuleById(RESOLVED_VIRTUAL_SERVER_MANIFEST_ID);\n\n if (clientModule) {\n server.environments.client?.moduleGraph.invalidateModule(clientModule);\n }\n if (serverModule) {\n server.environments.ssr?.moduleGraph.invalidateModule(serverModule);\n }\n\n // Reload the server manifest and re-register methods\n try {\n // Clear config cache to ensure fresh config is loaded\n clearConfigCache();\n const config = await loadConfig(root);\n const mod = await server.ssrLoadModule(VIRTUAL_SERVER_MANIFEST_ID);\n const registerAll = mod.registerAll;\n const httpHandlers = mod.httpHandlers || [];\n const seoMetadataHandlers = mod.seoMetadataHandlers || [];\n const pageRoutePatterns = mod.pageRoutePatterns || [];\n const middlewareHandler = mod.middlewareHandler || null;\n const workers = mod.workers || [];\n const ssrPages = mod.ssrPages || [];\n const appShell = mod.appShell || null;\n\n // Update the dev server registry with new methods and HTTP handlers\n if (server.httpServer) {\n attachToDevServer(\n server.httpServer,\n (registry, httpRouter, seoRouter) => {\n registerAll(registry);\n httpRouter.registerRoutes(httpHandlers);\n seoRouter.registerRoutes(seoMetadataHandlers);\n seoRouter.setPageRoutePatterns(pageRoutePatterns);\n if (middlewareHandler) {\n registry.setMiddleware(middlewareHandler);\n httpRouter.setMiddleware(middlewareHandler);\n }\n },\n config,\n workers,\n ssrPages,\n appShell\n );\n }\n } catch (e) {\n log(\"error\", \"Failed to reload Helium server manifest\", e);\n }\n\n // Trigger HMR for any client code that imports heliumts/server\n server.ws.send({\n type: \"full-reload\",\n path: \"*\",\n });\n };\n\n // Watch server directory for changes\n const serverPath = path.join(root, serverDir);\n server.watcher.add(serverPath);\n\n // Watch config files for changes\n const configFiles = [\"helium.config.ts\", \"helium.config.js\", \"helium.config.mjs\"];\n for (const configFile of configFiles) {\n const configPath = path.join(root, configFile);\n if (fs.existsSync(configPath)) {\n server.watcher.add(configPath);\n }\n }\n\n /**\n * Debounced handler for server file changes.\n * This prevents multiple rapid regenerations during file saves.\n * @param allowFewer - pass true when files are deleted, so the\n * method count is allowed to decrease.\n */\n let pendingAllowFewer = false;\n const debouncedHandleServerFileChange = (allowFewer = false) => {\n // If any event in the batch is an unlink, honour it\n if (allowFewer) {\n pendingAllowFewer = true;\n }\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(() => {\n debounceTimer = null;\n const shouldAllowFewer = pendingAllowFewer;\n pendingAllowFewer = false;\n handleServerFileChange(shouldAllowFewer);\n }, DEBOUNCE_DELAY);\n };\n\n server.watcher.on(\"change\", (file) => {\n const relative = path.relative(root, file);\n const normalized = normalizeToPosix(relative);\n\n // If a server file changed, regenerate everything\n if (normalized.startsWith(`${serverDir}/`)) {\n debouncedHandleServerFileChange();\n }\n\n // If config file changed, reload config and regenerate\n if (configFiles.some((cf) => normalized === cf)) {\n log(\"info\", `Config file changed: ${normalized}`);\n debouncedHandleServerFileChange();\n }\n });\n\n server.watcher.on(\"add\", (file) => {\n const relative = path.relative(root, file);\n const normalized = normalizeToPosix(relative);\n\n // If a server file was added, regenerate everything\n if (normalized.startsWith(`${serverDir}/`)) {\n debouncedHandleServerFileChange();\n }\n });\n\n server.watcher.on(\"unlink\", (file) => {\n const relative = path.relative(root, file);\n const normalized = normalizeToPosix(relative);\n\n // If a server file was removed, regenerate (allow fewer methods)\n if (normalized.startsWith(`${serverDir}/`)) {\n debouncedHandleServerFileChange(true);\n }\n });\n\n // We hook into the server start to attach our RPC server\n server.httpServer?.on(\"listening\", async () => {\n try {\n // Load config\n const config = await loadConfig(root);\n\n // Load the manifest using Vite's SSR loader\n // This allows us to load TS files directly and handle dependencies\n const mod = await server.ssrLoadModule(VIRTUAL_SERVER_MANIFEST_ID);\n const registerAll = mod.registerAll;\n const httpHandlers = mod.httpHandlers || [];\n const seoMetadataHandlers = mod.seoMetadataHandlers || [];\n const pageRoutePatterns = mod.pageRoutePatterns || [];\n const middlewareHandler = mod.middlewareHandler || null;\n const workers = mod.workers || [];\n const ssrPages = mod.ssrPages || [];\n const appShell = mod.appShell || null;\n\n if (server.httpServer) {\n attachToDevServer(\n server.httpServer,\n (registry, httpRouter, seoRouter) => {\n registerAll(registry);\n httpRouter.registerRoutes(httpHandlers);\n seoRouter.registerRoutes(seoMetadataHandlers);\n seoRouter.setPageRoutePatterns(pageRoutePatterns);\n if (middlewareHandler) {\n registry.setMiddleware(middlewareHandler);\n httpRouter.setMiddleware(middlewareHandler);\n }\n },\n config,\n workers,\n ssrPages,\n appShell\n );\n }\n } catch (e) {\n log(\"error\", \"Failed to attach Helium RPC server\", e);\n }\n });\n },\n };\n}\n\nfunction generateSSRClientStubModule(): string {\n return `\nimport React from 'react';\n\nexport const RouterContext = React.createContext(null);\n\nfunction getSSRRouterSnapshot() {\n const snapshot = globalThis.__HELIUM_SSR_ROUTER__;\n if (!snapshot || typeof snapshot !== 'object') {\n return {\n path: '/',\n params: {},\n search: '',\n };\n }\n\n return {\n path: typeof snapshot.path === 'string' ? snapshot.path : '/',\n params: snapshot.params && typeof snapshot.params === 'object' ? snapshot.params : {},\n search: typeof snapshot.search === 'string' ? snapshot.search : '',\n };\n}\n\nexport function useRouter() {\n const snapshot = getSSRRouterSnapshot();\n return {\n path: snapshot.path,\n params: snapshot.params,\n searchParams: new URLSearchParams(snapshot.search),\n push: () => {},\n replace: () => {},\n on: () => () => {},\n status: 200,\n isNavigating: false,\n isPending: false,\n };\n}\n\nexport function Link(props) {\n const { href = '#', children, ...rest } = props || {};\n return React.createElement('a', { href, ...rest }, children);\n}\n\nexport function Redirect() {\n return null;\n}\n\nexport function AppRouter() {\n return null;\n}\n\nexport function useCall() {\n return {\n call: async () => null,\n isCalling: false,\n error: null,\n };\n}\n\nexport function useFetch() {\n return {\n data: null,\n isLoading: false,\n error: null,\n refetch: async () => undefined,\n };\n}\n\nexport class RpcError extends Error {}\n\nexport function getRpcTransport() {\n return 'websocket';\n}\n\nexport function isAutoHttpOnMobileEnabled() {\n return false;\n}\n\nexport function preconnect() {}\n\nexport function isSSR() {\n return true;\n}\n`;\n}\n\nfunction generateSSRTransitionsStubModule(): string {\n return `\nimport React from 'react';\n\nexport function useDeferredNavigation() {\n return {\n path: '/',\n deferredPath: '/',\n isStale: false,\n isPending: false,\n isTransitioning: false,\n };\n}\n\nexport function PageTransition({ children }) {\n return React.createElement(React.Fragment, null, children);\n}\n`;\n}\n\nfunction generateSSRPrefetchStubModule(): string {\n return `\nexport function prefetchRoute() {}\nexport function clearPrefetchCache() {}\n`;\n}\n\n/**\n * Convert file path to POSIX format\n * @internal Exported for testing\n */\nexport function normalizeToPosix(filePath: string): string {\n return filePath.split(path.sep).join(\"/\");\n}\n\n/**\n * Check if an importer is a server module\n * @internal Exported for testing\n */\nexport function isServerModule(importer: string | undefined, root: string, serverDir: string): boolean {\n if (!importer || importer.startsWith(\"\\0\")) {\n return false;\n }\n\n const [importerPath] = importer.split(\"?\");\n if (!importerPath) {\n return false;\n }\n\n const relative = path.relative(root, importerPath);\n if (!relative || relative.startsWith(\"..\")) {\n return false;\n }\n\n const normalized = normalizeToPosix(relative);\n return normalized === serverDir || normalized.startsWith(`${serverDir}/`);\n}\n\n/**\n * Touch the project's tsconfig.json to force the TypeScript language server\n * to reload the project and pick up changed module augmentations.\n *\n * TS language server watches tsconfig.json for changes. When a `.d.ts` file\n * with `declare module` augmentations is regenerated, TS doesn't always\n * detect the new content — leading to stale autocomplete. By updating\n * tsconfig.json's mtime we trigger a full project reload.\n *\n * The file content is NOT modified; only the filesystem timestamp changes.\n *\n * @internal Exported for testing\n */\nexport function touchTsConfig(root: string): void {\n const tsconfigPath = path.join(root, \"tsconfig.json\");\n try {\n if (fs.existsSync(tsconfigPath)) {\n const now = new Date();\n fs.utimesSync(tsconfigPath, now, now);\n }\n } catch {\n // Non-critical: if we can't touch the file, TS may just need a manual reload\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualServerModule.d.ts","sourceRoot":"","sources":["../../src/vite/virtualServerModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjI,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,YAAY,EAAE,EACvB,YAAY,EAAE,iBAAiB,EAAE,EACjC,WAAW,GAAE,iBAAiB,EAAO,EACrC,iBAAiB,GAAE,MAAM,EAAO,EAChC,QAAQ,GAAE,aAAa,EAAO,EAC9B,gBAAgB,GAAE,MAAM,GAAG,IAAW,EACtC,UAAU,CAAC,EAAE,gBAAgB,EAC7B,OAAO,GAAE,YAAY,EAAO,GAC7B,MAAM,CAmGR;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAIpE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAiErF;AAED,wBAAgB,mBAAmB,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"virtualServerModule.d.ts","sourceRoot":"","sources":["../../src/vite/virtualServerModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjI,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,YAAY,EAAE,EACvB,YAAY,EAAE,iBAAiB,EAAE,EACjC,WAAW,GAAE,iBAAiB,EAAO,EACrC,iBAAiB,GAAE,MAAM,EAAO,EAChC,QAAQ,GAAE,aAAa,EAAO,EAC9B,gBAAgB,GAAE,MAAM,GAAG,IAAW,EACtC,UAAU,CAAC,EAAE,gBAAgB,EAC7B,OAAO,GAAE,YAAY,EAAO,GAC7B,MAAM,CAmGR;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAIpE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAiErF;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CA+B5C"}
|
|
@@ -159,9 +159,16 @@ import { createRoot, hydrateRoot } from 'react-dom/client';
|
|
|
159
159
|
import { AppRouter } from 'heliumts/client';
|
|
160
160
|
import App from '/src/App';
|
|
161
161
|
|
|
162
|
+
// Merge runtime public env vars injected by the production server.
|
|
163
|
+
// This ensures platform env vars (Render, DigitalOcean Apps, etc.) are
|
|
164
|
+
// available via import.meta.env even if they weren't present at build time.
|
|
165
|
+
if (typeof window !== 'undefined' && window.__HELIUM_PUBLIC_ENV__) {
|
|
166
|
+
Object.assign(import.meta.env, window.__HELIUM_PUBLIC_ENV__);
|
|
167
|
+
}
|
|
168
|
+
|
|
162
169
|
const rootEl = document.getElementById('root');
|
|
163
170
|
if (!rootEl) {
|
|
164
|
-
throw new Error('Root element not found. Helium requires a <div id
|
|
171
|
+
throw new Error('Root element not found. Helium requires a <div id="root"></div> in your HTML.');
|
|
165
172
|
}
|
|
166
173
|
|
|
167
174
|
const app = (
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualServerModule.js","sourceRoot":"","sources":["../../src/vite/virtualServerModule.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"path\";\n\nimport { HTTPHandlerExport, MethodExport, MiddlewareExport, SEOMetadataExport, SSRPageExport, WorkerExport } from \"./scanner.js\";\n\nexport function generateServerManifest(\n methods: MethodExport[],\n httpHandlers: HTTPHandlerExport[],\n seoMetadata: SEOMetadataExport[] = [],\n pageRoutePatterns: string[] = [],\n ssrPages: SSRPageExport[] = [],\n appShellFilePath: string | null = null,\n middleware?: MiddlewareExport,\n workers: WorkerExport[] = []\n): string {\n const methodImports = methods.map((m, i) => `import { ${m.name} as method_${i} } from '${m.filePath}';`).join(\"\\n\");\n const httpImports = httpHandlers.map((h, i) => `import { ${h.name} as http_${i} } from '${h.filePath}';`).join(\"\\n\");\n const seoImports = seoMetadata.map((s, i) => `import { ${s.name} as seo_${i} } from '${s.filePath}';`).join(\"\\n\");\n const workerImports = workers.map((w, i) => `import { ${w.name} as worker_${i} } from '${w.filePath}';`).join(\"\\n\");\n const middlewareImport = middleware ? `import ${middleware.name === \"default\" ? \"middleware\" : `{ ${middleware.name} as middleware }`} from '${middleware.filePath}';` : \"\";\n\n const methodRegistrations = methods.map((m, i) => ` registry.register('${m.name}', method_${i});`).join(\"\\n\");\n\n const httpExports = httpHandlers.map((h, i) => ` { name: '${h.name}', handler: http_${i} },`).join(\"\\n\");\n const seoExports = seoMetadata.map((s, i) => ` { name: '${s.name}', handler: seo_${i} },`).join(\"\\n\");\n\n const workerExports = workers.map((w, i) => ` { name: '${w.name}', worker: worker_${i} },`).join(\"\\n\");\n\n const ssrPageExports = ssrPages\n .map((s, i) => {\n const loadLayoutsBody = s.layoutFilePaths\n .map(\n (layoutPath, layoutIndex) => ` {\n const mod_${layoutIndex} = await import('${layoutPath}');\n if (mod_${layoutIndex}.default) {\n layouts.push(mod_${layoutIndex}.default);\n }\n }`\n )\n .join(\"\\n\");\n\n const sidecarCheck = s.serverFilePath\n ? ` {\n const sidecar = await import('${s.serverFilePath}');\n if (typeof sidecar.getServerSideProps === 'function') {\n return sidecar.getServerSideProps(req, ctx);\n }\n }\n`\n : \"\";\n\n return ` {\n pathPattern: '${s.pathPattern}',\n loadComponent: async () => {\n const page = await import('${s.pageFilePath}');\n return page.default;\n },\n loadLayouts: async () => {\n const layouts = [];\n${loadLayoutsBody}\n return layouts;\n },\n getServerSideProps: async (req, ctx) => {\n${sidecarCheck} const page = await import('${s.pageFilePath}');\n if (typeof page.getServerSideProps === 'function') {\n return page.getServerSideProps(req, ctx);\n }\n return null;\n }\n },`;\n })\n .join(\"\\n\");\n\n return `\n${methodImports}\n${httpImports}\n${seoImports}\n${workerImports}\n${middlewareImport}\n\nexport function registerAll(registry) {\n${methodRegistrations}\n}\n\nexport const httpHandlers = [\n${httpExports}\n];\n\nexport const seoMetadataHandlers = [\n${seoExports}\n];\n\nexport const pageRoutePatterns = ${JSON.stringify(pageRoutePatterns)};\n\nexport const ssrPages = [\n${ssrPageExports}\n];\n\nexport const appShell = ${\n appShellFilePath\n ? `async () => {\n const mod = await import('${appShellFilePath}');\n return mod.default ?? mod.App ?? mod.app ?? null;\n}`\n : \"null\"\n };\n\nexport const workers = [\n${workerExports}\n];\n\nexport const middlewareHandler = ${middleware ? \"middleware\" : \"null\"};\n`;\n}\n\nexport function generateClientModule(methods: MethodExport[]): string {\n const exports = methods.map((m) => `export const ${m.name} = { __id: '${m.name}' };`).join(\"\\n\");\n\n return exports;\n}\n\nexport function generateTypeDefinitions(methods: MethodExport[], root: string): string {\n // Sort methods by name for a stable output regardless of file-system walk order\n const sorted = [...methods].sort((a, b) => a.name.localeCompare(b.name));\n\n const methodsWithRelativePath = sorted.map((m) => {\n let relPath = path.relative(path.join(root, \"src\"), m.filePath);\n if (!relPath.startsWith(\".\")) {\n relPath = \"../\" + relPath;\n }\n // Normalize to posix separators for import paths\n relPath = relPath.replace(/\\\\/g, \"/\").replace(/\\.ts$/, \"\");\n return {\n ...m,\n relPath,\n };\n });\n\n const imports = methodsWithRelativePath\n .map((m, index) => {\n return `import type { ${m.name} as __helium_method_${index} } from '${m.relPath}';`;\n })\n .join(\"\\n\");\n\n const methodExports = methodsWithRelativePath\n .map((m, index) => {\n return ` export const ${m.name}: import('heliumts/client').MethodStub<\n Parameters<typeof __helium_method_${index}['handler']>[0],\n Awaited<ReturnType<typeof __helium_method_${index}['handler']>>\n >;`;\n })\n .join(\"\\n\");\n\n // If there are no methods, we don't need to generate any augmentation\n // This prevents shadowing the actual heliumts/server exports\n if (methods.length === 0) {\n return `/* eslint-disable */\n/**\n* Auto generated file - DO NOT EDIT!\n* # Helium Server Type Definitions\n* \n* This file is empty because no methods have been defined yet.\n* Once you create a method using defineMethod(), type stubs will be generated here.\n*\n* @helium-methods (none)\n**/\nexport {};\n`;\n }\n\n const methodSignature = methodsWithRelativePath.map((m) => m.name).join(\", \");\n\n return `/* eslint-disable */\n/**\n* Auto generated file - DO NOT EDIT!\n* # Helium Server Type Definitions\n*\n* @helium-methods ${methodSignature}\n**/\n${imports}\n\ndeclare module 'heliumts/server' {\n // Method stubs for client-side type inference\n${methodExports}\n}\n`;\n}\n\nexport function generateEntryModule(): string {\n return `\nimport React from 'react';\nimport { createRoot, hydrateRoot } from 'react-dom/client';\nimport { AppRouter } from 'heliumts/client';\nimport App from '/src/App';\n\nconst rootEl = document.getElementById('root');\nif (!rootEl) {\n throw new Error('Root element not found. Helium requires a <div id=\\\"root\\\"></div> in your HTML.');\n}\n\nconst app = (\n <React.StrictMode>\n <AppRouter AppShell={App} />\n </React.StrictMode>\n);\n\nif (rootEl.hasChildNodes()) {\n hydrateRoot(rootEl, app);\n} else {\n createRoot(rootEl).render(app);\n}\n`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"virtualServerModule.js","sourceRoot":"","sources":["../../src/vite/virtualServerModule.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"path\";\n\nimport { HTTPHandlerExport, MethodExport, MiddlewareExport, SEOMetadataExport, SSRPageExport, WorkerExport } from \"./scanner.js\";\n\nexport function generateServerManifest(\n methods: MethodExport[],\n httpHandlers: HTTPHandlerExport[],\n seoMetadata: SEOMetadataExport[] = [],\n pageRoutePatterns: string[] = [],\n ssrPages: SSRPageExport[] = [],\n appShellFilePath: string | null = null,\n middleware?: MiddlewareExport,\n workers: WorkerExport[] = []\n): string {\n const methodImports = methods.map((m, i) => `import { ${m.name} as method_${i} } from '${m.filePath}';`).join(\"\\n\");\n const httpImports = httpHandlers.map((h, i) => `import { ${h.name} as http_${i} } from '${h.filePath}';`).join(\"\\n\");\n const seoImports = seoMetadata.map((s, i) => `import { ${s.name} as seo_${i} } from '${s.filePath}';`).join(\"\\n\");\n const workerImports = workers.map((w, i) => `import { ${w.name} as worker_${i} } from '${w.filePath}';`).join(\"\\n\");\n const middlewareImport = middleware ? `import ${middleware.name === \"default\" ? \"middleware\" : `{ ${middleware.name} as middleware }`} from '${middleware.filePath}';` : \"\";\n\n const methodRegistrations = methods.map((m, i) => ` registry.register('${m.name}', method_${i});`).join(\"\\n\");\n\n const httpExports = httpHandlers.map((h, i) => ` { name: '${h.name}', handler: http_${i} },`).join(\"\\n\");\n const seoExports = seoMetadata.map((s, i) => ` { name: '${s.name}', handler: seo_${i} },`).join(\"\\n\");\n\n const workerExports = workers.map((w, i) => ` { name: '${w.name}', worker: worker_${i} },`).join(\"\\n\");\n\n const ssrPageExports = ssrPages\n .map((s, i) => {\n const loadLayoutsBody = s.layoutFilePaths\n .map(\n (layoutPath, layoutIndex) => ` {\n const mod_${layoutIndex} = await import('${layoutPath}');\n if (mod_${layoutIndex}.default) {\n layouts.push(mod_${layoutIndex}.default);\n }\n }`\n )\n .join(\"\\n\");\n\n const sidecarCheck = s.serverFilePath\n ? ` {\n const sidecar = await import('${s.serverFilePath}');\n if (typeof sidecar.getServerSideProps === 'function') {\n return sidecar.getServerSideProps(req, ctx);\n }\n }\n`\n : \"\";\n\n return ` {\n pathPattern: '${s.pathPattern}',\n loadComponent: async () => {\n const page = await import('${s.pageFilePath}');\n return page.default;\n },\n loadLayouts: async () => {\n const layouts = [];\n${loadLayoutsBody}\n return layouts;\n },\n getServerSideProps: async (req, ctx) => {\n${sidecarCheck} const page = await import('${s.pageFilePath}');\n if (typeof page.getServerSideProps === 'function') {\n return page.getServerSideProps(req, ctx);\n }\n return null;\n }\n },`;\n })\n .join(\"\\n\");\n\n return `\n${methodImports}\n${httpImports}\n${seoImports}\n${workerImports}\n${middlewareImport}\n\nexport function registerAll(registry) {\n${methodRegistrations}\n}\n\nexport const httpHandlers = [\n${httpExports}\n];\n\nexport const seoMetadataHandlers = [\n${seoExports}\n];\n\nexport const pageRoutePatterns = ${JSON.stringify(pageRoutePatterns)};\n\nexport const ssrPages = [\n${ssrPageExports}\n];\n\nexport const appShell = ${\n appShellFilePath\n ? `async () => {\n const mod = await import('${appShellFilePath}');\n return mod.default ?? mod.App ?? mod.app ?? null;\n}`\n : \"null\"\n };\n\nexport const workers = [\n${workerExports}\n];\n\nexport const middlewareHandler = ${middleware ? \"middleware\" : \"null\"};\n`;\n}\n\nexport function generateClientModule(methods: MethodExport[]): string {\n const exports = methods.map((m) => `export const ${m.name} = { __id: '${m.name}' };`).join(\"\\n\");\n\n return exports;\n}\n\nexport function generateTypeDefinitions(methods: MethodExport[], root: string): string {\n // Sort methods by name for a stable output regardless of file-system walk order\n const sorted = [...methods].sort((a, b) => a.name.localeCompare(b.name));\n\n const methodsWithRelativePath = sorted.map((m) => {\n let relPath = path.relative(path.join(root, \"src\"), m.filePath);\n if (!relPath.startsWith(\".\")) {\n relPath = \"../\" + relPath;\n }\n // Normalize to posix separators for import paths\n relPath = relPath.replace(/\\\\/g, \"/\").replace(/\\.ts$/, \"\");\n return {\n ...m,\n relPath,\n };\n });\n\n const imports = methodsWithRelativePath\n .map((m, index) => {\n return `import type { ${m.name} as __helium_method_${index} } from '${m.relPath}';`;\n })\n .join(\"\\n\");\n\n const methodExports = methodsWithRelativePath\n .map((m, index) => {\n return ` export const ${m.name}: import('heliumts/client').MethodStub<\n Parameters<typeof __helium_method_${index}['handler']>[0],\n Awaited<ReturnType<typeof __helium_method_${index}['handler']>>\n >;`;\n })\n .join(\"\\n\");\n\n // If there are no methods, we don't need to generate any augmentation\n // This prevents shadowing the actual heliumts/server exports\n if (methods.length === 0) {\n return `/* eslint-disable */\n/**\n* Auto generated file - DO NOT EDIT!\n* # Helium Server Type Definitions\n* \n* This file is empty because no methods have been defined yet.\n* Once you create a method using defineMethod(), type stubs will be generated here.\n*\n* @helium-methods (none)\n**/\nexport {};\n`;\n }\n\n const methodSignature = methodsWithRelativePath.map((m) => m.name).join(\", \");\n\n return `/* eslint-disable */\n/**\n* Auto generated file - DO NOT EDIT!\n* # Helium Server Type Definitions\n*\n* @helium-methods ${methodSignature}\n**/\n${imports}\n\ndeclare module 'heliumts/server' {\n // Method stubs for client-side type inference\n${methodExports}\n}\n`;\n}\n\nexport function generateEntryModule(): string {\n return `\nimport React from 'react';\nimport { createRoot, hydrateRoot } from 'react-dom/client';\nimport { AppRouter } from 'heliumts/client';\nimport App from '/src/App';\n\n// Merge runtime public env vars injected by the production server.\n// This ensures platform env vars (Render, DigitalOcean Apps, etc.) are\n// available via import.meta.env even if they weren't present at build time.\nif (typeof window !== 'undefined' && window.__HELIUM_PUBLIC_ENV__) {\n Object.assign(import.meta.env, window.__HELIUM_PUBLIC_ENV__);\n}\n\nconst rootEl = document.getElementById('root');\nif (!rootEl) {\n throw new Error('Root element not found. Helium requires a <div id=\"root\"></div> in your HTML.');\n}\n\nconst app = (\n <React.StrictMode>\n <AppRouter AppShell={App} />\n </React.StrictMode>\n);\n\nif (rootEl.hasChildNodes()) {\n hydrateRoot(rootEl, app);\n} else {\n createRoot(rootEl).render(app);\n}\n`;\n}\n"]}
|