@hy_ong/zod-kit 0.0.1 → 0.0.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.
- package/dist/index.cjs +343 -0
- package/dist/index.d.cts +84 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.js +308 -0
- package/package.json +15 -3
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
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.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
boolean: () => boolean,
|
|
24
|
+
email: () => email,
|
|
25
|
+
getLocale: () => getLocale,
|
|
26
|
+
integer: () => integer,
|
|
27
|
+
number: () => number,
|
|
28
|
+
password: () => password,
|
|
29
|
+
setLocale: () => setLocale,
|
|
30
|
+
text: () => text,
|
|
31
|
+
url: () => url
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(index_exports);
|
|
34
|
+
|
|
35
|
+
// src/common/boolean.ts
|
|
36
|
+
var import_zod = require("zod");
|
|
37
|
+
|
|
38
|
+
// src/i18n/locales/zh-TW.json
|
|
39
|
+
var zh_TW_default = {
|
|
40
|
+
common: {
|
|
41
|
+
boolean: {
|
|
42
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
43
|
+
shouldBe: {
|
|
44
|
+
true: "${label} \u5FC5\u9808\u70BA\u662F",
|
|
45
|
+
false: "${label} \u5FC5\u9808\u70BA\u5426"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
email: {
|
|
49
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
50
|
+
min: "${label} \u9577\u5EA6\u81F3\u5C11 ${min} \u5B57\u5143",
|
|
51
|
+
max: "${label} \u9577\u5EA6\u6700\u591A ${max} \u5B57\u5143",
|
|
52
|
+
includes: "${label} \u5FC5\u9808\u5305\u542B\u300C${includes}\u300D",
|
|
53
|
+
invalid: "${label} \u683C\u5F0F\u932F\u8AA4",
|
|
54
|
+
domain: "${label} \u5FC5\u9808\u70BA @${domain} \u7DB2\u57DF"
|
|
55
|
+
},
|
|
56
|
+
url: {
|
|
57
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
58
|
+
min: "${label} \u9577\u5EA6\u81F3\u5C11 ${min} \u5B57\u5143",
|
|
59
|
+
max: "${label} \u9577\u5EA6\u6700\u591A ${max} \u5B57\u5143",
|
|
60
|
+
includes: "${label} \u5FC5\u9808\u5305\u542B\u300C${includes}\u300D",
|
|
61
|
+
invalid: "${label} \u683C\u5F0F\u932F\u8AA4"
|
|
62
|
+
},
|
|
63
|
+
password: {
|
|
64
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
65
|
+
min: "${label} \u9577\u5EA6\u81F3\u5C11 ${min} \u5B57\u5143",
|
|
66
|
+
max: "${label} \u9577\u5EA6\u6700\u591A ${max} \u5B57\u5143",
|
|
67
|
+
uppercase: "${label} \u5FC5\u9808\u5305\u542B\u81F3\u5C11\u4E00\u500B\u5927\u5BEB\u5B57\u6BCD",
|
|
68
|
+
lowercase: "${label} \u5FC5\u9808\u5305\u542B\u81F3\u5C11\u4E00\u500B\u5C0F\u5BEB\u5B57\u6BCD",
|
|
69
|
+
digits: "${label} \u5FC5\u9808\u5305\u542B\u81F3\u5C11\u4E00\u500B\u6578\u5B57",
|
|
70
|
+
special: "${label} \u5FC5\u9808\u5305\u542B\u81F3\u5C11\u4E00\u500B\u7279\u6B8A\u7B26\u865F"
|
|
71
|
+
},
|
|
72
|
+
number: {
|
|
73
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
74
|
+
min: "${label} \u6700\u5C0F\u503C ${min}",
|
|
75
|
+
max: "${label} \u6700\u5927\u503C ${max}"
|
|
76
|
+
},
|
|
77
|
+
id: {
|
|
78
|
+
required: "\u8ACB\u9078\u64C7 ${label}",
|
|
79
|
+
invalid: "${label} \u7121\u6548"
|
|
80
|
+
},
|
|
81
|
+
integer: {
|
|
82
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
83
|
+
min: "${label} \u6700\u5C0F\u503C ${min}",
|
|
84
|
+
max: "${label} \u6700\u5927\u503C ${max}",
|
|
85
|
+
integer: "${label} \u5FC5\u9808\u70BA\u6574\u6578"
|
|
86
|
+
},
|
|
87
|
+
float: {
|
|
88
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
89
|
+
float: "${label} \u5FC5\u9808\u70BA\u6D6E\u9EDE\u6578",
|
|
90
|
+
min: "${label} \u6700\u5C0F\u503C ${min}",
|
|
91
|
+
max: "${label} \u6700\u5927\u503C ${max}"
|
|
92
|
+
},
|
|
93
|
+
text: {
|
|
94
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
95
|
+
min: "${label} \u9577\u5EA6\u81F3\u5C11 ${min} \u5B57\u5143",
|
|
96
|
+
max: "${label} \u9577\u5EA6\u6700\u591A ${max} \u5B57\u5143",
|
|
97
|
+
startsWith: "${label} \u5FC5\u9808\u4EE5\u300C${startsWith}\u300D\u958B\u982D",
|
|
98
|
+
endsWith: "${label} \u5FC5\u9808\u4EE5\u300C${endsWith}\u300D\u7D50\u5C3E",
|
|
99
|
+
includes: "${label} \u5FC5\u9808\u5305\u542B\u300C${includes}\u300D",
|
|
100
|
+
invalid: "${label} \u683C\u5F0F\u932F\u8AA4"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// src/i18n/locales/en.json
|
|
106
|
+
var en_default = {
|
|
107
|
+
common: {
|
|
108
|
+
boolean: {
|
|
109
|
+
required: "${label} is required",
|
|
110
|
+
shouldBe: {
|
|
111
|
+
true: "${label} must be True",
|
|
112
|
+
false: "${label} must be False"
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
email: {
|
|
116
|
+
required: "${label} is required",
|
|
117
|
+
min: "${label} must be at least ${min} characters",
|
|
118
|
+
max: "${label} must be at most ${max} characters",
|
|
119
|
+
includes: "${label} must include ${includes}",
|
|
120
|
+
invalid: "${label} is invalid format",
|
|
121
|
+
domain: "${label} must be under the domain @${domain}"
|
|
122
|
+
},
|
|
123
|
+
url: {
|
|
124
|
+
required: "${label} is required",
|
|
125
|
+
min: "${label} must be at least ${min} characters",
|
|
126
|
+
max: "${label} must be at most ${max} characters",
|
|
127
|
+
includes: "${label} must include ${includes}",
|
|
128
|
+
invalid: "${label} is invalid format"
|
|
129
|
+
},
|
|
130
|
+
password: {
|
|
131
|
+
required: "${label} is required",
|
|
132
|
+
min: "${label} must be at least ${min} characters",
|
|
133
|
+
max: "${label} must be at most ${max} characters",
|
|
134
|
+
uppercase: "${label} must include at least one uppercase letter",
|
|
135
|
+
lowercase: "${label} must include at least one lowercase letter",
|
|
136
|
+
digits: "${label} must include at least one digit",
|
|
137
|
+
special: "${label} must include at least one special character"
|
|
138
|
+
},
|
|
139
|
+
number: {
|
|
140
|
+
required: "${label} is required",
|
|
141
|
+
min: "${label} must be at least ${min}",
|
|
142
|
+
max: "${label} must be at most ${max}"
|
|
143
|
+
},
|
|
144
|
+
integer: {
|
|
145
|
+
required: "${label} is required",
|
|
146
|
+
min: "${label} must be at least ${min}",
|
|
147
|
+
max: "${label} must be at most ${max}",
|
|
148
|
+
integer: "${label} must be an integer"
|
|
149
|
+
},
|
|
150
|
+
float: {
|
|
151
|
+
required: "${label} is required",
|
|
152
|
+
min: "${label} must be at least ${min}",
|
|
153
|
+
max: "${label} must be at most ${max}",
|
|
154
|
+
float: "${label} must be an float"
|
|
155
|
+
},
|
|
156
|
+
text: {
|
|
157
|
+
required: "${label} is required",
|
|
158
|
+
min: "${label} must be at least ${min} characters",
|
|
159
|
+
max: "${label} must be at most ${max} characters",
|
|
160
|
+
startsWith: "${label} must start with ${startsWith}",
|
|
161
|
+
endsWith: "${label} must end with ${endsWith}",
|
|
162
|
+
includes: "${label} must include ${includes}",
|
|
163
|
+
invalid: "${label} is invalid format"
|
|
164
|
+
},
|
|
165
|
+
date: {
|
|
166
|
+
required: "${label} is required",
|
|
167
|
+
min: "${label} must be at least ${min} characters",
|
|
168
|
+
max: "${label} must be at most ${max} characters",
|
|
169
|
+
includes: "${label} must include ${includes}",
|
|
170
|
+
format: "${label} must be in ${format} format"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// src/config.ts
|
|
176
|
+
var currentLocale = "zh-TW";
|
|
177
|
+
var setLocale = (locale) => {
|
|
178
|
+
currentLocale = locale;
|
|
179
|
+
};
|
|
180
|
+
var getLocale = () => currentLocale;
|
|
181
|
+
|
|
182
|
+
// src/i18n/index.ts
|
|
183
|
+
var dicts = {
|
|
184
|
+
"zh-TW": zh_TW_default,
|
|
185
|
+
en: en_default
|
|
186
|
+
};
|
|
187
|
+
var t = (key, params = {}) => {
|
|
188
|
+
const locale = getLocale();
|
|
189
|
+
const dict = dicts[locale] || {};
|
|
190
|
+
const template = getNestedValue(dict, key) ?? key;
|
|
191
|
+
return template.replace(/\$\{(\w+)}/g, (_, k) => params[k] ?? "");
|
|
192
|
+
};
|
|
193
|
+
function getNestedValue(obj, path) {
|
|
194
|
+
const result = path.split(".").reduce((acc, part) => acc && typeof acc === "object" ? acc[part] : void 0, obj);
|
|
195
|
+
return typeof result === "string" ? result : void 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// src/common/boolean.ts
|
|
199
|
+
function boolean(options) {
|
|
200
|
+
const { required = true, label, defaultValue = null, shouldBe } = options ?? {};
|
|
201
|
+
let result = import_zod.z.preprocess(
|
|
202
|
+
(val) => {
|
|
203
|
+
if (val === "" || val === void 0 || val === null) return defaultValue;
|
|
204
|
+
if (val === "true" || val === 1 || val === "1") return true;
|
|
205
|
+
if (val === "false" || val === 0 || val === "0") return false;
|
|
206
|
+
return val;
|
|
207
|
+
},
|
|
208
|
+
import_zod.z.union([import_zod.z.literal(true), import_zod.z.literal(false), import_zod.z.literal(null)])
|
|
209
|
+
);
|
|
210
|
+
if (required && defaultValue === null) {
|
|
211
|
+
result = result.refine((val) => val !== null, { message: t("common.boolean.required", { label }) });
|
|
212
|
+
}
|
|
213
|
+
if (shouldBe === true) {
|
|
214
|
+
result = result.refine((val) => val === true, { message: t("common.boolean.shouldBe.true", { label }) });
|
|
215
|
+
} else if (shouldBe === false) {
|
|
216
|
+
result = result.refine((val) => val === false, { message: t("common.boolean.shouldBe.false", { label }) });
|
|
217
|
+
}
|
|
218
|
+
return result;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// src/common/email.ts
|
|
222
|
+
var import_zod2 = require("zod");
|
|
223
|
+
function email(options) {
|
|
224
|
+
const { required = true, label, domain, min, max, includes } = options ?? {};
|
|
225
|
+
const baseSchema = required ? import_zod2.z.preprocess(
|
|
226
|
+
(val) => val === "" || val === null || val === void 0 ? null : val,
|
|
227
|
+
import_zod2.z.email({
|
|
228
|
+
error: (issue) => {
|
|
229
|
+
if (issue.code === "invalid_type") return t("common.email.required", { label });
|
|
230
|
+
else if (issue.code === "invalid_format") return t("common.email.invalid", { label });
|
|
231
|
+
return t("common.email.invalid", { label });
|
|
232
|
+
}
|
|
233
|
+
})
|
|
234
|
+
) : import_zod2.z.preprocess((val) => val === "" || val === null || val === void 0 ? null : val, import_zod2.z.email({ message: t("common.email.invalid", { label }) }).nullable());
|
|
235
|
+
const schema = baseSchema.refine((val) => required ? val !== "" && val !== "null" && val !== "undefined" : true, { message: t("common.text.required", { label }) }).refine((val) => val === null || min === void 0 || val.length >= min, { message: t("common.text.min", { label, min }) }).refine((val) => val === null || max === void 0 || val.length <= max, { message: t("common.text.max", { label, max }) }).refine((val) => val === null || includes === void 0 || val.includes(includes), { message: t("common.text.includes", { label, includes }) }).refine(
|
|
236
|
+
(val) => {
|
|
237
|
+
if (val === null || domain === void 0) return true;
|
|
238
|
+
return val.split("@")[1]?.toLowerCase() === domain.toLowerCase();
|
|
239
|
+
},
|
|
240
|
+
{ message: t("common.email.domain", { label, domain }) }
|
|
241
|
+
);
|
|
242
|
+
return schema;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// src/common/url.ts
|
|
246
|
+
var import_zod3 = require("zod");
|
|
247
|
+
function url(options) {
|
|
248
|
+
const { required = true, label, min, max, includes } = options ?? {};
|
|
249
|
+
const baseSchema = required ? import_zod3.z.preprocess(
|
|
250
|
+
(val) => val === "" || val === null || val === void 0 ? null : val,
|
|
251
|
+
import_zod3.z.url({
|
|
252
|
+
error: (issue) => {
|
|
253
|
+
if (issue.code === "invalid_type") return t("common.url.required", { label });
|
|
254
|
+
else if (issue.code === "invalid_format") return t("common.url.invalid", { label });
|
|
255
|
+
return t("common.url.invalid", { label });
|
|
256
|
+
}
|
|
257
|
+
})
|
|
258
|
+
) : import_zod3.z.preprocess((val) => val === "" || val === null || val === void 0 ? null : val, import_zod3.z.url({ message: t("common.url.invalid", { label }) }).nullable());
|
|
259
|
+
const schema = baseSchema.refine((val) => required ? val !== "" && val !== "null" && val !== "undefined" : true, { message: t("common.text.required", { label }) }).refine((val) => val === null || min === void 0 || val.length >= min, { message: t("common.text.min", { label, min }) }).refine((val) => val === null || max === void 0 || val.length <= max, { message: t("common.text.max", { label, max }) }).refine((val) => val === null || includes === void 0 || val.includes(includes), { message: t("common.text.includes", { label, includes }) });
|
|
260
|
+
return schema;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/common/text.ts
|
|
264
|
+
var import_zod4 = require("zod");
|
|
265
|
+
function text(options) {
|
|
266
|
+
const { required = true, label, min, max, startsWith, endsWith, includes, regex, defaultValue = null } = options ?? {};
|
|
267
|
+
const baseSchema = required ? import_zod4.z.preprocess((val) => val === "" || val === null || val === void 0 ? defaultValue : val, import_zod4.z.coerce.string().trim()) : import_zod4.z.preprocess((val) => val === "" || val === null || val === void 0 ? defaultValue : val, import_zod4.z.coerce.string().trim().nullable());
|
|
268
|
+
const schema = baseSchema.refine((val) => required ? val !== "" && val !== "null" && val !== "undefined" : true, { message: t("common.text.required", { label }) }).refine((val) => val === null || min === void 0 || val.length >= min, { message: t("common.text.min", { label, min }) }).refine((val) => val === null || max === void 0 || val.length <= max, { message: t("common.text.max", { label, max }) }).refine((val) => val === null || startsWith === void 0 || val.startsWith(startsWith), { message: t("common.text.startsWith", { label, startsWith }) }).refine((val) => val === null || endsWith === void 0 || val.endsWith(endsWith), { message: t("common.text.endsWith", { label, endsWith }) }).refine((val) => val === null || includes === void 0 || val.includes(includes), { message: t("common.text.includes", { label, includes }) }).refine((val) => val === null || regex === void 0 || regex.test(val), { message: t("common.text.invalid", { label, regex }) });
|
|
269
|
+
return schema;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// src/common/number.ts
|
|
273
|
+
var import_zod5 = require("zod");
|
|
274
|
+
function number(options) {
|
|
275
|
+
const { required = true, label, min, max, defaultValue } = options ?? {};
|
|
276
|
+
const schema = import_zod5.z.preprocess(
|
|
277
|
+
(val) => {
|
|
278
|
+
if (val === "" || val === void 0 || val === null) return defaultValue ?? null;
|
|
279
|
+
return typeof val === "string" ? Number(val) : val;
|
|
280
|
+
},
|
|
281
|
+
import_zod5.z.union([
|
|
282
|
+
import_zod5.z.number({
|
|
283
|
+
error: (issue) => {
|
|
284
|
+
if (issue.code === "invalid_type") return t("common.number.integer", { label });
|
|
285
|
+
return t("common.number.required", { label });
|
|
286
|
+
}
|
|
287
|
+
}),
|
|
288
|
+
import_zod5.z.null()
|
|
289
|
+
])
|
|
290
|
+
).refine((val) => !required || val !== null, { message: t("common.number.required", { label }) }).refine((val) => val === null || min === void 0 || val >= min, { message: t("common.number.min", { label, min }) }).refine((val) => val === null || max === void 0 || val <= max, { message: t("common.number.max", { label, max }) });
|
|
291
|
+
return schema;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// src/common/password.ts
|
|
295
|
+
var import_zod6 = require("zod");
|
|
296
|
+
function password(options) {
|
|
297
|
+
const { required = true, label, min, max, uppercase, lowercase, digits, special } = options ?? {};
|
|
298
|
+
const baseSchema = required ? import_zod6.z.preprocess((val) => val === "" || val === null || val === void 0 ? null : val, import_zod6.z.coerce.string().trim()) : import_zod6.z.preprocess((val) => val === "" || val === null || val === void 0 ? null : val, import_zod6.z.coerce.string().trim().nullable());
|
|
299
|
+
const schema = baseSchema.refine((val) => required ? val !== "" && val !== "null" && val !== "undefined" : true, { message: t("common.password.required", { label }) }).refine((val) => val === null || min === void 0 || val.length >= min, { message: t("common.password.min", { label, min }) }).refine((val) => val === null || max === void 0 || val.length <= max, { message: t("common.password.max", { label, max }) }).refine((val) => val === null || !uppercase || /[A-Z]/.test(val), { message: t("common.password.uppercase", { label }) }).refine((val) => val === null || !lowercase || /[a-z]/.test(val), { message: t("common.password.lowercase", { label }) }).refine((val) => val === null || !special || /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]+/.test(val), { message: t("common.password.special", { label }) }).refine((val) => val === null || !digits || /[0-9]/.test(val), { message: t("common.password.digits", { label }) });
|
|
300
|
+
return schema;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// src/common/integer.ts
|
|
304
|
+
var import_zod7 = require("zod");
|
|
305
|
+
function integer(options) {
|
|
306
|
+
const { required = true, label, min, max, defaultValue } = options ?? {};
|
|
307
|
+
const schema = import_zod7.z.preprocess(
|
|
308
|
+
(val) => {
|
|
309
|
+
if (val === "" || val === void 0 || val === null) return defaultValue ?? null;
|
|
310
|
+
return typeof val === "string" ? Number(val) : val;
|
|
311
|
+
},
|
|
312
|
+
import_zod7.z.union([
|
|
313
|
+
import_zod7.z.number({
|
|
314
|
+
error: (issue) => {
|
|
315
|
+
if (issue.code === "invalid_type") return t("common.integer.integer", { label });
|
|
316
|
+
return t("common.integer.required", { label });
|
|
317
|
+
}
|
|
318
|
+
}),
|
|
319
|
+
import_zod7.z.null()
|
|
320
|
+
])
|
|
321
|
+
).refine((val) => !required || val !== null, {
|
|
322
|
+
message: t("common.integer.required", { label })
|
|
323
|
+
}).refine((val) => val === null || Number.isInteger(val), {
|
|
324
|
+
message: t("common.integer.integer", { label })
|
|
325
|
+
}).refine((val) => val === null || min === void 0 || val >= min, {
|
|
326
|
+
message: t("common.integer.min", { label, min })
|
|
327
|
+
}).refine((val) => val === null || max === void 0 || val <= max, {
|
|
328
|
+
message: t("common.integer.max", { label, max })
|
|
329
|
+
});
|
|
330
|
+
return schema;
|
|
331
|
+
}
|
|
332
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
333
|
+
0 && (module.exports = {
|
|
334
|
+
boolean,
|
|
335
|
+
email,
|
|
336
|
+
getLocale,
|
|
337
|
+
integer,
|
|
338
|
+
number,
|
|
339
|
+
password,
|
|
340
|
+
setLocale,
|
|
341
|
+
text,
|
|
342
|
+
url
|
|
343
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ZodBoolean, ZodNullable, ZodString, ZodNumber } from 'zod';
|
|
2
|
+
|
|
3
|
+
type BooleanOptions<IsRequired extends boolean = true> = {
|
|
4
|
+
required?: IsRequired;
|
|
5
|
+
label: string;
|
|
6
|
+
defaultValue?: IsRequired extends true ? boolean : boolean | null;
|
|
7
|
+
shouldBe?: boolean;
|
|
8
|
+
};
|
|
9
|
+
type BooleanSchema<IsRequired extends boolean> = IsRequired extends true ? ZodBoolean : ZodNullable<ZodBoolean>;
|
|
10
|
+
declare function boolean<IsRequired extends boolean = true>(options?: BooleanOptions<IsRequired>): BooleanSchema<IsRequired>;
|
|
11
|
+
|
|
12
|
+
type EmailOptions<IsRequired extends boolean = true> = {
|
|
13
|
+
required?: IsRequired;
|
|
14
|
+
label: string;
|
|
15
|
+
domain?: string;
|
|
16
|
+
min?: number;
|
|
17
|
+
max?: number;
|
|
18
|
+
includes?: string;
|
|
19
|
+
};
|
|
20
|
+
type EmailSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>;
|
|
21
|
+
declare function email<IsRequired extends boolean = true>(options?: EmailOptions<IsRequired>): EmailSchema<IsRequired>;
|
|
22
|
+
|
|
23
|
+
type UrlOptions<IsRequired extends boolean = true> = {
|
|
24
|
+
required?: IsRequired;
|
|
25
|
+
label: string;
|
|
26
|
+
min?: number;
|
|
27
|
+
max?: number;
|
|
28
|
+
includes?: string;
|
|
29
|
+
};
|
|
30
|
+
type UrlSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>;
|
|
31
|
+
declare function url<IsRequired extends boolean = true>(options?: UrlOptions<IsRequired>): UrlSchema<IsRequired>;
|
|
32
|
+
|
|
33
|
+
type TextOptions<IsRequired extends boolean = true> = {
|
|
34
|
+
required?: IsRequired;
|
|
35
|
+
label: string;
|
|
36
|
+
min?: number;
|
|
37
|
+
max?: number;
|
|
38
|
+
startsWith?: string;
|
|
39
|
+
endsWith?: string;
|
|
40
|
+
includes?: string;
|
|
41
|
+
regex?: RegExp;
|
|
42
|
+
defaultValue?: IsRequired extends true ? string : string | null;
|
|
43
|
+
};
|
|
44
|
+
type TextSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>;
|
|
45
|
+
declare function text<IsRequired extends boolean = true>(options?: TextOptions<IsRequired>): TextSchema<IsRequired>;
|
|
46
|
+
|
|
47
|
+
type NumberOptions<IsRequired extends boolean = true> = {
|
|
48
|
+
required?: IsRequired;
|
|
49
|
+
label: string;
|
|
50
|
+
min?: number;
|
|
51
|
+
max?: number;
|
|
52
|
+
defaultValue?: IsRequired extends true ? number : number | null;
|
|
53
|
+
};
|
|
54
|
+
type NumberSchema<IsRequired extends boolean> = IsRequired extends true ? ZodNumber : ZodNullable<ZodNumber>;
|
|
55
|
+
declare function number<IsRequired extends boolean = true>(options?: NumberOptions<IsRequired>): NumberSchema<IsRequired>;
|
|
56
|
+
|
|
57
|
+
type PasswordOptions<IsRequired extends boolean = true> = {
|
|
58
|
+
required?: IsRequired;
|
|
59
|
+
label: string;
|
|
60
|
+
min?: number;
|
|
61
|
+
max?: number;
|
|
62
|
+
uppercase?: boolean;
|
|
63
|
+
lowercase?: boolean;
|
|
64
|
+
digits?: boolean;
|
|
65
|
+
special?: boolean;
|
|
66
|
+
};
|
|
67
|
+
type PasswordSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>;
|
|
68
|
+
declare function password<IsRequired extends boolean = true>(options?: PasswordOptions<IsRequired>): PasswordSchema<IsRequired>;
|
|
69
|
+
|
|
70
|
+
type IntegerOptions<IsRequired extends boolean = true> = {
|
|
71
|
+
required?: IsRequired;
|
|
72
|
+
label: string;
|
|
73
|
+
min?: number;
|
|
74
|
+
max?: number;
|
|
75
|
+
defaultValue?: IsRequired extends true ? number : number | null;
|
|
76
|
+
};
|
|
77
|
+
type IntegerSchema<IsRequired extends boolean> = IsRequired extends true ? ZodNumber : ZodNullable<ZodNumber>;
|
|
78
|
+
declare function integer<IsRequired extends boolean = true>(options?: IntegerOptions<IsRequired>): IntegerSchema<IsRequired>;
|
|
79
|
+
|
|
80
|
+
type Locale = "zh-TW" | "en";
|
|
81
|
+
declare const setLocale: (locale: Locale) => void;
|
|
82
|
+
declare const getLocale: () => Locale;
|
|
83
|
+
|
|
84
|
+
export { type BooleanOptions, type BooleanSchema, type EmailOptions, type EmailSchema, type IntegerOptions, type IntegerSchema, type Locale, type NumberOptions, type NumberSchema, type PasswordOptions, type PasswordSchema, type TextOptions, type TextSchema, type UrlOptions, type UrlSchema, boolean, email, getLocale, integer, number, password, setLocale, text, url };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ZodBoolean, ZodNullable, ZodString, ZodNumber } from 'zod';
|
|
2
|
+
|
|
3
|
+
type BooleanOptions<IsRequired extends boolean = true> = {
|
|
4
|
+
required?: IsRequired;
|
|
5
|
+
label: string;
|
|
6
|
+
defaultValue?: IsRequired extends true ? boolean : boolean | null;
|
|
7
|
+
shouldBe?: boolean;
|
|
8
|
+
};
|
|
9
|
+
type BooleanSchema<IsRequired extends boolean> = IsRequired extends true ? ZodBoolean : ZodNullable<ZodBoolean>;
|
|
10
|
+
declare function boolean<IsRequired extends boolean = true>(options?: BooleanOptions<IsRequired>): BooleanSchema<IsRequired>;
|
|
11
|
+
|
|
12
|
+
type EmailOptions<IsRequired extends boolean = true> = {
|
|
13
|
+
required?: IsRequired;
|
|
14
|
+
label: string;
|
|
15
|
+
domain?: string;
|
|
16
|
+
min?: number;
|
|
17
|
+
max?: number;
|
|
18
|
+
includes?: string;
|
|
19
|
+
};
|
|
20
|
+
type EmailSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>;
|
|
21
|
+
declare function email<IsRequired extends boolean = true>(options?: EmailOptions<IsRequired>): EmailSchema<IsRequired>;
|
|
22
|
+
|
|
23
|
+
type UrlOptions<IsRequired extends boolean = true> = {
|
|
24
|
+
required?: IsRequired;
|
|
25
|
+
label: string;
|
|
26
|
+
min?: number;
|
|
27
|
+
max?: number;
|
|
28
|
+
includes?: string;
|
|
29
|
+
};
|
|
30
|
+
type UrlSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>;
|
|
31
|
+
declare function url<IsRequired extends boolean = true>(options?: UrlOptions<IsRequired>): UrlSchema<IsRequired>;
|
|
32
|
+
|
|
33
|
+
type TextOptions<IsRequired extends boolean = true> = {
|
|
34
|
+
required?: IsRequired;
|
|
35
|
+
label: string;
|
|
36
|
+
min?: number;
|
|
37
|
+
max?: number;
|
|
38
|
+
startsWith?: string;
|
|
39
|
+
endsWith?: string;
|
|
40
|
+
includes?: string;
|
|
41
|
+
regex?: RegExp;
|
|
42
|
+
defaultValue?: IsRequired extends true ? string : string | null;
|
|
43
|
+
};
|
|
44
|
+
type TextSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>;
|
|
45
|
+
declare function text<IsRequired extends boolean = true>(options?: TextOptions<IsRequired>): TextSchema<IsRequired>;
|
|
46
|
+
|
|
47
|
+
type NumberOptions<IsRequired extends boolean = true> = {
|
|
48
|
+
required?: IsRequired;
|
|
49
|
+
label: string;
|
|
50
|
+
min?: number;
|
|
51
|
+
max?: number;
|
|
52
|
+
defaultValue?: IsRequired extends true ? number : number | null;
|
|
53
|
+
};
|
|
54
|
+
type NumberSchema<IsRequired extends boolean> = IsRequired extends true ? ZodNumber : ZodNullable<ZodNumber>;
|
|
55
|
+
declare function number<IsRequired extends boolean = true>(options?: NumberOptions<IsRequired>): NumberSchema<IsRequired>;
|
|
56
|
+
|
|
57
|
+
type PasswordOptions<IsRequired extends boolean = true> = {
|
|
58
|
+
required?: IsRequired;
|
|
59
|
+
label: string;
|
|
60
|
+
min?: number;
|
|
61
|
+
max?: number;
|
|
62
|
+
uppercase?: boolean;
|
|
63
|
+
lowercase?: boolean;
|
|
64
|
+
digits?: boolean;
|
|
65
|
+
special?: boolean;
|
|
66
|
+
};
|
|
67
|
+
type PasswordSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>;
|
|
68
|
+
declare function password<IsRequired extends boolean = true>(options?: PasswordOptions<IsRequired>): PasswordSchema<IsRequired>;
|
|
69
|
+
|
|
70
|
+
type IntegerOptions<IsRequired extends boolean = true> = {
|
|
71
|
+
required?: IsRequired;
|
|
72
|
+
label: string;
|
|
73
|
+
min?: number;
|
|
74
|
+
max?: number;
|
|
75
|
+
defaultValue?: IsRequired extends true ? number : number | null;
|
|
76
|
+
};
|
|
77
|
+
type IntegerSchema<IsRequired extends boolean> = IsRequired extends true ? ZodNumber : ZodNullable<ZodNumber>;
|
|
78
|
+
declare function integer<IsRequired extends boolean = true>(options?: IntegerOptions<IsRequired>): IntegerSchema<IsRequired>;
|
|
79
|
+
|
|
80
|
+
type Locale = "zh-TW" | "en";
|
|
81
|
+
declare const setLocale: (locale: Locale) => void;
|
|
82
|
+
declare const getLocale: () => Locale;
|
|
83
|
+
|
|
84
|
+
export { type BooleanOptions, type BooleanSchema, type EmailOptions, type EmailSchema, type IntegerOptions, type IntegerSchema, type Locale, type NumberOptions, type NumberSchema, type PasswordOptions, type PasswordSchema, type TextOptions, type TextSchema, type UrlOptions, type UrlSchema, boolean, email, getLocale, integer, number, password, setLocale, text, url };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
// src/common/boolean.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
// src/i18n/locales/zh-TW.json
|
|
5
|
+
var zh_TW_default = {
|
|
6
|
+
common: {
|
|
7
|
+
boolean: {
|
|
8
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
9
|
+
shouldBe: {
|
|
10
|
+
true: "${label} \u5FC5\u9808\u70BA\u662F",
|
|
11
|
+
false: "${label} \u5FC5\u9808\u70BA\u5426"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
email: {
|
|
15
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
16
|
+
min: "${label} \u9577\u5EA6\u81F3\u5C11 ${min} \u5B57\u5143",
|
|
17
|
+
max: "${label} \u9577\u5EA6\u6700\u591A ${max} \u5B57\u5143",
|
|
18
|
+
includes: "${label} \u5FC5\u9808\u5305\u542B\u300C${includes}\u300D",
|
|
19
|
+
invalid: "${label} \u683C\u5F0F\u932F\u8AA4",
|
|
20
|
+
domain: "${label} \u5FC5\u9808\u70BA @${domain} \u7DB2\u57DF"
|
|
21
|
+
},
|
|
22
|
+
url: {
|
|
23
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
24
|
+
min: "${label} \u9577\u5EA6\u81F3\u5C11 ${min} \u5B57\u5143",
|
|
25
|
+
max: "${label} \u9577\u5EA6\u6700\u591A ${max} \u5B57\u5143",
|
|
26
|
+
includes: "${label} \u5FC5\u9808\u5305\u542B\u300C${includes}\u300D",
|
|
27
|
+
invalid: "${label} \u683C\u5F0F\u932F\u8AA4"
|
|
28
|
+
},
|
|
29
|
+
password: {
|
|
30
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
31
|
+
min: "${label} \u9577\u5EA6\u81F3\u5C11 ${min} \u5B57\u5143",
|
|
32
|
+
max: "${label} \u9577\u5EA6\u6700\u591A ${max} \u5B57\u5143",
|
|
33
|
+
uppercase: "${label} \u5FC5\u9808\u5305\u542B\u81F3\u5C11\u4E00\u500B\u5927\u5BEB\u5B57\u6BCD",
|
|
34
|
+
lowercase: "${label} \u5FC5\u9808\u5305\u542B\u81F3\u5C11\u4E00\u500B\u5C0F\u5BEB\u5B57\u6BCD",
|
|
35
|
+
digits: "${label} \u5FC5\u9808\u5305\u542B\u81F3\u5C11\u4E00\u500B\u6578\u5B57",
|
|
36
|
+
special: "${label} \u5FC5\u9808\u5305\u542B\u81F3\u5C11\u4E00\u500B\u7279\u6B8A\u7B26\u865F"
|
|
37
|
+
},
|
|
38
|
+
number: {
|
|
39
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
40
|
+
min: "${label} \u6700\u5C0F\u503C ${min}",
|
|
41
|
+
max: "${label} \u6700\u5927\u503C ${max}"
|
|
42
|
+
},
|
|
43
|
+
id: {
|
|
44
|
+
required: "\u8ACB\u9078\u64C7 ${label}",
|
|
45
|
+
invalid: "${label} \u7121\u6548"
|
|
46
|
+
},
|
|
47
|
+
integer: {
|
|
48
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
49
|
+
min: "${label} \u6700\u5C0F\u503C ${min}",
|
|
50
|
+
max: "${label} \u6700\u5927\u503C ${max}",
|
|
51
|
+
integer: "${label} \u5FC5\u9808\u70BA\u6574\u6578"
|
|
52
|
+
},
|
|
53
|
+
float: {
|
|
54
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
55
|
+
float: "${label} \u5FC5\u9808\u70BA\u6D6E\u9EDE\u6578",
|
|
56
|
+
min: "${label} \u6700\u5C0F\u503C ${min}",
|
|
57
|
+
max: "${label} \u6700\u5927\u503C ${max}"
|
|
58
|
+
},
|
|
59
|
+
text: {
|
|
60
|
+
required: "\u8ACB\u8F38\u5165 ${label}",
|
|
61
|
+
min: "${label} \u9577\u5EA6\u81F3\u5C11 ${min} \u5B57\u5143",
|
|
62
|
+
max: "${label} \u9577\u5EA6\u6700\u591A ${max} \u5B57\u5143",
|
|
63
|
+
startsWith: "${label} \u5FC5\u9808\u4EE5\u300C${startsWith}\u300D\u958B\u982D",
|
|
64
|
+
endsWith: "${label} \u5FC5\u9808\u4EE5\u300C${endsWith}\u300D\u7D50\u5C3E",
|
|
65
|
+
includes: "${label} \u5FC5\u9808\u5305\u542B\u300C${includes}\u300D",
|
|
66
|
+
invalid: "${label} \u683C\u5F0F\u932F\u8AA4"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/i18n/locales/en.json
|
|
72
|
+
var en_default = {
|
|
73
|
+
common: {
|
|
74
|
+
boolean: {
|
|
75
|
+
required: "${label} is required",
|
|
76
|
+
shouldBe: {
|
|
77
|
+
true: "${label} must be True",
|
|
78
|
+
false: "${label} must be False"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
email: {
|
|
82
|
+
required: "${label} is required",
|
|
83
|
+
min: "${label} must be at least ${min} characters",
|
|
84
|
+
max: "${label} must be at most ${max} characters",
|
|
85
|
+
includes: "${label} must include ${includes}",
|
|
86
|
+
invalid: "${label} is invalid format",
|
|
87
|
+
domain: "${label} must be under the domain @${domain}"
|
|
88
|
+
},
|
|
89
|
+
url: {
|
|
90
|
+
required: "${label} is required",
|
|
91
|
+
min: "${label} must be at least ${min} characters",
|
|
92
|
+
max: "${label} must be at most ${max} characters",
|
|
93
|
+
includes: "${label} must include ${includes}",
|
|
94
|
+
invalid: "${label} is invalid format"
|
|
95
|
+
},
|
|
96
|
+
password: {
|
|
97
|
+
required: "${label} is required",
|
|
98
|
+
min: "${label} must be at least ${min} characters",
|
|
99
|
+
max: "${label} must be at most ${max} characters",
|
|
100
|
+
uppercase: "${label} must include at least one uppercase letter",
|
|
101
|
+
lowercase: "${label} must include at least one lowercase letter",
|
|
102
|
+
digits: "${label} must include at least one digit",
|
|
103
|
+
special: "${label} must include at least one special character"
|
|
104
|
+
},
|
|
105
|
+
number: {
|
|
106
|
+
required: "${label} is required",
|
|
107
|
+
min: "${label} must be at least ${min}",
|
|
108
|
+
max: "${label} must be at most ${max}"
|
|
109
|
+
},
|
|
110
|
+
integer: {
|
|
111
|
+
required: "${label} is required",
|
|
112
|
+
min: "${label} must be at least ${min}",
|
|
113
|
+
max: "${label} must be at most ${max}",
|
|
114
|
+
integer: "${label} must be an integer"
|
|
115
|
+
},
|
|
116
|
+
float: {
|
|
117
|
+
required: "${label} is required",
|
|
118
|
+
min: "${label} must be at least ${min}",
|
|
119
|
+
max: "${label} must be at most ${max}",
|
|
120
|
+
float: "${label} must be an float"
|
|
121
|
+
},
|
|
122
|
+
text: {
|
|
123
|
+
required: "${label} is required",
|
|
124
|
+
min: "${label} must be at least ${min} characters",
|
|
125
|
+
max: "${label} must be at most ${max} characters",
|
|
126
|
+
startsWith: "${label} must start with ${startsWith}",
|
|
127
|
+
endsWith: "${label} must end with ${endsWith}",
|
|
128
|
+
includes: "${label} must include ${includes}",
|
|
129
|
+
invalid: "${label} is invalid format"
|
|
130
|
+
},
|
|
131
|
+
date: {
|
|
132
|
+
required: "${label} is required",
|
|
133
|
+
min: "${label} must be at least ${min} characters",
|
|
134
|
+
max: "${label} must be at most ${max} characters",
|
|
135
|
+
includes: "${label} must include ${includes}",
|
|
136
|
+
format: "${label} must be in ${format} format"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// src/config.ts
|
|
142
|
+
var currentLocale = "zh-TW";
|
|
143
|
+
var setLocale = (locale) => {
|
|
144
|
+
currentLocale = locale;
|
|
145
|
+
};
|
|
146
|
+
var getLocale = () => currentLocale;
|
|
147
|
+
|
|
148
|
+
// src/i18n/index.ts
|
|
149
|
+
var dicts = {
|
|
150
|
+
"zh-TW": zh_TW_default,
|
|
151
|
+
en: en_default
|
|
152
|
+
};
|
|
153
|
+
var t = (key, params = {}) => {
|
|
154
|
+
const locale = getLocale();
|
|
155
|
+
const dict = dicts[locale] || {};
|
|
156
|
+
const template = getNestedValue(dict, key) ?? key;
|
|
157
|
+
return template.replace(/\$\{(\w+)}/g, (_, k) => params[k] ?? "");
|
|
158
|
+
};
|
|
159
|
+
function getNestedValue(obj, path) {
|
|
160
|
+
const result = path.split(".").reduce((acc, part) => acc && typeof acc === "object" ? acc[part] : void 0, obj);
|
|
161
|
+
return typeof result === "string" ? result : void 0;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/common/boolean.ts
|
|
165
|
+
function boolean(options) {
|
|
166
|
+
const { required = true, label, defaultValue = null, shouldBe } = options ?? {};
|
|
167
|
+
let result = z.preprocess(
|
|
168
|
+
(val) => {
|
|
169
|
+
if (val === "" || val === void 0 || val === null) return defaultValue;
|
|
170
|
+
if (val === "true" || val === 1 || val === "1") return true;
|
|
171
|
+
if (val === "false" || val === 0 || val === "0") return false;
|
|
172
|
+
return val;
|
|
173
|
+
},
|
|
174
|
+
z.union([z.literal(true), z.literal(false), z.literal(null)])
|
|
175
|
+
);
|
|
176
|
+
if (required && defaultValue === null) {
|
|
177
|
+
result = result.refine((val) => val !== null, { message: t("common.boolean.required", { label }) });
|
|
178
|
+
}
|
|
179
|
+
if (shouldBe === true) {
|
|
180
|
+
result = result.refine((val) => val === true, { message: t("common.boolean.shouldBe.true", { label }) });
|
|
181
|
+
} else if (shouldBe === false) {
|
|
182
|
+
result = result.refine((val) => val === false, { message: t("common.boolean.shouldBe.false", { label }) });
|
|
183
|
+
}
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/common/email.ts
|
|
188
|
+
import { z as z2 } from "zod";
|
|
189
|
+
function email(options) {
|
|
190
|
+
const { required = true, label, domain, min, max, includes } = options ?? {};
|
|
191
|
+
const baseSchema = required ? z2.preprocess(
|
|
192
|
+
(val) => val === "" || val === null || val === void 0 ? null : val,
|
|
193
|
+
z2.email({
|
|
194
|
+
error: (issue) => {
|
|
195
|
+
if (issue.code === "invalid_type") return t("common.email.required", { label });
|
|
196
|
+
else if (issue.code === "invalid_format") return t("common.email.invalid", { label });
|
|
197
|
+
return t("common.email.invalid", { label });
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
) : z2.preprocess((val) => val === "" || val === null || val === void 0 ? null : val, z2.email({ message: t("common.email.invalid", { label }) }).nullable());
|
|
201
|
+
const schema = baseSchema.refine((val) => required ? val !== "" && val !== "null" && val !== "undefined" : true, { message: t("common.text.required", { label }) }).refine((val) => val === null || min === void 0 || val.length >= min, { message: t("common.text.min", { label, min }) }).refine((val) => val === null || max === void 0 || val.length <= max, { message: t("common.text.max", { label, max }) }).refine((val) => val === null || includes === void 0 || val.includes(includes), { message: t("common.text.includes", { label, includes }) }).refine(
|
|
202
|
+
(val) => {
|
|
203
|
+
if (val === null || domain === void 0) return true;
|
|
204
|
+
return val.split("@")[1]?.toLowerCase() === domain.toLowerCase();
|
|
205
|
+
},
|
|
206
|
+
{ message: t("common.email.domain", { label, domain }) }
|
|
207
|
+
);
|
|
208
|
+
return schema;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/common/url.ts
|
|
212
|
+
import { z as z3 } from "zod";
|
|
213
|
+
function url(options) {
|
|
214
|
+
const { required = true, label, min, max, includes } = options ?? {};
|
|
215
|
+
const baseSchema = required ? z3.preprocess(
|
|
216
|
+
(val) => val === "" || val === null || val === void 0 ? null : val,
|
|
217
|
+
z3.url({
|
|
218
|
+
error: (issue) => {
|
|
219
|
+
if (issue.code === "invalid_type") return t("common.url.required", { label });
|
|
220
|
+
else if (issue.code === "invalid_format") return t("common.url.invalid", { label });
|
|
221
|
+
return t("common.url.invalid", { label });
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
) : z3.preprocess((val) => val === "" || val === null || val === void 0 ? null : val, z3.url({ message: t("common.url.invalid", { label }) }).nullable());
|
|
225
|
+
const schema = baseSchema.refine((val) => required ? val !== "" && val !== "null" && val !== "undefined" : true, { message: t("common.text.required", { label }) }).refine((val) => val === null || min === void 0 || val.length >= min, { message: t("common.text.min", { label, min }) }).refine((val) => val === null || max === void 0 || val.length <= max, { message: t("common.text.max", { label, max }) }).refine((val) => val === null || includes === void 0 || val.includes(includes), { message: t("common.text.includes", { label, includes }) });
|
|
226
|
+
return schema;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// src/common/text.ts
|
|
230
|
+
import { z as z4 } from "zod";
|
|
231
|
+
function text(options) {
|
|
232
|
+
const { required = true, label, min, max, startsWith, endsWith, includes, regex, defaultValue = null } = options ?? {};
|
|
233
|
+
const baseSchema = required ? z4.preprocess((val) => val === "" || val === null || val === void 0 ? defaultValue : val, z4.coerce.string().trim()) : z4.preprocess((val) => val === "" || val === null || val === void 0 ? defaultValue : val, z4.coerce.string().trim().nullable());
|
|
234
|
+
const schema = baseSchema.refine((val) => required ? val !== "" && val !== "null" && val !== "undefined" : true, { message: t("common.text.required", { label }) }).refine((val) => val === null || min === void 0 || val.length >= min, { message: t("common.text.min", { label, min }) }).refine((val) => val === null || max === void 0 || val.length <= max, { message: t("common.text.max", { label, max }) }).refine((val) => val === null || startsWith === void 0 || val.startsWith(startsWith), { message: t("common.text.startsWith", { label, startsWith }) }).refine((val) => val === null || endsWith === void 0 || val.endsWith(endsWith), { message: t("common.text.endsWith", { label, endsWith }) }).refine((val) => val === null || includes === void 0 || val.includes(includes), { message: t("common.text.includes", { label, includes }) }).refine((val) => val === null || regex === void 0 || regex.test(val), { message: t("common.text.invalid", { label, regex }) });
|
|
235
|
+
return schema;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// src/common/number.ts
|
|
239
|
+
import { z as z5 } from "zod";
|
|
240
|
+
function number(options) {
|
|
241
|
+
const { required = true, label, min, max, defaultValue } = options ?? {};
|
|
242
|
+
const schema = z5.preprocess(
|
|
243
|
+
(val) => {
|
|
244
|
+
if (val === "" || val === void 0 || val === null) return defaultValue ?? null;
|
|
245
|
+
return typeof val === "string" ? Number(val) : val;
|
|
246
|
+
},
|
|
247
|
+
z5.union([
|
|
248
|
+
z5.number({
|
|
249
|
+
error: (issue) => {
|
|
250
|
+
if (issue.code === "invalid_type") return t("common.number.integer", { label });
|
|
251
|
+
return t("common.number.required", { label });
|
|
252
|
+
}
|
|
253
|
+
}),
|
|
254
|
+
z5.null()
|
|
255
|
+
])
|
|
256
|
+
).refine((val) => !required || val !== null, { message: t("common.number.required", { label }) }).refine((val) => val === null || min === void 0 || val >= min, { message: t("common.number.min", { label, min }) }).refine((val) => val === null || max === void 0 || val <= max, { message: t("common.number.max", { label, max }) });
|
|
257
|
+
return schema;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// src/common/password.ts
|
|
261
|
+
import { z as z6 } from "zod";
|
|
262
|
+
function password(options) {
|
|
263
|
+
const { required = true, label, min, max, uppercase, lowercase, digits, special } = options ?? {};
|
|
264
|
+
const baseSchema = required ? z6.preprocess((val) => val === "" || val === null || val === void 0 ? null : val, z6.coerce.string().trim()) : z6.preprocess((val) => val === "" || val === null || val === void 0 ? null : val, z6.coerce.string().trim().nullable());
|
|
265
|
+
const schema = baseSchema.refine((val) => required ? val !== "" && val !== "null" && val !== "undefined" : true, { message: t("common.password.required", { label }) }).refine((val) => val === null || min === void 0 || val.length >= min, { message: t("common.password.min", { label, min }) }).refine((val) => val === null || max === void 0 || val.length <= max, { message: t("common.password.max", { label, max }) }).refine((val) => val === null || !uppercase || /[A-Z]/.test(val), { message: t("common.password.uppercase", { label }) }).refine((val) => val === null || !lowercase || /[a-z]/.test(val), { message: t("common.password.lowercase", { label }) }).refine((val) => val === null || !special || /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]+/.test(val), { message: t("common.password.special", { label }) }).refine((val) => val === null || !digits || /[0-9]/.test(val), { message: t("common.password.digits", { label }) });
|
|
266
|
+
return schema;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// src/common/integer.ts
|
|
270
|
+
import { z as z7 } from "zod";
|
|
271
|
+
function integer(options) {
|
|
272
|
+
const { required = true, label, min, max, defaultValue } = options ?? {};
|
|
273
|
+
const schema = z7.preprocess(
|
|
274
|
+
(val) => {
|
|
275
|
+
if (val === "" || val === void 0 || val === null) return defaultValue ?? null;
|
|
276
|
+
return typeof val === "string" ? Number(val) : val;
|
|
277
|
+
},
|
|
278
|
+
z7.union([
|
|
279
|
+
z7.number({
|
|
280
|
+
error: (issue) => {
|
|
281
|
+
if (issue.code === "invalid_type") return t("common.integer.integer", { label });
|
|
282
|
+
return t("common.integer.required", { label });
|
|
283
|
+
}
|
|
284
|
+
}),
|
|
285
|
+
z7.null()
|
|
286
|
+
])
|
|
287
|
+
).refine((val) => !required || val !== null, {
|
|
288
|
+
message: t("common.integer.required", { label })
|
|
289
|
+
}).refine((val) => val === null || Number.isInteger(val), {
|
|
290
|
+
message: t("common.integer.integer", { label })
|
|
291
|
+
}).refine((val) => val === null || min === void 0 || val >= min, {
|
|
292
|
+
message: t("common.integer.min", { label, min })
|
|
293
|
+
}).refine((val) => val === null || max === void 0 || val <= max, {
|
|
294
|
+
message: t("common.integer.max", { label, max })
|
|
295
|
+
});
|
|
296
|
+
return schema;
|
|
297
|
+
}
|
|
298
|
+
export {
|
|
299
|
+
boolean,
|
|
300
|
+
email,
|
|
301
|
+
getLocale,
|
|
302
|
+
integer,
|
|
303
|
+
number,
|
|
304
|
+
password,
|
|
305
|
+
setLocale,
|
|
306
|
+
text,
|
|
307
|
+
url
|
|
308
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hy_ong/zod-kit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Zod Kit",
|
|
5
5
|
"keywords": [
|
|
6
|
+
"hy_ong",
|
|
6
7
|
"zod",
|
|
7
8
|
"kit",
|
|
8
9
|
"zod-kit"
|
|
@@ -20,8 +21,17 @@
|
|
|
20
21
|
},
|
|
21
22
|
"license": "ISC",
|
|
22
23
|
"author": "Ong Hoe Yuan",
|
|
23
|
-
"type": "
|
|
24
|
-
"main": "dist/index.
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "dist/index.cjs",
|
|
26
|
+
"module": "dist/index.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"require": "./dist/index.cjs",
|
|
32
|
+
"types": "./dist/index.d.ts"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
25
35
|
"scripts": {
|
|
26
36
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
27
37
|
"test": "vitest"
|
|
@@ -32,8 +42,10 @@
|
|
|
32
42
|
},
|
|
33
43
|
"devDependencies": {
|
|
34
44
|
"@eslint/js": "^9.32.0",
|
|
45
|
+
"@types/node": "^22.17.0",
|
|
35
46
|
"eslint": "^9.32.0",
|
|
36
47
|
"prettier": "^3.6.2",
|
|
48
|
+
"tsup": "^8.5.0",
|
|
37
49
|
"typescript": "^5.8.3",
|
|
38
50
|
"typescript-eslint": "^8.38.0",
|
|
39
51
|
"vitest": "^3.2.4"
|