better-call 0.0.5-beta.2 → 0.0.5-beta.21

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/index.d.cts CHANGED
@@ -1,192 +1,109 @@
1
- import { ZodSchema, ZodOptional, z } from 'zod';
2
- import { HasRequiredKeys as HasRequiredKeys$1 } from 'type-fest';
1
+ import { E as EndpointOptions, a as EndpointResponse, H as Handler, b as HasRequiredKeys, C as Context, M as Method, P as Prettify, I as InferBody, c as InferRequest, d as InferHeaders, e as ContextTools, f as Endpoint } from './router-BoATPhwk.cjs';
2
+ export { j as CookieOptions, m as InferMethod, o as InferParam, h as InferParamPath, i as InferParamWildCard, n as InferQuery, k as InferUse, l as InferUseOptions, R as Router, g as createRouter } from './router-BoATPhwk.cjs';
3
+ import 'zod';
3
4
 
4
- type Middleware<E extends Record<string, string>> = (ctx: Context<string, EndpointOptions, E>) => Promise<{
5
- context: E;
6
- } | void>;
7
- declare const createMiddleware: <E extends Record<string, any>, M extends Middleware<E>>(middleware: M) => <Path extends string, Opts extends EndpointOptions, R extends EndpointResponse>(path: Path, options: Opts, handler: Handler<Path, Opts, R, Awaited<ReturnType<M>> extends {
8
- context: infer C;
9
- } ? C extends Record<string, any> ? C : {} : {}>) => {
10
- (...ctx: HasRequiredKeys$1<Context<Path, Opts, Awaited<ReturnType<M>> extends {
11
- context: infer C;
12
- } ? C extends Record<string, any> ? C : {} : {}>> extends true ? [Context<Path, Opts, Awaited<ReturnType<M>> extends {
13
- context: infer C;
14
- } ? C extends Record<string, any> ? C : {} : {}>] : [Context<Path, Opts, Awaited<ReturnType<M>> extends {
15
- context: infer C;
16
- } ? C extends Record<string, any> ? C : {} : {}>?]): Promise<R>;
17
- path: Path;
18
- options: Opts;
19
- middleware: M;
20
- };
21
-
22
- type RequiredKeysOf<BaseType extends object> = Exclude<{
23
- [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> ? Key : never;
24
- }[keyof BaseType], undefined>;
25
- type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never ? false : true;
26
- type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "*";
27
- interface EndpointOptions {
28
- method: Method | Method[];
29
- body?: ZodSchema;
30
- query?: ZodSchema;
31
- params?: ZodSchema<any>;
32
- /**
33
- * If true headers will be required to be passed in the context
34
- */
35
- requireHeaders?: boolean;
36
- /**
37
- * If true request object will be required
38
- */
39
- requireRequest?: boolean;
40
- }
41
- type InferParamPath<Path> = Path extends `${infer _Start}:${infer Param}/${infer Rest}` ? {
42
- [K in Param | keyof InferParamPath<Rest>]: string;
43
- } : Path extends `${infer _Start}:${infer Param}` ? {
44
- [K in Param]: string;
45
- } : Path extends `${infer _Start}/${infer Rest}` ? InferParamPath<Rest> : undefined;
46
- type InferParamWildCard<Path> = Path extends `${infer _Start}/*:${infer Param}/${infer Rest}` | `${infer _Start}/**:${infer Param}/${infer Rest}` ? {
47
- [K in Param | keyof InferParamPath<Rest>]: string;
48
- } : Path extends `${infer _Start}/*` ? {
49
- [K in "_"]: string;
50
- } : Path extends `${infer _Start}/${infer Rest}` ? InferParamPath<Rest> : undefined;
51
- type Prettify<T> = {
52
- [key in keyof T]: T[key];
53
- } & {};
54
- type ContextTools = {
55
- setHeader: (key: string, value: string) => void;
56
- setCookie: (key: string, value: string) => void;
57
- getCookie: (key: string) => string | undefined;
58
- };
59
- type Context<Path extends string, Opts extends EndpointOptions, Extra extends Record<string, any> = {}> = InferBody<Opts["body"]> & InferParam<Path> & InferMethod<Opts['method']> & InferHeaders<Opts["requireHeaders"]> & InferRequest<Opts["requireRequest"]> & InferQuery<Opts["query"]> & Extra;
60
- type InferMethod<M extends Method | Method[]> = M extends Array<Method> ? {
61
- method: M[number];
62
- } : {
63
- method?: M;
64
- };
65
- type InferHeaders<HeaderReq> = HeaderReq extends true ? {
66
- headers: Headers;
67
- } : {
68
- headers?: Headers;
69
- };
70
- type InferRequest<RequestReq> = RequestReq extends true ? {
71
- request: Request;
72
- } : {
73
- request?: Request;
74
- };
75
- type InferBody<Body> = Body extends ZodSchema ? Body extends ZodOptional<any> ? {
76
- body?: z.infer<Body>;
77
- } : {
78
- body: z.infer<Body>;
79
- } : {
80
- body?: undefined;
81
- };
82
- type InferQuery<Query> = Query extends ZodSchema ? Query extends ZodOptional<any> ? {
83
- query?: z.infer<Query>;
84
- } : {
85
- query: z.infer<Query>;
86
- } : {
87
- query?: undefined;
88
- };
89
- type InferParam<Path extends string, ParamPath extends InferParamPath<Path> = InferParamPath<Path>, WildCard extends InferParamWildCard<Path> = InferParamWildCard<Path>> = ParamPath extends undefined ? WildCard extends undefined ? {
90
- params?: undefined;
91
- } : {
92
- params: WildCard;
93
- } : {
94
- params: ParamPath & (WildCard extends undefined ? {} : WildCard);
95
- };
96
- type EndpointResponse = Record<string, any> | string | boolean | number | void | undefined;
97
- type Handler<Path extends string, Opts extends EndpointOptions, R extends EndpointResponse, Extra extends Record<string, any> = Record<string, any>> = (ctx: Context<Path, Opts, Extra>) => Promise<R>;
98
5
  interface EndpointConfig {
99
6
  /**
100
7
  * Throw when the response isn't in 200 range
101
8
  */
102
9
  throwOnError?: boolean;
103
10
  }
104
- declare function createEndpoint<Path extends string, Opts extends EndpointOptions, R extends EndpointResponse>(path: Path, options: Opts, handler: Handler<Path, Opts, R, ContextTools>): {
105
- (...ctx: HasRequiredKeys<Context<Path, Opts, {}>> extends true ? [Context<Path, Opts, {}>] : [Context<Path, Opts, {}>?]): Promise<R>;
11
+ declare function createEndpointCreator<T extends Record<string, any>>(): <Path extends string, Opts extends EndpointOptions, R extends EndpointResponse>(path: Path, options: Opts, handler: Handler<Path, Opts, R, T>) => {
12
+ (...ctx: HasRequiredKeys<Context<Path, Opts>> extends true ? [Context<Path, Opts>] : [(Context<Path, Opts> | undefined)?]): Promise<R>;
13
+ path: Path;
14
+ options: Opts;
15
+ method: Method | Method[];
16
+ headers: Headers;
17
+ };
18
+ declare function createEndpoint<Path extends string, Opts extends EndpointOptions, R extends EndpointResponse>(path: Path, options: Opts, handler: Handler<Path, Opts, R>): {
19
+ (...ctx: HasRequiredKeys<Context<Path, Opts>> extends true ? [Context<Path, Opts>] : [Context<Path, Opts>?]): Promise<R>;
106
20
  path: Path;
107
21
  options: Opts;
108
22
  method: Method | Method[];
109
23
  headers: Headers;
110
- middleware: Middleware<any> | undefined;
111
24
  };
112
- type Endpoint = {
113
- path: string;
114
- options: EndpointOptions;
115
- middleware?: Middleware<any>;
116
- headers?: Headers;
117
- } & ((ctx: any) => Promise<any>);
118
25
 
119
- interface RouterConfig {
120
- /**
121
- * Throw error if error occurred other than APIError
122
- */
123
- throwError?: boolean;
124
- /**
125
- * Handle error
126
- */
127
- onError?: (e: unknown) => void | Promise<void> | Response | Promise<Response>;
128
- /**
129
- * Base path for the router
130
- */
131
- basePath?: string;
132
- }
133
- declare const createRouter: <E extends Endpoint, Config extends RouterConfig>(endpoints: E[], config?: Config) => {
134
- handler: (request: Request) => Promise<Response>;
26
+ type MiddlewareHandler<Opts extends EndpointOptions, R extends EndpointResponse, Extra extends Record<string, any> = {}> = (ctx: Prettify<InferBody<Opts> & InferRequest<Opts> & InferHeaders<Opts> & {
27
+ params?: Record<string, string>;
28
+ query?: Record<string, string>;
29
+ } & ContextTools> & Extra) => Promise<R>;
30
+ declare function createMiddleware<Opts extends EndpointOptions, R extends EndpointResponse>(optionsOrHandler: MiddlewareHandler<Opts, R>): Endpoint<Handler<string, Opts, R>, Opts>;
31
+ declare function createMiddleware<Opts extends Omit<EndpointOptions, "method">, R extends EndpointResponse>(optionsOrHandler: Opts, handler: MiddlewareHandler<Opts & {
32
+ method: "*";
33
+ }, R>): Endpoint<Handler<string, Opts & {
34
+ method: "*";
35
+ }, R>, Opts & {
36
+ method: "*";
37
+ }>;
38
+ declare const createMiddlewareCreator: <ExtraContext extends Record<string, any> = {}>() => {
39
+ <Opts extends EndpointOptions, R extends EndpointResponse>(optionsOrHandler: MiddlewareHandler<Opts, R, ExtraContext>): Endpoint<Handler<string, Opts, R>, Opts>;
40
+ <Opts extends Omit<EndpointOptions, "method">, R_1 extends EndpointResponse>(optionsOrHandler: Opts, handler: MiddlewareHandler<Opts & {
41
+ method: "*";
42
+ }, R_1, ExtraContext>): Endpoint<Handler<string, Opts & {
43
+ method: "*";
44
+ }, R_1>, Opts & {
45
+ method: "*";
46
+ }>;
135
47
  };
48
+ type Middleware<Opts extends EndpointOptions = EndpointOptions, R extends EndpointResponse = EndpointResponse> = (opts: Opts, handler: (ctx: {
49
+ body?: InferBody<Opts>;
50
+ params?: Record<string, string>;
51
+ query?: Record<string, string>;
52
+ }) => Promise<R>) => Endpoint;
136
53
 
137
54
  declare function getBody(request: Request): Promise<any>;
138
55
  declare function shouldSerialize(body: any): boolean;
139
56
  declare const statusCode: {
140
57
  OK: number;
141
- Created: number;
142
- Accepted: number;
143
- "No Content": number;
144
- "Multiple Choices": number;
145
- "Moved Permanently": number;
146
- Found: number;
147
- "See Other": number;
148
- "Not Modified": number;
149
- "Temporary Redirect": number;
150
- "Bad Request": number;
151
- Unauthorized: number;
152
- "Payment Required": number;
153
- Forbidden: number;
154
- "Not Found": number;
155
- "Method Not Allowed": number;
156
- "Not Acceptable": number;
157
- "Proxy Authentication Required": number;
158
- "Request Timeout": number;
159
- Conflict: number;
160
- Gone: number;
161
- "Length Required": number;
162
- "Precondition Failed": number;
163
- "Payload Too Large": number;
164
- "URI Too Long": number;
165
- "Unsupported Media Type": number;
166
- "Range Not Satisfiable": number;
167
- "Expectation Failed": number;
168
- "I'm a teapot": number;
169
- "Misdirected Request": number;
170
- "Unprocessable Entity": number;
171
- Locked: number;
172
- "Failed Dependency": number;
173
- "Too Early": number;
174
- "Upgrade Required": number;
175
- "Precondition Required": number;
176
- "Too Many Requests": number;
177
- "Request Header Fields Too Large": number;
178
- "Unavailable For Legal Reasons": number;
179
- "Internal Server Error": number;
180
- "Not Implemented": number;
181
- "Bad Gateway": number;
182
- "Service Unavailable": number;
183
- "Gateway Timeout": number;
184
- "HTTP Version Not Supported": number;
185
- "Variant Also Negotiates": number;
186
- "Insufficient Storage": number;
187
- "Loop Detected": number;
188
- "Not Extended": number;
189
- "Network Authentication Required": number;
58
+ CREATED: number;
59
+ ACCEPTED: number;
60
+ NO_CONTENT: number;
61
+ MULTIPLE_CHOICES: number;
62
+ MOVED_PERMANENTLY: number;
63
+ FOUND: number;
64
+ SEE_OTHER: number;
65
+ NOT_MODIFIED: number;
66
+ TEMPORARY_REDIRECT: number;
67
+ BAD_REQUEST: number;
68
+ UNAUTHORIZED: number;
69
+ PAYMENT_REQUIRED: number;
70
+ FORBIDDEN: number;
71
+ NOT_FOUND: number;
72
+ METHOD_NOT_ALLOWED: number;
73
+ NOT_ACCEPTABLE: number;
74
+ PROXY_AUTHENTICATION_REQUIRED: number;
75
+ REQUEST_TIMEOUT: number;
76
+ CONFLICT: number;
77
+ GONE: number;
78
+ LENGTH_REQUIRED: number;
79
+ PRECONDITION_FAILED: number;
80
+ PAYLOAD_TOO_LARGE: number;
81
+ URI_TOO_LONG: number;
82
+ UNSUPPORTED_MEDIA_TYPE: number;
83
+ RANGE_NOT_SATISFIABLE: number;
84
+ EXPECTATION_FAILED: number;
85
+ "I'M_A_TEAPOT": number;
86
+ MISDIRECTED_REQUEST: number;
87
+ UNPROCESSABLE_ENTITY: number;
88
+ LOCKED: number;
89
+ FAILED_DEPENDENCY: number;
90
+ TOO_EARLY: number;
91
+ UPGRADE_REQUIRED: number;
92
+ PRECONDITION_REQUIRED: number;
93
+ TOO_MANY_REQUESTS: number;
94
+ REQUEST_HEADER_FIELDS_TOO_LARGE: number;
95
+ UNAVAILABLE_FOR_LEGAL_REASONS: number;
96
+ INTERNAL_SERVER_ERROR: number;
97
+ NOT_IMPLEMENTED: number;
98
+ BAD_GATEWAY: number;
99
+ SERVICE_UNAVAILABLE: number;
100
+ GATEWAY_TIMEOUT: number;
101
+ HTTP_VERSION_NOT_SUPPORTED: number;
102
+ VARIANT_ALSO_NEGOTIATES: number;
103
+ INSUFFICIENT_STORAGE: number;
104
+ LOOP_DETECTED: number;
105
+ NOT_EXTENDED: number;
106
+ NETWORK_AUTHENTICATION_REQUIRED: number;
190
107
  };
191
108
 
192
109
  type Status = keyof typeof statusCode;
@@ -196,4 +113,4 @@ declare class APIError extends Error {
196
113
  constructor(status: Status, body?: Record<string, any>);
197
114
  }
198
115
 
199
- export { APIError, type Context, type Endpoint, type EndpointConfig, type EndpointOptions, type EndpointResponse, type Handler, type HasRequiredKeys, type Middleware, type Prettify, type RequiredKeysOf, createEndpoint, createMiddleware, createRouter, getBody, shouldSerialize, statusCode };
116
+ export { APIError, Context, ContextTools, Endpoint, type EndpointConfig, EndpointOptions, EndpointResponse, Handler, InferBody, InferHeaders, InferRequest, Method, type Middleware, type MiddlewareHandler, Prettify, createEndpoint, createEndpointCreator, createMiddleware, createMiddlewareCreator, getBody, shouldSerialize, statusCode };
package/dist/index.d.ts CHANGED
@@ -1,192 +1,109 @@
1
- import { ZodSchema, ZodOptional, z } from 'zod';
2
- import { HasRequiredKeys as HasRequiredKeys$1 } from 'type-fest';
1
+ import { E as EndpointOptions, a as EndpointResponse, H as Handler, b as HasRequiredKeys, C as Context, M as Method, P as Prettify, I as InferBody, c as InferRequest, d as InferHeaders, e as ContextTools, f as Endpoint } from './router-BoATPhwk.js';
2
+ export { j as CookieOptions, m as InferMethod, o as InferParam, h as InferParamPath, i as InferParamWildCard, n as InferQuery, k as InferUse, l as InferUseOptions, R as Router, g as createRouter } from './router-BoATPhwk.js';
3
+ import 'zod';
3
4
 
4
- type Middleware<E extends Record<string, string>> = (ctx: Context<string, EndpointOptions, E>) => Promise<{
5
- context: E;
6
- } | void>;
7
- declare const createMiddleware: <E extends Record<string, any>, M extends Middleware<E>>(middleware: M) => <Path extends string, Opts extends EndpointOptions, R extends EndpointResponse>(path: Path, options: Opts, handler: Handler<Path, Opts, R, Awaited<ReturnType<M>> extends {
8
- context: infer C;
9
- } ? C extends Record<string, any> ? C : {} : {}>) => {
10
- (...ctx: HasRequiredKeys$1<Context<Path, Opts, Awaited<ReturnType<M>> extends {
11
- context: infer C;
12
- } ? C extends Record<string, any> ? C : {} : {}>> extends true ? [Context<Path, Opts, Awaited<ReturnType<M>> extends {
13
- context: infer C;
14
- } ? C extends Record<string, any> ? C : {} : {}>] : [Context<Path, Opts, Awaited<ReturnType<M>> extends {
15
- context: infer C;
16
- } ? C extends Record<string, any> ? C : {} : {}>?]): Promise<R>;
17
- path: Path;
18
- options: Opts;
19
- middleware: M;
20
- };
21
-
22
- type RequiredKeysOf<BaseType extends object> = Exclude<{
23
- [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> ? Key : never;
24
- }[keyof BaseType], undefined>;
25
- type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never ? false : true;
26
- type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "*";
27
- interface EndpointOptions {
28
- method: Method | Method[];
29
- body?: ZodSchema;
30
- query?: ZodSchema;
31
- params?: ZodSchema<any>;
32
- /**
33
- * If true headers will be required to be passed in the context
34
- */
35
- requireHeaders?: boolean;
36
- /**
37
- * If true request object will be required
38
- */
39
- requireRequest?: boolean;
40
- }
41
- type InferParamPath<Path> = Path extends `${infer _Start}:${infer Param}/${infer Rest}` ? {
42
- [K in Param | keyof InferParamPath<Rest>]: string;
43
- } : Path extends `${infer _Start}:${infer Param}` ? {
44
- [K in Param]: string;
45
- } : Path extends `${infer _Start}/${infer Rest}` ? InferParamPath<Rest> : undefined;
46
- type InferParamWildCard<Path> = Path extends `${infer _Start}/*:${infer Param}/${infer Rest}` | `${infer _Start}/**:${infer Param}/${infer Rest}` ? {
47
- [K in Param | keyof InferParamPath<Rest>]: string;
48
- } : Path extends `${infer _Start}/*` ? {
49
- [K in "_"]: string;
50
- } : Path extends `${infer _Start}/${infer Rest}` ? InferParamPath<Rest> : undefined;
51
- type Prettify<T> = {
52
- [key in keyof T]: T[key];
53
- } & {};
54
- type ContextTools = {
55
- setHeader: (key: string, value: string) => void;
56
- setCookie: (key: string, value: string) => void;
57
- getCookie: (key: string) => string | undefined;
58
- };
59
- type Context<Path extends string, Opts extends EndpointOptions, Extra extends Record<string, any> = {}> = InferBody<Opts["body"]> & InferParam<Path> & InferMethod<Opts['method']> & InferHeaders<Opts["requireHeaders"]> & InferRequest<Opts["requireRequest"]> & InferQuery<Opts["query"]> & Extra;
60
- type InferMethod<M extends Method | Method[]> = M extends Array<Method> ? {
61
- method: M[number];
62
- } : {
63
- method?: M;
64
- };
65
- type InferHeaders<HeaderReq> = HeaderReq extends true ? {
66
- headers: Headers;
67
- } : {
68
- headers?: Headers;
69
- };
70
- type InferRequest<RequestReq> = RequestReq extends true ? {
71
- request: Request;
72
- } : {
73
- request?: Request;
74
- };
75
- type InferBody<Body> = Body extends ZodSchema ? Body extends ZodOptional<any> ? {
76
- body?: z.infer<Body>;
77
- } : {
78
- body: z.infer<Body>;
79
- } : {
80
- body?: undefined;
81
- };
82
- type InferQuery<Query> = Query extends ZodSchema ? Query extends ZodOptional<any> ? {
83
- query?: z.infer<Query>;
84
- } : {
85
- query: z.infer<Query>;
86
- } : {
87
- query?: undefined;
88
- };
89
- type InferParam<Path extends string, ParamPath extends InferParamPath<Path> = InferParamPath<Path>, WildCard extends InferParamWildCard<Path> = InferParamWildCard<Path>> = ParamPath extends undefined ? WildCard extends undefined ? {
90
- params?: undefined;
91
- } : {
92
- params: WildCard;
93
- } : {
94
- params: ParamPath & (WildCard extends undefined ? {} : WildCard);
95
- };
96
- type EndpointResponse = Record<string, any> | string | boolean | number | void | undefined;
97
- type Handler<Path extends string, Opts extends EndpointOptions, R extends EndpointResponse, Extra extends Record<string, any> = Record<string, any>> = (ctx: Context<Path, Opts, Extra>) => Promise<R>;
98
5
  interface EndpointConfig {
99
6
  /**
100
7
  * Throw when the response isn't in 200 range
101
8
  */
102
9
  throwOnError?: boolean;
103
10
  }
104
- declare function createEndpoint<Path extends string, Opts extends EndpointOptions, R extends EndpointResponse>(path: Path, options: Opts, handler: Handler<Path, Opts, R, ContextTools>): {
105
- (...ctx: HasRequiredKeys<Context<Path, Opts, {}>> extends true ? [Context<Path, Opts, {}>] : [Context<Path, Opts, {}>?]): Promise<R>;
11
+ declare function createEndpointCreator<T extends Record<string, any>>(): <Path extends string, Opts extends EndpointOptions, R extends EndpointResponse>(path: Path, options: Opts, handler: Handler<Path, Opts, R, T>) => {
12
+ (...ctx: HasRequiredKeys<Context<Path, Opts>> extends true ? [Context<Path, Opts>] : [(Context<Path, Opts> | undefined)?]): Promise<R>;
13
+ path: Path;
14
+ options: Opts;
15
+ method: Method | Method[];
16
+ headers: Headers;
17
+ };
18
+ declare function createEndpoint<Path extends string, Opts extends EndpointOptions, R extends EndpointResponse>(path: Path, options: Opts, handler: Handler<Path, Opts, R>): {
19
+ (...ctx: HasRequiredKeys<Context<Path, Opts>> extends true ? [Context<Path, Opts>] : [Context<Path, Opts>?]): Promise<R>;
106
20
  path: Path;
107
21
  options: Opts;
108
22
  method: Method | Method[];
109
23
  headers: Headers;
110
- middleware: Middleware<any> | undefined;
111
24
  };
112
- type Endpoint = {
113
- path: string;
114
- options: EndpointOptions;
115
- middleware?: Middleware<any>;
116
- headers?: Headers;
117
- } & ((ctx: any) => Promise<any>);
118
25
 
119
- interface RouterConfig {
120
- /**
121
- * Throw error if error occurred other than APIError
122
- */
123
- throwError?: boolean;
124
- /**
125
- * Handle error
126
- */
127
- onError?: (e: unknown) => void | Promise<void> | Response | Promise<Response>;
128
- /**
129
- * Base path for the router
130
- */
131
- basePath?: string;
132
- }
133
- declare const createRouter: <E extends Endpoint, Config extends RouterConfig>(endpoints: E[], config?: Config) => {
134
- handler: (request: Request) => Promise<Response>;
26
+ type MiddlewareHandler<Opts extends EndpointOptions, R extends EndpointResponse, Extra extends Record<string, any> = {}> = (ctx: Prettify<InferBody<Opts> & InferRequest<Opts> & InferHeaders<Opts> & {
27
+ params?: Record<string, string>;
28
+ query?: Record<string, string>;
29
+ } & ContextTools> & Extra) => Promise<R>;
30
+ declare function createMiddleware<Opts extends EndpointOptions, R extends EndpointResponse>(optionsOrHandler: MiddlewareHandler<Opts, R>): Endpoint<Handler<string, Opts, R>, Opts>;
31
+ declare function createMiddleware<Opts extends Omit<EndpointOptions, "method">, R extends EndpointResponse>(optionsOrHandler: Opts, handler: MiddlewareHandler<Opts & {
32
+ method: "*";
33
+ }, R>): Endpoint<Handler<string, Opts & {
34
+ method: "*";
35
+ }, R>, Opts & {
36
+ method: "*";
37
+ }>;
38
+ declare const createMiddlewareCreator: <ExtraContext extends Record<string, any> = {}>() => {
39
+ <Opts extends EndpointOptions, R extends EndpointResponse>(optionsOrHandler: MiddlewareHandler<Opts, R, ExtraContext>): Endpoint<Handler<string, Opts, R>, Opts>;
40
+ <Opts extends Omit<EndpointOptions, "method">, R_1 extends EndpointResponse>(optionsOrHandler: Opts, handler: MiddlewareHandler<Opts & {
41
+ method: "*";
42
+ }, R_1, ExtraContext>): Endpoint<Handler<string, Opts & {
43
+ method: "*";
44
+ }, R_1>, Opts & {
45
+ method: "*";
46
+ }>;
135
47
  };
48
+ type Middleware<Opts extends EndpointOptions = EndpointOptions, R extends EndpointResponse = EndpointResponse> = (opts: Opts, handler: (ctx: {
49
+ body?: InferBody<Opts>;
50
+ params?: Record<string, string>;
51
+ query?: Record<string, string>;
52
+ }) => Promise<R>) => Endpoint;
136
53
 
137
54
  declare function getBody(request: Request): Promise<any>;
138
55
  declare function shouldSerialize(body: any): boolean;
139
56
  declare const statusCode: {
140
57
  OK: number;
141
- Created: number;
142
- Accepted: number;
143
- "No Content": number;
144
- "Multiple Choices": number;
145
- "Moved Permanently": number;
146
- Found: number;
147
- "See Other": number;
148
- "Not Modified": number;
149
- "Temporary Redirect": number;
150
- "Bad Request": number;
151
- Unauthorized: number;
152
- "Payment Required": number;
153
- Forbidden: number;
154
- "Not Found": number;
155
- "Method Not Allowed": number;
156
- "Not Acceptable": number;
157
- "Proxy Authentication Required": number;
158
- "Request Timeout": number;
159
- Conflict: number;
160
- Gone: number;
161
- "Length Required": number;
162
- "Precondition Failed": number;
163
- "Payload Too Large": number;
164
- "URI Too Long": number;
165
- "Unsupported Media Type": number;
166
- "Range Not Satisfiable": number;
167
- "Expectation Failed": number;
168
- "I'm a teapot": number;
169
- "Misdirected Request": number;
170
- "Unprocessable Entity": number;
171
- Locked: number;
172
- "Failed Dependency": number;
173
- "Too Early": number;
174
- "Upgrade Required": number;
175
- "Precondition Required": number;
176
- "Too Many Requests": number;
177
- "Request Header Fields Too Large": number;
178
- "Unavailable For Legal Reasons": number;
179
- "Internal Server Error": number;
180
- "Not Implemented": number;
181
- "Bad Gateway": number;
182
- "Service Unavailable": number;
183
- "Gateway Timeout": number;
184
- "HTTP Version Not Supported": number;
185
- "Variant Also Negotiates": number;
186
- "Insufficient Storage": number;
187
- "Loop Detected": number;
188
- "Not Extended": number;
189
- "Network Authentication Required": number;
58
+ CREATED: number;
59
+ ACCEPTED: number;
60
+ NO_CONTENT: number;
61
+ MULTIPLE_CHOICES: number;
62
+ MOVED_PERMANENTLY: number;
63
+ FOUND: number;
64
+ SEE_OTHER: number;
65
+ NOT_MODIFIED: number;
66
+ TEMPORARY_REDIRECT: number;
67
+ BAD_REQUEST: number;
68
+ UNAUTHORIZED: number;
69
+ PAYMENT_REQUIRED: number;
70
+ FORBIDDEN: number;
71
+ NOT_FOUND: number;
72
+ METHOD_NOT_ALLOWED: number;
73
+ NOT_ACCEPTABLE: number;
74
+ PROXY_AUTHENTICATION_REQUIRED: number;
75
+ REQUEST_TIMEOUT: number;
76
+ CONFLICT: number;
77
+ GONE: number;
78
+ LENGTH_REQUIRED: number;
79
+ PRECONDITION_FAILED: number;
80
+ PAYLOAD_TOO_LARGE: number;
81
+ URI_TOO_LONG: number;
82
+ UNSUPPORTED_MEDIA_TYPE: number;
83
+ RANGE_NOT_SATISFIABLE: number;
84
+ EXPECTATION_FAILED: number;
85
+ "I'M_A_TEAPOT": number;
86
+ MISDIRECTED_REQUEST: number;
87
+ UNPROCESSABLE_ENTITY: number;
88
+ LOCKED: number;
89
+ FAILED_DEPENDENCY: number;
90
+ TOO_EARLY: number;
91
+ UPGRADE_REQUIRED: number;
92
+ PRECONDITION_REQUIRED: number;
93
+ TOO_MANY_REQUESTS: number;
94
+ REQUEST_HEADER_FIELDS_TOO_LARGE: number;
95
+ UNAVAILABLE_FOR_LEGAL_REASONS: number;
96
+ INTERNAL_SERVER_ERROR: number;
97
+ NOT_IMPLEMENTED: number;
98
+ BAD_GATEWAY: number;
99
+ SERVICE_UNAVAILABLE: number;
100
+ GATEWAY_TIMEOUT: number;
101
+ HTTP_VERSION_NOT_SUPPORTED: number;
102
+ VARIANT_ALSO_NEGOTIATES: number;
103
+ INSUFFICIENT_STORAGE: number;
104
+ LOOP_DETECTED: number;
105
+ NOT_EXTENDED: number;
106
+ NETWORK_AUTHENTICATION_REQUIRED: number;
190
107
  };
191
108
 
192
109
  type Status = keyof typeof statusCode;
@@ -196,4 +113,4 @@ declare class APIError extends Error {
196
113
  constructor(status: Status, body?: Record<string, any>);
197
114
  }
198
115
 
199
- export { APIError, type Context, type Endpoint, type EndpointConfig, type EndpointOptions, type EndpointResponse, type Handler, type HasRequiredKeys, type Middleware, type Prettify, type RequiredKeysOf, createEndpoint, createMiddleware, createRouter, getBody, shouldSerialize, statusCode };
116
+ export { APIError, Context, ContextTools, Endpoint, type EndpointConfig, EndpointOptions, EndpointResponse, Handler, InferBody, InferHeaders, InferRequest, Method, type Middleware, type MiddlewareHandler, Prettify, createEndpoint, createEndpointCreator, createMiddleware, createMiddlewareCreator, getBody, shouldSerialize, statusCode };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var E=Object.defineProperty;var w=(r,e,n)=>e in r?E(r,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):r[e]=n;var l=(r,e,n)=>w(r,typeof e!="symbol"?e+"":e,n);import{ZodError as C}from"zod";var y=class extends Error{constructor(n,a){super(`API Error: ${n} ${a?.message??""}`,{cause:a});l(this,"status");l(this,"body");this.status=n,this.body=a??{},this.stack="",this.name="BetterCallAPIError"}};function B(r,e,n){let a=new Headers,t=async(...s)=>{let o={setHeader(d,i){a.set(d,i)},setCookie(d,i){a.append("Set-Cookie",`${d}=${i}`)},getCookie(d){return s[0]?.headers?.get("cookie")?.split(";").find(c=>c.startsWith(`${d}=`))?.split("=")[1]},...s[0]||{}};try{o.body=e.body?e.body.parse(o.body):void 0,o.query=e.query?e.query.parse(o.query):void 0,o.params=e.params?e.params.parse(o.params):void 0}catch(d){throw d instanceof C?new y("Bad Request",{message:d.message,details:d.errors}):d}if(e.requireHeaders&&!o.headers)throw new y("Bad Request",{message:"Headers are required"});if(e.requireRequest&&!o.request)throw new y("Bad Request",{message:"Request is required"});return await n(o)};return t.path=r,t.options=e,t.method=e.method,t.headers=a,t.middleware=void 0,t}import{createRouter as q,addRoute as P,findRoute as b}from"rou3";async function m(r){let e=r.headers.get("content-type")||"";if(r.body){if(e.includes("application/json"))return await r.json();if(e.includes("application/x-www-form-urlencoded")){let n=await r.formData(),a={};return n.forEach((t,s)=>{a[s]=t.toString()}),a}if(e.includes("multipart/form-data")){let n=await r.formData(),a={};return n.forEach((t,s)=>{a[s]=t}),a}return e.includes("text/plain")?await r.text():e.includes("application/octet-stream")?await r.arrayBuffer():e.includes("application/pdf")||e.includes("image/")||e.includes("video/")?await r.blob():e.includes("application/stream")||r.body instanceof ReadableStream?r.body:await r.text()}}function x(r){return typeof r=="object"&&r!==null&&!(r instanceof Blob)&&!(r instanceof FormData)}var R={OK:200,Created:201,Accepted:202,"No Content":204,"Multiple Choices":300,"Moved Permanently":301,Found:302,"See Other":303,"Not Modified":304,"Temporary Redirect":307,"Bad Request":400,Unauthorized:401,"Payment Required":402,Forbidden:403,"Not Found":404,"Method Not Allowed":405,"Not Acceptable":406,"Proxy Authentication Required":407,"Request Timeout":408,Conflict:409,Gone:410,"Length Required":411,"Precondition Failed":412,"Payload Too Large":413,"URI Too Long":414,"Unsupported Media Type":415,"Range Not Satisfiable":416,"Expectation Failed":417,"I'm a teapot":418,"Misdirected Request":421,"Unprocessable Entity":422,Locked:423,"Failed Dependency":424,"Too Early":425,"Upgrade Required":426,"Precondition Required":428,"Too Many Requests":429,"Request Header Fields Too Large":431,"Unavailable For Legal Reasons":451,"Internal Server Error":500,"Not Implemented":501,"Bad Gateway":502,"Service Unavailable":503,"Gateway Timeout":504,"HTTP Version Not Supported":505,"Variant Also Negotiates":506,"Insufficient Storage":507,"Loop Detected":508,"Not Extended":510,"Network Authentication Required":511};var N=(r,e)=>{let n=q();for(let t of r)if(Array.isArray(t.options?.method))for(let s of t.options.method)P(n,s,t.path,t);else P(n,t.options.method,t.path,t);return{handler:async t=>{let s=new URL(t.url),o=s.pathname;e?.basePath&&(o=o.split(e.basePath)[1]);let f=t.method,d=b(n,f,o),i=d?.data,c=await m(t),h=t.headers;if(!i)return new Response(null,{status:404,statusText:"Not Found"});try{let p={};i.middleware&&(p=await i.middleware({path:o,method:f,headers:h,params:s.searchParams,request:t.clone(),body:c})||{});let u=await i({path:o,method:f,headers:h,params:d?.params,request:t,body:c,...p?.context});if(u instanceof Response)return u;let g=x(u)?JSON.stringify(u):u;return new Response(g,{headers:i.headers})}catch(p){if(e?.onError){let u=await e.onError(p);if(u instanceof Response)return u}if(p instanceof y)return new Response(p.body?JSON.stringify(p.body):null,{status:R[p.status],statusText:p.status,headers:{"Content-Type":"application/json"}});if(e?.throwError)throw p;return new Response(null,{status:500,statusText:"Internal Server Error"})}}}};var L=r=>(e,n,a)=>{let t=async(...s)=>await a(s[0]||{});return t.path=e,t.options=n,t.middleware=r,t};export{y as APIError,B as createEndpoint,L as createMiddleware,N as createRouter,m as getBody,x as shouldSerialize,R as statusCode};
1
+ var $=Object.defineProperty;var Q=(r,e,t)=>e in r?$(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var l=(r,e,t)=>Q(r,typeof e!="symbol"?e+"":e,t);import{ZodError as G}from"zod";import"zod";function j(r,e){if(typeof r=="function")return m("*",{method:"*"},r);if(!e)throw new Error("Middleware handler is required");return m("*",{...r,method:"*"},e)}var X=()=>{function r(e,t){if(typeof e=="function")return m("*",{method:"*"},e);if(!t)throw new Error("Middleware handler is required");return m("*",{...e,method:"*"},t)}return r};var y=class extends Error{constructor(t,n){super(`API Error: ${t} ${n?.message??""}`,{cause:n});l(this,"status");l(this,"body");this.status=t,this.body=n??{},this.stack="",this.name="BetterCallAPIError"}};var g={name:"HMAC",hash:"SHA-256"},w=async r=>{let e=typeof r=="string"?new TextEncoder().encode(r):r;return await crypto.subtle.importKey("raw",e,g,!1,["sign","verify"])},W=async(r,e)=>{let t=await w(e),n=await crypto.subtle.sign(g.name,t,new TextEncoder().encode(r));return btoa(String.fromCharCode(...new Uint8Array(n)))},v=async(r,e,t)=>{try{let n=atob(r),s=new Uint8Array(n.length);for(let i=0,o=n.length;i<o;i++)s[i]=n.charCodeAt(i);return await crypto.subtle.verify(g,t,s,new TextEncoder().encode(e))}catch{return!1}},K=/^[\w!#$%&'*.^`|~+-]+$/,F=/^[ !#-:<-[\]-~]*$/,R=(r,e)=>r.trim().split(";").reduce((n,s)=>{s=s.trim();let i=s.indexOf("=");if(i===-1)return n;let o=s.substring(0,i).trim();if(e&&e!==o||!K.test(o))return n;let p=s.substring(i+1).trim();return p.startsWith('"')&&p.endsWith('"')&&(p=p.slice(1,-1)),F.test(p)&&(n[o]=decodeURIComponent(p)),n},{}),I=async(r,e,t)=>{let n={},s=await w(e);for(let[i,o]of Object.entries(R(r,t))){let p=o.lastIndexOf(".");if(p<1)continue;let a=o.substring(0,p),d=o.substring(p+1);if(d.length!==44||!d.endsWith("="))continue;let u=await v(d,a,s);n[i]=u?a:!1}return n},k=(r,e,t={})=>{let n=`${r}=${e}`;if(r.startsWith("__Secure-")&&!t.secure)throw new Error("__Secure- Cookie must have Secure attributes");if(r.startsWith("__Host-")){if(!t.secure)throw new Error("__Host- Cookie must have Secure attributes");if(t.path!=="/")throw new Error('__Host- Cookie must have Path attributes with "/"');if(t.domain)throw new Error("__Host- Cookie must not have Domain attributes")}if(t&&typeof t.maxAge=="number"&&t.maxAge>=0){if(t.maxAge>3456e4)throw new Error("Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.");n+=`; Max-Age=${Math.floor(t.maxAge)}`}if(t.domain&&t.prefix!=="host"&&(n+=`; Domain=${t.domain}`),t.path&&(n+=`; Path=${t.path}`),t.expires){if(t.expires.getTime()-Date.now()>3456e7)throw new Error("Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.");n+=`; Expires=${t.expires.toUTCString()}`}if(t.httpOnly&&(n+="; HttpOnly"),t.secure&&(n+="; Secure"),t.sameSite&&(n+=`; SameSite=${t.sameSite.charAt(0).toUpperCase()+t.sameSite.slice(1)}`),t.partitioned){if(!t.secure)throw new Error("Partitioned Cookie must have Secure attributes");n+="; Partitioned"}return n},x=(r,e,t)=>(e=encodeURIComponent(e),k(r,e,t)),h=async(r,e,t,n={})=>{let s=await W(e,t);return e=`${e}.${s}`,e=encodeURIComponent(e),k(r,e,n)};var b=(r,e,t)=>{if(!r)return;let n=e;if(t==="secure")n="__Secure-"+e;else if(t==="host")n="__Host-"+e;else return;return R(r,n)[n]},A=(r,e,t,n)=>{let s;n?.prefix==="secure"?s=x("__Secure-"+e,t,{path:"/",...n,secure:!0}):n?.prefix==="host"?s=x("__Host-"+e,t,{...n,path:"/",secure:!0,domain:void 0}):s=x(e,t,{path:"/",...n}),r.append("Set-Cookie",s)},H=async(r,e,t,n,s)=>{let i;s?.prefix==="secure"?i=await h("__Secure-"+e,t,n,{path:"/",...s,secure:!0}):s?.prefix==="host"?i=await h("__Host-"+e,t,n,{...s,path:"/",secure:!0,domain:void 0}):i=await h(e,t,n,{path:"/",...s}),r.append("Set-Cookie",i)},N=async(r,e,t,n)=>{let s=r.get("Cookie");if(!s)return;let i=t;return n==="secure"?i="__Secure-"+t:n==="host"&&(i="__Host-"+t),(await I(s,e,i))[i]};function fe(){return(r,e,t)=>m(r,e,t)}function m(r,e,t){let n=new Headers,s=async(...i)=>{let o={setHeader(a,d){n.set(a,d)},setCookie(a,d,u){A(n,a,d,u)},getCookie(a,d){let u=i[0]?.headers;return b(u?.get("Cookie")||"",a,d)},getSignedCookie(a,d,u){let c=i[0]?.headers;if(!c)throw new TypeError("Headers are required");return N(c,d,a,u)},async setSignedCookie(a,d,u,c){await H(n,a,d,u,c)},...i[0]||{},context:{}};if(e.use?.length)for(let a of e.use){let d=await a(o),u=d.options?.body?d.options.body.parse(o.body):void 0;d&&(o={...o,body:u?{...u,...o.body}:o.body,context:{...o.context||{},...d}})}try{let a=e.body?e.body.parse(o.body):o.body;o={...o,body:a?{...a,...o.body}:o.body},o.query=e.query?e.query.parse(o.query):o.query,o.params=e.params?e.params.parse(o.params):o.params}catch(a){throw a instanceof G?new y("BAD_REQUEST",{message:a.message,details:a.errors}):a}if(e.requireHeaders&&!o.headers)throw new y("BAD_REQUEST",{message:"Headers are required"});if(e.requireRequest&&!o.request)throw new y("BAD_REQUEST",{message:"Request is required"});return await t(o)};return s.path=r,s.options=e,s.method=e.method,s.headers=n,s}import{createRouter as q,addRoute as C,findRoute as B}from"rou3";async function D(r){let e=r.headers.get("content-type")||"";if(r.body){if(e.includes("application/json"))return await r.json();if(e.includes("application/x-www-form-urlencoded")){let t=await r.formData(),n={};return t.forEach((s,i)=>{n[i]=s.toString()}),n}if(e.includes("multipart/form-data")){let t=await r.formData(),n={};return t.forEach((s,i)=>{n[i]=s}),n}return e.includes("text/plain")?await r.text():e.includes("application/octet-stream")?await r.arrayBuffer():e.includes("application/pdf")||e.includes("image/")||e.includes("video/")?await r.blob():e.includes("application/stream")||r.body instanceof ReadableStream?r.body:await r.text()}}function U(r){return typeof r=="object"&&r!==null&&!(r instanceof Blob)&&!(r instanceof FormData)}var M={OK:200,CREATED:201,ACCEPTED:202,NO_CONTENT:204,MULTIPLE_CHOICES:300,MOVED_PERMANENTLY:301,FOUND:302,SEE_OTHER:303,NOT_MODIFIED:304,TEMPORARY_REDIRECT:307,BAD_REQUEST:400,UNAUTHORIZED:401,PAYMENT_REQUIRED:402,FORBIDDEN:403,NOT_FOUND:404,METHOD_NOT_ALLOWED:405,NOT_ACCEPTABLE:406,PROXY_AUTHENTICATION_REQUIRED:407,REQUEST_TIMEOUT:408,CONFLICT:409,GONE:410,LENGTH_REQUIRED:411,PRECONDITION_FAILED:412,PAYLOAD_TOO_LARGE:413,URI_TOO_LONG:414,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,EXPECTATION_FAILED:417,"I'M_A_TEAPOT":418,MISDIRECTED_REQUEST:421,UNPROCESSABLE_ENTITY:422,LOCKED:423,FAILED_DEPENDENCY:424,TOO_EARLY:425,UPGRADE_REQUIRED:426,PRECONDITION_REQUIRED:428,TOO_MANY_REQUESTS:429,REQUEST_HEADER_FIELDS_TOO_LARGE:431,UNAVAILABLE_FOR_LEGAL_REASONS:451,INTERNAL_SERVER_ERROR:500,NOT_IMPLEMENTED:501,BAD_GATEWAY:502,SERVICE_UNAVAILABLE:503,GATEWAY_TIMEOUT:504,HTTP_VERSION_NOT_SUPPORTED:505,VARIANT_ALSO_NEGOTIATES:506,INSUFFICIENT_STORAGE:507,LOOP_DETECTED:508,NOT_EXTENDED:510,NETWORK_AUTHENTICATION_REQUIRED:511};var he=(r,e)=>{let t=Object.values(r),n=q();for(let o of t)if(Array.isArray(o.options?.method))for(let p of o.options.method)C(n,p,o.path,o);else C(n,o.options.method,o.path,o);let s=q();for(let o of e?.routerMiddleware||[])C(s,"*",o.path,o.middleware);return{handler:async o=>{let p=new URL(o.url),a=p.pathname;e?.basePath&&(a=a.split(e.basePath)[1]);let d=o.method,u=B(n,d,a),c=u?.data,O=await D(o),P=o.headers,T=Object.fromEntries(p.searchParams),S=B(s,"*",a)?.data;if(!c)return new Response(null,{status:404,statusText:"Not Found"});try{let f={};if(S){let _=await S({path:a,method:d,headers:P,params:u?.params,request:o,body:O,query:T,...e?.extraContext});_&&(f={..._,...f})}let E=await c({path:a,method:d,headers:P,params:u?.params,request:o,body:O,query:T,...f,...e?.extraContext});if(E instanceof Response)return E;let L=U(E)?JSON.stringify(E):E;return new Response(L,{headers:c.headers})}catch(f){if(e?.onError){let E=await e.onError(f);if(E instanceof Response)return E}if(f instanceof y)return new Response(f.body?JSON.stringify(f.body):null,{status:M[f.status],statusText:f.status,headers:c.headers});if(e?.throwError)throw f;return new Response(null,{status:500,statusText:"Internal Server Error"})}},endpoints:r}};import"zod";export{y as APIError,m as createEndpoint,fe as createEndpointCreator,j as createMiddleware,X as createMiddlewareCreator,he as createRouter,D as getBody,U as shouldSerialize,M as statusCode};
2
2
  //# sourceMappingURL=index.js.map