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
package/dist/endpoint.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { APIError, BetterCallError, ValidationError } from "./error.mjs";
2
2
  import { isAPIError, tryCatch } from "./utils.mjs";
3
- import { toResponse } from "./to-response.mjs";
4
3
  import { createInternalContext } from "./context.mjs";
4
+ import { toResponse } from "./to-response.mjs";
5
5
 
6
6
  //#region src/endpoint.ts
7
7
  function createEndpoint(pathOrOptions, handlerOrOptions, handlerOrNever) {
@@ -10,10 +10,24 @@ function createEndpoint(pathOrOptions, handlerOrOptions, handlerOrNever) {
10
10
  const handler = typeof handlerOrOptions === "function" ? handlerOrOptions : handlerOrNever;
11
11
  if ((options.method === "GET" || options.method === "HEAD") && options.body) throw new BetterCallError("Body is not allowed with GET or HEAD methods");
12
12
  if (path && /\/{2,}/.test(path)) throw new BetterCallError("Path cannot contain consecutive slashes");
13
+ const runtimeOptions = {
14
+ method: options.method,
15
+ body: options.body,
16
+ query: options.query,
17
+ error: options.error,
18
+ requireHeaders: options.requireHeaders,
19
+ requireRequest: options.requireRequest,
20
+ cloneRequest: options.cloneRequest,
21
+ disableBody: options.disableBody,
22
+ metadata: options.metadata,
23
+ use: options.use,
24
+ onAPIError: options.onAPIError,
25
+ onValidationError: options.onValidationError
26
+ };
13
27
  const internalHandler = async (...inputCtx) => {
14
28
  const context = inputCtx[0] || {};
15
29
  const { data: internalContext, error: validationError } = await tryCatch(createInternalContext(context, {
16
- options,
30
+ options: runtimeOptions,
17
31
  path
18
32
  }));
19
33
  if (validationError) {
@@ -35,24 +49,24 @@ function createEndpoint(pathOrOptions, handlerOrOptions, handlerOrNever) {
35
49
  }
36
50
  throw e;
37
51
  });
38
- const headers = internalContext.responseHeaders;
52
+ const responseHeaders = internalContext.responseHeaders;
39
53
  const status = internalContext.responseStatus;
40
54
  return context.asResponse ? toResponse(response, {
41
- headers,
55
+ headers: responseHeaders,
42
56
  status
43
57
  }) : context.returnHeaders ? context.returnStatus ? {
44
- headers,
58
+ headers: responseHeaders,
45
59
  response,
46
60
  status
47
61
  } : {
48
- headers,
62
+ headers: responseHeaders,
49
63
  response
50
64
  } : context.returnStatus ? {
51
65
  response,
52
66
  status
53
67
  } : response;
54
68
  };
55
- internalHandler.options = options;
69
+ internalHandler.options = runtimeOptions;
56
70
  internalHandler.path = path;
57
71
  return internalHandler;
58
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint.mjs","names":[],"sources":["../src/endpoint.ts"],"sourcesContent":["import type { HasRequiredKeys, Prettify } from \"./helper\";\nimport { toResponse } from \"./to-response\";\nimport type { Middleware } from \"./middleware\";\nimport {\n\tcreateInternalContext,\n\ttype InferBody,\n\ttype InferHeaders,\n\ttype InferMethod,\n\ttype InferParam,\n\ttype InferQuery,\n\ttype InferRequest,\n\ttype InferUse,\n\ttype InputContext,\n\ttype Method,\n} from \"./context\";\nimport type { CookieOptions, CookiePrefixOptions } from \"./cookies\";\nimport {\n\tAPIError,\n\tValidationError,\n\ttype statusCodes,\n\ttype Status,\n\tBetterCallError,\n} from \"./error\";\nimport type { OpenAPIParameter, OpenAPISchemaType } from \"./openapi\";\nimport type { StandardSchemaV1 } from \"./standard-schema\";\nimport { isAPIError, tryCatch } from \"./utils\";\n\nexport interface EndpointBaseOptions {\n\t/**\n\t * Query Schema\n\t */\n\tquery?: StandardSchemaV1;\n\t/**\n\t * Error Schema\n\t */\n\terror?: StandardSchemaV1;\n\t/**\n\t * If true headers will be required to be passed in the context\n\t */\n\trequireHeaders?: boolean;\n\t/**\n\t * If true request object will be required\n\t */\n\trequireRequest?: boolean;\n\t/**\n\t * Clone the request object from the router\n\t */\n\tcloneRequest?: boolean;\n\t/**\n\t * If true the body will be undefined\n\t */\n\tdisableBody?: boolean;\n\t/**\n\t * Endpoint metadata\n\t */\n\tmetadata?: {\n\t\t/**\n\t\t * Open API definition\n\t\t */\n\t\topenapi?: {\n\t\t\tsummary?: string;\n\t\t\tdescription?: string;\n\t\t\ttags?: string[];\n\t\t\toperationId?: string;\n\t\t\tparameters?: OpenAPIParameter[];\n\t\t\trequestBody?: {\n\t\t\t\tcontent: {\n\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\ttype?: OpenAPISchemaType;\n\t\t\t\t\t\t\tproperties?: Record<string, any>;\n\t\t\t\t\t\t\trequired?: string[];\n\t\t\t\t\t\t\t$ref?: string;\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tresponses?: {\n\t\t\t\t[status: string]: {\n\t\t\t\t\tdescription: string;\n\t\t\t\t\tcontent?: {\n\t\t\t\t\t\t\"application/json\"?: {\n\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\ttype?: OpenAPISchemaType;\n\t\t\t\t\t\t\t\tproperties?: Record<string, any>;\n\t\t\t\t\t\t\t\trequired?: string[];\n\t\t\t\t\t\t\t\t$ref?: string;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t};\n\t\t\t\t\t\t\"text/plain\"?: {\n\t\t\t\t\t\t\tschema?: {\n\t\t\t\t\t\t\t\ttype?: OpenAPISchemaType;\n\t\t\t\t\t\t\t\tproperties?: Record<string, any>;\n\t\t\t\t\t\t\t\trequired?: string[];\n\t\t\t\t\t\t\t\t$ref?: string;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t};\n\t\t\t\t\t\t\"text/html\"?: {\n\t\t\t\t\t\t\tschema?: {\n\t\t\t\t\t\t\t\ttype?: OpenAPISchemaType;\n\t\t\t\t\t\t\t\tproperties?: Record<string, any>;\n\t\t\t\t\t\t\t\trequired?: string[];\n\t\t\t\t\t\t\t\t$ref?: string;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t\t/**\n\t\t * Infer body and query type from ts interface\n\t\t *\n\t\t * useful for generic and dynamic types\n\t\t *\n\t\t * @example\n\t\t * ```ts\n\t\t * const endpoint = createEndpoint(\"/path\", {\n\t\t * \t\tmethod: \"POST\",\n\t\t * \t\tbody: z.record(z.string()),\n\t\t * \t\t$Infer: {\n\t\t * \t\t\tbody: {} as {\n\t\t * \t\t\t\ttype: InferTypeFromOptions<Option> // custom type inference\n\t\t * \t\t\t}\n\t\t * \t\t}\n\t\t * \t}, async(ctx)=>{\n\t\t * \t\tconst body = ctx.body\n\t\t * \t})\n\t\t * ```\n\t\t */\n\t\t$Infer?: {\n\t\t\t/**\n\t\t\t * Body\n\t\t\t */\n\t\t\tbody?: any;\n\t\t\t/**\n\t\t\t * Query\n\t\t\t */\n\t\t\tquery?: Record<string, any>;\n\t\t};\n\t\t/**\n\t\t * If enabled, endpoint won't be exposed over a router\n\t\t * @deprecated Use path-less endpoints instead\n\t\t */\n\t\tSERVER_ONLY?: boolean;\n\t\t/**\n\t\t * If enabled, endpoint won't be exposed as an action to the client\n\t\t * @deprecated Use path-less endpoints instead\n\t\t */\n\t\tisAction?: boolean;\n\t\t/**\n\t\t * Defines the places where the endpoint will be available\n\t\t *\n\t\t * Possible options:\n\t\t * - `rpc` - the endpoint is exposed to the router, can be invoked directly and is available to the client\n\t\t * - `server` - the endpoint is exposed to the router, can be invoked directly, but is not available to the client\n\t\t * - `http` - the endpoint is only exposed to the router\n\t\t * @default \"rpc\"\n\t\t */\n\t\tscope?: \"rpc\" | \"server\" | \"http\";\n\t\t/**\n\t\t * List of allowed media types (MIME types) for the endpoint\n\t\t *\n\t\t * if provided, only the media types in the list will be allowed to be passed in the body\n\t\t *\n\t\t * @example\n\t\t * ```ts\n\t\t * const endpoint = createEndpoint(\"/path\", {\n\t\t * \t\tmethod: \"POST\",\n\t\t * \t\tallowedMediaTypes: [\"application/json\", \"application/x-www-form-urlencoded\"],\n\t\t * \t}, async(ctx)=>{\n\t\t * \t\tconst body = ctx.body\n\t\t * \t})\n\t\t * ```\n\t\t */\n\t\tallowedMediaTypes?: string[];\n\t\t/**\n\t\t * Extra metadata\n\t\t */\n\t\t[key: string]: any;\n\t};\n\t/**\n\t * List of middlewares to use\n\t */\n\tuse?: Middleware[];\n\t/**\n\t * A callback to run before any API error is throw or returned\n\t *\n\t * @param e - The API error\n\t * @returns - The response to return\n\t */\n\tonAPIError?: (e: APIError) => void | Promise<void>;\n\t/**\n\t * A callback to run before a validation error is thrown\n\t * You can customize the validation error message by throwing your own APIError\n\t */\n\tonValidationError?: ({\n\t\tissues,\n\t\tmessage,\n\t}: {\n\t\tmessage: string;\n\t\tissues: readonly StandardSchemaV1.Issue[];\n\t}) => void | Promise<void>;\n}\n\nexport type EndpointBodyMethodOptions =\n\t| {\n\t\t\t/**\n\t\t\t * Request Method\n\t\t\t */\n\t\t\tmethod:\n\t\t\t\t| \"POST\"\n\t\t\t\t| \"PUT\"\n\t\t\t\t| \"DELETE\"\n\t\t\t\t| \"PATCH\"\n\t\t\t\t| (\"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\")[];\n\t\t\t/**\n\t\t\t * Body Schema\n\t\t\t */\n\t\t\tbody?: StandardSchemaV1;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * Request Method\n\t\t\t */\n\t\t\tmethod: \"GET\" | \"HEAD\" | (\"GET\" | \"HEAD\")[];\n\t\t\t/**\n\t\t\t * Body Schema\n\t\t\t */\n\t\t\tbody?: never;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * Request Method\n\t\t\t */\n\t\t\tmethod: \"*\";\n\t\t\t/**\n\t\t\t * Body Schema\n\t\t\t */\n\t\t\tbody?: StandardSchemaV1;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * Request Method\n\t\t\t */\n\t\t\tmethod: (\"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"GET\" | \"HEAD\")[];\n\t\t\t/**\n\t\t\t * Body Schema\n\t\t\t */\n\t\t\tbody?: StandardSchemaV1;\n\t };\n\nexport type EndpointOptions = EndpointBaseOptions & EndpointBodyMethodOptions;\n\nexport type EndpointContext<\n\tPath extends string,\n\tOptions extends EndpointOptions,\n\tContext = {},\n> = {\n\t/**\n\t * Method\n\t *\n\t * The request method\n\t */\n\tmethod: InferMethod<Options>;\n\t/**\n\t * Path\n\t *\n\t * The path of the endpoint\n\t */\n\tpath: Path;\n\t/**\n\t * Body\n\t *\n\t * The body object will be the parsed JSON from the request and validated\n\t * against the body schema if it exists.\n\t */\n\tbody: InferBody<Options>;\n\t/**\n\t * Query\n\t *\n\t * The query object will be the parsed query string from the request\n\t * and validated against the query schema if it exists\n\t */\n\tquery: InferQuery<Options>;\n\t/**\n\t * Params\n\t *\n\t * If the path is `/user/:id` and the request is `/user/1` then the params will\n\t * be `{ id: \"1\" }` and if the path includes a wildcard like `/user/*` then the\n\t * params will be `{ _: \"1\" }` where `_` is the wildcard key. If the wildcard\n\t * is named like `/user/**:name` then the params will be `{ name: string }`\n\t */\n\tparams: InferParam<Path>;\n\t/**\n\t * Request object\n\t *\n\t * If `requireRequest` is set to true in the endpoint options this will be\n\t * required\n\t */\n\trequest: InferRequest<Options>;\n\t/**\n\t * Headers\n\t *\n\t * If `requireHeaders` is set to true in the endpoint options this will be\n\t * required\n\t */\n\theaders: InferHeaders<Options>;\n\t/**\n\t * Set header\n\t *\n\t * If it's called outside of a request it will just be ignored.\n\t */\n\tsetHeader: (key: string, value: string) => void;\n\t/**\n\t * Set the response status code\n\t */\n\tsetStatus: (status: Status) => void;\n\t/**\n\t * Get header\n\t *\n\t * If it's called outside of a request it will just return null\n\t *\n\t * @param key - The key of the header\n\t * @returns\n\t */\n\tgetHeader: (key: string) => string | null;\n\t/**\n\t * Get a cookie value from the request\n\t *\n\t * @param key - The key of the cookie\n\t * @param prefix - The prefix of the cookie between `__Secure-` and `__Host-`\n\t * @returns - The value of the cookie\n\t */\n\tgetCookie: (key: string, prefix?: CookiePrefixOptions) => string | null;\n\t/**\n\t * Get a signed cookie value from the request\n\t *\n\t * @param key - The key of the cookie\n\t * @param secret - The secret of the signed cookie\n\t * @param prefix - The prefix of the cookie between `__Secure-` and `__Host-`\n\t * @returns - The value of the cookie or null if the cookie is not found or false if the signature is invalid\n\t */\n\tgetSignedCookie: (\n\t\tkey: string,\n\t\tsecret: string,\n\t\tprefix?: CookiePrefixOptions,\n\t) => Promise<string | null | false>;\n\t/**\n\t * Set a cookie value in the response\n\t *\n\t * @param key - The key of the cookie\n\t * @param value - The value to set\n\t * @param options - The options of the cookie\n\t * @returns - The cookie string\n\t */\n\tsetCookie: (key: string, value: string, options?: CookieOptions) => string;\n\t/**\n\t * Set signed cookie\n\t *\n\t * @param key - The key of the cookie\n\t * @param value - The value to set\n\t * @param secret - The secret to sign the cookie with\n\t * @param options - The options of the cookie\n\t * @returns - The cookie string\n\t */\n\tsetSignedCookie: (\n\t\tkey: string,\n\t\tvalue: string,\n\t\tsecret: string,\n\t\toptions?: CookieOptions,\n\t) => Promise<string>;\n\t/**\n\t * JSON\n\t *\n\t * a helper function to create a JSON response with\n\t * the correct headers\n\t * and status code. If `asResponse` is set to true in\n\t * the context then\n\t * it will return a Response object instead of the\n\t * JSON object.\n\t *\n\t * @param json - The JSON object to return\n\t * @param routerResponse - The response object to\n\t * return if `asResponse` is\n\t * true in the context this will take precedence\n\t */\n\tjson: <R extends Record<string, any> | null>(\n\t\tjson: R,\n\t\trouterResponse?:\n\t\t\t| {\n\t\t\t\t\tstatus?: number;\n\t\t\t\t\theaders?: Record<string, string>;\n\t\t\t\t\tresponse?: Response;\n\t\t\t\t\tbody?: Record<string, string>;\n\t\t\t }\n\t\t\t| Response,\n\t) => Promise<R>;\n\t/**\n\t * Middleware context\n\t */\n\tcontext: Prettify<Context & InferUse<Options[\"use\"]>>;\n\t/**\n\t * Redirect to a new URL\n\t */\n\tredirect: (url: string) => APIError;\n\t/**\n\t * Return error\n\t */\n\terror: (\n\t\tstatus: keyof typeof statusCodes | Status,\n\t\tbody?: {\n\t\t\tmessage?: string;\n\t\t\tcode?: string;\n\t\t} & Record<string, any>,\n\t\theaders?: HeadersInit,\n\t) => APIError;\n};\n\ntype ExtractBody<E extends EndpointBodyMethodOptions> = E extends {\n\tmethod: (\"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"GET\" | \"HEAD\")[];\n\tbody?: StandardSchemaV1<infer B>;\n}\n\t? E extends {\n\t\t\tmethod: infer M;\n\t\t\tbody?: StandardSchemaV1<B>;\n\t\t}\n\t\t? { method: M; body: StandardSchemaV1<B> }\n\t\t: never\n\t: E extends {\n\t\t\t\tmethod:\n\t\t\t\t\t| \"POST\"\n\t\t\t\t\t| \"PUT\"\n\t\t\t\t\t| \"DELETE\"\n\t\t\t\t\t| \"PATCH\"\n\t\t\t\t\t| (\"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\")[];\n\t\t\t\tbody?: StandardSchemaV1<infer B>;\n\t\t\t}\n\t\t? E extends {\n\t\t\t\tmethod: infer M;\n\t\t\t\tbody?: StandardSchemaV1<B>;\n\t\t\t}\n\t\t\t? { method: M; body: StandardSchemaV1<B> }\n\t\t\t: never\n\t\t: E extends {\n\t\t\t\t\tmethod: \"*\";\n\t\t\t\t\tbody?: StandardSchemaV1<infer B>;\n\t\t\t\t}\n\t\t\t? {\n\t\t\t\t\tmethod: \"*\";\n\t\t\t\t\tbody?: StandardSchemaV1<B>;\n\t\t\t\t}\n\t\t\t: E extends {\n\t\t\t\t\t\tmethod: \"GET\" | \"HEAD\" | (\"GET\" | \"HEAD\")[];\n\t\t\t\t\t\tbody?: never;\n\t\t\t\t\t}\n\t\t\t\t? E extends { method: infer M }\n\t\t\t\t\t? { method: M }\n\t\t\t\t\t: never\n\t\t\t\t: never;\ntype ExtractError<E extends EndpointOptions> = E extends {\n\terror?: StandardSchemaV1<infer Err>;\n}\n\t? {\n\t\t\terror: StandardSchemaV1<Err>;\n\t\t}\n\t: {};\ntype ExtractQuery<E extends EndpointOptions> = E extends {\n\tquery?: StandardSchemaV1<infer Q>;\n}\n\t? {\n\t\t\tquery: StandardSchemaV1<Q>;\n\t\t}\n\t: {};\n\ntype ExtractOthers<E extends EndpointOptions> = Pick<\n\tE,\n\tExclude<keyof E, \"method\" | \"body\" | \"query\" | \"error\">\n>;\n\n/**\n * DO NOT EXPORT THIS TYPE\n */\ntype ExtractStandSchema<E extends EndpointOptions> = ExtractOthers<E> &\n\tExtractBody<E> &\n\tExtractQuery<E> &\n\tExtractError<E>;\n\nexport type EndpointHandler<\n\tPath extends string,\n\tOptions extends EndpointOptions,\n\tR,\n> = (context: EndpointContext<Path, Options>) => Promise<R>;\n\nexport function createEndpoint<\n\tPath extends string,\n\tOptions extends EndpointOptions,\n\tR,\n>(\n\tpath: Path,\n\toptions: Options,\n\thandler: EndpointHandler<Path, Options, R>,\n): StrictEndpoint<Path, ExtractStandSchema<Options>, R>;\n\nexport function createEndpoint<Options extends EndpointOptions, R>(\n\toptions: Options,\n\thandler: EndpointHandler<never, Options, R>,\n): StrictEndpoint<never, ExtractStandSchema<Options>, R>;\n\nexport function createEndpoint<\n\tPath extends string,\n\tOptions extends EndpointOptions,\n\tR,\n>(\n\tpathOrOptions: Path | Options,\n\thandlerOrOptions: EndpointHandler<Path, Options, R> | Options,\n\thandlerOrNever?: any,\n): StrictEndpoint<Path, ExtractStandSchema<Options>, R> {\n\tconst path: string | undefined =\n\t\ttypeof pathOrOptions === \"string\" ? pathOrOptions : undefined;\n\tconst options: Options =\n\t\ttypeof handlerOrOptions === \"object\"\n\t\t\t? handlerOrOptions\n\t\t\t: (pathOrOptions as Options);\n\tconst handler: EndpointHandler<Path, Options, R> =\n\t\ttypeof handlerOrOptions === \"function\" ? handlerOrOptions : handlerOrNever;\n\n\tif ((options.method === \"GET\" || options.method === \"HEAD\") && options.body) {\n\t\tthrow new BetterCallError(\"Body is not allowed with GET or HEAD methods\");\n\t}\n\n\tif (path && /\\/{2,}/.test(path)) {\n\t\tthrow new BetterCallError(\"Path cannot contain consecutive slashes\");\n\t}\n\ttype Context = InputContext<Path, Options>;\n\n\ttype ResultType<\n\t\tAsResponse extends boolean,\n\t\tReturnHeaders extends boolean,\n\t\tReturnStatus extends boolean,\n\t> = AsResponse extends true\n\t\t? Response\n\t\t: ReturnHeaders extends true\n\t\t\t? ReturnStatus extends true\n\t\t\t\t? {\n\t\t\t\t\t\theaders: Headers;\n\t\t\t\t\t\tstatus: number;\n\t\t\t\t\t\tresponse: Awaited<R>;\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\theaders: Headers;\n\t\t\t\t\t\tresponse: Awaited<R>;\n\t\t\t\t\t}\n\t\t\t: ReturnStatus extends true\n\t\t\t\t? {\n\t\t\t\t\t\tstatus: number;\n\t\t\t\t\t\tresponse: Awaited<R>;\n\t\t\t\t\t}\n\t\t\t\t: Awaited<R>;\n\n\tconst internalHandler = async <\n\t\tAsResponse extends boolean = false,\n\t\tReturnHeaders extends boolean = false,\n\t\tReturnStatus extends boolean = false,\n\t>(\n\t\t...inputCtx: HasRequiredKeys<Context> extends true\n\t\t\t? [\n\t\t\t\t\tContext & {\n\t\t\t\t\t\tasResponse?: AsResponse;\n\t\t\t\t\t\treturnHeaders?: ReturnHeaders;\n\t\t\t\t\t\treturnStatus?: ReturnStatus;\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t: [\n\t\t\t\t\t(Context & {\n\t\t\t\t\t\tasResponse?: AsResponse;\n\t\t\t\t\t\treturnHeaders?: ReturnHeaders;\n\t\t\t\t\t\treturnStatus?: ReturnStatus;\n\t\t\t\t\t})?,\n\t\t\t\t]\n\t): Promise<ResultType<AsResponse, ReturnHeaders, ReturnStatus>> => {\n\t\tconst context = (inputCtx[0] || {}) as InputContext<any, any>;\n\t\tconst { data: internalContext, error: validationError } = await tryCatch(\n\t\t\tcreateInternalContext(context, {\n\t\t\t\toptions,\n\t\t\t\tpath,\n\t\t\t}),\n\t\t);\n\n\t\tif (validationError) {\n\t\t\t// If it's not a validation error, we throw it\n\t\t\tif (!(validationError instanceof ValidationError)) throw validationError;\n\n\t\t\t// Check if the endpoint has a custom onValidationError callback\n\t\t\tif (options.onValidationError) {\n\t\t\t\t// This can possibly throw an APIError in order to customize the validation error message\n\t\t\t\tawait options.onValidationError({\n\t\t\t\t\tmessage: validationError.message,\n\t\t\t\t\tissues: validationError.issues,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow new APIError(400, {\n\t\t\t\tmessage: validationError.message,\n\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t});\n\t\t}\n\t\tconst response = await handler(internalContext as any).catch(async (e) => {\n\t\t\tif (isAPIError(e)) {\n\t\t\t\tconst onAPIError = options.onAPIError;\n\t\t\t\tif (onAPIError) {\n\t\t\t\t\tawait onAPIError(e);\n\t\t\t\t}\n\t\t\t\tif (context.asResponse) {\n\t\t\t\t\treturn e;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow e;\n\t\t});\n\t\tconst headers = internalContext.responseHeaders;\n\t\tconst status = internalContext.responseStatus;\n\n\t\treturn (\n\t\t\tcontext.asResponse\n\t\t\t\t? toResponse(response, {\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t})\n\t\t\t\t: context.returnHeaders\n\t\t\t\t\t? context.returnStatus\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t\t\tstatus,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t: context.returnStatus\n\t\t\t\t\t\t? { response, status }\n\t\t\t\t\t\t: response\n\t\t) as ResultType<AsResponse, ReturnHeaders, ReturnStatus>;\n\t};\n\tinternalHandler.options = options;\n\tinternalHandler.path = path;\n\treturn internalHandler as unknown as StrictEndpoint<\n\t\tPath,\n\t\tExtractStandSchema<Options>,\n\t\tR\n\t>;\n}\n\ncreateEndpoint.create = <E extends { use?: Middleware[] }>(opts?: E) => {\n\treturn <\n\t\tPath extends string,\n\t\tOpts extends EndpointOptions,\n\t\tR extends Promise<any>,\n\t>(\n\t\tpath: Path,\n\t\toptions: Opts,\n\t\thandler: (ctx: EndpointContext<Path, Opts, InferUse<E[\"use\"]>>) => R,\n\t) => {\n\t\treturn createEndpoint(\n\t\t\tpath,\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tuse: [...(options?.use || []), ...(opts?.use || [])],\n\t\t\t},\n\t\t\thandler,\n\t\t);\n\t};\n};\n\nexport type StrictEndpoint<\n\tPath extends string,\n\tOptions extends EndpointOptions,\n\tR = any,\n> = {\n\t// asResponse cases\n\t(\n\t\tcontext: InputContext<Path, Options> & { asResponse: true },\n\t): Promise<Response>;\n\n\t// returnHeaders & returnStatus cases\n\t(\n\t\tcontext: InputContext<Path, Options> & {\n\t\t\treturnHeaders: true;\n\t\t\treturnStatus: true;\n\t\t},\n\t): Promise<{ headers: Headers; status: number; response: Awaited<R> }>;\n\t(\n\t\tcontext: InputContext<Path, Options> & {\n\t\t\treturnHeaders: true;\n\t\t\treturnStatus: false;\n\t\t},\n\t): Promise<{ headers: Headers; response: Awaited<R> }>;\n\t(\n\t\tcontext: InputContext<Path, Options> & {\n\t\t\treturnHeaders: false;\n\t\t\treturnStatus: true;\n\t\t},\n\t): Promise<{ status: number; response: Awaited<R> }>;\n\t(\n\t\tcontext: InputContext<Path, Options> & {\n\t\t\treturnHeaders: false;\n\t\t\treturnStatus: false;\n\t\t},\n\t): Promise<R>;\n\n\t// individual flag cases\n\t(\n\t\tcontext: InputContext<Path, Options> & { returnHeaders: true },\n\t): Promise<{ headers: Headers; response: Awaited<R> }>;\n\t(\n\t\tcontext: InputContext<Path, Options> & { returnStatus: true },\n\t): Promise<{ status: number; response: Awaited<R> }>;\n\n\t// default case\n\t(context?: InputContext<Path, Options>): Promise<R>;\n\n\toptions: Options;\n\tpath: Path;\n};\n\nexport type Endpoint<\n\tPath extends string = string,\n\tOptions extends EndpointOptions = EndpointOptions,\n\tHandler extends (inputCtx: any) => Promise<any> = (\n\t\tinputCtx: any,\n\t) => Promise<any>,\n> = Handler & {\n\toptions: Options;\n\tpath: Path;\n};\n"],"mappings":";;;;;;AA4fA,SAAgB,eAKf,eACA,kBACA,gBACuD;CACvD,MAAM,OACL,OAAO,kBAAkB,WAAW,gBAAgB;CACrD,MAAM,UACL,OAAO,qBAAqB,WACzB,mBACC;CACL,MAAM,UACL,OAAO,qBAAqB,aAAa,mBAAmB;AAE7D,MAAK,QAAQ,WAAW,SAAS,QAAQ,WAAW,WAAW,QAAQ,KACtE,OAAM,IAAI,gBAAgB,+CAA+C;AAG1E,KAAI,QAAQ,SAAS,KAAK,KAAK,CAC9B,OAAM,IAAI,gBAAgB,0CAA0C;CA4BrE,MAAM,kBAAkB,OAKvB,GAAG,aAe+D;EAClE,MAAM,UAAW,SAAS,MAAM,EAAE;EAClC,MAAM,EAAE,MAAM,iBAAiB,OAAO,oBAAoB,MAAM,SAC/D,sBAAsB,SAAS;GAC9B;GACA;GACA,CAAC,CACF;AAED,MAAI,iBAAiB;AAEpB,OAAI,EAAE,2BAA2B,iBAAkB,OAAM;AAGzD,OAAI,QAAQ,kBAEX,OAAM,QAAQ,kBAAkB;IAC/B,SAAS,gBAAgB;IACzB,QAAQ,gBAAgB;IACxB,CAAC;AAGH,SAAM,IAAI,SAAS,KAAK;IACvB,SAAS,gBAAgB;IACzB,MAAM;IACN,CAAC;;EAEH,MAAM,WAAW,MAAM,QAAQ,gBAAuB,CAAC,MAAM,OAAO,MAAM;AACzE,OAAI,WAAW,EAAE,EAAE;IAClB,MAAM,aAAa,QAAQ;AAC3B,QAAI,WACH,OAAM,WAAW,EAAE;AAEpB,QAAI,QAAQ,WACX,QAAO;;AAGT,SAAM;IACL;EACF,MAAM,UAAU,gBAAgB;EAChC,MAAM,SAAS,gBAAgB;AAE/B,SACC,QAAQ,aACL,WAAW,UAAU;GACrB;GACA;GACA,CAAC,GACD,QAAQ,gBACP,QAAQ,eACP;GACA;GACA;GACA;GACA,GACA;GACA;GACA;GACA,GACD,QAAQ,eACP;GAAE;GAAU;GAAQ,GACpB;;AAGP,iBAAgB,UAAU;AAC1B,iBAAgB,OAAO;AACvB,QAAO;;AAOR,eAAe,UAA4C,SAAa;AACvE,SAKC,MACA,SACA,YACI;AACJ,SAAO,eACN,MACA;GACC,GAAG;GACH,KAAK,CAAC,GAAI,SAAS,OAAO,EAAE,EAAG,GAAI,MAAM,OAAO,EAAE,CAAE;GACpD,EACD,QACA"}
1
+ {"version":3,"file":"endpoint.mjs","names":[],"sources":["../src/endpoint.ts"],"sourcesContent":["import { createInternalContext, type EndpointContext } from \"./context\";\nimport type { CookieOptions, CookiePrefixOptions } from \"./cookies\";\nimport {\n\tAPIError,\n\tBetterCallError,\n\ttype Status,\n\ttype statusCodes,\n\tValidationError,\n} from \"./error\";\nimport type { HasRequiredKeys, Prettify } from \"./helper\";\nimport type { Middleware } from \"./middleware\";\nimport type { OpenAPIParameter, OpenAPISchemaType } from \"./openapi\";\nimport type { StandardSchemaV1 } from \"./standard-schema\";\nimport { toResponse } from \"./to-response\";\nimport type {\n\tBodyOption,\n\tHasRequiredInputKeys,\n\tHTTPMethod,\n\tInferUse,\n\tInputContext,\n\tResolveBodyInput,\n\tResolveErrorInput,\n\tResolveQueryInput,\n} from \"./types\";\nimport { isAPIError, tryCatch } from \"./utils\";\n\nexport type { EndpointContext } from \"./context\";\n\nexport interface EndpointMetadata {\n\t/**\n\t * Open API definition\n\t */\n\topenapi?: {\n\t\tsummary?: string;\n\t\tdescription?: string;\n\t\ttags?: string[];\n\t\toperationId?: string;\n\t\tparameters?: OpenAPIParameter[];\n\t\trequestBody?: {\n\t\t\tcontent: {\n\t\t\t\t\"application/json\": {\n\t\t\t\t\tschema: {\n\t\t\t\t\t\ttype?: OpenAPISchemaType;\n\t\t\t\t\t\tproperties?: Record<string, any>;\n\t\t\t\t\t\trequired?: string[];\n\t\t\t\t\t\t$ref?: string;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t\tresponses?: {\n\t\t\t[status: string]: {\n\t\t\t\tdescription: string;\n\t\t\t\tcontent?: {\n\t\t\t\t\t\"application/json\"?: {\n\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\ttype?: OpenAPISchemaType;\n\t\t\t\t\t\t\tproperties?: Record<string, any>;\n\t\t\t\t\t\t\trequired?: string[];\n\t\t\t\t\t\t\t$ref?: string;\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t\t\"text/plain\"?: {\n\t\t\t\t\t\tschema?: {\n\t\t\t\t\t\t\ttype?: OpenAPISchemaType;\n\t\t\t\t\t\t\tproperties?: Record<string, any>;\n\t\t\t\t\t\t\trequired?: string[];\n\t\t\t\t\t\t\t$ref?: string;\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t\t\"text/html\"?: {\n\t\t\t\t\t\tschema?: {\n\t\t\t\t\t\t\ttype?: OpenAPISchemaType;\n\t\t\t\t\t\t\tproperties?: Record<string, any>;\n\t\t\t\t\t\t\trequired?: string[];\n\t\t\t\t\t\t\t$ref?: string;\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n\t/**\n\t * Infer body and query type from ts interface\n\t *\n\t * useful for generic and dynamic types\n\t *\n\t * @example\n\t * ```ts\n\t * const endpoint = createEndpoint(\"/path\", {\n\t * \t\tmethod: \"POST\",\n\t * \t\tbody: z.record(z.string()),\n\t * \t\t$Infer: {\n\t * \t\t\tbody: {} as {\n\t * \t\t\t\ttype: InferTypeFromOptions<Option> // custom type inference\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}, async(ctx)=>{\n\t * \t\tconst body = ctx.body\n\t * \t})\n\t * ```\n\t */\n\t$Infer?: {\n\t\t/**\n\t\t * Body\n\t\t */\n\t\tbody?: any;\n\t\t/**\n\t\t * Query\n\t\t */\n\t\tquery?: Record<string, any>;\n\t\t/**\n\t\t * Error\n\t\t */\n\t\terror?: any;\n\t};\n\t/**\n\t * If enabled, endpoint won't be exposed over a router\n\t * @deprecated Use path-less endpoints instead\n\t */\n\tSERVER_ONLY?: boolean;\n\t/**\n\t * If enabled, endpoint won't be exposed as an action to the client\n\t * @deprecated Use path-less endpoints instead\n\t */\n\tisAction?: boolean;\n\t/**\n\t * Defines the places where the endpoint will be available\n\t *\n\t * Possible options:\n\t * - `rpc` - the endpoint is exposed to the router, can be invoked directly and is available to the client\n\t * - `server` - the endpoint is exposed to the router, can be invoked directly, but is not available to the client\n\t * - `http` - the endpoint is only exposed to the router\n\t * @default \"rpc\"\n\t */\n\tscope?: \"rpc\" | \"server\" | \"http\";\n\t/**\n\t * List of allowed media types (MIME types) for the endpoint\n\t *\n\t * if provided, only the media types in the list will be allowed to be passed in the body\n\t *\n\t * @example\n\t * ```ts\n\t * const endpoint = createEndpoint(\"/path\", {\n\t * \t\tmethod: \"POST\",\n\t * \t\tallowedMediaTypes: [\"application/json\", \"application/x-www-form-urlencoded\"],\n\t * \t}, async(ctx)=>{\n\t * \t\tconst body = ctx.body\n\t * \t})\n\t * ```\n\t */\n\tallowedMediaTypes?: string[];\n\t/**\n\t * Extra metadata\n\t */\n\t[key: string]: any;\n}\n\nexport interface EndpointRuntimeOptions {\n\tmethod: string | string[];\n\tbody?: StandardSchemaV1;\n\t/**\n\t * Query Schema\n\t */\n\tquery?: StandardSchemaV1;\n\t/**\n\t * Error Schema\n\t */\n\terror?: StandardSchemaV1;\n\t/**\n\t * If true headers will be required to be passed in the context\n\t */\n\trequireHeaders?: boolean;\n\t/**\n\t * If true request object will be required\n\t */\n\trequireRequest?: boolean;\n\t/**\n\t * Clone the request object from the router\n\t */\n\tcloneRequest?: boolean;\n\t/**\n\t * If true the body will be undefined\n\t */\n\tdisableBody?: boolean;\n\t/**\n\t * Endpoint metadata\n\t */\n\tmetadata?: EndpointMetadata;\n\t/**\n\t * List of middlewares to use\n\t */\n\tuse?: Middleware[];\n\t/**\n\t * A callback to run before any API error is thrown or returned\n\t *\n\t * @param e - The API error\n\t */\n\tonAPIError?: (e: APIError) => void | Promise<void>;\n\t/**\n\t * A callback to run before a validation error is thrown.\n\t * You can customize the validation error message by throwing your own APIError.\n\t */\n\tonValidationError?: (info: {\n\t\tmessage: string;\n\t\tissues: readonly StandardSchemaV1.Issue[];\n\t}) => void | Promise<void>;\n}\n\nexport type Endpoint<\n\tPath extends string = string,\n\tMethod = any,\n\tBody = any,\n\tQuery = any,\n\tUse extends Middleware[] = any,\n\tR = any,\n\tMeta extends EndpointMetadata | undefined = EndpointMetadata | undefined,\n\tError = any,\n> = {\n\t(\n\t\tcontext: InputContext<Path, Method, Body, Query, false, false> & {\n\t\t\tasResponse: true;\n\t\t},\n\t): Promise<Response>;\n\t(\n\t\tcontext: InputContext<Path, Method, Body, Query, false, false> & {\n\t\t\treturnHeaders: true;\n\t\t\treturnStatus: true;\n\t\t},\n\t): Promise<{\n\t\theaders: Headers;\n\t\tstatus: number;\n\t\tresponse: Awaited<R>;\n\t}>;\n\t(\n\t\tcontext: InputContext<Path, Method, Body, Query, false, false> & {\n\t\t\treturnHeaders: true;\n\t\t},\n\t): Promise<{\n\t\theaders: Headers;\n\t\tresponse: Awaited<R>;\n\t}>;\n\t(\n\t\tcontext: InputContext<Path, Method, Body, Query, false, false> & {\n\t\t\treturnStatus: true;\n\t\t},\n\t): Promise<{\n\t\tstatus: number;\n\t\tresponse: Awaited<R>;\n\t}>;\n\t(\n\t\tcontext?: InputContext<Path, Method, Body, Query, false, false>,\n\t): Promise<Awaited<R>>;\n\toptions: EndpointRuntimeOptions & {\n\t\tmethod: Method;\n\t\tmetadata?: Meta;\n\t};\n\tpath: Path;\n};\n\n// Path + options + handler overload\nexport function createEndpoint<\n\tPath extends string,\n\tMethod extends HTTPMethod | HTTPMethod[] | \"*\",\n\tBodySchema extends object | undefined = undefined,\n\tQuerySchema extends object | undefined = undefined,\n\tUse extends Middleware[] = [],\n\tReqHeaders extends boolean = false,\n\tReqRequest extends boolean = false,\n\tR = unknown,\n\tMeta extends EndpointMetadata | undefined = undefined,\n\tErrorSchema extends StandardSchemaV1 | undefined = undefined,\n>(\n\tpath: Path,\n\toptions: { method: Method } & BodyOption<Method, BodySchema> & {\n\t\t\tquery?: QuerySchema;\n\t\t\tuse?: [...Use];\n\t\t\trequireHeaders?: ReqHeaders;\n\t\t\trequireRequest?: ReqRequest;\n\t\t\terror?: ErrorSchema;\n\t\t\tcloneRequest?: boolean;\n\t\t\tdisableBody?: boolean;\n\t\t\tmetadata?: Meta;\n\t\t\tonAPIError?: (e: APIError) => void | Promise<void>;\n\t\t\tonValidationError?: (info: {\n\t\t\t\tmessage: string;\n\t\t\t\tissues: readonly StandardSchemaV1.Issue[];\n\t\t\t}) => void | Promise<void>;\n\t\t\t[key: string]: any;\n\t\t},\n\thandler: (\n\t\tctx: EndpointContext<\n\t\t\tPath,\n\t\t\tMethod,\n\t\t\tBodySchema,\n\t\t\tQuerySchema,\n\t\t\tUse,\n\t\t\tReqHeaders,\n\t\t\tReqRequest,\n\t\t\tInferUse<Use>,\n\t\t\tMeta\n\t\t>,\n\t) => Promise<R>,\n): Endpoint<\n\tPath,\n\tMethod,\n\tResolveBodyInput<BodySchema, Meta>,\n\tResolveQueryInput<QuerySchema, Meta>,\n\tUse,\n\tR,\n\tMeta,\n\tResolveErrorInput<ErrorSchema, Meta>\n>;\n\n// Options-only (virtual/path-less) overload\nexport function createEndpoint<\n\tMethod extends HTTPMethod | HTTPMethod[] | \"*\",\n\tBodySchema extends object | undefined = undefined,\n\tQuerySchema extends object | undefined = undefined,\n\tUse extends Middleware[] = [],\n\tReqHeaders extends boolean = false,\n\tReqRequest extends boolean = false,\n\tR = unknown,\n\tMeta extends EndpointMetadata | undefined = undefined,\n\tErrorSchema extends StandardSchemaV1 | undefined = undefined,\n>(\n\toptions: { method: Method } & BodyOption<Method, BodySchema> & {\n\t\t\tpath?: never;\n\t\t\tquery?: QuerySchema;\n\t\t\tuse?: [...Use];\n\t\t\trequireHeaders?: ReqHeaders;\n\t\t\trequireRequest?: ReqRequest;\n\t\t\terror?: ErrorSchema;\n\t\t\tcloneRequest?: boolean;\n\t\t\tdisableBody?: boolean;\n\t\t\tmetadata?: Meta;\n\t\t\tonAPIError?: (e: APIError) => void | Promise<void>;\n\t\t\tonValidationError?: (info: {\n\t\t\t\tmessage: string;\n\t\t\t\tissues: readonly StandardSchemaV1.Issue[];\n\t\t\t}) => void | Promise<void>;\n\t\t\t[key: string]: any;\n\t\t},\n\thandler: (\n\t\tctx: EndpointContext<\n\t\t\tnever,\n\t\t\tMethod,\n\t\t\tBodySchema,\n\t\t\tQuerySchema,\n\t\t\tUse,\n\t\t\tReqHeaders,\n\t\t\tReqRequest,\n\t\t\tInferUse<Use>,\n\t\t\tMeta\n\t\t>,\n\t) => Promise<R>,\n): Endpoint<\n\tnever,\n\tMethod,\n\tResolveBodyInput<BodySchema, Meta>,\n\tResolveQueryInput<QuerySchema, Meta>,\n\tUse,\n\tR,\n\tMeta,\n\tResolveErrorInput<ErrorSchema, Meta>\n>;\n\n// Implementation\nexport function createEndpoint(\n\tpathOrOptions: any,\n\thandlerOrOptions: any,\n\thandlerOrNever?: any,\n): any {\n\tconst path: string | undefined =\n\t\ttypeof pathOrOptions === \"string\" ? pathOrOptions : undefined;\n\tconst options: any =\n\t\ttypeof handlerOrOptions === \"object\" ? handlerOrOptions : pathOrOptions;\n\tconst handler: any =\n\t\ttypeof handlerOrOptions === \"function\" ? handlerOrOptions : handlerOrNever;\n\n\tif ((options.method === \"GET\" || options.method === \"HEAD\") && options.body) {\n\t\tthrow new BetterCallError(\"Body is not allowed with GET or HEAD methods\");\n\t}\n\n\tif (path && /\\/{2,}/.test(path)) {\n\t\tthrow new BetterCallError(\"Path cannot contain consecutive slashes\");\n\t}\n\n\tconst runtimeOptions: EndpointRuntimeOptions = {\n\t\tmethod: options.method,\n\t\tbody: options.body,\n\t\tquery: options.query,\n\t\terror: options.error,\n\t\trequireHeaders: options.requireHeaders,\n\t\trequireRequest: options.requireRequest,\n\t\tcloneRequest: options.cloneRequest,\n\t\tdisableBody: options.disableBody,\n\t\tmetadata: options.metadata,\n\t\tuse: options.use,\n\t\tonAPIError: options.onAPIError,\n\t\tonValidationError: options.onValidationError,\n\t};\n\n\tconst internalHandler = async (...inputCtx: any[]): Promise<any> => {\n\t\tconst context = (inputCtx[0] || {}) as Record<string, any>;\n\t\tconst { data: internalContext, error: validationError } = await tryCatch(\n\t\t\tcreateInternalContext(context, {\n\t\t\t\toptions: runtimeOptions,\n\t\t\t\tpath,\n\t\t\t}),\n\t\t);\n\n\t\tif (validationError) {\n\t\t\tif (!(validationError instanceof ValidationError)) throw validationError;\n\n\t\t\tif (options.onValidationError) {\n\t\t\t\tawait options.onValidationError({\n\t\t\t\t\tmessage: validationError.message,\n\t\t\t\t\tissues: validationError.issues,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow new APIError(400, {\n\t\t\t\tmessage: validationError.message,\n\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t});\n\t\t}\n\n\t\tconst response = await handler(internalContext as any).catch(\n\t\t\tasync (e: any) => {\n\t\t\t\tif (isAPIError(e)) {\n\t\t\t\t\tconst onAPIError = options.onAPIError;\n\t\t\t\t\tif (onAPIError) {\n\t\t\t\t\t\tawait onAPIError(e);\n\t\t\t\t\t}\n\t\t\t\t\tif (context.asResponse) {\n\t\t\t\t\t\treturn e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow e;\n\t\t\t},\n\t\t);\n\n\t\tconst responseHeaders = internalContext.responseHeaders;\n\t\tconst status = internalContext.responseStatus;\n\n\t\treturn context.asResponse\n\t\t\t? toResponse(response, {\n\t\t\t\t\theaders: responseHeaders,\n\t\t\t\t\tstatus,\n\t\t\t\t})\n\t\t\t: context.returnHeaders\n\t\t\t\t? context.returnStatus\n\t\t\t\t\t? {\n\t\t\t\t\t\t\theaders: responseHeaders,\n\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t\tstatus,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\theaders: responseHeaders,\n\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t}\n\t\t\t\t: context.returnStatus\n\t\t\t\t\t? { response, status }\n\t\t\t\t\t: response;\n\t};\n\n\tinternalHandler.options = runtimeOptions;\n\tinternalHandler.path = path;\n\treturn internalHandler as any;\n}\n\ncreateEndpoint.create = <E extends { use?: Middleware[] }>(opts?: E) => {\n\treturn <\n\t\tPath extends string,\n\t\tMethod extends HTTPMethod | HTTPMethod[] | \"*\",\n\t\tBodySchema extends object | undefined = undefined,\n\t\tQuerySchema extends object | undefined = undefined,\n\t\tUse extends Middleware[] = [],\n\t\tReqHeaders extends boolean = false,\n\t\tReqRequest extends boolean = false,\n\t\tR = unknown,\n\t\tMeta extends EndpointMetadata | undefined = undefined,\n\t\tErrorSchema extends StandardSchemaV1 | undefined = undefined,\n\t>(\n\t\tpath: Path,\n\t\toptions: { method: Method } & BodyOption<Method, BodySchema> & {\n\t\t\t\tquery?: QuerySchema;\n\t\t\t\tuse?: [...Use];\n\t\t\t\trequireHeaders?: ReqHeaders;\n\t\t\t\trequireRequest?: ReqRequest;\n\t\t\t\terror?: ErrorSchema;\n\t\t\t\tcloneRequest?: boolean;\n\t\t\t\tdisableBody?: boolean;\n\t\t\t\tmetadata?: Meta;\n\t\t\t\tonAPIError?: (e: APIError) => void | Promise<void>;\n\t\t\t\tonValidationError?: (info: {\n\t\t\t\t\tmessage: string;\n\t\t\t\t\tissues: readonly StandardSchemaV1.Issue[];\n\t\t\t\t}) => void | Promise<void>;\n\t\t\t\t[key: string]: any;\n\t\t\t},\n\t\thandler: (\n\t\t\tctx: EndpointContext<\n\t\t\t\tPath,\n\t\t\t\tMethod,\n\t\t\t\tBodySchema,\n\t\t\t\tQuerySchema,\n\t\t\t\tUse,\n\t\t\t\tReqHeaders,\n\t\t\t\tReqRequest,\n\t\t\t\tInferUse<E[\"use\"]>,\n\t\t\t\tMeta\n\t\t\t>,\n\t\t) => Promise<R>,\n\t): Endpoint<\n\t\tPath,\n\t\tMethod,\n\t\tResolveBodyInput<BodySchema, Meta>,\n\t\tResolveQueryInput<QuerySchema, Meta>,\n\t\tUse,\n\t\tAwaited<R>,\n\t\tMeta,\n\t\tResolveErrorInput<ErrorSchema, Meta>\n\t> => {\n\t\treturn createEndpoint(\n\t\t\tpath,\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tuse: [...(options?.use || []), ...(opts?.use || [])],\n\t\t\t} as any,\n\t\t\thandler as any,\n\t\t) as any;\n\t};\n};\n"],"mappings":";;;;;;AAgXA,SAAgB,eACf,eACA,kBACA,gBACM;CACN,MAAM,OACL,OAAO,kBAAkB,WAAW,gBAAgB;CACrD,MAAM,UACL,OAAO,qBAAqB,WAAW,mBAAmB;CAC3D,MAAM,UACL,OAAO,qBAAqB,aAAa,mBAAmB;AAE7D,MAAK,QAAQ,WAAW,SAAS,QAAQ,WAAW,WAAW,QAAQ,KACtE,OAAM,IAAI,gBAAgB,+CAA+C;AAG1E,KAAI,QAAQ,SAAS,KAAK,KAAK,CAC9B,OAAM,IAAI,gBAAgB,0CAA0C;CAGrE,MAAM,iBAAyC;EAC9C,QAAQ,QAAQ;EAChB,MAAM,QAAQ;EACd,OAAO,QAAQ;EACf,OAAO,QAAQ;EACf,gBAAgB,QAAQ;EACxB,gBAAgB,QAAQ;EACxB,cAAc,QAAQ;EACtB,aAAa,QAAQ;EACrB,UAAU,QAAQ;EAClB,KAAK,QAAQ;EACb,YAAY,QAAQ;EACpB,mBAAmB,QAAQ;EAC3B;CAED,MAAM,kBAAkB,OAAO,GAAG,aAAkC;EACnE,MAAM,UAAW,SAAS,MAAM,EAAE;EAClC,MAAM,EAAE,MAAM,iBAAiB,OAAO,oBAAoB,MAAM,SAC/D,sBAAsB,SAAS;GAC9B,SAAS;GACT;GACA,CAAC,CACF;AAED,MAAI,iBAAiB;AACpB,OAAI,EAAE,2BAA2B,iBAAkB,OAAM;AAEzD,OAAI,QAAQ,kBACX,OAAM,QAAQ,kBAAkB;IAC/B,SAAS,gBAAgB;IACzB,QAAQ,gBAAgB;IACxB,CAAC;AAGH,SAAM,IAAI,SAAS,KAAK;IACvB,SAAS,gBAAgB;IACzB,MAAM;IACN,CAAC;;EAGH,MAAM,WAAW,MAAM,QAAQ,gBAAuB,CAAC,MACtD,OAAO,MAAW;AACjB,OAAI,WAAW,EAAE,EAAE;IAClB,MAAM,aAAa,QAAQ;AAC3B,QAAI,WACH,OAAM,WAAW,EAAE;AAEpB,QAAI,QAAQ,WACX,QAAO;;AAGT,SAAM;IAEP;EAED,MAAM,kBAAkB,gBAAgB;EACxC,MAAM,SAAS,gBAAgB;AAE/B,SAAO,QAAQ,aACZ,WAAW,UAAU;GACrB,SAAS;GACT;GACA,CAAC,GACD,QAAQ,gBACP,QAAQ,eACP;GACA,SAAS;GACT;GACA;GACA,GACA;GACA,SAAS;GACT;GACA,GACD,QAAQ,eACP;GAAE;GAAU;GAAQ,GACpB;;AAGN,iBAAgB,UAAU;AAC1B,iBAAgB,OAAO;AACvB,QAAO;;AAGR,eAAe,UAA4C,SAAa;AACvE,SAYC,MACA,SAgBA,YAsBI;AACJ,SAAO,eACN,MACA;GACC,GAAG;GACH,KAAK,CAAC,GAAI,SAAS,OAAO,EAAE,EAAG,GAAI,MAAM,OAAO,EAAE,CAAE;GACpD,EACD,QACA"}
package/dist/error.cjs CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  function isErrorStackTraceLimitWritable() {
5
5
  const desc = Object.getOwnPropertyDescriptor(Error, "stackTraceLimit");
6
6
  if (desc === void 0) return Object.isExtensible(Error);
7
- return Object.prototype.hasOwnProperty.call(desc, "writable") ? desc.writable : desc.set !== void 0;
7
+ return Object.hasOwn(desc, "writable") ? desc.writable : desc.set !== void 0;
8
8
  }
9
9
  /**
10
10
  * Hide internal stack frames from the error stack trace.
@@ -1 +1 @@
1
- {"version":3,"file":"error.cjs","names":["#hiddenStack"],"sources":["../src/error.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"./standard-schema\";\n// https://github.com/nodejs/node/blob/360f7cc7867b43344aac00564286b895e15f21d7/lib/internal/errors.js#L246C1-L261C2\nfunction isErrorStackTraceLimitWritable() {\n\tconst desc = Object.getOwnPropertyDescriptor(Error, \"stackTraceLimit\");\n\tif (desc === undefined) {\n\t\treturn Object.isExtensible(Error);\n\t}\n\n\treturn Object.prototype.hasOwnProperty.call(desc, \"writable\")\n\t\t? desc.writable\n\t\t: desc.set !== undefined;\n}\n\n/**\n * Hide internal stack frames from the error stack trace.\n */\nexport function hideInternalStackFrames(stack: string): string {\n\tconst lines = stack.split(\"\\n at \");\n\tif (lines.length <= 1) {\n\t\treturn stack;\n\t}\n\tlines.splice(1, 1);\n\treturn lines.join(\"\\n at \");\n}\n\n// https://github.com/nodejs/node/blob/360f7cc7867b43344aac00564286b895e15f21d7/lib/internal/errors.js#L411-L432\n/**\n * Creates a custom error class that hides stack frames.\n */\nexport function makeErrorForHideStackFrame<\n\tB extends new (\n\t\t...args: any[]\n\t) => Error,\n>(\n\tBase: B,\n\tclazz: any,\n): {\n\tnew (\n\t\t...args: ConstructorParameters<B>\n\t): InstanceType<B> & { errorStack: string | undefined };\n} {\n\tclass HideStackFramesError extends Base {\n\t\t#hiddenStack: string | undefined;\n\n\t\tconstructor(...args: any[]) {\n\t\t\tif (isErrorStackTraceLimitWritable()) {\n\t\t\t\tconst limit = Error.stackTraceLimit;\n\t\t\t\tError.stackTraceLimit = 0;\n\t\t\t\tsuper(...args);\n\t\t\t\tError.stackTraceLimit = limit;\n\t\t\t} else {\n\t\t\t\tsuper(...args);\n\t\t\t}\n\t\t\tconst stack = new Error().stack;\n\t\t\tif (stack) {\n\t\t\t\tthis.#hiddenStack = hideInternalStackFrames(\n\t\t\t\t\tstack.replace(/^Error/, this.name),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// use `getter` here to avoid the stack trace being captured by loggers\n\t\tget errorStack() {\n\t\t\treturn this.#hiddenStack;\n\t\t}\n\t}\n\n\t// This is a workaround for wpt tests that expect that the error\n\t// constructor has a `name` property of the base class.\n\tObject.defineProperty(HideStackFramesError.prototype, \"constructor\", {\n\t\tget() {\n\t\t\treturn clazz;\n\t\t},\n\t\tenumerable: false,\n\t\tconfigurable: true,\n\t});\n\n\treturn HideStackFramesError as any;\n}\n\nexport const statusCodes = {\n\tOK: 200,\n\tCREATED: 201,\n\tACCEPTED: 202,\n\tNO_CONTENT: 204,\n\tMULTIPLE_CHOICES: 300,\n\tMOVED_PERMANENTLY: 301,\n\tFOUND: 302,\n\tSEE_OTHER: 303,\n\tNOT_MODIFIED: 304,\n\tTEMPORARY_REDIRECT: 307,\n\tBAD_REQUEST: 400,\n\tUNAUTHORIZED: 401,\n\tPAYMENT_REQUIRED: 402,\n\tFORBIDDEN: 403,\n\tNOT_FOUND: 404,\n\tMETHOD_NOT_ALLOWED: 405,\n\tNOT_ACCEPTABLE: 406,\n\tPROXY_AUTHENTICATION_REQUIRED: 407,\n\tREQUEST_TIMEOUT: 408,\n\tCONFLICT: 409,\n\tGONE: 410,\n\tLENGTH_REQUIRED: 411,\n\tPRECONDITION_FAILED: 412,\n\tPAYLOAD_TOO_LARGE: 413,\n\tURI_TOO_LONG: 414,\n\tUNSUPPORTED_MEDIA_TYPE: 415,\n\tRANGE_NOT_SATISFIABLE: 416,\n\tEXPECTATION_FAILED: 417,\n\t\"I'M_A_TEAPOT\": 418,\n\tMISDIRECTED_REQUEST: 421,\n\tUNPROCESSABLE_ENTITY: 422,\n\tLOCKED: 423,\n\tFAILED_DEPENDENCY: 424,\n\tTOO_EARLY: 425,\n\tUPGRADE_REQUIRED: 426,\n\tPRECONDITION_REQUIRED: 428,\n\tTOO_MANY_REQUESTS: 429,\n\tREQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n\tUNAVAILABLE_FOR_LEGAL_REASONS: 451,\n\tINTERNAL_SERVER_ERROR: 500,\n\tNOT_IMPLEMENTED: 501,\n\tBAD_GATEWAY: 502,\n\tSERVICE_UNAVAILABLE: 503,\n\tGATEWAY_TIMEOUT: 504,\n\tHTTP_VERSION_NOT_SUPPORTED: 505,\n\tVARIANT_ALSO_NEGOTIATES: 506,\n\tINSUFFICIENT_STORAGE: 507,\n\tLOOP_DETECTED: 508,\n\tNOT_EXTENDED: 510,\n\tNETWORK_AUTHENTICATION_REQUIRED: 511,\n};\n\nexport type Status =\n\t| 100\n\t| 101\n\t| 102\n\t| 103\n\t| 200\n\t| 201\n\t| 202\n\t| 203\n\t| 204\n\t| 205\n\t| 206\n\t| 207\n\t| 208\n\t| 226\n\t| 300\n\t| 301\n\t| 302\n\t| 303\n\t| 304\n\t| 305\n\t| 306\n\t| 307\n\t| 308\n\t| 400\n\t| 401\n\t| 402\n\t| 403\n\t| 404\n\t| 405\n\t| 406\n\t| 407\n\t| 408\n\t| 409\n\t| 410\n\t| 411\n\t| 412\n\t| 413\n\t| 414\n\t| 415\n\t| 416\n\t| 417\n\t| 418\n\t| 421\n\t| 422\n\t| 423\n\t| 424\n\t| 425\n\t| 426\n\t| 428\n\t| 429\n\t| 431\n\t| 451\n\t| 500\n\t| 501\n\t| 502\n\t| 503\n\t| 504\n\t| 505\n\t| 506\n\t| 507\n\t| 508\n\t| 510\n\t| 511;\n\nclass InternalAPIError extends Error {\n\tconstructor(\n\t\tpublic status: keyof typeof statusCodes | Status = \"INTERNAL_SERVER_ERROR\",\n\t\tpublic body:\n\t\t\t| ({\n\t\t\t\t\tmessage?: string;\n\t\t\t\t\tcode?: string;\n\t\t\t\t\tcause?: unknown;\n\t\t\t } & Record<string, any>)\n\t\t\t| undefined = undefined,\n\t\tpublic headers: HeadersInit = {},\n\t\tpublic statusCode = typeof status === \"number\"\n\t\t\t? status\n\t\t\t: statusCodes[status],\n\t) {\n\t\tsuper(\n\t\t\tbody?.message,\n\t\t\tbody?.cause\n\t\t\t\t? {\n\t\t\t\t\t\tcause: body.cause,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t);\n\t\tthis.name = \"APIError\";\n\t\tthis.status = status;\n\t\tthis.headers = headers;\n\t\tthis.statusCode = statusCode;\n\t\tthis.body = body;\n\t}\n}\n\nexport class ValidationError extends InternalAPIError {\n\tconstructor(\n\t\tpublic message: string,\n\t\tpublic issues: readonly StandardSchemaV1.Issue[],\n\t) {\n\t\tsuper(400, {\n\t\t\tmessage: message,\n\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t});\n\n\t\tthis.issues = issues;\n\t}\n}\n\nexport class BetterCallError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"BetterCallError\";\n\t}\n}\n\nexport const kAPIErrorHeaderSymbol = Symbol.for(\n\t\"better-call:api-error-headers\",\n);\n\nexport type APIError = InstanceType<typeof InternalAPIError>;\nexport const APIError = makeErrorForHideStackFrame(InternalAPIError, Error);\n"],"mappings":";;;AAEA,SAAS,iCAAiC;CACzC,MAAM,OAAO,OAAO,yBAAyB,OAAO,kBAAkB;AACtE,KAAI,SAAS,OACZ,QAAO,OAAO,aAAa,MAAM;AAGlC,QAAO,OAAO,UAAU,eAAe,KAAK,MAAM,WAAW,GAC1D,KAAK,WACL,KAAK,QAAQ;;;;;AAMjB,SAAgB,wBAAwB,OAAuB;CAC9D,MAAM,QAAQ,MAAM,MAAM,YAAY;AACtC,KAAI,MAAM,UAAU,EACnB,QAAO;AAER,OAAM,OAAO,GAAG,EAAE;AAClB,QAAO,MAAM,KAAK,YAAY;;;;;AAO/B,SAAgB,2BAKf,MACA,OAKC;CACD,MAAM,6BAA6B,KAAK;EACvC;EAEA,YAAY,GAAG,MAAa;AAC3B,OAAI,gCAAgC,EAAE;IACrC,MAAM,QAAQ,MAAM;AACpB,UAAM,kBAAkB;AACxB,UAAM,GAAG,KAAK;AACd,UAAM,kBAAkB;SAExB,OAAM,GAAG,KAAK;GAEf,MAAM,yBAAQ,IAAI,OAAO,EAAC;AAC1B,OAAI,MACH,OAAKA,cAAe,wBACnB,MAAM,QAAQ,UAAU,KAAK,KAAK,CAClC;;EAKH,IAAI,aAAa;AAChB,UAAO,MAAKA;;;AAMd,QAAO,eAAe,qBAAqB,WAAW,eAAe;EACpE,MAAM;AACL,UAAO;;EAER,YAAY;EACZ,cAAc;EACd,CAAC;AAEF,QAAO;;AAGR,MAAa,cAAc;CAC1B,IAAI;CACJ,SAAS;CACT,UAAU;CACV,YAAY;CACZ,kBAAkB;CAClB,mBAAmB;CACnB,OAAO;CACP,WAAW;CACX,cAAc;CACd,oBAAoB;CACpB,aAAa;CACb,cAAc;CACd,kBAAkB;CAClB,WAAW;CACX,WAAW;CACX,oBAAoB;CACpB,gBAAgB;CAChB,+BAA+B;CAC/B,iBAAiB;CACjB,UAAU;CACV,MAAM;CACN,iBAAiB;CACjB,qBAAqB;CACrB,mBAAmB;CACnB,cAAc;CACd,wBAAwB;CACxB,uBAAuB;CACvB,oBAAoB;CACpB,gBAAgB;CAChB,qBAAqB;CACrB,sBAAsB;CACtB,QAAQ;CACR,mBAAmB;CACnB,WAAW;CACX,kBAAkB;CAClB,uBAAuB;CACvB,mBAAmB;CACnB,iCAAiC;CACjC,+BAA+B;CAC/B,uBAAuB;CACvB,iBAAiB;CACjB,aAAa;CACb,qBAAqB;CACrB,iBAAiB;CACjB,4BAA4B;CAC5B,yBAAyB;CACzB,sBAAsB;CACtB,eAAe;CACf,cAAc;CACd,iCAAiC;CACjC;AAmED,IAAM,mBAAN,cAA+B,MAAM;CACpC,YACC,AAAO,SAA4C,yBACnD,AAAO,OAMQ,QACf,AAAO,UAAuB,EAAE,EAChC,AAAO,aAAa,OAAO,WAAW,WACnC,SACA,YAAY,SACd;AACD,QACC,MAAM,SACN,MAAM,QACH,EACA,OAAO,KAAK,OACZ,GACA,OACH;EApBM;EACA;EAOA;EACA;AAYP,OAAK,OAAO;AACZ,OAAK,SAAS;AACd,OAAK,UAAU;AACf,OAAK,aAAa;AAClB,OAAK,OAAO;;;AAId,IAAa,kBAAb,cAAqC,iBAAiB;CACrD,YACC,AAAO,SACP,AAAO,QACN;AACD,QAAM,KAAK;GACD;GACT,MAAM;GACN,CAAC;EANK;EACA;AAOP,OAAK,SAAS;;;AAIhB,IAAa,kBAAb,cAAqC,MAAM;CAC1C,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAId,MAAa,wBAAwB,OAAO,IAC3C,gCACA;AAGD,MAAa,WAAW,2BAA2B,kBAAkB,MAAM"}
1
+ {"version":3,"file":"error.cjs","names":["#hiddenStack"],"sources":["../src/error.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"./standard-schema\";\n\n// https://github.com/nodejs/node/blob/360f7cc7867b43344aac00564286b895e15f21d7/lib/internal/errors.js#L246C1-L261C2\nfunction isErrorStackTraceLimitWritable() {\n\tconst desc = Object.getOwnPropertyDescriptor(Error, \"stackTraceLimit\");\n\tif (desc === undefined) {\n\t\treturn Object.isExtensible(Error);\n\t}\n\n\treturn Object.hasOwn(desc, \"writable\")\n\t\t? desc.writable\n\t\t: desc.set !== undefined;\n}\n\n/**\n * Hide internal stack frames from the error stack trace.\n */\nexport function hideInternalStackFrames(stack: string): string {\n\tconst lines = stack.split(\"\\n at \");\n\tif (lines.length <= 1) {\n\t\treturn stack;\n\t}\n\tlines.splice(1, 1);\n\treturn lines.join(\"\\n at \");\n}\n\n// https://github.com/nodejs/node/blob/360f7cc7867b43344aac00564286b895e15f21d7/lib/internal/errors.js#L411-L432\n/**\n * Creates a custom error class that hides stack frames.\n */\nexport function makeErrorForHideStackFrame<\n\tB extends new (\n\t\t...args: any[]\n\t) => Error,\n>(\n\tBase: B,\n\tclazz: any,\n): {\n\tnew (\n\t\t...args: ConstructorParameters<B>\n\t): InstanceType<B> & { errorStack: string | undefined };\n} {\n\tclass HideStackFramesError extends Base {\n\t\t#hiddenStack: string | undefined;\n\n\t\tconstructor(...args: any[]) {\n\t\t\tif (isErrorStackTraceLimitWritable()) {\n\t\t\t\tconst limit = Error.stackTraceLimit;\n\t\t\t\tError.stackTraceLimit = 0;\n\t\t\t\tsuper(...args);\n\t\t\t\tError.stackTraceLimit = limit;\n\t\t\t} else {\n\t\t\t\tsuper(...args);\n\t\t\t}\n\t\t\tconst stack = new Error().stack;\n\t\t\tif (stack) {\n\t\t\t\tthis.#hiddenStack = hideInternalStackFrames(\n\t\t\t\t\tstack.replace(/^Error/, this.name),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// use `getter` here to avoid the stack trace being captured by loggers\n\t\tget errorStack() {\n\t\t\treturn this.#hiddenStack;\n\t\t}\n\t}\n\n\t// This is a workaround for wpt tests that expect that the error\n\t// constructor has a `name` property of the base class.\n\tObject.defineProperty(HideStackFramesError.prototype, \"constructor\", {\n\t\tget() {\n\t\t\treturn clazz;\n\t\t},\n\t\tenumerable: false,\n\t\tconfigurable: true,\n\t});\n\n\treturn HideStackFramesError as any;\n}\n\nexport const statusCodes = {\n\tOK: 200,\n\tCREATED: 201,\n\tACCEPTED: 202,\n\tNO_CONTENT: 204,\n\tMULTIPLE_CHOICES: 300,\n\tMOVED_PERMANENTLY: 301,\n\tFOUND: 302,\n\tSEE_OTHER: 303,\n\tNOT_MODIFIED: 304,\n\tTEMPORARY_REDIRECT: 307,\n\tBAD_REQUEST: 400,\n\tUNAUTHORIZED: 401,\n\tPAYMENT_REQUIRED: 402,\n\tFORBIDDEN: 403,\n\tNOT_FOUND: 404,\n\tMETHOD_NOT_ALLOWED: 405,\n\tNOT_ACCEPTABLE: 406,\n\tPROXY_AUTHENTICATION_REQUIRED: 407,\n\tREQUEST_TIMEOUT: 408,\n\tCONFLICT: 409,\n\tGONE: 410,\n\tLENGTH_REQUIRED: 411,\n\tPRECONDITION_FAILED: 412,\n\tPAYLOAD_TOO_LARGE: 413,\n\tURI_TOO_LONG: 414,\n\tUNSUPPORTED_MEDIA_TYPE: 415,\n\tRANGE_NOT_SATISFIABLE: 416,\n\tEXPECTATION_FAILED: 417,\n\t\"I'M_A_TEAPOT\": 418,\n\tMISDIRECTED_REQUEST: 421,\n\tUNPROCESSABLE_ENTITY: 422,\n\tLOCKED: 423,\n\tFAILED_DEPENDENCY: 424,\n\tTOO_EARLY: 425,\n\tUPGRADE_REQUIRED: 426,\n\tPRECONDITION_REQUIRED: 428,\n\tTOO_MANY_REQUESTS: 429,\n\tREQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n\tUNAVAILABLE_FOR_LEGAL_REASONS: 451,\n\tINTERNAL_SERVER_ERROR: 500,\n\tNOT_IMPLEMENTED: 501,\n\tBAD_GATEWAY: 502,\n\tSERVICE_UNAVAILABLE: 503,\n\tGATEWAY_TIMEOUT: 504,\n\tHTTP_VERSION_NOT_SUPPORTED: 505,\n\tVARIANT_ALSO_NEGOTIATES: 506,\n\tINSUFFICIENT_STORAGE: 507,\n\tLOOP_DETECTED: 508,\n\tNOT_EXTENDED: 510,\n\tNETWORK_AUTHENTICATION_REQUIRED: 511,\n};\n\nexport type Status =\n\t| 100\n\t| 101\n\t| 102\n\t| 103\n\t| 200\n\t| 201\n\t| 202\n\t| 203\n\t| 204\n\t| 205\n\t| 206\n\t| 207\n\t| 208\n\t| 226\n\t| 300\n\t| 301\n\t| 302\n\t| 303\n\t| 304\n\t| 305\n\t| 306\n\t| 307\n\t| 308\n\t| 400\n\t| 401\n\t| 402\n\t| 403\n\t| 404\n\t| 405\n\t| 406\n\t| 407\n\t| 408\n\t| 409\n\t| 410\n\t| 411\n\t| 412\n\t| 413\n\t| 414\n\t| 415\n\t| 416\n\t| 417\n\t| 418\n\t| 421\n\t| 422\n\t| 423\n\t| 424\n\t| 425\n\t| 426\n\t| 428\n\t| 429\n\t| 431\n\t| 451\n\t| 500\n\t| 501\n\t| 502\n\t| 503\n\t| 504\n\t| 505\n\t| 506\n\t| 507\n\t| 508\n\t| 510\n\t| 511;\n\nclass InternalAPIError extends Error {\n\tconstructor(\n\t\tpublic status: keyof typeof statusCodes | Status = \"INTERNAL_SERVER_ERROR\",\n\t\tpublic body:\n\t\t\t| ({\n\t\t\t\t\tmessage?: string;\n\t\t\t\t\tcode?: string;\n\t\t\t\t\tcause?: unknown;\n\t\t\t } & Record<string, any>)\n\t\t\t| undefined = undefined,\n\t\tpublic headers: HeadersInit = {},\n\t\tpublic statusCode = typeof status === \"number\"\n\t\t\t? status\n\t\t\t: statusCodes[status],\n\t) {\n\t\tsuper(\n\t\t\tbody?.message,\n\t\t\tbody?.cause\n\t\t\t\t? {\n\t\t\t\t\t\tcause: body.cause,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t);\n\t\tthis.name = \"APIError\";\n\t\tthis.status = status;\n\t\tthis.headers = headers;\n\t\tthis.statusCode = statusCode;\n\t\tthis.body = body;\n\t}\n}\n\nexport class ValidationError extends InternalAPIError {\n\tconstructor(\n\t\tpublic message: string,\n\t\tpublic issues: readonly StandardSchemaV1.Issue[],\n\t) {\n\t\tsuper(400, {\n\t\t\tmessage: message,\n\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t});\n\n\t\tthis.issues = issues;\n\t}\n}\n\nexport class BetterCallError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"BetterCallError\";\n\t}\n}\n\nexport const kAPIErrorHeaderSymbol = Symbol.for(\n\t\"better-call:api-error-headers\",\n);\n\nexport type APIError = InstanceType<typeof InternalAPIError>;\nexport const APIError = makeErrorForHideStackFrame(InternalAPIError, Error);\n"],"mappings":";;;AAGA,SAAS,iCAAiC;CACzC,MAAM,OAAO,OAAO,yBAAyB,OAAO,kBAAkB;AACtE,KAAI,SAAS,OACZ,QAAO,OAAO,aAAa,MAAM;AAGlC,QAAO,OAAO,OAAO,MAAM,WAAW,GACnC,KAAK,WACL,KAAK,QAAQ;;;;;AAMjB,SAAgB,wBAAwB,OAAuB;CAC9D,MAAM,QAAQ,MAAM,MAAM,YAAY;AACtC,KAAI,MAAM,UAAU,EACnB,QAAO;AAER,OAAM,OAAO,GAAG,EAAE;AAClB,QAAO,MAAM,KAAK,YAAY;;;;;AAO/B,SAAgB,2BAKf,MACA,OAKC;CACD,MAAM,6BAA6B,KAAK;EACvC;EAEA,YAAY,GAAG,MAAa;AAC3B,OAAI,gCAAgC,EAAE;IACrC,MAAM,QAAQ,MAAM;AACpB,UAAM,kBAAkB;AACxB,UAAM,GAAG,KAAK;AACd,UAAM,kBAAkB;SAExB,OAAM,GAAG,KAAK;GAEf,MAAM,yBAAQ,IAAI,OAAO,EAAC;AAC1B,OAAI,MACH,OAAKA,cAAe,wBACnB,MAAM,QAAQ,UAAU,KAAK,KAAK,CAClC;;EAKH,IAAI,aAAa;AAChB,UAAO,MAAKA;;;AAMd,QAAO,eAAe,qBAAqB,WAAW,eAAe;EACpE,MAAM;AACL,UAAO;;EAER,YAAY;EACZ,cAAc;EACd,CAAC;AAEF,QAAO;;AAGR,MAAa,cAAc;CAC1B,IAAI;CACJ,SAAS;CACT,UAAU;CACV,YAAY;CACZ,kBAAkB;CAClB,mBAAmB;CACnB,OAAO;CACP,WAAW;CACX,cAAc;CACd,oBAAoB;CACpB,aAAa;CACb,cAAc;CACd,kBAAkB;CAClB,WAAW;CACX,WAAW;CACX,oBAAoB;CACpB,gBAAgB;CAChB,+BAA+B;CAC/B,iBAAiB;CACjB,UAAU;CACV,MAAM;CACN,iBAAiB;CACjB,qBAAqB;CACrB,mBAAmB;CACnB,cAAc;CACd,wBAAwB;CACxB,uBAAuB;CACvB,oBAAoB;CACpB,gBAAgB;CAChB,qBAAqB;CACrB,sBAAsB;CACtB,QAAQ;CACR,mBAAmB;CACnB,WAAW;CACX,kBAAkB;CAClB,uBAAuB;CACvB,mBAAmB;CACnB,iCAAiC;CACjC,+BAA+B;CAC/B,uBAAuB;CACvB,iBAAiB;CACjB,aAAa;CACb,qBAAqB;CACrB,iBAAiB;CACjB,4BAA4B;CAC5B,yBAAyB;CACzB,sBAAsB;CACtB,eAAe;CACf,cAAc;CACd,iCAAiC;CACjC;AAmED,IAAM,mBAAN,cAA+B,MAAM;CACpC,YACC,AAAO,SAA4C,yBACnD,AAAO,OAMQ,QACf,AAAO,UAAuB,EAAE,EAChC,AAAO,aAAa,OAAO,WAAW,WACnC,SACA,YAAY,SACd;AACD,QACC,MAAM,SACN,MAAM,QACH,EACA,OAAO,KAAK,OACZ,GACA,OACH;EApBM;EACA;EAOA;EACA;AAYP,OAAK,OAAO;AACZ,OAAK,SAAS;AACd,OAAK,UAAU;AACf,OAAK,aAAa;AAClB,OAAK,OAAO;;;AAId,IAAa,kBAAb,cAAqC,iBAAiB;CACrD,YACC,AAAO,SACP,AAAO,QACN;AACD,QAAM,KAAK;GACD;GACT,MAAM;GACN,CAAC;EANK;EACA;AAOP,OAAK,SAAS;;;AAIhB,IAAa,kBAAb,cAAqC,MAAM;CAC1C,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAId,MAAa,wBAAwB,OAAO,IAC3C,gCACA;AAGD,MAAa,WAAW,2BAA2B,kBAAkB,MAAM"}
package/dist/error.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  function isErrorStackTraceLimitWritable() {
3
3
  const desc = Object.getOwnPropertyDescriptor(Error, "stackTraceLimit");
4
4
  if (desc === void 0) return Object.isExtensible(Error);
5
- return Object.prototype.hasOwnProperty.call(desc, "writable") ? desc.writable : desc.set !== void 0;
5
+ return Object.hasOwn(desc, "writable") ? desc.writable : desc.set !== void 0;
6
6
  }
7
7
  /**
8
8
  * Hide internal stack frames from the error stack trace.
@@ -1 +1 @@
1
- {"version":3,"file":"error.mjs","names":["#hiddenStack"],"sources":["../src/error.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"./standard-schema\";\n// https://github.com/nodejs/node/blob/360f7cc7867b43344aac00564286b895e15f21d7/lib/internal/errors.js#L246C1-L261C2\nfunction isErrorStackTraceLimitWritable() {\n\tconst desc = Object.getOwnPropertyDescriptor(Error, \"stackTraceLimit\");\n\tif (desc === undefined) {\n\t\treturn Object.isExtensible(Error);\n\t}\n\n\treturn Object.prototype.hasOwnProperty.call(desc, \"writable\")\n\t\t? desc.writable\n\t\t: desc.set !== undefined;\n}\n\n/**\n * Hide internal stack frames from the error stack trace.\n */\nexport function hideInternalStackFrames(stack: string): string {\n\tconst lines = stack.split(\"\\n at \");\n\tif (lines.length <= 1) {\n\t\treturn stack;\n\t}\n\tlines.splice(1, 1);\n\treturn lines.join(\"\\n at \");\n}\n\n// https://github.com/nodejs/node/blob/360f7cc7867b43344aac00564286b895e15f21d7/lib/internal/errors.js#L411-L432\n/**\n * Creates a custom error class that hides stack frames.\n */\nexport function makeErrorForHideStackFrame<\n\tB extends new (\n\t\t...args: any[]\n\t) => Error,\n>(\n\tBase: B,\n\tclazz: any,\n): {\n\tnew (\n\t\t...args: ConstructorParameters<B>\n\t): InstanceType<B> & { errorStack: string | undefined };\n} {\n\tclass HideStackFramesError extends Base {\n\t\t#hiddenStack: string | undefined;\n\n\t\tconstructor(...args: any[]) {\n\t\t\tif (isErrorStackTraceLimitWritable()) {\n\t\t\t\tconst limit = Error.stackTraceLimit;\n\t\t\t\tError.stackTraceLimit = 0;\n\t\t\t\tsuper(...args);\n\t\t\t\tError.stackTraceLimit = limit;\n\t\t\t} else {\n\t\t\t\tsuper(...args);\n\t\t\t}\n\t\t\tconst stack = new Error().stack;\n\t\t\tif (stack) {\n\t\t\t\tthis.#hiddenStack = hideInternalStackFrames(\n\t\t\t\t\tstack.replace(/^Error/, this.name),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// use `getter` here to avoid the stack trace being captured by loggers\n\t\tget errorStack() {\n\t\t\treturn this.#hiddenStack;\n\t\t}\n\t}\n\n\t// This is a workaround for wpt tests that expect that the error\n\t// constructor has a `name` property of the base class.\n\tObject.defineProperty(HideStackFramesError.prototype, \"constructor\", {\n\t\tget() {\n\t\t\treturn clazz;\n\t\t},\n\t\tenumerable: false,\n\t\tconfigurable: true,\n\t});\n\n\treturn HideStackFramesError as any;\n}\n\nexport const statusCodes = {\n\tOK: 200,\n\tCREATED: 201,\n\tACCEPTED: 202,\n\tNO_CONTENT: 204,\n\tMULTIPLE_CHOICES: 300,\n\tMOVED_PERMANENTLY: 301,\n\tFOUND: 302,\n\tSEE_OTHER: 303,\n\tNOT_MODIFIED: 304,\n\tTEMPORARY_REDIRECT: 307,\n\tBAD_REQUEST: 400,\n\tUNAUTHORIZED: 401,\n\tPAYMENT_REQUIRED: 402,\n\tFORBIDDEN: 403,\n\tNOT_FOUND: 404,\n\tMETHOD_NOT_ALLOWED: 405,\n\tNOT_ACCEPTABLE: 406,\n\tPROXY_AUTHENTICATION_REQUIRED: 407,\n\tREQUEST_TIMEOUT: 408,\n\tCONFLICT: 409,\n\tGONE: 410,\n\tLENGTH_REQUIRED: 411,\n\tPRECONDITION_FAILED: 412,\n\tPAYLOAD_TOO_LARGE: 413,\n\tURI_TOO_LONG: 414,\n\tUNSUPPORTED_MEDIA_TYPE: 415,\n\tRANGE_NOT_SATISFIABLE: 416,\n\tEXPECTATION_FAILED: 417,\n\t\"I'M_A_TEAPOT\": 418,\n\tMISDIRECTED_REQUEST: 421,\n\tUNPROCESSABLE_ENTITY: 422,\n\tLOCKED: 423,\n\tFAILED_DEPENDENCY: 424,\n\tTOO_EARLY: 425,\n\tUPGRADE_REQUIRED: 426,\n\tPRECONDITION_REQUIRED: 428,\n\tTOO_MANY_REQUESTS: 429,\n\tREQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n\tUNAVAILABLE_FOR_LEGAL_REASONS: 451,\n\tINTERNAL_SERVER_ERROR: 500,\n\tNOT_IMPLEMENTED: 501,\n\tBAD_GATEWAY: 502,\n\tSERVICE_UNAVAILABLE: 503,\n\tGATEWAY_TIMEOUT: 504,\n\tHTTP_VERSION_NOT_SUPPORTED: 505,\n\tVARIANT_ALSO_NEGOTIATES: 506,\n\tINSUFFICIENT_STORAGE: 507,\n\tLOOP_DETECTED: 508,\n\tNOT_EXTENDED: 510,\n\tNETWORK_AUTHENTICATION_REQUIRED: 511,\n};\n\nexport type Status =\n\t| 100\n\t| 101\n\t| 102\n\t| 103\n\t| 200\n\t| 201\n\t| 202\n\t| 203\n\t| 204\n\t| 205\n\t| 206\n\t| 207\n\t| 208\n\t| 226\n\t| 300\n\t| 301\n\t| 302\n\t| 303\n\t| 304\n\t| 305\n\t| 306\n\t| 307\n\t| 308\n\t| 400\n\t| 401\n\t| 402\n\t| 403\n\t| 404\n\t| 405\n\t| 406\n\t| 407\n\t| 408\n\t| 409\n\t| 410\n\t| 411\n\t| 412\n\t| 413\n\t| 414\n\t| 415\n\t| 416\n\t| 417\n\t| 418\n\t| 421\n\t| 422\n\t| 423\n\t| 424\n\t| 425\n\t| 426\n\t| 428\n\t| 429\n\t| 431\n\t| 451\n\t| 500\n\t| 501\n\t| 502\n\t| 503\n\t| 504\n\t| 505\n\t| 506\n\t| 507\n\t| 508\n\t| 510\n\t| 511;\n\nclass InternalAPIError extends Error {\n\tconstructor(\n\t\tpublic status: keyof typeof statusCodes | Status = \"INTERNAL_SERVER_ERROR\",\n\t\tpublic body:\n\t\t\t| ({\n\t\t\t\t\tmessage?: string;\n\t\t\t\t\tcode?: string;\n\t\t\t\t\tcause?: unknown;\n\t\t\t } & Record<string, any>)\n\t\t\t| undefined = undefined,\n\t\tpublic headers: HeadersInit = {},\n\t\tpublic statusCode = typeof status === \"number\"\n\t\t\t? status\n\t\t\t: statusCodes[status],\n\t) {\n\t\tsuper(\n\t\t\tbody?.message,\n\t\t\tbody?.cause\n\t\t\t\t? {\n\t\t\t\t\t\tcause: body.cause,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t);\n\t\tthis.name = \"APIError\";\n\t\tthis.status = status;\n\t\tthis.headers = headers;\n\t\tthis.statusCode = statusCode;\n\t\tthis.body = body;\n\t}\n}\n\nexport class ValidationError extends InternalAPIError {\n\tconstructor(\n\t\tpublic message: string,\n\t\tpublic issues: readonly StandardSchemaV1.Issue[],\n\t) {\n\t\tsuper(400, {\n\t\t\tmessage: message,\n\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t});\n\n\t\tthis.issues = issues;\n\t}\n}\n\nexport class BetterCallError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"BetterCallError\";\n\t}\n}\n\nexport const kAPIErrorHeaderSymbol = Symbol.for(\n\t\"better-call:api-error-headers\",\n);\n\nexport type APIError = InstanceType<typeof InternalAPIError>;\nexport const APIError = makeErrorForHideStackFrame(InternalAPIError, Error);\n"],"mappings":";AAEA,SAAS,iCAAiC;CACzC,MAAM,OAAO,OAAO,yBAAyB,OAAO,kBAAkB;AACtE,KAAI,SAAS,OACZ,QAAO,OAAO,aAAa,MAAM;AAGlC,QAAO,OAAO,UAAU,eAAe,KAAK,MAAM,WAAW,GAC1D,KAAK,WACL,KAAK,QAAQ;;;;;AAMjB,SAAgB,wBAAwB,OAAuB;CAC9D,MAAM,QAAQ,MAAM,MAAM,YAAY;AACtC,KAAI,MAAM,UAAU,EACnB,QAAO;AAER,OAAM,OAAO,GAAG,EAAE;AAClB,QAAO,MAAM,KAAK,YAAY;;;;;AAO/B,SAAgB,2BAKf,MACA,OAKC;CACD,MAAM,6BAA6B,KAAK;EACvC;EAEA,YAAY,GAAG,MAAa;AAC3B,OAAI,gCAAgC,EAAE;IACrC,MAAM,QAAQ,MAAM;AACpB,UAAM,kBAAkB;AACxB,UAAM,GAAG,KAAK;AACd,UAAM,kBAAkB;SAExB,OAAM,GAAG,KAAK;GAEf,MAAM,yBAAQ,IAAI,OAAO,EAAC;AAC1B,OAAI,MACH,OAAKA,cAAe,wBACnB,MAAM,QAAQ,UAAU,KAAK,KAAK,CAClC;;EAKH,IAAI,aAAa;AAChB,UAAO,MAAKA;;;AAMd,QAAO,eAAe,qBAAqB,WAAW,eAAe;EACpE,MAAM;AACL,UAAO;;EAER,YAAY;EACZ,cAAc;EACd,CAAC;AAEF,QAAO;;AAGR,MAAa,cAAc;CAC1B,IAAI;CACJ,SAAS;CACT,UAAU;CACV,YAAY;CACZ,kBAAkB;CAClB,mBAAmB;CACnB,OAAO;CACP,WAAW;CACX,cAAc;CACd,oBAAoB;CACpB,aAAa;CACb,cAAc;CACd,kBAAkB;CAClB,WAAW;CACX,WAAW;CACX,oBAAoB;CACpB,gBAAgB;CAChB,+BAA+B;CAC/B,iBAAiB;CACjB,UAAU;CACV,MAAM;CACN,iBAAiB;CACjB,qBAAqB;CACrB,mBAAmB;CACnB,cAAc;CACd,wBAAwB;CACxB,uBAAuB;CACvB,oBAAoB;CACpB,gBAAgB;CAChB,qBAAqB;CACrB,sBAAsB;CACtB,QAAQ;CACR,mBAAmB;CACnB,WAAW;CACX,kBAAkB;CAClB,uBAAuB;CACvB,mBAAmB;CACnB,iCAAiC;CACjC,+BAA+B;CAC/B,uBAAuB;CACvB,iBAAiB;CACjB,aAAa;CACb,qBAAqB;CACrB,iBAAiB;CACjB,4BAA4B;CAC5B,yBAAyB;CACzB,sBAAsB;CACtB,eAAe;CACf,cAAc;CACd,iCAAiC;CACjC;AAmED,IAAM,mBAAN,cAA+B,MAAM;CACpC,YACC,AAAO,SAA4C,yBACnD,AAAO,OAMQ,QACf,AAAO,UAAuB,EAAE,EAChC,AAAO,aAAa,OAAO,WAAW,WACnC,SACA,YAAY,SACd;AACD,QACC,MAAM,SACN,MAAM,QACH,EACA,OAAO,KAAK,OACZ,GACA,OACH;EApBM;EACA;EAOA;EACA;AAYP,OAAK,OAAO;AACZ,OAAK,SAAS;AACd,OAAK,UAAU;AACf,OAAK,aAAa;AAClB,OAAK,OAAO;;;AAId,IAAa,kBAAb,cAAqC,iBAAiB;CACrD,YACC,AAAO,SACP,AAAO,QACN;AACD,QAAM,KAAK;GACD;GACT,MAAM;GACN,CAAC;EANK;EACA;AAOP,OAAK,SAAS;;;AAIhB,IAAa,kBAAb,cAAqC,MAAM;CAC1C,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAId,MAAa,wBAAwB,OAAO,IAC3C,gCACA;AAGD,MAAa,WAAW,2BAA2B,kBAAkB,MAAM"}
1
+ {"version":3,"file":"error.mjs","names":["#hiddenStack"],"sources":["../src/error.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"./standard-schema\";\n\n// https://github.com/nodejs/node/blob/360f7cc7867b43344aac00564286b895e15f21d7/lib/internal/errors.js#L246C1-L261C2\nfunction isErrorStackTraceLimitWritable() {\n\tconst desc = Object.getOwnPropertyDescriptor(Error, \"stackTraceLimit\");\n\tif (desc === undefined) {\n\t\treturn Object.isExtensible(Error);\n\t}\n\n\treturn Object.hasOwn(desc, \"writable\")\n\t\t? desc.writable\n\t\t: desc.set !== undefined;\n}\n\n/**\n * Hide internal stack frames from the error stack trace.\n */\nexport function hideInternalStackFrames(stack: string): string {\n\tconst lines = stack.split(\"\\n at \");\n\tif (lines.length <= 1) {\n\t\treturn stack;\n\t}\n\tlines.splice(1, 1);\n\treturn lines.join(\"\\n at \");\n}\n\n// https://github.com/nodejs/node/blob/360f7cc7867b43344aac00564286b895e15f21d7/lib/internal/errors.js#L411-L432\n/**\n * Creates a custom error class that hides stack frames.\n */\nexport function makeErrorForHideStackFrame<\n\tB extends new (\n\t\t...args: any[]\n\t) => Error,\n>(\n\tBase: B,\n\tclazz: any,\n): {\n\tnew (\n\t\t...args: ConstructorParameters<B>\n\t): InstanceType<B> & { errorStack: string | undefined };\n} {\n\tclass HideStackFramesError extends Base {\n\t\t#hiddenStack: string | undefined;\n\n\t\tconstructor(...args: any[]) {\n\t\t\tif (isErrorStackTraceLimitWritable()) {\n\t\t\t\tconst limit = Error.stackTraceLimit;\n\t\t\t\tError.stackTraceLimit = 0;\n\t\t\t\tsuper(...args);\n\t\t\t\tError.stackTraceLimit = limit;\n\t\t\t} else {\n\t\t\t\tsuper(...args);\n\t\t\t}\n\t\t\tconst stack = new Error().stack;\n\t\t\tif (stack) {\n\t\t\t\tthis.#hiddenStack = hideInternalStackFrames(\n\t\t\t\t\tstack.replace(/^Error/, this.name),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// use `getter` here to avoid the stack trace being captured by loggers\n\t\tget errorStack() {\n\t\t\treturn this.#hiddenStack;\n\t\t}\n\t}\n\n\t// This is a workaround for wpt tests that expect that the error\n\t// constructor has a `name` property of the base class.\n\tObject.defineProperty(HideStackFramesError.prototype, \"constructor\", {\n\t\tget() {\n\t\t\treturn clazz;\n\t\t},\n\t\tenumerable: false,\n\t\tconfigurable: true,\n\t});\n\n\treturn HideStackFramesError as any;\n}\n\nexport const statusCodes = {\n\tOK: 200,\n\tCREATED: 201,\n\tACCEPTED: 202,\n\tNO_CONTENT: 204,\n\tMULTIPLE_CHOICES: 300,\n\tMOVED_PERMANENTLY: 301,\n\tFOUND: 302,\n\tSEE_OTHER: 303,\n\tNOT_MODIFIED: 304,\n\tTEMPORARY_REDIRECT: 307,\n\tBAD_REQUEST: 400,\n\tUNAUTHORIZED: 401,\n\tPAYMENT_REQUIRED: 402,\n\tFORBIDDEN: 403,\n\tNOT_FOUND: 404,\n\tMETHOD_NOT_ALLOWED: 405,\n\tNOT_ACCEPTABLE: 406,\n\tPROXY_AUTHENTICATION_REQUIRED: 407,\n\tREQUEST_TIMEOUT: 408,\n\tCONFLICT: 409,\n\tGONE: 410,\n\tLENGTH_REQUIRED: 411,\n\tPRECONDITION_FAILED: 412,\n\tPAYLOAD_TOO_LARGE: 413,\n\tURI_TOO_LONG: 414,\n\tUNSUPPORTED_MEDIA_TYPE: 415,\n\tRANGE_NOT_SATISFIABLE: 416,\n\tEXPECTATION_FAILED: 417,\n\t\"I'M_A_TEAPOT\": 418,\n\tMISDIRECTED_REQUEST: 421,\n\tUNPROCESSABLE_ENTITY: 422,\n\tLOCKED: 423,\n\tFAILED_DEPENDENCY: 424,\n\tTOO_EARLY: 425,\n\tUPGRADE_REQUIRED: 426,\n\tPRECONDITION_REQUIRED: 428,\n\tTOO_MANY_REQUESTS: 429,\n\tREQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n\tUNAVAILABLE_FOR_LEGAL_REASONS: 451,\n\tINTERNAL_SERVER_ERROR: 500,\n\tNOT_IMPLEMENTED: 501,\n\tBAD_GATEWAY: 502,\n\tSERVICE_UNAVAILABLE: 503,\n\tGATEWAY_TIMEOUT: 504,\n\tHTTP_VERSION_NOT_SUPPORTED: 505,\n\tVARIANT_ALSO_NEGOTIATES: 506,\n\tINSUFFICIENT_STORAGE: 507,\n\tLOOP_DETECTED: 508,\n\tNOT_EXTENDED: 510,\n\tNETWORK_AUTHENTICATION_REQUIRED: 511,\n};\n\nexport type Status =\n\t| 100\n\t| 101\n\t| 102\n\t| 103\n\t| 200\n\t| 201\n\t| 202\n\t| 203\n\t| 204\n\t| 205\n\t| 206\n\t| 207\n\t| 208\n\t| 226\n\t| 300\n\t| 301\n\t| 302\n\t| 303\n\t| 304\n\t| 305\n\t| 306\n\t| 307\n\t| 308\n\t| 400\n\t| 401\n\t| 402\n\t| 403\n\t| 404\n\t| 405\n\t| 406\n\t| 407\n\t| 408\n\t| 409\n\t| 410\n\t| 411\n\t| 412\n\t| 413\n\t| 414\n\t| 415\n\t| 416\n\t| 417\n\t| 418\n\t| 421\n\t| 422\n\t| 423\n\t| 424\n\t| 425\n\t| 426\n\t| 428\n\t| 429\n\t| 431\n\t| 451\n\t| 500\n\t| 501\n\t| 502\n\t| 503\n\t| 504\n\t| 505\n\t| 506\n\t| 507\n\t| 508\n\t| 510\n\t| 511;\n\nclass InternalAPIError extends Error {\n\tconstructor(\n\t\tpublic status: keyof typeof statusCodes | Status = \"INTERNAL_SERVER_ERROR\",\n\t\tpublic body:\n\t\t\t| ({\n\t\t\t\t\tmessage?: string;\n\t\t\t\t\tcode?: string;\n\t\t\t\t\tcause?: unknown;\n\t\t\t } & Record<string, any>)\n\t\t\t| undefined = undefined,\n\t\tpublic headers: HeadersInit = {},\n\t\tpublic statusCode = typeof status === \"number\"\n\t\t\t? status\n\t\t\t: statusCodes[status],\n\t) {\n\t\tsuper(\n\t\t\tbody?.message,\n\t\t\tbody?.cause\n\t\t\t\t? {\n\t\t\t\t\t\tcause: body.cause,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t);\n\t\tthis.name = \"APIError\";\n\t\tthis.status = status;\n\t\tthis.headers = headers;\n\t\tthis.statusCode = statusCode;\n\t\tthis.body = body;\n\t}\n}\n\nexport class ValidationError extends InternalAPIError {\n\tconstructor(\n\t\tpublic message: string,\n\t\tpublic issues: readonly StandardSchemaV1.Issue[],\n\t) {\n\t\tsuper(400, {\n\t\t\tmessage: message,\n\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t});\n\n\t\tthis.issues = issues;\n\t}\n}\n\nexport class BetterCallError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"BetterCallError\";\n\t}\n}\n\nexport const kAPIErrorHeaderSymbol = Symbol.for(\n\t\"better-call:api-error-headers\",\n);\n\nexport type APIError = InstanceType<typeof InternalAPIError>;\nexport const APIError = makeErrorForHideStackFrame(InternalAPIError, Error);\n"],"mappings":";AAGA,SAAS,iCAAiC;CACzC,MAAM,OAAO,OAAO,yBAAyB,OAAO,kBAAkB;AACtE,KAAI,SAAS,OACZ,QAAO,OAAO,aAAa,MAAM;AAGlC,QAAO,OAAO,OAAO,MAAM,WAAW,GACnC,KAAK,WACL,KAAK,QAAQ;;;;;AAMjB,SAAgB,wBAAwB,OAAuB;CAC9D,MAAM,QAAQ,MAAM,MAAM,YAAY;AACtC,KAAI,MAAM,UAAU,EACnB,QAAO;AAER,OAAM,OAAO,GAAG,EAAE;AAClB,QAAO,MAAM,KAAK,YAAY;;;;;AAO/B,SAAgB,2BAKf,MACA,OAKC;CACD,MAAM,6BAA6B,KAAK;EACvC;EAEA,YAAY,GAAG,MAAa;AAC3B,OAAI,gCAAgC,EAAE;IACrC,MAAM,QAAQ,MAAM;AACpB,UAAM,kBAAkB;AACxB,UAAM,GAAG,KAAK;AACd,UAAM,kBAAkB;SAExB,OAAM,GAAG,KAAK;GAEf,MAAM,yBAAQ,IAAI,OAAO,EAAC;AAC1B,OAAI,MACH,OAAKA,cAAe,wBACnB,MAAM,QAAQ,UAAU,KAAK,KAAK,CAClC;;EAKH,IAAI,aAAa;AAChB,UAAO,MAAKA;;;AAMd,QAAO,eAAe,qBAAqB,WAAW,eAAe;EACpE,MAAM;AACL,UAAO;;EAER,YAAY;EACZ,cAAc;EACd,CAAC;AAEF,QAAO;;AAGR,MAAa,cAAc;CAC1B,IAAI;CACJ,SAAS;CACT,UAAU;CACV,YAAY;CACZ,kBAAkB;CAClB,mBAAmB;CACnB,OAAO;CACP,WAAW;CACX,cAAc;CACd,oBAAoB;CACpB,aAAa;CACb,cAAc;CACd,kBAAkB;CAClB,WAAW;CACX,WAAW;CACX,oBAAoB;CACpB,gBAAgB;CAChB,+BAA+B;CAC/B,iBAAiB;CACjB,UAAU;CACV,MAAM;CACN,iBAAiB;CACjB,qBAAqB;CACrB,mBAAmB;CACnB,cAAc;CACd,wBAAwB;CACxB,uBAAuB;CACvB,oBAAoB;CACpB,gBAAgB;CAChB,qBAAqB;CACrB,sBAAsB;CACtB,QAAQ;CACR,mBAAmB;CACnB,WAAW;CACX,kBAAkB;CAClB,uBAAuB;CACvB,mBAAmB;CACnB,iCAAiC;CACjC,+BAA+B;CAC/B,uBAAuB;CACvB,iBAAiB;CACjB,aAAa;CACb,qBAAqB;CACrB,iBAAiB;CACjB,4BAA4B;CAC5B,yBAAyB;CACzB,sBAAsB;CACtB,eAAe;CACf,cAAc;CACd,iCAAiC;CACjC;AAmED,IAAM,mBAAN,cAA+B,MAAM;CACpC,YACC,AAAO,SAA4C,yBACnD,AAAO,OAMQ,QACf,AAAO,UAAuB,EAAE,EAChC,AAAO,aAAa,OAAO,WAAW,WACnC,SACA,YAAY,SACd;AACD,QACC,MAAM,SACN,MAAM,QACH,EACA,OAAO,KAAK,OACZ,GACA,OACH;EApBM;EACA;EAOA;EACA;AAYP,OAAK,OAAO;AACZ,OAAK,SAAS;AACd,OAAK,UAAU;AACf,OAAK,aAAa;AAClB,OAAK,OAAO;;;AAId,IAAa,kBAAb,cAAqC,iBAAiB;CACrD,YACC,AAAO,SACP,AAAO,QACN;AACD,QAAM,KAAK;GACD;GACT,MAAM;GACN,CAAC;EANK;EACA;AAOP,OAAK,SAAS;;;AAIhB,IAAa,kBAAb,cAAqC,MAAM;CAC1C,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAId,MAAa,wBAAwB,OAAO,IAC3C,gCACA;AAGD,MAAa,WAAW,2BAA2B,kBAAkB,MAAM"}
package/dist/helper.d.cts CHANGED
@@ -1,12 +1,11 @@
1
1
  //#region src/helper.d.ts
2
2
  type RequiredKeysOf<BaseType extends object> = Exclude<{ [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> ? Key : never }[keyof BaseType], undefined>;
3
3
  type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never ? false : true;
4
- type Prettify<T> = { [K in keyof T]: T[K] } & {};
4
+ type Prettify<T> = 0 extends 1 & T ? any : { [K in keyof T]: T[K] } & {};
5
5
  type IsEmptyObject<T> = keyof T extends never ? true : false;
6
6
  type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends ((mergedIntersection: infer Intersection) => void) ? Intersection & Union : never;
7
- type MergeObject<T extends Record<string, any> | never, S extends Record<string, any> | never> = T extends never ? S : S extends never ? T : T & S;
8
7
  type InferParamPath<Path> = Path extends `${infer _Start}:${infer Param}/${infer Rest}` ? { [K in Param | keyof InferParamPath<Rest>]: string } : Path extends `${infer _Start}:${infer Param}` ? { [K in Param]: string } : Path extends `${infer _Start}/${infer Rest}` ? InferParamPath<Rest> : {};
9
8
  type InferParamWildCard<Path> = Path extends `${infer _Start}/*:${infer Param}/${infer Rest}` | `${infer _Start}/**:${infer Param}/${infer Rest}` ? { [K in Param | keyof InferParamPath<Rest>]: string } : Path extends `${infer _Start}/*` ? { [K in "_"]: string } : Path extends `${infer _Start}/${infer Rest}` ? InferParamWildCard<Rest> : {};
10
9
  //#endregion
11
- export { HasRequiredKeys, InferParamPath, InferParamWildCard, IsEmptyObject, MergeObject, Prettify, RequiredKeysOf, UnionToIntersection };
10
+ export { HasRequiredKeys, InferParamPath, InferParamWildCard, IsEmptyObject, Prettify, UnionToIntersection };
12
11
  //# sourceMappingURL=helper.d.cts.map
package/dist/helper.d.mts CHANGED
@@ -1,12 +1,11 @@
1
1
  //#region src/helper.d.ts
2
2
  type RequiredKeysOf<BaseType extends object> = Exclude<{ [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> ? Key : never }[keyof BaseType], undefined>;
3
3
  type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never ? false : true;
4
- type Prettify<T> = { [K in keyof T]: T[K] } & {};
4
+ type Prettify<T> = 0 extends 1 & T ? any : { [K in keyof T]: T[K] } & {};
5
5
  type IsEmptyObject<T> = keyof T extends never ? true : false;
6
6
  type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends ((mergedIntersection: infer Intersection) => void) ? Intersection & Union : never;
7
- type MergeObject<T extends Record<string, any> | never, S extends Record<string, any> | never> = T extends never ? S : S extends never ? T : T & S;
8
7
  type InferParamPath<Path> = Path extends `${infer _Start}:${infer Param}/${infer Rest}` ? { [K in Param | keyof InferParamPath<Rest>]: string } : Path extends `${infer _Start}:${infer Param}` ? { [K in Param]: string } : Path extends `${infer _Start}/${infer Rest}` ? InferParamPath<Rest> : {};
9
8
  type InferParamWildCard<Path> = Path extends `${infer _Start}/*:${infer Param}/${infer Rest}` | `${infer _Start}/**:${infer Param}/${infer Rest}` ? { [K in Param | keyof InferParamPath<Rest>]: string } : Path extends `${infer _Start}/*` ? { [K in "_"]: string } : Path extends `${infer _Start}/${infer Rest}` ? InferParamWildCard<Rest> : {};
10
9
  //#endregion
11
- export { HasRequiredKeys, InferParamPath, InferParamWildCard, IsEmptyObject, MergeObject, Prettify, RequiredKeysOf, UnionToIntersection };
10
+ export { HasRequiredKeys, InferParamPath, InferParamWildCard, IsEmptyObject, Prettify, UnionToIntersection };
12
11
  //# sourceMappingURL=helper.d.mts.map
package/dist/index.cjs CHANGED
@@ -1,8 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_error = require('./error.cjs');
3
- const require_to_response = require('./to-response.cjs');
4
3
  const require_cookies = require('./cookies.cjs');
5
- const require_context = require('./context.cjs');
4
+ const require_to_response = require('./to-response.cjs');
6
5
  const require_endpoint = require('./endpoint.cjs');
7
6
  const require_middleware = require('./middleware.cjs');
8
7
  const require_openapi = require('./openapi.cjs');
@@ -12,17 +11,11 @@ exports.APIError = require_error.APIError;
12
11
  exports.BetterCallError = require_error.BetterCallError;
13
12
  exports.ValidationError = require_error.ValidationError;
14
13
  exports.createEndpoint = require_endpoint.createEndpoint;
15
- exports.createInternalContext = require_context.createInternalContext;
16
14
  exports.createMiddleware = require_middleware.createMiddleware;
17
15
  exports.createRouter = require_router.createRouter;
18
- exports.generator = require_openapi.generator;
19
- exports.getCookieKey = require_cookies.getCookieKey;
20
- exports.getHTML = require_openapi.getHTML;
21
- exports.hideInternalStackFrames = require_error.hideInternalStackFrames;
16
+ exports.generateOpenAPI = require_openapi.generator;
17
+ exports.getOpenAPIHTML = require_openapi.getHTML;
22
18
  exports.kAPIErrorHeaderSymbol = require_error.kAPIErrorHeaderSymbol;
23
- exports.makeErrorForHideStackFrame = require_error.makeErrorForHideStackFrame;
24
- exports.parseCookies = require_cookies.parseCookies;
25
- exports.serializeCookie = require_cookies.serializeCookie;
26
19
  exports.serializeSignedCookie = require_cookies.serializeSignedCookie;
27
20
  exports.statusCodes = require_error.statusCodes;
28
21
  exports.toResponse = require_to_response.toResponse;
package/dist/index.d.cts CHANGED
@@ -1,11 +1,12 @@
1
- import { HasRequiredKeys, InferParamPath, InferParamWildCard, IsEmptyObject, MergeObject, Prettify, RequiredKeysOf, UnionToIntersection } from "./helper.cjs";
1
+ import { CookieOptions, CookiePrefixOptions, serializeSignedCookie } from "./cookies.cjs";
2
2
  import { StandardSchemaV1 } from "./standard-schema.cjs";
3
- import { APIError, BetterCallError, Status, ValidationError, hideInternalStackFrames, kAPIErrorHeaderSymbol, makeErrorForHideStackFrame, statusCodes } from "./error.cjs";
4
- import { CookieOptions, CookiePrefixOptions, getCookieKey, parseCookies, serializeCookie, serializeSignedCookie } from "./cookies.cjs";
5
- import { HTTPMethod, InferBody, InferBodyInput, InferHeaders, InferHeadersInput, InferInputMethod, InferMethod, InferMiddlewareBody, InferMiddlewareQuery, InferParam, InferParamInput, InferQuery, InferQueryInput, InferRequest, InferRequestInput, InferUse, InputContext, Method, createInternalContext } from "./context.cjs";
6
- import { Middleware, MiddlewareContext, MiddlewareInputContext, MiddlewareOptions, MiddlewareResponse, createMiddleware } from "./middleware.cjs";
7
- import { OpenAPIParameter, OpenAPISchemaType, Path, generator, getHTML } from "./openapi.cjs";
8
- import { Endpoint, EndpointBaseOptions, EndpointBodyMethodOptions, EndpointContext, EndpointHandler, EndpointOptions, StrictEndpoint, createEndpoint } from "./endpoint.cjs";
3
+ import { APIError, BetterCallError, Status, ValidationError, kAPIErrorHeaderSymbol, statusCodes } from "./error.cjs";
4
+ import { Prettify } from "./helper.cjs";
5
+ import { HTTPMethod, InputContext, ResolveBodyInput, ResolveErrorInput, ResolveQueryInput } from "./types.cjs";
6
+ import { Middleware, MiddlewareContext, createMiddleware } from "./middleware.cjs";
7
+ import { EndpointContext } from "./context.cjs";
8
+ import { OpenAPIParameter, OpenAPISchemaType, generator, getHTML } from "./openapi.cjs";
9
+ import { Endpoint, EndpointMetadata, EndpointRuntimeOptions, createEndpoint } from "./endpoint.cjs";
9
10
  import { Router, RouterConfig, createRouter } from "./router.cjs";
10
11
  import { JSONResponse, toResponse } from "./to-response.cjs";
11
- export { APIError, BetterCallError, CookieOptions, CookiePrefixOptions, Endpoint, EndpointBaseOptions, EndpointBodyMethodOptions, EndpointContext, EndpointHandler, EndpointOptions, HTTPMethod, HasRequiredKeys, InferBody, InferBodyInput, InferHeaders, InferHeadersInput, InferInputMethod, InferMethod, InferMiddlewareBody, InferMiddlewareQuery, InferParam, InferParamInput, InferParamPath, InferParamWildCard, InferQuery, InferQueryInput, InferRequest, InferRequestInput, InferUse, InputContext, IsEmptyObject, JSONResponse, MergeObject, Method, Middleware, MiddlewareContext, MiddlewareInputContext, MiddlewareOptions, MiddlewareResponse, OpenAPIParameter, OpenAPISchemaType, Path, Prettify, RequiredKeysOf, Router, RouterConfig, StandardSchemaV1, Status, StrictEndpoint, UnionToIntersection, ValidationError, createEndpoint, createInternalContext, createMiddleware, createRouter, generator, getCookieKey, getHTML, hideInternalStackFrames, kAPIErrorHeaderSymbol, makeErrorForHideStackFrame, parseCookies, serializeCookie, serializeSignedCookie, statusCodes, toResponse };
12
+ export { APIError, BetterCallError, type CookieOptions, type CookiePrefixOptions, type Endpoint, type EndpointContext, type EndpointMetadata, type EndpointRuntimeOptions, type HTTPMethod, type InputContext, type JSONResponse, type Middleware, type MiddlewareContext, type OpenAPIParameter, type OpenAPISchemaType, type Prettify, type ResolveBodyInput, type ResolveErrorInput, type ResolveQueryInput, type Router, type RouterConfig, type StandardSchemaV1, type Status, ValidationError, createEndpoint, createMiddleware, createRouter, generator as generateOpenAPI, getHTML as getOpenAPIHTML, kAPIErrorHeaderSymbol, serializeSignedCookie, statusCodes, toResponse };
package/dist/index.d.mts CHANGED
@@ -1,11 +1,12 @@
1
- import { HasRequiredKeys, InferParamPath, InferParamWildCard, IsEmptyObject, MergeObject, Prettify, RequiredKeysOf, UnionToIntersection } from "./helper.mjs";
1
+ import { CookieOptions, CookiePrefixOptions, serializeSignedCookie } from "./cookies.mjs";
2
2
  import { StandardSchemaV1 } from "./standard-schema.mjs";
3
- import { APIError, BetterCallError, Status, ValidationError, hideInternalStackFrames, kAPIErrorHeaderSymbol, makeErrorForHideStackFrame, statusCodes } from "./error.mjs";
4
- import { CookieOptions, CookiePrefixOptions, getCookieKey, parseCookies, serializeCookie, serializeSignedCookie } from "./cookies.mjs";
5
- import { HTTPMethod, InferBody, InferBodyInput, InferHeaders, InferHeadersInput, InferInputMethod, InferMethod, InferMiddlewareBody, InferMiddlewareQuery, InferParam, InferParamInput, InferQuery, InferQueryInput, InferRequest, InferRequestInput, InferUse, InputContext, Method, createInternalContext } from "./context.mjs";
6
- import { Middleware, MiddlewareContext, MiddlewareInputContext, MiddlewareOptions, MiddlewareResponse, createMiddleware } from "./middleware.mjs";
7
- import { OpenAPIParameter, OpenAPISchemaType, Path, generator, getHTML } from "./openapi.mjs";
8
- import { Endpoint, EndpointBaseOptions, EndpointBodyMethodOptions, EndpointContext, EndpointHandler, EndpointOptions, StrictEndpoint, createEndpoint } from "./endpoint.mjs";
3
+ import { APIError, BetterCallError, Status, ValidationError, kAPIErrorHeaderSymbol, statusCodes } from "./error.mjs";
4
+ import { Prettify } from "./helper.mjs";
5
+ import { HTTPMethod, InputContext, ResolveBodyInput, ResolveErrorInput, ResolveQueryInput } from "./types.mjs";
6
+ import { Middleware, MiddlewareContext, createMiddleware } from "./middleware.mjs";
7
+ import { EndpointContext } from "./context.mjs";
8
+ import { OpenAPIParameter, OpenAPISchemaType, generator, getHTML } from "./openapi.mjs";
9
+ import { Endpoint, EndpointMetadata, EndpointRuntimeOptions, createEndpoint } from "./endpoint.mjs";
9
10
  import { Router, RouterConfig, createRouter } from "./router.mjs";
10
11
  import { JSONResponse, toResponse } from "./to-response.mjs";
11
- export { APIError, BetterCallError, CookieOptions, CookiePrefixOptions, Endpoint, EndpointBaseOptions, EndpointBodyMethodOptions, EndpointContext, EndpointHandler, EndpointOptions, HTTPMethod, HasRequiredKeys, InferBody, InferBodyInput, InferHeaders, InferHeadersInput, InferInputMethod, InferMethod, InferMiddlewareBody, InferMiddlewareQuery, InferParam, InferParamInput, InferParamPath, InferParamWildCard, InferQuery, InferQueryInput, InferRequest, InferRequestInput, InferUse, InputContext, IsEmptyObject, JSONResponse, MergeObject, Method, Middleware, MiddlewareContext, MiddlewareInputContext, MiddlewareOptions, MiddlewareResponse, OpenAPIParameter, OpenAPISchemaType, Path, Prettify, RequiredKeysOf, Router, RouterConfig, StandardSchemaV1, Status, StrictEndpoint, UnionToIntersection, ValidationError, createEndpoint, createInternalContext, createMiddleware, createRouter, generator, getCookieKey, getHTML, hideInternalStackFrames, kAPIErrorHeaderSymbol, makeErrorForHideStackFrame, parseCookies, serializeCookie, serializeSignedCookie, statusCodes, toResponse };
12
+ export { APIError, BetterCallError, type CookieOptions, type CookiePrefixOptions, type Endpoint, type EndpointContext, type EndpointMetadata, type EndpointRuntimeOptions, type HTTPMethod, type InputContext, type JSONResponse, type Middleware, type MiddlewareContext, type OpenAPIParameter, type OpenAPISchemaType, type Prettify, type ResolveBodyInput, type ResolveErrorInput, type ResolveQueryInput, type Router, type RouterConfig, type StandardSchemaV1, type Status, ValidationError, createEndpoint, createMiddleware, createRouter, generator as generateOpenAPI, getHTML as getOpenAPIHTML, kAPIErrorHeaderSymbol, serializeSignedCookie, statusCodes, toResponse };
package/dist/index.mjs CHANGED
@@ -1,10 +1,9 @@
1
- import { APIError, BetterCallError, ValidationError, hideInternalStackFrames, kAPIErrorHeaderSymbol, makeErrorForHideStackFrame, statusCodes } from "./error.mjs";
1
+ import { APIError, BetterCallError, ValidationError, kAPIErrorHeaderSymbol, statusCodes } from "./error.mjs";
2
+ import { serializeSignedCookie } from "./cookies.mjs";
2
3
  import { toResponse } from "./to-response.mjs";
3
- import { getCookieKey, parseCookies, serializeCookie, serializeSignedCookie } from "./cookies.mjs";
4
- import { createInternalContext } from "./context.mjs";
5
4
  import { createEndpoint } from "./endpoint.mjs";
6
5
  import { createMiddleware } from "./middleware.mjs";
7
6
  import { generator, getHTML } from "./openapi.mjs";
8
7
  import { createRouter } from "./router.mjs";
9
8
 
10
- export { APIError, BetterCallError, ValidationError, createEndpoint, createInternalContext, createMiddleware, createRouter, generator, getCookieKey, getHTML, hideInternalStackFrames, kAPIErrorHeaderSymbol, makeErrorForHideStackFrame, parseCookies, serializeCookie, serializeSignedCookie, statusCodes, toResponse };
9
+ export { APIError, BetterCallError, ValidationError, createEndpoint, createMiddleware, createRouter, generator as generateOpenAPI, getHTML as getOpenAPIHTML, kAPIErrorHeaderSymbol, serializeSignedCookie, statusCodes, toResponse };
@@ -1,20 +1,17 @@
1
1
  const require_error = require('./error.cjs');
2
2
  const require_utils = require('./utils.cjs');
3
3
  const require_context = require('./context.cjs');
4
- require('./endpoint.cjs');
5
4
 
6
5
  //#region src/middleware.ts
7
- function createMiddleware(optionsOrHandler, handler) {
6
+ function createMiddleware(handler) {
8
7
  const internalHandler = async (inputCtx) => {
9
8
  const context = inputCtx;
10
- const _handler = typeof optionsOrHandler === "function" ? optionsOrHandler : handler;
11
9
  const internalContext = await require_context.createInternalContext(context, {
12
- options: typeof optionsOrHandler === "function" ? {} : optionsOrHandler,
10
+ options: {},
13
11
  path: "/"
14
12
  });
15
- if (!_handler) throw new Error("handler must be defined");
16
13
  try {
17
- const response = await _handler(internalContext);
14
+ const response = await handler(internalContext);
18
15
  const headers = internalContext.responseHeaders;
19
16
  return context.returnHeaders ? {
20
17
  headers,
@@ -31,18 +28,67 @@ function createMiddleware(optionsOrHandler, handler) {
31
28
  throw e;
32
29
  }
33
30
  };
34
- internalHandler.options = typeof optionsOrHandler === "function" ? {} : optionsOrHandler;
31
+ internalHandler.options = {};
35
32
  return internalHandler;
36
33
  }
37
34
  createMiddleware.create = (opts) => {
38
35
  function fn(optionsOrHandler, handler) {
39
- if (typeof optionsOrHandler === "function") return createMiddleware({ use: opts?.use }, optionsOrHandler);
36
+ if (typeof optionsOrHandler === "function") {
37
+ const internalHandler = async (inputCtx) => {
38
+ const context = inputCtx;
39
+ const internalContext = await require_context.createInternalContext(context, {
40
+ options: { use: opts?.use },
41
+ path: "/"
42
+ });
43
+ try {
44
+ const response = await optionsOrHandler(internalContext);
45
+ const headers = internalContext.responseHeaders;
46
+ return context.returnHeaders ? {
47
+ headers,
48
+ response
49
+ } : response;
50
+ } catch (e) {
51
+ if (require_utils.isAPIError(e)) Object.defineProperty(e, require_error.kAPIErrorHeaderSymbol, {
52
+ enumerable: false,
53
+ configurable: false,
54
+ get() {
55
+ return internalContext.responseHeaders;
56
+ }
57
+ });
58
+ throw e;
59
+ }
60
+ };
61
+ internalHandler.options = { use: opts?.use };
62
+ return internalHandler;
63
+ }
40
64
  if (!handler) throw new Error("Middleware handler is required");
41
- return createMiddleware({
42
- ...optionsOrHandler,
43
- method: "*",
44
- use: [...opts?.use || [], ...optionsOrHandler.use || []]
45
- }, handler);
65
+ const use = [...opts?.use || [], ...optionsOrHandler.use || []];
66
+ const internalHandler = async (inputCtx) => {
67
+ const context = inputCtx;
68
+ const internalContext = await require_context.createInternalContext(context, {
69
+ options: { use },
70
+ path: "/"
71
+ });
72
+ try {
73
+ const response = await handler(internalContext);
74
+ const headers = internalContext.responseHeaders;
75
+ return context.returnHeaders ? {
76
+ headers,
77
+ response
78
+ } : response;
79
+ } catch (e) {
80
+ if (require_utils.isAPIError(e)) Object.defineProperty(e, require_error.kAPIErrorHeaderSymbol, {
81
+ enumerable: false,
82
+ configurable: false,
83
+ get() {
84
+ return internalContext.responseHeaders;
85
+ }
86
+ });
87
+ throw e;
88
+ }
89
+ };
90
+ internalHandler.options = { use };
91
+ return internalHandler;
46
92
  }
47
93
  return fn;
48
94
  };
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.cjs","names":["createInternalContext","isAPIError","kAPIErrorHeaderSymbol"],"sources":["../src/middleware.ts"],"sourcesContent":["import {\n\tcreateEndpoint,\n\ttype Endpoint,\n\ttype EndpointContext,\n\ttype EndpointOptions,\n} from \"./endpoint\";\nimport {\n\tcreateInternalContext,\n\ttype InferBody,\n\ttype InferBodyInput,\n\ttype InferHeaders,\n\ttype InferHeadersInput,\n\ttype InferMiddlewareBody,\n\ttype InferMiddlewareQuery,\n\ttype InferQuery,\n\ttype InferQueryInput,\n\ttype InferRequest,\n\ttype InferRequestInput,\n\ttype InferUse,\n\ttype InputContext,\n} from \"./context\";\nimport type { Prettify } from \"./helper\";\nimport { isAPIError } from \"./utils\";\nimport { kAPIErrorHeaderSymbol } from \"./error\";\n\nexport interface MiddlewareOptions extends Omit<EndpointOptions, \"method\"> {}\n\nexport type MiddlewareResponse = null | void | undefined | Record<string, any>;\n\nexport type MiddlewareContext<\n\tOptions extends MiddlewareOptions,\n\tContext = {},\n> = EndpointContext<\n\tstring,\n\tOptions & {\n\t\tmethod: \"*\";\n\t}\n> & {\n\t/**\n\t * Method\n\t *\n\t * The request method\n\t */\n\tmethod: string;\n\t/**\n\t * Path\n\t *\n\t * The path of the endpoint\n\t */\n\tpath: string;\n\t/**\n\t * Body\n\t *\n\t * The body object will be the parsed JSON from the request and validated\n\t * against the body schema if it exists\n\t */\n\tbody: InferMiddlewareBody<Options>;\n\t/**\n\t * Query\n\t *\n\t * The query object will be the parsed query string from the request\n\t * and validated against the query schema if it exists\n\t */\n\tquery: InferMiddlewareQuery<Options>;\n\t/**\n\t * Params\n\t *\n\t * If the path is `/user/:id` and the request is `/user/1` then the\n\t * params will\n\t * be `{ id: \"1\" }` and if the path includes a wildcard like `/user/*`\n\t * then the\n\t * params will be `{ _: \"1\" }` where `_` is the wildcard key. If the\n\t * wildcard\n\t * is named like `/user/**:name` then the params will be `{ name: string }`\n\t */\n\tparams: string;\n\t/**\n\t * Request object\n\t *\n\t * If `requireRequest` is set to true in the endpoint options this will be\n\t * required\n\t */\n\trequest: InferRequest<Options>;\n\t/**\n\t * Headers\n\t *\n\t * If `requireHeaders` is set to true in the endpoint options this will be\n\t * required\n\t */\n\theaders: InferHeaders<Options>;\n\t/**\n\t * Set header\n\t *\n\t * If it's called outside of a request it will just be ignored.\n\t */\n\tsetHeader: (key: string, value: string) => void;\n\t/**\n\t * Get header\n\t *\n\t * If it's called outside of a request it will just return null\n\t *\n\t * @param key - The key of the header\n\t * @returns\n\t */\n\tgetHeader: (key: string) => string | null;\n\t/**\n\t * JSON\n\t *\n\t * a helper function to create a JSON response with\n\t * the correct headers\n\t * and status code. If `asResponse` is set to true in\n\t * the context then\n\t * it will return a Response object instead of the\n\t * JSON object.\n\t *\n\t * @param json - The JSON object to return\n\t * @param routerResponse - The response object to\n\t * return if `asResponse` is\n\t * true in the context this will take precedence\n\t */\n\tjson: <R extends Record<string, any> | null>(\n\t\tjson: R,\n\t\trouterResponse?:\n\t\t\t| {\n\t\t\t\t\tstatus?: number;\n\t\t\t\t\theaders?: Record<string, string>;\n\t\t\t\t\tresponse?: Response;\n\t\t\t }\n\t\t\t| Response,\n\t) => Promise<R>;\n\t/**\n\t * Middleware context\n\t */\n\tcontext: Prettify<Context>;\n};\n\nexport function createMiddleware<Options extends MiddlewareOptions, R>(\n\toptions: Options,\n\thandler: (context: MiddlewareContext<Options>) => Promise<R>,\n): <InputCtx extends MiddlewareInputContext<Options>>(\n\tinputContext: InputCtx,\n) => Promise<R>;\nexport function createMiddleware<Options extends MiddlewareOptions, R>(\n\thandler: (context: MiddlewareContext<Options>) => Promise<R>,\n): <InputCtx extends MiddlewareInputContext<Options>>(\n\tinputContext: InputCtx,\n) => Promise<R>;\nexport function createMiddleware(optionsOrHandler: any, handler?: any) {\n\tconst internalHandler = async (inputCtx: InputContext<any, any>) => {\n\t\tconst context = inputCtx as InputContext<any, any>;\n\t\tconst _handler =\n\t\t\ttypeof optionsOrHandler === \"function\" ? optionsOrHandler : handler;\n\t\tconst options =\n\t\t\ttypeof optionsOrHandler === \"function\" ? {} : optionsOrHandler;\n\t\tconst internalContext = await createInternalContext(context, {\n\t\t\toptions,\n\t\t\tpath: \"/\",\n\t\t});\n\n\t\tif (!_handler) {\n\t\t\tthrow new Error(\"handler must be defined\");\n\t\t}\n\t\ttry {\n\t\t\tconst response = await _handler(internalContext as any);\n\t\t\tconst headers = internalContext.responseHeaders;\n\t\t\treturn context.returnHeaders\n\t\t\t\t? {\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tresponse,\n\t\t\t\t\t}\n\t\t\t\t: response;\n\t\t} catch (e) {\n\t\t\t// fixme(alex): this is workaround that set-cookie headers are not accessible when error is thrown from middleware\n\t\t\tif (isAPIError(e)) {\n\t\t\t\tObject.defineProperty(e, kAPIErrorHeaderSymbol, {\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tget() {\n\t\t\t\t\t\treturn internalContext.responseHeaders;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t};\n\tinternalHandler.options =\n\t\ttypeof optionsOrHandler === \"function\" ? {} : optionsOrHandler;\n\treturn internalHandler;\n}\n\nexport type MiddlewareInputContext<Options extends MiddlewareOptions> =\n\tInferBodyInput<Options> &\n\t\tInferQueryInput<Options> &\n\t\tInferRequestInput<Options> &\n\t\tInferHeadersInput<Options> & {\n\t\t\tasResponse?: boolean;\n\t\t\treturnHeaders?: boolean;\n\t\t\tuse?: Middleware[];\n\t\t};\n\nexport type Middleware<\n\tOptions extends MiddlewareOptions = MiddlewareOptions,\n\tHandler extends (inputCtx: any) => Promise<any> = any,\n> = Handler & {\n\toptions: Options;\n};\n\ncreateMiddleware.create = <\n\tE extends {\n\t\tuse?: Middleware[];\n\t},\n>(\n\topts?: E,\n) => {\n\ttype InferredContext = InferUse<E[\"use\"]>;\n\tfunction fn<Options extends MiddlewareOptions, R>(\n\t\toptions: Options,\n\t\thandler: (ctx: MiddlewareContext<Options, InferredContext>) => Promise<R>,\n\t): (inputContext: MiddlewareInputContext<Options>) => Promise<R>;\n\tfunction fn<Options extends MiddlewareOptions, R>(\n\t\thandler: (ctx: MiddlewareContext<Options, InferredContext>) => Promise<R>,\n\t): (inputContext: MiddlewareInputContext<Options>) => Promise<R>;\n\tfunction fn(optionsOrHandler: any, handler?: any) {\n\t\tif (typeof optionsOrHandler === \"function\") {\n\t\t\treturn createMiddleware(\n\t\t\t\t{\n\t\t\t\t\tuse: opts?.use,\n\t\t\t\t},\n\t\t\t\toptionsOrHandler,\n\t\t\t);\n\t\t}\n\t\tif (!handler) {\n\t\t\tthrow new Error(\"Middleware handler is required\");\n\t\t}\n\t\tconst middleware = createMiddleware(\n\t\t\t{\n\t\t\t\t...optionsOrHandler,\n\t\t\t\tmethod: \"*\",\n\t\t\t\tuse: [...(opts?.use || []), ...(optionsOrHandler.use || [])],\n\t\t\t},\n\t\t\thandler,\n\t\t);\n\t\treturn middleware as any;\n\t}\n\treturn fn;\n};\n"],"mappings":";;;;;;AAmJA,SAAgB,iBAAiB,kBAAuB,SAAe;CACtE,MAAM,kBAAkB,OAAO,aAAqC;EACnE,MAAM,UAAU;EAChB,MAAM,WACL,OAAO,qBAAqB,aAAa,mBAAmB;EAG7D,MAAM,kBAAkB,MAAMA,sCAAsB,SAAS;GAC5D,SAFA,OAAO,qBAAqB,aAAa,EAAE,GAAG;GAG9C,MAAM;GACN,CAAC;AAEF,MAAI,CAAC,SACJ,OAAM,IAAI,MAAM,0BAA0B;AAE3C,MAAI;GACH,MAAM,WAAW,MAAM,SAAS,gBAAuB;GACvD,MAAM,UAAU,gBAAgB;AAChC,UAAO,QAAQ,gBACZ;IACA;IACA;IACA,GACA;WACK,GAAG;AAEX,OAAIC,yBAAW,EAAE,CAChB,QAAO,eAAe,GAAGC,qCAAuB;IAC/C,YAAY;IACZ,cAAc;IACd,MAAM;AACL,YAAO,gBAAgB;;IAExB,CAAC;AAEH,SAAM;;;AAGR,iBAAgB,UACf,OAAO,qBAAqB,aAAa,EAAE,GAAG;AAC/C,QAAO;;AAoBR,iBAAiB,UAKhB,SACI;CASJ,SAAS,GAAG,kBAAuB,SAAe;AACjD,MAAI,OAAO,qBAAqB,WAC/B,QAAO,iBACN,EACC,KAAK,MAAM,KACX,EACD,iBACA;AAEF,MAAI,CAAC,QACJ,OAAM,IAAI,MAAM,iCAAiC;AAUlD,SARmB,iBAClB;GACC,GAAG;GACH,QAAQ;GACR,KAAK,CAAC,GAAI,MAAM,OAAO,EAAE,EAAG,GAAI,iBAAiB,OAAO,EAAE,CAAE;GAC5D,EACD,QACA;;AAGF,QAAO"}
1
+ {"version":3,"file":"middleware.cjs","names":["createInternalContext","isAPIError","kAPIErrorHeaderSymbol"],"sources":["../src/middleware.ts"],"sourcesContent":["import { createInternalContext } from \"./context\";\nimport type { CookieOptions, CookiePrefixOptions } from \"./cookies\";\nimport type { Status, statusCodes } from \"./error\";\nimport { type APIError, kAPIErrorHeaderSymbol } from \"./error\";\nimport type { Prettify } from \"./helper\";\nimport type { InferUse } from \"./types\";\nimport { isAPIError } from \"./utils\";\n\nexport type MiddlewareContext<Context = {}> = {\n\t/**\n\t * Method\n\t *\n\t * The request method\n\t */\n\tmethod: string;\n\t/**\n\t * Path\n\t *\n\t * The path of the endpoint\n\t */\n\tpath: string;\n\t/**\n\t * Body\n\t *\n\t * The body object will be the parsed JSON from the request and validated\n\t * against the body schema if it exists\n\t */\n\tbody: any;\n\t/**\n\t * Query\n\t *\n\t * The query object will be the parsed query string from the request\n\t * and validated against the query schema if it exists\n\t */\n\tquery: Record<string, any> | undefined;\n\t/**\n\t * Params\n\t *\n\t * If the path is `/user/:id` and the request is `/user/1` then the\n\t * params will be `{ id: \"1\" }` and if the path includes a wildcard like\n\t * `/user/*` then the params will be `{ _: \"1\" }` where `_` is the wildcard\n\t * key. If the wildcard is named like `/user/**:name` then the params will\n\t * be `{ name: string }`\n\t */\n\tparams: Record<string, any> | undefined;\n\t/**\n\t * Request object\n\t *\n\t * If `requireRequest` is set to true in the endpoint options this will be\n\t * required\n\t */\n\trequest: Request | undefined;\n\t/**\n\t * Headers\n\t *\n\t * If `requireHeaders` is set to true in the endpoint options this will be\n\t * required\n\t */\n\theaders: Headers | undefined;\n\t/**\n\t * Set header\n\t *\n\t * If it's called outside of a request it will just be ignored.\n\t */\n\tsetHeader: (key: string, value: string) => void;\n\t/**\n\t * Set the response status code\n\t */\n\tsetStatus: (status: Status) => void;\n\t/**\n\t * Get header\n\t *\n\t * If it's called outside of a request it will just return null\n\t *\n\t * @param key - The key of the header\n\t */\n\tgetHeader: (key: string) => string | null;\n\t/**\n\t * Get a cookie value from the request\n\t *\n\t * @param key - The key of the cookie\n\t * @param prefix - The prefix of the cookie between `__Secure-` and `__Host-`\n\t * @returns The value of the cookie\n\t */\n\tgetCookie: (key: string, prefix?: CookiePrefixOptions) => string | null;\n\t/**\n\t * Get a signed cookie value from the request\n\t *\n\t * @param key - The key of the cookie\n\t * @param secret - The secret of the signed cookie\n\t * @param prefix - The prefix of the cookie between `__Secure-` and `__Host-`\n\t * @returns The value of the cookie or null if the cookie is not found or false if the signature is invalid\n\t */\n\tgetSignedCookie: (\n\t\tkey: string,\n\t\tsecret: string,\n\t\tprefix?: CookiePrefixOptions,\n\t) => Promise<string | null | false>;\n\t/**\n\t * Set a cookie value in the response\n\t *\n\t * @param key - The key of the cookie\n\t * @param value - The value to set\n\t * @param options - The options of the cookie\n\t * @returns The cookie string\n\t */\n\tsetCookie: (key: string, value: string, options?: CookieOptions) => string;\n\t/**\n\t * Set signed cookie\n\t *\n\t * @param key - The key of the cookie\n\t * @param value - The value to set\n\t * @param secret - The secret to sign the cookie with\n\t * @param options - The options of the cookie\n\t * @returns The cookie string\n\t */\n\tsetSignedCookie: (\n\t\tkey: string,\n\t\tvalue: string,\n\t\tsecret: string,\n\t\toptions?: CookieOptions,\n\t) => Promise<string>;\n\t/**\n\t * JSON\n\t *\n\t * A helper function to create a JSON response with the correct headers\n\t * and status code. If `asResponse` is set to true in the context then\n\t * it will return a Response object instead of the JSON object.\n\t *\n\t * @param json - The JSON object to return\n\t * @param routerResponse - The response object to return if `asResponse` is\n\t * true in the context this will take precedence\n\t */\n\tjson: <R extends Record<string, any> | null>(\n\t\tjson: R,\n\t\trouterResponse?:\n\t\t\t| {\n\t\t\t\t\tstatus?: number;\n\t\t\t\t\theaders?: Record<string, string>;\n\t\t\t\t\tresponse?: Response;\n\t\t\t\t\tbody?: Record<string, any>;\n\t\t\t }\n\t\t\t| Response,\n\t) => R;\n\t/**\n\t * Middleware context\n\t */\n\tcontext: Prettify<Context>;\n\t/**\n\t * Redirect to a new URL\n\t */\n\tredirect: (url: string) => APIError;\n\t/**\n\t * Return error\n\t */\n\terror: (\n\t\tstatus: keyof typeof statusCodes | Status,\n\t\tbody?: {\n\t\t\tmessage?: string;\n\t\t\tcode?: string;\n\t\t} & Record<string, any>,\n\t\theaders?: HeadersInit,\n\t) => APIError;\n\tasResponse?: boolean;\n\treturnHeaders?: boolean;\n\treturnStatus?: boolean;\n\tresponseHeaders: Headers;\n};\n\ntype DefaultHandler = (inputCtx: MiddlewareContext<any>) => Promise<any>;\n\nexport type Middleware<\n\tHandler extends (\n\t\tinputCtx: MiddlewareContext<any>,\n\t) => Promise<any> = DefaultHandler,\n> = Handler & {\n\toptions: Record<string, any>;\n};\n\nexport function createMiddleware<Context = {}, R = unknown>(\n\thandler: (context: MiddlewareContext<Context>) => Promise<R>,\n): Middleware<(inputContext: Record<string, any>) => Promise<R>>;\nexport function createMiddleware(handler: any) {\n\tconst internalHandler = async (inputCtx: any) => {\n\t\tconst context = inputCtx as Record<string, any>;\n\t\tconst internalContext = await createInternalContext(context, {\n\t\t\toptions: {},\n\t\t\tpath: \"/\",\n\t\t});\n\n\t\ttry {\n\t\t\tconst response = await handler(internalContext as any);\n\t\t\tconst headers = internalContext.responseHeaders;\n\t\t\treturn context.returnHeaders\n\t\t\t\t? {\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tresponse,\n\t\t\t\t\t}\n\t\t\t\t: response;\n\t\t} catch (e) {\n\t\t\t// fixme(alex): this is workaround that set-cookie headers are not accessible when error is thrown from middleware\n\t\t\tif (isAPIError(e)) {\n\t\t\t\tObject.defineProperty(e, kAPIErrorHeaderSymbol, {\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tget() {\n\t\t\t\t\t\treturn internalContext.responseHeaders;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t};\n\tinternalHandler.options = {};\n\treturn internalHandler;\n}\n\ncreateMiddleware.create = <\n\tE extends {\n\t\tuse?: Middleware[];\n\t},\n>(\n\topts?: E,\n) => {\n\ttype InferredContext = InferUse<E[\"use\"]>;\n\n\tfunction fn<R>(\n\t\toptions: { use?: Middleware[] },\n\t\thandler: (ctx: MiddlewareContext<InferredContext>) => Promise<R>,\n\t): Middleware<(inputContext: Record<string, any>) => Promise<R>>;\n\tfunction fn<R>(\n\t\thandler: (ctx: MiddlewareContext<InferredContext>) => Promise<R>,\n\t): Middleware<(inputContext: Record<string, any>) => Promise<R>>;\n\tfunction fn(optionsOrHandler: any, handler?: any) {\n\t\tif (typeof optionsOrHandler === \"function\") {\n\t\t\tconst internalHandler = async (inputCtx: any) => {\n\t\t\t\tconst context = inputCtx as Record<string, any>;\n\t\t\t\tconst internalContext = await createInternalContext(context, {\n\t\t\t\t\toptions: { use: opts?.use },\n\t\t\t\t\tpath: \"/\",\n\t\t\t\t});\n\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await optionsOrHandler(internalContext as any);\n\t\t\t\t\tconst headers = internalContext.responseHeaders;\n\t\t\t\t\treturn context.returnHeaders ? { headers, response } : response;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (isAPIError(e)) {\n\t\t\t\t\t\tObject.defineProperty(e, kAPIErrorHeaderSymbol, {\n\t\t\t\t\t\t\tenumerable: false,\n\t\t\t\t\t\t\tconfigurable: false,\n\t\t\t\t\t\t\tget() {\n\t\t\t\t\t\t\t\treturn internalContext.responseHeaders;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t};\n\t\t\tinternalHandler.options = { use: opts?.use };\n\t\t\treturn internalHandler;\n\t\t}\n\t\tif (!handler) {\n\t\t\tthrow new Error(\"Middleware handler is required\");\n\t\t}\n\t\tconst use = [...(opts?.use || []), ...(optionsOrHandler.use || [])];\n\t\tconst internalHandler = async (inputCtx: any) => {\n\t\t\tconst context = inputCtx as Record<string, any>;\n\t\t\tconst internalContext = await createInternalContext(context, {\n\t\t\t\toptions: { use },\n\t\t\t\tpath: \"/\",\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tconst response = await handler(internalContext as any);\n\t\t\t\tconst headers = internalContext.responseHeaders;\n\t\t\t\treturn context.returnHeaders ? { headers, response } : response;\n\t\t\t} catch (e) {\n\t\t\t\tif (isAPIError(e)) {\n\t\t\t\t\tObject.defineProperty(e, kAPIErrorHeaderSymbol, {\n\t\t\t\t\t\tenumerable: false,\n\t\t\t\t\t\tconfigurable: false,\n\t\t\t\t\t\tget() {\n\t\t\t\t\t\t\treturn internalContext.responseHeaders;\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t};\n\t\tinternalHandler.options = { use };\n\t\treturn internalHandler as any;\n\t}\n\treturn fn;\n};\n"],"mappings":";;;;;AAsLA,SAAgB,iBAAiB,SAAc;CAC9C,MAAM,kBAAkB,OAAO,aAAkB;EAChD,MAAM,UAAU;EAChB,MAAM,kBAAkB,MAAMA,sCAAsB,SAAS;GAC5D,SAAS,EAAE;GACX,MAAM;GACN,CAAC;AAEF,MAAI;GACH,MAAM,WAAW,MAAM,QAAQ,gBAAuB;GACtD,MAAM,UAAU,gBAAgB;AAChC,UAAO,QAAQ,gBACZ;IACA;IACA;IACA,GACA;WACK,GAAG;AAEX,OAAIC,yBAAW,EAAE,CAChB,QAAO,eAAe,GAAGC,qCAAuB;IAC/C,YAAY;IACZ,cAAc;IACd,MAAM;AACL,YAAO,gBAAgB;;IAExB,CAAC;AAEH,SAAM;;;AAGR,iBAAgB,UAAU,EAAE;AAC5B,QAAO;;AAGR,iBAAiB,UAKhB,SACI;CAUJ,SAAS,GAAG,kBAAuB,SAAe;AACjD,MAAI,OAAO,qBAAqB,YAAY;GAC3C,MAAM,kBAAkB,OAAO,aAAkB;IAChD,MAAM,UAAU;IAChB,MAAM,kBAAkB,MAAMF,sCAAsB,SAAS;KAC5D,SAAS,EAAE,KAAK,MAAM,KAAK;KAC3B,MAAM;KACN,CAAC;AAEF,QAAI;KACH,MAAM,WAAW,MAAM,iBAAiB,gBAAuB;KAC/D,MAAM,UAAU,gBAAgB;AAChC,YAAO,QAAQ,gBAAgB;MAAE;MAAS;MAAU,GAAG;aAC/C,GAAG;AACX,SAAIC,yBAAW,EAAE,CAChB,QAAO,eAAe,GAAGC,qCAAuB;MAC/C,YAAY;MACZ,cAAc;MACd,MAAM;AACL,cAAO,gBAAgB;;MAExB,CAAC;AAEH,WAAM;;;AAGR,mBAAgB,UAAU,EAAE,KAAK,MAAM,KAAK;AAC5C,UAAO;;AAER,MAAI,CAAC,QACJ,OAAM,IAAI,MAAM,iCAAiC;EAElD,MAAM,MAAM,CAAC,GAAI,MAAM,OAAO,EAAE,EAAG,GAAI,iBAAiB,OAAO,EAAE,CAAE;EACnE,MAAM,kBAAkB,OAAO,aAAkB;GAChD,MAAM,UAAU;GAChB,MAAM,kBAAkB,MAAMF,sCAAsB,SAAS;IAC5D,SAAS,EAAE,KAAK;IAChB,MAAM;IACN,CAAC;AAEF,OAAI;IACH,MAAM,WAAW,MAAM,QAAQ,gBAAuB;IACtD,MAAM,UAAU,gBAAgB;AAChC,WAAO,QAAQ,gBAAgB;KAAE;KAAS;KAAU,GAAG;YAC/C,GAAG;AACX,QAAIC,yBAAW,EAAE,CAChB,QAAO,eAAe,GAAGC,qCAAuB;KAC/C,YAAY;KACZ,cAAc;KACd,MAAM;AACL,aAAO,gBAAgB;;KAExB,CAAC;AAEH,UAAM;;;AAGR,kBAAgB,UAAU,EAAE,KAAK;AACjC,SAAO;;AAER,QAAO"}