@hy_ong/zod-kit 0.2.4 → 0.2.5
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/chunk-5NBWPAHC.cjs +77 -0
- package/dist/{chunk-BZWQPSHO.cjs → chunk-5U5ERV2P.cjs} +16 -28
- package/dist/{chunk-7X3XPK6A.js → chunk-S4OJGXWC.js} +16 -28
- package/dist/chunk-YG6YHVAE.js +77 -0
- package/dist/common/many-of.cjs +2 -2
- package/dist/common/many-of.d.cts +13 -9
- package/dist/common/many-of.d.ts +13 -9
- package/dist/common/many-of.js +1 -1
- package/dist/common/one-of.cjs +2 -2
- package/dist/common/one-of.d.cts +16 -10
- package/dist/common/one-of.d.ts +16 -10
- package/dist/common/one-of.js +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/src/validators/common/many-of.ts +76 -71
- package/src/validators/common/one-of.ts +89 -47
- package/dist/chunk-3ZF5JO3F.js +0 -61
- package/dist/chunk-FMPHW7ID.cjs +0 -61
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkQ7TUNJD4cjs = require('./chunk-Q7TUNJD4.cjs');
|
|
5
|
+
|
|
6
|
+
// src/validators/common/one-of.ts
|
|
7
|
+
var _zod = require('zod');
|
|
8
|
+
function oneOf(required, options) {
|
|
9
|
+
const { values = [], defaultValue = null, caseSensitive = true, transform, i18n } = _nullishCoalesce(options, () => ( {}));
|
|
10
|
+
const isRequired = _nullishCoalesce(required, () => ( false));
|
|
11
|
+
const valuesArr = values;
|
|
12
|
+
const isAllStrings = valuesArr.every((v) => typeof v === "string");
|
|
13
|
+
const getMessage = (key, params) => {
|
|
14
|
+
if (i18n) {
|
|
15
|
+
const currentLocale = _chunkQ7TUNJD4cjs.getLocale.call(void 0, );
|
|
16
|
+
const customMessages = i18n[currentLocale];
|
|
17
|
+
if (customMessages && customMessages[key]) {
|
|
18
|
+
const template = customMessages[key];
|
|
19
|
+
return template.replace(/\$\{(\w+)}/g, (_, k) => _nullishCoalesce(_optionalChain([params, 'optionalAccess', _2 => _2[k]]), () => ( "")));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return _chunkQ7TUNJD4cjs.t.call(void 0, `common.oneOf.${key}`, params);
|
|
23
|
+
};
|
|
24
|
+
const isEmpty = (v) => v === "" || v === null || v === void 0;
|
|
25
|
+
let valueSchema;
|
|
26
|
+
if (isAllStrings && valuesArr.length > 0) {
|
|
27
|
+
valueSchema = _zod.z.enum(valuesArr, {
|
|
28
|
+
error: (issue) => {
|
|
29
|
+
if (isEmpty(issue.input)) return getMessage("required");
|
|
30
|
+
return getMessage("invalid", { values: valuesArr.join(", ") });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
} else if (valuesArr.length >= 2) {
|
|
34
|
+
const literals = valuesArr.map((v) => _zod.z.literal(v));
|
|
35
|
+
valueSchema = _zod.z.union(literals, {
|
|
36
|
+
error: () => getMessage("invalid", { values: valuesArr.join(", ") })
|
|
37
|
+
});
|
|
38
|
+
} else if (valuesArr.length === 1) {
|
|
39
|
+
valueSchema = _zod.z.literal(valuesArr[0]);
|
|
40
|
+
} else {
|
|
41
|
+
valueSchema = _zod.z.never();
|
|
42
|
+
}
|
|
43
|
+
if (!caseSensitive) {
|
|
44
|
+
valueSchema = _zod.z.string().transform((v) => {
|
|
45
|
+
const match = valuesArr.find((val) => typeof val === "string" && val.toLowerCase() === v.toLowerCase());
|
|
46
|
+
return _nullishCoalesce(match, () => ( v));
|
|
47
|
+
}).pipe(valueSchema);
|
|
48
|
+
}
|
|
49
|
+
if (transform) {
|
|
50
|
+
valueSchema = valueSchema.transform((v) => transform(v));
|
|
51
|
+
}
|
|
52
|
+
const fallback = defaultValue;
|
|
53
|
+
const emptySchema = _zod.z.union([_zod.z.literal(""), _zod.z.null(), _zod.z.undefined()]).transform(() => fallback);
|
|
54
|
+
if (isRequired && fallback === null) {
|
|
55
|
+
const emptyRejectSchema = _zod.z.union([_zod.z.literal(""), _zod.z.null(), _zod.z.undefined()]).refine(() => false, { message: getMessage("required") });
|
|
56
|
+
if (!isAllStrings) {
|
|
57
|
+
const numCoerceSchema = _zod.z.string().transform((v) => {
|
|
58
|
+
const n = Number(v);
|
|
59
|
+
return isNaN(n) ? v : n;
|
|
60
|
+
}).pipe(valueSchema);
|
|
61
|
+
return _zod.z.union([valueSchema, numCoerceSchema, emptyRejectSchema]);
|
|
62
|
+
}
|
|
63
|
+
return _zod.z.union([valueSchema, emptyRejectSchema]);
|
|
64
|
+
}
|
|
65
|
+
if (!isAllStrings) {
|
|
66
|
+
const numCoerceSchema = _zod.z.string().transform((v) => {
|
|
67
|
+
const n = Number(v);
|
|
68
|
+
return isNaN(n) ? v : n;
|
|
69
|
+
}).pipe(valueSchema);
|
|
70
|
+
return _zod.z.union([valueSchema, numCoerceSchema, emptySchema]);
|
|
71
|
+
}
|
|
72
|
+
return _zod.z.union([valueSchema, emptySchema]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
exports.oneOf = oneOf;
|
|
@@ -8,6 +8,7 @@ var _zod = require('zod');
|
|
|
8
8
|
function manyOf(required, options) {
|
|
9
9
|
const { values = [], defaultValue = null, min, max, allowDuplicates = false, caseSensitive = true, transform, i18n } = _nullishCoalesce(options, () => ( {}));
|
|
10
10
|
const isRequired = _nullishCoalesce(required, () => ( false));
|
|
11
|
+
const valuesArr = values;
|
|
11
12
|
const getMessage = (key, params) => {
|
|
12
13
|
if (i18n) {
|
|
13
14
|
const currentLocale = _chunkQ7TUNJD4cjs.getLocale.call(void 0, );
|
|
@@ -20,44 +21,24 @@ function manyOf(required, options) {
|
|
|
20
21
|
return _chunkQ7TUNJD4cjs.t.call(void 0, `common.manyOf.${key}`, params);
|
|
21
22
|
};
|
|
22
23
|
const normalizeItem = (item) => {
|
|
23
|
-
const hasNumbers =
|
|
24
|
+
const hasNumbers = valuesArr.some((v) => typeof v === "number");
|
|
24
25
|
if (hasNumbers && typeof item === "string" && !isNaN(Number(item)) && item.trim() !== "") {
|
|
25
26
|
const numVal = Number(item);
|
|
26
|
-
if (
|
|
27
|
+
if (valuesArr.includes(numVal)) return numVal;
|
|
27
28
|
}
|
|
28
29
|
if (!caseSensitive && typeof item === "string") {
|
|
29
|
-
const match =
|
|
30
|
+
const match = valuesArr.find((v) => typeof v === "string" && v.toLowerCase() === item.toLowerCase());
|
|
30
31
|
if (match !== void 0) return match;
|
|
31
32
|
return item;
|
|
32
33
|
}
|
|
33
34
|
return item;
|
|
34
35
|
};
|
|
35
|
-
const
|
|
36
|
-
if (val === null || val === void 0 || val === "") {
|
|
37
|
-
return defaultValue;
|
|
38
|
-
}
|
|
39
|
-
if (!Array.isArray(val)) {
|
|
40
|
-
return [normalizeItem(val)];
|
|
41
|
-
}
|
|
42
|
-
return val.map(normalizeItem);
|
|
43
|
-
};
|
|
44
|
-
const baseSchema = _zod.z.preprocess(preprocessFn, _zod.z.any());
|
|
45
|
-
const schema = baseSchema.superRefine((val, ctx) => {
|
|
46
|
-
if (val === null) {
|
|
47
|
-
if (isRequired) {
|
|
48
|
-
ctx.addIssue({ code: "custom", message: getMessage("required") });
|
|
49
|
-
}
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
if (!Array.isArray(val)) {
|
|
53
|
-
ctx.addIssue({ code: "custom", message: getMessage("invalid", { values: values.join(", ") }) });
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
36
|
+
const arraySchema = _zod.z.array(_zod.z.any()).transform((arr) => arr.map(normalizeItem)).superRefine((val, ctx) => {
|
|
56
37
|
for (const item of val) {
|
|
57
|
-
if (!
|
|
38
|
+
if (!valuesArr.includes(item)) {
|
|
58
39
|
ctx.addIssue({
|
|
59
40
|
code: "custom",
|
|
60
|
-
message: getMessage("invalid", { values:
|
|
41
|
+
message: getMessage("invalid", { values: valuesArr.join(", ") })
|
|
61
42
|
});
|
|
62
43
|
return;
|
|
63
44
|
}
|
|
@@ -81,10 +62,17 @@ function manyOf(required, options) {
|
|
|
81
62
|
return;
|
|
82
63
|
}
|
|
83
64
|
}).transform((val) => {
|
|
84
|
-
if (
|
|
65
|
+
if (!transform) return val;
|
|
85
66
|
return transform(val);
|
|
86
67
|
});
|
|
87
|
-
|
|
68
|
+
const singleToArray = _zod.z.union([_zod.z.string(), _zod.z.number()]).transform((v) => [normalizeItem(v)]).pipe(arraySchema);
|
|
69
|
+
const fallback = defaultValue;
|
|
70
|
+
if (isRequired && fallback === null) {
|
|
71
|
+
const emptyRejectSchema = _zod.z.union([_zod.z.literal(""), _zod.z.null(), _zod.z.undefined()]).refine(() => false, { message: getMessage("required") });
|
|
72
|
+
return _zod.z.union([arraySchema, singleToArray, emptyRejectSchema]);
|
|
73
|
+
}
|
|
74
|
+
const emptySchema = _zod.z.union([_zod.z.literal(""), _zod.z.null(), _zod.z.undefined()]).transform(() => fallback);
|
|
75
|
+
return _zod.z.union([arraySchema, singleToArray, emptySchema]);
|
|
88
76
|
}
|
|
89
77
|
|
|
90
78
|
|
|
@@ -8,6 +8,7 @@ import { z } from "zod";
|
|
|
8
8
|
function manyOf(required, options) {
|
|
9
9
|
const { values = [], defaultValue = null, min, max, allowDuplicates = false, caseSensitive = true, transform, i18n } = options ?? {};
|
|
10
10
|
const isRequired = required ?? false;
|
|
11
|
+
const valuesArr = values;
|
|
11
12
|
const getMessage = (key, params) => {
|
|
12
13
|
if (i18n) {
|
|
13
14
|
const currentLocale = getLocale();
|
|
@@ -20,44 +21,24 @@ function manyOf(required, options) {
|
|
|
20
21
|
return t(`common.manyOf.${key}`, params);
|
|
21
22
|
};
|
|
22
23
|
const normalizeItem = (item) => {
|
|
23
|
-
const hasNumbers =
|
|
24
|
+
const hasNumbers = valuesArr.some((v) => typeof v === "number");
|
|
24
25
|
if (hasNumbers && typeof item === "string" && !isNaN(Number(item)) && item.trim() !== "") {
|
|
25
26
|
const numVal = Number(item);
|
|
26
|
-
if (
|
|
27
|
+
if (valuesArr.includes(numVal)) return numVal;
|
|
27
28
|
}
|
|
28
29
|
if (!caseSensitive && typeof item === "string") {
|
|
29
|
-
const match =
|
|
30
|
+
const match = valuesArr.find((v) => typeof v === "string" && v.toLowerCase() === item.toLowerCase());
|
|
30
31
|
if (match !== void 0) return match;
|
|
31
32
|
return item;
|
|
32
33
|
}
|
|
33
34
|
return item;
|
|
34
35
|
};
|
|
35
|
-
const
|
|
36
|
-
if (val === null || val === void 0 || val === "") {
|
|
37
|
-
return defaultValue;
|
|
38
|
-
}
|
|
39
|
-
if (!Array.isArray(val)) {
|
|
40
|
-
return [normalizeItem(val)];
|
|
41
|
-
}
|
|
42
|
-
return val.map(normalizeItem);
|
|
43
|
-
};
|
|
44
|
-
const baseSchema = z.preprocess(preprocessFn, z.any());
|
|
45
|
-
const schema = baseSchema.superRefine((val, ctx) => {
|
|
46
|
-
if (val === null) {
|
|
47
|
-
if (isRequired) {
|
|
48
|
-
ctx.addIssue({ code: "custom", message: getMessage("required") });
|
|
49
|
-
}
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
if (!Array.isArray(val)) {
|
|
53
|
-
ctx.addIssue({ code: "custom", message: getMessage("invalid", { values: values.join(", ") }) });
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
36
|
+
const arraySchema = z.array(z.any()).transform((arr) => arr.map(normalizeItem)).superRefine((val, ctx) => {
|
|
56
37
|
for (const item of val) {
|
|
57
|
-
if (!
|
|
38
|
+
if (!valuesArr.includes(item)) {
|
|
58
39
|
ctx.addIssue({
|
|
59
40
|
code: "custom",
|
|
60
|
-
message: getMessage("invalid", { values:
|
|
41
|
+
message: getMessage("invalid", { values: valuesArr.join(", ") })
|
|
61
42
|
});
|
|
62
43
|
return;
|
|
63
44
|
}
|
|
@@ -81,10 +62,17 @@ function manyOf(required, options) {
|
|
|
81
62
|
return;
|
|
82
63
|
}
|
|
83
64
|
}).transform((val) => {
|
|
84
|
-
if (
|
|
65
|
+
if (!transform) return val;
|
|
85
66
|
return transform(val);
|
|
86
67
|
});
|
|
87
|
-
|
|
68
|
+
const singleToArray = z.union([z.string(), z.number()]).transform((v) => [normalizeItem(v)]).pipe(arraySchema);
|
|
69
|
+
const fallback = defaultValue;
|
|
70
|
+
if (isRequired && fallback === null) {
|
|
71
|
+
const emptyRejectSchema = z.union([z.literal(""), z.null(), z.undefined()]).refine(() => false, { message: getMessage("required") });
|
|
72
|
+
return z.union([arraySchema, singleToArray, emptyRejectSchema]);
|
|
73
|
+
}
|
|
74
|
+
const emptySchema = z.union([z.literal(""), z.null(), z.undefined()]).transform(() => fallback);
|
|
75
|
+
return z.union([arraySchema, singleToArray, emptySchema]);
|
|
88
76
|
}
|
|
89
77
|
|
|
90
78
|
export {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getLocale,
|
|
3
|
+
t
|
|
4
|
+
} from "./chunk-POIDES2L.js";
|
|
5
|
+
|
|
6
|
+
// src/validators/common/one-of.ts
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
function oneOf(required, options) {
|
|
9
|
+
const { values = [], defaultValue = null, caseSensitive = true, transform, i18n } = options ?? {};
|
|
10
|
+
const isRequired = required ?? false;
|
|
11
|
+
const valuesArr = values;
|
|
12
|
+
const isAllStrings = valuesArr.every((v) => typeof v === "string");
|
|
13
|
+
const getMessage = (key, params) => {
|
|
14
|
+
if (i18n) {
|
|
15
|
+
const currentLocale = getLocale();
|
|
16
|
+
const customMessages = i18n[currentLocale];
|
|
17
|
+
if (customMessages && customMessages[key]) {
|
|
18
|
+
const template = customMessages[key];
|
|
19
|
+
return template.replace(/\$\{(\w+)}/g, (_, k) => params?.[k] ?? "");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return t(`common.oneOf.${key}`, params);
|
|
23
|
+
};
|
|
24
|
+
const isEmpty = (v) => v === "" || v === null || v === void 0;
|
|
25
|
+
let valueSchema;
|
|
26
|
+
if (isAllStrings && valuesArr.length > 0) {
|
|
27
|
+
valueSchema = z.enum(valuesArr, {
|
|
28
|
+
error: (issue) => {
|
|
29
|
+
if (isEmpty(issue.input)) return getMessage("required");
|
|
30
|
+
return getMessage("invalid", { values: valuesArr.join(", ") });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
} else if (valuesArr.length >= 2) {
|
|
34
|
+
const literals = valuesArr.map((v) => z.literal(v));
|
|
35
|
+
valueSchema = z.union(literals, {
|
|
36
|
+
error: () => getMessage("invalid", { values: valuesArr.join(", ") })
|
|
37
|
+
});
|
|
38
|
+
} else if (valuesArr.length === 1) {
|
|
39
|
+
valueSchema = z.literal(valuesArr[0]);
|
|
40
|
+
} else {
|
|
41
|
+
valueSchema = z.never();
|
|
42
|
+
}
|
|
43
|
+
if (!caseSensitive) {
|
|
44
|
+
valueSchema = z.string().transform((v) => {
|
|
45
|
+
const match = valuesArr.find((val) => typeof val === "string" && val.toLowerCase() === v.toLowerCase());
|
|
46
|
+
return match ?? v;
|
|
47
|
+
}).pipe(valueSchema);
|
|
48
|
+
}
|
|
49
|
+
if (transform) {
|
|
50
|
+
valueSchema = valueSchema.transform((v) => transform(v));
|
|
51
|
+
}
|
|
52
|
+
const fallback = defaultValue;
|
|
53
|
+
const emptySchema = z.union([z.literal(""), z.null(), z.undefined()]).transform(() => fallback);
|
|
54
|
+
if (isRequired && fallback === null) {
|
|
55
|
+
const emptyRejectSchema = z.union([z.literal(""), z.null(), z.undefined()]).refine(() => false, { message: getMessage("required") });
|
|
56
|
+
if (!isAllStrings) {
|
|
57
|
+
const numCoerceSchema = z.string().transform((v) => {
|
|
58
|
+
const n = Number(v);
|
|
59
|
+
return isNaN(n) ? v : n;
|
|
60
|
+
}).pipe(valueSchema);
|
|
61
|
+
return z.union([valueSchema, numCoerceSchema, emptyRejectSchema]);
|
|
62
|
+
}
|
|
63
|
+
return z.union([valueSchema, emptyRejectSchema]);
|
|
64
|
+
}
|
|
65
|
+
if (!isAllStrings) {
|
|
66
|
+
const numCoerceSchema = z.string().transform((v) => {
|
|
67
|
+
const n = Number(v);
|
|
68
|
+
return isNaN(n) ? v : n;
|
|
69
|
+
}).pipe(valueSchema);
|
|
70
|
+
return z.union([valueSchema, numCoerceSchema, emptySchema]);
|
|
71
|
+
}
|
|
72
|
+
return z.union([valueSchema, emptySchema]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export {
|
|
76
|
+
oneOf
|
|
77
|
+
};
|
package/dist/common/many-of.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunk5U5ERV2Pcjs = require('../chunk-5U5ERV2P.cjs');
|
|
4
4
|
require('../chunk-Q7TUNJD4.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
exports.manyOf =
|
|
7
|
+
exports.manyOf = _chunk5U5ERV2Pcjs.manyOf;
|
|
@@ -7,8 +7,10 @@ import { L as Locale } from '../config-CABSSvAp.cjs';
|
|
|
7
7
|
* Provides multi-select validation that restricts input to an array of values
|
|
8
8
|
* from a predefined set, with min/max selection, duplicate control, and transformation.
|
|
9
9
|
*
|
|
10
|
+
* Avoids z.preprocess() to preserve z.input types for React Hook Form compatibility.
|
|
11
|
+
*
|
|
10
12
|
* @author Ong Hoe Yuan
|
|
11
|
-
* @version 0.2.
|
|
13
|
+
* @version 0.2.5
|
|
12
14
|
*/
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -32,11 +34,11 @@ type ManyOfMessages = {
|
|
|
32
34
|
* Configuration options for manyOf validation
|
|
33
35
|
*
|
|
34
36
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
35
|
-
* @template
|
|
37
|
+
* @template V - The tuple type of allowed values, preserving literal types
|
|
36
38
|
*
|
|
37
39
|
* @interface ManyOfOptions
|
|
38
|
-
* @property {
|
|
39
|
-
* @property {
|
|
40
|
+
* @property {V} values - Array of allowed values
|
|
41
|
+
* @property {V[number][] | null} [defaultValue] - Default value when input is empty
|
|
40
42
|
* @property {number} [min] - Minimum number of selections
|
|
41
43
|
* @property {number} [max] - Maximum number of selections
|
|
42
44
|
* @property {boolean} [allowDuplicates=false] - Whether to allow duplicate selections
|
|
@@ -58,17 +60,19 @@ type ManyOfOptions<IsRequired extends boolean = true, V extends readonly (string
|
|
|
58
60
|
* Type alias for manyOf validation schema based on required flag
|
|
59
61
|
*
|
|
60
62
|
* @template IsRequired - Whether the field is required
|
|
61
|
-
* @template
|
|
63
|
+
* @template V - The tuple type of allowed values
|
|
62
64
|
*/
|
|
63
|
-
type ManyOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true ? ZodType<V[number][]> : ZodType<V[number][] | null>;
|
|
65
|
+
type ManyOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true ? ZodType<V[number][], V[number][] | "" | null | undefined> : ZodType<V[number][] | null, V[number][] | "" | null | undefined>;
|
|
64
66
|
/**
|
|
65
67
|
* Creates a Zod schema for multi-select validation that restricts values to a predefined set
|
|
66
68
|
*
|
|
69
|
+
* Avoids z.preprocess() to preserve z.input types for React Hook Form compatibility.
|
|
70
|
+
*
|
|
67
71
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
68
|
-
* @template
|
|
72
|
+
* @template V - The tuple type of allowed values (inferred via const type parameter)
|
|
69
73
|
* @param {IsRequired} [required=false] - Whether the field is required
|
|
70
|
-
* @param {ManyOfOptions<IsRequired,
|
|
71
|
-
* @returns {ManyOfSchema<IsRequired,
|
|
74
|
+
* @param {ManyOfOptions<IsRequired, V>} options - Configuration options (values is required)
|
|
75
|
+
* @returns {ManyOfSchema<IsRequired, V>} Zod schema for manyOf validation
|
|
72
76
|
*
|
|
73
77
|
* @example
|
|
74
78
|
* ```typescript
|
package/dist/common/many-of.d.ts
CHANGED
|
@@ -7,8 +7,10 @@ import { L as Locale } from '../config-CABSSvAp.js';
|
|
|
7
7
|
* Provides multi-select validation that restricts input to an array of values
|
|
8
8
|
* from a predefined set, with min/max selection, duplicate control, and transformation.
|
|
9
9
|
*
|
|
10
|
+
* Avoids z.preprocess() to preserve z.input types for React Hook Form compatibility.
|
|
11
|
+
*
|
|
10
12
|
* @author Ong Hoe Yuan
|
|
11
|
-
* @version 0.2.
|
|
13
|
+
* @version 0.2.5
|
|
12
14
|
*/
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -32,11 +34,11 @@ type ManyOfMessages = {
|
|
|
32
34
|
* Configuration options for manyOf validation
|
|
33
35
|
*
|
|
34
36
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
35
|
-
* @template
|
|
37
|
+
* @template V - The tuple type of allowed values, preserving literal types
|
|
36
38
|
*
|
|
37
39
|
* @interface ManyOfOptions
|
|
38
|
-
* @property {
|
|
39
|
-
* @property {
|
|
40
|
+
* @property {V} values - Array of allowed values
|
|
41
|
+
* @property {V[number][] | null} [defaultValue] - Default value when input is empty
|
|
40
42
|
* @property {number} [min] - Minimum number of selections
|
|
41
43
|
* @property {number} [max] - Maximum number of selections
|
|
42
44
|
* @property {boolean} [allowDuplicates=false] - Whether to allow duplicate selections
|
|
@@ -58,17 +60,19 @@ type ManyOfOptions<IsRequired extends boolean = true, V extends readonly (string
|
|
|
58
60
|
* Type alias for manyOf validation schema based on required flag
|
|
59
61
|
*
|
|
60
62
|
* @template IsRequired - Whether the field is required
|
|
61
|
-
* @template
|
|
63
|
+
* @template V - The tuple type of allowed values
|
|
62
64
|
*/
|
|
63
|
-
type ManyOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true ? ZodType<V[number][]> : ZodType<V[number][] | null>;
|
|
65
|
+
type ManyOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true ? ZodType<V[number][], V[number][] | "" | null | undefined> : ZodType<V[number][] | null, V[number][] | "" | null | undefined>;
|
|
64
66
|
/**
|
|
65
67
|
* Creates a Zod schema for multi-select validation that restricts values to a predefined set
|
|
66
68
|
*
|
|
69
|
+
* Avoids z.preprocess() to preserve z.input types for React Hook Form compatibility.
|
|
70
|
+
*
|
|
67
71
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
68
|
-
* @template
|
|
72
|
+
* @template V - The tuple type of allowed values (inferred via const type parameter)
|
|
69
73
|
* @param {IsRequired} [required=false] - Whether the field is required
|
|
70
|
-
* @param {ManyOfOptions<IsRequired,
|
|
71
|
-
* @returns {ManyOfSchema<IsRequired,
|
|
74
|
+
* @param {ManyOfOptions<IsRequired, V>} options - Configuration options (values is required)
|
|
75
|
+
* @returns {ManyOfSchema<IsRequired, V>} Zod schema for manyOf validation
|
|
72
76
|
*
|
|
73
77
|
* @example
|
|
74
78
|
* ```typescript
|
package/dist/common/many-of.js
CHANGED
package/dist/common/one-of.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunk5NBWPAHCcjs = require('../chunk-5NBWPAHC.cjs');
|
|
4
4
|
require('../chunk-Q7TUNJD4.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
exports.oneOf =
|
|
7
|
+
exports.oneOf = _chunk5NBWPAHCcjs.oneOf;
|
package/dist/common/one-of.d.cts
CHANGED
|
@@ -7,8 +7,11 @@ import { L as Locale } from '../config-CABSSvAp.cjs';
|
|
|
7
7
|
* Provides single-select validation that restricts input to a predefined set of allowed values,
|
|
8
8
|
* with support for case-insensitive matching, default values, and transformation.
|
|
9
9
|
*
|
|
10
|
+
* Uses z.enum() internally to preserve literal type inference for both z.input and z.output,
|
|
11
|
+
* making it compatible with React Hook Form resolvers and other type-aware form libraries.
|
|
12
|
+
*
|
|
10
13
|
* @author Ong Hoe Yuan
|
|
11
|
-
* @version 0.2.
|
|
14
|
+
* @version 0.2.5
|
|
12
15
|
*/
|
|
13
16
|
|
|
14
17
|
/**
|
|
@@ -26,11 +29,11 @@ type OneOfMessages = {
|
|
|
26
29
|
* Configuration options for oneOf validation
|
|
27
30
|
*
|
|
28
31
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
29
|
-
* @template
|
|
32
|
+
* @template V - The tuple type of allowed values, preserving literal types
|
|
30
33
|
*
|
|
31
34
|
* @interface OneOfOptions
|
|
32
|
-
* @property {
|
|
33
|
-
* @property {
|
|
35
|
+
* @property {V} values - Array of allowed values
|
|
36
|
+
* @property {V[number] | null} [defaultValue] - Default value when input is empty
|
|
34
37
|
* @property {boolean} [caseSensitive=true] - Whether string matching is case-sensitive
|
|
35
38
|
* @property {Function} [transform] - Custom transformation function applied after validation
|
|
36
39
|
* @property {Record<Locale, OneOfMessages>} [i18n] - Custom error messages for different locales
|
|
@@ -46,17 +49,20 @@ type OneOfOptions<IsRequired extends boolean = true, V extends readonly (string
|
|
|
46
49
|
* Type alias for oneOf validation schema based on required flag
|
|
47
50
|
*
|
|
48
51
|
* @template IsRequired - Whether the field is required
|
|
49
|
-
* @template
|
|
52
|
+
* @template V - The tuple type of allowed values
|
|
50
53
|
*/
|
|
51
|
-
type OneOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true ? ZodType<V[number]> : ZodType<V[number] | null>;
|
|
54
|
+
type OneOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true ? ZodType<V[number], V[number] | "" | null | undefined> : ZodType<V[number] | null, V[number] | "" | null | undefined>;
|
|
52
55
|
/**
|
|
53
56
|
* Creates a Zod schema for single-select validation that restricts values to a predefined set
|
|
54
57
|
*
|
|
58
|
+
* Uses z.enum() internally to preserve both z.input and z.output literal types,
|
|
59
|
+
* ensuring compatibility with React Hook Form and other type-aware form libraries.
|
|
60
|
+
*
|
|
55
61
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
56
|
-
* @template
|
|
62
|
+
* @template V - The tuple type of allowed values (inferred via const type parameter)
|
|
57
63
|
* @param {IsRequired} [required=false] - Whether the field is required
|
|
58
|
-
* @param {OneOfOptions<IsRequired,
|
|
59
|
-
* @returns {OneOfSchema<IsRequired,
|
|
64
|
+
* @param {OneOfOptions<IsRequired, V>} options - Configuration options (values is required)
|
|
65
|
+
* @returns {OneOfSchema<IsRequired, V>} Zod schema for oneOf validation
|
|
60
66
|
*
|
|
61
67
|
* @example
|
|
62
68
|
* ```typescript
|
|
@@ -65,7 +71,7 @@ type OneOfSchema<IsRequired extends boolean, V extends readonly (string | number
|
|
|
65
71
|
* roleSchema.parse("admin") // ✓ "admin"
|
|
66
72
|
* roleSchema.parse(null) // ✓ null
|
|
67
73
|
*
|
|
68
|
-
* // Required
|
|
74
|
+
* // Required — z.input and z.output are both "active" | "inactive" | "pending"
|
|
69
75
|
* const statusSchema = oneOf(true, { values: ["active", "inactive", "pending"] })
|
|
70
76
|
* statusSchema.parse("active") // ✓ "active"
|
|
71
77
|
* statusSchema.parse(null) // ✗ Required
|
package/dist/common/one-of.d.ts
CHANGED
|
@@ -7,8 +7,11 @@ import { L as Locale } from '../config-CABSSvAp.js';
|
|
|
7
7
|
* Provides single-select validation that restricts input to a predefined set of allowed values,
|
|
8
8
|
* with support for case-insensitive matching, default values, and transformation.
|
|
9
9
|
*
|
|
10
|
+
* Uses z.enum() internally to preserve literal type inference for both z.input and z.output,
|
|
11
|
+
* making it compatible with React Hook Form resolvers and other type-aware form libraries.
|
|
12
|
+
*
|
|
10
13
|
* @author Ong Hoe Yuan
|
|
11
|
-
* @version 0.2.
|
|
14
|
+
* @version 0.2.5
|
|
12
15
|
*/
|
|
13
16
|
|
|
14
17
|
/**
|
|
@@ -26,11 +29,11 @@ type OneOfMessages = {
|
|
|
26
29
|
* Configuration options for oneOf validation
|
|
27
30
|
*
|
|
28
31
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
29
|
-
* @template
|
|
32
|
+
* @template V - The tuple type of allowed values, preserving literal types
|
|
30
33
|
*
|
|
31
34
|
* @interface OneOfOptions
|
|
32
|
-
* @property {
|
|
33
|
-
* @property {
|
|
35
|
+
* @property {V} values - Array of allowed values
|
|
36
|
+
* @property {V[number] | null} [defaultValue] - Default value when input is empty
|
|
34
37
|
* @property {boolean} [caseSensitive=true] - Whether string matching is case-sensitive
|
|
35
38
|
* @property {Function} [transform] - Custom transformation function applied after validation
|
|
36
39
|
* @property {Record<Locale, OneOfMessages>} [i18n] - Custom error messages for different locales
|
|
@@ -46,17 +49,20 @@ type OneOfOptions<IsRequired extends boolean = true, V extends readonly (string
|
|
|
46
49
|
* Type alias for oneOf validation schema based on required flag
|
|
47
50
|
*
|
|
48
51
|
* @template IsRequired - Whether the field is required
|
|
49
|
-
* @template
|
|
52
|
+
* @template V - The tuple type of allowed values
|
|
50
53
|
*/
|
|
51
|
-
type OneOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true ? ZodType<V[number]> : ZodType<V[number] | null>;
|
|
54
|
+
type OneOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true ? ZodType<V[number], V[number] | "" | null | undefined> : ZodType<V[number] | null, V[number] | "" | null | undefined>;
|
|
52
55
|
/**
|
|
53
56
|
* Creates a Zod schema for single-select validation that restricts values to a predefined set
|
|
54
57
|
*
|
|
58
|
+
* Uses z.enum() internally to preserve both z.input and z.output literal types,
|
|
59
|
+
* ensuring compatibility with React Hook Form and other type-aware form libraries.
|
|
60
|
+
*
|
|
55
61
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
56
|
-
* @template
|
|
62
|
+
* @template V - The tuple type of allowed values (inferred via const type parameter)
|
|
57
63
|
* @param {IsRequired} [required=false] - Whether the field is required
|
|
58
|
-
* @param {OneOfOptions<IsRequired,
|
|
59
|
-
* @returns {OneOfSchema<IsRequired,
|
|
64
|
+
* @param {OneOfOptions<IsRequired, V>} options - Configuration options (values is required)
|
|
65
|
+
* @returns {OneOfSchema<IsRequired, V>} Zod schema for oneOf validation
|
|
60
66
|
*
|
|
61
67
|
* @example
|
|
62
68
|
* ```typescript
|
|
@@ -65,7 +71,7 @@ type OneOfSchema<IsRequired extends boolean, V extends readonly (string | number
|
|
|
65
71
|
* roleSchema.parse("admin") // ✓ "admin"
|
|
66
72
|
* roleSchema.parse(null) // ✓ null
|
|
67
73
|
*
|
|
68
|
-
* // Required
|
|
74
|
+
* // Required — z.input and z.output are both "active" | "inactive" | "pending"
|
|
69
75
|
* const statusSchema = oneOf(true, { values: ["active", "inactive", "pending"] })
|
|
70
76
|
* statusSchema.parse("active") // ✓ "active"
|
|
71
77
|
* statusSchema.parse(null) // ✗ Required
|
package/dist/common/one-of.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -60,7 +60,7 @@ var _chunkBZSPJJYTcjs = require('./chunk-BZSPJJYT.cjs');
|
|
|
60
60
|
var _chunkG747FHUZcjs = require('./chunk-G747FHUZ.cjs');
|
|
61
61
|
|
|
62
62
|
|
|
63
|
-
var
|
|
63
|
+
var _chunk5NBWPAHCcjs = require('./chunk-5NBWPAHC.cjs');
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
var _chunkQ24GYUTOcjs = require('./chunk-Q24GYUTO.cjs');
|
|
@@ -114,7 +114,7 @@ var _chunkKIUO2HIRcjs = require('./chunk-KIUO2HIR.cjs');
|
|
|
114
114
|
var _chunkJZEF5Q3Wcjs = require('./chunk-JZEF5Q3W.cjs');
|
|
115
115
|
|
|
116
116
|
|
|
117
|
-
var
|
|
117
|
+
var _chunk5U5ERV2Pcjs = require('./chunk-5U5ERV2P.cjs');
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
|
|
@@ -185,4 +185,4 @@ var _chunkQ7TUNJD4cjs = require('./chunk-Q7TUNJD4.cjs');
|
|
|
185
185
|
|
|
186
186
|
|
|
187
187
|
|
|
188
|
-
exports.DATETIME_PATTERNS = _chunk53EEWALQcjs.DATETIME_PATTERNS; exports.ID_PATTERNS = _chunkJZEF5Q3Wcjs.ID_PATTERNS; exports.TAIWAN_BANK_CODES = _chunkQQWX3ICKcjs.TAIWAN_BANK_CODES; exports.TIME_PATTERNS = _chunkEDTNS2XLcjs.TIME_PATTERNS; exports.VALID_3_DIGIT_PREFIXES = _chunkFP4O2ICMcjs.VALID_3_DIGIT_PREFIXES; exports.boolean = _chunkLNWEJED7cjs.boolean; exports.color = _chunkA2GAEU4Ocjs.color; exports.coordinate = _chunkFEL432I2cjs.coordinate; exports.creditCard = _chunkZCX22PY4cjs.creditCard; exports.date = _chunk4AQB4RSUcjs.date; exports.datetime = _chunk53EEWALQcjs.datetime; exports.detectCardType = _chunkZCX22PY4cjs.detectCardType; exports.detectIdType = _chunkJZEF5Q3Wcjs.detectIdType; exports.email = _chunkH25N5GP6cjs.email; exports.file = _chunkKIUO2HIRcjs.file; exports.getLocale = _chunkQ7TUNJD4cjs.getLocale; exports.id = _chunkJZEF5Q3Wcjs.id; exports.ip = _chunkLXFRQLH4cjs.ip; exports.manyOf =
|
|
188
|
+
exports.DATETIME_PATTERNS = _chunk53EEWALQcjs.DATETIME_PATTERNS; exports.ID_PATTERNS = _chunkJZEF5Q3Wcjs.ID_PATTERNS; exports.TAIWAN_BANK_CODES = _chunkQQWX3ICKcjs.TAIWAN_BANK_CODES; exports.TIME_PATTERNS = _chunkEDTNS2XLcjs.TIME_PATTERNS; exports.VALID_3_DIGIT_PREFIXES = _chunkFP4O2ICMcjs.VALID_3_DIGIT_PREFIXES; exports.boolean = _chunkLNWEJED7cjs.boolean; exports.color = _chunkA2GAEU4Ocjs.color; exports.coordinate = _chunkFEL432I2cjs.coordinate; exports.creditCard = _chunkZCX22PY4cjs.creditCard; exports.date = _chunk4AQB4RSUcjs.date; exports.datetime = _chunk53EEWALQcjs.datetime; exports.detectCardType = _chunkZCX22PY4cjs.detectCardType; exports.detectIdType = _chunkJZEF5Q3Wcjs.detectIdType; exports.email = _chunkH25N5GP6cjs.email; exports.file = _chunkKIUO2HIRcjs.file; exports.getLocale = _chunkQ7TUNJD4cjs.getLocale; exports.id = _chunkJZEF5Q3Wcjs.id; exports.ip = _chunkLXFRQLH4cjs.ip; exports.manyOf = _chunk5U5ERV2Pcjs.manyOf; exports.normalizeDateTimeValue = _chunk53EEWALQcjs.normalizeDateTimeValue; exports.normalizeTime = _chunkEDTNS2XLcjs.normalizeTime; exports.number = _chunkG747FHUZcjs.number; exports.oneOf = _chunk5NBWPAHCcjs.oneOf; exports.parseDateTimeValue = _chunk53EEWALQcjs.parseDateTimeValue; exports.parseTimeToMinutes = _chunkEDTNS2XLcjs.parseTimeToMinutes; exports.password = _chunkQ24GYUTOcjs.password; exports.setLocale = _chunkQ7TUNJD4cjs.setLocale; exports.text = _chunkHZ2WESSLcjs.text; exports.time = _chunkEDTNS2XLcjs.time; exports.twBankAccount = _chunkQQWX3ICKcjs.twBankAccount; exports.twBusinessId = _chunkIWR3H7IHcjs.twBusinessId; exports.twFax = _chunkBZSPJJYTcjs.twFax; exports.twInvoice = _chunkV2KKGSKQcjs.twInvoice; exports.twLicensePlate = _chunkTPXRQT2Hcjs.twLicensePlate; exports.twMobile = _chunkAYCXAJRAcjs.twMobile; exports.twNationalId = _chunkUCPKW43Kcjs.twNationalId; exports.twPassport = _chunk5ZMTAI4Gcjs.twPassport; exports.twPostalCode = _chunkFP4O2ICMcjs.twPostalCode; exports.twTel = _chunkVKBNKPFOcjs.twTel; exports.url = _chunkTDEXEIHHcjs.url; exports.validate3DigitPostalCode = _chunkFP4O2ICMcjs.validate3DigitPostalCode; exports.validate5DigitPostalCode = _chunkFP4O2ICMcjs.validate5DigitPostalCode; exports.validate6DigitPostalCode = _chunkFP4O2ICMcjs.validate6DigitPostalCode; exports.validateCitizenId = _chunkUCPKW43Kcjs.validateCitizenId; exports.validateColor = _chunkA2GAEU4Ocjs.validateColor; exports.validateCreditCard = _chunkZCX22PY4cjs.validateCreditCard; exports.validateDateTimeFormat = _chunk53EEWALQcjs.validateDateTimeFormat; exports.validateIPv4 = _chunkLXFRQLH4cjs.validateIPv4; exports.validateIPv6 = _chunkLXFRQLH4cjs.validateIPv6; exports.validateIdType = _chunkJZEF5Q3Wcjs.validateIdType; exports.validateLatitude = _chunkFEL432I2cjs.validateLatitude; exports.validateLongitude = _chunkFEL432I2cjs.validateLongitude; exports.validateNewResidentId = _chunkUCPKW43Kcjs.validateNewResidentId; exports.validateOldResidentId = _chunkUCPKW43Kcjs.validateOldResidentId; exports.validateTaiwanBankAccount = _chunkQQWX3ICKcjs.validateTaiwanBankAccount; exports.validateTaiwanBusinessId = _chunkIWR3H7IHcjs.validateTaiwanBusinessId; exports.validateTaiwanFax = _chunkBZSPJJYTcjs.validateTaiwanFax; exports.validateTaiwanInvoice = _chunkV2KKGSKQcjs.validateTaiwanInvoice; exports.validateTaiwanLicensePlate = _chunkTPXRQT2Hcjs.validateTaiwanLicensePlate; exports.validateTaiwanMobile = _chunkAYCXAJRAcjs.validateTaiwanMobile; exports.validateTaiwanNationalId = _chunkUCPKW43Kcjs.validateTaiwanNationalId; exports.validateTaiwanPassport = _chunk5ZMTAI4Gcjs.validateTaiwanPassport; exports.validateTaiwanPostalCode = _chunkFP4O2ICMcjs.validateTaiwanPostalCode; exports.validateTaiwanTel = _chunkVKBNKPFOcjs.validateTaiwanTel; exports.validateTimeFormat = _chunkEDTNS2XLcjs.validateTimeFormat;
|
package/dist/index.js
CHANGED
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
} from "./chunk-3QLUXIY2.js";
|
|
61
61
|
import {
|
|
62
62
|
oneOf
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-YG6YHVAE.js";
|
|
64
64
|
import {
|
|
65
65
|
password
|
|
66
66
|
} from "./chunk-NWQSOSNF.js";
|
|
@@ -114,7 +114,7 @@ import {
|
|
|
114
114
|
} from "./chunk-H6STFX4I.js";
|
|
115
115
|
import {
|
|
116
116
|
manyOf
|
|
117
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-S4OJGXWC.js";
|
|
118
118
|
import {
|
|
119
119
|
getLocale,
|
|
120
120
|
setLocale
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hy_ong/zod-kit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "A comprehensive TypeScript library providing pre-built Zod validation schemas with full internationalization support for common data types and Taiwan-specific formats",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"zod",
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
* Provides multi-select validation that restricts input to an array of values
|
|
5
5
|
* from a predefined set, with min/max selection, duplicate control, and transformation.
|
|
6
6
|
*
|
|
7
|
+
* Avoids z.preprocess() to preserve z.input types for React Hook Form compatibility.
|
|
8
|
+
*
|
|
7
9
|
* @author Ong Hoe Yuan
|
|
8
|
-
* @version 0.2.
|
|
10
|
+
* @version 0.2.5
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
import { z, ZodType } from "zod"
|
|
@@ -34,11 +36,11 @@ export type ManyOfMessages = {
|
|
|
34
36
|
* Configuration options for manyOf validation
|
|
35
37
|
*
|
|
36
38
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
37
|
-
* @template
|
|
39
|
+
* @template V - The tuple type of allowed values, preserving literal types
|
|
38
40
|
*
|
|
39
41
|
* @interface ManyOfOptions
|
|
40
|
-
* @property {
|
|
41
|
-
* @property {
|
|
42
|
+
* @property {V} values - Array of allowed values
|
|
43
|
+
* @property {V[number][] | null} [defaultValue] - Default value when input is empty
|
|
42
44
|
* @property {number} [min] - Minimum number of selections
|
|
43
45
|
* @property {number} [max] - Maximum number of selections
|
|
44
46
|
* @property {boolean} [allowDuplicates=false] - Whether to allow duplicate selections
|
|
@@ -61,18 +63,22 @@ export type ManyOfOptions<IsRequired extends boolean = true, V extends readonly
|
|
|
61
63
|
* Type alias for manyOf validation schema based on required flag
|
|
62
64
|
*
|
|
63
65
|
* @template IsRequired - Whether the field is required
|
|
64
|
-
* @template
|
|
66
|
+
* @template V - The tuple type of allowed values
|
|
65
67
|
*/
|
|
66
|
-
export type ManyOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true
|
|
68
|
+
export type ManyOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true
|
|
69
|
+
? ZodType<V[number][], V[number][] | "" | null | undefined>
|
|
70
|
+
: ZodType<V[number][] | null, V[number][] | "" | null | undefined>
|
|
67
71
|
|
|
68
72
|
/**
|
|
69
73
|
* Creates a Zod schema for multi-select validation that restricts values to a predefined set
|
|
70
74
|
*
|
|
75
|
+
* Avoids z.preprocess() to preserve z.input types for React Hook Form compatibility.
|
|
76
|
+
*
|
|
71
77
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
72
|
-
* @template
|
|
78
|
+
* @template V - The tuple type of allowed values (inferred via const type parameter)
|
|
73
79
|
* @param {IsRequired} [required=false] - Whether the field is required
|
|
74
|
-
* @param {ManyOfOptions<IsRequired,
|
|
75
|
-
* @returns {ManyOfSchema<IsRequired,
|
|
80
|
+
* @param {ManyOfOptions<IsRequired, V>} options - Configuration options (values is required)
|
|
81
|
+
* @returns {ManyOfSchema<IsRequired, V>} Zod schema for manyOf validation
|
|
76
82
|
*
|
|
77
83
|
* @example
|
|
78
84
|
* ```typescript
|
|
@@ -117,6 +123,7 @@ export function manyOf<IsRequired extends boolean = false, const V extends reado
|
|
|
117
123
|
const { values = [] as unknown as V, defaultValue = null, min, max, allowDuplicates = false, caseSensitive = true, transform, i18n } = options ?? {}
|
|
118
124
|
|
|
119
125
|
const isRequired = required ?? (false as IsRequired)
|
|
126
|
+
const valuesArr = values as readonly (string | number)[]
|
|
120
127
|
|
|
121
128
|
const getMessage = (key: keyof ManyOfMessages, params?: Record<string, any>) => {
|
|
122
129
|
if (i18n) {
|
|
@@ -132,15 +139,15 @@ export function manyOf<IsRequired extends boolean = false, const V extends reado
|
|
|
132
139
|
|
|
133
140
|
const normalizeItem = (item: unknown): unknown => {
|
|
134
141
|
// Coerce number strings to numbers when values contains numbers
|
|
135
|
-
const hasNumbers =
|
|
142
|
+
const hasNumbers = valuesArr.some((v) => typeof v === "number")
|
|
136
143
|
if (hasNumbers && typeof item === "string" && !isNaN(Number(item)) && item.trim() !== "") {
|
|
137
144
|
const numVal = Number(item)
|
|
138
|
-
if ((
|
|
145
|
+
if ((valuesArr as readonly number[]).includes(numVal)) return numVal
|
|
139
146
|
}
|
|
140
147
|
|
|
141
148
|
// Case-insensitive normalization
|
|
142
149
|
if (!caseSensitive && typeof item === "string") {
|
|
143
|
-
const match =
|
|
150
|
+
const match = valuesArr.find((v) => typeof v === "string" && v.toLowerCase() === item.toLowerCase())
|
|
144
151
|
if (match !== undefined) return match
|
|
145
152
|
return item
|
|
146
153
|
}
|
|
@@ -148,72 +155,70 @@ export function manyOf<IsRequired extends boolean = false, const V extends reado
|
|
|
148
155
|
return item
|
|
149
156
|
}
|
|
150
157
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const schema = baseSchema.superRefine((val, ctx) => {
|
|
167
|
-
if (val === null) {
|
|
168
|
-
if (isRequired) {
|
|
169
|
-
ctx.addIssue({ code: "custom", message: getMessage("required") })
|
|
158
|
+
// Build an array schema that validates + normalizes items, then applies superRefine for constraints
|
|
159
|
+
const arraySchema = z
|
|
160
|
+
.array(z.any())
|
|
161
|
+
.transform((arr) => arr.map(normalizeItem))
|
|
162
|
+
.superRefine((val, ctx) => {
|
|
163
|
+
// Check each item is in the allowed values
|
|
164
|
+
for (const item of val) {
|
|
165
|
+
if (!(valuesArr as readonly (string | number)[]).includes(item as string | number)) {
|
|
166
|
+
ctx.addIssue({
|
|
167
|
+
code: "custom",
|
|
168
|
+
message: getMessage("invalid", { values: valuesArr.join(", ") }),
|
|
169
|
+
})
|
|
170
|
+
return
|
|
171
|
+
}
|
|
170
172
|
}
|
|
171
|
-
return
|
|
172
|
-
}
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
174
|
+
// Duplicate check
|
|
175
|
+
if (!allowDuplicates) {
|
|
176
|
+
const seen = new Set()
|
|
177
|
+
for (const item of val) {
|
|
178
|
+
if (seen.has(item)) {
|
|
179
|
+
ctx.addIssue({ code: "custom", message: getMessage("duplicate") })
|
|
180
|
+
return
|
|
181
|
+
}
|
|
182
|
+
seen.add(item)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
178
185
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
ctx.addIssue({
|
|
183
|
-
code: "custom",
|
|
184
|
-
message: getMessage("invalid", { values: values.join(", ") }),
|
|
185
|
-
})
|
|
186
|
+
// Min/max selection count
|
|
187
|
+
if (min !== undefined && val.length < min) {
|
|
188
|
+
ctx.addIssue({ code: "custom", message: getMessage("minSelect", { min }) })
|
|
186
189
|
return
|
|
187
190
|
}
|
|
188
|
-
}
|
|
189
191
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
for (const item of val) {
|
|
194
|
-
if (seen.has(item)) {
|
|
195
|
-
ctx.addIssue({ code: "custom", message: getMessage("duplicate") })
|
|
196
|
-
return
|
|
197
|
-
}
|
|
198
|
-
seen.add(item)
|
|
192
|
+
if (max !== undefined && val.length > max) {
|
|
193
|
+
ctx.addIssue({ code: "custom", message: getMessage("maxSelect", { max }) })
|
|
194
|
+
return
|
|
199
195
|
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
196
|
+
})
|
|
197
|
+
.transform((val) => {
|
|
198
|
+
if (!transform) return val as V[number][]
|
|
199
|
+
return transform(val as V[number][])
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
// Single value → wrap in array
|
|
203
|
+
const singleToArray = z.union([z.string(), z.number()]).transform((v) => [normalizeItem(v)])
|
|
204
|
+
.pipe(arraySchema)
|
|
205
|
+
|
|
206
|
+
// Handle required vs optional
|
|
207
|
+
const fallback = defaultValue as V[number][] | null
|
|
208
|
+
|
|
209
|
+
if (isRequired && fallback === null) {
|
|
210
|
+
// Required, no default: empty values should fail with "required" message
|
|
211
|
+
const emptyRejectSchema = z
|
|
212
|
+
.union([z.literal("" as const), z.null(), z.undefined()])
|
|
213
|
+
.refine(() => false, { message: getMessage("required") })
|
|
214
|
+
|
|
215
|
+
return z.union([arraySchema, singleToArray, emptyRejectSchema]) as unknown as ManyOfSchema<IsRequired, V>
|
|
216
|
+
}
|
|
207
217
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
})
|
|
213
|
-
.transform((val) => {
|
|
214
|
-
if (val === null || !Array.isArray(val) || !transform) return val
|
|
215
|
-
return transform(val as V[number][])
|
|
216
|
-
})
|
|
218
|
+
// Optional or has default: empty values → fallback
|
|
219
|
+
const emptySchema = z
|
|
220
|
+
.union([z.literal("" as const), z.null(), z.undefined()])
|
|
221
|
+
.transform(() => fallback)
|
|
217
222
|
|
|
218
|
-
return
|
|
223
|
+
return z.union([arraySchema, singleToArray, emptySchema]) as unknown as ManyOfSchema<IsRequired, V>
|
|
219
224
|
}
|
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
* Provides single-select validation that restricts input to a predefined set of allowed values,
|
|
5
5
|
* with support for case-insensitive matching, default values, and transformation.
|
|
6
6
|
*
|
|
7
|
+
* Uses z.enum() internally to preserve literal type inference for both z.input and z.output,
|
|
8
|
+
* making it compatible with React Hook Form resolvers and other type-aware form libraries.
|
|
9
|
+
*
|
|
7
10
|
* @author Ong Hoe Yuan
|
|
8
|
-
* @version 0.2.
|
|
11
|
+
* @version 0.2.5
|
|
9
12
|
*/
|
|
10
13
|
|
|
11
14
|
import { z, ZodType } from "zod"
|
|
@@ -28,11 +31,11 @@ export type OneOfMessages = {
|
|
|
28
31
|
* Configuration options for oneOf validation
|
|
29
32
|
*
|
|
30
33
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
31
|
-
* @template
|
|
34
|
+
* @template V - The tuple type of allowed values, preserving literal types
|
|
32
35
|
*
|
|
33
36
|
* @interface OneOfOptions
|
|
34
|
-
* @property {
|
|
35
|
-
* @property {
|
|
37
|
+
* @property {V} values - Array of allowed values
|
|
38
|
+
* @property {V[number] | null} [defaultValue] - Default value when input is empty
|
|
36
39
|
* @property {boolean} [caseSensitive=true] - Whether string matching is case-sensitive
|
|
37
40
|
* @property {Function} [transform] - Custom transformation function applied after validation
|
|
38
41
|
* @property {Record<Locale, OneOfMessages>} [i18n] - Custom error messages for different locales
|
|
@@ -49,18 +52,23 @@ export type OneOfOptions<IsRequired extends boolean = true, V extends readonly (
|
|
|
49
52
|
* Type alias for oneOf validation schema based on required flag
|
|
50
53
|
*
|
|
51
54
|
* @template IsRequired - Whether the field is required
|
|
52
|
-
* @template
|
|
55
|
+
* @template V - The tuple type of allowed values
|
|
53
56
|
*/
|
|
54
|
-
export type OneOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true
|
|
57
|
+
export type OneOfSchema<IsRequired extends boolean, V extends readonly (string | number)[]> = IsRequired extends true
|
|
58
|
+
? ZodType<V[number], V[number] | "" | null | undefined>
|
|
59
|
+
: ZodType<V[number] | null, V[number] | "" | null | undefined>
|
|
55
60
|
|
|
56
61
|
/**
|
|
57
62
|
* Creates a Zod schema for single-select validation that restricts values to a predefined set
|
|
58
63
|
*
|
|
64
|
+
* Uses z.enum() internally to preserve both z.input and z.output literal types,
|
|
65
|
+
* ensuring compatibility with React Hook Form and other type-aware form libraries.
|
|
66
|
+
*
|
|
59
67
|
* @template IsRequired - Whether the field is required (affects return type)
|
|
60
|
-
* @template
|
|
68
|
+
* @template V - The tuple type of allowed values (inferred via const type parameter)
|
|
61
69
|
* @param {IsRequired} [required=false] - Whether the field is required
|
|
62
|
-
* @param {OneOfOptions<IsRequired,
|
|
63
|
-
* @returns {OneOfSchema<IsRequired,
|
|
70
|
+
* @param {OneOfOptions<IsRequired, V>} options - Configuration options (values is required)
|
|
71
|
+
* @returns {OneOfSchema<IsRequired, V>} Zod schema for oneOf validation
|
|
64
72
|
*
|
|
65
73
|
* @example
|
|
66
74
|
* ```typescript
|
|
@@ -69,7 +77,7 @@ export type OneOfSchema<IsRequired extends boolean, V extends readonly (string |
|
|
|
69
77
|
* roleSchema.parse("admin") // ✓ "admin"
|
|
70
78
|
* roleSchema.parse(null) // ✓ null
|
|
71
79
|
*
|
|
72
|
-
* // Required
|
|
80
|
+
* // Required — z.input and z.output are both "active" | "inactive" | "pending"
|
|
73
81
|
* const statusSchema = oneOf(true, { values: ["active", "inactive", "pending"] })
|
|
74
82
|
* statusSchema.parse("active") // ✓ "active"
|
|
75
83
|
* statusSchema.parse(null) // ✗ Required
|
|
@@ -110,6 +118,8 @@ export function oneOf<IsRequired extends boolean = false, const V extends readon
|
|
|
110
118
|
const { values = [] as unknown as V, defaultValue = null, caseSensitive = true, transform, i18n } = options ?? {}
|
|
111
119
|
|
|
112
120
|
const isRequired = required ?? (false as IsRequired)
|
|
121
|
+
const valuesArr = values as readonly (string | number)[]
|
|
122
|
+
const isAllStrings = valuesArr.every((v) => typeof v === "string")
|
|
113
123
|
|
|
114
124
|
const getMessage = (key: keyof OneOfMessages, params?: Record<string, any>) => {
|
|
115
125
|
if (i18n) {
|
|
@@ -123,50 +133,82 @@ export function oneOf<IsRequired extends boolean = false, const V extends readon
|
|
|
123
133
|
return t(`common.oneOf.${key}`, params)
|
|
124
134
|
}
|
|
125
135
|
|
|
126
|
-
const
|
|
127
|
-
if (val === "" || val === null || val === undefined) {
|
|
128
|
-
return defaultValue
|
|
129
|
-
}
|
|
136
|
+
const isEmpty = (v: unknown) => v === "" || v === null || v === undefined
|
|
130
137
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
// Build the value-matching schema using z.enum() or z.union(z.literal())
|
|
139
|
+
let valueSchema: ZodType
|
|
140
|
+
if (isAllStrings && valuesArr.length > 0) {
|
|
141
|
+
valueSchema = z.enum(valuesArr as unknown as readonly [string, ...string[]], {
|
|
142
|
+
error: (issue) => {
|
|
143
|
+
if (isEmpty(issue.input)) return getMessage("required")
|
|
144
|
+
return getMessage("invalid", { values: valuesArr.join(", ") })
|
|
145
|
+
},
|
|
146
|
+
})
|
|
147
|
+
} else if (valuesArr.length >= 2) {
|
|
148
|
+
const literals = valuesArr.map((v) => z.literal(v))
|
|
149
|
+
valueSchema = z.union(literals as unknown as readonly [ZodType, ZodType, ...ZodType[]], {
|
|
150
|
+
error: () => getMessage("invalid", { values: valuesArr.join(", ") }),
|
|
151
|
+
})
|
|
152
|
+
} else if (valuesArr.length === 1) {
|
|
153
|
+
valueSchema = z.literal(valuesArr[0])
|
|
154
|
+
} else {
|
|
155
|
+
valueSchema = z.never()
|
|
156
|
+
}
|
|
137
157
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
158
|
+
// Case-insensitive: pipe through a string normalizer
|
|
159
|
+
if (!caseSensitive) {
|
|
160
|
+
valueSchema = z
|
|
161
|
+
.string()
|
|
162
|
+
.transform((v) => {
|
|
163
|
+
const match = valuesArr.find((val) => typeof val === "string" && val.toLowerCase() === v.toLowerCase())
|
|
164
|
+
return (match ?? v) as string
|
|
165
|
+
})
|
|
166
|
+
.pipe(valueSchema as ZodType<any, any>)
|
|
167
|
+
}
|
|
144
168
|
|
|
145
|
-
|
|
169
|
+
// User transform (applied after validation)
|
|
170
|
+
if (transform) {
|
|
171
|
+
valueSchema = valueSchema.transform((v) => transform(v as V[number]))
|
|
146
172
|
}
|
|
147
173
|
|
|
148
|
-
|
|
174
|
+
// Handle required vs optional
|
|
175
|
+
const fallback = defaultValue as V[number] | null
|
|
176
|
+
const emptySchema = z
|
|
177
|
+
.union([z.literal("" as const), z.null(), z.undefined()])
|
|
178
|
+
.transform(() => fallback)
|
|
149
179
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
return
|
|
157
|
-
}
|
|
180
|
+
if (isRequired && fallback === null) {
|
|
181
|
+
// Required, no default: empty values should fail with "required" message
|
|
182
|
+
const emptyRejectSchema = z
|
|
183
|
+
.union([z.literal("" as const), z.null(), z.undefined()])
|
|
184
|
+
.refine(() => false, { message: getMessage("required") })
|
|
158
185
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
186
|
+
// For numeric values from forms (string "3" → number 3)
|
|
187
|
+
if (!isAllStrings) {
|
|
188
|
+
const numCoerceSchema = z
|
|
189
|
+
.string()
|
|
190
|
+
.transform((v) => {
|
|
191
|
+
const n = Number(v)
|
|
192
|
+
return isNaN(n) ? v : n
|
|
163
193
|
})
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
194
|
+
.pipe(valueSchema as ZodType<any, any>)
|
|
195
|
+
return z.union([valueSchema, numCoerceSchema, emptyRejectSchema]) as unknown as OneOfSchema<IsRequired, V>
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return z.union([valueSchema, emptyRejectSchema]) as unknown as OneOfSchema<IsRequired, V>
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Required with default or optional: empty values → fallback
|
|
202
|
+
if (!isAllStrings) {
|
|
203
|
+
const numCoerceSchema = z
|
|
204
|
+
.string()
|
|
205
|
+
.transform((v) => {
|
|
206
|
+
const n = Number(v)
|
|
207
|
+
return isNaN(n) ? v : n
|
|
208
|
+
})
|
|
209
|
+
.pipe(valueSchema as ZodType<any, any>)
|
|
210
|
+
return z.union([valueSchema, numCoerceSchema, emptySchema]) as unknown as OneOfSchema<IsRequired, V>
|
|
211
|
+
}
|
|
170
212
|
|
|
171
|
-
return
|
|
213
|
+
return z.union([valueSchema, emptySchema]) as unknown as OneOfSchema<IsRequired, V>
|
|
172
214
|
}
|
package/dist/chunk-3ZF5JO3F.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getLocale,
|
|
3
|
-
t
|
|
4
|
-
} from "./chunk-POIDES2L.js";
|
|
5
|
-
|
|
6
|
-
// src/validators/common/one-of.ts
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
function oneOf(required, options) {
|
|
9
|
-
const { values = [], defaultValue = null, caseSensitive = true, transform, i18n } = options ?? {};
|
|
10
|
-
const isRequired = required ?? false;
|
|
11
|
-
const getMessage = (key, params) => {
|
|
12
|
-
if (i18n) {
|
|
13
|
-
const currentLocale = getLocale();
|
|
14
|
-
const customMessages = i18n[currentLocale];
|
|
15
|
-
if (customMessages && customMessages[key]) {
|
|
16
|
-
const template = customMessages[key];
|
|
17
|
-
return template.replace(/\$\{(\w+)}/g, (_, k) => params?.[k] ?? "");
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return t(`common.oneOf.${key}`, params);
|
|
21
|
-
};
|
|
22
|
-
const preprocessFn = (val) => {
|
|
23
|
-
if (val === "" || val === null || val === void 0) {
|
|
24
|
-
return defaultValue;
|
|
25
|
-
}
|
|
26
|
-
const hasNumbers = values.some((v) => typeof v === "number");
|
|
27
|
-
if (hasNumbers && typeof val === "string" && !isNaN(Number(val)) && val.trim() !== "") {
|
|
28
|
-
const numVal = Number(val);
|
|
29
|
-
if (values.includes(numVal)) return numVal;
|
|
30
|
-
}
|
|
31
|
-
if (!caseSensitive && typeof val === "string") {
|
|
32
|
-
const match = values.find((v) => typeof v === "string" && v.toLowerCase() === val.toLowerCase());
|
|
33
|
-
if (match !== void 0) return match;
|
|
34
|
-
return val;
|
|
35
|
-
}
|
|
36
|
-
return val;
|
|
37
|
-
};
|
|
38
|
-
const baseSchema = z.preprocess(preprocessFn, z.any());
|
|
39
|
-
const schema = baseSchema.superRefine((val, ctx) => {
|
|
40
|
-
if (val === null) {
|
|
41
|
-
if (isRequired) {
|
|
42
|
-
ctx.addIssue({ code: "custom", message: getMessage("required") });
|
|
43
|
-
}
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
if (!values.includes(val)) {
|
|
47
|
-
ctx.addIssue({
|
|
48
|
-
code: "custom",
|
|
49
|
-
message: getMessage("invalid", { values: values.join(", ") })
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}).transform((val) => {
|
|
53
|
-
if (val === null || !transform) return val;
|
|
54
|
-
return transform(val);
|
|
55
|
-
});
|
|
56
|
-
return schema;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export {
|
|
60
|
-
oneOf
|
|
61
|
-
};
|
package/dist/chunk-FMPHW7ID.cjs
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var _chunkQ7TUNJD4cjs = require('./chunk-Q7TUNJD4.cjs');
|
|
5
|
-
|
|
6
|
-
// src/validators/common/one-of.ts
|
|
7
|
-
var _zod = require('zod');
|
|
8
|
-
function oneOf(required, options) {
|
|
9
|
-
const { values = [], defaultValue = null, caseSensitive = true, transform, i18n } = _nullishCoalesce(options, () => ( {}));
|
|
10
|
-
const isRequired = _nullishCoalesce(required, () => ( false));
|
|
11
|
-
const getMessage = (key, params) => {
|
|
12
|
-
if (i18n) {
|
|
13
|
-
const currentLocale = _chunkQ7TUNJD4cjs.getLocale.call(void 0, );
|
|
14
|
-
const customMessages = i18n[currentLocale];
|
|
15
|
-
if (customMessages && customMessages[key]) {
|
|
16
|
-
const template = customMessages[key];
|
|
17
|
-
return template.replace(/\$\{(\w+)}/g, (_, k) => _nullishCoalesce(_optionalChain([params, 'optionalAccess', _2 => _2[k]]), () => ( "")));
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return _chunkQ7TUNJD4cjs.t.call(void 0, `common.oneOf.${key}`, params);
|
|
21
|
-
};
|
|
22
|
-
const preprocessFn = (val) => {
|
|
23
|
-
if (val === "" || val === null || val === void 0) {
|
|
24
|
-
return defaultValue;
|
|
25
|
-
}
|
|
26
|
-
const hasNumbers = values.some((v) => typeof v === "number");
|
|
27
|
-
if (hasNumbers && typeof val === "string" && !isNaN(Number(val)) && val.trim() !== "") {
|
|
28
|
-
const numVal = Number(val);
|
|
29
|
-
if (values.includes(numVal)) return numVal;
|
|
30
|
-
}
|
|
31
|
-
if (!caseSensitive && typeof val === "string") {
|
|
32
|
-
const match = values.find((v) => typeof v === "string" && v.toLowerCase() === val.toLowerCase());
|
|
33
|
-
if (match !== void 0) return match;
|
|
34
|
-
return val;
|
|
35
|
-
}
|
|
36
|
-
return val;
|
|
37
|
-
};
|
|
38
|
-
const baseSchema = _zod.z.preprocess(preprocessFn, _zod.z.any());
|
|
39
|
-
const schema = baseSchema.superRefine((val, ctx) => {
|
|
40
|
-
if (val === null) {
|
|
41
|
-
if (isRequired) {
|
|
42
|
-
ctx.addIssue({ code: "custom", message: getMessage("required") });
|
|
43
|
-
}
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
if (!values.includes(val)) {
|
|
47
|
-
ctx.addIssue({
|
|
48
|
-
code: "custom",
|
|
49
|
-
message: getMessage("invalid", { values: values.join(", ") })
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}).transform((val) => {
|
|
53
|
-
if (val === null || !transform) return val;
|
|
54
|
-
return transform(val);
|
|
55
|
-
});
|
|
56
|
-
return schema;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
exports.oneOf = oneOf;
|