@webtypen/webframez-react 0.0.14 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/http.cjs CHANGED
@@ -429,6 +429,7 @@ function createFileRouter(options) {
429
429
  const pagesDir = options.pagesDir;
430
430
  const layoutPath = import_node_path2.default.join(pagesDir, "layout.js");
431
431
  const errorPath = import_node_path2.default.join(pagesDir, "errors.js");
432
+ const middlewaresPath = import_node_path2.default.join(pagesDir, "middlewares.js");
432
433
  function buildRouteEntries() {
433
434
  const files = walkFiles(pagesDir);
434
435
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -471,6 +472,75 @@ function createFileRouter(options) {
471
472
  head: mergeHead(layoutHead, errorHead)
472
473
  };
473
474
  }
475
+ function normalizeMiddlewareNames(config) {
476
+ if (!config) {
477
+ return [];
478
+ }
479
+ return Array.isArray(config) ? config : [config];
480
+ }
481
+ function isPlainObject(value) {
482
+ if (!value || typeof value !== "object") {
483
+ return false;
484
+ }
485
+ const prototype = Object.getPrototypeOf(value);
486
+ return prototype === Object.prototype || prototype === null;
487
+ }
488
+ function mergeRouteData(currentData, nextData) {
489
+ if (typeof nextData === "undefined") {
490
+ return currentData;
491
+ }
492
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
493
+ return {
494
+ ...currentData,
495
+ ...nextData
496
+ };
497
+ }
498
+ return nextData;
499
+ }
500
+ async function resolveMiddlewares(config, context) {
501
+ const middlewareNames = normalizeMiddlewareNames(config);
502
+ const requiresNamedMiddleware = middlewareNames.length > 0;
503
+ if (!import_node_fs.default.existsSync(middlewaresPath)) {
504
+ if (!requiresNamedMiddleware) {
505
+ return context;
506
+ }
507
+ throw createAbort({
508
+ status: 500,
509
+ message: `Invalid middleware '${middlewareNames[0]}'`
510
+ });
511
+ }
512
+ const middlewareModule = resolveModule(middlewaresPath);
513
+ const registry = middlewareModule.middlewares;
514
+ if (!registry) {
515
+ if (!requiresNamedMiddleware) {
516
+ return context;
517
+ }
518
+ throw createAbort({
519
+ status: 500,
520
+ message: `Invalid middleware '${middlewareNames[0]}'`
521
+ });
522
+ }
523
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
524
+ if (orderedMiddlewareNames.length === 0) {
525
+ return context;
526
+ }
527
+ let nextContext = context;
528
+ for (const middlewareName of orderedMiddlewareNames) {
529
+ const middleware = registry[middlewareName];
530
+ if (typeof middleware !== "function") {
531
+ throw createAbort({
532
+ status: 500,
533
+ message: `Invalid middleware '${middlewareName}'`
534
+ });
535
+ }
536
+ const middlewareData = await middleware(nextContext);
537
+ nextContext = {
538
+ ...nextContext,
539
+ data: mergeRouteData(nextContext.data, middlewareData)
540
+ };
541
+ }
542
+ return nextContext;
543
+ }
474
544
  async function resolve(input) {
475
545
  const pathname = normalizePathname(input.pathname);
476
546
  const contextBase = {
@@ -496,10 +566,12 @@ function createFileRouter(options) {
496
566
  activeContext = context;
497
567
  const pageModule = resolveModule(match.entry.filePath);
498
568
  const layoutModule = import_node_fs.default.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
499
- const pageData = await resolvePageData(pageModule, context);
569
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
570
+ activeContext = middlewareContext;
571
+ const pageData = await resolvePageData(pageModule, middlewareContext);
500
572
  const pageContext = {
501
- ...context,
502
- data: pageData
573
+ ...middlewareContext,
574
+ data: mergeRouteData(middlewareContext.data, pageData)
503
575
  };
504
576
  activeContext = pageContext;
505
577
  const pageNode = await pageModule.default(pageContext);
package/dist/http.js CHANGED
@@ -404,6 +404,7 @@ function createFileRouter(options) {
404
404
  const pagesDir = options.pagesDir;
405
405
  const layoutPath = path2.join(pagesDir, "layout.js");
406
406
  const errorPath = path2.join(pagesDir, "errors.js");
407
+ const middlewaresPath = path2.join(pagesDir, "middlewares.js");
407
408
  function buildRouteEntries() {
408
409
  const files = walkFiles(pagesDir);
409
410
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -446,6 +447,75 @@ function createFileRouter(options) {
446
447
  head: mergeHead(layoutHead, errorHead)
447
448
  };
448
449
  }
450
+ function normalizeMiddlewareNames(config) {
451
+ if (!config) {
452
+ return [];
453
+ }
454
+ return Array.isArray(config) ? config : [config];
455
+ }
456
+ function isPlainObject(value) {
457
+ if (!value || typeof value !== "object") {
458
+ return false;
459
+ }
460
+ const prototype = Object.getPrototypeOf(value);
461
+ return prototype === Object.prototype || prototype === null;
462
+ }
463
+ function mergeRouteData(currentData, nextData) {
464
+ if (typeof nextData === "undefined") {
465
+ return currentData;
466
+ }
467
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
468
+ return {
469
+ ...currentData,
470
+ ...nextData
471
+ };
472
+ }
473
+ return nextData;
474
+ }
475
+ async function resolveMiddlewares(config, context) {
476
+ const middlewareNames = normalizeMiddlewareNames(config);
477
+ const requiresNamedMiddleware = middlewareNames.length > 0;
478
+ if (!fs.existsSync(middlewaresPath)) {
479
+ if (!requiresNamedMiddleware) {
480
+ return context;
481
+ }
482
+ throw createAbort({
483
+ status: 500,
484
+ message: `Invalid middleware '${middlewareNames[0]}'`
485
+ });
486
+ }
487
+ const middlewareModule = resolveModule(middlewaresPath);
488
+ const registry = middlewareModule.middlewares;
489
+ if (!registry) {
490
+ if (!requiresNamedMiddleware) {
491
+ return context;
492
+ }
493
+ throw createAbort({
494
+ status: 500,
495
+ message: `Invalid middleware '${middlewareNames[0]}'`
496
+ });
497
+ }
498
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
499
+ if (orderedMiddlewareNames.length === 0) {
500
+ return context;
501
+ }
502
+ let nextContext = context;
503
+ for (const middlewareName of orderedMiddlewareNames) {
504
+ const middleware = registry[middlewareName];
505
+ if (typeof middleware !== "function") {
506
+ throw createAbort({
507
+ status: 500,
508
+ message: `Invalid middleware '${middlewareName}'`
509
+ });
510
+ }
511
+ const middlewareData = await middleware(nextContext);
512
+ nextContext = {
513
+ ...nextContext,
514
+ data: mergeRouteData(nextContext.data, middlewareData)
515
+ };
516
+ }
517
+ return nextContext;
518
+ }
449
519
  async function resolve(input) {
450
520
  const pathname = normalizePathname(input.pathname);
451
521
  const contextBase = {
@@ -471,10 +541,12 @@ function createFileRouter(options) {
471
541
  activeContext = context;
472
542
  const pageModule = resolveModule(match.entry.filePath);
473
543
  const layoutModule = fs.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
474
- const pageData = await resolvePageData(pageModule, context);
544
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
545
+ activeContext = middlewareContext;
546
+ const pageData = await resolvePageData(pageModule, middlewareContext);
475
547
  const pageContext = {
476
- ...context,
477
- data: pageData
548
+ ...middlewareContext,
549
+ data: mergeRouteData(middlewareContext.data, pageData)
478
550
  };
479
551
  activeContext = pageContext;
480
552
  const pageNode = await pageModule.default(pageContext);
package/dist/index.cjs CHANGED
@@ -462,6 +462,7 @@ function createFileRouter(options) {
462
462
  const pagesDir = options.pagesDir;
463
463
  const layoutPath = import_node_path2.default.join(pagesDir, "layout.js");
464
464
  const errorPath = import_node_path2.default.join(pagesDir, "errors.js");
465
+ const middlewaresPath = import_node_path2.default.join(pagesDir, "middlewares.js");
465
466
  function buildRouteEntries() {
466
467
  const files = walkFiles(pagesDir);
467
468
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -504,6 +505,75 @@ function createFileRouter(options) {
504
505
  head: mergeHead(layoutHead, errorHead)
505
506
  };
506
507
  }
508
+ function normalizeMiddlewareNames(config) {
509
+ if (!config) {
510
+ return [];
511
+ }
512
+ return Array.isArray(config) ? config : [config];
513
+ }
514
+ function isPlainObject(value) {
515
+ if (!value || typeof value !== "object") {
516
+ return false;
517
+ }
518
+ const prototype = Object.getPrototypeOf(value);
519
+ return prototype === Object.prototype || prototype === null;
520
+ }
521
+ function mergeRouteData(currentData, nextData) {
522
+ if (typeof nextData === "undefined") {
523
+ return currentData;
524
+ }
525
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
526
+ return {
527
+ ...currentData,
528
+ ...nextData
529
+ };
530
+ }
531
+ return nextData;
532
+ }
533
+ async function resolveMiddlewares(config, context) {
534
+ const middlewareNames = normalizeMiddlewareNames(config);
535
+ const requiresNamedMiddleware = middlewareNames.length > 0;
536
+ if (!import_node_fs.default.existsSync(middlewaresPath)) {
537
+ if (!requiresNamedMiddleware) {
538
+ return context;
539
+ }
540
+ throw createAbort({
541
+ status: 500,
542
+ message: `Invalid middleware '${middlewareNames[0]}'`
543
+ });
544
+ }
545
+ const middlewareModule = resolveModule(middlewaresPath);
546
+ const registry = middlewareModule.middlewares;
547
+ if (!registry) {
548
+ if (!requiresNamedMiddleware) {
549
+ return context;
550
+ }
551
+ throw createAbort({
552
+ status: 500,
553
+ message: `Invalid middleware '${middlewareNames[0]}'`
554
+ });
555
+ }
556
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
557
+ if (orderedMiddlewareNames.length === 0) {
558
+ return context;
559
+ }
560
+ let nextContext = context;
561
+ for (const middlewareName of orderedMiddlewareNames) {
562
+ const middleware = registry[middlewareName];
563
+ if (typeof middleware !== "function") {
564
+ throw createAbort({
565
+ status: 500,
566
+ message: `Invalid middleware '${middlewareName}'`
567
+ });
568
+ }
569
+ const middlewareData = await middleware(nextContext);
570
+ nextContext = {
571
+ ...nextContext,
572
+ data: mergeRouteData(nextContext.data, middlewareData)
573
+ };
574
+ }
575
+ return nextContext;
576
+ }
507
577
  async function resolve(input) {
508
578
  const pathname = normalizePathname(input.pathname);
509
579
  const contextBase = {
@@ -529,10 +599,12 @@ function createFileRouter(options) {
529
599
  activeContext = context;
530
600
  const pageModule = resolveModule(match.entry.filePath);
531
601
  const layoutModule = import_node_fs.default.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
532
- const pageData = await resolvePageData(pageModule, context);
602
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
603
+ activeContext = middlewareContext;
604
+ const pageData = await resolvePageData(pageModule, middlewareContext);
533
605
  const pageContext = {
534
- ...context,
535
- data: pageData
606
+ ...middlewareContext,
607
+ data: mergeRouteData(middlewareContext.data, pageData)
536
608
  };
537
609
  activeContext = pageContext;
538
610
  const pageNode = await pageModule.default(pageContext);
package/dist/index.js CHANGED
@@ -426,6 +426,7 @@ function createFileRouter(options) {
426
426
  const pagesDir = options.pagesDir;
427
427
  const layoutPath = path2.join(pagesDir, "layout.js");
428
428
  const errorPath = path2.join(pagesDir, "errors.js");
429
+ const middlewaresPath = path2.join(pagesDir, "middlewares.js");
429
430
  function buildRouteEntries() {
430
431
  const files = walkFiles(pagesDir);
431
432
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -468,6 +469,75 @@ function createFileRouter(options) {
468
469
  head: mergeHead(layoutHead, errorHead)
469
470
  };
470
471
  }
472
+ function normalizeMiddlewareNames(config) {
473
+ if (!config) {
474
+ return [];
475
+ }
476
+ return Array.isArray(config) ? config : [config];
477
+ }
478
+ function isPlainObject(value) {
479
+ if (!value || typeof value !== "object") {
480
+ return false;
481
+ }
482
+ const prototype = Object.getPrototypeOf(value);
483
+ return prototype === Object.prototype || prototype === null;
484
+ }
485
+ function mergeRouteData(currentData, nextData) {
486
+ if (typeof nextData === "undefined") {
487
+ return currentData;
488
+ }
489
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
490
+ return {
491
+ ...currentData,
492
+ ...nextData
493
+ };
494
+ }
495
+ return nextData;
496
+ }
497
+ async function resolveMiddlewares(config, context) {
498
+ const middlewareNames = normalizeMiddlewareNames(config);
499
+ const requiresNamedMiddleware = middlewareNames.length > 0;
500
+ if (!fs.existsSync(middlewaresPath)) {
501
+ if (!requiresNamedMiddleware) {
502
+ return context;
503
+ }
504
+ throw createAbort({
505
+ status: 500,
506
+ message: `Invalid middleware '${middlewareNames[0]}'`
507
+ });
508
+ }
509
+ const middlewareModule = resolveModule(middlewaresPath);
510
+ const registry = middlewareModule.middlewares;
511
+ if (!registry) {
512
+ if (!requiresNamedMiddleware) {
513
+ return context;
514
+ }
515
+ throw createAbort({
516
+ status: 500,
517
+ message: `Invalid middleware '${middlewareNames[0]}'`
518
+ });
519
+ }
520
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
521
+ if (orderedMiddlewareNames.length === 0) {
522
+ return context;
523
+ }
524
+ let nextContext = context;
525
+ for (const middlewareName of orderedMiddlewareNames) {
526
+ const middleware = registry[middlewareName];
527
+ if (typeof middleware !== "function") {
528
+ throw createAbort({
529
+ status: 500,
530
+ message: `Invalid middleware '${middlewareName}'`
531
+ });
532
+ }
533
+ const middlewareData = await middleware(nextContext);
534
+ nextContext = {
535
+ ...nextContext,
536
+ data: mergeRouteData(nextContext.data, middlewareData)
537
+ };
538
+ }
539
+ return nextContext;
540
+ }
471
541
  async function resolve(input) {
472
542
  const pathname = normalizePathname(input.pathname);
473
543
  const contextBase = {
@@ -493,10 +563,12 @@ function createFileRouter(options) {
493
563
  activeContext = context;
494
564
  const pageModule = resolveModule(match.entry.filePath);
495
565
  const layoutModule = fs.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
496
- const pageData = await resolvePageData(pageModule, context);
566
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
567
+ activeContext = middlewareContext;
568
+ const pageData = await resolvePageData(pageModule, middlewareContext);
497
569
  const pageContext = {
498
- ...context,
499
- data: pageData
570
+ ...middlewareContext,
571
+ data: mergeRouteData(middlewareContext.data, pageData)
500
572
  };
501
573
  activeContext = pageContext;
502
574
  const pageNode = await pageModule.default(pageContext);
package/dist/router.cjs CHANGED
@@ -298,6 +298,7 @@ function createFileRouter(options) {
298
298
  const pagesDir = options.pagesDir;
299
299
  const layoutPath = import_node_path.default.join(pagesDir, "layout.js");
300
300
  const errorPath = import_node_path.default.join(pagesDir, "errors.js");
301
+ const middlewaresPath = import_node_path.default.join(pagesDir, "middlewares.js");
301
302
  function buildRouteEntries() {
302
303
  const files = walkFiles(pagesDir);
303
304
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -340,6 +341,75 @@ function createFileRouter(options) {
340
341
  head: mergeHead(layoutHead, errorHead)
341
342
  };
342
343
  }
344
+ function normalizeMiddlewareNames(config) {
345
+ if (!config) {
346
+ return [];
347
+ }
348
+ return Array.isArray(config) ? config : [config];
349
+ }
350
+ function isPlainObject(value) {
351
+ if (!value || typeof value !== "object") {
352
+ return false;
353
+ }
354
+ const prototype = Object.getPrototypeOf(value);
355
+ return prototype === Object.prototype || prototype === null;
356
+ }
357
+ function mergeRouteData(currentData, nextData) {
358
+ if (typeof nextData === "undefined") {
359
+ return currentData;
360
+ }
361
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
362
+ return {
363
+ ...currentData,
364
+ ...nextData
365
+ };
366
+ }
367
+ return nextData;
368
+ }
369
+ async function resolveMiddlewares(config, context) {
370
+ const middlewareNames = normalizeMiddlewareNames(config);
371
+ const requiresNamedMiddleware = middlewareNames.length > 0;
372
+ if (!import_node_fs.default.existsSync(middlewaresPath)) {
373
+ if (!requiresNamedMiddleware) {
374
+ return context;
375
+ }
376
+ throw createAbort({
377
+ status: 500,
378
+ message: `Invalid middleware '${middlewareNames[0]}'`
379
+ });
380
+ }
381
+ const middlewareModule = resolveModule(middlewaresPath);
382
+ const registry = middlewareModule.middlewares;
383
+ if (!registry) {
384
+ if (!requiresNamedMiddleware) {
385
+ return context;
386
+ }
387
+ throw createAbort({
388
+ status: 500,
389
+ message: `Invalid middleware '${middlewareNames[0]}'`
390
+ });
391
+ }
392
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
393
+ if (orderedMiddlewareNames.length === 0) {
394
+ return context;
395
+ }
396
+ let nextContext = context;
397
+ for (const middlewareName of orderedMiddlewareNames) {
398
+ const middleware = registry[middlewareName];
399
+ if (typeof middleware !== "function") {
400
+ throw createAbort({
401
+ status: 500,
402
+ message: `Invalid middleware '${middlewareName}'`
403
+ });
404
+ }
405
+ const middlewareData = await middleware(nextContext);
406
+ nextContext = {
407
+ ...nextContext,
408
+ data: mergeRouteData(nextContext.data, middlewareData)
409
+ };
410
+ }
411
+ return nextContext;
412
+ }
343
413
  async function resolve(input) {
344
414
  const pathname = normalizePathname(input.pathname);
345
415
  const contextBase = {
@@ -365,10 +435,12 @@ function createFileRouter(options) {
365
435
  activeContext = context;
366
436
  const pageModule = resolveModule(match.entry.filePath);
367
437
  const layoutModule = import_node_fs.default.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
368
- const pageData = await resolvePageData(pageModule, context);
438
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
439
+ activeContext = middlewareContext;
440
+ const pageData = await resolvePageData(pageModule, middlewareContext);
369
441
  const pageContext = {
370
- ...context,
371
- data: pageData
442
+ ...middlewareContext,
443
+ data: mergeRouteData(middlewareContext.data, pageData)
372
444
  };
373
445
  activeContext = pageContext;
374
446
  const pageNode = await pageModule.default(pageContext);
package/dist/router.js CHANGED
@@ -268,6 +268,7 @@ function createFileRouter(options) {
268
268
  const pagesDir = options.pagesDir;
269
269
  const layoutPath = path.join(pagesDir, "layout.js");
270
270
  const errorPath = path.join(pagesDir, "errors.js");
271
+ const middlewaresPath = path.join(pagesDir, "middlewares.js");
271
272
  function buildRouteEntries() {
272
273
  const files = walkFiles(pagesDir);
273
274
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -310,6 +311,75 @@ function createFileRouter(options) {
310
311
  head: mergeHead(layoutHead, errorHead)
311
312
  };
312
313
  }
314
+ function normalizeMiddlewareNames(config) {
315
+ if (!config) {
316
+ return [];
317
+ }
318
+ return Array.isArray(config) ? config : [config];
319
+ }
320
+ function isPlainObject(value) {
321
+ if (!value || typeof value !== "object") {
322
+ return false;
323
+ }
324
+ const prototype = Object.getPrototypeOf(value);
325
+ return prototype === Object.prototype || prototype === null;
326
+ }
327
+ function mergeRouteData(currentData, nextData) {
328
+ if (typeof nextData === "undefined") {
329
+ return currentData;
330
+ }
331
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
332
+ return {
333
+ ...currentData,
334
+ ...nextData
335
+ };
336
+ }
337
+ return nextData;
338
+ }
339
+ async function resolveMiddlewares(config, context) {
340
+ const middlewareNames = normalizeMiddlewareNames(config);
341
+ const requiresNamedMiddleware = middlewareNames.length > 0;
342
+ if (!fs.existsSync(middlewaresPath)) {
343
+ if (!requiresNamedMiddleware) {
344
+ return context;
345
+ }
346
+ throw createAbort({
347
+ status: 500,
348
+ message: `Invalid middleware '${middlewareNames[0]}'`
349
+ });
350
+ }
351
+ const middlewareModule = resolveModule(middlewaresPath);
352
+ const registry = middlewareModule.middlewares;
353
+ if (!registry) {
354
+ if (!requiresNamedMiddleware) {
355
+ return context;
356
+ }
357
+ throw createAbort({
358
+ status: 500,
359
+ message: `Invalid middleware '${middlewareNames[0]}'`
360
+ });
361
+ }
362
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
363
+ if (orderedMiddlewareNames.length === 0) {
364
+ return context;
365
+ }
366
+ let nextContext = context;
367
+ for (const middlewareName of orderedMiddlewareNames) {
368
+ const middleware = registry[middlewareName];
369
+ if (typeof middleware !== "function") {
370
+ throw createAbort({
371
+ status: 500,
372
+ message: `Invalid middleware '${middlewareName}'`
373
+ });
374
+ }
375
+ const middlewareData = await middleware(nextContext);
376
+ nextContext = {
377
+ ...nextContext,
378
+ data: mergeRouteData(nextContext.data, middlewareData)
379
+ };
380
+ }
381
+ return nextContext;
382
+ }
313
383
  async function resolve(input) {
314
384
  const pathname = normalizePathname(input.pathname);
315
385
  const contextBase = {
@@ -335,10 +405,12 @@ function createFileRouter(options) {
335
405
  activeContext = context;
336
406
  const pageModule = resolveModule(match.entry.filePath);
337
407
  const layoutModule = fs.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
338
- const pageData = await resolvePageData(pageModule, context);
408
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
409
+ activeContext = middlewareContext;
410
+ const pageData = await resolvePageData(pageModule, middlewareContext);
339
411
  const pageContext = {
340
- ...context,
341
- data: pageData
412
+ ...middlewareContext,
413
+ data: mergeRouteData(middlewareContext.data, pageData)
342
414
  };
343
415
  activeContext = pageContext;
344
416
  const pageNode = await pageModule.default(pageContext);
package/dist/types.d.ts CHANGED
@@ -69,10 +69,18 @@ export type PageDataResolver<TData = unknown> = (
69
69
  context: RouteContext
70
70
  ) => TData | Promise<TData>;
71
71
 
72
+ export type RouteMiddlewareResult = Record<string, unknown> | undefined | void;
73
+ export type RouteMiddlewareResolver<TData = unknown> = (
74
+ context: RouteContext<TData>
75
+ ) => RouteMiddlewareResult | Promise<RouteMiddlewareResult>;
76
+ export type RouteMiddlewareRegistry = Record<string, RouteMiddlewareResolver<any>>;
77
+ export type RouteMiddlewareConfig = string | string[];
78
+
72
79
  export type PageModule<TData = unknown> = {
73
80
  default: (props: PageProps<TData>) => ReactNode | Promise<ReactNode>;
74
81
  Head?: HeadResolver<PageProps<TData>>;
75
82
  Data?: PageDataResolver<TData>;
83
+ middlewares?: RouteMiddlewareConfig;
76
84
  };
77
85
 
78
86
  export type LayoutModule = {
@@ -91,6 +99,8 @@ export type CreateHtmlShellOptions = {
91
99
  clientScriptUrl?: string;
92
100
  headTags?: string;
93
101
  rootHtml?: string;
102
+ initialFlightData?: string;
103
+ clientRenderMode?: "hydrate" | "mount";
94
104
  basename?: string;
95
105
  liveReloadPath?: string;
96
106
  liveReloadServerId?: string;
@@ -432,6 +432,7 @@ function createFileRouter(options) {
432
432
  const pagesDir = options.pagesDir;
433
433
  const layoutPath = import_node_path2.default.join(pagesDir, "layout.js");
434
434
  const errorPath = import_node_path2.default.join(pagesDir, "errors.js");
435
+ const middlewaresPath = import_node_path2.default.join(pagesDir, "middlewares.js");
435
436
  function buildRouteEntries() {
436
437
  const files = walkFiles(pagesDir);
437
438
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -474,6 +475,75 @@ function createFileRouter(options) {
474
475
  head: mergeHead(layoutHead, errorHead)
475
476
  };
476
477
  }
478
+ function normalizeMiddlewareNames(config) {
479
+ if (!config) {
480
+ return [];
481
+ }
482
+ return Array.isArray(config) ? config : [config];
483
+ }
484
+ function isPlainObject(value) {
485
+ if (!value || typeof value !== "object") {
486
+ return false;
487
+ }
488
+ const prototype = Object.getPrototypeOf(value);
489
+ return prototype === Object.prototype || prototype === null;
490
+ }
491
+ function mergeRouteData(currentData, nextData) {
492
+ if (typeof nextData === "undefined") {
493
+ return currentData;
494
+ }
495
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
496
+ return {
497
+ ...currentData,
498
+ ...nextData
499
+ };
500
+ }
501
+ return nextData;
502
+ }
503
+ async function resolveMiddlewares(config, context) {
504
+ const middlewareNames = normalizeMiddlewareNames(config);
505
+ const requiresNamedMiddleware = middlewareNames.length > 0;
506
+ if (!import_node_fs.default.existsSync(middlewaresPath)) {
507
+ if (!requiresNamedMiddleware) {
508
+ return context;
509
+ }
510
+ throw createAbort({
511
+ status: 500,
512
+ message: `Invalid middleware '${middlewareNames[0]}'`
513
+ });
514
+ }
515
+ const middlewareModule = resolveModule(middlewaresPath);
516
+ const registry = middlewareModule.middlewares;
517
+ if (!registry) {
518
+ if (!requiresNamedMiddleware) {
519
+ return context;
520
+ }
521
+ throw createAbort({
522
+ status: 500,
523
+ message: `Invalid middleware '${middlewareNames[0]}'`
524
+ });
525
+ }
526
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
527
+ if (orderedMiddlewareNames.length === 0) {
528
+ return context;
529
+ }
530
+ let nextContext = context;
531
+ for (const middlewareName of orderedMiddlewareNames) {
532
+ const middleware = registry[middlewareName];
533
+ if (typeof middleware !== "function") {
534
+ throw createAbort({
535
+ status: 500,
536
+ message: `Invalid middleware '${middlewareName}'`
537
+ });
538
+ }
539
+ const middlewareData = await middleware(nextContext);
540
+ nextContext = {
541
+ ...nextContext,
542
+ data: mergeRouteData(nextContext.data, middlewareData)
543
+ };
544
+ }
545
+ return nextContext;
546
+ }
477
547
  async function resolve(input) {
478
548
  const pathname = normalizePathname(input.pathname);
479
549
  const contextBase = {
@@ -499,10 +569,12 @@ function createFileRouter(options) {
499
569
  activeContext = context;
500
570
  const pageModule = resolveModule(match.entry.filePath);
501
571
  const layoutModule = import_node_fs.default.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
502
- const pageData = await resolvePageData(pageModule, context);
572
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
573
+ activeContext = middlewareContext;
574
+ const pageData = await resolvePageData(pageModule, middlewareContext);
503
575
  const pageContext = {
504
- ...context,
505
- data: pageData
576
+ ...middlewareContext,
577
+ data: mergeRouteData(middlewareContext.data, pageData)
506
578
  };
507
579
  activeContext = pageContext;
508
580
  const pageNode = await pageModule.default(pageContext);
@@ -404,6 +404,7 @@ function createFileRouter(options) {
404
404
  const pagesDir = options.pagesDir;
405
405
  const layoutPath = path2.join(pagesDir, "layout.js");
406
406
  const errorPath = path2.join(pagesDir, "errors.js");
407
+ const middlewaresPath = path2.join(pagesDir, "middlewares.js");
407
408
  function buildRouteEntries() {
408
409
  const files = walkFiles(pagesDir);
409
410
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -446,6 +447,75 @@ function createFileRouter(options) {
446
447
  head: mergeHead(layoutHead, errorHead)
447
448
  };
448
449
  }
450
+ function normalizeMiddlewareNames(config) {
451
+ if (!config) {
452
+ return [];
453
+ }
454
+ return Array.isArray(config) ? config : [config];
455
+ }
456
+ function isPlainObject(value) {
457
+ if (!value || typeof value !== "object") {
458
+ return false;
459
+ }
460
+ const prototype = Object.getPrototypeOf(value);
461
+ return prototype === Object.prototype || prototype === null;
462
+ }
463
+ function mergeRouteData(currentData, nextData) {
464
+ if (typeof nextData === "undefined") {
465
+ return currentData;
466
+ }
467
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
468
+ return {
469
+ ...currentData,
470
+ ...nextData
471
+ };
472
+ }
473
+ return nextData;
474
+ }
475
+ async function resolveMiddlewares(config, context) {
476
+ const middlewareNames = normalizeMiddlewareNames(config);
477
+ const requiresNamedMiddleware = middlewareNames.length > 0;
478
+ if (!fs.existsSync(middlewaresPath)) {
479
+ if (!requiresNamedMiddleware) {
480
+ return context;
481
+ }
482
+ throw createAbort({
483
+ status: 500,
484
+ message: `Invalid middleware '${middlewareNames[0]}'`
485
+ });
486
+ }
487
+ const middlewareModule = resolveModule(middlewaresPath);
488
+ const registry = middlewareModule.middlewares;
489
+ if (!registry) {
490
+ if (!requiresNamedMiddleware) {
491
+ return context;
492
+ }
493
+ throw createAbort({
494
+ status: 500,
495
+ message: `Invalid middleware '${middlewareNames[0]}'`
496
+ });
497
+ }
498
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
499
+ if (orderedMiddlewareNames.length === 0) {
500
+ return context;
501
+ }
502
+ let nextContext = context;
503
+ for (const middlewareName of orderedMiddlewareNames) {
504
+ const middleware = registry[middlewareName];
505
+ if (typeof middleware !== "function") {
506
+ throw createAbort({
507
+ status: 500,
508
+ message: `Invalid middleware '${middlewareName}'`
509
+ });
510
+ }
511
+ const middlewareData = await middleware(nextContext);
512
+ nextContext = {
513
+ ...nextContext,
514
+ data: mergeRouteData(nextContext.data, middlewareData)
515
+ };
516
+ }
517
+ return nextContext;
518
+ }
449
519
  async function resolve(input) {
450
520
  const pathname = normalizePathname(input.pathname);
451
521
  const contextBase = {
@@ -471,10 +541,12 @@ function createFileRouter(options) {
471
541
  activeContext = context;
472
542
  const pageModule = resolveModule(match.entry.filePath);
473
543
  const layoutModule = fs.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
474
- const pageData = await resolvePageData(pageModule, context);
544
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
545
+ activeContext = middlewareContext;
546
+ const pageData = await resolvePageData(pageModule, middlewareContext);
475
547
  const pageContext = {
476
- ...context,
477
- data: pageData
548
+ ...middlewareContext,
549
+ data: mergeRouteData(middlewareContext.data, pageData)
478
550
  };
479
551
  activeContext = pageContext;
480
552
  const pageNode = await pageModule.default(pageContext);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-react",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "description": "TypeScript React RSC addition for @webtypen/webframez-core",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "author": {