@blinkk/root 1.0.0-beta.5 → 1.0.0-beta.51

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/render/render.tsx","../src/render/router.ts","../src/render/route-trie.ts","../src/core/pages/ErrorPage.tsx","../src/core/pages/DevNotFoundPage.tsx","../src/core/pages/DevErrorPage.tsx"],"sourcesContent":["import {ComponentChildren, ComponentType} from 'preact';\nimport renderToString from 'preact-render-to-string';\nimport {getRoutes, getAllPathsForRoute} from './router';\nimport {ErrorPage} from '../core/pages/ErrorPage';\nimport {AssetMap} from './asset-map/asset-map';\nimport {RootConfig} from '../core/config';\nimport {RouteTrie} from './route-trie';\nimport {DevNotFoundPage} from '../core/pages/DevNotFoundPage';\nimport {HtmlContext, HTML_CONTEXT} from '../core/components/Html';\nimport {\n Request,\n Response,\n NextFunction,\n HandlerContext,\n RouteParams,\n Route,\n} from '../core/types';\nimport {htmlMinify} from './html-minify';\nimport {htmlPretty} from './html-pretty';\nimport {DevErrorPage} from '../core/pages/DevErrorPage';\nimport {RequestContext, REQUEST_CONTEXT} from '../core/hooks/useRequestContext';\nimport {getTranslations, I18N_CONTEXT} from '../core/hooks/useI18nContext';\nimport type {ElementGraph} from '../node/element-graph';\nimport {parseTagNames} from '../utils/elements';\n\ninterface RenderHtmlOptions {\n /** Attrs passed to the <html> tag, e.g. `{lang: 'en'}`. */\n htmlAttrs?: preact.JSX.HTMLAttributes<HTMLHtmlElement>;\n /** Attrs passed to the <head> tag. */\n headAttrs?: preact.JSX.HTMLAttributes<HTMLHeadElement>;\n /** Child components for the <head> tag. */\n headComponents?: ComponentChildren[];\n /** Attrs passed to the <body> tag. */\n bodyAttrs?: preact.JSX.HTMLAttributes<HTMLBodyElement>;\n}\n\nexport class Renderer {\n private rootConfig: RootConfig;\n private routes: RouteTrie<Route>;\n private assetMap: AssetMap;\n private elementGraph: ElementGraph;\n\n constructor(\n rootConfig: RootConfig,\n options: {assetMap: AssetMap; elementGraph: ElementGraph}\n ) {\n this.rootConfig = rootConfig;\n this.routes = getRoutes(this.rootConfig);\n this.assetMap = options.assetMap;\n this.elementGraph = options.elementGraph;\n }\n\n async handle(req: Request, res: Response, next: NextFunction) {\n // TODO(stevenle): handle baseUrl config.\n const url = req.path;\n const [route, routeParams] = this.routes.get(url);\n if (!route) {\n next();\n return;\n }\n if (route.locale) {\n routeParams.$locale = route.locale;\n }\n\n const render404 = async () => {\n // Calling next() will allow the dev server or prod server handle the 404\n // page as appropriate for the env.\n next();\n };\n\n const render = async (props: any) => {\n if (!route.module.default) {\n console.error(`no default component exported in route: ${route.src}`);\n render404();\n return;\n }\n const output = await this.renderComponent(route.module.default, props, {\n route,\n routeParams,\n });\n let html = output.html;\n if (this.rootConfig.prettyHtml) {\n html = await htmlPretty(html, this.rootConfig.prettyHtmlOptions);\n } else if (this.rootConfig.minifyHtml !== false) {\n html = await htmlMinify(html, this.rootConfig.minifyHtmlOptions);\n }\n if (req.viteServer) {\n html = await req.viteServer.transformIndexHtml(req.originalUrl, html);\n }\n // Override the status code for 404 and 500 routes, which are defined at\n // routes/404.tsx and routes/500.tsx respectively.\n let statusCode = 200;\n if (route.src === 'routes/404.tsx') {\n statusCode = 404;\n } else if (route.src === 'routes/500.tsx') {\n statusCode = 500;\n }\n res.status(statusCode).set({'Content-Type': 'text/html'}).end(html);\n };\n\n if (route.module.handle) {\n const handlerContext: HandlerContext = {\n route: route,\n params: routeParams,\n render: render,\n render404: render404,\n };\n req.handlerContext = handlerContext;\n return route.module.handle(req, res, next);\n }\n\n let props = {};\n if (route.module.getStaticProps) {\n const propsData = await route.module.getStaticProps({\n rootConfig: this.rootConfig,\n params: routeParams,\n });\n if (propsData.notFound) {\n return render404();\n }\n if (propsData.props) {\n props = propsData.props;\n }\n }\n await render(props);\n }\n\n private async renderComponent(\n Component: ComponentType,\n props: any,\n options: {route: Route; routeParams: RouteParams}\n ) {\n const {route, routeParams} = options;\n const locale = route.locale;\n const translations = getTranslations(locale);\n const ctx: RequestContext = {\n route,\n props,\n routeParams,\n locale,\n translations,\n };\n const htmlContext: HtmlContext = {\n htmlAttrs: {},\n headAttrs: {},\n headComponents: [],\n bodyAttrs: {},\n scriptDeps: [],\n };\n const vdom = (\n <REQUEST_CONTEXT.Provider value={ctx}>\n <I18N_CONTEXT.Provider value={{locale, translations}}>\n <HTML_CONTEXT.Provider value={htmlContext}>\n <Component {...props} />\n </HTML_CONTEXT.Provider>\n </I18N_CONTEXT.Provider>\n </REQUEST_CONTEXT.Provider>\n );\n const mainHtml = renderToString(vdom);\n\n const jsDeps = new Set<string>();\n const cssDeps = new Set<string>();\n\n // Walk the route's dependency tree for CSS dependencies that are added via\n // `import 'foo.scss'` or `import 'foo.module.scss'`.\n const routeAsset = await this.assetMap.get(route.src);\n if (routeAsset) {\n const routeCssDeps = await routeAsset.getCssDeps();\n routeCssDeps.forEach((dep) => cssDeps.add(dep));\n }\n\n // Parse the HTML for custom elements that are found within the project\n // and automatically inject the script deps for them.\n await this.collectElementDeps(mainHtml, jsDeps, cssDeps);\n\n // Add user defined scripts added via the `<Script>` component.\n await Promise.all(\n htmlContext.scriptDeps.map(async (scriptDep) => {\n if (!scriptDep.src) {\n return;\n }\n const scriptAsset = await this.assetMap.get(scriptDep.src.slice(1));\n if (scriptAsset) {\n jsDeps.add(scriptAsset.assetUrl);\n const scriptJsDeps = await scriptAsset.getJsDeps();\n scriptJsDeps.forEach((dep) => jsDeps.add(dep));\n }\n })\n );\n\n const styleTags = Array.from(cssDeps).map((cssUrl) => {\n return <link rel=\"stylesheet\" href={cssUrl} />;\n });\n const scriptTags = Array.from(jsDeps).map((jsUrls) => {\n return <script type=\"module\" src={jsUrls} />;\n });\n\n const html = await this.renderHtml(mainHtml, {\n htmlAttrs: htmlContext.htmlAttrs,\n headAttrs: htmlContext.headAttrs,\n bodyAttrs: htmlContext.bodyAttrs,\n headComponents: [\n ...htmlContext.headComponents,\n ...styleTags,\n ...scriptTags,\n ],\n });\n return {html};\n }\n\n /** SSG renders a route. */\n async renderRoute(\n route: Route,\n options: {routeParams: Record<string, string>}\n ): Promise<{html?: string; notFound?: boolean}> {\n const routeParams = options.routeParams;\n if (route.locale) {\n routeParams.$locale = route.locale;\n }\n const Component = route.module.default;\n if (!Component) {\n throw new Error(\n 'unable to render route. the route should have a default export that renders a jsx component.'\n );\n }\n let props = {};\n if (route.module.getStaticProps) {\n const propsData = await route.module.getStaticProps({\n rootConfig: this.rootConfig,\n params: routeParams,\n });\n if (propsData.notFound) {\n return {notFound: true};\n }\n if (propsData.props) {\n props = propsData.props;\n }\n }\n return this.renderComponent(Component, props, {route, routeParams});\n }\n\n async getSitemap(): Promise<\n Record<string, {route: Route; params: Record<string, string>}>\n > {\n const sitemap: Record<\n string,\n {route: Route; params: Record<string, string>}\n > = {};\n await this.routes.walk(async (urlPath: string, route: Route) => {\n const routePaths = await getAllPathsForRoute(urlPath, route);\n routePaths.forEach((routePath) => {\n sitemap[routePath.urlPath] = {\n route,\n params: routePath.params,\n };\n });\n });\n return sitemap;\n }\n\n private async renderHtml(html: string, options?: RenderHtmlOptions) {\n const htmlAttrs = options?.htmlAttrs || {};\n const headAttrs = options?.headAttrs || {};\n const bodyAttrs = options?.bodyAttrs || {};\n const page = (\n <html {...htmlAttrs}>\n <head {...headAttrs}>\n <meta charSet=\"utf-8\" />\n {options?.headComponents}\n </head>\n <body {...bodyAttrs} dangerouslySetInnerHTML={{__html: html}} />\n </html>\n );\n return `<!doctype html>\\n${renderToString(page)}\\n`;\n }\n\n async render404() {\n const [route, routeParams] = this.routes.get('/404');\n if (route && route.src === 'routes/404.tsx' && route.module.default) {\n const Component = route.module.default;\n return this.renderComponent(Component, {}, {route, routeParams});\n }\n\n const mainHtml = renderToString(\n <ErrorPage\n code={404}\n title=\"Not found\"\n message=\"Double-check the URL entered and try again.\"\n />\n );\n const html = await this.renderHtml(mainHtml, {\n headComponents: [\n <title>404 Not Found</title>,\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1.0\"\n />,\n ],\n });\n return {html};\n }\n\n async renderError(err: any) {\n const [route, routeParams] = this.routes.get('/500');\n if (route && route.src === 'routes/500.tsx' && route.module.default) {\n const Component = route.module.default;\n return this.renderComponent(\n Component,\n {error: err},\n {route, routeParams}\n );\n }\n\n const mainHtml = renderToString(\n <ErrorPage\n code={500}\n title=\"Something went wrong\"\n message=\"An unknown error occurred.\"\n />\n );\n const html = await this.renderHtml(mainHtml, {\n headComponents: [\n <title>500 Error</title>,\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1.0\"\n />,\n ],\n });\n return {html};\n }\n\n async renderDevServer404(req: Request) {\n const sitemap = await this.getSitemap();\n const mainHtml = renderToString(\n <DevNotFoundPage req={req} sitemap={sitemap} />\n );\n const html = await this.renderHtml(mainHtml, {\n headComponents: [<title>404 Not found | Root.js</title>],\n });\n return {html};\n }\n\n async renderDevServer500(req: Request, error: unknown) {\n const [route, routeParams] = this.routes.get(req.path);\n const mainHtml = renderToString(\n <DevErrorPage\n req={req}\n route={route}\n routeParams={routeParams}\n error={error}\n />\n );\n const html = await this.renderHtml(mainHtml, {\n headComponents: [<title>500 Error | Root.js</title>],\n });\n return {html};\n }\n\n /**\n * Parses rendered HTML for custom element tags used on the page and\n * automatically adds the JS/CSS deps to the page.\n */\n private async collectElementDeps(\n html: string,\n jsDeps: Set<string>,\n cssDeps: Set<string>\n ): Promise<{jsDeps: Set<string>; cssDeps: Set<string>}> {\n const elementsMap = this.elementGraph.sourceFiles;\n const assetMap = this.assetMap;\n\n const tagNames = new Set<string>();\n for (const tagName of parseTagNames(html)) {\n if (tagName && tagName in elementsMap) {\n tagNames.add(tagName);\n for (const depTagName of this.elementGraph.getDeps(tagName)) {\n tagNames.add(depTagName);\n }\n }\n }\n\n await Promise.all(\n Array.from(tagNames).map(async (tagName: string) => {\n const elementModule = elementsMap[tagName];\n const asset = await assetMap.get(elementModule.relPath);\n if (!asset) {\n return;\n }\n const assetJsDeps = await asset.getJsDeps();\n assetJsDeps.forEach((dep) => jsDeps.add(dep));\n const assetCssDeps = await asset.getCssDeps();\n assetCssDeps.forEach((dep) => cssDeps.add(dep));\n })\n );\n\n return {jsDeps, cssDeps};\n }\n}\n","import path from 'node:path';\nimport {RootConfig} from '../core/config';\nimport {Route, RouteModule} from '../core/types';\nimport {RouteTrie} from './route-trie';\n\nexport function getRoutes(config: RootConfig) {\n const locales = config.i18n?.locales || [];\n const i18nUrlFormat = config.i18n?.urlFormat || '/{locale}/{path}';\n const defaultLocale = config.i18n?.defaultLocale || 'en';\n\n const routes = import.meta.glob(\n ['/routes/*.ts', '/routes/**/*.ts', '/routes/*.tsx', '/routes/**/*.tsx'],\n {\n eager: true,\n }\n );\n const trie = new RouteTrie<Route>();\n Object.keys(routes).forEach((modulePath) => {\n const src = modulePath.slice(1);\n let routePath = modulePath.replace(/^\\/routes/, '');\n const parts = path.parse(routePath);\n if (parts.name.startsWith('_')) {\n return;\n }\n if (parts.name === 'index') {\n routePath = parts.dir;\n } else {\n routePath = path.join(parts.dir, parts.name);\n }\n\n const localeRoutePath = i18nUrlFormat\n .replace('{locale}', '[locale]')\n .replace('{path}', routePath.replace(/^\\/*/, ''));\n\n trie.add(routePath, {\n src,\n module: routes[modulePath] as RouteModule,\n locale: defaultLocale,\n routePath,\n localeRoutePath,\n });\n\n // At the moment, all routes are assumed to use the site-wide i18n config.\n // TODO(stevenle): provide routes with a way to override the default\n // i18n serving behavior.\n locales.forEach((locale) => {\n const localePath = localeRoutePath.replace('[locale]', locale);\n if (localePath !== routePath) {\n trie.add(localePath, {\n src,\n module: routes[modulePath] as RouteModule,\n locale: locale,\n routePath,\n localeRoutePath,\n });\n }\n });\n });\n return trie;\n}\n\nexport async function getAllPathsForRoute(\n urlPathFormat: string,\n route: Route\n): Promise<Array<{urlPath: string; params: Record<string, string>}>> {\n const routeModule = route.module;\n if (!routeModule.default) {\n return [];\n }\n\n const urlPaths: Array<{urlPath: string; params: Record<string, string>}> = [];\n if (routeModule.getStaticPaths) {\n const staticPaths = await routeModule.getStaticPaths();\n if (staticPaths.paths) {\n staticPaths.paths.forEach(\n (pathParams: {params: Record<string, string>}) => {\n const urlPath = replaceParams(urlPathFormat, pathParams.params || {});\n if (pathContainsPlaceholders(urlPath)) {\n console.warn(\n `path contains placeholders: ${urlPathFormat}, double check getStaticPaths() and ensure all params are returned. more info: https://rootjs.dev/guide/routes#getStaticPaths`\n );\n } else {\n urlPaths.push({\n urlPath: replaceParams(urlPathFormat, pathParams.params),\n params: pathParams.params || {},\n });\n }\n }\n );\n }\n } else if (pathContainsPlaceholders(urlPathFormat)) {\n console.warn(\n `path contains placeholders: ${urlPathFormat}, did you forget to define getStaticPaths()? more info: https://rootjs.dev/guide/routes#getStaticPaths`\n );\n } else {\n urlPaths.push({urlPath: urlPathFormat, params: {}});\n }\n return urlPaths;\n}\n\nexport function replaceParams(\n urlPathFormat: string,\n params: Record<string, string>\n) {\n const urlPath = urlPathFormat.replaceAll(\n /\\[(\\.\\.\\.)?([\\w\\-_]*)\\]/g,\n (match: string, _wildcard: string, key: string) => {\n const val = params[key];\n if (!val) {\n throw new Error(`unreplaced param ${match} in url: ${urlPathFormat}`);\n }\n return val;\n }\n );\n return urlPath;\n}\n\nfunction pathContainsPlaceholders(urlPath: string) {\n const segments = urlPath.split('/');\n return segments.some((segment) => {\n return segment.startsWith('[') && segment.endsWith(']');\n });\n}\n","/**\n * A trie data structure that stores routes. The trie supports `:param` and\n * `*wildcard` values.\n */\nexport class RouteTrie<T> {\n private children: Record<string, RouteTrie<T>> = {};\n private paramChild?: ParamChild<T>;\n private wildcardChild?: WildcardChild<T>;\n private route?: T;\n\n /**\n * Adds a route to the trie.\n */\n add(path: string, route: T) {\n path = this.normalizePath(path);\n\n // If the end was reached, save the value to the node.\n if (path === '') {\n this.route = route;\n return;\n }\n\n const [head, tail] = this.splitPath(path);\n if (head.startsWith('[...') && head.endsWith(']')) {\n const paramName = head.slice(4, -1);\n this.wildcardChild = new WildcardChild(paramName, route);\n return;\n }\n\n let nextNode: RouteTrie<T>;\n if (head.startsWith('[') && head.endsWith(']')) {\n if (!this.paramChild) {\n const paramName = head.slice(1, -1);\n this.paramChild = new ParamChild(paramName);\n }\n nextNode = this.paramChild.trie;\n } else {\n nextNode = this.children[head];\n if (!nextNode) {\n nextNode = new RouteTrie();\n this.children[head] = nextNode;\n }\n }\n nextNode.add(tail, route);\n }\n\n /**\n * Returns a route mapped to the given path and any parameter values from the\n * URL.\n */\n get(path: string): [T | undefined, Record<string, string>] {\n const params = {};\n const route = this.getRoute(path, params);\n return [route, params];\n }\n\n /**\n * Walks the route trie and calls a callback function for each route.\n */\n walk(cb: (urlPath: string, route: T) => Promise<void> | void): Promise<void> {\n const promises: Array<Promise<void>> = [];\n const addPromise = (promise: Promise<void> | void) => {\n if (promise) {\n promises.push(promise);\n }\n };\n if (this.route) {\n addPromise(cb('/', this.route));\n }\n if (this.paramChild) {\n const param = `[${this.paramChild.name}]`;\n this.paramChild.trie.walk((childPath: string, route: T) => {\n const paramUrlPath = `/${param}${childPath}`;\n addPromise(cb(paramUrlPath, route));\n });\n }\n if (this.wildcardChild) {\n const wildcardUrlPath = `/[...${this.wildcardChild.name}]`;\n addPromise(cb(wildcardUrlPath, this.wildcardChild.route));\n }\n for (const subpath of Object.keys(this.children)) {\n const childTrie = this.children[subpath];\n childTrie.walk((childPath: string, childRoute: T) => {\n addPromise(cb(`/${subpath}${childPath}`, childRoute));\n });\n }\n return Promise.all(promises).then(() => {});\n }\n\n /**\n * Removes all routes from the trie.\n */\n clear() {\n this.children = {};\n this.paramChild = undefined;\n this.wildcardChild = undefined;\n this.route = undefined;\n }\n\n private getRoute(\n urlPath: string,\n params: Record<string, string>\n ): T | undefined {\n urlPath = this.normalizePath(urlPath);\n if (urlPath === '') {\n return this.route;\n }\n\n const [head, tail] = this.splitPath(urlPath);\n\n const child = this.children[head];\n if (child) {\n const route = child.getRoute(tail, params);\n if (route) {\n return route;\n }\n }\n\n if (this.paramChild) {\n const route = this.paramChild.trie.getRoute(tail, params);\n if (route) {\n params[this.paramChild.name] = head;\n return route;\n }\n }\n\n if (this.wildcardChild) {\n params[this.wildcardChild.name] = urlPath;\n return this.wildcardChild.route;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a path for inclusion into the route trie.\n */\n private normalizePath(path: string) {\n // Remove leading slashes.\n return path.replace(/^\\/+/g, '');\n }\n\n /**\n * Splits the parent directory from its children, e.g.:\n *\n * splitPath(\"foo/bar/baz\") -> [\"foo\", \"bar/baz\"]\n */\n private splitPath(path: string): [string, string] {\n const i = path.indexOf('/');\n if (i === -1) {\n return [path, ''];\n }\n return [path.slice(0, i), path.slice(i + 1)];\n }\n}\n\n/**\n * A node in the RouteTrie for a :param child.\n */\nclass ParamChild<T> {\n readonly name: string;\n readonly trie: RouteTrie<T> = new RouteTrie();\n\n constructor(name: string) {\n this.name = name;\n }\n}\n\n/**\n * A node in the RouteTrie for a *wildcard child.\n */\nclass WildcardChild<T> {\n readonly name: string;\n readonly route: T;\n\n constructor(name: string, route: T) {\n this.name = name;\n this.route = route;\n }\n}\n","import {ComponentChildren} from 'preact';\n\nconst STYLES = `\n@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');\n\n:root {\n --font-family-text: \"Inter\", sans-serif;\n}\n\nbody {\n font-family: var(--font-family-text);\n background: #F5F5F5;\n padding: 40px 16px;\n}\n\n.root {\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.root.align-center {\n text-align: center;\n}\n\nh1.title {\n margin-top: 0;\n margin-bottom: 24px;\n}\n\np.message {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.box {\n font-size: 16px;\n line-height: 1.5;\n padding: 16px;\n border-radius: 12px;\n background: #ffffff;\n}\n\npre.box {\n white-space: pre-wrap;\n}\n\n@media (min-width: 500px) {\n body {\n padding: 40px;\n }\n\n .box {\n padding: 24px;\n }\n}\n\n@media (min-width: 1024px) {\n body {\n padding: 100px;\n }\n}\n`;\n\nexport interface ErrorPageProps {\n code: number;\n title?: string;\n message?: string;\n children?: ComponentChildren;\n align?: 'center';\n}\n\nexport function ErrorPage(props: ErrorPageProps) {\n const {code, message} = props;\n const title = props.title || code;\n return (\n <>\n <style dangerouslySetInnerHTML={{__html: STYLES}}></style>\n <div className={`root align-${props.align || 'left'}`}>\n <h1 className=\"title\">{title}</h1>\n {message && <p className=\"message\">{message}</p>}\n {props.children}\n </div>\n </>\n );\n}\n","import {Request, Route} from '../types';\nimport {ErrorPage} from './ErrorPage';\n\ninterface DevNotFoundPageProps {\n req: Request;\n sitemap: Record<string, {route: Route; params: Record<string, string>}>;\n}\n\nexport function DevNotFoundPage(props: DevNotFoundPageProps) {\n const req = props.req;\n const routesList: Array<{src: string; urlPath: string}> = [];\n let urlMaxLength = 0;\n Object.keys(props.sitemap).forEach((urlPath) => {\n const route = props.sitemap[urlPath].route;\n routesList.push(Object.assign({}, route, {urlPath}));\n if (urlPath.length > urlMaxLength) {\n urlMaxLength = urlPath.length;\n }\n });\n const routesListString = routesList\n .map((route) => {\n return `${route.urlPath.padEnd(urlMaxLength, ' ')} => ${route.src}`;\n })\n .join('\\n');\n return (\n <ErrorPage code={404} title=\"Not found\">\n <h2>Routes</h2>\n {routesList.length > 0 ? (\n <pre className=\"box\">\n <code>{routesListString}</code>\n </pre>\n ) : (\n <div className=\"box\">\n Add your first route at <code>/routes/index.tsx</code>\n </div>\n )}\n\n <h2>Debug Info</h2>\n <pre className=\"box\">\n <code>{`url: ${req.originalUrl}`}</code>\n </pre>\n </ErrorPage>\n );\n}\n","import {Request, Route, RouteParams} from '../types';\nimport {ErrorPage} from './ErrorPage';\n\ninterface DevErrorPageProps {\n req: Request;\n route?: Route;\n routeParams?: RouteParams;\n error: any;\n}\n\nexport function DevErrorPage(props: DevErrorPageProps) {\n const req = props.req;\n const err = props.error;\n const route = props.route;\n const routeParams = props.routeParams;\n\n let errMsg = String(err);\n if (err && err.stack) {\n // Obfuscate some user info from the stack trace so that when people send\n // error reports and screenshots, less identifiable information is sent.\n errMsg = err.stack\n .replace(/\\(.*node_modules/g, '(node_modules')\n .replace(/at \\/.*node_modules/g, 'at node_modules');\n if (req.rootConfig?.rootDir) {\n errMsg = errMsg.replaceAll(req.rootConfig.rootDir, '<root>');\n }\n if (process.env.HOME) {\n errMsg = errMsg.replaceAll(process.env.HOME, '$HOME');\n }\n }\n return (\n <ErrorPage code={500} title=\"Something went wrong\">\n {errMsg && (\n <>\n <h2>Error</h2>\n <pre className=\"box\">\n <code>{errMsg}</code>\n </pre>\n </>\n )}\n <h2>Debug Info</h2>\n <pre className=\"box\">\n <code>{`url: ${req.originalUrl}\nroute: ${route?.src || 'null'}\nrouteParams: ${(routeParams && JSON.stringify(routeParams)) || 'null'}`}</code>\n </pre>\n </ErrorPage>\n );\n}\n"],"mappings":"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","names":["path","jsx","jsxs","Fragment","jsx","jsxs","jsx","jsxs","props"]}
1
+ {"version":3,"sources":["../src/render/render.tsx","../src/core/pages/ErrorPage.tsx","../src/core/pages/DevErrorPage.tsx","../src/core/pages/DevNotFoundPage.tsx","../src/render/accept-language.ts","../src/render/i18n-fallbacks.ts","../src/render/router.ts","../src/render/route-trie.ts"],"sourcesContent":["import {ComponentChildren, ComponentType} from 'preact';\nimport renderToString from 'preact-render-to-string';\n\nimport {HtmlContext, HTML_CONTEXT} from '../core/components/Html';\nimport {RootConfig} from '../core/config';\nimport {getTranslations, I18N_CONTEXT} from '../core/hooks/useI18nContext';\nimport {RequestContext, REQUEST_CONTEXT} from '../core/hooks/useRequestContext';\nimport {DevErrorPage} from '../core/pages/DevErrorPage';\nimport {DevNotFoundPage} from '../core/pages/DevNotFoundPage';\nimport {ErrorPage} from '../core/pages/ErrorPage';\nimport {\n Request,\n Response,\n NextFunction,\n HandlerContext,\n RouteParams,\n Route,\n HandlerRenderFn,\n HandlerRenderOptions,\n} from '../core/types';\nimport type {ElementGraph} from '../node/element-graph';\nimport {parseTagNames} from '../utils/elements';\n\nimport {AssetMap} from './asset-map/asset-map';\nimport {htmlMinify} from './html-minify';\nimport {htmlPretty} from './html-pretty';\nimport {getFallbackLocales} from './i18n-fallbacks';\nimport {RouteTrie} from './route-trie';\nimport {getRoutes, getAllPathsForRoute, replaceParams} from './router';\n\ninterface RenderHtmlOptions {\n /** Attrs passed to the <html> tag, e.g. `{lang: 'en'}`. */\n htmlAttrs?: preact.JSX.HTMLAttributes<HTMLHtmlElement>;\n /** Attrs passed to the <head> tag. */\n headAttrs?: preact.JSX.HTMLAttributes<HTMLHeadElement>;\n /** Child components for the <head> tag. */\n headComponents?: ComponentChildren[];\n /** Attrs passed to the <body> tag. */\n bodyAttrs?: preact.JSX.HTMLAttributes<HTMLBodyElement>;\n}\n\nexport class Renderer {\n private rootConfig: RootConfig;\n private routes: RouteTrie<Route>;\n private assetMap: AssetMap;\n private elementGraph: ElementGraph;\n\n constructor(\n rootConfig: RootConfig,\n options: {assetMap: AssetMap; elementGraph: ElementGraph}\n ) {\n this.rootConfig = rootConfig;\n this.routes = getRoutes(this.rootConfig);\n this.assetMap = options.assetMap;\n this.elementGraph = options.elementGraph;\n }\n\n async handle(req: Request, res: Response, next: NextFunction) {\n // TODO(stevenle): handle baseUrl config.\n const url = req.path;\n const [route, routeParams] = this.routes.get(url);\n if (!route) {\n next();\n return;\n }\n if (route.locale) {\n routeParams.$locale = route.locale;\n }\n\n const fallbackLocales = route.isDefaultLocale\n ? getFallbackLocales(req)\n : [route.locale];\n const getPreferredLocale = (availableLocales: string[]) => {\n const lowerLocales = availableLocales.map((l) => l.toLowerCase());\n for (const fallbackLocale of fallbackLocales) {\n if (lowerLocales.includes(fallbackLocale.toLowerCase())) {\n return fallbackLocale;\n }\n }\n return req.rootConfig?.i18n?.defaultLocale || 'en';\n };\n\n const render404 = async () => {\n // Calling next() will allow the dev server or prod server handle the 404\n // page as appropriate for the env.\n next();\n };\n\n const render: HandlerRenderFn = async (\n props: any,\n options?: HandlerRenderOptions\n ) => {\n if (!route.module.default) {\n console.error(`no default component exported in route: ${route.src}`);\n render404();\n return;\n }\n const currentPath = req.path;\n const locale = options?.locale || route.locale;\n const translations = options?.translations;\n const output = await this.renderComponent(route.module.default, props, {\n currentPath,\n route,\n routeParams,\n locale,\n translations,\n });\n let html = output.html;\n if (this.rootConfig.prettyHtml) {\n html = await htmlPretty(html, this.rootConfig.prettyHtmlOptions);\n } else if (this.rootConfig.minifyHtml !== false) {\n html = await htmlMinify(html, this.rootConfig.minifyHtmlOptions);\n }\n if (req.viteServer) {\n html = await req.viteServer.transformIndexHtml(currentPath, html);\n }\n // Override the status code for 404 and 500 routes, which are defined at\n // routes/404.tsx and routes/500.tsx respectively.\n let statusCode = 200;\n if (route.src === 'routes/404.tsx') {\n statusCode = 404;\n } else if (route.src === 'routes/500.tsx') {\n statusCode = 500;\n }\n res.status(statusCode).set({'Content-Type': 'text/html'}).end(html);\n };\n\n if (route.module.handle) {\n const handlerContext: HandlerContext = {\n route: route,\n params: routeParams,\n i18nFallbackLocales: fallbackLocales,\n getPreferredLocale: getPreferredLocale,\n render: render,\n render404: render404,\n };\n req.handlerContext = handlerContext;\n return route.module.handle(req, res, next);\n }\n\n let props = {};\n if (route.module.getStaticProps) {\n const propsData = await route.module.getStaticProps({\n rootConfig: this.rootConfig,\n params: routeParams,\n });\n if (propsData.notFound) {\n return render404();\n }\n if (propsData.props) {\n props = propsData.props;\n }\n }\n await render(props);\n }\n\n private async renderComponent(\n Component: ComponentType,\n props: any,\n options: {\n currentPath: string;\n route: Route;\n routeParams: RouteParams;\n locale: string;\n translations?: Record<string, string>;\n }\n ) {\n const {currentPath, route, routeParams} = options;\n const locale = options.locale;\n const translations = {\n ...getTranslations(locale),\n ...(options.translations || {}),\n };\n const ctx: RequestContext = {\n currentPath,\n route,\n props,\n routeParams,\n locale,\n translations,\n };\n const htmlContext: HtmlContext = {\n htmlAttrs: {},\n headAttrs: {},\n headComponents: [],\n bodyAttrs: {},\n scriptDeps: [],\n };\n const vdom = (\n <REQUEST_CONTEXT.Provider value={ctx}>\n <I18N_CONTEXT.Provider value={{locale, translations}}>\n <HTML_CONTEXT.Provider value={htmlContext}>\n <Component {...props} />\n </HTML_CONTEXT.Provider>\n </I18N_CONTEXT.Provider>\n </REQUEST_CONTEXT.Provider>\n );\n const mainHtml = renderToString(vdom);\n\n const jsDeps = new Set<string>();\n const cssDeps = new Set<string>();\n\n // Walk the route's dependency tree for CSS dependencies that are added via\n // `import 'foo.scss'` or `import 'foo.module.scss'`.\n const routeAsset = await this.assetMap.get(route.src);\n if (routeAsset) {\n const routeCssDeps = await routeAsset.getCssDeps();\n routeCssDeps.forEach((dep) => cssDeps.add(dep));\n }\n\n // Parse the HTML for custom elements that are found within the project\n // and automatically inject the script deps for them.\n await this.collectElementDeps(mainHtml, jsDeps, cssDeps);\n\n // Add user defined scripts added via the `<Script>` component.\n await Promise.all(\n htmlContext.scriptDeps.map(async (scriptDep) => {\n if (!scriptDep.src) {\n return;\n }\n const scriptAsset = await this.assetMap.get(scriptDep.src.slice(1));\n if (scriptAsset) {\n jsDeps.add(scriptAsset.assetUrl);\n const scriptJsDeps = await scriptAsset.getJsDeps();\n scriptJsDeps.forEach((dep) => jsDeps.add(dep));\n }\n })\n );\n\n const styleTags = Array.from(cssDeps).map((cssUrl) => {\n return <link rel=\"stylesheet\" href={cssUrl} />;\n });\n const scriptTags = Array.from(jsDeps).map((jsUrls) => {\n return <script type=\"module\" src={jsUrls} />;\n });\n\n const html = await this.renderHtml(mainHtml, {\n htmlAttrs: htmlContext.htmlAttrs,\n headAttrs: htmlContext.headAttrs,\n bodyAttrs: htmlContext.bodyAttrs,\n headComponents: [\n ...htmlContext.headComponents,\n ...styleTags,\n ...scriptTags,\n ],\n });\n return {html};\n }\n\n /** SSG renders a route. */\n async renderRoute(\n route: Route,\n options: {routeParams: Record<string, string>}\n ): Promise<{html?: string; notFound?: boolean}> {\n const routeParams = options.routeParams;\n if (route.locale) {\n routeParams.$locale = route.locale;\n }\n const Component = route.module.default;\n if (!Component) {\n throw new Error(\n 'unable to render route. the route should have a default export that renders a jsx component.'\n );\n }\n let props = {};\n let locale = route.locale;\n let translations = undefined;\n if (route.module.getStaticProps) {\n const propsData = await route.module.getStaticProps({\n rootConfig: this.rootConfig,\n params: routeParams,\n });\n if (propsData.notFound) {\n return {notFound: true};\n }\n if (propsData.props) {\n props = propsData.props;\n }\n if (propsData.locale) {\n locale = propsData.locale;\n }\n if (propsData.translations) {\n translations = propsData.translations;\n }\n }\n const routePath = route.isDefaultLocale\n ? route.routePath\n : route.localeRoutePath;\n const currentPath = replaceParams(routePath, {\n ...routeParams,\n locale: locale,\n });\n return this.renderComponent(Component, props, {\n currentPath,\n route,\n routeParams,\n locale,\n translations,\n });\n }\n\n async getSitemap(): Promise<\n Record<string, {route: Route; params: Record<string, string>}>\n > {\n const sitemap: Record<\n string,\n {route: Route; params: Record<string, string>}\n > = {};\n await this.routes.walk(async (urlPath: string, route: Route) => {\n const routePaths = await getAllPathsForRoute(urlPath, route);\n routePaths.forEach((routePath) => {\n sitemap[routePath.urlPath] = {\n route,\n params: routePath.params,\n };\n });\n });\n return sitemap;\n }\n\n private async renderHtml(html: string, options?: RenderHtmlOptions) {\n const htmlAttrs = options?.htmlAttrs || {};\n const headAttrs = options?.headAttrs || {};\n const bodyAttrs = options?.bodyAttrs || {};\n const page = (\n <html {...htmlAttrs}>\n <head {...headAttrs}>\n <meta charSet=\"utf-8\" />\n {options?.headComponents}\n </head>\n <body {...bodyAttrs} dangerouslySetInnerHTML={{__html: html}} />\n </html>\n );\n return `<!doctype html>\\n${renderToString(page)}\\n`;\n }\n\n async render404(options?: {currentPath?: string}) {\n const currentPath = options?.currentPath || '/404';\n const [route, routeParams] = this.routes.get('/404');\n if (route && route.src === 'routes/404.tsx' && route.module.default) {\n const Component = route.module.default;\n return this.renderComponent(\n Component,\n {},\n {currentPath, route, routeParams, locale: 'en'}\n );\n }\n\n const mainHtml = renderToString(\n <ErrorPage\n code={404}\n title=\"Not found\"\n message=\"Double-check the URL entered and try again.\"\n align=\"center\"\n />\n );\n const html = await this.renderHtml(mainHtml, {\n headComponents: [\n <title>404 Not Found</title>,\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1.0\"\n />,\n ],\n });\n return {html};\n }\n\n async renderError(err: any, options?: {currentPath?: string}) {\n const currentPath = options?.currentPath || '/500';\n const [route, routeParams] = this.routes.get('/500');\n if (route && route.src === 'routes/500.tsx' && route.module.default) {\n const Component = route.module.default;\n return this.renderComponent(\n Component,\n {error: err},\n {currentPath, route, routeParams, locale: 'en'}\n );\n }\n\n const mainHtml = renderToString(\n <ErrorPage\n code={500}\n title=\"Something went wrong\"\n message=\"An unknown error occurred.\"\n align=\"center\"\n />\n );\n const html = await this.renderHtml(mainHtml, {\n headComponents: [\n <title>500 Error</title>,\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1.0\"\n />,\n ],\n });\n return {html};\n }\n\n async renderDevServer404(req: Request) {\n const sitemap = await this.getSitemap();\n const mainHtml = renderToString(\n <DevNotFoundPage req={req} sitemap={sitemap} />\n );\n const html = await this.renderHtml(mainHtml, {\n headComponents: [<title>404 Not found | Root.js</title>],\n });\n return {html};\n }\n\n async renderDevServer500(req: Request, error: unknown) {\n const [route, routeParams] = this.routes.get(req.path);\n const mainHtml = renderToString(\n <DevErrorPage\n req={req}\n route={route}\n routeParams={routeParams}\n error={error}\n />\n );\n const html = await this.renderHtml(mainHtml, {\n headComponents: [<title>500 Error | Root.js</title>],\n });\n return {html};\n }\n\n /**\n * Parses rendered HTML for custom element tags used on the page and\n * automatically adds the JS/CSS deps to the page.\n */\n private async collectElementDeps(\n html: string,\n jsDeps: Set<string>,\n cssDeps: Set<string>\n ): Promise<{jsDeps: Set<string>; cssDeps: Set<string>}> {\n const elementsMap = this.elementGraph.sourceFiles;\n const assetMap = this.assetMap;\n\n const tagNames = new Set<string>();\n for (const tagName of parseTagNames(html)) {\n if (tagName && tagName in elementsMap) {\n tagNames.add(tagName);\n for (const depTagName of this.elementGraph.getDeps(tagName)) {\n tagNames.add(depTagName);\n }\n }\n }\n\n await Promise.all(\n Array.from(tagNames).map(async (tagName: string) => {\n const elementModule = elementsMap[tagName];\n const asset = await assetMap.get(elementModule.relPath);\n if (!asset) {\n return;\n }\n const assetJsDeps = await asset.getJsDeps();\n assetJsDeps.forEach((dep) => jsDeps.add(dep));\n const assetCssDeps = await asset.getCssDeps();\n assetCssDeps.forEach((dep) => cssDeps.add(dep));\n })\n );\n\n return {jsDeps, cssDeps};\n }\n}\n","import {ComponentChildren} from 'preact';\n\nconst STYLES = `\n@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');\n\n:root {\n --font-family-text: \"Inter\", sans-serif;\n}\n\nbody {\n font-family: var(--font-family-text);\n background: #F5F5F5;\n padding: 40px 16px;\n}\n\n.root {\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.root.align-center {\n text-align: center;\n}\n\nh1.title {\n margin-top: 0;\n margin-bottom: 24px;\n}\n\np.message {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.box {\n font-size: 16px;\n line-height: 1.5;\n padding: 16px;\n border-radius: 12px;\n background: #ffffff;\n}\n\npre.box {\n white-space: pre-wrap;\n}\n\n@media (min-width: 500px) {\n body {\n padding: 40px;\n }\n\n .box {\n padding: 24px;\n }\n}\n\n@media (min-width: 1024px) {\n body {\n padding: 100px;\n }\n}\n`;\n\nexport interface ErrorPageProps {\n code: number;\n title?: string;\n message?: string;\n children?: ComponentChildren;\n align?: 'center';\n}\n\nexport function ErrorPage(props: ErrorPageProps) {\n const {code, message} = props;\n const title = props.title || code;\n return (\n <>\n <style dangerouslySetInnerHTML={{__html: STYLES}}></style>\n <div className={`root align-${props.align || 'left'}`}>\n <h1 className=\"title\">{title}</h1>\n {message && <p className=\"message\">{message}</p>}\n {props.children}\n </div>\n </>\n );\n}\n","import {Request, Route, RouteParams} from '../types';\n\nimport {ErrorPage} from './ErrorPage';\n\ninterface DevErrorPageProps {\n req: Request;\n route?: Route;\n routeParams?: RouteParams;\n error: any;\n}\n\nexport function DevErrorPage(props: DevErrorPageProps) {\n const req = props.req;\n const err = props.error;\n const route = props.route;\n const routeParams = props.routeParams;\n\n let errMsg = String(err);\n if (err && err.stack) {\n // Obfuscate some user info from the stack trace so that when people send\n // error reports and screenshots, less identifiable information is sent.\n errMsg = err.stack\n .replace(/\\(.*node_modules/g, '(node_modules')\n .replace(/at \\/.*node_modules/g, 'at node_modules');\n if (req.rootConfig?.rootDir) {\n errMsg = errMsg.replaceAll(req.rootConfig.rootDir, '<root>');\n }\n if (process.env.HOME) {\n errMsg = errMsg.replaceAll(process.env.HOME, '$HOME');\n }\n }\n return (\n <ErrorPage code={500} title=\"Something went wrong\">\n {errMsg && (\n <>\n <h2>Error</h2>\n <pre className=\"box\">\n <code>{errMsg}</code>\n </pre>\n </>\n )}\n <h2>Debug Info</h2>\n <pre className=\"box\">\n <code>{`url: ${req.originalUrl}\nroute: ${route?.src || 'null'}\nrouteParams: ${(routeParams && JSON.stringify(routeParams)) || 'null'}`}</code>\n </pre>\n </ErrorPage>\n );\n}\n","import {Request, Route} from '../types';\n\nimport {ErrorPage} from './ErrorPage';\n\ninterface DevNotFoundPageProps {\n req: Request;\n sitemap: Record<string, {route: Route; params: Record<string, string>}>;\n}\n\ninterface RoutesListMap {\n [src: string]: Array<RouteURLPath>;\n}\n\ninterface RouteURLPath {\n route: Route;\n urlPath: string;\n}\n\nexport function DevNotFoundPage(props: DevNotFoundPageProps) {\n const req = props.req;\n const routesListMap: RoutesListMap = {};\n let srcMaxLength = 0;\n Object.keys(props.sitemap).forEach((urlPath) => {\n const route = props.sitemap[urlPath].route;\n routesListMap[route.src] ??= [];\n routesListMap[route.src].push({route, urlPath});\n if (route.src.length > srcMaxLength) {\n srcMaxLength = route.src.length;\n }\n });\n const routeSrcs = Object.keys(routesListMap).sort(sortRouteFiles);\n const lines: string[] = [];\n routeSrcs.forEach((routeSrc) => {\n const routeUrls = routesListMap[routeSrc].sort(sortRouteURLs);\n routeUrls.forEach((routeUrl, i) => {\n const urlPath = routeUrl.urlPath;\n if (i === 0) {\n lines.push(`${routeSrc.padEnd(srcMaxLength, ' ')} => ${urlPath}`);\n } else {\n lines.push(`${''.padEnd(srcMaxLength, ' ')} => ${urlPath}`);\n }\n });\n });\n const routesListString = lines.join('\\n');\n // const routesListString = routesList\n // .map((route) => {\n // return `${route.urlPath.padEnd(srcMaxLength, ' ')} => ${route.src}`;\n // })\n // .join('\\n');\n return (\n <ErrorPage code={404} title=\"Not found\">\n <h2>Routes</h2>\n {Object.keys(routesListMap).length > 0 ? (\n <pre className=\"box\">\n <code>{routesListString}</code>\n </pre>\n ) : (\n <div className=\"box\">\n Add your first route at <code>/routes/index.tsx</code>\n </div>\n )}\n\n <h2>Debug Info</h2>\n <pre className=\"box\">\n <code>{`url: ${req.originalUrl}`}</code>\n </pre>\n </ErrorPage>\n );\n}\n\nfunction sortRouteFiles(a: string, b: string): number {\n if (a === 'routes/index.tsx') {\n return -1;\n }\n if (b === 'routes/index.tsx') {\n return 1;\n }\n return a.localeCompare(b);\n}\n\nfunction sortRouteURLs(a: RouteURLPath, b: RouteURLPath): number {\n if (a.route.isDefaultLocale && !b.route.isDefaultLocale) {\n return -1;\n }\n if (!a.route.isDefaultLocale && b.route.isDefaultLocale) {\n return 1;\n }\n return a.urlPath.localeCompare(b.urlPath);\n}\n","export const ACCEPT_LANG_RE =\n /((([a-zA-Z]+(-[a-zA-Z0-9]+){0,2})|\\*)(;q=[0-1](\\.[0-9]+)?)?)*/g;\n\nexport interface AcceptLanguage {\n code: string;\n script?: string;\n region?: string;\n quality: number;\n}\n\nexport function parseAcceptLanguage(value: string): AcceptLanguage[] {\n const matches = String(value).match(ACCEPT_LANG_RE);\n if (!matches) {\n return [];\n }\n const results: AcceptLanguage[] = [];\n matches.forEach((m) => {\n if (!m) {\n return;\n }\n\n const parts = m.split(';');\n const ietf = parts[0].split('-');\n const hasScript = ietf.length === 3;\n\n results.push({\n code: ietf[0],\n script: hasScript ? ietf[1] : undefined,\n region: hasScript ? ietf[2] : ietf[1],\n quality: parts[1] ? parseFloat(parts[1].split('=')[1]) : 1.0,\n });\n });\n results.sort((a, b) => b.quality - a.quality);\n return results;\n}\n","/**\n * Utility functions for handling requests that mimic the Firebase Hosting i18n\n * fallback logic.\n * https://firebase.google.com/docs/hosting/i18n-rewrites\n */\n\nimport {Request} from '../core/types';\nimport {parseAcceptLanguage} from './accept-language';\n\nexport const UNKNOWN_COUNTRY = 'zz';\n\nexport function getFallbackLocales(req: Request): string[] {\n const hl = getFirstQueryParam(req, 'hl');\n const countryCode = getCountry(req);\n\n // Web crawlers should only use the default locale.\n if (isWebCrawler(req)) {\n const defaultLocale = req.rootConfig?.i18n?.defaultLocale || 'en';\n if (hl && hl !== defaultLocale) {\n return [hl, defaultLocale];\n }\n return [defaultLocale];\n }\n\n const locales = new Set<string>();\n\n // Add locales from ?hl= query parameter.\n if (hl) {\n const langCode = hl;\n locales.add(`${langCode}_${countryCode}`);\n locales.add(`${langCode}_ALL`);\n locales.add(langCode);\n }\n\n const langs = getFallbackLanguages(req);\n\n // Add `{lang}_{country}` locales.\n langs.forEach((langCode) => {\n locales.add(`${langCode}_${countryCode}`);\n });\n\n // Add ALL_{country} locale.\n locales.add(`ALL_${countryCode}`);\n\n // Add `{lang}_ALL` and `{lang}` locales.\n langs.forEach((langCode) => {\n locales.add(`${langCode}_ALL`);\n locales.add(langCode);\n });\n\n return Array.from(locales) as string[];\n}\n\nexport function getCountry(req: Request) {\n const normalize = (countryCode: string) => String(countryCode).toLowerCase();\n // Check the ?gl= query param.\n const gl = getFirstQueryParam(req, 'gl');\n if (gl) {\n return normalize(gl);\n }\n const gaeCountry =\n req.get('x-country-code') || req.get('x-appengine-country');\n if (gaeCountry) {\n return normalize(gaeCountry);\n }\n return UNKNOWN_COUNTRY;\n}\n\nfunction getFallbackLanguages(req: Request): string[] {\n const langs = new Set<string>();\n // Add languages from the Accept-Language header.\n const acceptLangHeader = req.get('accept-language') || '';\n if (acceptLangHeader) {\n parseAcceptLanguage(acceptLangHeader).forEach((lang) => {\n // For a lang like `en-US`, add both `en-US` and `en`.\n if (lang.region) {\n langs.add(`${lang.code}-${lang.region}`);\n }\n langs.add(lang.code);\n });\n }\n // Fall back to \"en\" as a last resort.\n langs.add('en');\n return Array.from(langs);\n}\n\n/**\n * Returns the first query param value in a given request.\n *\n * For example, for a URL like `/?foo=bar&foo=baz`, calling\n * `getFirstQueryParam(req, 'foo')` would return `\"bar\"`.\n */\nfunction getFirstQueryParam(req: Request, key: string): string | null {\n const val = req.query[key];\n if (val === null || val === undefined) {\n return null;\n }\n if (Array.isArray(val)) {\n if (val.length === 0) {\n return null;\n }\n return String(val[0]);\n }\n return String(val);\n}\n\nfunction isWebCrawler(req: Request): boolean {\n const userAgentHeader = req.get('User-Agent');\n if (!userAgentHeader) {\n return false;\n }\n const userAgent = userAgentHeader.toLowerCase();\n return (\n userAgent.includes('googlebot') ||\n userAgent.includes('bingbot') ||\n userAgent.includes('twitterbot')\n );\n}\n","import path from 'node:path';\n\nimport {RootConfig} from '../core/config';\nimport {Route, RouteModule} from '../core/types';\n\nimport {RouteTrie} from './route-trie';\n\nexport function getRoutes(config: RootConfig) {\n const locales = config.i18n?.locales || [];\n const i18nUrlFormat = config.i18n?.urlFormat || '/{locale}/{path}';\n const defaultLocale = config.i18n?.defaultLocale || 'en';\n\n const routes = import.meta.glob(\n ['/routes/*.ts', '/routes/**/*.ts', '/routes/*.tsx', '/routes/**/*.tsx'],\n {\n eager: true,\n }\n );\n const trie = new RouteTrie<Route>();\n Object.keys(routes).forEach((modulePath) => {\n const src = modulePath.slice(1);\n let routePath = modulePath.replace(/^\\/routes/, '');\n const parts = path.parse(routePath);\n if (parts.name.startsWith('_')) {\n return;\n }\n if (parts.name === 'index') {\n routePath = parts.dir;\n } else {\n routePath = path.join(parts.dir, parts.name);\n }\n\n const localeRoutePath = i18nUrlFormat\n .replace('{locale}', '[locale]')\n .replace('{path}', routePath.replace(/^\\/*/, ''));\n\n trie.add(routePath, {\n src,\n module: routes[modulePath] as RouteModule,\n locale: defaultLocale,\n isDefaultLocale: true,\n routePath: normalizeUrlPath(routePath),\n localeRoutePath: normalizeUrlPath(localeRoutePath),\n });\n\n // At the moment, all routes are assumed to use the site-wide i18n config.\n // TODO(stevenle): provide routes with a way to override the default\n // i18n serving behavior.\n locales.forEach((locale) => {\n const localePath = localeRoutePath.replace('[locale]', locale);\n if (localePath !== routePath) {\n trie.add(localePath, {\n src,\n module: routes[modulePath] as RouteModule,\n locale: locale,\n isDefaultLocale: false,\n routePath,\n localeRoutePath,\n });\n }\n });\n });\n return trie;\n}\n\nexport async function getAllPathsForRoute(\n urlPathFormat: string,\n route: Route\n): Promise<Array<{urlPath: string; params: Record<string, string>}>> {\n const routeModule = route.module;\n if (!routeModule.default) {\n return [];\n }\n\n const urlPaths: Array<{urlPath: string; params: Record<string, string>}> = [];\n if (routeModule.getStaticPaths) {\n const staticPaths = await routeModule.getStaticPaths();\n if (staticPaths.paths) {\n staticPaths.paths.forEach(\n (pathParams: {params: Record<string, string>}) => {\n const urlPath = replaceParams(urlPathFormat, pathParams.params || {});\n if (pathContainsPlaceholders(urlPath)) {\n console.warn(\n `path contains placeholders: ${urlPathFormat}, double check getStaticPaths() and ensure all params are returned. more info: https://rootjs.dev/guide/routes#getStaticPaths`\n );\n } else {\n urlPaths.push({\n urlPath: normalizeUrlPath(urlPath),\n params: pathParams.params || {},\n });\n }\n }\n );\n }\n } else if (pathContainsPlaceholders(urlPathFormat)) {\n console.warn(\n `path contains placeholders: ${urlPathFormat}, did you forget to define getStaticPaths()? more info: https://rootjs.dev/guide/routes#getStaticPaths`\n );\n } else {\n urlPaths.push({urlPath: normalizeUrlPath(urlPathFormat), params: {}});\n }\n return urlPaths;\n}\n\nexport function replaceParams(\n urlPathFormat: string,\n params: Record<string, string>\n) {\n const urlPath = urlPathFormat.replaceAll(\n /\\[(\\.\\.\\.)?([\\w\\-_]*)\\]/g,\n (match: string, _wildcard: string, key: string) => {\n const val = params[key];\n if (!val) {\n throw new Error(`unreplaced param ${match} in url: ${urlPathFormat}`);\n }\n return val;\n }\n );\n return urlPath;\n}\n\nexport function normalizeUrlPath(urlPath: string) {\n if (urlPath !== '/' && urlPath.endsWith('/')) {\n urlPath = urlPath.replace(/\\/*$/g, '');\n }\n return urlPath;\n}\n\nfunction pathContainsPlaceholders(urlPath: string) {\n const segments = urlPath.split('/');\n return segments.some((segment) => {\n return segment.startsWith('[') && segment.endsWith(']');\n });\n}\n","/**\n * A trie data structure that stores routes. The trie supports `:param` and\n * `*wildcard` values.\n */\nexport class RouteTrie<T> {\n private children: Record<string, RouteTrie<T>> = {};\n private paramChildren?: {[param: string]: ParamChild<T>};\n private wildcardChild?: WildcardChild<T>;\n private route?: T;\n\n /**\n * Adds a route to the trie.\n */\n add(path: string, route: T) {\n path = this.normalizePath(path);\n\n // If the end was reached, save the value to the node.\n if (path === '') {\n this.route = route;\n return;\n }\n\n const [head, tail] = this.splitPath(path);\n if (head.startsWith('[...') && head.endsWith(']')) {\n const paramName = head.slice(4, -1);\n this.wildcardChild = new WildcardChild(paramName, route);\n return;\n }\n\n let nextNode: RouteTrie<T>;\n if (head.startsWith('[') && head.endsWith(']')) {\n if (!this.paramChildren) {\n this.paramChildren = {};\n }\n const paramName = head.slice(1, -1);\n if (!this.paramChildren[paramName]) {\n this.paramChildren[paramName] = new ParamChild(paramName);\n }\n nextNode = this.paramChildren[paramName].trie;\n } else {\n nextNode = this.children[head];\n if (!nextNode) {\n nextNode = new RouteTrie();\n this.children[head] = nextNode;\n }\n }\n nextNode.add(tail, route);\n }\n\n /**\n * Returns a route mapped to the given path and any parameter values from the\n * URL.\n */\n get(path: string): [T | undefined, Record<string, string>] {\n const params = {};\n const route = this.getRoute(path, params);\n return [route, params];\n }\n\n /**\n * Walks the route trie and calls a callback function for each route.\n */\n walk(cb: (urlPath: string, route: T) => Promise<void> | void): Promise<void> {\n const promises: Array<Promise<void>> = [];\n const addPromise = (promise: Promise<void> | void) => {\n if (promise) {\n promises.push(promise);\n }\n };\n if (this.route) {\n addPromise(cb('/', this.route));\n }\n if (this.paramChildren) {\n Object.values(this.paramChildren).forEach((paramChild) => {\n const param = `[${paramChild.name}]`;\n paramChild.trie.walk((childPath: string, route: T) => {\n const paramUrlPath = `/${param}${childPath}`;\n addPromise(cb(paramUrlPath, route));\n });\n });\n }\n if (this.wildcardChild) {\n const wildcardUrlPath = `/[...${this.wildcardChild.name}]`;\n addPromise(cb(wildcardUrlPath, this.wildcardChild.route));\n }\n for (const subpath of Object.keys(this.children)) {\n const childTrie = this.children[subpath];\n childTrie.walk((childPath: string, childRoute: T) => {\n addPromise(cb(`/${subpath}${childPath}`, childRoute));\n });\n }\n return Promise.all(promises).then(() => {});\n }\n\n /**\n * Removes all routes from the trie.\n */\n clear() {\n this.children = {};\n this.paramChildren = undefined;\n this.wildcardChild = undefined;\n this.route = undefined;\n }\n\n private getRoute(\n urlPath: string,\n params: Record<string, string>\n ): T | undefined {\n urlPath = this.normalizePath(urlPath);\n if (urlPath === '') {\n return this.route;\n }\n\n const [head, tail] = this.splitPath(urlPath);\n\n const child = this.children[head];\n if (child) {\n const route = child.getRoute(tail, params);\n if (route) {\n return route;\n }\n }\n\n if (this.paramChildren) {\n for (const paramChild of Object.values(this.paramChildren)) {\n const route = paramChild.trie.getRoute(tail, params);\n if (route) {\n params[paramChild.name] = head;\n return route;\n }\n }\n }\n\n if (this.wildcardChild) {\n params[this.wildcardChild.name] = urlPath;\n return this.wildcardChild.route;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a path for inclusion into the route trie.\n */\n private normalizePath(path: string) {\n // Remove leading slashes.\n return path.replace(/^\\/+/g, '');\n }\n\n /**\n * Splits the parent directory from its children, e.g.:\n *\n * splitPath(\"foo/bar/baz\") -> [\"foo\", \"bar/baz\"]\n */\n private splitPath(path: string): [string, string] {\n const i = path.indexOf('/');\n if (i === -1) {\n return [path, ''];\n }\n return [path.slice(0, i), path.slice(i + 1)];\n }\n}\n\n/**\n * A node in the RouteTrie for a :param child.\n */\nclass ParamChild<T> {\n readonly name: string;\n readonly trie: RouteTrie<T> = new RouteTrie();\n\n constructor(name: string) {\n this.name = name;\n }\n}\n\n/**\n * A node in the RouteTrie for a *wildcard child.\n */\nclass WildcardChild<T> {\n readonly name: string;\n readonly route: T;\n\n constructor(name: string, route: T) {\n this.name = name;\n this.route = route;\n }\n}\n"],"mappings":"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","names":["Fragment","jsx","jsxs","jsx","jsxs","path","jsx","jsxs","props"]}
@@ -4,31 +4,9 @@ import { PluginOption, UserConfig, ViteDevServer } from 'vite';
4
4
  import { Options } from 'html-minifier-terser';
5
5
  import { HTMLBeautifyOptions } from 'js-beautify';
6
6
 
7
- interface Asset {
8
- /**
9
- * The path to the asset's src file, relative to the project root.
10
- */
11
- src: string;
12
- /**
13
- * The serving URL for the asset.
14
- */
15
- assetUrl: string;
16
- /**
17
- * Recursively walks all deps and returns a list of CSS asset URLs.
18
- */
19
- getCssDeps(): Promise<string[]>;
20
- /**
21
- * Recursively walks all deps and returns a list of JS asset URLs.
22
- */
23
- getJsDeps(): Promise<string[]>;
24
- }
25
- interface AssetMap {
26
- /**
27
- * Returns the asset for a given src file. The `src` value should be a path
28
- * relative to the project root, e.g. "routes/index.tsx".
29
- */
30
- get: (src: string) => Promise<Asset | null>;
31
- }
7
+ declare type HtmlMinifyOptions = Options;
8
+
9
+ declare type HtmlPrettyOptions = HTMLBeautifyOptions;
32
10
 
33
11
  declare type MaybePromise<T> = T | Promise<T>;
34
12
  declare type ConfigureServerHook = (server: Server, options: ConfigureServerOptions) => MaybePromise<void> | MaybePromise<() => void>;
@@ -70,10 +48,6 @@ interface Plugin {
70
48
  declare function configureServerPlugins(server: Server, callback: () => Promise<void>, plugins: Plugin[], options: ConfigureServerOptions): Promise<void>;
71
49
  declare function getVitePlugins(plugins: Plugin[]): PluginOption[];
72
50
 
73
- declare type HtmlMinifyOptions = Options;
74
-
75
- declare type HtmlPrettyOptions = HTMLBeautifyOptions;
76
-
77
51
  interface RootUserConfig {
78
52
  /**
79
53
  * Canonical domain the website will serve on. Useful for things like the
@@ -137,6 +111,10 @@ interface RootUserConfig {
137
111
  declare type RootConfig = RootUserConfig & {
138
112
  rootDir: string;
139
113
  };
114
+ interface LocaleGroup {
115
+ label?: string;
116
+ locales: string[];
117
+ }
140
118
  interface RootI18nConfig {
141
119
  /**
142
120
  * Locales enabled for the site.
@@ -150,6 +128,11 @@ interface RootI18nConfig {
150
128
  * URL format for localized content. Default is `/{locale}/{path}`.
151
129
  */
152
130
  urlFormat?: string;
131
+ /**
132
+ * Localization groups, to help UIs (like Root.js CMS) logically group
133
+ * locales.
134
+ */
135
+ groups?: Record<string, LocaleGroup>;
153
136
  }
154
137
  interface RootServerConfig {
155
138
  /**
@@ -157,6 +140,16 @@ interface RootServerConfig {
157
140
  * added to the beginning of the express app.
158
141
  */
159
142
  middlewares?: Array<(req: Request, res: Response, next: NextFunction) => void | Promise<void>>;
143
+ /**
144
+ * The `trailingSlash` config allows you to control how the server handles
145
+ * trailing slashes. This config only affects URLs that do not have a file
146
+ * extension (i.e. HTML paths).
147
+ *
148
+ * - When `true`, the server redirects URLs to add a trailing slash
149
+ * - When `false`, the server redirects URLs to remove a trailing slash
150
+ * - When unspecified, the server allows URLs with and without trailing slash
151
+ */
152
+ trailingSlash?: boolean;
160
153
  }
161
154
  declare function defineConfig(config: RootUserConfig): RootUserConfig;
162
155
 
@@ -184,6 +177,16 @@ declare class ElementGraph {
184
177
  constructor(sourceFiles: {
185
178
  [tagName: string]: ElementSourceFile;
186
179
  });
180
+ toJson(): {
181
+ sourceFiles: {
182
+ [tagName: string]: ElementSourceFile;
183
+ };
184
+ deps: Record<string, string[]>;
185
+ };
186
+ static fromJson(data: {
187
+ deps: any;
188
+ sourceFiles: any;
189
+ }): ElementGraph;
187
190
  getDeps(tagName: string, visited?: Set<string>): string[];
188
191
  /**
189
192
  * Parses an element's source file for usage of other custom elements.
@@ -191,6 +194,32 @@ declare class ElementGraph {
191
194
  private parseDepsFromSource;
192
195
  }
193
196
 
197
+ interface Asset {
198
+ /**
199
+ * The path to the asset's src file, relative to the project root.
200
+ */
201
+ src: string;
202
+ /**
203
+ * The serving URL for the asset.
204
+ */
205
+ assetUrl: string;
206
+ /**
207
+ * Recursively walks all deps and returns a list of CSS asset URLs.
208
+ */
209
+ getCssDeps(): Promise<string[]>;
210
+ /**
211
+ * Recursively walks all deps and returns a list of JS asset URLs.
212
+ */
213
+ getJsDeps(): Promise<string[]>;
214
+ }
215
+ interface AssetMap {
216
+ /**
217
+ * Returns the asset for a given src file. The `src` value should be a path
218
+ * relative to the project root, e.g. "routes/index.tsx".
219
+ */
220
+ get: (src: string) => Promise<Asset | null>;
221
+ }
222
+
194
223
  declare class Renderer {
195
224
  private rootConfig;
196
225
  private routes;
@@ -214,10 +243,14 @@ declare class Renderer {
214
243
  params: Record<string, string>;
215
244
  }>>;
216
245
  private renderHtml;
217
- render404(): Promise<{
246
+ render404(options?: {
247
+ currentPath?: string;
248
+ }): Promise<{
218
249
  html: string;
219
250
  }>;
220
- renderError(err: any): Promise<{
251
+ renderError(err: any, options?: {
252
+ currentPath?: string;
253
+ }): Promise<{
221
254
  html: string;
222
255
  }>;
223
256
  renderDevServer404(req: Request): Promise<{
@@ -249,6 +282,14 @@ declare type GetStaticProps<T = unknown> = (ctx: {
249
282
  }) => Promise<{
250
283
  /** Props to pass to the component. */
251
284
  props?: T;
285
+ /** The rendered locale. */
286
+ locale?: string;
287
+ /**
288
+ * Translations to pass to `useTranslations()`. If provided, the translations
289
+ * map passed here will be merged with the translations from
290
+ * `/translations/{locale}.json`.
291
+ */
292
+ translations?: Record<string, string>;
252
293
  /** Set to true if the route should result in a 404 page. */
253
294
  notFound?: boolean;
254
295
  }>;
@@ -298,8 +339,19 @@ interface HandlerContext<T = any> {
298
339
  * pass `{slug: 'foo'}`.
299
340
  */
300
341
  params: RouteParams;
342
+ /**
343
+ * i18n locales to try for the user's http request. The priority order mimics
344
+ * the Firebase Hosting i18n fallback logic.
345
+ * https://firebase.google.com/docs/hosting/i18n-rewrites#priority-order
346
+ */
347
+ i18nFallbackLocales: string[];
348
+ /**
349
+ * Iterates through the i18nFallbackLocales and returns the first available
350
+ * locale.
351
+ */
352
+ getPreferredLocale: (availableLocales: string[]) => string;
301
353
  /** Renders the default exported component from the route. */
302
- render: (props: T) => Promise<void>;
354
+ render: HandlerRenderFn;
303
355
  /** Renders a 404 page. */
304
356
  render404: () => Promise<void>;
305
357
  }
@@ -323,6 +375,13 @@ interface Route {
323
375
  module: RouteModule;
324
376
  /** The locale used for the route. */
325
377
  locale: string;
378
+ /**
379
+ * Returns `true` if the route is the default locale route mapped without the
380
+ * i18n url prefix. For example, a route may be mapped to `/foo` and
381
+ * `/[locale]/foo`. The `/foo` route would have `route.isDefaultLocale` set to
382
+ * `true` whereas for `/[locale]/foo` it would be `false`.
383
+ */
384
+ isDefaultLocale: boolean;
326
385
  /**
327
386
  * The mapped URL path for the route, e.g.:
328
387
  *
@@ -339,5 +398,16 @@ interface Route {
339
398
  */
340
399
  localeRoutePath: string;
341
400
  }
401
+ interface HandlerRenderOptions {
402
+ /** The rendered locale. */
403
+ locale?: string;
404
+ /**
405
+ * Translations to pass to `useTranslations()`. If provided, the translations
406
+ * map passed here will be merged with the translations from
407
+ * `/translations/{locale}.json`.
408
+ */
409
+ translations?: Record<string, string>;
410
+ }
411
+ declare type HandlerRenderFn = (props: any, options?: HandlerRenderOptions) => Promise<void>;
342
412
 
343
- export { ConfigureServerHook as C, GetStaticProps as G, HandlerContext as H, NextFunction as N, Plugin as P, Route as R, Server as S, RootUserConfig as a, RootConfig as b, RootI18nConfig as c, RootServerConfig as d, defineConfig as e, ConfigureServerOptions as f, configureServerPlugins as g, getVitePlugins as h, RouteParams as i, GetStaticPaths as j, Request as k, Response as l, Handler as m, RouteModule as n, Renderer as o };
413
+ export { ConfigureServerHook as C, GetStaticProps as G, HandlerContext as H, LocaleGroup as L, NextFunction as N, Plugin as P, Route as R, Server as S, RootUserConfig as a, RootConfig as b, RootI18nConfig as c, RootServerConfig as d, defineConfig as e, ConfigureServerOptions as f, configureServerPlugins as g, getVitePlugins as h, RouteParams as i, GetStaticPaths as j, Request as k, Response as l, Handler as m, RouteModule as n, HandlerRenderOptions as o, HandlerRenderFn as p, Renderer as q };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkk/root",
3
- "version": "1.0.0-beta.5",
3
+ "version": "1.0.0-beta.51",
4
4
  "author": "s@blinkk.com",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -27,10 +27,26 @@
27
27
  "types": "./dist/core.d.ts",
28
28
  "import": "./dist/core.js"
29
29
  },
30
+ "./cli": {
31
+ "types": "./dist/cli.d.ts",
32
+ "import": "./dist/cli.js"
33
+ },
30
34
  "./client": "./client.d.ts",
31
- "./*": {
32
- "types": "./dist/*.d.ts",
33
- "import": "./dist/*.js"
35
+ "./core": {
36
+ "types": "./dist/core.d.ts",
37
+ "import": "./dist/core.js"
38
+ },
39
+ "./functions": {
40
+ "types": "./dist/functions.d.ts",
41
+ "import": "./dist/functions.js"
42
+ },
43
+ "./node": {
44
+ "types": "./dist/node.d.ts",
45
+ "import": "./dist/node.js"
46
+ },
47
+ "./render": {
48
+ "types": "./dist/render.d.ts",
49
+ "import": "./dist/render.js"
34
50
  }
35
51
  },
36
52
  "dependencies": {
@@ -49,9 +65,19 @@
49
65
  "vite": "4.2.0"
50
66
  },
51
67
  "peerDependencies": {
68
+ "firebase-admin": ">=11",
69
+ "firebase-functions": ">=4",
52
70
  "preact": "10.x",
53
71
  "preact-render-to-string": "5.x"
54
72
  },
73
+ "peerDependenciesMeta": {
74
+ "firebase-functions": {
75
+ "optional": true
76
+ },
77
+ "firebase-admin": {
78
+ "optional": true
79
+ }
80
+ },
55
81
  "devDependencies": {
56
82
  "@types/compression": "^1.7.2",
57
83
  "@types/express": "^4.17.13",
@@ -60,6 +86,8 @@
60
86
  "@types/js-beautify": "^1.13.3",
61
87
  "@types/node": "^18.7.14",
62
88
  "@types/preact-custom-element": "^4.0.1",
89
+ "firebase-admin": "^11.5.0",
90
+ "firebase-functions": "^4.4.0",
63
91
  "nodemon": "^2.0.19",
64
92
  "preact": "^10.10.6",
65
93
  "preact-custom-element": "^4.2.1",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/plugin.ts"],"sourcesContent":["import {PluginOption as VitePlugin} from 'vite';\nimport {RootConfig} from './config';\nimport {Server} from './types';\n\ntype MaybePromise<T> = T | Promise<T>;\n\nexport type ConfigureServerHook = (\n server: Server,\n options: ConfigureServerOptions\n) => MaybePromise<void> | MaybePromise<() => void>;\n\nexport interface ConfigureServerOptions {\n type: 'dev' | 'preview' | 'prod';\n rootConfig: RootConfig;\n}\n\nexport interface Plugin {\n [key: string]: any;\n /** The name of the plugin. */\n name?: string;\n /**\n * Configures the root.js express server. Any middleware defined by the plugin\n * will be added to the server first. If a callback fn is returned, it will\n * be called after the root.js middlewares are added.\n */\n configureServer?: ConfigureServerHook;\n /**\n * Returns a list of deps to bundle for ssr. The files will be bundled and\n * output to `dist/server/`. The return value should be a map of\n * `{output filename => input filepath}`.\n *\n * E.g. a value of `{foo: 'path/to/bar.js'}` will output `dist/server/foo.js`.\n *\n * @experimental This config is subject to change to be incorporated into a\n * broader config option called \"ssr\" or \"ssrOptions\".\n */\n ssrInput?: () => {[entryAlias: string]: string};\n /** Adds vite plugins. */\n vitePlugins?: VitePlugin[];\n}\n\n/**\n * Runs the pre-hook configureServer method of every plugin, calls a callback\n * function, and then runs the configureServer's post-hook if provided. Plugins\n * provide a post-hook by returning a callback function from configureServer.\n */\nexport async function configureServerPlugins(\n server: Server,\n callback: () => Promise<void>,\n plugins: Plugin[],\n options: ConfigureServerOptions\n) {\n const postHooks: Array<() => void> = [];\n\n // Call the `configureServer()` method for each plugin.\n for (const plugin of plugins) {\n if (plugin.configureServer) {\n const postHook = await plugin.configureServer(server, options);\n if (postHook) {\n postHooks.push(postHook);\n }\n }\n }\n\n // Register any built-in middleware.\n callback();\n\n // Run any post hooks returned by `plugin.configureServer()`.\n for (const postHook of postHooks) {\n await postHook();\n }\n}\n\nexport function getVitePlugins(plugins: Plugin[]): VitePlugin[] {\n const vitePlugins: VitePlugin[] = [];\n for (const plugin of plugins) {\n if (plugin.vitePlugins) {\n vitePlugins.push(...plugin.vitePlugins);\n }\n }\n return vitePlugins;\n}\n"],"mappings":";AA8CA,eAAsB,uBACpB,QACA,UACA,SACA,SACA;AACA,QAAM,YAA+B,CAAC;AAGtC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,iBAAiB;AAC1B,YAAM,WAAW,MAAM,OAAO,gBAAgB,QAAQ,OAAO;AAC7D,UAAI,UAAU;AACZ,kBAAU,KAAK,QAAQ;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAGA,WAAS;AAGT,aAAW,YAAY,WAAW;AAChC,UAAM,SAAS;AAAA,EACjB;AACF;AAEO,SAAS,eAAe,SAAiC;AAC9D,QAAM,cAA4B,CAAC;AACnC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,aAAa;AACtB,kBAAY,KAAK,GAAG,OAAO,WAAW;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/node/load-config.ts","../src/utils/fsutils.ts","../src/node/vite.ts"],"sourcesContent":["import path from 'node:path';\nimport {bundleRequire} from 'bundle-require';\nimport {RootConfig} from '../core/config';\nimport {fileExists} from '../utils/fsutils';\n\nexport interface ConfigOptions {\n command: string;\n}\n\nexport async function loadRootConfig(\n rootDir: string,\n options: ConfigOptions\n): Promise<RootConfig> {\n const configPath = path.resolve(rootDir, 'root.config.ts');\n const exists = await fileExists(configPath);\n if (!exists) {\n throw new Error(`${configPath} does not exist`);\n }\n const configBundle = await bundleRequire({\n filepath: configPath,\n });\n let config = configBundle.mod.default || {};\n if (typeof config === 'function') {\n config = (await config(options)) || {};\n }\n return Object.assign({}, config, {rootDir});\n}\n","import {promises as fs} from 'node:fs';\nimport path from 'node:path';\nimport fsExtra from 'fs-extra';\nimport glob from 'tiny-glob';\n\nexport function isJsFile(filename: string) {\n return !!filename.match(/\\.(j|t)sx?$/);\n}\n\nexport async function writeFile(filepath: string, content: string) {\n const dirPath = path.dirname(filepath);\n await makeDir(dirPath);\n await fs.writeFile(filepath, content);\n}\n\nexport async function makeDir(dirpath: string) {\n try {\n await fs.access(dirpath);\n } catch (e) {\n await fs.mkdir(dirpath, {recursive: true});\n }\n}\n\nexport async function copyDir(srcdir: string, dstdir: string) {\n if (!fsExtra.existsSync(srcdir)) {\n return;\n }\n fsExtra.copySync(srcdir, dstdir, {recursive: true, overwrite: true});\n}\n\n/**\n * Copies a glob of files from one directory to another.\n *\n * Example:\n *\n * ```\n * await copyGlob('*.css', 'src/styles', 'dist/html/styles');\n * ```\n */\nexport async function copyGlob(\n pattern: string,\n srcdir: string,\n dstdir: string\n) {\n const files = await glob(pattern, {cwd: srcdir});\n if (files.length > 0) {\n await makeDir(dstdir);\n }\n files.forEach((file) => {\n fsExtra.copySync(path.resolve(srcdir, file), path.resolve(dstdir, file));\n });\n}\n\nexport async function rmDir(dirpath: string) {\n await fs.rm(dirpath, {recursive: true, force: true});\n}\n\nexport async function loadJson<T = unknown>(filepath: string): Promise<T> {\n const content = await fs.readFile(filepath, 'utf-8');\n return JSON.parse(content);\n}\n\nexport async function isDirectory(dirpath: string) {\n return fs\n .stat(dirpath)\n .then((fsStat) => {\n return fsStat.isDirectory();\n })\n .catch((err) => {\n if (err.code === 'ENOENT') {\n return false;\n }\n throw err;\n });\n}\n\nexport function fileExists(filepath: string): Promise<boolean> {\n return fs\n .access(filepath)\n .then(() => true)\n .catch(() => false);\n}\n\nexport async function directoryContains(\n dirpath: string,\n subpath: string\n): Promise<boolean> {\n const outer = await fs.realpath(dirpath);\n const inner = await fs.realpath(subpath);\n const rel = path.relative(outer, inner);\n return !rel.startsWith('..');\n}\n","import path from 'node:path';\nimport {createServer, ViteDevServer} from 'vite';\nimport {getVitePlugins} from '../core/plugin.js';\nimport {RootConfig} from '../core/config.js';\n\nexport interface CreateViteServerOptions {\n /** Override HMR settings. */\n hmr?: boolean;\n /** The port the server will run on. */\n port?: number;\n /** List of files to include in the optimizeDeps.include config. */\n optimizeDeps?: string[];\n}\n\n/**\n * Returns a vite dev server.\n */\nexport async function createViteServer(\n rootConfig: RootConfig,\n options?: CreateViteServerOptions\n): Promise<ViteDevServer> {\n const rootDir = rootConfig.rootDir;\n const viteConfig = rootConfig.vite || {};\n\n let hmrOptions = viteConfig.server?.hmr;\n if (options?.hmr === false) {\n hmrOptions = false;\n } else if (typeof hmrOptions === 'undefined' && options?.port) {\n // Automatically set the HMR port to `port + 10`. This allows multiple\n // root.js dev servers to run without conflicts.\n hmrOptions = {port: options.port + 10};\n }\n\n const viteServer = await createServer({\n ...viteConfig,\n mode: 'development',\n root: rootDir,\n publicDir: path.join(rootDir, 'public'),\n server: {\n ...(viteConfig.server || {}),\n middlewareMode: true,\n hmr: hmrOptions,\n },\n appType: 'custom',\n optimizeDeps: {\n ...(viteConfig.optimizeDeps || {}),\n include: [\n ...(options?.optimizeDeps || []),\n ...(viteConfig.optimizeDeps?.include || []),\n ],\n },\n ssr: {\n ...(viteConfig.ssr || {}),\n noExternal: ['@blinkk/root'],\n },\n esbuild: {\n ...(viteConfig.esbuild || {}),\n jsx: 'automatic',\n jsxImportSource: 'preact',\n },\n plugins: [\n ...(viteConfig.plugins || []),\n ...getVitePlugins(rootConfig.plugins || []),\n ],\n });\n return viteServer;\n}\n\n/**\n * Shortcut `viteServer.ssrLoadModule()` without starting an actual dev server.\n */\nexport async function viteSsrLoadModule(\n rootConfig: RootConfig,\n file: string\n): Promise<Record<string, any>> {\n const viteServer = await createViteServer(rootConfig, {hmr: false});\n const module = await viteServer.ssrLoadModule(file);\n await viteServer.close();\n return module;\n}\n"],"mappings":";;;;;AAAA,OAAOA,WAAU;AACjB,SAAQ,qBAAoB;;;ACD5B,SAAQ,YAAY,UAAS;AAC7B,OAAO,UAAU;AACjB,OAAO,aAAa;AACpB,OAAO,UAAU;AAEV,SAAS,SAAS,UAAkB;AACzC,SAAO,CAAC,CAAC,SAAS,MAAM,aAAa;AACvC;AAEA,eAAsB,UAAU,UAAkB,SAAiB;AACjE,QAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAM,QAAQ,OAAO;AACrB,QAAM,GAAG,UAAU,UAAU,OAAO;AACtC;AAEA,eAAsB,QAAQ,SAAiB;AAC7C,MAAI;AACF,UAAM,GAAG,OAAO,OAAO;AAAA,EACzB,SAAS,GAAP;AACA,UAAM,GAAG,MAAM,SAAS,EAAC,WAAW,KAAI,CAAC;AAAA,EAC3C;AACF;AAkBA,eAAsB,SACpB,SACA,QACA,QACA;AACA,QAAM,QAAQ,MAAM,KAAK,SAAS,EAAC,KAAK,OAAM,CAAC;AAC/C,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,QAAQ,MAAM;AAAA,EACtB;AACA,QAAM,QAAQ,CAAC,SAAS;AACtB,YAAQ,SAAS,KAAK,QAAQ,QAAQ,IAAI,GAAG,KAAK,QAAQ,QAAQ,IAAI,CAAC;AAAA,EACzE,CAAC;AACH;AAEA,eAAsB,MAAM,SAAiB;AAC3C,QAAM,GAAG,GAAG,SAAS,EAAC,WAAW,MAAM,OAAO,KAAI,CAAC;AACrD;AAEA,eAAsB,SAAsB,UAA8B;AACxE,QAAM,UAAU,MAAM,GAAG,SAAS,UAAU,OAAO;AACnD,SAAO,KAAK,MAAM,OAAO;AAC3B;AAEA,eAAsB,YAAY,SAAiB;AACjD,SAAO,GACJ,KAAK,OAAO,EACZ,KAAK,CAAC,WAAW;AAChB,WAAO,OAAO,YAAY;AAAA,EAC5B,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,QAAI,IAAI,SAAS,UAAU;AACzB,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR,CAAC;AACL;AAEO,SAAS,WAAW,UAAoC;AAC7D,SAAO,GACJ,OAAO,QAAQ,EACf,KAAK,MAAM,IAAI,EACf,MAAM,MAAM,KAAK;AACtB;AAEA,eAAsB,kBACpB,SACA,SACkB;AAClB,QAAM,QAAQ,MAAM,GAAG,SAAS,OAAO;AACvC,QAAM,QAAQ,MAAM,GAAG,SAAS,OAAO;AACvC,QAAM,MAAM,KAAK,SAAS,OAAO,KAAK;AACtC,SAAO,CAAC,IAAI,WAAW,IAAI;AAC7B;;;ADlFA,eAAsB,eACpB,SACA,SACqB;AACrB,QAAM,aAAaC,MAAK,QAAQ,SAAS,gBAAgB;AACzD,QAAM,SAAS,MAAM,WAAW,UAAU;AAC1C,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,GAAG,2BAA2B;AAAA,EAChD;AACA,QAAM,eAAe,MAAM,cAAc;AAAA,IACvC,UAAU;AAAA,EACZ,CAAC;AACD,MAAI,SAAS,aAAa,IAAI,WAAW,CAAC;AAC1C,MAAI,OAAO,WAAW,YAAY;AAChC,aAAU,MAAM,OAAO,OAAO,KAAM,CAAC;AAAA,EACvC;AACA,SAAO,OAAO,OAAO,CAAC,GAAG,QAAQ,EAAC,QAAO,CAAC;AAC5C;;;AE1BA,OAAOC,WAAU;AACjB,SAAQ,oBAAkC;AAgB1C,eAAsB,iBACpB,YACA,SACwB;AApB1B;AAqBE,QAAM,UAAU,WAAW;AAC3B,QAAM,aAAa,WAAW,QAAQ,CAAC;AAEvC,MAAI,cAAa,gBAAW,WAAX,mBAAmB;AACpC,OAAI,mCAAS,SAAQ,OAAO;AAC1B,iBAAa;AAAA,EACf,WAAW,OAAO,eAAe,gBAAe,mCAAS,OAAM;AAG7D,iBAAa,EAAC,MAAM,QAAQ,OAAO,GAAE;AAAA,EACvC;AAEA,QAAM,aAAa,MAAM,aAAa;AAAA,IACpC,GAAG;AAAA,IACH,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAWC,MAAK,KAAK,SAAS,QAAQ;AAAA,IACtC,QAAQ;AAAA,MACN,GAAI,WAAW,UAAU,CAAC;AAAA,MAC1B,gBAAgB;AAAA,MAChB,KAAK;AAAA,IACP;AAAA,IACA,SAAS;AAAA,IACT,cAAc;AAAA,MACZ,GAAI,WAAW,gBAAgB,CAAC;AAAA,MAChC,SAAS;AAAA,QACP,IAAI,mCAAS,iBAAgB,CAAC;AAAA,QAC9B,KAAI,gBAAW,iBAAX,mBAAyB,YAAW,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,IACA,KAAK;AAAA,MACH,GAAI,WAAW,OAAO,CAAC;AAAA,MACvB,YAAY,CAAC,cAAc;AAAA,IAC7B;AAAA,IACA,SAAS;AAAA,MACP,GAAI,WAAW,WAAW,CAAC;AAAA,MAC3B,KAAK;AAAA,MACL,iBAAiB;AAAA,IACnB;AAAA,IACA,SAAS;AAAA,MACP,GAAI,WAAW,WAAW,CAAC;AAAA,MAC3B,GAAG,eAAe,WAAW,WAAW,CAAC,CAAC;AAAA,IAC5C;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAKA,eAAsB,kBACpB,YACA,MAC8B;AAC9B,QAAM,aAAa,MAAM,iBAAiB,YAAY,EAAC,KAAK,MAAK,CAAC;AAClE,QAAM,SAAS,MAAM,WAAW,cAAc,IAAI;AAClD,QAAM,WAAW,MAAM;AACvB,SAAO;AACT;","names":["path","path","path","path"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/components/Html.tsx","../src/core/hooks/useI18nContext.ts","../src/core/hooks/useRequestContext.ts"],"sourcesContent":["import {ComponentChildren, FunctionalComponent, createContext} from 'preact';\nimport {useContext} from 'preact/hooks';\n\nexport interface HtmlContext {\n htmlAttrs: preact.JSX.HTMLAttributes<HTMLHtmlElement>;\n headAttrs: preact.JSX.HTMLAttributes<HTMLHeadElement>;\n headComponents: ComponentChildren[];\n bodyAttrs: preact.JSX.HTMLAttributes<HTMLBodyElement>;\n scriptDeps: Array<preact.JSX.HTMLAttributes<HTMLScriptElement>>;\n}\n\nexport const HTML_CONTEXT = createContext<HtmlContext | null>(null);\n\nexport type HtmlProps = preact.JSX.HTMLAttributes<HTMLHtmlElement> & {\n children?: ComponentChildren;\n};\n\n/**\n * The `<Html>` component can be used to update attrs in the `<html>` tag.\n *\n * Usage:\n *\n * ```tsx\n * <Html lang=\"en-US\">\n * <h1>Hello world</h1>\n * </Html>\n * ```\n */\nexport const Html: FunctionalComponent<HtmlProps> = ({children, ...attrs}) => {\n const context = useContext(HTML_CONTEXT);\n if (!context) {\n throw new Error(\n 'HTML_CONTEXT not found, double-check usage of the <Html> component'\n );\n }\n context.htmlAttrs = attrs;\n return <>{children}</>;\n};\n","import path from 'node:path';\nimport {createContext} from 'preact';\nimport {useContext} from 'preact/hooks';\n\nexport const I18N_CONTEXT = createContext<I18nContext | null>(null);\n\nexport interface I18nContext {\n locale: string;\n translations: Record<string, string>;\n}\n\n/**\n * A hook that returns information about the current i18n context, including the\n * locale for the given route and a map of translations for that locale.\n */\nexport function useI18nContext() {\n const context = useContext(I18N_CONTEXT);\n if (!context) {\n throw new Error('I18N_CONTEXT not found');\n }\n return context;\n}\n\nexport function getTranslations(locale: string): Record<string, string> {\n const translations: Record<string, Record<string, string>> = {};\n const translationsFiles = import.meta.glob(['/translations/*.json'], {\n eager: true,\n }) as Record<string, {default?: Record<string, string>}>;\n Object.keys(translationsFiles).forEach((translationPath) => {\n const parts = path.parse(translationPath);\n const locale = parts.name;\n const module = translationsFiles[translationPath];\n if (module && module.default) {\n translations[locale] = module.default;\n }\n });\n return translations[locale] || {};\n}\n","import {createContext} from 'preact';\nimport {useContext} from 'preact/hooks';\nimport {Route} from '../types';\n\nexport interface RequestContext {\n /** The route file. */\n route: Route;\n /**\n * Route param values. E.g. for a route like `routes/blog/[slug].tsx`,\n * visiting `/blog/foo` will pass {slug: 'foo'} here.\n */\n routeParams: Record<string, string>;\n /** Props passed to the route's server component. */\n props: any;\n /** The current locale. */\n locale: string;\n /** Translations map for the current locale. */\n translations: Record<string, string>;\n}\n\nexport const REQUEST_CONTEXT = createContext<RequestContext | null>(null);\n\n/**\n * A hook that returns information about the current route.\n *\n * Usage:\n *\n * ```ts\n * const ctx = useRequestContext();\n * ctx.route.src;\n * // => 'routes/index.tsx'\n * ```\n */\nexport function useRequestContext() {\n const context = useContext(REQUEST_CONTEXT);\n if (!context) {\n throw new Error('REQUEST_CONTEXT not found');\n }\n return context;\n}\n"],"mappings":";AAAA,SAAgD,qBAAoB;AACpE,SAAQ,kBAAiB;AAmChB;AAzBF,IAAM,eAAe,cAAkC,IAAI;AAiB3D,IAAM,OAAuC,CAAC,EAAC,aAAa,MAAK,MAAM;AAC5E,QAAM,UAAU,WAAW,YAAY;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,UAAQ,YAAY;AACpB,SAAO;AAAA,IAAG;AAAA,GAAS;AACrB;;;ACrCA,OAAO,UAAU;AACjB,SAAQ,iBAAAA,sBAAoB;AAC5B,SAAQ,cAAAC,mBAAiB;AAElB,IAAM,eAAeD,eAAkC,IAAI;AAW3D,SAAS,iBAAiB;AAC/B,QAAM,UAAUC,YAAW,YAAY;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB,QAAwC;AACtE,QAAM,eAAuD,CAAC;AAC9D,QAAM,oBAAoB,YAAY,KAAK,CAAC,sBAAsB,GAAG;AAAA,IACnE,OAAO;AAAA,EACT,CAAC;AACD,SAAO,KAAK,iBAAiB,EAAE,QAAQ,CAAC,oBAAoB;AAC1D,UAAM,QAAQ,KAAK,MAAM,eAAe;AACxC,UAAMC,UAAS,MAAM;AACrB,UAAM,SAAS,kBAAkB;AACjC,QAAI,UAAU,OAAO,SAAS;AAC5B,mBAAaA,WAAU,OAAO;AAAA,IAChC;AAAA,EACF,CAAC;AACD,SAAO,aAAa,WAAW,CAAC;AAClC;;;ACrCA,SAAQ,iBAAAC,sBAAoB;AAC5B,SAAQ,cAAAC,mBAAiB;AAmBlB,IAAM,kBAAkBD,eAAqC,IAAI;AAajE,SAAS,oBAAoB;AAClC,QAAM,UAAUC,YAAW,eAAe;AAC1C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C;AACA,SAAO;AACT;","names":["createContext","useContext","locale","createContext","useContext"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/render/html-minify.ts","../src/utils/elements.ts","../src/render/html-pretty.ts"],"sourcesContent":["import {createRequire} from 'module';\nconst require = createRequire(import.meta.url);\nconst {minify} = require('html-minifier-terser');\nimport type {Options} from 'html-minifier-terser';\n\nexport type HtmlMinifyOptions = Options;\n\nexport async function htmlMinify(\n html: string,\n options?: HtmlMinifyOptions\n): Promise<string> {\n const minifyOptions = options || {\n collapseWhitespace: true,\n removeComments: true,\n preserveLineBreaks: true,\n };\n try {\n const min = await minify(html, minifyOptions);\n return min.trimStart();\n } catch (e) {\n console.error('failed to minify html:', e);\n return html;\n }\n}\n","export const ELEMENT_RE = /^[a-z][\\w-]*-[\\w-]*$/;\nexport const HTML_ELEMENTS_REGEX = /<([a-z][\\w-]*-[\\w-]*)/g;\n\n/**\n * Returns true if the tagName is a valid custom element tag.\n */\nexport function isValidTagName(tagName: string) {\n return ELEMENT_RE.test(tagName);\n}\n\n/**\n * Returns a list of custom elements used in a src string (e.g. HTML, jsx, lit).\n * NOTE: the impl uses a simple regex, so tagNames used in comments and attr\n * values may be included.\n */\nexport function parseTagNames(src: string): string[] {\n const tagNames = new Set<string>();\n const matches = Array.from(src.matchAll(HTML_ELEMENTS_REGEX));\n for (const match of matches) {\n const tagName = match[1];\n tagNames.add(tagName);\n }\n return Array.from(tagNames);\n}\n","import {createRequire} from 'module';\nconst require = createRequire(import.meta.url);\nconst beautify = require('js-beautify');\nimport type {HTMLBeautifyOptions} from 'js-beautify';\n\nexport type HtmlPrettyOptions = HTMLBeautifyOptions;\n\nexport async function htmlPretty(\n html: string,\n options?: HtmlPrettyOptions\n): Promise<string> {\n const prettyOptions = options || {\n indent_size: 0,\n end_with_newline: true,\n extra_liners: [],\n };\n try {\n const output = beautify.html(html, prettyOptions);\n return output.trimStart();\n } catch (e) {\n console.error('failed to pretty html:', e);\n return html;\n }\n}\n"],"mappings":";AAAA,SAAQ,qBAAoB;AAC5B,IAAMA,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,EAAC,OAAM,IAAIA,SAAQ,sBAAsB;AAK/C,eAAsB,WACpB,MACA,SACiB;AACjB,QAAM,gBAAgB,WAAW;AAAA,IAC/B,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,EACtB;AACA,MAAI;AACF,UAAM,MAAM,MAAM,OAAO,MAAM,aAAa;AAC5C,WAAO,IAAI,UAAU;AAAA,EACvB,SAAS,GAAP;AACA,YAAQ,MAAM,0BAA0B,CAAC;AACzC,WAAO;AAAA,EACT;AACF;;;ACvBO,IAAM,aAAa;AACnB,IAAM,sBAAsB;AAK5B,SAAS,eAAe,SAAiB;AAC9C,SAAO,WAAW,KAAK,OAAO;AAChC;AAOO,SAAS,cAAc,KAAuB;AACnD,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,UAAU,MAAM,KAAK,IAAI,SAAS,mBAAmB,CAAC;AAC5D,aAAW,SAAS,SAAS;AAC3B,UAAM,UAAU,MAAM;AACtB,aAAS,IAAI,OAAO;AAAA,EACtB;AACA,SAAO,MAAM,KAAK,QAAQ;AAC5B;;;ACvBA,SAAQ,iBAAAC,sBAAoB;AAC5B,IAAMC,WAAUD,eAAc,YAAY,GAAG;AAC7C,IAAM,WAAWC,SAAQ,aAAa;AAKtC,eAAsB,WACpB,MACA,SACiB;AACjB,QAAM,gBAAgB,WAAW;AAAA,IAC/B,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,cAAc,CAAC;AAAA,EACjB;AACA,MAAI;AACF,UAAM,SAAS,SAAS,KAAK,MAAM,aAAa;AAChD,WAAO,OAAO,UAAU;AAAA,EAC1B,SAAS,GAAP;AACA,YAAQ,MAAM,0BAA0B,CAAC;AACzC,WAAO;AAAA,EACT;AACF;","names":["require","createRequire","require"]}