@blinkk/root 1.0.5 → 1.0.7
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/{chunk-MLPPFGKW.js → chunk-BMKSXG4B.js} +2 -2
- package/dist/{chunk-MLPPFGKW.js.map → chunk-BMKSXG4B.js.map} +1 -1
- package/dist/{chunk-YKQ4SVXX.js → chunk-G5ALYSEQ.js} +2 -2
- package/dist/{chunk-U2COJCIX.js → chunk-GNRN2XDJ.js} +156 -65
- package/dist/chunk-GNRN2XDJ.js.map +1 -0
- package/dist/{chunk-6JZGMQBR.js → chunk-WICFYADD.js} +1 -1
- package/dist/chunk-WICFYADD.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +4 -4
- package/dist/core.d.ts +2 -2
- package/dist/core.js +1 -1
- package/dist/functions.js +4 -4
- package/dist/middleware.d.ts +2 -2
- package/dist/middleware.js +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +2 -2
- package/dist/render.d.ts +1 -1
- package/dist/render.js +13 -2
- package/dist/render.js.map +1 -1
- package/dist/{types-yoz1mf3y.d.ts → types-E50PeqBX.d.ts} +11 -1
- package/package.json +1 -1
- package/dist/chunk-6JZGMQBR.js.map +0 -1
- package/dist/chunk-U2COJCIX.js.map +0 -1
- /package/dist/{chunk-YKQ4SVXX.js.map → chunk-G5ALYSEQ.js.map} +0 -0
|
@@ -143,7 +143,7 @@ function sessionMiddleware(options) {
|
|
|
143
143
|
sameSite
|
|
144
144
|
});
|
|
145
145
|
};
|
|
146
|
-
req.hooks.add("
|
|
146
|
+
req.hooks.add("preRender", () => {
|
|
147
147
|
res.saveSession();
|
|
148
148
|
});
|
|
149
149
|
next();
|
|
@@ -200,4 +200,4 @@ export {
|
|
|
200
200
|
sessionMiddleware,
|
|
201
201
|
Session
|
|
202
202
|
};
|
|
203
|
-
//# sourceMappingURL=chunk-
|
|
203
|
+
//# sourceMappingURL=chunk-BMKSXG4B.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/middleware/common.ts","../src/middleware/multipart.ts","../src/middleware/session.ts"],"sourcesContent":["import path from 'node:path';\nimport micromatch from 'micromatch';\nimport {RootConfig} from '../core/config.js';\nimport {Request, Response, NextFunction} from '../core/types.js';\n\n/**\n * Middleware that injects the root.js project config into the request context.\n */\nexport function rootProjectMiddleware(options: {rootConfig: RootConfig}) {\n return (req: Request, _: Response, next: NextFunction) => {\n req.rootConfig = options.rootConfig;\n next();\n };\n}\n\n/**\n * Middleware that injects HTTP headers from the `server.headers` config in\n * root.config.ts.\n */\nexport function headersMiddleware(options: {rootConfig: RootConfig}) {\n const headersUserConfig = options.rootConfig.server?.headers || [];\n // Filter header config values that are invalid.\n const headersConfig = headersUserConfig.filter((headerConfig) => {\n return (\n headerConfig.source &&\n headerConfig.headers &&\n headerConfig.headers.length > 0\n );\n });\n return (req: Request, res: Response, next: NextFunction) => {\n headersConfig.forEach((headerConfig) => {\n if (micromatch.isMatch(req.path, headerConfig.source)) {\n headerConfig.headers.forEach((header) => {\n if (header.key) {\n res.setHeader(String(header.key), String(header.value));\n }\n });\n }\n });\n next();\n };\n}\n\n/**\n * Trailing slash middleware. Handles trailing slash redirects (preserving any\n * query params) using the `server.trailingSlash` config in root.config.ts.\n */\nexport function trailingSlashMiddleware(options: {rootConfig: RootConfig}) {\n const trailingSlash = options.rootConfig.server?.trailingSlash;\n\n return (req: Request, res: Response, next: NextFunction) => {\n // If `trailingSlash: false`, force a trailing slash in the URL.\n if (\n trailingSlash === true &&\n !path.extname(req.path) &&\n !req.path.endsWith('/')\n ) {\n const redirectPath = `${req.path}/`;\n redirectWithQuery(req, res, 301, redirectPath);\n return;\n }\n\n // If `trailingSlash: false`, remove any trailing slash from the URL.\n if (\n trailingSlash === false &&\n !path.extname(req.path) &&\n req.path !== '/' &&\n req.path.endsWith('/')\n ) {\n const redirectPath = removeTrailingSlashes(req.path);\n redirectWithQuery(req, res, 301, redirectPath);\n return;\n }\n\n next();\n };\n}\n\n/**\n * Issues an HTTP redirect, preserving any query params from the original req.\n */\nfunction redirectWithQuery(\n req: Request,\n res: Response,\n redirectCode: number,\n redirectPath: string\n) {\n const queryStr = getQueryStr(req);\n const redirectUrl = queryStr ? `${redirectPath}?${queryStr}` : redirectPath;\n res.redirect(redirectCode, redirectUrl);\n}\n\n/**\n * Returns the query string for a request, or empty string if no query.\n */\nfunction getQueryStr(req: Request): string {\n const qIndex = req.originalUrl.indexOf('?');\n if (qIndex === -1) {\n return '';\n }\n return req.originalUrl.slice(qIndex + 1);\n}\n\n/**\n * Removes trailing slashes from a URL path.\n * Note: A path with only slashes (e.g. `///`) returns `/`.\n */\nfunction removeTrailingSlashes(urlPath: string) {\n while (urlPath.endsWith('/') && urlPath !== '/') {\n urlPath = urlPath.slice(0, -1);\n }\n return urlPath;\n}\n","import busboy from 'busboy';\nimport {RequestHandler} from 'express';\nimport {Request, Response, NextFunction, MultipartFile} from '../core/types.js';\n\nconst DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB\n\n/**\n * Middleware for parsing multipart file uploads that's compatible with the dev\n * server and Firebase Functions.\n *\n * Context:\n * https://stackoverflow.com/questions/47242340/how-to-perform-an-http-file-upload-using-express-on-cloud-functions-for-firebase\n */\nexport function multipartMiddleware(options?: {\n maxFileSize?: number;\n}): RequestHandler {\n const maxFileSize = options?.maxFileSize || DEFAULT_MAX_FILE_SIZE;\n const handler: any = (req: Request, res: Response, next: NextFunction) => {\n const contentType = String(req.headers['content-type'] || '');\n if (\n req.method === 'POST' &&\n contentType.startsWith('multipart/form-data')\n ) {\n const parser = busboy({headers: req.headers});\n\n // Data storage for fields and files\n const fields: {[fieldname: string]: string} = {};\n const files: {[name: string]: MultipartFile} = {};\n\n // Handle field data.\n parser.on('field', (fieldname: string, val: any) => {\n fields[fieldname] = val;\n });\n\n // Handle file data. Files are saved to an in-memory buffer.\n parser.on(\n 'file',\n (\n fieldname: string,\n file: any,\n meta: {\n filename: string;\n encoding: string;\n mimeType: string;\n }\n ) => {\n const {filename, encoding, mimeType: mimetype} = meta;\n const fileChunks: Uint8Array[] = [];\n let totalBytesRead = 0;\n\n file.on('data', (chunk: Uint8Array) => {\n totalBytesRead += chunk.length;\n\n if (totalBytesRead > maxFileSize) {\n // File size exceeds the limit, stop reading.\n console.error(`File size exceeds the limit: ${fieldname}.`);\n file.removeAllListeners('data');\n // Consume and discard remaining data.\n file.resume();\n } else {\n fileChunks.push(chunk);\n }\n });\n\n file.on('end', () => {\n if (totalBytesRead <= maxFileSize) {\n const buffer = Buffer.concat(fileChunks);\n\n files[fieldname] = {\n fieldname,\n buffer,\n originalName: filename,\n encoding,\n mimetype,\n };\n }\n });\n }\n );\n\n // Update `req.body` and `req.files`.\n parser.on('finish', () => {\n req.body = fields;\n req.files = files;\n next();\n });\n\n // Pipe the request to Busboy. On Firebase Functions, `rawBody` contains\n // the multipart request. Otherwise the express request can be piped to\n // the Busboy parser.\n if (req.rawBody) {\n parser.end(req.rawBody);\n } else {\n req.pipe(parser);\n }\n } else {\n next();\n }\n };\n return handler;\n}\n","import {NextFunction, Request, Response} from '../core/types.js';\n\nexport const SESSION_COOKIE = '__session';\n\n// 5 days.\nconst DEFAULT_MAX_AGE = 60 * 60 * 24 * 5 * 1000;\n\nexport interface SessionMiddlewareOptions {\n maxAge?: number;\n}\n\nexport interface SaveSessionOptions {\n sameSite?: 'strict' | 'lax' | 'none';\n}\n\n/**\n * Middleware for storing session data stored in an http cookie called\n * `__session`. This cookie is compatible with Firebase Hosting:\n * https://firebase.google.com/docs/hosting/manage-cache#using_cookies\n */\nexport function sessionMiddleware(options?: SessionMiddlewareOptions) {\n const maxAge = options?.maxAge || DEFAULT_MAX_AGE;\n return (req: Request, res: Response, next: NextFunction) => {\n const cookieValue = String(req.signedCookies[SESSION_COOKIE] || '');\n const session = Session.fromCookieValue(cookieValue);\n req.session = session;\n res.session = session;\n res.saveSession = (saveSessionOptions?: SaveSessionOptions) => {\n // \"secure\" cookies require https, so disable \"secure\" when in development.\n const secureCookie = Boolean(process.env.NODE_ENV !== 'development');\n const cookieValue = session.toString();\n const sameSite = saveSessionOptions?.sameSite || 'strict';\n res.cookie(SESSION_COOKIE, cookieValue, {\n maxAge: maxAge,\n httpOnly: true,\n secure: secureCookie,\n signed: true,\n sameSite: sameSite,\n });\n };\n req.hooks.add('beforeRender', () => {\n res.saveSession();\n });\n next();\n };\n}\n\nexport class Session {\n private data: Record<string, string> = {};\n\n constructor(data?: Record<string, string>) {\n this.data = data || {};\n }\n\n static fromCookieValue(cookieValue: string) {\n const data: Record<string, string> = {};\n if (cookieValue.startsWith('b64:')) {\n try {\n const encodedStr = cookieValue.slice(4);\n const params = new URLSearchParams(base64Decode(encodedStr));\n for (const [key, value] of params.entries()) {\n data[key] = value;\n }\n } catch (err) {\n console.warn('failed to parse session cookie:', err);\n return new Session();\n }\n }\n return new Session(data);\n }\n\n getItem(key: string): string | null {\n return this.data[key] ?? null;\n }\n\n setItem(key: string, value: string) {\n this.data[key] = value;\n }\n\n removeItem(key: string) {\n delete this.data[key];\n }\n\n toString(): string {\n const params = new URLSearchParams(this.data);\n return `b64:${base64Encode(params.toString())}`;\n }\n}\n\nfunction base64Encode(str: string): string {\n return Buffer.from(str, 'utf-8').toString('base64');\n}\n\nfunction base64Decode(str: string): string {\n return Buffer.from(str, 'base64').toString('utf-8');\n}\n"],"mappings":"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","names":["cookieValue"]}
|
|
1
|
+
{"version":3,"sources":["../src/middleware/common.ts","../src/middleware/multipart.ts","../src/middleware/session.ts"],"sourcesContent":["import path from 'node:path';\nimport micromatch from 'micromatch';\nimport {RootConfig} from '../core/config.js';\nimport {Request, Response, NextFunction} from '../core/types.js';\n\n/**\n * Middleware that injects the root.js project config into the request context.\n */\nexport function rootProjectMiddleware(options: {rootConfig: RootConfig}) {\n return (req: Request, _: Response, next: NextFunction) => {\n req.rootConfig = options.rootConfig;\n next();\n };\n}\n\n/**\n * Middleware that injects HTTP headers from the `server.headers` config in\n * root.config.ts.\n */\nexport function headersMiddleware(options: {rootConfig: RootConfig}) {\n const headersUserConfig = options.rootConfig.server?.headers || [];\n // Filter header config values that are invalid.\n const headersConfig = headersUserConfig.filter((headerConfig) => {\n return (\n headerConfig.source &&\n headerConfig.headers &&\n headerConfig.headers.length > 0\n );\n });\n return (req: Request, res: Response, next: NextFunction) => {\n headersConfig.forEach((headerConfig) => {\n if (micromatch.isMatch(req.path, headerConfig.source)) {\n headerConfig.headers.forEach((header) => {\n if (header.key) {\n res.setHeader(String(header.key), String(header.value));\n }\n });\n }\n });\n next();\n };\n}\n\n/**\n * Trailing slash middleware. Handles trailing slash redirects (preserving any\n * query params) using the `server.trailingSlash` config in root.config.ts.\n */\nexport function trailingSlashMiddleware(options: {rootConfig: RootConfig}) {\n const trailingSlash = options.rootConfig.server?.trailingSlash;\n\n return (req: Request, res: Response, next: NextFunction) => {\n // If `trailingSlash: false`, force a trailing slash in the URL.\n if (\n trailingSlash === true &&\n !path.extname(req.path) &&\n !req.path.endsWith('/')\n ) {\n const redirectPath = `${req.path}/`;\n redirectWithQuery(req, res, 301, redirectPath);\n return;\n }\n\n // If `trailingSlash: false`, remove any trailing slash from the URL.\n if (\n trailingSlash === false &&\n !path.extname(req.path) &&\n req.path !== '/' &&\n req.path.endsWith('/')\n ) {\n const redirectPath = removeTrailingSlashes(req.path);\n redirectWithQuery(req, res, 301, redirectPath);\n return;\n }\n\n next();\n };\n}\n\n/**\n * Issues an HTTP redirect, preserving any query params from the original req.\n */\nfunction redirectWithQuery(\n req: Request,\n res: Response,\n redirectCode: number,\n redirectPath: string\n) {\n const queryStr = getQueryStr(req);\n const redirectUrl = queryStr ? `${redirectPath}?${queryStr}` : redirectPath;\n res.redirect(redirectCode, redirectUrl);\n}\n\n/**\n * Returns the query string for a request, or empty string if no query.\n */\nfunction getQueryStr(req: Request): string {\n const qIndex = req.originalUrl.indexOf('?');\n if (qIndex === -1) {\n return '';\n }\n return req.originalUrl.slice(qIndex + 1);\n}\n\n/**\n * Removes trailing slashes from a URL path.\n * Note: A path with only slashes (e.g. `///`) returns `/`.\n */\nfunction removeTrailingSlashes(urlPath: string) {\n while (urlPath.endsWith('/') && urlPath !== '/') {\n urlPath = urlPath.slice(0, -1);\n }\n return urlPath;\n}\n","import busboy from 'busboy';\nimport {RequestHandler} from 'express';\nimport {Request, Response, NextFunction, MultipartFile} from '../core/types.js';\n\nconst DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB\n\n/**\n * Middleware for parsing multipart file uploads that's compatible with the dev\n * server and Firebase Functions.\n *\n * Context:\n * https://stackoverflow.com/questions/47242340/how-to-perform-an-http-file-upload-using-express-on-cloud-functions-for-firebase\n */\nexport function multipartMiddleware(options?: {\n maxFileSize?: number;\n}): RequestHandler {\n const maxFileSize = options?.maxFileSize || DEFAULT_MAX_FILE_SIZE;\n const handler: any = (req: Request, res: Response, next: NextFunction) => {\n const contentType = String(req.headers['content-type'] || '');\n if (\n req.method === 'POST' &&\n contentType.startsWith('multipart/form-data')\n ) {\n const parser = busboy({headers: req.headers});\n\n // Data storage for fields and files\n const fields: {[fieldname: string]: string} = {};\n const files: {[name: string]: MultipartFile} = {};\n\n // Handle field data.\n parser.on('field', (fieldname: string, val: any) => {\n fields[fieldname] = val;\n });\n\n // Handle file data. Files are saved to an in-memory buffer.\n parser.on(\n 'file',\n (\n fieldname: string,\n file: any,\n meta: {\n filename: string;\n encoding: string;\n mimeType: string;\n }\n ) => {\n const {filename, encoding, mimeType: mimetype} = meta;\n const fileChunks: Uint8Array[] = [];\n let totalBytesRead = 0;\n\n file.on('data', (chunk: Uint8Array) => {\n totalBytesRead += chunk.length;\n\n if (totalBytesRead > maxFileSize) {\n // File size exceeds the limit, stop reading.\n console.error(`File size exceeds the limit: ${fieldname}.`);\n file.removeAllListeners('data');\n // Consume and discard remaining data.\n file.resume();\n } else {\n fileChunks.push(chunk);\n }\n });\n\n file.on('end', () => {\n if (totalBytesRead <= maxFileSize) {\n const buffer = Buffer.concat(fileChunks);\n\n files[fieldname] = {\n fieldname,\n buffer,\n originalName: filename,\n encoding,\n mimetype,\n };\n }\n });\n }\n );\n\n // Update `req.body` and `req.files`.\n parser.on('finish', () => {\n req.body = fields;\n req.files = files;\n next();\n });\n\n // Pipe the request to Busboy. On Firebase Functions, `rawBody` contains\n // the multipart request. Otherwise the express request can be piped to\n // the Busboy parser.\n if (req.rawBody) {\n parser.end(req.rawBody);\n } else {\n req.pipe(parser);\n }\n } else {\n next();\n }\n };\n return handler;\n}\n","import {NextFunction, Request, Response} from '../core/types.js';\n\nexport const SESSION_COOKIE = '__session';\n\n// 5 days.\nconst DEFAULT_MAX_AGE = 60 * 60 * 24 * 5 * 1000;\n\nexport interface SessionMiddlewareOptions {\n maxAge?: number;\n}\n\nexport interface SaveSessionOptions {\n sameSite?: 'strict' | 'lax' | 'none';\n}\n\n/**\n * Middleware for storing session data stored in an http cookie called\n * `__session`. This cookie is compatible with Firebase Hosting:\n * https://firebase.google.com/docs/hosting/manage-cache#using_cookies\n */\nexport function sessionMiddleware(options?: SessionMiddlewareOptions) {\n const maxAge = options?.maxAge || DEFAULT_MAX_AGE;\n return (req: Request, res: Response, next: NextFunction) => {\n const cookieValue = String(req.signedCookies[SESSION_COOKIE] || '');\n const session = Session.fromCookieValue(cookieValue);\n req.session = session;\n res.session = session;\n res.saveSession = (saveSessionOptions?: SaveSessionOptions) => {\n // \"secure\" cookies require https, so disable \"secure\" when in development.\n const secureCookie = Boolean(process.env.NODE_ENV !== 'development');\n const cookieValue = session.toString();\n const sameSite = saveSessionOptions?.sameSite || 'strict';\n res.cookie(SESSION_COOKIE, cookieValue, {\n maxAge: maxAge,\n httpOnly: true,\n secure: secureCookie,\n signed: true,\n sameSite: sameSite,\n });\n };\n req.hooks.add('preRender', () => {\n res.saveSession();\n });\n next();\n };\n}\n\nexport class Session {\n private data: Record<string, string> = {};\n\n constructor(data?: Record<string, string>) {\n this.data = data || {};\n }\n\n static fromCookieValue(cookieValue: string) {\n const data: Record<string, string> = {};\n if (cookieValue.startsWith('b64:')) {\n try {\n const encodedStr = cookieValue.slice(4);\n const params = new URLSearchParams(base64Decode(encodedStr));\n for (const [key, value] of params.entries()) {\n data[key] = value;\n }\n } catch (err) {\n console.warn('failed to parse session cookie:', err);\n return new Session();\n }\n }\n return new Session(data);\n }\n\n getItem(key: string): string | null {\n return this.data[key] ?? null;\n }\n\n setItem(key: string, value: string) {\n this.data[key] = value;\n }\n\n removeItem(key: string) {\n delete this.data[key];\n }\n\n toString(): string {\n const params = new URLSearchParams(this.data);\n return `b64:${base64Encode(params.toString())}`;\n }\n}\n\nfunction base64Encode(str: string): string {\n return Buffer.from(str, 'utf-8').toString('base64');\n}\n\nfunction base64Decode(str: string): string {\n return Buffer.from(str, 'base64').toString('utf-8');\n}\n"],"mappings":"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","names":["cookieValue"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getVitePlugins
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WICFYADD.js";
|
|
4
4
|
|
|
5
5
|
// src/node/load-config.ts
|
|
6
6
|
import path2 from "node:path";
|
|
@@ -264,4 +264,4 @@ export {
|
|
|
264
264
|
createViteServer,
|
|
265
265
|
viteSsrLoadModule
|
|
266
266
|
};
|
|
267
|
-
//# sourceMappingURL=chunk-
|
|
267
|
+
//# sourceMappingURL=chunk-G5ALYSEQ.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
rootProjectMiddleware,
|
|
4
4
|
sessionMiddleware,
|
|
5
5
|
trailingSlashMiddleware
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BMKSXG4B.js";
|
|
7
7
|
import {
|
|
8
8
|
bundleRootConfig,
|
|
9
9
|
copyDir,
|
|
@@ -21,11 +21,11 @@ import {
|
|
|
21
21
|
rmDir,
|
|
22
22
|
writeFile,
|
|
23
23
|
writeJson
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-G5ALYSEQ.js";
|
|
25
25
|
import {
|
|
26
26
|
configureServerPlugins,
|
|
27
27
|
getVitePlugins
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-WICFYADD.js";
|
|
29
29
|
import {
|
|
30
30
|
RouteTrie,
|
|
31
31
|
htmlMinify,
|
|
@@ -687,24 +687,104 @@ function formatParams(params) {
|
|
|
687
687
|
}).join("\n");
|
|
688
688
|
}
|
|
689
689
|
|
|
690
|
-
// src/cli/
|
|
690
|
+
// src/cli/codegen.ts
|
|
691
691
|
import { promises as fs3 } from "node:fs";
|
|
692
692
|
import path4 from "node:path";
|
|
693
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
694
|
+
import glob3 from "tiny-glob";
|
|
695
|
+
var __dirname2 = path4.dirname(fileURLToPath2(import.meta.url));
|
|
696
|
+
async function codegen(type, name, options) {
|
|
697
|
+
const rootDir = path4.resolve(process.cwd());
|
|
698
|
+
const project = new Project(rootDir);
|
|
699
|
+
await project.generateCode(type, name, options);
|
|
700
|
+
}
|
|
701
|
+
var Project = class {
|
|
702
|
+
rootDir;
|
|
703
|
+
tplDirs;
|
|
704
|
+
constructor(rootDir) {
|
|
705
|
+
this.rootDir = rootDir;
|
|
706
|
+
this.tplDirs = [
|
|
707
|
+
path4.join(rootDir, "codegen"),
|
|
708
|
+
path4.join(__dirname2, "../codegen")
|
|
709
|
+
];
|
|
710
|
+
}
|
|
711
|
+
async generateCode(type, name, options) {
|
|
712
|
+
const files = await this.loadFiles(type);
|
|
713
|
+
if (Object.keys(files).length === 0) {
|
|
714
|
+
console.log(`no files in codegen/${type}/*.tpl`);
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
const outname = options?.out || `${type}s`;
|
|
718
|
+
const outdir = path4.join(this.rootDir, outname, name);
|
|
719
|
+
if (await dirExists(outdir)) {
|
|
720
|
+
await rmDir(outdir);
|
|
721
|
+
}
|
|
722
|
+
await makeDir(outdir);
|
|
723
|
+
for (const tplName in files) {
|
|
724
|
+
const tpl = await files[tplName].read();
|
|
725
|
+
const content = tpl.replaceAll("[[name]]", name).replaceAll("[[name:camel_upper]]", toCamelCaseUpper(name));
|
|
726
|
+
const filename = tplName.replace("[name]", name);
|
|
727
|
+
const filepath = path4.join(outdir, filename);
|
|
728
|
+
await writeFile(filepath, content);
|
|
729
|
+
console.log(`saved ${filepath}`);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Searches the project's "codegen" dir (or fallsback to root's "codegen" dir)
|
|
734
|
+
* and returns a `TemplateMap` for all files in `codgen/<type>/*.tpl`.
|
|
735
|
+
*/
|
|
736
|
+
async loadFiles(type) {
|
|
737
|
+
for (const tplDir of this.tplDirs) {
|
|
738
|
+
const typeDir = path4.join(tplDir, type);
|
|
739
|
+
if (await dirExists(typeDir)) {
|
|
740
|
+
return this.loadTplFiles(typeDir);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return {};
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Reads files matching `*.tpl` in a given directory.
|
|
747
|
+
*/
|
|
748
|
+
async loadTplFiles(dirpath) {
|
|
749
|
+
const tplFiles = {};
|
|
750
|
+
const files = await glob3("*.tpl", { cwd: dirpath });
|
|
751
|
+
for (const filename of files) {
|
|
752
|
+
const filepath = path4.join(dirpath, filename);
|
|
753
|
+
const name = filename.slice(0, -4);
|
|
754
|
+
tplFiles[name] = {
|
|
755
|
+
read: () => fs3.readFile(filepath, "utf-8")
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
return tplFiles;
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
function toCamelCaseUpper(str) {
|
|
762
|
+
const segments = str.split("-");
|
|
763
|
+
return segments.map((part) => toTitleCase(part)).join("");
|
|
764
|
+
}
|
|
765
|
+
function toTitleCase(str) {
|
|
766
|
+
const ch = String(str).charAt(0).toUpperCase();
|
|
767
|
+
return `${ch}${str.slice(1)}`;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// src/cli/create-package.ts
|
|
771
|
+
import { promises as fs4 } from "node:fs";
|
|
772
|
+
import path5 from "node:path";
|
|
693
773
|
import { build as esbuild } from "esbuild";
|
|
694
774
|
async function createPackage(rootProjectDir, options) {
|
|
695
775
|
const mode = options?.mode || "production";
|
|
696
776
|
process.env.NODE_ENV = mode;
|
|
697
|
-
const rootDir =
|
|
698
|
-
const distDir =
|
|
777
|
+
const rootDir = path5.resolve(rootProjectDir || process.cwd());
|
|
778
|
+
const distDir = path5.join(rootDir, "dist");
|
|
699
779
|
const target = options?.target || await getDefaultTarget(rootDir);
|
|
700
|
-
const outDir =
|
|
780
|
+
const outDir = path5.resolve(options?.out || target || "out");
|
|
701
781
|
await build(rootProjectDir, { ssrOnly: true, mode });
|
|
702
782
|
await rmDir(outDir);
|
|
703
783
|
await makeDir(outDir);
|
|
704
|
-
await copyDir(distDir,
|
|
705
|
-
const collectionsDir =
|
|
784
|
+
await copyDir(distDir, path5.resolve(outDir, "dist"));
|
|
785
|
+
const collectionsDir = path5.resolve(rootDir, "collections");
|
|
706
786
|
if (await dirExists(collectionsDir)) {
|
|
707
|
-
await copyDir(collectionsDir,
|
|
787
|
+
await copyDir(collectionsDir, path5.join(outDir, "collections"));
|
|
708
788
|
}
|
|
709
789
|
const packageJson = await generatePackageJson(rootDir);
|
|
710
790
|
if (options?.version && packageJson.dependencies) {
|
|
@@ -723,16 +803,16 @@ async function createPackage(rootProjectDir, options) {
|
|
|
723
803
|
} else if (target === "firebase") {
|
|
724
804
|
await onFirebase({ rootDir, packageJson, outDir });
|
|
725
805
|
}
|
|
726
|
-
await writeJson(
|
|
806
|
+
await writeJson(path5.resolve(outDir, "package.json"), packageJson);
|
|
727
807
|
console.log("done!");
|
|
728
808
|
console.log(`saved package to ${outDir}`);
|
|
729
809
|
}
|
|
730
810
|
async function getDefaultTarget(rootDir) {
|
|
731
|
-
const firebaseConfigPath =
|
|
811
|
+
const firebaseConfigPath = path5.resolve(rootDir, "firebase.json");
|
|
732
812
|
if (await fileExists(firebaseConfigPath)) {
|
|
733
813
|
return "firebase";
|
|
734
814
|
}
|
|
735
|
-
const appEngineConfigPath =
|
|
815
|
+
const appEngineConfigPath = path5.resolve(rootDir, "app.yaml");
|
|
736
816
|
if (await fileExists(appEngineConfigPath)) {
|
|
737
817
|
return "appengine";
|
|
738
818
|
}
|
|
@@ -740,7 +820,7 @@ async function getDefaultTarget(rootDir) {
|
|
|
740
820
|
}
|
|
741
821
|
async function generatePackageJson(rootDir) {
|
|
742
822
|
const packageJson = await loadJson(
|
|
743
|
-
|
|
823
|
+
path5.resolve(rootDir, "package.json")
|
|
744
824
|
);
|
|
745
825
|
if (packageJson.peerDependencies) {
|
|
746
826
|
await updatePeerDepsFromWorkspace(rootDir, packageJson);
|
|
@@ -756,7 +836,7 @@ async function updatePeerDepsFromWorkspace(rootDir, packageJson) {
|
|
|
756
836
|
if (!workspaceRoot) {
|
|
757
837
|
return;
|
|
758
838
|
}
|
|
759
|
-
const workspacePackageJsonPath =
|
|
839
|
+
const workspacePackageJsonPath = path5.resolve(workspaceRoot, "package.json");
|
|
760
840
|
const workspacePackageJson = await loadJson(
|
|
761
841
|
workspacePackageJsonPath
|
|
762
842
|
);
|
|
@@ -779,15 +859,15 @@ async function updatePeerDepsFromWorkspace(rootDir, packageJson) {
|
|
|
779
859
|
}
|
|
780
860
|
}
|
|
781
861
|
async function findWorkspaceRoot(rootDir) {
|
|
782
|
-
const parentDir =
|
|
862
|
+
const parentDir = path5.dirname(rootDir);
|
|
783
863
|
if (parentDir === "/") {
|
|
784
864
|
return null;
|
|
785
865
|
}
|
|
786
|
-
const pnpmWorkspaceFile =
|
|
866
|
+
const pnpmWorkspaceFile = path5.resolve(parentDir, "pnpm-workspace.yaml");
|
|
787
867
|
if (await fileExists(pnpmWorkspaceFile)) {
|
|
788
868
|
return parentDir;
|
|
789
869
|
}
|
|
790
|
-
const packageJsonPath =
|
|
870
|
+
const packageJsonPath = path5.resolve(parentDir, "package.json");
|
|
791
871
|
if (await fileExists(packageJsonPath)) {
|
|
792
872
|
const parentPackageJson = await loadJson(packageJsonPath);
|
|
793
873
|
if (parentPackageJson && parentPackageJson.workspaces) {
|
|
@@ -809,21 +889,31 @@ function getRequiredPeerDeps(packageJson) {
|
|
|
809
889
|
return requiredPeerDeps;
|
|
810
890
|
}
|
|
811
891
|
async function onAppEngine(options) {
|
|
812
|
-
const { rootDir, outDir } = options;
|
|
813
|
-
const configPath =
|
|
892
|
+
const { rootDir, outDir, packageJson } = options;
|
|
893
|
+
const configPath = path5.resolve(rootDir, "app.yaml");
|
|
814
894
|
if (await fileExists(configPath)) {
|
|
815
|
-
await
|
|
895
|
+
await fs4.copyFile(configPath, path5.resolve(outDir, "app.yaml"));
|
|
896
|
+
}
|
|
897
|
+
if (packageJson.scripts?.start) {
|
|
898
|
+
packageJson.scripts = { start: packageJson.scripts.start };
|
|
899
|
+
} else {
|
|
900
|
+
packageJson.scripts = { start: "root start --host=0.0.0.0" };
|
|
816
901
|
}
|
|
817
902
|
}
|
|
818
903
|
async function onFirebase(options) {
|
|
819
|
-
const { rootDir, outDir } = options;
|
|
820
|
-
const outBasename =
|
|
904
|
+
const { rootDir, outDir, packageJson } = options;
|
|
905
|
+
const outBasename = path5.basename(outDir);
|
|
821
906
|
if (outBasename === "functions") {
|
|
822
|
-
const indexTsFile =
|
|
907
|
+
const indexTsFile = path5.resolve(rootDir, "index.ts");
|
|
823
908
|
if (await fileExists(indexTsFile)) {
|
|
824
|
-
await bundleTsFile(indexTsFile,
|
|
909
|
+
await bundleTsFile(indexTsFile, path5.resolve(outDir, "index.js"));
|
|
825
910
|
}
|
|
826
911
|
}
|
|
912
|
+
if (packageJson.scripts?.start) {
|
|
913
|
+
packageJson.scripts = { start: packageJson.scripts.start };
|
|
914
|
+
} else {
|
|
915
|
+
packageJson.scripts = { start: "root start --host=0.0.0.0" };
|
|
916
|
+
}
|
|
827
917
|
}
|
|
828
918
|
async function bundleTsFile(srcPath, outPath) {
|
|
829
919
|
await esbuild({
|
|
@@ -841,7 +931,7 @@ async function bundleTsFile(srcPath, outPath) {
|
|
|
841
931
|
setup(build2) {
|
|
842
932
|
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
843
933
|
const id = args.path;
|
|
844
|
-
if (id[0] !== "." && !
|
|
934
|
+
if (id[0] !== "." && !path5.isAbsolute(id)) {
|
|
845
935
|
return {
|
|
846
936
|
external: true
|
|
847
937
|
};
|
|
@@ -855,13 +945,13 @@ async function bundleTsFile(srcPath, outPath) {
|
|
|
855
945
|
}
|
|
856
946
|
|
|
857
947
|
// src/cli/dev.ts
|
|
858
|
-
import
|
|
859
|
-
import { fileURLToPath as
|
|
948
|
+
import path7 from "node:path";
|
|
949
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
860
950
|
import cookieParser from "cookie-parser";
|
|
861
951
|
import { default as express } from "express";
|
|
862
952
|
import { dim as dim2 } from "kleur/colors";
|
|
863
953
|
import sirv from "sirv";
|
|
864
|
-
import
|
|
954
|
+
import glob4 from "tiny-glob";
|
|
865
955
|
|
|
866
956
|
// src/middleware/hooks.ts
|
|
867
957
|
function hooksMiddleware() {
|
|
@@ -930,7 +1020,7 @@ function replaceParams(urlPathFormat, params) {
|
|
|
930
1020
|
}
|
|
931
1021
|
|
|
932
1022
|
// src/render/asset-map/dev-asset-map.ts
|
|
933
|
-
import
|
|
1023
|
+
import path6 from "node:path";
|
|
934
1024
|
import { searchForWorkspaceRoot as searchForWorkspaceRoot2 } from "vite";
|
|
935
1025
|
var DevServerAssetMap = class {
|
|
936
1026
|
rootConfig;
|
|
@@ -940,7 +1030,7 @@ var DevServerAssetMap = class {
|
|
|
940
1030
|
this.moduleGraph = moduleGraph;
|
|
941
1031
|
}
|
|
942
1032
|
async get(src) {
|
|
943
|
-
const file =
|
|
1033
|
+
const file = path6.resolve(this.rootConfig.rootDir, src);
|
|
944
1034
|
const viteModules = this.moduleGraph.getModulesByFile(file);
|
|
945
1035
|
if (viteModules && viteModules.size > 0) {
|
|
946
1036
|
const [viteModule] = viteModules;
|
|
@@ -972,7 +1062,7 @@ var DevServerAssetMap = class {
|
|
|
972
1062
|
return null;
|
|
973
1063
|
}
|
|
974
1064
|
filePathToSrc(file) {
|
|
975
|
-
return
|
|
1065
|
+
return path6.relative(this.rootConfig.rootDir, file);
|
|
976
1066
|
}
|
|
977
1067
|
};
|
|
978
1068
|
var DevServerAsset = class _DevServerAsset {
|
|
@@ -1014,7 +1104,7 @@ var DevServerAsset = class _DevServerAsset {
|
|
|
1014
1104
|
return;
|
|
1015
1105
|
}
|
|
1016
1106
|
visited.add(asset.moduleId);
|
|
1017
|
-
const parts =
|
|
1107
|
+
const parts = path6.parse(asset.assetUrl);
|
|
1018
1108
|
if ([".js", ".jsx", ".ts", ".tsx"].includes(parts.ext) && asset.moduleId.includes("/elements/")) {
|
|
1019
1109
|
urls.add(asset.assetUrl);
|
|
1020
1110
|
}
|
|
@@ -1041,7 +1131,7 @@ var DevServerAsset = class _DevServerAsset {
|
|
|
1041
1131
|
}
|
|
1042
1132
|
visited.add(asset.assetUrl);
|
|
1043
1133
|
if (asset.src.endsWith(".scss")) {
|
|
1044
|
-
const parts =
|
|
1134
|
+
const parts = path6.parse(asset.src);
|
|
1045
1135
|
if (!parts.name.startsWith("_")) {
|
|
1046
1136
|
urls.add(asset.assetUrl);
|
|
1047
1137
|
}
|
|
@@ -1108,10 +1198,10 @@ function randString(len) {
|
|
|
1108
1198
|
}
|
|
1109
1199
|
|
|
1110
1200
|
// src/cli/dev.ts
|
|
1111
|
-
var
|
|
1201
|
+
var __dirname3 = path7.dirname(fileURLToPath3(import.meta.url));
|
|
1112
1202
|
async function dev(rootProjectDir, options) {
|
|
1113
1203
|
process.env.NODE_ENV = "development";
|
|
1114
|
-
const rootDir =
|
|
1204
|
+
const rootDir = path7.resolve(rootProjectDir || process.cwd());
|
|
1115
1205
|
const defaultPort = parseInt(process.env.PORT || "4007");
|
|
1116
1206
|
const host = options?.host || "localhost";
|
|
1117
1207
|
const port = await findOpenPort(defaultPort, defaultPort + 10);
|
|
@@ -1129,7 +1219,7 @@ async function dev(rootProjectDir, options) {
|
|
|
1129
1219
|
server.listen(port, host);
|
|
1130
1220
|
}
|
|
1131
1221
|
async function createDevServer(options) {
|
|
1132
|
-
const rootDir =
|
|
1222
|
+
const rootDir = path7.resolve(options?.rootDir || process.cwd());
|
|
1133
1223
|
const rootConfig = await loadRootConfig(rootDir, { command: "dev" });
|
|
1134
1224
|
const port = options?.port;
|
|
1135
1225
|
const server = express();
|
|
@@ -1162,7 +1252,7 @@ async function createDevServer(options) {
|
|
|
1162
1252
|
if (rootConfig.server?.headers) {
|
|
1163
1253
|
server.use(headersMiddleware({ rootConfig }));
|
|
1164
1254
|
}
|
|
1165
|
-
const publicDir =
|
|
1255
|
+
const publicDir = path7.join(rootDir, "public");
|
|
1166
1256
|
if (await dirExists(publicDir)) {
|
|
1167
1257
|
server.use(rootPublicDirMiddleware({ publicDir, viteServer }));
|
|
1168
1258
|
}
|
|
@@ -1184,10 +1274,10 @@ async function createViteMiddleware(options) {
|
|
|
1184
1274
|
return sourceFile.relPath;
|
|
1185
1275
|
});
|
|
1186
1276
|
const bundleScripts = [];
|
|
1187
|
-
if (await isDirectory(
|
|
1188
|
-
const bundleFiles = await
|
|
1277
|
+
if (await isDirectory(path7.join(rootDir, "bundles"))) {
|
|
1278
|
+
const bundleFiles = await glob4("bundles/*", { cwd: rootDir });
|
|
1189
1279
|
bundleFiles.forEach((file) => {
|
|
1190
|
-
const parts =
|
|
1280
|
+
const parts = path7.parse(file);
|
|
1191
1281
|
if (isJsFile(parts.base)) {
|
|
1192
1282
|
bundleScripts.push(file);
|
|
1193
1283
|
}
|
|
@@ -1199,7 +1289,7 @@ async function createViteMiddleware(options) {
|
|
|
1199
1289
|
optimizeDeps
|
|
1200
1290
|
});
|
|
1201
1291
|
function isInElementsDir(changedFilePath) {
|
|
1202
|
-
const filePath =
|
|
1292
|
+
const filePath = path7.resolve(changedFilePath);
|
|
1203
1293
|
const elementsDirs = getElementsDirs(rootConfig);
|
|
1204
1294
|
return elementsDirs.some((dirPath) => filePath.startsWith(dirPath));
|
|
1205
1295
|
}
|
|
@@ -1218,7 +1308,7 @@ async function createViteMiddleware(options) {
|
|
|
1218
1308
|
const viteMiddleware = async (req, res, next) => {
|
|
1219
1309
|
try {
|
|
1220
1310
|
req.viteServer = viteServer;
|
|
1221
|
-
const renderModulePath =
|
|
1311
|
+
const renderModulePath = path7.resolve(__dirname3, "./render.js");
|
|
1222
1312
|
const render = await viteServer.ssrLoadModule(
|
|
1223
1313
|
renderModulePath
|
|
1224
1314
|
);
|
|
@@ -1242,7 +1332,7 @@ function rootPublicDirMiddleware(options) {
|
|
|
1242
1332
|
handler = sirv(publicDir, sirvOptions);
|
|
1243
1333
|
}, 1e3);
|
|
1244
1334
|
function isInPublicDir(changedFilePath) {
|
|
1245
|
-
const filePath =
|
|
1335
|
+
const filePath = path7.resolve(changedFilePath);
|
|
1246
1336
|
return filePath.startsWith(publicDir);
|
|
1247
1337
|
}
|
|
1248
1338
|
const watcher = options.viteServer.watcher;
|
|
@@ -1272,7 +1362,7 @@ function rootDevServer404Middleware() {
|
|
|
1272
1362
|
console.error(`\u2753 404 ${req.originalUrl}`);
|
|
1273
1363
|
if (req.renderer) {
|
|
1274
1364
|
const url = req.path;
|
|
1275
|
-
const ext =
|
|
1365
|
+
const ext = path7.extname(url);
|
|
1276
1366
|
if (!ext) {
|
|
1277
1367
|
const renderer = req.renderer;
|
|
1278
1368
|
const data = await renderer.renderDevServer404(req);
|
|
@@ -1290,7 +1380,7 @@ function rootDevServer500Middleware() {
|
|
|
1290
1380
|
console.error(String(err.stack || err));
|
|
1291
1381
|
if (req.renderer) {
|
|
1292
1382
|
const url = req.path;
|
|
1293
|
-
const ext =
|
|
1383
|
+
const ext = path7.extname(url);
|
|
1294
1384
|
if (!ext) {
|
|
1295
1385
|
const renderer = req.renderer;
|
|
1296
1386
|
const data = await renderer.renderDevServer500(req, err);
|
|
@@ -1315,7 +1405,7 @@ function debounce(fn, timeout) {
|
|
|
1315
1405
|
}
|
|
1316
1406
|
|
|
1317
1407
|
// src/cli/preview.ts
|
|
1318
|
-
import
|
|
1408
|
+
import path8 from "node:path";
|
|
1319
1409
|
import compression from "compression";
|
|
1320
1410
|
import cookieParser2 from "cookie-parser";
|
|
1321
1411
|
import { default as express2 } from "express";
|
|
@@ -1323,7 +1413,7 @@ import { dim as dim3 } from "kleur/colors";
|
|
|
1323
1413
|
import sirv2 from "sirv";
|
|
1324
1414
|
async function preview(rootProjectDir, options) {
|
|
1325
1415
|
process.env.NODE_ENV = "development";
|
|
1326
|
-
const rootDir =
|
|
1416
|
+
const rootDir = path8.resolve(rootProjectDir || process.cwd());
|
|
1327
1417
|
const server = await createPreviewServer({ rootDir });
|
|
1328
1418
|
const port = parseInt(process.env.PORT || "4007");
|
|
1329
1419
|
const host = options?.host || "localhost";
|
|
@@ -1337,7 +1427,7 @@ async function preview(rootProjectDir, options) {
|
|
|
1337
1427
|
async function createPreviewServer(options) {
|
|
1338
1428
|
const rootDir = options.rootDir;
|
|
1339
1429
|
const rootConfig = await loadBundledConfig(rootDir, { command: "preview" });
|
|
1340
|
-
const distDir =
|
|
1430
|
+
const distDir = path8.join(rootDir, "dist");
|
|
1341
1431
|
const server = express2();
|
|
1342
1432
|
server.disable("x-powered-by");
|
|
1343
1433
|
server.use(compression());
|
|
@@ -1363,7 +1453,7 @@ async function createPreviewServer(options) {
|
|
|
1363
1453
|
if (rootConfig.server?.headers) {
|
|
1364
1454
|
server.use(headersMiddleware({ rootConfig }));
|
|
1365
1455
|
}
|
|
1366
|
-
const publicDir =
|
|
1456
|
+
const publicDir = path8.join(distDir, "html");
|
|
1367
1457
|
server.use(sirv2(publicDir, { dev: false }));
|
|
1368
1458
|
server.use(trailingSlashMiddleware({ rootConfig }));
|
|
1369
1459
|
server.use(rootPreviewServerMiddleware());
|
|
@@ -1377,14 +1467,14 @@ async function createPreviewServer(options) {
|
|
|
1377
1467
|
}
|
|
1378
1468
|
async function rootPreviewRendererMiddleware(options) {
|
|
1379
1469
|
const { distDir, rootConfig } = options;
|
|
1380
|
-
const render = await import(
|
|
1381
|
-
const manifestPath =
|
|
1470
|
+
const render = await import(path8.join(distDir, "server/render.js"));
|
|
1471
|
+
const manifestPath = path8.join(distDir, ".root/manifest.json");
|
|
1382
1472
|
if (!await fileExists(manifestPath)) {
|
|
1383
1473
|
throw new Error(
|
|
1384
1474
|
`could not find ${manifestPath}. run \`root build\` before \`root preview\`.`
|
|
1385
1475
|
);
|
|
1386
1476
|
}
|
|
1387
|
-
const elementGraphJsonPath =
|
|
1477
|
+
const elementGraphJsonPath = path8.join(distDir, ".root/elements.json");
|
|
1388
1478
|
if (!await fileExists(elementGraphJsonPath)) {
|
|
1389
1479
|
throw new Error(
|
|
1390
1480
|
`could not find ${elementGraphJsonPath}. run \`root build\` before \`root preview\`.`
|
|
@@ -1424,7 +1514,7 @@ function rootPreviewServer404Middleware() {
|
|
|
1424
1514
|
console.error(`\u2753 404 ${req.originalUrl}`);
|
|
1425
1515
|
if (req.renderer) {
|
|
1426
1516
|
const url = req.path;
|
|
1427
|
-
const ext =
|
|
1517
|
+
const ext = path8.extname(url);
|
|
1428
1518
|
if (!ext) {
|
|
1429
1519
|
const renderer = req.renderer;
|
|
1430
1520
|
const data = await renderer.render404({ currentPath: url });
|
|
@@ -1442,7 +1532,7 @@ function rootPreviewServer500Middleware() {
|
|
|
1442
1532
|
console.error(String(err.stack || err));
|
|
1443
1533
|
if (req.renderer) {
|
|
1444
1534
|
const url = req.path;
|
|
1445
|
-
const ext =
|
|
1535
|
+
const ext = path8.extname(url);
|
|
1446
1536
|
if (!ext) {
|
|
1447
1537
|
const renderer = req.renderer;
|
|
1448
1538
|
const data = await renderer.renderDevServer500(req, err);
|
|
@@ -1456,7 +1546,7 @@ function rootPreviewServer500Middleware() {
|
|
|
1456
1546
|
}
|
|
1457
1547
|
|
|
1458
1548
|
// src/cli/start.ts
|
|
1459
|
-
import
|
|
1549
|
+
import path9 from "node:path";
|
|
1460
1550
|
import compression2 from "compression";
|
|
1461
1551
|
import cookieParser3 from "cookie-parser";
|
|
1462
1552
|
import { default as express3 } from "express";
|
|
@@ -1464,7 +1554,7 @@ import { dim as dim4 } from "kleur/colors";
|
|
|
1464
1554
|
import sirv3 from "sirv";
|
|
1465
1555
|
async function start(rootProjectDir, options) {
|
|
1466
1556
|
process.env.NODE_ENV = "production";
|
|
1467
|
-
const rootDir =
|
|
1557
|
+
const rootDir = path9.resolve(rootProjectDir || process.cwd());
|
|
1468
1558
|
const server = await createProdServer({ rootDir });
|
|
1469
1559
|
const port = parseInt(process.env.PORT || "4007");
|
|
1470
1560
|
const host = options?.host || "localhost";
|
|
@@ -1478,7 +1568,7 @@ async function start(rootProjectDir, options) {
|
|
|
1478
1568
|
async function createProdServer(options) {
|
|
1479
1569
|
const rootDir = options.rootDir;
|
|
1480
1570
|
const rootConfig = await loadBundledConfig(rootDir, { command: "start" });
|
|
1481
|
-
const distDir =
|
|
1571
|
+
const distDir = path9.join(rootDir, "dist");
|
|
1482
1572
|
const server = express3();
|
|
1483
1573
|
server.disable("x-powered-by");
|
|
1484
1574
|
server.use(compression2());
|
|
@@ -1504,7 +1594,7 @@ async function createProdServer(options) {
|
|
|
1504
1594
|
if (rootConfig.server?.headers) {
|
|
1505
1595
|
server.use(headersMiddleware({ rootConfig }));
|
|
1506
1596
|
}
|
|
1507
|
-
const publicDir =
|
|
1597
|
+
const publicDir = path9.join(distDir, "html");
|
|
1508
1598
|
server.use(sirv3(publicDir, { dev: false }));
|
|
1509
1599
|
server.use(trailingSlashMiddleware({ rootConfig }));
|
|
1510
1600
|
server.use(rootProdServerMiddleware());
|
|
@@ -1518,14 +1608,14 @@ async function createProdServer(options) {
|
|
|
1518
1608
|
}
|
|
1519
1609
|
async function rootProdRendererMiddleware(options) {
|
|
1520
1610
|
const { distDir, rootConfig } = options;
|
|
1521
|
-
const render = await import(
|
|
1522
|
-
const manifestPath =
|
|
1611
|
+
const render = await import(path9.join(distDir, "server/render.js"));
|
|
1612
|
+
const manifestPath = path9.join(distDir, ".root/manifest.json");
|
|
1523
1613
|
if (!await fileExists(manifestPath)) {
|
|
1524
1614
|
throw new Error(
|
|
1525
1615
|
`could not find ${manifestPath}. run \`root build\` before \`root start\`.`
|
|
1526
1616
|
);
|
|
1527
1617
|
}
|
|
1528
|
-
const elementGraphJsonPath =
|
|
1618
|
+
const elementGraphJsonPath = path9.join(distDir, ".root/elements.json");
|
|
1529
1619
|
if (!await fileExists(elementGraphJsonPath)) {
|
|
1530
1620
|
throw new Error(
|
|
1531
1621
|
`could not find ${elementGraphJsonPath}. run \`root build\` before \`root start\`.`
|
|
@@ -1565,7 +1655,7 @@ function rootProdServer404Middleware() {
|
|
|
1565
1655
|
console.error(`\u2753 404 ${req.originalUrl}`);
|
|
1566
1656
|
if (req.renderer) {
|
|
1567
1657
|
const url = req.path;
|
|
1568
|
-
const ext =
|
|
1658
|
+
const ext = path9.extname(url);
|
|
1569
1659
|
if (!ext) {
|
|
1570
1660
|
const renderer = req.renderer;
|
|
1571
1661
|
const data = await renderer.render404({ currentPath: url });
|
|
@@ -1583,7 +1673,7 @@ function rootProdServer500Middleware() {
|
|
|
1583
1673
|
console.error(String(err.stack || err));
|
|
1584
1674
|
if (req.renderer) {
|
|
1585
1675
|
const url = req.path;
|
|
1586
|
-
const ext =
|
|
1676
|
+
const ext = path9.extname(url);
|
|
1587
1677
|
if (!ext) {
|
|
1588
1678
|
const renderer = req.renderer;
|
|
1589
1679
|
const data = await renderer.renderError(err);
|
|
@@ -1625,6 +1715,7 @@ var CliRunner = class {
|
|
|
1625
1715
|
"number of files to build concurrently",
|
|
1626
1716
|
"10"
|
|
1627
1717
|
).action(build);
|
|
1718
|
+
program.command("codegen [type] [name]").description("generates boilerplate code").option("--out <outdir>", "output dir").action(codegen);
|
|
1628
1719
|
program.command("create-package [path]").alias("package").description(
|
|
1629
1720
|
"creates a standalone npm package for deployment to various hosting services"
|
|
1630
1721
|
).option("--target <target>", "hosting target, i.e. appengine or firebase").option("--out <outdir>", "output dir").option("--mode <mode>", "deployment mode, i.e. production or preview").action((rootPackageDir, options) => {
|
|
@@ -1658,4 +1749,4 @@ export {
|
|
|
1658
1749
|
createProdServer,
|
|
1659
1750
|
CliRunner
|
|
1660
1751
|
};
|
|
1661
|
-
//# sourceMappingURL=chunk-
|
|
1752
|
+
//# sourceMappingURL=chunk-GNRN2XDJ.js.map
|