@taserjs/router 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,7 @@ import type {
16
16
  ExtractState,
17
17
  Method,
18
18
  MiddlewareDefinition,
19
+ MiddlewareRequirements,
19
20
  MiddlewareReturnFromParts,
20
21
  MiddlewareUnit,
21
22
  NextFn,
@@ -57,6 +58,7 @@ export type {
57
58
  IsUnknown,
58
59
  Method,
59
60
  MiddlewareDefinition,
61
+ MiddlewareRequirements,
60
62
  MiddlewareReturnFromParts,
61
63
  MiddlewareUnit,
62
64
  MiddlewareUnitBuilder,
@@ -121,6 +123,14 @@ type LayoutParent<Layout extends LayoutId> = Layout extends keyof LayoutParentsM
121
123
  ? Parent
122
124
  : null;
123
125
 
126
+ type LayoutMiddlewares<Layout extends LayoutId> = LayoutTree[Layout]["middlewares"] extends {
127
+ readonly __acc?: infer Acc extends readonly unknown[];
128
+ }
129
+ ? Acc
130
+ : LayoutTree[Layout]["middlewares"] extends infer Acc extends readonly unknown[]
131
+ ? Acc
132
+ : readonly [];
133
+
124
134
  type ResolveLayoutMiddlewares<
125
135
  Layout extends LayoutId | null,
126
136
  Depth extends readonly unknown[] = [],
@@ -129,7 +139,7 @@ type ResolveLayoutMiddlewares<
129
139
  : Layout extends LayoutId
130
140
  ? readonly [
131
141
  ...ResolveLayoutMiddlewares<LayoutParent<Layout>, [...Depth, unknown]>,
132
- ...LayoutTree[Layout]["middlewares"],
142
+ ...LayoutMiddlewares<Layout>,
133
143
  ]
134
144
  : readonly [];
135
145
 
@@ -163,7 +173,7 @@ type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]> = Chain ex
163
173
  ...infer Rest,
164
174
  ]
165
175
  ? readonly [
166
- ...LayoutTree[Head]["middlewares"],
176
+ ...LayoutMiddlewares<Head>,
167
177
  ...ResolveLayoutChainMiddlewares<Rest extends readonly LayoutId[] ? Rest : readonly []>,
168
178
  ]
169
179
  : readonly [];
@@ -344,19 +354,66 @@ export type IsLayoutAllowed<TRequiredLayouts, TChain extends readonly LayoutId[]
344
354
  : true
345
355
  : true;
346
356
 
347
- export type IsStateSatisfied<TActualState, TRequiredState> = [TRequiredState] extends [never]
357
+ export type IsRequirementsSatisfied<
358
+ TActual extends {
359
+ query?: unknown;
360
+ params?: unknown;
361
+ body?: unknown;
362
+ state?: unknown;
363
+ },
364
+ TRequires extends MiddlewareRequirements,
365
+ > = [TRequires] extends [never]
348
366
  ? true
349
- : [unknown] extends [TRequiredState]
367
+ : [unknown] extends [TRequires]
350
368
  ? true
351
- : [null] extends [TRequiredState]
369
+ : [null] extends [TRequires]
352
370
  ? true
353
- : [undefined] extends [TRequiredState]
371
+ : [undefined] extends [TRequires]
354
372
  ? true
355
- : [IsEmptyObject<TRequiredState>] extends [true]
373
+ : [IsEmptyObject<TRequires>] extends [true]
356
374
  ? true
357
- : [TActualState] extends [TRequiredState]
358
- ? true
359
- : false;
375
+ : (
376
+ TRequires extends { state: infer S extends Record<string, unknown> }
377
+ ? [TActual["state"]] extends [S]
378
+ ? true
379
+ : false
380
+ : true
381
+ ) extends false
382
+ ? false
383
+ : (
384
+ TRequires extends { query: infer Q extends Record<string, unknown> }
385
+ ? [TActual["query"]] extends [Q]
386
+ ? true
387
+ : false
388
+ : true
389
+ ) extends false
390
+ ? false
391
+ : (
392
+ TRequires extends { params: infer P extends Record<string, unknown> }
393
+ ? [TActual["params"]] extends [P]
394
+ ? true
395
+ : false
396
+ : true
397
+ ) extends false
398
+ ? false
399
+ : (
400
+ TRequires extends { body: infer B }
401
+ ? unknown extends B
402
+ ? true
403
+ : [TRequires["body"]] extends [undefined]
404
+ ? true
405
+ : [TActual["body"]] extends [B]
406
+ ? true
407
+ : false
408
+ : true
409
+ ) extends false
410
+ ? false
411
+ : true;
412
+
413
+ export type IsStateSatisfied<TActualState, TRequiredState> = IsRequirementsSatisfied<
414
+ { state: TActualState },
415
+ { state: TRequiredState extends Record<string, unknown> ? TRequiredState : {} }
416
+ >;
360
417
 
361
418
  type InputFacet<T, K extends string> =
362
419
  IsNever<T> extends true ? {} : IsEmptyObject<T> extends true ? {} : { [Key in K]: T };
@@ -470,28 +527,44 @@ export type MiddlewareBuilder<
470
527
  Layout extends LayoutId,
471
528
  Acc extends readonly unknown[] = readonly [],
472
529
  TAppContext extends Record<string, unknown> = AppContext,
473
- > = Acc & {
530
+ > = {
474
531
  readonly layout: Layout;
475
532
  readonly middlewares: readonly MiddlewareDefinition[];
533
+ readonly __acc?: Acc;
476
534
  readonly $Infer: {
477
535
  Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
478
536
  };
479
- use<TAcc, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(
480
- unit: MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequiredState>,
481
- ..._assert: [
537
+ use<
538
+ TAcc,
539
+ TReturns extends ReturnsMap = {},
540
+ TRequiredLayouts = unknown,
541
+ TRequires extends MiddlewareRequirements = {},
542
+ >(
543
+ unit: [
482
544
  IsLayoutAllowed<TRequiredLayouts, ResolveLayoutIdChain<Layout>>,
483
- IsStateSatisfied<MiddlewareChainField<Layout, Acc, "state">, TRequiredState>,
545
+ IsRequirementsSatisfied<
546
+ {
547
+ query: MiddlewareChainField<Layout, Acc, "query">;
548
+ params: MiddlewareChainField<Layout, Acc, "params">;
549
+ body: MiddlewareChainField<Layout, Acc, "body">;
550
+ state: MiddlewareChainField<Layout, Acc, "state">;
551
+ },
552
+ TRequires
553
+ >,
484
554
  ] extends [true, true]
485
- ? []
486
- : [
487
- {
488
- error: "Middleware cannot be attached to this layout";
489
- requiredLayouts: TRequiredLayouts;
490
- layoutChain: ResolveLayoutIdChain<Layout>;
491
- requiredState: TRequiredState;
492
- actualState: MiddlewareChainField<Layout, Acc, "state">;
493
- },
494
- ]
555
+ ? MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequires>
556
+ : {
557
+ error: "Middleware cannot be attached to this layout";
558
+ requiredLayouts: TRequiredLayouts;
559
+ layoutChain: ResolveLayoutIdChain<Layout>;
560
+ requirements: TRequires;
561
+ actual: {
562
+ query: MiddlewareChainField<Layout, Acc, "query">;
563
+ params: MiddlewareChainField<Layout, Acc, "params">;
564
+ body: MiddlewareChainField<Layout, Acc, "body">;
565
+ state: MiddlewareChainField<Layout, Acc, "state">;
566
+ };
567
+ },
495
568
  ): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
496
569
  use<R = unknown>(
497
570
  fn: (
@@ -511,11 +584,12 @@ export type RouteExport<
511
584
  Acc extends readonly unknown[],
512
585
  TReturns extends ReturnsMap = {},
513
586
  TOutput = Response,
514
- > = Acc & {
587
+ > = {
515
588
  readonly path: Path;
516
589
  readonly method: TMethod | "ANY" | "ALL";
517
590
  readonly methods?: readonly Method[];
518
591
  readonly middlewares: readonly MiddlewareDefinition[];
592
+ readonly __acc?: Acc;
519
593
  readonly returns?: TReturns;
520
594
  readonly bodyMode?: "json" | "form" | "urlencoded";
521
595
  handler: (ctx: unknown) => Awaitable<Response>;
@@ -553,7 +627,7 @@ type RouteHandleResult<
553
627
  };
554
628
  };
555
629
 
556
- export type RouteBuilderBase<
630
+ export type RouteContractBuilderBase<
557
631
  Path extends RoutePath,
558
632
  TMethod extends Method,
559
633
  Acc extends readonly unknown[] = readonly [],
@@ -574,7 +648,7 @@ export type RouteBuilderBase<
574
648
  };
575
649
  query<TQuery, TQueryIn = unknown>(
576
650
  schema: Schema<TQuery, TQueryIn>,
577
- ): RouteBuilder<
651
+ ): RouteContractBuilder<
578
652
  Path,
579
653
  TMethod,
580
654
  Acc,
@@ -584,7 +658,7 @@ export type RouteBuilderBase<
584
658
  >;
585
659
  params<TParams, TParamsIn = unknown>(
586
660
  schema: Schema<TParams, TParamsIn>,
587
- ): RouteBuilder<
661
+ ): RouteContractBuilder<
588
662
  Path,
589
663
  TMethod,
590
664
  Acc,
@@ -594,44 +668,7 @@ export type RouteBuilderBase<
594
668
  >;
595
669
  returns<const M extends ReturnsMap>(
596
670
  map: M,
597
- ): RouteBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
598
- use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(
599
- unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>,
600
- ..._assert: [
601
- IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
602
- IsStateSatisfied<RouteResolvedField<Path, TMethod, Acc, "state">, TRequiredState>,
603
- ] extends [true, true]
604
- ? []
605
- : [
606
- {
607
- error: "Middleware cannot be attached to this route";
608
- requiredLayouts: TRequiredLayouts;
609
- routeLayoutChain: RouteLayoutChain<Path, TMethod>;
610
- requiredState: TRequiredState;
611
- actualState: RouteResolvedField<Path, TMethod, Acc, "state">;
612
- },
613
- ]
614
- ): RouteBuilder<
615
- Path,
616
- TMethod,
617
- readonly [...Acc, TAcc],
618
- Validators,
619
- Omit<TReturns, keyof UReturns> & UReturns,
620
- TAppContext
621
- >;
622
- use<R = unknown>(
623
- fn: (
624
- ctx: RouteChainContext<Path, TMethod, Acc, unknown, unknown, unknown, TAppContext>,
625
- next: NextFn,
626
- ) => Awaitable<R>,
627
- ): RouteBuilder<
628
- Path,
629
- TMethod,
630
- readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>],
631
- Validators,
632
- TReturns,
633
- TAppContext
634
- >;
671
+ ): RouteContractBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
635
672
  handler<R extends Response = Response>(
636
673
  fn: (
637
674
  ctx: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS"
@@ -649,20 +686,20 @@ export type RouteBuilderBase<
649
686
  ): RouteHandleResult<Path, TMethod, Acc, Validators, TReturns, R, TAppContext>;
650
687
  };
651
688
 
652
- export type RouteBuilder<
689
+ export type RouteContractBuilder<
653
690
  Path extends RoutePath,
654
691
  TMethod extends Method,
655
692
  Acc extends readonly unknown[] = readonly [],
656
693
  Validators extends ValidatorParts = {},
657
694
  TReturns extends ReturnsMap = {},
658
695
  TAppContext extends Record<string, unknown> = AppContext,
659
- > = RouteBuilderBase<Path, TMethod, Acc, Validators, TReturns, TAppContext> &
696
+ > = RouteContractBuilderBase<Path, TMethod, Acc, Validators, TReturns, TAppContext> &
660
697
  (TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS"
661
698
  ? {}
662
699
  : {
663
700
  body<TBody, TBodyIn = unknown>(
664
701
  schema: Schema<TBody, TBodyIn>,
665
- ): RouteBuilder<
702
+ ): RouteContractBuilder<
666
703
  Path,
667
704
  TMethod,
668
705
  Acc,
@@ -673,7 +710,7 @@ export type RouteBuilder<
673
710
  body<Mode extends "json" | "form" | "urlencoded", TBody, TBodyIn = unknown>(
674
711
  mode: Mode,
675
712
  schema: Schema<TBody, TBodyIn>,
676
- ): RouteBuilder<
713
+ ): RouteContractBuilder<
677
714
  Path,
678
715
  TMethod,
679
716
  Acc,
@@ -683,6 +720,80 @@ export type RouteBuilder<
683
720
  >;
684
721
  });
685
722
 
723
+ export type RouteMiddlewareBuilder<
724
+ Path extends RoutePath,
725
+ TMethod extends Method,
726
+ Acc extends readonly unknown[] = readonly [],
727
+ Validators extends ValidatorParts = {},
728
+ TReturns extends ReturnsMap = {},
729
+ TAppContext extends Record<string, unknown> = AppContext,
730
+ > = RouteContractBuilder<Path, TMethod, Acc, Validators, TReturns, TAppContext> & {
731
+ use<
732
+ TAcc,
733
+ UReturns extends ReturnsMap = {},
734
+ TRequiredLayouts = unknown,
735
+ TRequires extends MiddlewareRequirements = {},
736
+ >(
737
+ unit: [
738
+ IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
739
+ IsRequirementsSatisfied<
740
+ {
741
+ query: RouteResolvedField<Path, TMethod, Acc, "query">;
742
+ params: ResolveParams<PathParams<Path>, RouteResolvedField<Path, TMethod, Acc, "params">>;
743
+ body: RouteResolvedField<Path, TMethod, Acc, "body">;
744
+ state: RouteResolvedField<Path, TMethod, Acc, "state">;
745
+ },
746
+ TRequires
747
+ >,
748
+ ] extends [true, true]
749
+ ? MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequires>
750
+ : {
751
+ error: "Middleware cannot be attached to this route";
752
+ requiredLayouts: TRequiredLayouts;
753
+ routeLayoutChain: RouteLayoutChain<Path, TMethod>;
754
+ requirements: TRequires;
755
+ actual: {
756
+ query: RouteResolvedField<Path, TMethod, Acc, "query">;
757
+ params: ResolveParams<
758
+ PathParams<Path>,
759
+ RouteResolvedField<Path, TMethod, Acc, "params">
760
+ >;
761
+ body: RouteResolvedField<Path, TMethod, Acc, "body">;
762
+ state: RouteResolvedField<Path, TMethod, Acc, "state">;
763
+ };
764
+ },
765
+ ): RouteMiddlewareBuilder<
766
+ Path,
767
+ TMethod,
768
+ readonly [...Acc, TAcc],
769
+ Validators,
770
+ Omit<TReturns, keyof UReturns> & UReturns,
771
+ TAppContext
772
+ >;
773
+ use<R = unknown>(
774
+ fn: (
775
+ ctx: RouteChainContext<Path, TMethod, Acc, unknown, unknown, unknown, TAppContext>,
776
+ next: NextFn,
777
+ ) => Awaitable<R>,
778
+ ): RouteMiddlewareBuilder<
779
+ Path,
780
+ TMethod,
781
+ readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>],
782
+ Validators,
783
+ TReturns,
784
+ TAppContext
785
+ >;
786
+ };
787
+
788
+ export type RouteBuilder<
789
+ Path extends RoutePath,
790
+ TMethod extends Method,
791
+ Acc extends readonly unknown[] = readonly [],
792
+ Validators extends ValidatorParts = {},
793
+ TReturns extends ReturnsMap = {},
794
+ TAppContext extends Record<string, unknown> = AppContext,
795
+ > = RouteMiddlewareBuilder<Path, TMethod, Acc, Validators, TReturns, TAppContext>;
796
+
686
797
  export type RouteDefinition<
687
798
  Path extends RoutePath = RoutePath,
688
799
  TMethod extends Method = Method,
@@ -80,6 +80,13 @@ export type MiddlewareReturnFromParts<
80
80
  };
81
81
  };
82
82
 
83
+ export type MiddlewareRequirements = {
84
+ query?: Record<string, unknown>;
85
+ params?: Record<string, unknown>;
86
+ body?: unknown;
87
+ state?: Record<string, unknown>;
88
+ };
89
+
83
90
  export type DefineMiddlewareResult<
84
91
  TQuery,
85
92
  TParams,
@@ -91,7 +98,7 @@ export type DefineMiddlewareResult<
91
98
  TBodyIn = TBody,
92
99
  TReturns extends ReturnsMap = {},
93
100
  TLayout = null,
94
- TRequires = {},
101
+ TRequires extends MiddlewareRequirements = {},
95
102
  > = MiddlewareUnit<
96
103
  MiddlewareReturnFromParts<
97
104
  TQuery,
@@ -113,13 +120,30 @@ export type StandaloneMiddlewareContext<
113
120
  TBody = unknown,
114
121
  TAppContext extends Record<string, unknown> = EmptyAppContext,
115
122
  TState = {},
123
+ TRequires extends MiddlewareRequirements = {},
116
124
  > = Simplify<
117
125
  TAppContext &
118
126
  UnitRuntimeContext & {
119
- query: Simplify<UnwrapPart<TQuery>>;
120
- params: Simplify<UnwrapPart<TParams>>;
121
- body: Simplify<UnwrapPart<TBody>>;
122
- state: Simplify<UnwrapPart<TState>>;
127
+ query: Simplify<
128
+ UnwrapPart<TQuery> &
129
+ (TRequires["query"] extends Record<string, unknown> ? TRequires["query"] : {})
130
+ >;
131
+ params: Simplify<
132
+ UnwrapPart<TParams> &
133
+ (TRequires["params"] extends Record<string, unknown> ? TRequires["params"] : {})
134
+ >;
135
+ body: Simplify<
136
+ UnwrapPart<TBody> &
137
+ (unknown extends TRequires["body"]
138
+ ? {}
139
+ : [TRequires["body"]] extends [undefined]
140
+ ? {}
141
+ : TRequires["body"])
142
+ >;
143
+ state: Simplify<
144
+ UnwrapPart<TState> &
145
+ (TRequires["state"] extends Record<string, unknown> ? TRequires["state"] : {})
146
+ >;
123
147
  headers: TaserHeaders;
124
148
  cookies: TaserCookieJar;
125
149
  }
@@ -131,13 +155,13 @@ export type MiddlewareUnit<
131
155
  TAcc = unknown,
132
156
  TReturns extends ReturnsMap = {},
133
157
  TRequiredLayouts = unknown,
134
- TRequiredState = unknown,
158
+ TRequires extends MiddlewareRequirements = {},
135
159
  > = MiddlewareDefinition & {
136
160
  readonly [MiddlewareUnitBrand]: true;
137
161
  readonly __middlewareAcc: TAcc;
138
162
  readonly __returns?: TReturns;
139
163
  readonly __requiredLayouts?: TRequiredLayouts;
140
- readonly __requiredState?: TRequiredState;
164
+ readonly __requirements?: TRequires;
141
165
  };
142
166
 
143
167
  export type MiddlewareUnitBuilder<
@@ -146,7 +170,7 @@ export type MiddlewareUnitBuilder<
146
170
  TBody = unknown,
147
171
  TReturns extends ReturnsMap = {},
148
172
  TRequiredLayouts = unknown,
149
- TRequiredState = {},
173
+ TRequires extends MiddlewareRequirements = {},
150
174
  TAppContext extends Record<string, unknown> = EmptyAppContext,
151
175
  TInheritedState = {},
152
176
  TQueryIn = unknown,
@@ -165,7 +189,7 @@ export type MiddlewareUnitBuilder<
165
189
  >,
166
190
  TReturns,
167
191
  TRequiredLayouts,
168
- TRequiredState
192
+ TRequires
169
193
  > & {
170
194
  query<Q, QIn = unknown>(
171
195
  schema: Schema<Q, QIn>,
@@ -175,7 +199,7 @@ export type MiddlewareUnitBuilder<
175
199
  TBody,
176
200
  TReturns,
177
201
  TRequiredLayouts,
178
- TRequiredState,
202
+ TRequires,
179
203
  TAppContext,
180
204
  TInheritedState,
181
205
  QIn,
@@ -191,7 +215,7 @@ export type MiddlewareUnitBuilder<
191
215
  TBody,
192
216
  TReturns,
193
217
  TRequiredLayouts,
194
- TRequiredState,
218
+ TRequires,
195
219
  TAppContext,
196
220
  TInheritedState,
197
221
  TQueryIn,
@@ -207,7 +231,7 @@ export type MiddlewareUnitBuilder<
207
231
  B,
208
232
  TReturns,
209
233
  TRequiredLayouts,
210
- TRequiredState,
234
+ TRequires,
211
235
  TAppContext,
212
236
  TInheritedState,
213
237
  TQueryIn,
@@ -224,7 +248,7 @@ export type MiddlewareUnitBuilder<
224
248
  B,
225
249
  TReturns,
226
250
  TRequiredLayouts,
227
- TRequiredState,
251
+ TRequires,
228
252
  TAppContext,
229
253
  TInheritedState,
230
254
  TQueryIn,
@@ -240,7 +264,7 @@ export type MiddlewareUnitBuilder<
240
264
  TBody,
241
265
  Omit<TReturns, keyof M> & M,
242
266
  TRequiredLayouts,
243
- TRequiredState,
267
+ TRequires,
244
268
  TAppContext,
245
269
  TInheritedState,
246
270
  TQueryIn,
@@ -248,13 +272,13 @@ export type MiddlewareUnitBuilder<
248
272
  TBodyIn,
249
273
  TExpectedState
250
274
  >;
251
- requires<Requires extends Record<string, unknown>>(): MiddlewareUnitBuilder<
275
+ requires<Requires extends MiddlewareRequirements>(): MiddlewareUnitBuilder<
252
276
  TQuery,
253
277
  TParams,
254
278
  TBody,
255
279
  TReturns,
256
280
  TRequiredLayouts,
257
- TRequiredState & Requires,
281
+ TRequires & Requires,
258
282
  TAppContext,
259
283
  TInheritedState,
260
284
  TQueryIn,
@@ -269,7 +293,8 @@ export type MiddlewareUnitBuilder<
269
293
  TParams,
270
294
  TBody,
271
295
  TAppContext,
272
- TInheritedState & TRequiredState
296
+ TInheritedState,
297
+ TRequires
273
298
  >,
274
299
  next: NextFn<TExpectedState>,
275
300
  ) => R,
@@ -284,6 +309,6 @@ export type MiddlewareUnitBuilder<
284
309
  TBodyIn,
285
310
  TReturns,
286
311
  TRequiredLayouts,
287
- TRequiredState
312
+ TRequires
288
313
  >;
289
314
  };