@reckona/mreact-router 0.0.97 → 0.0.99
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/README.md +4 -0
- package/dist/actions.d.ts +7 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +26 -2
- package/dist/actions.js.map +1 -1
- package/dist/adapters/aws-lambda.d.ts.map +1 -1
- package/dist/adapters/aws-lambda.js +10 -7
- package/dist/adapters/aws-lambda.js.map +1 -1
- package/dist/build.d.ts +38 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +1087 -304
- package/dist/build.js.map +1 -1
- package/dist/bundle-pipeline.d.ts +7 -0
- package/dist/bundle-pipeline.d.ts.map +1 -1
- package/dist/bundle-pipeline.js +121 -87
- package/dist/bundle-pipeline.js.map +1 -1
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +10 -8
- package/dist/cache.js.map +1 -1
- package/dist/cli-options.d.ts +1 -0
- package/dist/cli-options.d.ts.map +1 -1
- package/dist/cli-options.js +16 -0
- package/dist/cli-options.js.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +6 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +113 -8
- package/dist/client.js.map +1 -1
- package/dist/csrf.d.ts.map +1 -1
- package/dist/csrf.js +7 -3
- package/dist/csrf.js.map +1 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +18 -1
- package/dist/http.js.map +1 -1
- package/dist/import-policy.d.ts.map +1 -1
- package/dist/import-policy.js +7 -3
- package/dist/import-policy.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/link.d.ts +5 -2
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +92 -3
- package/dist/link.js.map +1 -1
- package/dist/logger.d.ts +7 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/module-runner.d.ts +2 -0
- package/dist/module-runner.d.ts.map +1 -1
- package/dist/module-runner.js +1 -0
- package/dist/module-runner.js.map +1 -1
- package/dist/native-route-matcher.d.ts +2 -1
- package/dist/native-route-matcher.d.ts.map +1 -1
- package/dist/native-route-matcher.js +13 -2
- package/dist/native-route-matcher.js.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +117 -2
- package/dist/render.js.map +1 -1
- package/dist/route-source.d.ts +4 -4
- package/dist/route-source.d.ts.map +1 -1
- package/dist/route-source.js +8 -8
- package/dist/route-source.js.map +1 -1
- package/dist/route-styles.d.ts +6 -0
- package/dist/route-styles.d.ts.map +1 -1
- package/dist/route-styles.js +10 -1
- package/dist/route-styles.js.map +1 -1
- package/dist/serve.d.ts +5 -0
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +7 -4
- package/dist/serve.js.map +1 -1
- package/package.json +11 -11
- package/src/actions.ts +42 -2
- package/src/adapters/aws-lambda.ts +33 -16
- package/src/build.ts +1578 -397
- package/src/bundle-pipeline.ts +136 -88
- package/src/cache.ts +13 -8
- package/src/cli-options.ts +20 -0
- package/src/cli.ts +1 -0
- package/src/client.ts +145 -14
- package/src/csrf.ts +8 -3
- package/src/http.ts +21 -1
- package/src/import-policy.ts +8 -3
- package/src/index.ts +5 -0
- package/src/link.ts +129 -8
- package/src/logger.ts +9 -1
- package/src/module-runner.ts +4 -0
- package/src/native-route-matcher.ts +13 -2
- package/src/render.ts +177 -2
- package/src/route-source.ts +8 -8
- package/src/route-styles.ts +17 -1
- package/src/serve.ts +11 -6
package/src/bundle-pipeline.ts
CHANGED
|
@@ -12,6 +12,9 @@ import { workspacePackageFile } from "./workspace-packages.js";
|
|
|
12
12
|
|
|
13
13
|
export interface RouterBundleOptions {
|
|
14
14
|
base?: string | undefined;
|
|
15
|
+
cache?: Map<string, Promise<RouterBundleOutput>> | undefined;
|
|
16
|
+
cacheDir?: string | undefined;
|
|
17
|
+
cacheKey?: string | undefined;
|
|
15
18
|
code: string;
|
|
16
19
|
define?: Record<string, string> | undefined;
|
|
17
20
|
dropConsoleFunctions?: readonly string[] | undefined;
|
|
@@ -22,6 +25,7 @@ export interface RouterBundleOptions {
|
|
|
22
25
|
outfile?: string | undefined;
|
|
23
26
|
platform: "browser" | "node";
|
|
24
27
|
preserveExports?: boolean | undefined;
|
|
28
|
+
root?: string | undefined;
|
|
25
29
|
plugins?: readonly RouterCompatPlugin[] | undefined;
|
|
26
30
|
vitePlugins?: readonly PluginOption[] | undefined;
|
|
27
31
|
sourceMap?: boolean | undefined;
|
|
@@ -30,9 +34,12 @@ export interface RouterBundleOptions {
|
|
|
30
34
|
|
|
31
35
|
export interface RouterBundleModulesOptions {
|
|
32
36
|
base?: string | undefined;
|
|
37
|
+
cacheDir?: string | undefined;
|
|
38
|
+
chunkFileNames?: string | undefined;
|
|
33
39
|
define?: Record<string, string> | undefined;
|
|
34
40
|
dropConsoleFunctions?: readonly string[] | undefined;
|
|
35
41
|
entries: readonly RouterBundleEntryOptions[];
|
|
42
|
+
entryFileNames?: string | undefined;
|
|
36
43
|
minify?: boolean | undefined;
|
|
37
44
|
platform: "browser" | "node";
|
|
38
45
|
plugins?: readonly RouterCompatPlugin[] | undefined;
|
|
@@ -130,14 +137,122 @@ export type RouterCompatResolveResult =
|
|
|
130
137
|
| undefined;
|
|
131
138
|
|
|
132
139
|
const nodeBuiltinSpecifiers = new Set(builtinModules.flatMap((name) => [name, `node:${name}`]));
|
|
140
|
+
const mreactJsxRuntimeAliasPaths = new Map([
|
|
141
|
+
[
|
|
142
|
+
"react",
|
|
143
|
+
workspacePackageFile({
|
|
144
|
+
currentFileUrl: import.meta.url,
|
|
145
|
+
entry: "index",
|
|
146
|
+
monorepoDir: "react-compat",
|
|
147
|
+
packageName: "@reckona/mreact-compat",
|
|
148
|
+
}),
|
|
149
|
+
],
|
|
150
|
+
[
|
|
151
|
+
"react-dom",
|
|
152
|
+
workspacePackageFile({
|
|
153
|
+
currentFileUrl: import.meta.url,
|
|
154
|
+
entry: "index",
|
|
155
|
+
monorepoDir: "react-compat",
|
|
156
|
+
packageName: "@reckona/mreact-compat",
|
|
157
|
+
}),
|
|
158
|
+
],
|
|
159
|
+
[
|
|
160
|
+
"react-dom/client",
|
|
161
|
+
workspacePackageFile({
|
|
162
|
+
currentFileUrl: import.meta.url,
|
|
163
|
+
entry: "index",
|
|
164
|
+
monorepoDir: "react-compat",
|
|
165
|
+
packageName: "@reckona/mreact-compat",
|
|
166
|
+
}),
|
|
167
|
+
],
|
|
168
|
+
[
|
|
169
|
+
"react-dom/server",
|
|
170
|
+
workspacePackageFile({
|
|
171
|
+
currentFileUrl: import.meta.url,
|
|
172
|
+
entry: "index",
|
|
173
|
+
monorepoDir: "react-compat",
|
|
174
|
+
packageName: "@reckona/mreact-compat",
|
|
175
|
+
}),
|
|
176
|
+
],
|
|
177
|
+
[
|
|
178
|
+
"react/jsx-dev-runtime",
|
|
179
|
+
workspacePackageFile({
|
|
180
|
+
currentFileUrl: import.meta.url,
|
|
181
|
+
entry: "jsx-dev-runtime",
|
|
182
|
+
monorepoDir: "react-compat",
|
|
183
|
+
packageName: "@reckona/mreact-compat",
|
|
184
|
+
}),
|
|
185
|
+
],
|
|
186
|
+
[
|
|
187
|
+
"react/jsx-runtime",
|
|
188
|
+
workspacePackageFile({
|
|
189
|
+
currentFileUrl: import.meta.url,
|
|
190
|
+
entry: "jsx-runtime",
|
|
191
|
+
monorepoDir: "react-compat",
|
|
192
|
+
packageName: "@reckona/mreact-compat",
|
|
193
|
+
}),
|
|
194
|
+
],
|
|
195
|
+
[
|
|
196
|
+
"@reckona/mreact/jsx-dev-runtime",
|
|
197
|
+
workspacePackageFile({
|
|
198
|
+
currentFileUrl: import.meta.url,
|
|
199
|
+
entry: "jsx-dev-runtime",
|
|
200
|
+
monorepoDir: "react",
|
|
201
|
+
packageName: "@reckona/mreact",
|
|
202
|
+
}),
|
|
203
|
+
],
|
|
204
|
+
[
|
|
205
|
+
"@reckona/mreact/jsx-runtime",
|
|
206
|
+
workspacePackageFile({
|
|
207
|
+
currentFileUrl: import.meta.url,
|
|
208
|
+
entry: "jsx-runtime",
|
|
209
|
+
monorepoDir: "react",
|
|
210
|
+
packageName: "@reckona/mreact",
|
|
211
|
+
}),
|
|
212
|
+
],
|
|
213
|
+
[
|
|
214
|
+
"@reckona/mreact-compat/hooks",
|
|
215
|
+
workspacePackageFile({
|
|
216
|
+
currentFileUrl: import.meta.url,
|
|
217
|
+
entry: "hooks-entry",
|
|
218
|
+
monorepoDir: "react-compat",
|
|
219
|
+
packageName: "@reckona/mreact-compat",
|
|
220
|
+
}),
|
|
221
|
+
],
|
|
222
|
+
]);
|
|
133
223
|
|
|
134
224
|
export async function bundleRouterModule(
|
|
135
225
|
options: RouterBundleOptions,
|
|
226
|
+
): Promise<RouterBundleOutput> {
|
|
227
|
+
if (options.cache !== undefined && options.cacheKey !== undefined) {
|
|
228
|
+
const cached = options.cache.get(options.cacheKey);
|
|
229
|
+
|
|
230
|
+
if (cached !== undefined) {
|
|
231
|
+
return cloneRouterBundleOutput(await cached);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const pending = bundleRouterModuleUncached(options);
|
|
235
|
+
options.cache.set(options.cacheKey, pending);
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
return cloneRouterBundleOutput(await pending);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
options.cache.delete(options.cacheKey);
|
|
241
|
+
throw error;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return await bundleRouterModuleUncached(options);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async function bundleRouterModuleUncached(
|
|
249
|
+
options: RouterBundleOptions,
|
|
136
250
|
): Promise<RouterBundleOutput> {
|
|
137
251
|
const entryId = `${options.filename}?mreact-router-entry`;
|
|
138
252
|
const outfile = options.outfile ?? "entry.js";
|
|
139
253
|
const config = {
|
|
140
254
|
base: options.base ?? "/",
|
|
255
|
+
...(options.cacheDir === undefined ? {} : { cacheDir: options.cacheDir }),
|
|
141
256
|
configFile: false,
|
|
142
257
|
...(options.define === undefined ? {} : { define: options.define }),
|
|
143
258
|
logLevel: "silent",
|
|
@@ -157,7 +272,7 @@ export async function bundleRouterModule(
|
|
|
157
272
|
...(options.plugins ?? []).map(routerCompatPlugin),
|
|
158
273
|
],
|
|
159
274
|
publicDir: false,
|
|
160
|
-
root: dirname(options.filename),
|
|
275
|
+
root: options.root ?? dirname(options.filename),
|
|
161
276
|
ssr: {
|
|
162
277
|
noExternal: true,
|
|
163
278
|
},
|
|
@@ -218,6 +333,22 @@ export async function bundleRouterModule(
|
|
|
218
333
|
};
|
|
219
334
|
}
|
|
220
335
|
|
|
336
|
+
function cloneRouterBundleOutput(output: RouterBundleOutput): RouterBundleOutput {
|
|
337
|
+
return {
|
|
338
|
+
...(output.assets === undefined
|
|
339
|
+
? {}
|
|
340
|
+
: {
|
|
341
|
+
assets: output.assets.map((asset) => ({
|
|
342
|
+
fileName: asset.fileName,
|
|
343
|
+
source:
|
|
344
|
+
typeof asset.source === "string" ? asset.source : new Uint8Array(asset.source),
|
|
345
|
+
})),
|
|
346
|
+
}),
|
|
347
|
+
code: output.code,
|
|
348
|
+
...(output.map === undefined ? {} : { map: output.map }),
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
221
352
|
export async function bundleRouterModules(
|
|
222
353
|
options: RouterBundleModulesOptions,
|
|
223
354
|
): Promise<RouterBundleModulesOutput> {
|
|
@@ -236,6 +367,7 @@ export async function bundleRouterModules(
|
|
|
236
367
|
);
|
|
237
368
|
const config = {
|
|
238
369
|
base: options.base ?? "/",
|
|
370
|
+
...(options.cacheDir === undefined ? {} : { cacheDir: options.cacheDir }),
|
|
239
371
|
configFile: false,
|
|
240
372
|
...(options.define === undefined ? {} : { define: options.define }),
|
|
241
373
|
logLevel: "silent",
|
|
@@ -262,8 +394,8 @@ export async function bundleRouterModules(
|
|
|
262
394
|
input,
|
|
263
395
|
...routerBundleTreeshakeOptions(options.dropConsoleFunctions),
|
|
264
396
|
output: {
|
|
265
|
-
chunkFileNames: "assets/chunks/[name].[hash].js",
|
|
266
|
-
entryFileNames: "assets/routes/[name].[hash].js",
|
|
397
|
+
chunkFileNames: options.chunkFileNames ?? "assets/chunks/[name].[hash].js",
|
|
398
|
+
entryFileNames: options.entryFileNames ?? "assets/routes/[name].[hash].js",
|
|
267
399
|
format: "es",
|
|
268
400
|
hashCharacters: "hex",
|
|
269
401
|
},
|
|
@@ -315,95 +447,11 @@ export async function bundleRouterModules(
|
|
|
315
447
|
}
|
|
316
448
|
|
|
317
449
|
function mreactJsxRuntimeAliasPlugin(): VitePlugin {
|
|
318
|
-
const runtimePaths = new Map([
|
|
319
|
-
[
|
|
320
|
-
"react",
|
|
321
|
-
workspacePackageFile({
|
|
322
|
-
currentFileUrl: import.meta.url,
|
|
323
|
-
entry: "index",
|
|
324
|
-
monorepoDir: "react-compat",
|
|
325
|
-
packageName: "@reckona/mreact-compat",
|
|
326
|
-
}),
|
|
327
|
-
],
|
|
328
|
-
[
|
|
329
|
-
"react-dom",
|
|
330
|
-
workspacePackageFile({
|
|
331
|
-
currentFileUrl: import.meta.url,
|
|
332
|
-
entry: "index",
|
|
333
|
-
monorepoDir: "react-compat",
|
|
334
|
-
packageName: "@reckona/mreact-compat",
|
|
335
|
-
}),
|
|
336
|
-
],
|
|
337
|
-
[
|
|
338
|
-
"react-dom/client",
|
|
339
|
-
workspacePackageFile({
|
|
340
|
-
currentFileUrl: import.meta.url,
|
|
341
|
-
entry: "index",
|
|
342
|
-
monorepoDir: "react-compat",
|
|
343
|
-
packageName: "@reckona/mreact-compat",
|
|
344
|
-
}),
|
|
345
|
-
],
|
|
346
|
-
[
|
|
347
|
-
"react-dom/server",
|
|
348
|
-
workspacePackageFile({
|
|
349
|
-
currentFileUrl: import.meta.url,
|
|
350
|
-
entry: "index",
|
|
351
|
-
monorepoDir: "react-compat",
|
|
352
|
-
packageName: "@reckona/mreact-compat",
|
|
353
|
-
}),
|
|
354
|
-
],
|
|
355
|
-
[
|
|
356
|
-
"react/jsx-dev-runtime",
|
|
357
|
-
workspacePackageFile({
|
|
358
|
-
currentFileUrl: import.meta.url,
|
|
359
|
-
entry: "jsx-dev-runtime",
|
|
360
|
-
monorepoDir: "react-compat",
|
|
361
|
-
packageName: "@reckona/mreact-compat",
|
|
362
|
-
}),
|
|
363
|
-
],
|
|
364
|
-
[
|
|
365
|
-
"react/jsx-runtime",
|
|
366
|
-
workspacePackageFile({
|
|
367
|
-
currentFileUrl: import.meta.url,
|
|
368
|
-
entry: "jsx-runtime",
|
|
369
|
-
monorepoDir: "react-compat",
|
|
370
|
-
packageName: "@reckona/mreact-compat",
|
|
371
|
-
}),
|
|
372
|
-
],
|
|
373
|
-
[
|
|
374
|
-
"@reckona/mreact/jsx-dev-runtime",
|
|
375
|
-
workspacePackageFile({
|
|
376
|
-
currentFileUrl: import.meta.url,
|
|
377
|
-
entry: "jsx-dev-runtime",
|
|
378
|
-
monorepoDir: "react",
|
|
379
|
-
packageName: "@reckona/mreact",
|
|
380
|
-
}),
|
|
381
|
-
],
|
|
382
|
-
[
|
|
383
|
-
"@reckona/mreact/jsx-runtime",
|
|
384
|
-
workspacePackageFile({
|
|
385
|
-
currentFileUrl: import.meta.url,
|
|
386
|
-
entry: "jsx-runtime",
|
|
387
|
-
monorepoDir: "react",
|
|
388
|
-
packageName: "@reckona/mreact",
|
|
389
|
-
}),
|
|
390
|
-
],
|
|
391
|
-
[
|
|
392
|
-
"@reckona/mreact-compat/hooks",
|
|
393
|
-
workspacePackageFile({
|
|
394
|
-
currentFileUrl: import.meta.url,
|
|
395
|
-
entry: "hooks-entry",
|
|
396
|
-
monorepoDir: "react-compat",
|
|
397
|
-
packageName: "@reckona/mreact-compat",
|
|
398
|
-
}),
|
|
399
|
-
],
|
|
400
|
-
]);
|
|
401
|
-
|
|
402
450
|
return {
|
|
403
451
|
name: "mreact-router-jsx-runtime-alias",
|
|
404
452
|
enforce: "pre",
|
|
405
453
|
resolveId(id) {
|
|
406
|
-
return
|
|
454
|
+
return mreactJsxRuntimeAliasPaths.get(id);
|
|
407
455
|
},
|
|
408
456
|
};
|
|
409
457
|
}
|
package/src/cache.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
|
|
1
3
|
export interface RouteCachePolicy {
|
|
2
4
|
cacheControl: string;
|
|
3
5
|
revalidateSeconds: number;
|
|
@@ -35,6 +37,7 @@ interface AppRouterCacheState {
|
|
|
35
37
|
activeContexts: RouteCacheContext[];
|
|
36
38
|
invalidatedPaths: Set<string>;
|
|
37
39
|
memoryCache: AppRouterCache;
|
|
40
|
+
storage: AsyncLocalStorage<RouteCacheContext>;
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
interface RouteCacheContext {
|
|
@@ -49,7 +52,9 @@ const cacheState = ((
|
|
|
49
52
|
activeContexts: [],
|
|
50
53
|
invalidatedPaths: new Set(),
|
|
51
54
|
memoryCache: createMemoryRouteCache(),
|
|
55
|
+
storage: new AsyncLocalStorage<RouteCacheContext>(),
|
|
52
56
|
});
|
|
57
|
+
cacheState.storage ??= new AsyncLocalStorage<RouteCacheContext>();
|
|
53
58
|
|
|
54
59
|
export function createMemoryRouteCache(options: MemoryRouteCacheOptions = {}): AppRouterCache {
|
|
55
60
|
const maxEntries = positiveIntegerOrDefault(options.maxEntries, 10_000);
|
|
@@ -188,7 +193,7 @@ export function routeCachePolicyFromSource(code: string): RouteCachePolicy | und
|
|
|
188
193
|
}
|
|
189
194
|
|
|
190
195
|
export function cacheControl(options: CacheControlOptions): void {
|
|
191
|
-
const activeContext =
|
|
196
|
+
const activeContext = activeRouteCacheContext();
|
|
192
197
|
|
|
193
198
|
if (activeContext === undefined) {
|
|
194
199
|
throw new Error("cacheControl() must be called during an app router request.");
|
|
@@ -291,7 +296,7 @@ export async function cacheRouteResponse(options: {
|
|
|
291
296
|
|
|
292
297
|
export function revalidatePath(path: string): void {
|
|
293
298
|
const normalizedPath = normalizeRevalidationPath(path);
|
|
294
|
-
const activeContext =
|
|
299
|
+
const activeContext = activeRouteCacheContext();
|
|
295
300
|
|
|
296
301
|
if (activeContext !== undefined) {
|
|
297
302
|
activeContext.revalidatedPaths.add(normalizedPath);
|
|
@@ -324,9 +329,7 @@ export async function withRouteCacheContext<T>(
|
|
|
324
329
|
revalidatedPaths: new Set(),
|
|
325
330
|
};
|
|
326
331
|
|
|
327
|
-
cacheState.
|
|
328
|
-
|
|
329
|
-
try {
|
|
332
|
+
return cacheState.storage.run(context, async () => {
|
|
330
333
|
const value = await fn();
|
|
331
334
|
const cachePolicy = context.cachePolicy;
|
|
332
335
|
const revalidatedPaths = Array.from(context.revalidatedPaths);
|
|
@@ -336,9 +339,7 @@ export async function withRouteCacheContext<T>(
|
|
|
336
339
|
}
|
|
337
340
|
|
|
338
341
|
return { cachePolicy, revalidatedPaths, value };
|
|
339
|
-
}
|
|
340
|
-
cacheState.activeContexts.pop();
|
|
341
|
-
}
|
|
342
|
+
});
|
|
342
343
|
}
|
|
343
344
|
|
|
344
345
|
export function beginRouteCacheContext(cache: AppRouterCache | undefined): {
|
|
@@ -373,6 +374,10 @@ export function beginRouteCacheContext(cache: AppRouterCache | undefined): {
|
|
|
373
374
|
};
|
|
374
375
|
}
|
|
375
376
|
|
|
377
|
+
function activeRouteCacheContext(): RouteCacheContext | undefined {
|
|
378
|
+
return cacheState.storage.getStore() ?? cacheState.activeContexts.at(-1);
|
|
379
|
+
}
|
|
380
|
+
|
|
376
381
|
// Host is excluded from the cache key to prevent attacker-supplied Host
|
|
377
382
|
// headers from fragmenting / poisoning the cache (Issue 068). The Vary
|
|
378
383
|
// dimension is the request path + query; same-origin reverse proxies are
|
package/src/cli-options.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface ParsedCliArguments {
|
|
|
13
13
|
command: string;
|
|
14
14
|
allowedHosts?: readonly string[] | undefined;
|
|
15
15
|
from?: string | undefined;
|
|
16
|
+
handler?: string | undefined;
|
|
16
17
|
help?: boolean | undefined;
|
|
17
18
|
host?: string | undefined;
|
|
18
19
|
hostPolicy?: RequestHostPolicy | undefined;
|
|
@@ -120,6 +121,17 @@ export function parseCliArguments(argv: readonly string[]): ParsedCliArguments {
|
|
|
120
121
|
continue;
|
|
121
122
|
}
|
|
122
123
|
|
|
124
|
+
if (value === "--handler") {
|
|
125
|
+
parsed.handler = readOptionValue(argv, index, "handler");
|
|
126
|
+
index += 1;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (value.startsWith("--handler=")) {
|
|
131
|
+
parsed.handler = value.slice("--handler=".length);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
123
135
|
if (value.startsWith("--log=")) {
|
|
124
136
|
parsed.log = parseCliRequestLogMode(value.slice("--log=".length));
|
|
125
137
|
continue;
|
|
@@ -202,6 +214,8 @@ export function formatCliHelp(command?: string | undefined): string {
|
|
|
202
214
|
" --out <dir> Output directory. Defaults to .lambda for aws-lambda and .mreact/pages for cloudflare-pages.",
|
|
203
215
|
" --skip-runtime-dependency-check",
|
|
204
216
|
" For aws-lambda only, skip the production node_modules check when a later deploy step installs dependencies into the package directory.",
|
|
217
|
+
" --handler <entry>",
|
|
218
|
+
" For aws-lambda only, bundle a custom handler entry into mreact-handler.mjs. App-local extensionless TypeScript imports are bundled; package imports stay external.",
|
|
205
219
|
" -h, --help Show this help message.",
|
|
206
220
|
"",
|
|
207
221
|
"Examples:",
|
|
@@ -261,6 +275,8 @@ export function formatCliHelp(command?: string | undefined): string {
|
|
|
261
275
|
" start [outDir] Serve built Node output.",
|
|
262
276
|
" package aws-lambda --from .mreact --out .lambda",
|
|
263
277
|
" Package a minimal AWS Lambda asset directory.",
|
|
278
|
+
" package aws-lambda --handler lambda/mreact-handler.ts",
|
|
279
|
+
" Bundle a custom Lambda handler with app-local server imports.",
|
|
264
280
|
" package cloudflare-pages --from .mreact --out .mreact/pages",
|
|
265
281
|
" Package Cloudflare Pages advanced mode output.",
|
|
266
282
|
" help [command] Show help.",
|
|
@@ -449,5 +465,9 @@ function formatCliRequestLogEvent(event: AppRouterLogEvent): string {
|
|
|
449
465
|
return `[mreact] ${event.method} ${event.path} ${event.status} render timing`;
|
|
450
466
|
}
|
|
451
467
|
|
|
468
|
+
if (event.type === "router:csp:inline-nonce-warning") {
|
|
469
|
+
return `[mreact] ${event.path} CSP ${event.directive} will block inline <${event.tag}> without a matching nonce`;
|
|
470
|
+
}
|
|
471
|
+
|
|
452
472
|
return `[mreact] ${event.method} ${event.path} ${event.runtime}`;
|
|
453
473
|
}
|
package/src/cli.ts
CHANGED
|
@@ -58,6 +58,7 @@ if (parsed !== undefined) {
|
|
|
58
58
|
if (routeArg === "aws-lambda") {
|
|
59
59
|
const manifest = await packageAwsLambdaArtifact({
|
|
60
60
|
fromDir: resolve(parsed.from ?? ".mreact"),
|
|
61
|
+
...(parsed.handler === undefined ? {} : { handlerEntry: resolve(parsed.handler) }),
|
|
61
62
|
outDir: resolve(parsed.out ?? ".lambda"),
|
|
62
63
|
skipRuntimeDependencyCheck: parsed.skipRuntimeDependencyCheck,
|
|
63
64
|
});
|