@blinkk/root 1.0.0-alpha.8 → 1.0.0-beta.0
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/bin/root.js +1 -1
- package/dist/chunk-DTEQ2AIW.js +31 -0
- package/dist/chunk-DTEQ2AIW.js.map +1 -0
- package/dist/chunk-GGQGZ7ZE.js +61 -0
- package/dist/chunk-GGQGZ7ZE.js.map +1 -0
- package/dist/chunk-WTSNW7BB.js +68 -0
- package/dist/chunk-WTSNW7BB.js.map +1 -0
- package/dist/cli.js +777 -439
- package/dist/cli.js.map +1 -1
- package/dist/config-872b068d.d.ts +343 -0
- package/dist/core.d.ts +122 -19
- package/dist/core.js +78 -10
- package/dist/core.js.map +1 -1
- package/dist/render.d.ts +5 -61
- package/dist/render.js +417 -197
- package/dist/render.js.map +1 -1
- package/package.json +23 -25
- package/dist/chunk-ZV52A6YZ.js +0 -113
- package/dist/chunk-ZV52A6YZ.js.map +0 -1
- package/dist/types-2af24c42.d.ts +0 -66
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { Express, Request as Request$1, Response as Response$1, NextFunction as NextFunction$1 } from 'express';
|
|
2
|
+
import { ComponentType } from 'preact';
|
|
3
|
+
import { ViteDevServer, PluginOption, UserConfig } from 'vite';
|
|
4
|
+
import { Options } from 'html-minifier-terser';
|
|
5
|
+
import { HTMLBeautifyOptions } from 'js-beautify';
|
|
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
|
+
}
|
|
32
|
+
|
|
33
|
+
interface ElementSourceFile {
|
|
34
|
+
/** Full file path. */
|
|
35
|
+
filePath: string;
|
|
36
|
+
/** Path relative to the root project directory. */
|
|
37
|
+
relPath: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Dependency graph for element files to capture which other elements are used
|
|
41
|
+
* by any particular element.
|
|
42
|
+
*/
|
|
43
|
+
declare class ElementGraph {
|
|
44
|
+
/**
|
|
45
|
+
* Element tagName => sourceFile.
|
|
46
|
+
*/
|
|
47
|
+
readonly sourceFiles: {
|
|
48
|
+
[tagName: string]: ElementSourceFile;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Element tagName => set of element tagName dependencies.
|
|
52
|
+
*/
|
|
53
|
+
private deps;
|
|
54
|
+
constructor(sourceFiles: {
|
|
55
|
+
[tagName: string]: ElementSourceFile;
|
|
56
|
+
});
|
|
57
|
+
getDeps(tagName: string, visited?: Set<string>): string[];
|
|
58
|
+
/**
|
|
59
|
+
* Parses an element's source file for usage of other custom elements.
|
|
60
|
+
*/
|
|
61
|
+
private parseDepsFromSource;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare class Renderer {
|
|
65
|
+
private rootConfig;
|
|
66
|
+
private routes;
|
|
67
|
+
private assetMap;
|
|
68
|
+
private elementGraph;
|
|
69
|
+
constructor(rootConfig: RootConfig, options: {
|
|
70
|
+
assetMap: AssetMap;
|
|
71
|
+
elementGraph: ElementGraph;
|
|
72
|
+
});
|
|
73
|
+
handle(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
74
|
+
private renderComponent;
|
|
75
|
+
/** SSG renders a route. */
|
|
76
|
+
renderRoute(route: Route, options: {
|
|
77
|
+
routeParams: Record<string, string>;
|
|
78
|
+
}): Promise<{
|
|
79
|
+
html?: string;
|
|
80
|
+
notFound?: boolean;
|
|
81
|
+
}>;
|
|
82
|
+
getSitemap(): Promise<Record<string, {
|
|
83
|
+
route: Route;
|
|
84
|
+
params: Record<string, string>;
|
|
85
|
+
}>>;
|
|
86
|
+
private renderHtml;
|
|
87
|
+
render404(): Promise<{
|
|
88
|
+
html: string;
|
|
89
|
+
}>;
|
|
90
|
+
renderError(err: any): Promise<{
|
|
91
|
+
html: string;
|
|
92
|
+
}>;
|
|
93
|
+
renderDevServer404(req: Request): Promise<{
|
|
94
|
+
html: string;
|
|
95
|
+
}>;
|
|
96
|
+
renderDevServer500(req: Request, error: unknown): Promise<{
|
|
97
|
+
html: string;
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* Parses rendered HTML for custom element tags used on the page and
|
|
101
|
+
* automatically adds the JS/CSS deps to the page.
|
|
102
|
+
*/
|
|
103
|
+
private collectElementDeps;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Param values from the route, e.g. a route like `/route/[slug].tsx` will pass
|
|
108
|
+
* `{slug: 'foo'}`.
|
|
109
|
+
*/
|
|
110
|
+
declare type RouteParams = Record<string, string>;
|
|
111
|
+
/**
|
|
112
|
+
* The `getStaticProps()` function is an optional function that routes can
|
|
113
|
+
* define to fetch and transform props before passing it to the route's
|
|
114
|
+
* component.
|
|
115
|
+
*/
|
|
116
|
+
declare type GetStaticProps<T = unknown> = (ctx: {
|
|
117
|
+
rootConfig: RootConfig;
|
|
118
|
+
params: RouteParams;
|
|
119
|
+
}) => Promise<{
|
|
120
|
+
/** Props to pass to the component. */
|
|
121
|
+
props?: T;
|
|
122
|
+
/** Set to true if the route should result in a 404 page. */
|
|
123
|
+
notFound?: boolean;
|
|
124
|
+
}>;
|
|
125
|
+
/**
|
|
126
|
+
* The `getStaticPaths()` is used by the SSG build to determine all of the
|
|
127
|
+
* paths that should exist for a given route. This should be used alongside a
|
|
128
|
+
* parameterized route, e.g. `/routes/blog/[slug].tsx`.
|
|
129
|
+
*/
|
|
130
|
+
declare type GetStaticPaths<T = RouteParams> = () => Promise<{
|
|
131
|
+
paths: Array<{
|
|
132
|
+
params: T;
|
|
133
|
+
}>;
|
|
134
|
+
}>;
|
|
135
|
+
/** Root.js express app. */
|
|
136
|
+
declare type Server = Express;
|
|
137
|
+
/** Root.js express request. */
|
|
138
|
+
declare type Request = Request$1 & {
|
|
139
|
+
/** The root.js project config. */
|
|
140
|
+
rootConfig?: RootConfig & {
|
|
141
|
+
rootDir: string;
|
|
142
|
+
};
|
|
143
|
+
/** The vite dev server. This is only available when running `root dev`. */
|
|
144
|
+
viteServer?: ViteDevServer;
|
|
145
|
+
/** The root.js renderer, to render routes within middleware. */
|
|
146
|
+
renderer?: Renderer;
|
|
147
|
+
/**
|
|
148
|
+
* Handler context, provided to route files that export a custom `handler()`
|
|
149
|
+
* function.
|
|
150
|
+
*/
|
|
151
|
+
handlerContext?: HandlerContext;
|
|
152
|
+
};
|
|
153
|
+
/** Root.js express response. */
|
|
154
|
+
declare type Response = Response$1;
|
|
155
|
+
/** Root.js express next function. */
|
|
156
|
+
declare type NextFunction = NextFunction$1;
|
|
157
|
+
/**
|
|
158
|
+
* A context variable passed to a route's `handle()` method within the req
|
|
159
|
+
* object.
|
|
160
|
+
*/
|
|
161
|
+
interface HandlerContext<T = any> {
|
|
162
|
+
/**
|
|
163
|
+
* The resolved route.
|
|
164
|
+
*/
|
|
165
|
+
route: Route;
|
|
166
|
+
/**
|
|
167
|
+
* Param values from the route, e.g. a route like `/route/[slug].tsx` will
|
|
168
|
+
* pass `{slug: 'foo'}`.
|
|
169
|
+
*/
|
|
170
|
+
params: RouteParams;
|
|
171
|
+
/** Renders the default exported component from the route. */
|
|
172
|
+
render: (props: T) => Promise<void>;
|
|
173
|
+
/** Renders a 404 page. */
|
|
174
|
+
render404: () => Promise<void>;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* The `handle()` function can be exported by a route to define a custom express
|
|
178
|
+
* request handler. The `req` object will contain a `handlerContext` which
|
|
179
|
+
* contains the route's param values and also a `render()` method that can be
|
|
180
|
+
* used to render the route's default component.
|
|
181
|
+
*/
|
|
182
|
+
declare type Handler = (req: Request, res: Response, next: NextFunction) => void | Promise<void>;
|
|
183
|
+
interface RouteModule {
|
|
184
|
+
default?: ComponentType<unknown>;
|
|
185
|
+
getStaticPaths?: GetStaticPaths;
|
|
186
|
+
getStaticProps?: GetStaticProps;
|
|
187
|
+
handle?: Handler;
|
|
188
|
+
}
|
|
189
|
+
interface Route {
|
|
190
|
+
/** The relative path to the route file, e.g. `routes/index.tsx`. */
|
|
191
|
+
src: string;
|
|
192
|
+
/** The imported route module. */
|
|
193
|
+
module: RouteModule;
|
|
194
|
+
/** The locale used for the route. */
|
|
195
|
+
locale: string;
|
|
196
|
+
/**
|
|
197
|
+
* The mapped URL path for the route, e.g.:
|
|
198
|
+
*
|
|
199
|
+
* routes/index.tsx => `/`.
|
|
200
|
+
* routes/events.tsx => `/events`.
|
|
201
|
+
* routes/blog/[slug].tsx => `/blog/[slug]`.
|
|
202
|
+
*
|
|
203
|
+
* Per the example above, this value may contain placeholder params.
|
|
204
|
+
*/
|
|
205
|
+
routePath: string;
|
|
206
|
+
/**
|
|
207
|
+
* The localized URL path for the route, e.g. `/[locale]/blog/[slug]`.
|
|
208
|
+
* Per the example above, this value contains placeholder params.
|
|
209
|
+
*/
|
|
210
|
+
localeRoutePath: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
declare type MaybePromise<T> = T | Promise<T>;
|
|
214
|
+
declare type ConfigureServerHook = (server: Server, options: ConfigureServerOptions) => MaybePromise<void> | MaybePromise<() => void>;
|
|
215
|
+
interface ConfigureServerOptions {
|
|
216
|
+
type: 'dev' | 'preview' | 'prod';
|
|
217
|
+
rootConfig: RootConfig;
|
|
218
|
+
}
|
|
219
|
+
interface Plugin {
|
|
220
|
+
[key: string]: any;
|
|
221
|
+
/** The name of the plugin. */
|
|
222
|
+
name?: string;
|
|
223
|
+
/**
|
|
224
|
+
* Configures the root.js express server. Any middleware defined by the plugin
|
|
225
|
+
* will be added to the server first. If a callback fn is returned, it will
|
|
226
|
+
* be called after the root.js middlewares are added.
|
|
227
|
+
*/
|
|
228
|
+
configureServer?: ConfigureServerHook;
|
|
229
|
+
/**
|
|
230
|
+
* Returns a list of deps to bundle for ssr. The files will be bundled and
|
|
231
|
+
* output to `dist/server/`. The return value should be a map of
|
|
232
|
+
* `{output filename => input filepath}`.
|
|
233
|
+
*
|
|
234
|
+
* E.g. a value of `{foo: 'path/to/bar.js'}` will output `dist/server/foo.js`.
|
|
235
|
+
*
|
|
236
|
+
* @experimental This config is subject to change to be incorporated into a
|
|
237
|
+
* broader config option called "ssr" or "ssrOptions".
|
|
238
|
+
*/
|
|
239
|
+
ssrInput?: () => {
|
|
240
|
+
[entryAlias: string]: string;
|
|
241
|
+
};
|
|
242
|
+
/** Adds vite plugins. */
|
|
243
|
+
vitePlugins?: PluginOption[];
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Runs the pre-hook configureServer method of every plugin, calls a callback
|
|
247
|
+
* function, and then runs the configureServer's post-hook if provided. Plugins
|
|
248
|
+
* provide a post-hook by returning a callback function from configureServer.
|
|
249
|
+
*/
|
|
250
|
+
declare function configureServerPlugins(server: Server, callback: () => Promise<void>, plugins: Plugin[], options: ConfigureServerOptions): Promise<void>;
|
|
251
|
+
declare function getVitePlugins(plugins: Plugin[]): PluginOption[];
|
|
252
|
+
|
|
253
|
+
declare type HtmlMinifyOptions = Options;
|
|
254
|
+
|
|
255
|
+
declare type HtmlPrettyOptions = HTMLBeautifyOptions;
|
|
256
|
+
|
|
257
|
+
interface RootUserConfig {
|
|
258
|
+
/**
|
|
259
|
+
* Canonical domain the website will serve on. Useful for things like the
|
|
260
|
+
* sitemap, SEO tags, etc.
|
|
261
|
+
*/
|
|
262
|
+
domain?: string;
|
|
263
|
+
/**
|
|
264
|
+
* Config for auto-injecting custom element dependencies.
|
|
265
|
+
*/
|
|
266
|
+
elements?: {
|
|
267
|
+
/**
|
|
268
|
+
* A list of directories to use to look for custom elements. The dir path
|
|
269
|
+
* should be relative to the project dir, e.g. "path/to/elements".
|
|
270
|
+
*/
|
|
271
|
+
include?: string[];
|
|
272
|
+
/**
|
|
273
|
+
* A list of RegEx patterns to exclude. The string passed to the RegEx is
|
|
274
|
+
* the file URL relative to the project root, e.g. "/elements/foo/foo.ts".
|
|
275
|
+
*/
|
|
276
|
+
exclude?: RegExp[];
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* Config options for localization and internationalization.
|
|
280
|
+
*/
|
|
281
|
+
i18n?: RootI18nConfig;
|
|
282
|
+
/**
|
|
283
|
+
* Config options for the Root.js express server.
|
|
284
|
+
*/
|
|
285
|
+
server?: RootServerConfig;
|
|
286
|
+
/**
|
|
287
|
+
* Vite config.
|
|
288
|
+
* @see {@link https://vitejs.dev/config/} for more information.
|
|
289
|
+
*/
|
|
290
|
+
vite?: UserConfig;
|
|
291
|
+
/**
|
|
292
|
+
* Whether to automatically minify HTML output. This is enabled by default,
|
|
293
|
+
* in order to disable, pass `minifyHtml: false` to root.config.ts.
|
|
294
|
+
*/
|
|
295
|
+
minifyHtml?: boolean;
|
|
296
|
+
/**
|
|
297
|
+
* Options to pass to html-minifier-terser.
|
|
298
|
+
*/
|
|
299
|
+
minifyHtmlOptions?: HtmlMinifyOptions;
|
|
300
|
+
/**
|
|
301
|
+
* Whether to pretty print HTML output.
|
|
302
|
+
*/
|
|
303
|
+
prettyHtml?: boolean;
|
|
304
|
+
/**
|
|
305
|
+
* Options to pass to js-beautify.
|
|
306
|
+
*/
|
|
307
|
+
prettyHtmlOptions?: HtmlPrettyOptions;
|
|
308
|
+
/**
|
|
309
|
+
* Whether to include a sitemap.xml file to the build output.
|
|
310
|
+
*/
|
|
311
|
+
sitemap?: boolean;
|
|
312
|
+
/**
|
|
313
|
+
* Plugins.
|
|
314
|
+
*/
|
|
315
|
+
plugins?: Plugin[];
|
|
316
|
+
}
|
|
317
|
+
declare type RootConfig = RootUserConfig & {
|
|
318
|
+
rootDir: string;
|
|
319
|
+
};
|
|
320
|
+
interface RootI18nConfig {
|
|
321
|
+
/**
|
|
322
|
+
* Locales enabled for the site.
|
|
323
|
+
*/
|
|
324
|
+
locales?: string[];
|
|
325
|
+
/**
|
|
326
|
+
* The default locale to use. Defaults is `en`.
|
|
327
|
+
*/
|
|
328
|
+
defaultLocale?: string;
|
|
329
|
+
/**
|
|
330
|
+
* URL format for localized content. Default is `/{locale}/{path}`.
|
|
331
|
+
*/
|
|
332
|
+
urlFormat?: string;
|
|
333
|
+
}
|
|
334
|
+
interface RootServerConfig {
|
|
335
|
+
/**
|
|
336
|
+
* An array of middleware to add to the express server. These middleware are
|
|
337
|
+
* added to the beginning of the express app.
|
|
338
|
+
*/
|
|
339
|
+
middlewares?: Array<(req: Request, res: Response, next: NextFunction) => void | Promise<void>>;
|
|
340
|
+
}
|
|
341
|
+
declare function defineConfig(config: RootUserConfig): RootUserConfig;
|
|
342
|
+
|
|
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 };
|
package/dist/core.d.ts
CHANGED
|
@@ -1,41 +1,144 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { R as Route } from './config-872b068d.js';
|
|
2
|
+
export { C as ConfigureServerHook, f as ConfigureServerOptions, j as GetStaticPaths, G as GetStaticProps, m as Handler, H as HandlerContext, N as NextFunction, P as Plugin, k as Request, l as Response, b as RootConfig, c as RootI18nConfig, d as RootServerConfig, a as RootUserConfig, R as Route, n as RouteModule, i as RouteParams, S as Server, g as configureServerPlugins, e as defineConfig, h as getVitePlugins } from './config-872b068d.js';
|
|
3
|
+
import * as preact$1 from 'preact';
|
|
4
|
+
import { ComponentChildren, FunctionalComponent } from 'preact';
|
|
5
|
+
import 'express';
|
|
4
6
|
import 'vite';
|
|
7
|
+
import 'html-minifier-terser';
|
|
8
|
+
import 'js-beautify';
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
+
declare type BodyProps = preact.JSX.HTMLAttributes<HTMLBodyElement> & {
|
|
11
|
+
children?: ComponentChildren;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* The `<Body>` component can be used to update attrs in the `<body>` tag.
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
*
|
|
18
|
+
* ```tsx
|
|
19
|
+
* <Body className="body">
|
|
20
|
+
* <h1>Hello world</h1>
|
|
21
|
+
* </Body>
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* Output:
|
|
25
|
+
*
|
|
26
|
+
* ```html
|
|
27
|
+
* <body class="body">
|
|
28
|
+
* <h1>Hello world</h1>
|
|
29
|
+
* </body>
|
|
30
|
+
*/
|
|
31
|
+
declare const Body: FunctionalComponent<BodyProps>;
|
|
10
32
|
|
|
11
|
-
declare
|
|
12
|
-
interface HeadProps {
|
|
33
|
+
declare type HeadProps = preact.JSX.HTMLAttributes<HTMLHeadElement> & {
|
|
13
34
|
children?: ComponentChildren;
|
|
14
|
-
}
|
|
35
|
+
};
|
|
15
36
|
/**
|
|
16
37
|
* The <Head> component can be used for injecting elements into the HTML head
|
|
17
|
-
* tag from any part of a page.
|
|
38
|
+
* tag from any part of a page. The <Head> can be added via any component or
|
|
39
|
+
* sub-component and will automatically be hoisted to the `<head>` element.
|
|
40
|
+
*
|
|
41
|
+
* Usage:
|
|
42
|
+
*
|
|
43
|
+
* ```tsx
|
|
44
|
+
* <Head>
|
|
45
|
+
* <link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
46
|
+
* </Head>
|
|
47
|
+
* ```
|
|
18
48
|
*/
|
|
19
|
-
declare
|
|
49
|
+
declare const Head: FunctionalComponent<HeadProps>;
|
|
20
50
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
51
|
+
interface HtmlContext {
|
|
52
|
+
htmlAttrs: preact$1.JSX.HTMLAttributes<HTMLHtmlElement>;
|
|
53
|
+
headAttrs: preact$1.JSX.HTMLAttributes<HTMLHeadElement>;
|
|
54
|
+
headComponents: ComponentChildren[];
|
|
55
|
+
bodyAttrs: preact$1.JSX.HTMLAttributes<HTMLBodyElement>;
|
|
56
|
+
scriptDeps: Array<preact$1.JSX.HTMLAttributes<HTMLScriptElement>>;
|
|
25
57
|
}
|
|
58
|
+
declare const HTML_CONTEXT: preact$1.Context<HtmlContext | null>;
|
|
59
|
+
declare type HtmlProps = preact$1.JSX.HTMLAttributes<HTMLHtmlElement> & {
|
|
60
|
+
children?: ComponentChildren;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The `<Html>` component can be used to update attrs in the `<html>` tag.
|
|
64
|
+
*
|
|
65
|
+
* Usage:
|
|
66
|
+
*
|
|
67
|
+
* ```tsx
|
|
68
|
+
* <Html lang="en-US">
|
|
69
|
+
* <h1>Hello world</h1>
|
|
70
|
+
* </Html>
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare const Html: FunctionalComponent<HtmlProps>;
|
|
74
|
+
|
|
75
|
+
declare type ScriptProps = preact.JSX.HTMLAttributes<HTMLScriptElement>;
|
|
26
76
|
/**
|
|
27
77
|
* The <Script> component is used for rendering any custom script modules. At
|
|
28
78
|
* the moment, the system only pre-renders and bundles files that are in the
|
|
29
79
|
* `/bundles` folder at the root of the project.
|
|
80
|
+
*
|
|
81
|
+
* Usage:
|
|
82
|
+
*
|
|
83
|
+
* ```tsx
|
|
84
|
+
* <Script src="/bundles/main.ts" />
|
|
85
|
+
* ```
|
|
30
86
|
*/
|
|
31
|
-
declare
|
|
87
|
+
declare const Script: FunctionalComponent<ScriptProps>;
|
|
32
88
|
|
|
33
|
-
declare const I18N_CONTEXT: preact.Context<I18nContext | null>;
|
|
89
|
+
declare const I18N_CONTEXT: preact$1.Context<I18nContext | null>;
|
|
34
90
|
interface I18nContext {
|
|
35
91
|
locale: string;
|
|
36
92
|
translations: Record<string, string>;
|
|
37
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* A hook that returns information about the current i18n context, including the
|
|
96
|
+
* locale for the given route and a map of translations for that locale.
|
|
97
|
+
*/
|
|
98
|
+
declare function useI18nContext(): I18nContext;
|
|
38
99
|
declare function getTranslations(locale: string): Record<string, string>;
|
|
100
|
+
|
|
101
|
+
interface RequestContext {
|
|
102
|
+
/** The route file. */
|
|
103
|
+
route: Route;
|
|
104
|
+
/**
|
|
105
|
+
* Route param values. E.g. for a route like `routes/blog/[slug].tsx`,
|
|
106
|
+
* visiting `/blog/foo` will pass {slug: 'foo'} here.
|
|
107
|
+
*/
|
|
108
|
+
routeParams: Record<string, string>;
|
|
109
|
+
/** Props passed to the route's server component. */
|
|
110
|
+
props: any;
|
|
111
|
+
/** The current locale. */
|
|
112
|
+
locale: string;
|
|
113
|
+
/** Translations map for the current locale. */
|
|
114
|
+
translations: Record<string, string>;
|
|
115
|
+
}
|
|
116
|
+
declare const REQUEST_CONTEXT: preact$1.Context<RequestContext | null>;
|
|
117
|
+
/**
|
|
118
|
+
* A hook that returns information about the current route.
|
|
119
|
+
*
|
|
120
|
+
* Usage:
|
|
121
|
+
*
|
|
122
|
+
* ```ts
|
|
123
|
+
* const ctx = useRequestContext();
|
|
124
|
+
* ctx.route.src;
|
|
125
|
+
* // => 'routes/index.tsx'
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
declare function useRequestContext(): RequestContext;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* A hook that returns a function that can be used to translate a string, and
|
|
132
|
+
* optionally replace any parameterized values that are surrounded in curly
|
|
133
|
+
* braces.
|
|
134
|
+
*
|
|
135
|
+
* Usage:
|
|
136
|
+
*
|
|
137
|
+
* ```ts
|
|
138
|
+
* const t = useTranslations();
|
|
139
|
+
* t('Hello {name}', {name: 'Bob'});
|
|
140
|
+
* // => 'Bounjour Bob'
|
|
141
|
+
*/
|
|
39
142
|
declare function useTranslations(): (str: string, params?: Record<string, string>) => string;
|
|
40
143
|
|
|
41
|
-
export {
|
|
144
|
+
export { Body, BodyProps, HTML_CONTEXT, Head, HeadProps, Html, HtmlContext, HtmlProps, I18N_CONTEXT, I18nContext, REQUEST_CONTEXT, RequestContext, Script, ScriptProps, getTranslations, useI18nContext, useRequestContext, useTranslations };
|
package/dist/core.js
CHANGED
|
@@ -1,27 +1,95 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
configureServerPlugins,
|
|
3
|
+
getVitePlugins
|
|
4
|
+
} from "./chunk-DTEQ2AIW.js";
|
|
5
|
+
import {
|
|
6
|
+
HTML_CONTEXT,
|
|
7
|
+
Html,
|
|
5
8
|
I18N_CONTEXT,
|
|
6
|
-
|
|
7
|
-
Script,
|
|
9
|
+
REQUEST_CONTEXT,
|
|
8
10
|
getTranslations,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
useI18nContext,
|
|
12
|
+
useRequestContext
|
|
13
|
+
} from "./chunk-WTSNW7BB.js";
|
|
11
14
|
|
|
12
15
|
// src/core/config.ts
|
|
13
16
|
function defineConfig(config) {
|
|
14
17
|
return config;
|
|
15
18
|
}
|
|
19
|
+
|
|
20
|
+
// src/core/components/Body.tsx
|
|
21
|
+
import { useContext } from "preact/hooks";
|
|
22
|
+
import { Fragment, jsx } from "preact/jsx-runtime";
|
|
23
|
+
var Body = ({ children, ...attrs }) => {
|
|
24
|
+
const context = useContext(HTML_CONTEXT);
|
|
25
|
+
if (!context) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
"HTML_CONTEXT not found, double-check usage of the <Body> component"
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
context.bodyAttrs = attrs;
|
|
31
|
+
return /* @__PURE__ */ jsx(Fragment, {
|
|
32
|
+
children
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// src/core/components/Head.ts
|
|
37
|
+
import { useContext as useContext2 } from "preact/hooks";
|
|
38
|
+
var Head = ({ children, ...attrs }) => {
|
|
39
|
+
const context = useContext2(HTML_CONTEXT);
|
|
40
|
+
if (!context) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
"HTML_CONTEXT not found, double-check usage of the <Head> component"
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
context.headComponents.push(children);
|
|
46
|
+
context.headAttrs = attrs;
|
|
47
|
+
return null;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// src/core/components/Script.ts
|
|
51
|
+
import { useContext as useContext3 } from "preact/hooks";
|
|
52
|
+
var Script = (props) => {
|
|
53
|
+
const context = useContext3(HTML_CONTEXT);
|
|
54
|
+
if (!context) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
"HTML_CONTEXT not found, double-check usage of the <Script> component"
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
context.scriptDeps.push(props);
|
|
60
|
+
return null;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// src/core/hooks/useTranslations.ts
|
|
64
|
+
function useTranslations() {
|
|
65
|
+
const context = useI18nContext();
|
|
66
|
+
const translations = context.translations || {};
|
|
67
|
+
const t = (str, params) => {
|
|
68
|
+
let translation = translations[str] ?? str ?? "";
|
|
69
|
+
if (params) {
|
|
70
|
+
for (const key of Object.keys(params)) {
|
|
71
|
+
const val = String(params[key] ?? "");
|
|
72
|
+
translation = translation.replaceAll(`{${key}}`, val);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return translation;
|
|
76
|
+
};
|
|
77
|
+
return t;
|
|
78
|
+
}
|
|
16
79
|
export {
|
|
17
|
-
|
|
18
|
-
|
|
80
|
+
Body,
|
|
81
|
+
HTML_CONTEXT,
|
|
19
82
|
Head,
|
|
83
|
+
Html,
|
|
20
84
|
I18N_CONTEXT,
|
|
21
|
-
|
|
85
|
+
REQUEST_CONTEXT,
|
|
22
86
|
Script,
|
|
87
|
+
configureServerPlugins,
|
|
23
88
|
defineConfig,
|
|
24
89
|
getTranslations,
|
|
90
|
+
getVitePlugins,
|
|
91
|
+
useI18nContext,
|
|
92
|
+
useRequestContext,
|
|
25
93
|
useTranslations
|
|
26
94
|
};
|
|
27
95
|
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/config.ts"],"sourcesContent":["import {UserConfig as ViteUserConfig} from 'vite';\n\nexport interface
|
|
1
|
+
{"version":3,"sources":["../src/core/config.ts","../src/core/components/Body.tsx","../src/core/components/Head.ts","../src/core/components/Script.ts","../src/core/hooks/useTranslations.ts"],"sourcesContent":["import {Request, Response, NextFunction} from './types';\nimport {Plugin} from './plugin';\nimport {UserConfig as ViteUserConfig} from 'vite';\nimport {HtmlMinifyOptions} from '../render/html-minify';\nimport {HtmlPrettyOptions} from '../render/html-pretty';\n\nexport interface RootUserConfig {\n /**\n * Canonical domain the website will serve on. Useful for things like the\n * sitemap, SEO tags, etc.\n */\n domain?: string;\n\n /**\n * Config for auto-injecting custom element dependencies.\n */\n elements?: {\n /**\n * A list of directories to use to look for custom elements. The dir path\n * should be relative to the project dir, e.g. \"path/to/elements\".\n */\n include?: string[];\n\n /**\n * A list of RegEx patterns to exclude. The string passed to the RegEx is\n * the file URL relative to the project root, e.g. \"/elements/foo/foo.ts\".\n */\n exclude?: RegExp[];\n };\n\n /**\n * Config options for localization and internationalization.\n */\n i18n?: RootI18nConfig;\n\n /**\n * Config options for the Root.js express server.\n */\n server?: RootServerConfig;\n\n /**\n * Vite config.\n * @see {@link https://vitejs.dev/config/} for more information.\n */\n vite?: ViteUserConfig;\n\n /**\n * Whether to automatically minify HTML output. This is enabled by default,\n * in order to disable, pass `minifyHtml: false` to root.config.ts.\n */\n minifyHtml?: boolean;\n\n /**\n * Options to pass to html-minifier-terser.\n */\n minifyHtmlOptions?: HtmlMinifyOptions;\n\n /**\n * Whether to pretty print HTML output.\n */\n prettyHtml?: boolean;\n\n /**\n * Options to pass to js-beautify.\n */\n prettyHtmlOptions?: HtmlPrettyOptions;\n\n /**\n * Whether to include a sitemap.xml file to the build output.\n */\n sitemap?: boolean;\n\n /**\n * Plugins.\n */\n plugins?: Plugin[];\n}\n\nexport type RootConfig = RootUserConfig & {\n rootDir: string;\n};\n\nexport interface RootI18nConfig {\n /**\n * Locales enabled for the site.\n */\n locales?: string[];\n\n /**\n * The default locale to use. Defaults is `en`.\n */\n defaultLocale?: string;\n\n /**\n * URL format for localized content. Default is `/{locale}/{path}`.\n */\n urlFormat?: string;\n}\n\nexport interface RootServerConfig {\n /**\n * An array of middleware to add to the express server. These middleware are\n * added to the beginning of the express app.\n */\n middlewares?: Array<\n (req: Request, res: Response, next: NextFunction) => void | Promise<void>\n >;\n}\n\nexport function defineConfig(config: RootUserConfig): RootUserConfig {\n return config;\n}\n","import {ComponentChildren, FunctionalComponent} from 'preact';\nimport {useContext} from 'preact/hooks';\nimport {HTML_CONTEXT} from './Html';\n\nexport type BodyProps = preact.JSX.HTMLAttributes<HTMLBodyElement> & {\n children?: ComponentChildren;\n};\n\n/**\n * The `<Body>` component can be used to update attrs in the `<body>` tag.\n *\n * Usage:\n *\n * ```tsx\n * <Body className=\"body\">\n * <h1>Hello world</h1>\n * </Body>\n * ```\n *\n * Output:\n *\n * ```html\n * <body class=\"body\">\n * <h1>Hello world</h1>\n * </body>\n */\nexport const Body: FunctionalComponent<BodyProps> = ({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 <Body> component'\n );\n }\n context.bodyAttrs = attrs;\n return <>{children}</>;\n};\n","import {ComponentChildren, FunctionalComponent} from 'preact';\nimport {useContext} from 'preact/hooks';\nimport {HTML_CONTEXT} from './Html';\n\nexport type HeadProps = preact.JSX.HTMLAttributes<HTMLHeadElement> & {\n children?: ComponentChildren;\n};\n\n/**\n * The <Head> component can be used for injecting elements into the HTML head\n * tag from any part of a page. The <Head> can be added via any component or\n * sub-component and will automatically be hoisted to the `<head>` element.\n *\n * Usage:\n *\n * ```tsx\n * <Head>\n * <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n * </Head>\n * ```\n */\nexport const Head: FunctionalComponent<HeadProps> = ({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 <Head> component'\n );\n }\n context.headComponents.push(children);\n context.headAttrs = attrs;\n return null;\n};\n","import {FunctionalComponent} from 'preact';\nimport {useContext} from 'preact/hooks';\nimport {HTML_CONTEXT} from './Html';\n\nexport type ScriptProps = preact.JSX.HTMLAttributes<HTMLScriptElement>;\n\n/**\n * The <Script> component is used for rendering any custom script modules. At\n * the moment, the system only pre-renders and bundles files that are in the\n * `/bundles` folder at the root of the project.\n *\n * Usage:\n *\n * ```tsx\n * <Script src=\"/bundles/main.ts\" />\n * ```\n */\nexport const Script: FunctionalComponent<ScriptProps> = (props) => {\n const context = useContext(HTML_CONTEXT);\n if (!context) {\n throw new Error(\n 'HTML_CONTEXT not found, double-check usage of the <Script> component'\n );\n }\n context.scriptDeps.push(props);\n return null;\n};\n","import {useI18nContext} from './useI18nContext';\n\n/**\n * A hook that returns a function that can be used to translate a string, and\n * optionally replace any parameterized values that are surrounded in curly\n * braces.\n *\n * Usage:\n *\n * ```ts\n * const t = useTranslations();\n * t('Hello {name}', {name: 'Bob'});\n * // => 'Bounjour Bob'\n */\nexport function useTranslations() {\n const context = useI18nContext();\n const translations = context.translations || {};\n const t = (str: string, params?: Record<string, string>) => {\n let translation = translations[str] ?? str ?? '';\n if (params) {\n for (const key of Object.keys(params)) {\n const val = String(params[key] ?? '');\n translation = translation.replaceAll(`{${key}}`, val);\n }\n }\n return translation;\n };\n return t;\n}\n"],"mappings":";;;;;;;;;;;;;;;AA6GO,SAAS,aAAa,QAAwC;AACnE,SAAO;AACT;;;AC9GA,SAAQ,kBAAiB;AAiChB;AARF,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;;;AClCA,SAAQ,cAAAA,mBAAiB;AAoBlB,IAAM,OAAuC,CAAC,EAAC,aAAa,MAAK,MAAM;AAC5E,QAAM,UAAUC,YAAW,YAAY;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,UAAQ,eAAe,KAAK,QAAQ;AACpC,UAAQ,YAAY;AACpB,SAAO;AACT;;;AC9BA,SAAQ,cAAAC,mBAAiB;AAgBlB,IAAM,SAA2C,CAAC,UAAU;AACjE,QAAM,UAAUC,YAAW,YAAY;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,UAAQ,WAAW,KAAK,KAAK;AAC7B,SAAO;AACT;;;ACZO,SAAS,kBAAkB;AAChC,QAAM,UAAU,eAAe;AAC/B,QAAM,eAAe,QAAQ,gBAAgB,CAAC;AAC9C,QAAM,IAAI,CAAC,KAAa,WAAoC;AAC1D,QAAI,cAAc,aAAa,QAAQ,OAAO;AAC9C,QAAI,QAAQ;AACV,iBAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACrC,cAAM,MAAM,OAAO,OAAO,QAAQ,EAAE;AACpC,sBAAc,YAAY,WAAW,IAAI,QAAQ,GAAG;AAAA,MACtD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;","names":["useContext","useContext","useContext","useContext"]}
|