@aklinker1/zeta 1.3.3 → 2.1.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/src/types.ts CHANGED
@@ -130,12 +130,7 @@ export interface App<TAppData extends AppData = AppData> {
130
130
  onGlobalRequest(
131
131
  callback: (
132
132
  ctx: OnGlobalRequestContext<GetAppDataCtx<TAppData>>,
133
- ) => MaybePromise<void>,
134
- ): this;
135
- onGlobalRequest(
136
- callback: (
137
- ctx: OnGlobalRequestContext<GetAppDataCtx<TAppData>>,
138
- ) => MaybePromise<Response>,
133
+ ) => MaybePromise<Response | void>,
139
134
  ): this;
140
135
  onGlobalRequest<TNewCtx extends Record<string, any>>(
141
136
  callback: (
@@ -154,12 +149,7 @@ export interface App<TAppData extends AppData = AppData> {
154
149
  onTransform(
155
150
  callback: (
156
151
  ctx: OnTransformContext<GetAppDataCtx<TAppData>>,
157
- ) => MaybePromise<void>,
158
- ): this;
159
- onTransform(
160
- callback: (
161
- ctx: OnTransformContext<GetAppDataCtx<TAppData>>,
162
- ) => MaybePromise<Response>,
152
+ ) => MaybePromise<Response | void>,
163
153
  ): this;
164
154
  onTransform<TNewCtx extends Record<string, any>>(
165
155
  callback: (
@@ -178,12 +168,7 @@ export interface App<TAppData extends AppData = AppData> {
178
168
  onBeforeHandle(
179
169
  callback: (
180
170
  ctx: OnBeforeHandleContext<GetAppDataCtx<TAppData>>,
181
- ) => MaybePromise<void>,
182
- ): this;
183
- onBeforeHandle(
184
- callback: (
185
- ctx: OnBeforeHandleContext<GetAppDataCtx<TAppData>>,
186
- ) => MaybePromise<Response>,
171
+ ) => MaybePromise<Response | void>,
187
172
  ): this;
188
173
  onBeforeHandle<TNewCtx extends Record<string, any>>(
189
174
  callback: (
@@ -434,11 +419,20 @@ export type RouterData = {
434
419
  def?: RouteDef;
435
420
  route: string;
436
421
  hooks: LifeCycleHooks;
422
+ compiledHandler: CompiledRouteHandler;
437
423
  } & (
438
424
  | { fetch: ServerSideFetch }
439
425
  | { handler: (ctx: OnBeforeHandleContext) => Promise<any> }
440
426
  );
441
427
 
428
+ /**
429
+ * Function type called internally once a route is matched for a request.
430
+ */
431
+ export type CompiledRouteHandler = (
432
+ request: Request,
433
+ ctx: any,
434
+ ) => MaybePromise<Response>;
435
+
442
436
  //
443
437
  // HANDLERS
444
438
  //
@@ -512,9 +506,7 @@ export type LifeCycleHook<TCallback extends Function> = {
512
506
  * into the handler context.
513
507
  */
514
508
  export type OnGlobalRequestHook = LifeCycleHook<
515
- (
516
- ctx: Simplify<OnGlobalRequestContext>,
517
- ) => MaybePromise<Record<string, any> | void>
509
+ (ctx: Simplify<OnGlobalRequestContext>) => Record<string, any> | void
518
510
  >;
519
511
 
520
512
  /**
@@ -560,27 +552,29 @@ export type OnMapResponseHook = LifeCycleHook<
560
552
  * Zeta will handle any `HttpError`s thrown, but you can handle your own errors
561
553
  * here.
562
554
  */
563
- export type OnGlobalErrorHooks = LifeCycleHook<
564
- (ctx: Simplify<OnGlobalErrorContext>) => MaybePromise<void>
555
+ export type OnGlobalErrorHook = LifeCycleHook<
556
+ (ctx: Simplify<OnGlobalErrorContext>) => void
565
557
  >;
566
558
 
567
559
  /**
568
560
  * Called after the response is sent back to the client.
569
561
  */
570
562
  export type OnGlobalAfterResponseHook = LifeCycleHook<
571
- (ctx: Simplify<AfterResponseContext>) => MaybePromise<void>
563
+ (ctx: Simplify<AfterResponseContext>) => void
572
564
  >;
573
565
 
574
566
  export type LifeCycleHooks = {
575
- onGlobalRequest: OnGlobalRequestHook[];
576
- onTransform: OnTransformHook[];
577
- onBeforeHandle: OnBeforeHandleHook[];
578
- onAfterHandle: OnAfterHandleHook[];
579
- onMapResponse: OnMapResponseHook[];
580
- onGlobalError: OnGlobalErrorHooks[];
581
- onGlobalAfterResponse: OnGlobalAfterResponseHook[];
567
+ onGlobalRequest?: OnGlobalRequestHook[];
568
+ onTransform?: OnTransformHook[];
569
+ onBeforeHandle?: OnBeforeHandleHook[];
570
+ onAfterHandle?: OnAfterHandleHook[];
571
+ onMapResponse?: OnMapResponseHook[];
572
+ onGlobalError?: OnGlobalErrorHook[];
573
+ onGlobalAfterResponse?: OnGlobalAfterResponseHook[];
582
574
  };
583
575
 
576
+ export type LifeCycleHookName = keyof LifeCycleHooks;
577
+
584
578
  //
585
579
  // BASE TYPES
586
580
  //
@@ -1028,17 +1022,6 @@ export interface SchemaAdapter {
1028
1022
  * @returns The JSON schema.
1029
1023
  */
1030
1024
  toJsonSchema: (schema: any) => any;
1031
- /**
1032
- * Used to pull out the openapi parameters from a schema.
1033
- * @param schema The schema to parse.
1034
- * @returns An array of objects used to generate the OpenAPI docs.
1035
- */
1036
- parseParamsRecord: (schema: StandardSchemaV1) => Array<{
1037
- name: string;
1038
- optional: boolean;
1039
- schema: StandardSchemaV1;
1040
- description?: string;
1041
- }>;
1042
1025
  getMeta: (schema: StandardSchemaV1) => Record<string, any> | undefined;
1043
1026
  }
1044
1027
 
@@ -1,139 +0,0 @@
1
- import type { MatchedRoute } from "rou3";
2
- import type { RouterData, SchemaAdapter } from "../types";
3
- import { NotFoundHttpError } from "../errors";
4
- import {
5
- callCtxModifierHooks,
6
- getRawParams,
7
- getRawQuery,
8
- isStatusResult,
9
- IsStatusResult,
10
- validateInputSchema,
11
- validateOutputSchema,
12
- } from "./utils";
13
- import { smartDeserialize, smartSerialize } from "./serialization";
14
- import { getMeta } from "../meta";
15
-
16
- export async function callHandler(
17
- ctx: any,
18
- getRoute: (
19
- method: string,
20
- path: string,
21
- ) => MatchedRoute<RouterData> | undefined,
22
- schemaAdapter: SchemaAdapter | undefined,
23
- ): Promise<Response> {
24
- const route = getRoute(ctx.method, ctx.path);
25
- if (route == null) {
26
- throw new NotFoundHttpError(undefined, {
27
- method: ctx.method,
28
- path: ctx.path,
29
- });
30
- }
31
-
32
- if ("fetch" in route.data) {
33
- const res = route.data.fetch(ctx.request);
34
- return res instanceof Promise ? await res : res;
35
- }
36
-
37
- const rawBody = await smartDeserialize(ctx.request);
38
- const rawQuery = getRawQuery(ctx.url);
39
- const rawParams = getRawParams(route);
40
- ctx.route = route.data.route;
41
- ctx.params = rawParams;
42
- ctx.query = rawQuery;
43
- ctx.body = rawBody;
44
-
45
- if (route.data.hooks.onTransform.length > 0) {
46
- const onTransformResponse = await callCtxModifierHooks(
47
- ctx,
48
- route.data.hooks.onTransform,
49
- );
50
- if (onTransformResponse) return onTransformResponse;
51
- }
52
-
53
- if (route.data.def?.body)
54
- ctx.body = validateInputSchema(route.data.def?.body, rawBody);
55
- if (route.data.def?.query)
56
- ctx.query = validateInputSchema(route.data.def?.query, rawQuery);
57
- if (route.data.def?.params)
58
- ctx.params = validateInputSchema(route.data.def?.params, rawParams);
59
-
60
- if (route.data.hooks.onBeforeHandle.length > 0) {
61
- const res = await callCtxModifierHooks(
62
- ctx,
63
- route.data.hooks.onBeforeHandle,
64
- );
65
- if (res) return res;
66
- }
67
-
68
- ctx.status = (status: number, body: any) => ({
69
- [IsStatusResult]: true,
70
- status,
71
- body,
72
- });
73
-
74
- {
75
- let response: any = route.data.handler(ctx);
76
- if (response instanceof Promise) response = await response;
77
-
78
- ctx.response = response;
79
- }
80
-
81
- for (const hook of route.data.hooks.onAfterHandle) {
82
- let res = hook.callback(ctx);
83
- res = res instanceof Promise ? await res : res;
84
- if (res instanceof Response) return res;
85
- ctx.response = res;
86
- }
87
-
88
- let responseMeta: Record<string, any> | undefined;
89
- if (!(ctx.response instanceof Response)) {
90
- if (route.data.def?.responses) {
91
- if ("~standard" in route.data.def.responses) {
92
- ctx.response = validateOutputSchema(
93
- route.data.def.responses,
94
- ctx.response,
95
- );
96
- responseMeta = getMeta(schemaAdapter, route.data.def.responses);
97
- } else {
98
- if (!ctx.response || !isStatusResult(ctx.response)) {
99
- throw new Error(
100
- "When `responses` is a record of schemas, you must return a value from `ctx.status(...)`.",
101
- );
102
- }
103
- const { status, body } = ctx.response;
104
- const schema = route.data.def.responses[status];
105
- if (!schema) {
106
- // This should be caught by the `status` function's type definition, but it's here as a safeguard.
107
- throw new Error(`No response schema found for status ${status}.`);
108
- }
109
- ctx.set.status = status;
110
- ctx.response = validateOutputSchema(schema, body);
111
- responseMeta = getMeta(schemaAdapter, schema);
112
- }
113
- }
114
- }
115
-
116
- if (ctx.response instanceof Response) return ctx.response;
117
-
118
- for (const hook of route.data.hooks.onMapResponse) {
119
- let res = hook.callback(ctx);
120
- res = res instanceof Promise ? await res : res;
121
- if (res instanceof Response) return res;
122
- ctx.response = res;
123
- }
124
-
125
- const resBody = smartSerialize(ctx.response);
126
- if (!resBody)
127
- return new Response(undefined, {
128
- status: ctx.set.status,
129
- headers: ctx.set.headers,
130
- });
131
-
132
- return new Response(resBody.serialized, {
133
- status: ctx.set.status,
134
- headers: {
135
- "Content-Type": responseMeta?.contentType ?? resBody.contentType,
136
- ...ctx.set.headers,
137
- },
138
- });
139
- }