@apisr/response 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/error/default.mjs +11 -7
- package/dist/error/index.d.mts +6 -1
- package/dist/handler.d.mts +4 -4
- package/dist/handler.mjs +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +4 -4
- package/dist/options/base.d.mts +6 -6
- package/dist/options/index.d.mts +2 -2
- package/dist/options/index.mjs +2 -2
- package/dist/options/meta.d.mts +1 -1
- package/dist/response/base.d.mts +1 -1
- package/dist/response/default.d.mts +2 -2
- package/dist/schema/dist/index.mjs +2 -107
- package/dist/schema/dist/zod/dist/index.mjs +111 -0
- package/dist/types.d.mts +1 -1
- package/dist/zod/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/error/default.ts +14 -7
- package/src/error/index.ts +17 -3
package/dist/error/default.mjs
CHANGED
|
@@ -3,6 +3,10 @@ import { zod } from "../zod/dist/index.mjs";
|
|
|
3
3
|
//#region src/error/default.ts
|
|
4
4
|
function generateDefaultErrors(_mapDefaultError) {
|
|
5
5
|
const mapDefaultError = _mapDefaultError ?? ((err) => err);
|
|
6
|
+
const resolveCause = (input) => {
|
|
7
|
+
if (typeof input !== "object" || input === null || !("cause" in input)) return;
|
|
8
|
+
return input.cause;
|
|
9
|
+
};
|
|
6
10
|
const inputSchema = zod.object({ cause: zod.any().optional() }).optional();
|
|
7
11
|
return {
|
|
8
12
|
unauthorized: {
|
|
@@ -10,7 +14,7 @@ function generateDefaultErrors(_mapDefaultError) {
|
|
|
10
14
|
message: "Unauthorized",
|
|
11
15
|
code: "UNAUTHORIZED",
|
|
12
16
|
name: "UnauthorizedError",
|
|
13
|
-
cause: input
|
|
17
|
+
cause: resolveCause(input)
|
|
14
18
|
}),
|
|
15
19
|
options: {
|
|
16
20
|
input: inputSchema,
|
|
@@ -23,7 +27,7 @@ function generateDefaultErrors(_mapDefaultError) {
|
|
|
23
27
|
message: "Forbidden",
|
|
24
28
|
code: "FORBIDDEN",
|
|
25
29
|
name: "ForbiddenError",
|
|
26
|
-
cause: input
|
|
30
|
+
cause: resolveCause(input)
|
|
27
31
|
}),
|
|
28
32
|
options: {
|
|
29
33
|
input: inputSchema,
|
|
@@ -36,7 +40,7 @@ function generateDefaultErrors(_mapDefaultError) {
|
|
|
36
40
|
message: "Not Found",
|
|
37
41
|
code: "NOT_FOUND",
|
|
38
42
|
name: "NotFoundError",
|
|
39
|
-
cause: input
|
|
43
|
+
cause: resolveCause(input)
|
|
40
44
|
}),
|
|
41
45
|
options: {
|
|
42
46
|
input: inputSchema,
|
|
@@ -49,7 +53,7 @@ function generateDefaultErrors(_mapDefaultError) {
|
|
|
49
53
|
message: "Bad Request",
|
|
50
54
|
code: "BAD_REQUEST",
|
|
51
55
|
name: "BadRequestError",
|
|
52
|
-
cause: input
|
|
56
|
+
cause: resolveCause(input)
|
|
53
57
|
}),
|
|
54
58
|
options: {
|
|
55
59
|
input: inputSchema,
|
|
@@ -62,7 +66,7 @@ function generateDefaultErrors(_mapDefaultError) {
|
|
|
62
66
|
message: "Conflict",
|
|
63
67
|
code: "CONFLICT",
|
|
64
68
|
name: "ConflictError",
|
|
65
|
-
cause: input
|
|
69
|
+
cause: resolveCause(input)
|
|
66
70
|
}),
|
|
67
71
|
options: {
|
|
68
72
|
input: inputSchema,
|
|
@@ -75,7 +79,7 @@ function generateDefaultErrors(_mapDefaultError) {
|
|
|
75
79
|
message: "Too Many Requests",
|
|
76
80
|
code: "TOO_MANY_REQUESTS",
|
|
77
81
|
name: "TooManyRequestsError",
|
|
78
|
-
cause: input
|
|
82
|
+
cause: resolveCause(input)
|
|
79
83
|
}),
|
|
80
84
|
options: {
|
|
81
85
|
input: inputSchema,
|
|
@@ -88,7 +92,7 @@ function generateDefaultErrors(_mapDefaultError) {
|
|
|
88
92
|
message: "Internal Server Error",
|
|
89
93
|
code: "INTERNAL_SERVER_ERROR",
|
|
90
94
|
name: "InternalServerError",
|
|
91
|
-
cause: input
|
|
95
|
+
cause: resolveCause(input)
|
|
92
96
|
}),
|
|
93
97
|
options: {
|
|
94
98
|
input: inputSchema,
|
package/dist/error/index.d.mts
CHANGED
|
@@ -11,9 +11,14 @@ type DefaultError = {
|
|
|
11
11
|
cause?: unknown;
|
|
12
12
|
stack?: string[];
|
|
13
13
|
};
|
|
14
|
+
type InferErrorHandlerInput<THandlerOptions extends ErrorHandlerOptions | undefined> = THandlerOptions extends {
|
|
15
|
+
input: infer TSchema;
|
|
16
|
+
} ? TSchema extends Schema ? Infer<TSchema> : never : THandlerOptions extends {
|
|
17
|
+
input?: infer TSchema;
|
|
18
|
+
} ? TSchema extends Schema ? Infer<TSchema> | undefined : undefined : never;
|
|
14
19
|
type ErrorHandler<TOptions extends Options, THandlerOptions extends ErrorHandlerOptions | undefined> = (data: {
|
|
15
20
|
meta: TOptions["meta"] extends undefined ? never : Infer<ExtractSchema<TOptions["meta"]>>;
|
|
16
|
-
input:
|
|
21
|
+
input: InferErrorHandlerInput<THandlerOptions>;
|
|
17
22
|
}) => ErrorOptions.InferedSchema<TOptions>;
|
|
18
23
|
interface ErrorHandlerOptions<TSchema extends Schema = Schema> {
|
|
19
24
|
input?: TSchema;
|
package/dist/handler.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { PromiseOr } from "./types.mjs";
|
|
2
|
-
import { MetaOptions } from "./options/meta.mjs";
|
|
3
|
-
import { ErrorOptions } from "./options/error.mjs";
|
|
4
2
|
import { BaseResponse } from "./response/base.mjs";
|
|
5
|
-
import { JsonResponse } from "./response/json/index.mjs";
|
|
6
|
-
import { JsonOptions } from "./options/json.mjs";
|
|
7
3
|
import { Binary, BinaryResponse } from "./response/binary/index.mjs";
|
|
8
4
|
import { BinaryOptions } from "./options/binary.mjs";
|
|
5
|
+
import { ErrorOptions } from "./options/error.mjs";
|
|
6
|
+
import { JsonResponse } from "./response/json/index.mjs";
|
|
7
|
+
import { JsonOptions } from "./options/json.mjs";
|
|
8
|
+
import { MetaOptions } from "./options/meta.mjs";
|
|
9
9
|
import { ErrorResponse } from "./response/error/index.mjs";
|
|
10
10
|
import { DefaultResponse } from "./response/default.mjs";
|
|
11
11
|
import { Options } from "./options/base.mjs";
|
package/dist/handler.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { checkSchema } from "./schema/dist/index.mjs";
|
|
2
1
|
import { generateDefaultErrors } from "./error/default.mjs";
|
|
2
|
+
import { checkSchema } from "./schema/dist/index.mjs";
|
|
3
3
|
import { resolveHeaders } from "./headers.mjs";
|
|
4
4
|
import { options } from "./options/index.mjs";
|
|
5
5
|
import { BaseResponse } from "./response/base.mjs";
|
package/dist/index.d.mts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { DefaultMeta } from "./response/meta/index.mjs";
|
|
2
1
|
import { AnyObject, FunctionObject, PromiseOr } from "./types.mjs";
|
|
3
|
-
import { MetaOptions, meta } from "./options/meta.mjs";
|
|
4
2
|
import { Headers, RawHeaders, resolveHeaders } from "./headers.mjs";
|
|
5
|
-
import { ErrorOptions, error } from "./options/error.mjs";
|
|
6
3
|
import { BaseResponse, ResponseTypes } from "./response/base.mjs";
|
|
7
|
-
import { JsonResponse } from "./response/json/index.mjs";
|
|
8
|
-
import { JsonOptions, json } from "./options/json.mjs";
|
|
9
4
|
import { Binary, BinaryResponse } from "./response/binary/index.mjs";
|
|
10
5
|
import { BinaryOptions, binary } from "./options/binary.mjs";
|
|
6
|
+
import { ErrorOptions, error } from "./options/error.mjs";
|
|
7
|
+
import { JsonResponse } from "./response/json/index.mjs";
|
|
8
|
+
import { JsonOptions, json } from "./options/json.mjs";
|
|
9
|
+
import { DefaultMeta } from "./response/meta/index.mjs";
|
|
10
|
+
import { MetaOptions, meta } from "./options/meta.mjs";
|
|
11
11
|
import { ErrorResponse } from "./response/error/index.mjs";
|
|
12
12
|
import { DefaultResponse } from "./response/default.mjs";
|
|
13
13
|
import { Options } from "./options/base.mjs";
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { generateDefaultErrors } from "./error/default.mjs";
|
|
2
|
+
import "./error/index.mjs";
|
|
2
3
|
import { resolveHeaders } from "./headers.mjs";
|
|
4
|
+
import { binary } from "./options/binary.mjs";
|
|
5
|
+
import { error } from "./options/error.mjs";
|
|
3
6
|
import { json } from "./options/json.mjs";
|
|
4
7
|
import { meta } from "./options/meta.mjs";
|
|
5
|
-
import { error } from "./options/error.mjs";
|
|
6
|
-
import { binary } from "./options/binary.mjs";
|
|
7
8
|
import { options } from "./options/index.mjs";
|
|
8
9
|
import { BaseResponse } from "./response/base.mjs";
|
|
9
10
|
import { BinaryResponse } from "./response/binary/index.mjs";
|
|
@@ -11,8 +12,7 @@ import { ErrorResponse } from "./response/error/index.mjs";
|
|
|
11
12
|
import { JsonResponse } from "./response/json/index.mjs";
|
|
12
13
|
import { TextResponse } from "./response/text/index.mjs";
|
|
13
14
|
import { ResponseHandler, createResponseHandler } from "./handler.mjs";
|
|
14
|
-
import { responseSymbol } from "./symbol.mjs";
|
|
15
15
|
import "./response/index.mjs";
|
|
16
|
-
import "./
|
|
16
|
+
import { responseSymbol } from "./symbol.mjs";
|
|
17
17
|
|
|
18
18
|
export { BaseResponse, BinaryResponse, ErrorResponse, JsonResponse, ResponseHandler, TextResponse, binary, createResponseHandler, error, generateDefaultErrors, json, meta, options, resolveHeaders, responseSymbol };
|
package/dist/options/base.d.mts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { PromiseOr } from "../types.mjs";
|
|
2
|
-
import { MetaOptions } from "./meta.mjs";
|
|
3
2
|
import { Headers } from "../headers.mjs";
|
|
4
|
-
import { ErrorOptions } from "./error.mjs";
|
|
5
3
|
import { BaseResponse, ResponseTypes } from "../response/base.mjs";
|
|
6
|
-
import { JsonOptions } from "./json.mjs";
|
|
7
4
|
import { Binary } from "../response/binary/index.mjs";
|
|
8
5
|
import { BinaryOptions } from "./binary.mjs";
|
|
6
|
+
import { ErrorOptions } from "./error.mjs";
|
|
7
|
+
import { JsonOptions } from "./json.mjs";
|
|
8
|
+
import { MetaOptions } from "./meta.mjs";
|
|
9
9
|
import { DefaultResponse } from "../response/default.mjs";
|
|
10
10
|
|
|
11
11
|
//#region src/options/base.d.ts
|
|
12
12
|
interface Options<TMeta extends MetaOptions.Base = MetaOptions.Base, TError extends ErrorOptions.Base = ErrorOptions.Base, TJson extends JsonOptions.Base = JsonOptions.Base, TBinary extends BinaryOptions.Base = BinaryOptions.Base> {
|
|
13
|
+
binary?: TBinary;
|
|
14
|
+
error?: TError;
|
|
13
15
|
headers?: Headers<{
|
|
14
16
|
type: ResponseTypes;
|
|
15
17
|
data: any;
|
|
16
18
|
}>;
|
|
17
|
-
meta?: TMeta;
|
|
18
|
-
error?: TError;
|
|
19
19
|
json?: TJson;
|
|
20
|
-
binary?: TBinary;
|
|
21
20
|
mapResponse?(data: {
|
|
22
21
|
data: JsonOptions.InferedSchemaFromBase<TJson> | Binary | string;
|
|
23
22
|
error: ErrorOptions.InferedSchemaFromBase<TError>;
|
|
24
23
|
response: BaseResponse.Base<DefaultResponse>;
|
|
25
24
|
}): PromiseOr<Response>;
|
|
25
|
+
meta?: TMeta;
|
|
26
26
|
}
|
|
27
27
|
//#endregion
|
|
28
28
|
export { Options };
|
package/dist/options/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BinaryOptions, binary } from "./binary.mjs";
|
|
2
2
|
import { ErrorOptions, error } from "./error.mjs";
|
|
3
3
|
import { JsonOptions, json } from "./json.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { MetaOptions, meta } from "./meta.mjs";
|
|
5
5
|
import { Options } from "./base.mjs";
|
|
6
6
|
|
|
7
7
|
//#region src/options/index.d.ts
|
package/dist/options/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { binary } from "./binary.mjs";
|
|
2
|
+
import { error } from "./error.mjs";
|
|
1
3
|
import { json } from "./json.mjs";
|
|
2
4
|
import { meta } from "./meta.mjs";
|
|
3
|
-
import { error } from "./error.mjs";
|
|
4
|
-
import { binary } from "./binary.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/options/index.ts
|
|
7
7
|
const options = {
|
package/dist/options/meta.d.mts
CHANGED
package/dist/response/base.d.mts
CHANGED
|
@@ -4,9 +4,9 @@ import { RawHeaders } from "../headers.mjs";
|
|
|
4
4
|
type ResponseTypes = "json" | "binary" | "text" | "error";
|
|
5
5
|
declare namespace BaseResponse {
|
|
6
6
|
interface Options {
|
|
7
|
+
headers?: RawHeaders;
|
|
7
8
|
status?: number;
|
|
8
9
|
statusText?: string;
|
|
9
|
-
headers?: RawHeaders;
|
|
10
10
|
}
|
|
11
11
|
class Base<TPayload> extends Response {
|
|
12
12
|
payload: TPayload | undefined;
|
|
@@ -2,10 +2,10 @@ import { ErrorResponse } from "./error/index.mjs";
|
|
|
2
2
|
|
|
3
3
|
//#region src/response/default.d.ts
|
|
4
4
|
interface DefaultResponse<TData = unknown> {
|
|
5
|
-
success: boolean;
|
|
6
|
-
error: ErrorResponse.Base<any, any, any> | null;
|
|
7
5
|
data: TData | null;
|
|
6
|
+
error: ErrorResponse.Base<any, any, any> | null;
|
|
8
7
|
metadata: Record<string, unknown>;
|
|
8
|
+
success: boolean;
|
|
9
9
|
}
|
|
10
10
|
//#endregion
|
|
11
11
|
export { DefaultResponse };
|
|
@@ -1,111 +1,6 @@
|
|
|
1
|
-
import z from "zod";
|
|
1
|
+
import { resolveZodSchemaFromSources, z } from "./zod/dist/index.mjs";
|
|
2
2
|
|
|
3
3
|
//#region ../schema/dist/index.mjs
|
|
4
|
-
/**
|
|
5
|
-
* Extracts `from` metadata from each field of a zod object schema.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* const schema = z.object({
|
|
10
|
-
* name: z.string().from("body"),
|
|
11
|
-
* id: z.string().from("params"),
|
|
12
|
-
* token: z.string().from("headers", { key: "authorization" }),
|
|
13
|
-
* });
|
|
14
|
-
*
|
|
15
|
-
* resolveZodSchemaMeta(schema);
|
|
16
|
-
* // => {
|
|
17
|
-
* // name: { from: "body" },
|
|
18
|
-
* // id: { from: "params" },
|
|
19
|
-
* // token: { from: "headers", key: "authorization" },
|
|
20
|
-
* // }
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
function resolveZodSchemaMeta(schema) {
|
|
24
|
-
const shape = schema._zod.def.shape;
|
|
25
|
-
const result = {};
|
|
26
|
-
for (const fieldName in shape) {
|
|
27
|
-
const fieldSchema = shape[fieldName];
|
|
28
|
-
const meta = resolveFieldMeta(fieldSchema);
|
|
29
|
-
if (meta) result[fieldName] = meta;
|
|
30
|
-
}
|
|
31
|
-
return result;
|
|
32
|
-
}
|
|
33
|
-
function resolveFieldMeta(schema) {
|
|
34
|
-
const meta = z.globalRegistry.get(schema);
|
|
35
|
-
if (meta && typeof meta.from === "string") {
|
|
36
|
-
const key = meta.key ?? meta.fromKey;
|
|
37
|
-
return {
|
|
38
|
-
from: meta.from,
|
|
39
|
-
...key !== void 0 ? { key } : {}
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
const def = schema._zod?.def;
|
|
43
|
-
if (def?.innerType) return resolveFieldMeta(def.innerType);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Resolves field values from dynamic sources based on the schema's `from` metadata.
|
|
47
|
-
*
|
|
48
|
-
* Sources is a map where keys match possible `from` values
|
|
49
|
-
* (e.g. `"query"`, `"params"`, `"body"`, `"headers"`, `"handler.payload"`)
|
|
50
|
-
* and values are the corresponding data objects.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```ts
|
|
54
|
-
* const schema = z.object({
|
|
55
|
-
* name: z.string().from("body"),
|
|
56
|
-
* id: z.string().from("params"),
|
|
57
|
-
* search: z.string().from("query"),
|
|
58
|
-
* auth: z.string().from("headers", { key: "authorization" }),
|
|
59
|
-
* prev: z.string().from("handler.payload", { key: "name" }),
|
|
60
|
-
* });
|
|
61
|
-
*
|
|
62
|
-
* const resolved = resolveZodSchemaFromSources(schema, {
|
|
63
|
-
* body: { name: "John" },
|
|
64
|
-
* params: { id: "42" },
|
|
65
|
-
* query: { search: "test" },
|
|
66
|
-
* headers: { authorization: "Bearer ..." },
|
|
67
|
-
* "handler.payload": { name: "prev-value" },
|
|
68
|
-
* });
|
|
69
|
-
* // => { name: "John", id: "42", search: "test", auth: "Bearer ...", prev: "prev-value" }
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
function resolveZodSchemaFromSources(schema, sources) {
|
|
73
|
-
const fieldsMeta = resolveZodSchemaMeta(schema);
|
|
74
|
-
const result = {};
|
|
75
|
-
for (const [fieldName, meta] of Object.entries(fieldsMeta)) {
|
|
76
|
-
const source = sources[meta.from];
|
|
77
|
-
if (!source) continue;
|
|
78
|
-
const keys = meta.key ? Array.isArray(meta.key) ? meta.key : [meta.key] : [fieldName];
|
|
79
|
-
for (const k of keys) {
|
|
80
|
-
const value = getNestedValue(source, k);
|
|
81
|
-
if (value !== void 0) {
|
|
82
|
-
result[fieldName] = value;
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return result;
|
|
88
|
-
}
|
|
89
|
-
function getNestedValue(obj, path) {
|
|
90
|
-
const parts = path.split(".");
|
|
91
|
-
let current = obj;
|
|
92
|
-
for (const part of parts) {
|
|
93
|
-
if (current === null || current === void 0 || typeof current !== "object") return;
|
|
94
|
-
current = current[part];
|
|
95
|
-
}
|
|
96
|
-
return current;
|
|
97
|
-
}
|
|
98
|
-
function extendZod(zod) {
|
|
99
|
-
if (typeof zod.ZodType.prototype.from !== "undefined") return zod;
|
|
100
|
-
zod.ZodType.prototype.from = function(from, options) {
|
|
101
|
-
return this.meta({
|
|
102
|
-
from,
|
|
103
|
-
...options ?? {}
|
|
104
|
-
});
|
|
105
|
-
};
|
|
106
|
-
return zod;
|
|
107
|
-
}
|
|
108
|
-
extendZod(z);
|
|
109
4
|
function checkSchema(schema, input, options) {
|
|
110
5
|
const validationType = options?.validationType ?? "parse";
|
|
111
6
|
let resolved = input;
|
|
@@ -114,7 +9,7 @@ function checkSchema(schema, input, options) {
|
|
|
114
9
|
...resolveZodSchemaFromSources(schema, options.sources)
|
|
115
10
|
};
|
|
116
11
|
if (validationType === "parse") return schema.parse(resolved) ?? null;
|
|
117
|
-
|
|
12
|
+
if (validationType === "safeParse") {
|
|
118
13
|
const { data } = schema.safeParse(resolved);
|
|
119
14
|
return data ?? null;
|
|
120
15
|
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import z, { default as z$1 } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region ../schema/dist/zod/dist/index.mjs
|
|
4
|
+
/**
|
|
5
|
+
* Extracts `from` metadata from each field of a zod object schema.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const schema = z.object({
|
|
10
|
+
* name: z.string().from("body"),
|
|
11
|
+
* id: z.string().from("params"),
|
|
12
|
+
* token: z.string().from("headers", { key: "authorization" }),
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* resolveZodSchemaMeta(schema);
|
|
16
|
+
* // => {
|
|
17
|
+
* // name: { from: "body" },
|
|
18
|
+
* // id: { from: "params" },
|
|
19
|
+
* // token: { from: "headers", key: "authorization" },
|
|
20
|
+
* // }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
function resolveZodSchemaMeta(schema) {
|
|
24
|
+
const shape = schema._zod.def.shape;
|
|
25
|
+
const result = {};
|
|
26
|
+
for (const fieldName in shape) {
|
|
27
|
+
const fieldSchema = shape[fieldName];
|
|
28
|
+
const meta = resolveFieldMeta(fieldSchema);
|
|
29
|
+
if (meta) result[fieldName] = meta;
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
function resolveFieldMeta(schema) {
|
|
34
|
+
const meta = z$1.globalRegistry.get(schema);
|
|
35
|
+
if (meta && typeof meta.from === "string") {
|
|
36
|
+
const key = meta.key ?? meta.fromKey;
|
|
37
|
+
return {
|
|
38
|
+
from: meta.from,
|
|
39
|
+
...key !== void 0 ? { key } : {}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const def = schema._zod?.def;
|
|
43
|
+
if (def?.innerType) return resolveFieldMeta(def.innerType);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolves field values from dynamic sources based on the schema's `from` metadata.
|
|
47
|
+
*
|
|
48
|
+
* Sources is a map where keys match possible `from` values
|
|
49
|
+
* (e.g. `"query"`, `"params"`, `"body"`, `"headers"`, `"handler.payload"`)
|
|
50
|
+
* and values are the corresponding data objects.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* const schema = z.object({
|
|
55
|
+
* name: z.string().from("body"),
|
|
56
|
+
* id: z.string().from("params"),
|
|
57
|
+
* search: z.string().from("query"),
|
|
58
|
+
* auth: z.string().from("headers", { key: "authorization" }),
|
|
59
|
+
* prev: z.string().from("handler.payload", { key: "name" }),
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* const resolved = resolveZodSchemaFromSources(schema, {
|
|
63
|
+
* body: { name: "John" },
|
|
64
|
+
* params: { id: "42" },
|
|
65
|
+
* query: { search: "test" },
|
|
66
|
+
* headers: { authorization: "Bearer ..." },
|
|
67
|
+
* "handler.payload": { name: "prev-value" },
|
|
68
|
+
* });
|
|
69
|
+
* // => { name: "John", id: "42", search: "test", auth: "Bearer ...", prev: "prev-value" }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
function resolveZodSchemaFromSources(schema, sources) {
|
|
73
|
+
const fieldsMeta = resolveZodSchemaMeta(schema);
|
|
74
|
+
const result = {};
|
|
75
|
+
for (const [fieldName, meta] of Object.entries(fieldsMeta)) {
|
|
76
|
+
const source = sources[meta.from];
|
|
77
|
+
if (!source) continue;
|
|
78
|
+
const keys = meta.key ? Array.isArray(meta.key) ? meta.key : [meta.key] : [fieldName];
|
|
79
|
+
for (const k of keys) {
|
|
80
|
+
const value = getNestedValue(source, k);
|
|
81
|
+
if (value !== void 0) {
|
|
82
|
+
result[fieldName] = value;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
function getNestedValue(obj, path) {
|
|
90
|
+
const parts = path.split(".");
|
|
91
|
+
let current = obj;
|
|
92
|
+
for (const part of parts) {
|
|
93
|
+
if (current === null || current === void 0 || typeof current !== "object") return;
|
|
94
|
+
current = current[part];
|
|
95
|
+
}
|
|
96
|
+
return current;
|
|
97
|
+
}
|
|
98
|
+
function extendZod(zod) {
|
|
99
|
+
if (typeof zod.ZodType.prototype.from !== "undefined") return zod;
|
|
100
|
+
zod.ZodType.prototype.from = function(from, options) {
|
|
101
|
+
return this.meta({
|
|
102
|
+
from,
|
|
103
|
+
...options ?? {}
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
return zod;
|
|
107
|
+
}
|
|
108
|
+
extendZod(z);
|
|
109
|
+
|
|
110
|
+
//#endregion
|
|
111
|
+
export { resolveZodSchemaFromSources, z };
|
package/dist/types.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/types.d.ts
|
|
2
2
|
type AnyObject = Record<string, any>;
|
|
3
|
-
type FunctionObject<TResult
|
|
3
|
+
type FunctionObject<TResult, TFnArg = never> = TResult | (TFnArg extends never ? () => TResult : (arg: TFnArg) => TResult);
|
|
4
4
|
type PromiseOr<T> = PromiseLike<T> | T;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { AnyObject, FunctionObject, PromiseOr };
|
package/dist/zod/dist/index.mjs
CHANGED
package/package.json
CHANGED
package/src/error/default.ts
CHANGED
|
@@ -6,6 +6,13 @@ export function generateDefaultErrors<TOptions extends Options>(
|
|
|
6
6
|
_mapDefaultError: ErrorOptions.Base["mapDefaultError"]
|
|
7
7
|
): ErrorRegistry<TOptions> {
|
|
8
8
|
const mapDefaultError = _mapDefaultError ?? ((err) => err);
|
|
9
|
+
const resolveCause = (input: unknown): unknown => {
|
|
10
|
+
if (typeof input !== "object" || input === null || !("cause" in input)) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return (input as { cause?: unknown }).cause;
|
|
15
|
+
};
|
|
9
16
|
|
|
10
17
|
const inputSchema = z
|
|
11
18
|
.object({
|
|
@@ -20,7 +27,7 @@ export function generateDefaultErrors<TOptions extends Options>(
|
|
|
20
27
|
message: "Unauthorized",
|
|
21
28
|
code: "UNAUTHORIZED",
|
|
22
29
|
name: "UnauthorizedError",
|
|
23
|
-
cause: input
|
|
30
|
+
cause: resolveCause(input),
|
|
24
31
|
}),
|
|
25
32
|
options: {
|
|
26
33
|
input: inputSchema,
|
|
@@ -35,7 +42,7 @@ export function generateDefaultErrors<TOptions extends Options>(
|
|
|
35
42
|
message: "Forbidden",
|
|
36
43
|
code: "FORBIDDEN",
|
|
37
44
|
name: "ForbiddenError",
|
|
38
|
-
cause: input
|
|
45
|
+
cause: resolveCause(input),
|
|
39
46
|
}),
|
|
40
47
|
options: {
|
|
41
48
|
input: inputSchema,
|
|
@@ -50,7 +57,7 @@ export function generateDefaultErrors<TOptions extends Options>(
|
|
|
50
57
|
message: "Not Found",
|
|
51
58
|
code: "NOT_FOUND",
|
|
52
59
|
name: "NotFoundError",
|
|
53
|
-
cause: input
|
|
60
|
+
cause: resolveCause(input),
|
|
54
61
|
}),
|
|
55
62
|
options: {
|
|
56
63
|
input: inputSchema,
|
|
@@ -65,7 +72,7 @@ export function generateDefaultErrors<TOptions extends Options>(
|
|
|
65
72
|
message: "Bad Request",
|
|
66
73
|
code: "BAD_REQUEST",
|
|
67
74
|
name: "BadRequestError",
|
|
68
|
-
cause: input
|
|
75
|
+
cause: resolveCause(input),
|
|
69
76
|
}),
|
|
70
77
|
options: {
|
|
71
78
|
input: inputSchema,
|
|
@@ -80,7 +87,7 @@ export function generateDefaultErrors<TOptions extends Options>(
|
|
|
80
87
|
message: "Conflict",
|
|
81
88
|
code: "CONFLICT",
|
|
82
89
|
name: "ConflictError",
|
|
83
|
-
cause: input
|
|
90
|
+
cause: resolveCause(input),
|
|
84
91
|
}),
|
|
85
92
|
options: {
|
|
86
93
|
input: inputSchema,
|
|
@@ -95,7 +102,7 @@ export function generateDefaultErrors<TOptions extends Options>(
|
|
|
95
102
|
message: "Too Many Requests",
|
|
96
103
|
code: "TOO_MANY_REQUESTS",
|
|
97
104
|
name: "TooManyRequestsError",
|
|
98
|
-
cause: input
|
|
105
|
+
cause: resolveCause(input),
|
|
99
106
|
}),
|
|
100
107
|
options: {
|
|
101
108
|
input: inputSchema,
|
|
@@ -110,7 +117,7 @@ export function generateDefaultErrors<TOptions extends Options>(
|
|
|
110
117
|
message: "Internal Server Error",
|
|
111
118
|
code: "INTERNAL_SERVER_ERROR",
|
|
112
119
|
name: "InternalServerError",
|
|
113
|
-
cause: input
|
|
120
|
+
cause: resolveCause(input),
|
|
114
121
|
}),
|
|
115
122
|
options: {
|
|
116
123
|
input: inputSchema,
|
package/src/error/index.ts
CHANGED
|
@@ -28,6 +28,22 @@ export type DefaultError = {
|
|
|
28
28
|
stack?: string[];
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
type InferErrorHandlerInput<
|
|
32
|
+
THandlerOptions extends ErrorHandlerOptions | undefined,
|
|
33
|
+
> = THandlerOptions extends {
|
|
34
|
+
input: infer TSchema;
|
|
35
|
+
}
|
|
36
|
+
? TSchema extends Schema
|
|
37
|
+
? Infer<TSchema>
|
|
38
|
+
: never
|
|
39
|
+
: THandlerOptions extends {
|
|
40
|
+
input?: infer TSchema;
|
|
41
|
+
}
|
|
42
|
+
? TSchema extends Schema
|
|
43
|
+
? Infer<TSchema> | undefined
|
|
44
|
+
: undefined
|
|
45
|
+
: never;
|
|
46
|
+
|
|
31
47
|
export type ErrorHandler<
|
|
32
48
|
TOptions extends Options,
|
|
33
49
|
THandlerOptions extends ErrorHandlerOptions | undefined,
|
|
@@ -35,9 +51,7 @@ export type ErrorHandler<
|
|
|
35
51
|
meta: TOptions["meta"] extends undefined
|
|
36
52
|
? never
|
|
37
53
|
: Infer<ExtractSchema<TOptions["meta"]>>;
|
|
38
|
-
input: THandlerOptions
|
|
39
|
-
? never
|
|
40
|
-
: Infer<Exclude<THandlerOptions, undefined>["input"]>;
|
|
54
|
+
input: InferErrorHandlerInput<THandlerOptions>;
|
|
41
55
|
}) => ErrorOptions.InferedSchema<TOptions>;
|
|
42
56
|
|
|
43
57
|
export interface ErrorHandlerOptions<TSchema extends Schema = Schema> {
|