better-call 1.3.3 → 2.0.0-beta.2

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.
Files changed (59) hide show
  1. package/dist/client.cjs.map +1 -1
  2. package/dist/client.d.cts +13 -17
  3. package/dist/client.d.mts +13 -17
  4. package/dist/client.mjs.map +1 -1
  5. package/dist/context.cjs +10 -9
  6. package/dist/context.cjs.map +1 -1
  7. package/dist/context.d.cts +129 -323
  8. package/dist/context.d.mts +129 -323
  9. package/dist/context.mjs +10 -9
  10. package/dist/context.mjs.map +1 -1
  11. package/dist/cookies.cjs +1 -1
  12. package/dist/cookies.d.cts +1 -12
  13. package/dist/cookies.d.mts +1 -12
  14. package/dist/cookies.mjs +1 -1
  15. package/dist/crypto.cjs.map +1 -1
  16. package/dist/crypto.mjs.map +1 -1
  17. package/dist/endpoint.cjs +21 -7
  18. package/dist/endpoint.cjs.map +1 -1
  19. package/dist/endpoint.d.cts +197 -392
  20. package/dist/endpoint.d.mts +197 -392
  21. package/dist/endpoint.mjs +21 -7
  22. package/dist/endpoint.mjs.map +1 -1
  23. package/dist/error.cjs +1 -1
  24. package/dist/error.cjs.map +1 -1
  25. package/dist/error.mjs +1 -1
  26. package/dist/error.mjs.map +1 -1
  27. package/dist/helper.d.cts +2 -3
  28. package/dist/helper.d.mts +2 -3
  29. package/dist/index.cjs +3 -10
  30. package/dist/index.d.cts +9 -8
  31. package/dist/index.d.mts +9 -8
  32. package/dist/index.mjs +3 -4
  33. package/dist/middleware.cjs +59 -13
  34. package/dist/middleware.cjs.map +1 -1
  35. package/dist/middleware.d.cts +85 -42
  36. package/dist/middleware.d.mts +85 -42
  37. package/dist/middleware.mjs +59 -13
  38. package/dist/middleware.mjs.map +1 -1
  39. package/dist/node.cjs.map +1 -1
  40. package/dist/node.d.cts +1 -1
  41. package/dist/node.d.mts +1 -1
  42. package/dist/node.mjs.map +1 -1
  43. package/dist/openapi.cjs.map +1 -1
  44. package/dist/openapi.d.cts +1 -1
  45. package/dist/openapi.d.mts +1 -1
  46. package/dist/openapi.mjs.map +1 -1
  47. package/dist/router.cjs.map +1 -1
  48. package/dist/router.mjs.map +1 -1
  49. package/dist/to-response.cjs +1 -1
  50. package/dist/to-response.cjs.map +1 -1
  51. package/dist/to-response.mjs +1 -1
  52. package/dist/to-response.mjs.map +1 -1
  53. package/dist/types.d.cts +142 -0
  54. package/dist/types.d.mts +142 -0
  55. package/dist/validator.cjs +1 -1
  56. package/dist/validator.cjs.map +1 -1
  57. package/dist/validator.mjs +1 -1
  58. package/dist/validator.mjs.map +1 -1
  59. package/package.json +3 -3
@@ -1,341 +1,147 @@
1
- import { InferParamPath, InferParamWildCard, IsEmptyObject, Prettify, UnionToIntersection } from "./helper.cjs";
2
- import { StandardSchemaV1 } from "./standard-schema.cjs";
3
- import { Status, statusCodes } from "./error.cjs";
4
1
  import { CookieOptions, CookiePrefixOptions } from "./cookies.cjs";
5
- import { Middleware, MiddlewareOptions } from "./middleware.cjs";
6
- import { EndpointOptions } from "./endpoint.cjs";
2
+ import { APIError, Status, statusCodes } from "./error.cjs";
3
+ import { Prettify } from "./helper.cjs";
4
+ import { InferParam, InferUse, ResolveBody, ResolveMethod, ResolveQuery } from "./types.cjs";
5
+ import { Middleware } from "./middleware.cjs";
7
6
 
8
7
  //#region src/context.d.ts
9
- type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
10
- type Method = HTTPMethod | "*";
11
- type InferBodyInput<Options extends EndpointOptions | MiddlewareOptions, Body = (Options["metadata"] extends {
12
- $Infer: {
13
- body: infer B;
14
- };
15
- } ? B : Options["body"] extends StandardSchemaV1 ? StandardSchemaV1.InferInput<Options["body"]> : undefined)> = undefined extends Body ? {
16
- body?: Body;
17
- } : {
18
- body: Body;
19
- };
20
- type InferBody<Options extends EndpointOptions | MiddlewareOptions> = Options["metadata"] extends {
21
- $Infer: {
22
- body: infer Body;
23
- };
24
- } ? Body : Options["body"] extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Options["body"]> : any;
25
- type InferQueryInput<Options extends EndpointOptions | MiddlewareOptions, Query = (Options["metadata"] extends {
26
- $Infer: {
27
- query: infer Query;
28
- };
29
- } ? Query : Options["query"] extends StandardSchemaV1 ? StandardSchemaV1.InferInput<Options["query"]> : Record<string, any> | undefined)> = undefined extends Query ? {
30
- query?: Query;
31
- } : {
32
- query: Query;
33
- };
34
- type InferQuery<Options extends EndpointOptions | MiddlewareOptions> = Options["metadata"] extends {
35
- $Infer: {
36
- query: infer Query;
37
- };
38
- } ? Query : Options["query"] extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Options["query"]> : Record<string, any> | undefined;
39
- type InferMethod<Options extends EndpointOptions> = Options["method"] extends Array<Method> ? Options["method"][number] : Options["method"] extends "*" ? HTTPMethod : Options["method"];
40
- type InferInputMethod<Options extends EndpointOptions, Method = (Options["method"] extends Array<any> ? Options["method"][number] | undefined : Options["method"] extends "*" ? HTTPMethod : Options["method"] | undefined)> = undefined extends Method ? {
41
- method?: Method;
42
- } : {
43
- method: Method;
44
- };
45
- type InferParam<Path extends string> = [Path] extends [never] ? Record<string, any> | undefined : IsEmptyObject<InferParamPath<Path> & InferParamWildCard<Path>> extends true ? Record<string, any> | undefined : Prettify<InferParamPath<Path> & InferParamWildCard<Path>>;
46
- type InferParamInput<Path extends string> = [Path] extends [never] ? {
47
- params?: Record<string, any>;
48
- } : IsEmptyObject<InferParamPath<Path> & InferParamWildCard<Path>> extends true ? {
49
- params?: Record<string, any>;
50
- } : {
51
- params: Prettify<InferParamPath<Path> & InferParamWildCard<Path>>;
52
- };
53
- type InferRequest<Option extends EndpointOptions | MiddlewareOptions> = Option["requireRequest"] extends true ? Request : Request | undefined;
54
- type InferRequestInput<Option extends EndpointOptions | MiddlewareOptions> = Option["requireRequest"] extends true ? {
55
- request: Request;
56
- } : {
57
- request?: Request;
58
- };
59
- type InferHeaders<Option extends EndpointOptions | MiddlewareOptions> = Option["requireHeaders"] extends true ? Headers : Headers | undefined;
60
- type InferHeadersInput<Option extends EndpointOptions | MiddlewareOptions> = Option["requireHeaders"] extends true ? {
61
- headers: HeadersInit;
62
- } : {
63
- headers?: HeadersInit;
64
- };
65
- type InferUse<Opts extends EndpointOptions["use"]> = Opts extends Middleware[] ? UnionToIntersection<Awaited<ReturnType<Opts[number]>>> : {};
66
- type InferMiddlewareBody<Options extends MiddlewareOptions> = Options["body"] extends StandardSchemaV1<infer T> ? T : any;
67
- type InferMiddlewareQuery<Options extends MiddlewareOptions> = Options["query"] extends StandardSchemaV1<infer T> ? T : Record<string, any> | undefined;
68
- type InputContext<Path extends string, Options extends EndpointOptions> = InferBodyInput<Options> & InferInputMethod<Options> & InferQueryInput<Options> & InferParamInput<Path> & InferRequestInput<Options> & InferHeadersInput<Options> & {
69
- asResponse?: boolean;
70
- returnHeaders?: boolean;
71
- returnStatus?: boolean;
72
- use?: Middleware[];
73
- path?: string;
74
- context?: Record<string, any>;
75
- };
76
- declare const createInternalContext: (context: InputContext<any, any>, {
77
- options,
78
- path
79
- }: {
80
- options: EndpointOptions;
81
- path?: string;
82
- }) => Promise<{
83
- body: any;
84
- query: any;
85
- path: string;
86
- context: Record<string, any>;
87
- returned: any;
88
- headers: HeadersInit | undefined;
89
- request: Request | undefined;
90
- params: Record<string, any> | undefined;
91
- method: any;
8
+ type EndpointContext<Path extends string, M, BodySchema extends object | undefined, QuerySchema extends object | undefined, Use extends Middleware[], ReqHeaders extends boolean, ReqRequest extends boolean, Context = {}, Meta = undefined> = {
9
+ /**
10
+ * Method
11
+ *
12
+ * The request method
13
+ */
14
+ method: ResolveMethod<M>;
15
+ /**
16
+ * Path
17
+ *
18
+ * The path of the endpoint
19
+ */
20
+ path: Path;
21
+ /**
22
+ * Body
23
+ *
24
+ * The body object will be the parsed JSON from the request and validated
25
+ * against the body schema if it exists.
26
+ */
27
+ body: ResolveBody<BodySchema, Meta>;
28
+ /**
29
+ * Query
30
+ *
31
+ * The query object will be the parsed query string from the request
32
+ * and validated against the query schema if it exists
33
+ */
34
+ query: ResolveQuery<QuerySchema, Meta>;
35
+ /**
36
+ * Params
37
+ *
38
+ * If the path is `/user/:id` and the request is `/user/1` then the params will
39
+ * be `{ id: "1" }` and if the path includes a wildcard like `/user/*` then the
40
+ * params will be `{ _: "1" }` where `_` is the wildcard key. If the wildcard
41
+ * is named like `/user/**:name` then the params will be `{ name: string }`
42
+ */
43
+ params: InferParam<Path>;
44
+ /**
45
+ * Request object
46
+ *
47
+ * If `requireRequest` is set to true in the endpoint options this will be
48
+ * required
49
+ */
50
+ request: ReqRequest extends true ? Request : Request | undefined;
51
+ /**
52
+ * Headers
53
+ *
54
+ * If `requireHeaders` is set to true in the endpoint options this will be
55
+ * required
56
+ */
57
+ headers: ReqHeaders extends true ? Headers : Headers | undefined;
58
+ /**
59
+ * Set header
60
+ *
61
+ * If it's called outside of a request it will just be ignored.
62
+ */
92
63
  setHeader: (key: string, value: string) => void;
93
- getHeader: (key: string) => string | null;
94
- getCookie: (key: string, prefix?: CookiePrefixOptions) => string | null;
95
- getSignedCookie: (key: string, secret: string, prefix?: CookiePrefixOptions) => Promise<string | false | null>;
96
- setCookie: (key: string, value: string, options?: CookieOptions) => string;
97
- setSignedCookie: (key: string, value: string, secret: string, options?: CookieOptions) => Promise<string>;
98
- redirect: (url: string) => {
99
- status: keyof typeof statusCodes | Status;
100
- body: ({
101
- message?: string;
102
- code?: string;
103
- cause?: unknown;
104
- } & Record<string, any>) | undefined;
105
- headers: HeadersInit;
106
- statusCode: number;
107
- name: string;
108
- message: string;
109
- stack?: string;
110
- cause?: unknown;
111
- } & {
112
- errorStack: string | undefined;
113
- };
114
- error: (status: keyof typeof statusCodes | Status, body?: {
115
- message?: string;
116
- code?: string;
117
- } | undefined, headers?: HeadersInit) => {
118
- status: keyof typeof statusCodes | Status;
119
- body: ({
120
- message?: string;
121
- code?: string;
122
- cause?: unknown;
123
- } & Record<string, any>) | undefined;
124
- headers: HeadersInit;
125
- statusCode: number;
126
- name: string;
127
- message: string;
128
- stack?: string;
129
- cause?: unknown;
130
- } & {
131
- errorStack: string | undefined;
132
- };
64
+ /**
65
+ * Set the response status code
66
+ */
133
67
  setStatus: (status: Status) => void;
134
- json: (json: Record<string, any>, routerResponse?: {
135
- status?: number;
136
- headers?: Record<string, string>;
137
- response?: Response;
138
- body?: Record<string, any>;
139
- } | Response) => Record<string, any>;
140
- responseHeaders: Headers;
141
- responseStatus: Status | undefined;
142
- asResponse?: boolean;
143
- returnHeaders?: boolean;
144
- returnStatus?: boolean;
145
- use?: Middleware[];
146
- } | {
147
- body: any;
148
- query: any;
149
- path: string;
150
- context: Record<string, any>;
151
- returned: any;
152
- headers: HeadersInit | undefined;
153
- request: Request | undefined;
154
- params: Record<string, any> | undefined;
155
- method: any;
156
- setHeader: (key: string, value: string) => void;
68
+ /**
69
+ * Get header
70
+ *
71
+ * If it's called outside of a request it will just return null
72
+ *
73
+ * @param key - The key of the header
74
+ */
157
75
  getHeader: (key: string) => string | null;
76
+ /**
77
+ * Get a cookie value from the request
78
+ *
79
+ * @param key - The key of the cookie
80
+ * @param prefix - The prefix of the cookie between `__Secure-` and `__Host-`
81
+ * @returns The value of the cookie
82
+ */
158
83
  getCookie: (key: string, prefix?: CookiePrefixOptions) => string | null;
159
- getSignedCookie: (key: string, secret: string, prefix?: CookiePrefixOptions) => Promise<string | false | null>;
84
+ /**
85
+ * Get a signed cookie value from the request
86
+ *
87
+ * @param key - The key of the cookie
88
+ * @param secret - The secret of the signed cookie
89
+ * @param prefix - The prefix of the cookie between `__Secure-` and `__Host-`
90
+ * @returns The value of the cookie or null if the cookie is not found or false if the signature is invalid
91
+ */
92
+ getSignedCookie: (key: string, secret: string, prefix?: CookiePrefixOptions) => Promise<string | null | false>;
93
+ /**
94
+ * Set a cookie value in the response
95
+ *
96
+ * @param key - The key of the cookie
97
+ * @param value - The value to set
98
+ * @param options - The options of the cookie
99
+ * @returns The cookie string
100
+ */
160
101
  setCookie: (key: string, value: string, options?: CookieOptions) => string;
102
+ /**
103
+ * Set signed cookie
104
+ *
105
+ * @param key - The key of the cookie
106
+ * @param value - The value to set
107
+ * @param secret - The secret to sign the cookie with
108
+ * @param options - The options of the cookie
109
+ * @returns The cookie string
110
+ */
161
111
  setSignedCookie: (key: string, value: string, secret: string, options?: CookieOptions) => Promise<string>;
162
- redirect: (url: string) => {
163
- status: keyof typeof statusCodes | Status;
164
- body: ({
165
- message?: string;
166
- code?: string;
167
- cause?: unknown;
168
- } & Record<string, any>) | undefined;
169
- headers: HeadersInit;
170
- statusCode: number;
171
- name: string;
172
- message: string;
173
- stack?: string;
174
- cause?: unknown;
175
- } & {
176
- errorStack: string | undefined;
177
- };
178
- error: (status: keyof typeof statusCodes | Status, body?: {
179
- message?: string;
180
- code?: string;
181
- } | undefined, headers?: HeadersInit) => {
182
- status: keyof typeof statusCodes | Status;
183
- body: ({
184
- message?: string;
185
- code?: string;
186
- cause?: unknown;
187
- } & Record<string, any>) | undefined;
188
- headers: HeadersInit;
189
- statusCode: number;
190
- name: string;
191
- message: string;
192
- stack?: string;
193
- cause?: unknown;
194
- } & {
195
- errorStack: string | undefined;
196
- };
197
- setStatus: (status: Status) => void;
198
- json: (json: Record<string, any>, routerResponse?: {
112
+ /**
113
+ * JSON
114
+ *
115
+ * A helper function to create a JSON response with the correct headers
116
+ * and status code. If `asResponse` is set to true in the context then
117
+ * it will return a Response object instead of the JSON object.
118
+ *
119
+ * @param json - The JSON object to return
120
+ * @param routerResponse - The response object to return if `asResponse` is
121
+ * true in the context this will take precedence
122
+ */
123
+ json: <R extends Record<string, any> | null>(json: R, routerResponse?: {
199
124
  status?: number;
200
125
  headers?: Record<string, string>;
201
126
  response?: Response;
202
127
  body?: Record<string, any>;
203
- } | Response) => Record<string, any>;
204
- responseHeaders: Headers;
205
- responseStatus: Status | undefined;
206
- asResponse?: boolean;
207
- returnHeaders?: boolean;
208
- returnStatus?: boolean;
209
- use?: Middleware[];
210
- } | {
211
- body: any;
212
- query: any;
213
- path: string;
214
- context: Record<string, any>;
215
- returned: any;
216
- headers: HeadersInit | undefined;
217
- request: Request | undefined;
218
- params: Record<string, any> | undefined;
219
- method: any;
220
- setHeader: (key: string, value: string) => void;
221
- getHeader: (key: string) => string | null;
222
- getCookie: (key: string, prefix?: CookiePrefixOptions) => string | null;
223
- getSignedCookie: (key: string, secret: string, prefix?: CookiePrefixOptions) => Promise<string | false | null>;
224
- setCookie: (key: string, value: string, options?: CookieOptions) => string;
225
- setSignedCookie: (key: string, value: string, secret: string, options?: CookieOptions) => Promise<string>;
226
- redirect: (url: string) => {
227
- status: keyof typeof statusCodes | Status;
228
- body: ({
229
- message?: string;
230
- code?: string;
231
- cause?: unknown;
232
- } & Record<string, any>) | undefined;
233
- headers: HeadersInit;
234
- statusCode: number;
235
- name: string;
236
- message: string;
237
- stack?: string;
238
- cause?: unknown;
239
- } & {
240
- errorStack: string | undefined;
241
- };
128
+ } | Response) => R;
129
+ /**
130
+ * Middleware context
131
+ */
132
+ context: 0 extends 1 & Use ? Prettify<Context> : Prettify<Context & InferUse<Use>>;
133
+ /**
134
+ * Redirect to a new URL
135
+ */
136
+ redirect: (url: string) => APIError;
137
+ /**
138
+ * Return error
139
+ */
242
140
  error: (status: keyof typeof statusCodes | Status, body?: {
243
141
  message?: string;
244
142
  code?: string;
245
- } | undefined, headers?: HeadersInit) => {
246
- status: keyof typeof statusCodes | Status;
247
- body: ({
248
- message?: string;
249
- code?: string;
250
- cause?: unknown;
251
- } & Record<string, any>) | undefined;
252
- headers: HeadersInit;
253
- statusCode: number;
254
- name: string;
255
- message: string;
256
- stack?: string;
257
- cause?: unknown;
258
- } & {
259
- errorStack: string | undefined;
260
- };
261
- setStatus: (status: Status) => void;
262
- json: (json: Record<string, any>, routerResponse?: {
263
- status?: number;
264
- headers?: Record<string, string>;
265
- response?: Response;
266
- body?: Record<string, any>;
267
- } | Response) => Record<string, any>;
268
- responseHeaders: Headers;
269
- responseStatus: Status | undefined;
270
- asResponse?: boolean;
271
- returnHeaders?: boolean;
272
- returnStatus?: boolean;
273
- use?: Middleware[];
274
- } | {
275
- body: any;
276
- query: any;
277
- path: string;
278
- context: Record<string, any>;
279
- returned: any;
280
- headers: HeadersInit | undefined;
281
- request: Request | undefined;
282
- params: Record<string, any> | undefined;
283
- method: any;
284
- setHeader: (key: string, value: string) => void;
285
- getHeader: (key: string) => string | null;
286
- getCookie: (key: string, prefix?: CookiePrefixOptions) => string | null;
287
- getSignedCookie: (key: string, secret: string, prefix?: CookiePrefixOptions) => Promise<string | false | null>;
288
- setCookie: (key: string, value: string, options?: CookieOptions) => string;
289
- setSignedCookie: (key: string, value: string, secret: string, options?: CookieOptions) => Promise<string>;
290
- redirect: (url: string) => {
291
- status: keyof typeof statusCodes | Status;
292
- body: ({
293
- message?: string;
294
- code?: string;
295
- cause?: unknown;
296
- } & Record<string, any>) | undefined;
297
- headers: HeadersInit;
298
- statusCode: number;
299
- name: string;
300
- message: string;
301
- stack?: string;
302
- cause?: unknown;
303
- } & {
304
- errorStack: string | undefined;
305
- };
306
- error: (status: keyof typeof statusCodes | Status, body?: {
307
- message?: string;
308
- code?: string;
309
- } | undefined, headers?: HeadersInit) => {
310
- status: keyof typeof statusCodes | Status;
311
- body: ({
312
- message?: string;
313
- code?: string;
314
- cause?: unknown;
315
- } & Record<string, any>) | undefined;
316
- headers: HeadersInit;
317
- statusCode: number;
318
- name: string;
319
- message: string;
320
- stack?: string;
321
- cause?: unknown;
322
- } & {
323
- errorStack: string | undefined;
324
- };
325
- setStatus: (status: Status) => void;
326
- json: (json: Record<string, any>, routerResponse?: {
327
- status?: number;
328
- headers?: Record<string, string>;
329
- response?: Response;
330
- body?: Record<string, any>;
331
- } | Response) => Record<string, any>;
332
- responseHeaders: Headers;
333
- responseStatus: Status | undefined;
334
- asResponse?: boolean;
335
- returnHeaders?: boolean;
336
- returnStatus?: boolean;
337
- use?: Middleware[];
338
- }>;
143
+ } & Record<string, any>, headers?: HeadersInit) => APIError;
144
+ };
339
145
  //#endregion
340
- export { HTTPMethod, InferBody, InferBodyInput, InferHeaders, InferHeadersInput, InferInputMethod, InferMethod, InferMiddlewareBody, InferMiddlewareQuery, InferParam, InferParamInput, InferQuery, InferQueryInput, InferRequest, InferRequestInput, InferUse, InputContext, Method, createInternalContext };
146
+ export { EndpointContext };
341
147
  //# sourceMappingURL=context.d.cts.map