zod-error-map 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +193 -0
- package/dist/index.d.cts +79 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.js +153 -0
- package/package.json +16 -9
- package/src/adapters/index.js +0 -4
- package/src/adapters/zod/index.js +0 -4
- package/src/adapters/zod/integration.js +0 -31
- package/src/core/constants/error-codes.js +0 -32
- package/src/core/constants/index.js +0 -1
- package/src/core/index.js +0 -1
- package/src/core/types/index.js +0 -37
- package/src/domain/builders/index.js +0 -10
- package/src/domain/builders/message-builders.js +0 -108
- package/src/domain/index.js +0 -15
- package/src/domain/mappers/error-mapper.js +0 -87
- package/src/domain/mappers/index.js +0 -4
- package/src/index.d.ts +0 -77
- package/src/index.js +0 -19
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.js
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ErrorCode: () => ErrorCode,
|
|
24
|
+
FormatType: () => FormatType,
|
|
25
|
+
buildInvalidTypeMessage: () => buildInvalidTypeMessage,
|
|
26
|
+
buildTooBigMessage: () => buildTooBigMessage,
|
|
27
|
+
buildTooSmallMessage: () => buildTooSmallMessage,
|
|
28
|
+
createCustomMessageBuilder: () => createCustomMessageBuilder,
|
|
29
|
+
createDefaultBuilders: () => createDefaultBuilders,
|
|
30
|
+
createErrorMapper: () => createErrorMapper,
|
|
31
|
+
createFormatMessageBuilder: () => createFormatMessageBuilder,
|
|
32
|
+
createZodErrorMap: () => createZodErrorMap,
|
|
33
|
+
defaultErrorMapper: () => defaultErrorMapper,
|
|
34
|
+
defaultFormatMessages: () => defaultFormatMessages,
|
|
35
|
+
getInputDescription: () => getInputDescription,
|
|
36
|
+
setZodErrorMap: () => setZodErrorMap
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(index_exports);
|
|
39
|
+
|
|
40
|
+
// src/core/constants/error-codes.js
|
|
41
|
+
var ErrorCode = (
|
|
42
|
+
/** @type {const} */
|
|
43
|
+
{
|
|
44
|
+
INVALID_TYPE: "invalid_type",
|
|
45
|
+
TOO_SMALL: "too_small",
|
|
46
|
+
TOO_BIG: "too_big",
|
|
47
|
+
INVALID_FORMAT: "invalid_format",
|
|
48
|
+
CUSTOM: "custom"
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
var FormatType = (
|
|
52
|
+
/** @type {const} */
|
|
53
|
+
{
|
|
54
|
+
EMAIL: "email",
|
|
55
|
+
UUID: "uuid",
|
|
56
|
+
URL: "url",
|
|
57
|
+
REGEX: "regex",
|
|
58
|
+
CUID: "cuid",
|
|
59
|
+
CUID2: "cuid2",
|
|
60
|
+
ULID: "ulid",
|
|
61
|
+
IP: "ip",
|
|
62
|
+
EMOJI: "emoji",
|
|
63
|
+
DATE: "date",
|
|
64
|
+
DATETIME: "datetime",
|
|
65
|
+
TIME: "time"
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// src/domain/builders/message-builders.js
|
|
70
|
+
function getInputDescription(input) {
|
|
71
|
+
if (input === void 0) return "undefined";
|
|
72
|
+
if (input === null) return "null";
|
|
73
|
+
if (Array.isArray(input)) return "array";
|
|
74
|
+
return typeof input;
|
|
75
|
+
}
|
|
76
|
+
var defaultFormatMessages = {
|
|
77
|
+
[FormatType.EMAIL]: (label) => `The ${label.quoted} must be a valid email address`,
|
|
78
|
+
[FormatType.UUID]: (label) => `The ${label.quoted} must be a valid UUID`,
|
|
79
|
+
[FormatType.URL]: (label) => `The ${label.quoted} is invalid`,
|
|
80
|
+
[FormatType.REGEX]: (label) => `The ${label.quoted} has an invalid format`,
|
|
81
|
+
[FormatType.CUID]: (label) => `The ${label.quoted} must be a valid CUID`,
|
|
82
|
+
[FormatType.CUID2]: (label) => `The ${label.quoted} must be a valid CUID2`,
|
|
83
|
+
[FormatType.ULID]: (label) => `The ${label.quoted} must be a valid ULID`,
|
|
84
|
+
[FormatType.IP]: (label) => `The ${label.quoted} must be a valid IP address`,
|
|
85
|
+
[FormatType.DATE]: (label) => `The ${label.quoted} must be a valid date`,
|
|
86
|
+
[FormatType.DATETIME]: (label) => `The ${label.quoted} must be a valid datetime`,
|
|
87
|
+
[FormatType.TIME]: (label) => `The ${label.quoted} must be a valid time`
|
|
88
|
+
};
|
|
89
|
+
function buildInvalidTypeMessage(issue, label) {
|
|
90
|
+
const received = getInputDescription(issue.input);
|
|
91
|
+
if (received === "undefined") {
|
|
92
|
+
return `The ${label.bare} is required`;
|
|
93
|
+
}
|
|
94
|
+
return `Expected ${issue.expected} for ${label.quoted}, received ${received}`;
|
|
95
|
+
}
|
|
96
|
+
function buildTooSmallMessage(issue, label) {
|
|
97
|
+
const min = Number(issue.minimum) || 0;
|
|
98
|
+
return `The ${label.quoted} must contain at least ${min} characters`;
|
|
99
|
+
}
|
|
100
|
+
function buildTooBigMessage(issue, label) {
|
|
101
|
+
const max = Number(issue.maximum) || 0;
|
|
102
|
+
return `The ${label.quoted} must contain at most ${max} characters`;
|
|
103
|
+
}
|
|
104
|
+
function createFormatMessageBuilder(formatMessages = defaultFormatMessages) {
|
|
105
|
+
return (issue, label) => {
|
|
106
|
+
const format = issue.format || "";
|
|
107
|
+
const messageBuilder = formatMessages[format];
|
|
108
|
+
if (messageBuilder) {
|
|
109
|
+
return messageBuilder(label);
|
|
110
|
+
}
|
|
111
|
+
return `The ${label.quoted} has an invalid format`;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function createCustomMessageBuilder(defaultError) {
|
|
115
|
+
return (issue, _label) => issue.message || defaultError;
|
|
116
|
+
}
|
|
117
|
+
function createDefaultBuilders(defaultError, formatMessages) {
|
|
118
|
+
return {
|
|
119
|
+
[ErrorCode.INVALID_TYPE]: buildInvalidTypeMessage,
|
|
120
|
+
[ErrorCode.TOO_SMALL]: buildTooSmallMessage,
|
|
121
|
+
[ErrorCode.TOO_BIG]: buildTooBigMessage,
|
|
122
|
+
[ErrorCode.INVALID_FORMAT]: createFormatMessageBuilder(formatMessages),
|
|
123
|
+
[ErrorCode.CUSTOM]: createCustomMessageBuilder(defaultError)
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/domain/mappers/error-mapper.js
|
|
128
|
+
var DEFAULT_ERROR = "Invalid input";
|
|
129
|
+
function isRawIssue(issue) {
|
|
130
|
+
return typeof issue === "object" && issue !== null && "code" in issue;
|
|
131
|
+
}
|
|
132
|
+
function getLabel(issue) {
|
|
133
|
+
const path = issue.path ?? [];
|
|
134
|
+
const field = path[path.length - 1];
|
|
135
|
+
if (typeof field === "string") {
|
|
136
|
+
return { bare: field, quoted: `'${field}'` };
|
|
137
|
+
}
|
|
138
|
+
return { bare: "value", quoted: "value" };
|
|
139
|
+
}
|
|
140
|
+
function createErrorMapper(config = {}) {
|
|
141
|
+
const defaultError = config.defaultError ?? DEFAULT_ERROR;
|
|
142
|
+
const defaultBuilders = createDefaultBuilders(defaultError, config.formatMessages);
|
|
143
|
+
const builders = { ...defaultBuilders, ...config.builders };
|
|
144
|
+
function buildMessage(issue) {
|
|
145
|
+
const label = getLabel(issue);
|
|
146
|
+
const builder = builders[issue.code];
|
|
147
|
+
if (builder) {
|
|
148
|
+
return builder(issue, label);
|
|
149
|
+
}
|
|
150
|
+
return issue.message || defaultError;
|
|
151
|
+
}
|
|
152
|
+
function format(issue) {
|
|
153
|
+
if (!isRawIssue(issue)) return defaultError;
|
|
154
|
+
return buildMessage(issue);
|
|
155
|
+
}
|
|
156
|
+
function createErrorMap() {
|
|
157
|
+
return format;
|
|
158
|
+
}
|
|
159
|
+
return { format, createErrorMap };
|
|
160
|
+
}
|
|
161
|
+
var defaultErrorMapper = createErrorMapper();
|
|
162
|
+
|
|
163
|
+
// src/adapters/zod/integration.js
|
|
164
|
+
function setZodErrorMap(z, config) {
|
|
165
|
+
const mapper = createErrorMapper(config);
|
|
166
|
+
z.config({
|
|
167
|
+
customError: (issue) => mapper.format(issue)
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function createZodErrorMap(config) {
|
|
171
|
+
const mapper = createErrorMapper(config);
|
|
172
|
+
return (issue, _ctx) => {
|
|
173
|
+
const message = mapper.format(issue);
|
|
174
|
+
return { message };
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
178
|
+
0 && (module.exports = {
|
|
179
|
+
ErrorCode,
|
|
180
|
+
FormatType,
|
|
181
|
+
buildInvalidTypeMessage,
|
|
182
|
+
buildTooBigMessage,
|
|
183
|
+
buildTooSmallMessage,
|
|
184
|
+
createCustomMessageBuilder,
|
|
185
|
+
createDefaultBuilders,
|
|
186
|
+
createErrorMapper,
|
|
187
|
+
createFormatMessageBuilder,
|
|
188
|
+
createZodErrorMap,
|
|
189
|
+
defaultErrorMapper,
|
|
190
|
+
defaultFormatMessages,
|
|
191
|
+
getInputDescription,
|
|
192
|
+
setZodErrorMap
|
|
193
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as zod from 'zod';
|
|
2
|
+
|
|
3
|
+
interface Label {
|
|
4
|
+
bare: string
|
|
5
|
+
quoted: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface RawIssue {
|
|
9
|
+
code: string
|
|
10
|
+
path: Array<string | number>
|
|
11
|
+
input?: unknown
|
|
12
|
+
expected?: string
|
|
13
|
+
minimum?: number
|
|
14
|
+
maximum?: number
|
|
15
|
+
format?: string
|
|
16
|
+
message?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type MessageBuilder = (issue: RawIssue, label: Label) => string
|
|
20
|
+
|
|
21
|
+
type FormatMessageBuilder = (label: Label) => string
|
|
22
|
+
|
|
23
|
+
interface ErrorMapConfig {
|
|
24
|
+
defaultError?: string
|
|
25
|
+
builders?: Record<string, MessageBuilder>
|
|
26
|
+
formatMessages?: Record<string, FormatMessageBuilder>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface ErrorMapper {
|
|
30
|
+
format: (issue: unknown) => string
|
|
31
|
+
createErrorMap: () => (issue: unknown) => string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare const ErrorCode: {
|
|
35
|
+
readonly INVALID_TYPE: 'invalid_type'
|
|
36
|
+
readonly TOO_SMALL: 'too_small'
|
|
37
|
+
readonly TOO_BIG: 'too_big'
|
|
38
|
+
readonly INVALID_FORMAT: 'invalid_format'
|
|
39
|
+
readonly CUSTOM: 'custom'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
declare const FormatType: {
|
|
43
|
+
readonly EMAIL: 'email'
|
|
44
|
+
readonly UUID: 'uuid'
|
|
45
|
+
readonly URL: 'url'
|
|
46
|
+
readonly REGEX: 'regex'
|
|
47
|
+
readonly CUID: 'cuid'
|
|
48
|
+
readonly CUID2: 'cuid2'
|
|
49
|
+
readonly ULID: 'ulid'
|
|
50
|
+
readonly IP: 'ip'
|
|
51
|
+
readonly EMOJI: 'emoji'
|
|
52
|
+
readonly DATE: 'date'
|
|
53
|
+
readonly DATETIME: 'datetime'
|
|
54
|
+
readonly TIME: 'time'
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
declare function createErrorMapper(config?: ErrorMapConfig): ErrorMapper
|
|
58
|
+
declare const defaultErrorMapper: ErrorMapper
|
|
59
|
+
|
|
60
|
+
declare function getInputDescription(input: unknown): string
|
|
61
|
+
declare const defaultFormatMessages: Record<string, (label: Label) => string>
|
|
62
|
+
declare function buildInvalidTypeMessage(issue: RawIssue, label: Label): string
|
|
63
|
+
declare function buildTooSmallMessage(issue: RawIssue, label: Label): string
|
|
64
|
+
declare function buildTooBigMessage(issue: RawIssue, label: Label): string
|
|
65
|
+
declare function createFormatMessageBuilder(
|
|
66
|
+
formatMessages?: Record<string, (label: Label) => string>
|
|
67
|
+
): MessageBuilder
|
|
68
|
+
declare function createCustomMessageBuilder(defaultError: string): MessageBuilder
|
|
69
|
+
declare function createDefaultBuilders(
|
|
70
|
+
defaultError: string,
|
|
71
|
+
formatMessages?: Record<string, (label: Label) => string>
|
|
72
|
+
): Record<string, MessageBuilder>
|
|
73
|
+
|
|
74
|
+
declare function setZodErrorMap(z: typeof zod.z, config?: ErrorMapConfig): void
|
|
75
|
+
declare function createZodErrorMap(
|
|
76
|
+
config?: ErrorMapConfig
|
|
77
|
+
): (issue: unknown, ctx: unknown) => { message: string }
|
|
78
|
+
|
|
79
|
+
export { ErrorCode, type ErrorMapConfig, type ErrorMapper, type FormatMessageBuilder, FormatType, type Label, type MessageBuilder, type RawIssue, buildInvalidTypeMessage, buildTooBigMessage, buildTooSmallMessage, createCustomMessageBuilder, createDefaultBuilders, createErrorMapper, createFormatMessageBuilder, createZodErrorMap, defaultErrorMapper, defaultFormatMessages, getInputDescription, setZodErrorMap };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as zod from 'zod';
|
|
2
|
+
|
|
3
|
+
interface Label {
|
|
4
|
+
bare: string
|
|
5
|
+
quoted: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface RawIssue {
|
|
9
|
+
code: string
|
|
10
|
+
path: Array<string | number>
|
|
11
|
+
input?: unknown
|
|
12
|
+
expected?: string
|
|
13
|
+
minimum?: number
|
|
14
|
+
maximum?: number
|
|
15
|
+
format?: string
|
|
16
|
+
message?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type MessageBuilder = (issue: RawIssue, label: Label) => string
|
|
20
|
+
|
|
21
|
+
type FormatMessageBuilder = (label: Label) => string
|
|
22
|
+
|
|
23
|
+
interface ErrorMapConfig {
|
|
24
|
+
defaultError?: string
|
|
25
|
+
builders?: Record<string, MessageBuilder>
|
|
26
|
+
formatMessages?: Record<string, FormatMessageBuilder>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface ErrorMapper {
|
|
30
|
+
format: (issue: unknown) => string
|
|
31
|
+
createErrorMap: () => (issue: unknown) => string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare const ErrorCode: {
|
|
35
|
+
readonly INVALID_TYPE: 'invalid_type'
|
|
36
|
+
readonly TOO_SMALL: 'too_small'
|
|
37
|
+
readonly TOO_BIG: 'too_big'
|
|
38
|
+
readonly INVALID_FORMAT: 'invalid_format'
|
|
39
|
+
readonly CUSTOM: 'custom'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
declare const FormatType: {
|
|
43
|
+
readonly EMAIL: 'email'
|
|
44
|
+
readonly UUID: 'uuid'
|
|
45
|
+
readonly URL: 'url'
|
|
46
|
+
readonly REGEX: 'regex'
|
|
47
|
+
readonly CUID: 'cuid'
|
|
48
|
+
readonly CUID2: 'cuid2'
|
|
49
|
+
readonly ULID: 'ulid'
|
|
50
|
+
readonly IP: 'ip'
|
|
51
|
+
readonly EMOJI: 'emoji'
|
|
52
|
+
readonly DATE: 'date'
|
|
53
|
+
readonly DATETIME: 'datetime'
|
|
54
|
+
readonly TIME: 'time'
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
declare function createErrorMapper(config?: ErrorMapConfig): ErrorMapper
|
|
58
|
+
declare const defaultErrorMapper: ErrorMapper
|
|
59
|
+
|
|
60
|
+
declare function getInputDescription(input: unknown): string
|
|
61
|
+
declare const defaultFormatMessages: Record<string, (label: Label) => string>
|
|
62
|
+
declare function buildInvalidTypeMessage(issue: RawIssue, label: Label): string
|
|
63
|
+
declare function buildTooSmallMessage(issue: RawIssue, label: Label): string
|
|
64
|
+
declare function buildTooBigMessage(issue: RawIssue, label: Label): string
|
|
65
|
+
declare function createFormatMessageBuilder(
|
|
66
|
+
formatMessages?: Record<string, (label: Label) => string>
|
|
67
|
+
): MessageBuilder
|
|
68
|
+
declare function createCustomMessageBuilder(defaultError: string): MessageBuilder
|
|
69
|
+
declare function createDefaultBuilders(
|
|
70
|
+
defaultError: string,
|
|
71
|
+
formatMessages?: Record<string, (label: Label) => string>
|
|
72
|
+
): Record<string, MessageBuilder>
|
|
73
|
+
|
|
74
|
+
declare function setZodErrorMap(z: typeof zod.z, config?: ErrorMapConfig): void
|
|
75
|
+
declare function createZodErrorMap(
|
|
76
|
+
config?: ErrorMapConfig
|
|
77
|
+
): (issue: unknown, ctx: unknown) => { message: string }
|
|
78
|
+
|
|
79
|
+
export { ErrorCode, type ErrorMapConfig, type ErrorMapper, type FormatMessageBuilder, FormatType, type Label, type MessageBuilder, type RawIssue, buildInvalidTypeMessage, buildTooBigMessage, buildTooSmallMessage, createCustomMessageBuilder, createDefaultBuilders, createErrorMapper, createFormatMessageBuilder, createZodErrorMap, defaultErrorMapper, defaultFormatMessages, getInputDescription, setZodErrorMap };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// src/core/constants/error-codes.js
|
|
2
|
+
var ErrorCode = (
|
|
3
|
+
/** @type {const} */
|
|
4
|
+
{
|
|
5
|
+
INVALID_TYPE: "invalid_type",
|
|
6
|
+
TOO_SMALL: "too_small",
|
|
7
|
+
TOO_BIG: "too_big",
|
|
8
|
+
INVALID_FORMAT: "invalid_format",
|
|
9
|
+
CUSTOM: "custom"
|
|
10
|
+
}
|
|
11
|
+
);
|
|
12
|
+
var FormatType = (
|
|
13
|
+
/** @type {const} */
|
|
14
|
+
{
|
|
15
|
+
EMAIL: "email",
|
|
16
|
+
UUID: "uuid",
|
|
17
|
+
URL: "url",
|
|
18
|
+
REGEX: "regex",
|
|
19
|
+
CUID: "cuid",
|
|
20
|
+
CUID2: "cuid2",
|
|
21
|
+
ULID: "ulid",
|
|
22
|
+
IP: "ip",
|
|
23
|
+
EMOJI: "emoji",
|
|
24
|
+
DATE: "date",
|
|
25
|
+
DATETIME: "datetime",
|
|
26
|
+
TIME: "time"
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
// src/domain/builders/message-builders.js
|
|
31
|
+
function getInputDescription(input) {
|
|
32
|
+
if (input === void 0) return "undefined";
|
|
33
|
+
if (input === null) return "null";
|
|
34
|
+
if (Array.isArray(input)) return "array";
|
|
35
|
+
return typeof input;
|
|
36
|
+
}
|
|
37
|
+
var defaultFormatMessages = {
|
|
38
|
+
[FormatType.EMAIL]: (label) => `The ${label.quoted} must be a valid email address`,
|
|
39
|
+
[FormatType.UUID]: (label) => `The ${label.quoted} must be a valid UUID`,
|
|
40
|
+
[FormatType.URL]: (label) => `The ${label.quoted} is invalid`,
|
|
41
|
+
[FormatType.REGEX]: (label) => `The ${label.quoted} has an invalid format`,
|
|
42
|
+
[FormatType.CUID]: (label) => `The ${label.quoted} must be a valid CUID`,
|
|
43
|
+
[FormatType.CUID2]: (label) => `The ${label.quoted} must be a valid CUID2`,
|
|
44
|
+
[FormatType.ULID]: (label) => `The ${label.quoted} must be a valid ULID`,
|
|
45
|
+
[FormatType.IP]: (label) => `The ${label.quoted} must be a valid IP address`,
|
|
46
|
+
[FormatType.DATE]: (label) => `The ${label.quoted} must be a valid date`,
|
|
47
|
+
[FormatType.DATETIME]: (label) => `The ${label.quoted} must be a valid datetime`,
|
|
48
|
+
[FormatType.TIME]: (label) => `The ${label.quoted} must be a valid time`
|
|
49
|
+
};
|
|
50
|
+
function buildInvalidTypeMessage(issue, label) {
|
|
51
|
+
const received = getInputDescription(issue.input);
|
|
52
|
+
if (received === "undefined") {
|
|
53
|
+
return `The ${label.bare} is required`;
|
|
54
|
+
}
|
|
55
|
+
return `Expected ${issue.expected} for ${label.quoted}, received ${received}`;
|
|
56
|
+
}
|
|
57
|
+
function buildTooSmallMessage(issue, label) {
|
|
58
|
+
const min = Number(issue.minimum) || 0;
|
|
59
|
+
return `The ${label.quoted} must contain at least ${min} characters`;
|
|
60
|
+
}
|
|
61
|
+
function buildTooBigMessage(issue, label) {
|
|
62
|
+
const max = Number(issue.maximum) || 0;
|
|
63
|
+
return `The ${label.quoted} must contain at most ${max} characters`;
|
|
64
|
+
}
|
|
65
|
+
function createFormatMessageBuilder(formatMessages = defaultFormatMessages) {
|
|
66
|
+
return (issue, label) => {
|
|
67
|
+
const format = issue.format || "";
|
|
68
|
+
const messageBuilder = formatMessages[format];
|
|
69
|
+
if (messageBuilder) {
|
|
70
|
+
return messageBuilder(label);
|
|
71
|
+
}
|
|
72
|
+
return `The ${label.quoted} has an invalid format`;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function createCustomMessageBuilder(defaultError) {
|
|
76
|
+
return (issue, _label) => issue.message || defaultError;
|
|
77
|
+
}
|
|
78
|
+
function createDefaultBuilders(defaultError, formatMessages) {
|
|
79
|
+
return {
|
|
80
|
+
[ErrorCode.INVALID_TYPE]: buildInvalidTypeMessage,
|
|
81
|
+
[ErrorCode.TOO_SMALL]: buildTooSmallMessage,
|
|
82
|
+
[ErrorCode.TOO_BIG]: buildTooBigMessage,
|
|
83
|
+
[ErrorCode.INVALID_FORMAT]: createFormatMessageBuilder(formatMessages),
|
|
84
|
+
[ErrorCode.CUSTOM]: createCustomMessageBuilder(defaultError)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/domain/mappers/error-mapper.js
|
|
89
|
+
var DEFAULT_ERROR = "Invalid input";
|
|
90
|
+
function isRawIssue(issue) {
|
|
91
|
+
return typeof issue === "object" && issue !== null && "code" in issue;
|
|
92
|
+
}
|
|
93
|
+
function getLabel(issue) {
|
|
94
|
+
const path = issue.path ?? [];
|
|
95
|
+
const field = path[path.length - 1];
|
|
96
|
+
if (typeof field === "string") {
|
|
97
|
+
return { bare: field, quoted: `'${field}'` };
|
|
98
|
+
}
|
|
99
|
+
return { bare: "value", quoted: "value" };
|
|
100
|
+
}
|
|
101
|
+
function createErrorMapper(config = {}) {
|
|
102
|
+
const defaultError = config.defaultError ?? DEFAULT_ERROR;
|
|
103
|
+
const defaultBuilders = createDefaultBuilders(defaultError, config.formatMessages);
|
|
104
|
+
const builders = { ...defaultBuilders, ...config.builders };
|
|
105
|
+
function buildMessage(issue) {
|
|
106
|
+
const label = getLabel(issue);
|
|
107
|
+
const builder = builders[issue.code];
|
|
108
|
+
if (builder) {
|
|
109
|
+
return builder(issue, label);
|
|
110
|
+
}
|
|
111
|
+
return issue.message || defaultError;
|
|
112
|
+
}
|
|
113
|
+
function format(issue) {
|
|
114
|
+
if (!isRawIssue(issue)) return defaultError;
|
|
115
|
+
return buildMessage(issue);
|
|
116
|
+
}
|
|
117
|
+
function createErrorMap() {
|
|
118
|
+
return format;
|
|
119
|
+
}
|
|
120
|
+
return { format, createErrorMap };
|
|
121
|
+
}
|
|
122
|
+
var defaultErrorMapper = createErrorMapper();
|
|
123
|
+
|
|
124
|
+
// src/adapters/zod/integration.js
|
|
125
|
+
function setZodErrorMap(z, config) {
|
|
126
|
+
const mapper = createErrorMapper(config);
|
|
127
|
+
z.config({
|
|
128
|
+
customError: (issue) => mapper.format(issue)
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function createZodErrorMap(config) {
|
|
132
|
+
const mapper = createErrorMapper(config);
|
|
133
|
+
return (issue, _ctx) => {
|
|
134
|
+
const message = mapper.format(issue);
|
|
135
|
+
return { message };
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
export {
|
|
139
|
+
ErrorCode,
|
|
140
|
+
FormatType,
|
|
141
|
+
buildInvalidTypeMessage,
|
|
142
|
+
buildTooBigMessage,
|
|
143
|
+
buildTooSmallMessage,
|
|
144
|
+
createCustomMessageBuilder,
|
|
145
|
+
createDefaultBuilders,
|
|
146
|
+
createErrorMapper,
|
|
147
|
+
createFormatMessageBuilder,
|
|
148
|
+
createZodErrorMap,
|
|
149
|
+
defaultErrorMapper,
|
|
150
|
+
defaultFormatMessages,
|
|
151
|
+
getInputDescription,
|
|
152
|
+
setZodErrorMap
|
|
153
|
+
};
|
package/package.json
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zod-error-map",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Type-safe, customizable error message mapping for Zod validation",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "
|
|
7
|
-
"
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
|
-
"import":
|
|
11
|
-
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
12
19
|
}
|
|
13
20
|
},
|
|
14
21
|
"files": [
|
|
15
|
-
"
|
|
16
|
-
"src/**/*.d.ts",
|
|
17
|
-
"!src/**/*.test.js"
|
|
22
|
+
"dist"
|
|
18
23
|
],
|
|
19
24
|
"scripts": {
|
|
20
|
-
"
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"test": "node --test tests/*.test.js",
|
|
21
27
|
"typecheck": "tsc"
|
|
22
28
|
},
|
|
23
29
|
"keywords": [
|
|
@@ -42,6 +48,7 @@
|
|
|
42
48
|
"zod": "^3.0.0 || ^4.0.0"
|
|
43
49
|
},
|
|
44
50
|
"devDependencies": {
|
|
51
|
+
"tsup": "^8.0.0",
|
|
45
52
|
"typescript": "^5.0.0",
|
|
46
53
|
"zod": "^4.1.0"
|
|
47
54
|
},
|
package/src/adapters/index.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {import('../../core/types/index.js').ErrorMapConfig} ErrorMapConfig
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { createErrorMapper } from '../../domain/mappers/index.js'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Sets the global Zod error map using z.config()
|
|
9
|
-
* @param {import('zod')} z - The Zod instance
|
|
10
|
-
* @param {ErrorMapConfig} [config] - Optional configuration
|
|
11
|
-
* @returns {void}
|
|
12
|
-
*/
|
|
13
|
-
export function setZodErrorMap(z, config) {
|
|
14
|
-
const mapper = createErrorMapper(config)
|
|
15
|
-
z.config({
|
|
16
|
-
customError: (issue) => mapper.format(issue),
|
|
17
|
-
})
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Creates a Zod error map function compatible with z.setErrorMap() (Zod v3)
|
|
22
|
-
* @param {ErrorMapConfig} [config] - Optional configuration
|
|
23
|
-
* @returns {(issue: unknown, ctx: unknown) => { message: string }}
|
|
24
|
-
*/
|
|
25
|
-
export function createZodErrorMap(config) {
|
|
26
|
-
const mapper = createErrorMapper(config)
|
|
27
|
-
return (issue, _ctx) => {
|
|
28
|
-
const message = mapper.format(issue)
|
|
29
|
-
return { message }
|
|
30
|
-
}
|
|
31
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Zod error codes
|
|
3
|
-
* @readonly
|
|
4
|
-
* @enum {string}
|
|
5
|
-
*/
|
|
6
|
-
export const ErrorCode = /** @type {const} */ ({
|
|
7
|
-
INVALID_TYPE: 'invalid_type',
|
|
8
|
-
TOO_SMALL: 'too_small',
|
|
9
|
-
TOO_BIG: 'too_big',
|
|
10
|
-
INVALID_FORMAT: 'invalid_format',
|
|
11
|
-
CUSTOM: 'custom',
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Format types for invalid_format errors
|
|
16
|
-
* @readonly
|
|
17
|
-
* @enum {string}
|
|
18
|
-
*/
|
|
19
|
-
export const FormatType = /** @type {const} */ ({
|
|
20
|
-
EMAIL: 'email',
|
|
21
|
-
UUID: 'uuid',
|
|
22
|
-
URL: 'url',
|
|
23
|
-
REGEX: 'regex',
|
|
24
|
-
CUID: 'cuid',
|
|
25
|
-
CUID2: 'cuid2',
|
|
26
|
-
ULID: 'ulid',
|
|
27
|
-
IP: 'ip',
|
|
28
|
-
EMOJI: 'emoji',
|
|
29
|
-
DATE: 'date',
|
|
30
|
-
DATETIME: 'datetime',
|
|
31
|
-
TIME: 'time',
|
|
32
|
-
})
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ErrorCode, FormatType } from './error-codes.js'
|
package/src/core/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ErrorCode, FormatType } from './constants/index.js'
|
package/src/core/types/index.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {object} Label
|
|
3
|
-
* @property {string} bare - The field name without quotes
|
|
4
|
-
* @property {string} quoted - The field name with quotes
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {object} RawIssue
|
|
9
|
-
* @property {string} code - The error code from Zod
|
|
10
|
-
* @property {Array<string | number>} path - The path to the field
|
|
11
|
-
* @property {unknown} [input] - The input value that caused the error
|
|
12
|
-
* @property {string} [expected] - The expected type
|
|
13
|
-
* @property {number} [minimum] - Minimum value/length constraint
|
|
14
|
-
* @property {number} [maximum] - Maximum value/length constraint
|
|
15
|
-
* @property {string} [format] - Format type (email, uuid, url, etc.)
|
|
16
|
-
* @property {string} [message] - Custom error message
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @callback MessageBuilder
|
|
21
|
-
* @param {RawIssue} issue - The raw Zod issue
|
|
22
|
-
* @param {Label} label - The field label
|
|
23
|
-
* @returns {string} The formatted error message
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* @typedef {(label: Label) => string} FormatMessageBuilder
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @typedef {object} ErrorMapConfig
|
|
32
|
-
* @property {string} [defaultError] - Default error message
|
|
33
|
-
* @property {Record<string, MessageBuilder>} [builders] - Custom message builders by error code
|
|
34
|
-
* @property {Record<string, FormatMessageBuilder>} [formatMessages] - Custom messages for format errors
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
export {}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { ErrorCode, FormatType } from '../../core/constants/index.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {import('../../core/types/index.js').RawIssue} RawIssue
|
|
5
|
-
* @typedef {import('../../core/types/index.js').Label} Label
|
|
6
|
-
* @typedef {import('../../core/types/index.js').MessageBuilder} MessageBuilder
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Gets a human-readable description of the input type
|
|
11
|
-
* @param {unknown} input
|
|
12
|
-
* @returns {string}
|
|
13
|
-
*/
|
|
14
|
-
export function getInputDescription(input) {
|
|
15
|
-
if (input === undefined) return 'undefined'
|
|
16
|
-
if (input === null) return 'null'
|
|
17
|
-
if (Array.isArray(input)) return 'array'
|
|
18
|
-
return typeof input
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Default format error messages
|
|
23
|
-
* @type {Record<string, (label: Label) => string>}
|
|
24
|
-
*/
|
|
25
|
-
export const defaultFormatMessages = {
|
|
26
|
-
[FormatType.EMAIL]: (label) => `The ${label.quoted} must be a valid email address`,
|
|
27
|
-
[FormatType.UUID]: (label) => `The ${label.quoted} must be a valid UUID`,
|
|
28
|
-
[FormatType.URL]: (label) => `The ${label.quoted} is invalid`,
|
|
29
|
-
[FormatType.REGEX]: (label) => `The ${label.quoted} has an invalid format`,
|
|
30
|
-
[FormatType.CUID]: (label) => `The ${label.quoted} must be a valid CUID`,
|
|
31
|
-
[FormatType.CUID2]: (label) => `The ${label.quoted} must be a valid CUID2`,
|
|
32
|
-
[FormatType.ULID]: (label) => `The ${label.quoted} must be a valid ULID`,
|
|
33
|
-
[FormatType.IP]: (label) => `The ${label.quoted} must be a valid IP address`,
|
|
34
|
-
[FormatType.DATE]: (label) => `The ${label.quoted} must be a valid date`,
|
|
35
|
-
[FormatType.DATETIME]: (label) => `The ${label.quoted} must be a valid datetime`,
|
|
36
|
-
[FormatType.TIME]: (label) => `The ${label.quoted} must be a valid time`,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Builds error message for invalid_type errors
|
|
41
|
-
* @type {MessageBuilder}
|
|
42
|
-
*/
|
|
43
|
-
export function buildInvalidTypeMessage(issue, label) {
|
|
44
|
-
const received = getInputDescription(issue.input)
|
|
45
|
-
if (received === 'undefined') {
|
|
46
|
-
return `The ${label.bare} is required`
|
|
47
|
-
}
|
|
48
|
-
return `Expected ${issue.expected} for ${label.quoted}, received ${received}`
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Builds error message for too_small errors
|
|
53
|
-
* @type {MessageBuilder}
|
|
54
|
-
*/
|
|
55
|
-
export function buildTooSmallMessage(issue, label) {
|
|
56
|
-
const min = Number(issue.minimum) || 0
|
|
57
|
-
return `The ${label.quoted} must contain at least ${min} characters`
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Builds error message for too_big errors
|
|
62
|
-
* @type {MessageBuilder}
|
|
63
|
-
*/
|
|
64
|
-
export function buildTooBigMessage(issue, label) {
|
|
65
|
-
const max = Number(issue.maximum) || 0
|
|
66
|
-
return `The ${label.quoted} must contain at most ${max} characters`
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Creates a format message builder with custom format messages
|
|
71
|
-
* @param {Record<string, (label: Label) => string>} [formatMessages]
|
|
72
|
-
* @returns {MessageBuilder}
|
|
73
|
-
*/
|
|
74
|
-
export function createFormatMessageBuilder(formatMessages = defaultFormatMessages) {
|
|
75
|
-
return (issue, label) => {
|
|
76
|
-
const format = issue.format || ''
|
|
77
|
-
const messageBuilder = formatMessages[format]
|
|
78
|
-
if (messageBuilder) {
|
|
79
|
-
return messageBuilder(label)
|
|
80
|
-
}
|
|
81
|
-
return `The ${label.quoted} has an invalid format`
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Builds error message for custom errors
|
|
87
|
-
* @param {string} defaultError
|
|
88
|
-
* @returns {MessageBuilder}
|
|
89
|
-
*/
|
|
90
|
-
export function createCustomMessageBuilder(defaultError) {
|
|
91
|
-
return (issue, _label) => issue.message || defaultError
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Creates the default message builders map
|
|
96
|
-
* @param {string} defaultError
|
|
97
|
-
* @param {Record<string, (label: Label) => string>} [formatMessages]
|
|
98
|
-
* @returns {Record<string, MessageBuilder>}
|
|
99
|
-
*/
|
|
100
|
-
export function createDefaultBuilders(defaultError, formatMessages) {
|
|
101
|
-
return {
|
|
102
|
-
[ErrorCode.INVALID_TYPE]: buildInvalidTypeMessage,
|
|
103
|
-
[ErrorCode.TOO_SMALL]: buildTooSmallMessage,
|
|
104
|
-
[ErrorCode.TOO_BIG]: buildTooBigMessage,
|
|
105
|
-
[ErrorCode.INVALID_FORMAT]: createFormatMessageBuilder(formatMessages),
|
|
106
|
-
[ErrorCode.CUSTOM]: createCustomMessageBuilder(defaultError),
|
|
107
|
-
}
|
|
108
|
-
}
|
package/src/domain/index.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
createErrorMapper,
|
|
3
|
-
defaultErrorMapper,
|
|
4
|
-
} from './mappers/index.js'
|
|
5
|
-
|
|
6
|
-
export {
|
|
7
|
-
getInputDescription,
|
|
8
|
-
defaultFormatMessages,
|
|
9
|
-
buildInvalidTypeMessage,
|
|
10
|
-
buildTooSmallMessage,
|
|
11
|
-
buildTooBigMessage,
|
|
12
|
-
createFormatMessageBuilder,
|
|
13
|
-
createCustomMessageBuilder,
|
|
14
|
-
createDefaultBuilders,
|
|
15
|
-
} from './builders/index.js'
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { createDefaultBuilders } from '../builders/index.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {import('../../core/types/index.js').RawIssue} RawIssue
|
|
5
|
-
* @typedef {import('../../core/types/index.js').Label} Label
|
|
6
|
-
* @typedef {import('../../core/types/index.js').MessageBuilder} MessageBuilder
|
|
7
|
-
* @typedef {import('../../core/types/index.js').ErrorMapConfig} ErrorMapConfig
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const DEFAULT_ERROR = 'Invalid input'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Checks if the issue is a valid RawIssue
|
|
14
|
-
* @param {unknown} issue
|
|
15
|
-
* @returns {issue is RawIssue}
|
|
16
|
-
*/
|
|
17
|
-
function isRawIssue(issue) {
|
|
18
|
-
return (
|
|
19
|
-
typeof issue === 'object' &&
|
|
20
|
-
issue !== null &&
|
|
21
|
-
'code' in issue
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Gets the label from the issue path
|
|
27
|
-
* @param {RawIssue} issue
|
|
28
|
-
* @returns {Label}
|
|
29
|
-
*/
|
|
30
|
-
function getLabel(issue) {
|
|
31
|
-
const path = issue.path ?? []
|
|
32
|
-
const field = path[path.length - 1]
|
|
33
|
-
if (typeof field === 'string') {
|
|
34
|
-
return { bare: field, quoted: `'${field}'` }
|
|
35
|
-
}
|
|
36
|
-
return { bare: 'value', quoted: 'value' }
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Creates a Zod error mapper with customizable message builders
|
|
41
|
-
* @param {ErrorMapConfig} [config]
|
|
42
|
-
* @returns {{ format: (issue: unknown) => string, createErrorMap: () => (issue: unknown) => string }}
|
|
43
|
-
*/
|
|
44
|
-
export function createErrorMapper(config = {}) {
|
|
45
|
-
const defaultError = config.defaultError ?? DEFAULT_ERROR
|
|
46
|
-
const defaultBuilders = createDefaultBuilders(defaultError, config.formatMessages)
|
|
47
|
-
const builders = { ...defaultBuilders, ...config.builders }
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Builds the error message for a Zod issue
|
|
51
|
-
* @param {RawIssue} issue
|
|
52
|
-
* @returns {string}
|
|
53
|
-
*/
|
|
54
|
-
function buildMessage(issue) {
|
|
55
|
-
const label = getLabel(issue)
|
|
56
|
-
const builder = builders[issue.code]
|
|
57
|
-
if (builder) {
|
|
58
|
-
return builder(issue, label)
|
|
59
|
-
}
|
|
60
|
-
return issue.message || defaultError
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Formats a Zod issue into a human-readable message
|
|
65
|
-
* @param {unknown} issue
|
|
66
|
-
* @returns {string}
|
|
67
|
-
*/
|
|
68
|
-
function format(issue) {
|
|
69
|
-
if (!isRawIssue(issue)) return defaultError
|
|
70
|
-
return buildMessage(issue)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Creates an error map function for Zod
|
|
75
|
-
* @returns {(issue: unknown) => string}
|
|
76
|
-
*/
|
|
77
|
-
function createErrorMap() {
|
|
78
|
-
return format
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return { format, createErrorMap }
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Default error mapper instance
|
|
86
|
-
*/
|
|
87
|
-
export const defaultErrorMapper = createErrorMapper()
|
package/src/index.d.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import type { z } from 'zod'
|
|
2
|
-
|
|
3
|
-
export interface Label {
|
|
4
|
-
bare: string
|
|
5
|
-
quoted: string
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface RawIssue {
|
|
9
|
-
code: string
|
|
10
|
-
path: Array<string | number>
|
|
11
|
-
input?: unknown
|
|
12
|
-
expected?: string
|
|
13
|
-
minimum?: number
|
|
14
|
-
maximum?: number
|
|
15
|
-
format?: string
|
|
16
|
-
message?: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type MessageBuilder = (issue: RawIssue, label: Label) => string
|
|
20
|
-
|
|
21
|
-
export type FormatMessageBuilder = (label: Label) => string
|
|
22
|
-
|
|
23
|
-
export interface ErrorMapConfig {
|
|
24
|
-
defaultError?: string
|
|
25
|
-
builders?: Record<string, MessageBuilder>
|
|
26
|
-
formatMessages?: Record<string, FormatMessageBuilder>
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface ErrorMapper {
|
|
30
|
-
format: (issue: unknown) => string
|
|
31
|
-
createErrorMap: () => (issue: unknown) => string
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export declare const ErrorCode: {
|
|
35
|
-
readonly INVALID_TYPE: 'invalid_type'
|
|
36
|
-
readonly TOO_SMALL: 'too_small'
|
|
37
|
-
readonly TOO_BIG: 'too_big'
|
|
38
|
-
readonly INVALID_FORMAT: 'invalid_format'
|
|
39
|
-
readonly CUSTOM: 'custom'
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export declare const FormatType: {
|
|
43
|
-
readonly EMAIL: 'email'
|
|
44
|
-
readonly UUID: 'uuid'
|
|
45
|
-
readonly URL: 'url'
|
|
46
|
-
readonly REGEX: 'regex'
|
|
47
|
-
readonly CUID: 'cuid'
|
|
48
|
-
readonly CUID2: 'cuid2'
|
|
49
|
-
readonly ULID: 'ulid'
|
|
50
|
-
readonly IP: 'ip'
|
|
51
|
-
readonly EMOJI: 'emoji'
|
|
52
|
-
readonly DATE: 'date'
|
|
53
|
-
readonly DATETIME: 'datetime'
|
|
54
|
-
readonly TIME: 'time'
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export declare function createErrorMapper(config?: ErrorMapConfig): ErrorMapper
|
|
58
|
-
export declare const defaultErrorMapper: ErrorMapper
|
|
59
|
-
|
|
60
|
-
export declare function getInputDescription(input: unknown): string
|
|
61
|
-
export declare const defaultFormatMessages: Record<string, (label: Label) => string>
|
|
62
|
-
export declare function buildInvalidTypeMessage(issue: RawIssue, label: Label): string
|
|
63
|
-
export declare function buildTooSmallMessage(issue: RawIssue, label: Label): string
|
|
64
|
-
export declare function buildTooBigMessage(issue: RawIssue, label: Label): string
|
|
65
|
-
export declare function createFormatMessageBuilder(
|
|
66
|
-
formatMessages?: Record<string, (label: Label) => string>
|
|
67
|
-
): MessageBuilder
|
|
68
|
-
export declare function createCustomMessageBuilder(defaultError: string): MessageBuilder
|
|
69
|
-
export declare function createDefaultBuilders(
|
|
70
|
-
defaultError: string,
|
|
71
|
-
formatMessages?: Record<string, (label: Label) => string>
|
|
72
|
-
): Record<string, MessageBuilder>
|
|
73
|
-
|
|
74
|
-
export declare function setZodErrorMap(z: typeof import('zod').z, config?: ErrorMapConfig): void
|
|
75
|
-
export declare function createZodErrorMap(
|
|
76
|
-
config?: ErrorMapConfig
|
|
77
|
-
): (issue: unknown, ctx: unknown) => { message: string }
|
package/src/index.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export { ErrorCode, FormatType } from './core/index.js'
|
|
2
|
-
|
|
3
|
-
export {
|
|
4
|
-
createErrorMapper,
|
|
5
|
-
defaultErrorMapper,
|
|
6
|
-
getInputDescription,
|
|
7
|
-
defaultFormatMessages,
|
|
8
|
-
buildInvalidTypeMessage,
|
|
9
|
-
buildTooSmallMessage,
|
|
10
|
-
buildTooBigMessage,
|
|
11
|
-
createFormatMessageBuilder,
|
|
12
|
-
createCustomMessageBuilder,
|
|
13
|
-
createDefaultBuilders,
|
|
14
|
-
} from './domain/index.js'
|
|
15
|
-
|
|
16
|
-
export {
|
|
17
|
-
setZodErrorMap,
|
|
18
|
-
createZodErrorMap,
|
|
19
|
-
} from './adapters/index.js'
|