@moluoxixi/zod3-to-rule 0.1.1

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/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # Zod 3 to Rule
2
+
3
+ `@moluoxixi/zod3-to-rule` 提供可序列化校验规则与 Zod 3 之间的桥接,不依赖 Vue 或任何表单 UI。
4
+
5
+ 规则 JSON 是稳定协议。外部输入先通过 `parseRuleSet()` 严格解析,再使用 `compileRules()` 编译为 Zod schema、required 元数据和跨字段/custom validator。`rulesToZod()` 只编译单字段 Zod 能力。
6
+
7
+ ```ts
8
+ import { compileRules, parseRuleSet } from '@moluoxixi/zod3-to-rule'
9
+
10
+ const parsed = parseRuleSet({
11
+ version: 1,
12
+ base: { type: 'string' },
13
+ rules: [
14
+ { kind: 'required', message: '请输入邮箱' },
15
+ { kind: 'email', message: '邮箱格式不正确' },
16
+ ],
17
+ })
18
+
19
+ if (parsed.success) {
20
+ const compiled = compileRules(parsed.data)
21
+ compiled.schema.safeParse('user@example.com')
22
+ }
23
+ ```
24
+
25
+ 支持的基础类型包括 string、number、boolean、date、enum 和 JSON primitive literal。内置规则覆盖字符串长度、regex、email、URL、UUID、数值范围、integer、finite、multipleOf、日期范围、required、基础跨字段比较和命名 custom validator。
26
+
27
+ `zodToRules()` 是受限的最佳努力导出器。它支持上述基础类型和 Zod 3 内置 checks,并返回结构化 diagnostics。`refine`、`superRefine`、transform、preprocess、coerce、default 和其他无法由规则 JSON 等价表达的行为不会被静默丢弃;存在不可恢复的 effects 或 coercion 时不会返回 `ruleSet`。
@@ -0,0 +1,8 @@
1
+ export * from './src/constants';
2
+ export * from './src/diagnostics';
3
+ export * from './src/from-zod';
4
+ export * from './src/parse';
5
+ export * from './src/rules';
6
+ export * from './src/to-zod';
7
+ export type * from './src/types';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,mBAAmB,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,421 @@
1
+ import { z as t } from "zod";
2
+ const _ = 1;
3
+ function o(n, e, r = [], s = "error", i) {
4
+ return { code: n, severity: s, path: r, message: e, ...i === void 0 ? {} : { ruleIndex: i } };
5
+ }
6
+ function M(n) {
7
+ return n.map((e) => o(
8
+ "RULE_DOCUMENT_INVALID",
9
+ e.message,
10
+ e.path
11
+ ));
12
+ }
13
+ class l extends Error {
14
+ constructor(e) {
15
+ super(e.map((r) => r.message).join("; ")), this.diagnostics = e, this.name = "RuleCompileError";
16
+ }
17
+ }
18
+ function R(n) {
19
+ return typeof n.message == "string" ? n.message : void 0;
20
+ }
21
+ function d(n, e) {
22
+ const r = R(e);
23
+ return r ? { ...n, message: r } : n;
24
+ }
25
+ function p(n, e = []) {
26
+ return o("ZOD_UNSUPPORTED", n, e, "warning");
27
+ }
28
+ function Z(n) {
29
+ let e = n, r = !1, s = !1;
30
+ const i = [];
31
+ for (; ; ) {
32
+ if (e instanceof t.ZodOptional) {
33
+ r = !0, e = e.unwrap();
34
+ continue;
35
+ }
36
+ if (e instanceof t.ZodNullable) {
37
+ s = !0, e = e.unwrap();
38
+ continue;
39
+ }
40
+ if (e instanceof t.ZodDefault) {
41
+ i.push(p("Zod default values are not part of the rule format")), e = e.removeDefault();
42
+ continue;
43
+ }
44
+ if (e instanceof t.ZodEffects)
45
+ return i.push(p("Zod effects/refine/transform cannot be represented as rules")), { schema: e, optional: r, nullable: s, unsupported: !0, diagnostics: i };
46
+ break;
47
+ }
48
+ return { schema: e, optional: r, nullable: s, unsupported: !1, diagnostics: i };
49
+ }
50
+ function S(n) {
51
+ const e = [], r = [], s = n._def.checks;
52
+ for (const i of s) {
53
+ const a = i.kind;
54
+ switch (a) {
55
+ case "min":
56
+ e.push(d({ kind: "minLength", value: i.value }, i));
57
+ break;
58
+ case "max":
59
+ e.push(d({ kind: "maxLength", value: i.value }, i));
60
+ break;
61
+ case "length":
62
+ e.push(d({ kind: "length", value: i.value }, i));
63
+ break;
64
+ case "email":
65
+ e.push(d({ kind: "email" }, i));
66
+ break;
67
+ case "url":
68
+ e.push(d({ kind: "url" }, i));
69
+ break;
70
+ case "uuid":
71
+ e.push(d({ kind: "uuid" }, i));
72
+ break;
73
+ case "regex": {
74
+ const f = i.regex;
75
+ f instanceof RegExp ? e.push(d({ kind: "regex", source: f.source, flags: f.flags }, i)) : r.push(p("Zod regex check does not contain a RegExp"));
76
+ break;
77
+ }
78
+ default:
79
+ r.push(p(`Zod string check is not supported: ${String(a)}`));
80
+ }
81
+ }
82
+ return { rules: e, diagnostics: r };
83
+ }
84
+ function L(n) {
85
+ const e = [], r = [], s = n._def.checks;
86
+ for (const i of s) {
87
+ const a = i.kind;
88
+ switch (a) {
89
+ case "min":
90
+ e.push(d({ kind: "min", value: i.value, inclusive: i.inclusive }, i));
91
+ break;
92
+ case "max":
93
+ e.push(d({ kind: "max", value: i.value, inclusive: i.inclusive }, i));
94
+ break;
95
+ case "int":
96
+ e.push(d({ kind: "integer" }, i));
97
+ break;
98
+ case "finite":
99
+ e.push(d({ kind: "finite" }, i));
100
+ break;
101
+ case "multipleOf":
102
+ e.push(d({ kind: "multipleOf", value: i.value }, i));
103
+ break;
104
+ default:
105
+ r.push(p(`Zod number check is not supported: ${String(a)}`));
106
+ }
107
+ }
108
+ return { rules: e, diagnostics: r };
109
+ }
110
+ function N(n) {
111
+ const e = [], r = [], s = n._def.checks;
112
+ for (const i of s) {
113
+ const a = new Date(i.value);
114
+ if (Number.isNaN(a.getTime())) {
115
+ r.push(p("Zod date check does not contain a valid date value"));
116
+ continue;
117
+ }
118
+ i.kind === "min" ? e.push(d({ kind: "dateMin", value: a.toISOString() }, i)) : e.push(d({ kind: "dateMax", value: a.toISOString() }, i));
119
+ }
120
+ return { rules: e, diagnostics: r };
121
+ }
122
+ function x(n) {
123
+ const e = Z(n), r = [...e.diagnostics];
124
+ if (e.unsupported)
125
+ return { diagnostics: r };
126
+ if ((e.schema instanceof t.ZodString || e.schema instanceof t.ZodNumber || e.schema instanceof t.ZodBoolean || e.schema instanceof t.ZodDate) && e.schema._def.coerce)
127
+ return r.push(p("Zod coercion cannot be represented as rules")), { diagnostics: r };
128
+ let s, i = [];
129
+ if (e.schema instanceof t.ZodString) {
130
+ s = { type: "string" };
131
+ const a = S(e.schema);
132
+ i = a.rules, r.push(...a.diagnostics);
133
+ } else if (e.schema instanceof t.ZodNumber) {
134
+ s = { type: "number" };
135
+ const a = L(e.schema);
136
+ i = a.rules, r.push(...a.diagnostics);
137
+ } else if (e.schema instanceof t.ZodBoolean)
138
+ s = { type: "boolean" };
139
+ else if (e.schema instanceof t.ZodDate) {
140
+ s = { type: "date" };
141
+ const a = N(e.schema);
142
+ i = a.rules, r.push(...a.diagnostics);
143
+ } else if (e.schema instanceof t.ZodEnum)
144
+ s = { type: "enum", values: e.schema.options };
145
+ else if (e.schema instanceof t.ZodLiteral) {
146
+ const a = e.schema.value;
147
+ if (typeof a != "string" && typeof a != "number" && typeof a != "boolean" && a !== null)
148
+ return r.push(p("Zod literal value is not JSON-safe")), { diagnostics: r };
149
+ s = { type: "literal", value: a };
150
+ } else {
151
+ const a = e.schema._def;
152
+ return r.push(p(`Zod schema type is not supported: ${String(a.typeName ?? "unknown")}`)), { diagnostics: r };
153
+ }
154
+ return {
155
+ ruleSet: {
156
+ version: _,
157
+ base: s,
158
+ rules: i,
159
+ ...e.optional ? { optional: !0 } : {},
160
+ ...e.nullable ? { nullable: !0 } : {}
161
+ },
162
+ diagnostics: r
163
+ };
164
+ }
165
+ const T = t.union([t.string(), t.number().finite(), t.boolean(), t.null()]), E = t.lazy(() => t.union([
166
+ T,
167
+ t.array(E),
168
+ t.record(t.string(), E)
169
+ ])), u = t.object({ message: t.string().min(1).optional() }).strict(), j = t.discriminatedUnion("type", [
170
+ t.object({ type: t.literal("string") }).strict(),
171
+ t.object({ type: t.literal("number") }).strict(),
172
+ t.object({ type: t.literal("boolean") }).strict(),
173
+ t.object({ type: t.literal("date") }).strict(),
174
+ t.object({ type: t.literal("enum"), values: t.array(t.string()).min(1) }).strict(),
175
+ t.object({ type: t.literal("literal"), value: T }).strict()
176
+ ]), q = t.discriminatedUnion("kind", [
177
+ t.object({ kind: t.literal("required") }).merge(u),
178
+ t.object({ kind: t.literal("minLength"), value: t.number().int().nonnegative() }).merge(u),
179
+ t.object({ kind: t.literal("maxLength"), value: t.number().int().nonnegative() }).merge(u),
180
+ t.object({ kind: t.literal("length"), value: t.number().int().nonnegative() }).merge(u),
181
+ t.object({ kind: t.literal("regex"), source: t.string().min(1), flags: t.string().optional() }).merge(u),
182
+ t.object({ kind: t.literal("email") }).merge(u),
183
+ t.object({ kind: t.literal("url") }).merge(u),
184
+ t.object({ kind: t.literal("uuid") }).merge(u),
185
+ t.object({ kind: t.literal("min"), value: t.number().finite(), inclusive: t.boolean().optional() }).merge(u),
186
+ t.object({ kind: t.literal("max"), value: t.number().finite(), inclusive: t.boolean().optional() }).merge(u),
187
+ t.object({ kind: t.literal("integer") }).merge(u),
188
+ t.object({ kind: t.literal("finite") }).merge(u),
189
+ t.object({ kind: t.literal("multipleOf"), value: t.number().finite().positive() }).merge(u),
190
+ t.object({ kind: t.literal("dateMin"), value: t.string().datetime() }).merge(u),
191
+ t.object({ kind: t.literal("dateMax"), value: t.string().datetime() }).merge(u),
192
+ t.object({
193
+ kind: t.literal("compare"),
194
+ field: t.string().min(1),
195
+ operator: t.enum(["eq", "neq", "gt", "gte", "lt", "lte"])
196
+ }).merge(u),
197
+ t.object({ kind: t.literal("custom"), key: t.string().min(1), params: E.optional() }).merge(u)
198
+ ]).superRefine((n, e) => {
199
+ if (n.kind === "regex")
200
+ try {
201
+ const r = new RegExp(n.source, n.flags);
202
+ } catch (r) {
203
+ e.addIssue({
204
+ code: t.ZodIssueCode.custom,
205
+ message: r instanceof Error ? r.message : "Invalid regular expression",
206
+ path: ["source"]
207
+ });
208
+ }
209
+ }), U = t.object({
210
+ version: t.literal(_),
211
+ base: j,
212
+ rules: t.array(q),
213
+ optional: t.boolean().optional(),
214
+ nullable: t.boolean().optional()
215
+ }).strict();
216
+ function V(n) {
217
+ const e = U.safeParse(n);
218
+ return e.success ? {
219
+ success: !0,
220
+ data: e.data,
221
+ diagnostics: []
222
+ } : { success: !1, diagnostics: M(e.error.issues) };
223
+ }
224
+ function c(n) {
225
+ return n.message ? { message: n.message } : {};
226
+ }
227
+ function A(n) {
228
+ switch (n.base.type) {
229
+ case "string":
230
+ return t.string();
231
+ case "number":
232
+ return t.number();
233
+ case "boolean":
234
+ return t.boolean();
235
+ case "date":
236
+ return t.date();
237
+ case "enum":
238
+ return t.enum(n.base.values);
239
+ case "literal":
240
+ return t.literal(n.base.value);
241
+ }
242
+ }
243
+ function C(n, e) {
244
+ try {
245
+ return new RegExp(n.source, n.flags);
246
+ } catch (r) {
247
+ throw new l([o(
248
+ "RULE_REGEX_INVALID",
249
+ r instanceof Error ? r.message : "Invalid regular expression",
250
+ ["rules", e],
251
+ "error",
252
+ e
253
+ )]);
254
+ }
255
+ }
256
+ function w(n, e, r) {
257
+ const s = new Date(n);
258
+ if (!Number.isNaN(s.getTime()))
259
+ return s;
260
+ throw new l([o(
261
+ "RULE_DATE_INVALID",
262
+ `${r} requires a valid ISO date`,
263
+ ["rules", e],
264
+ "error",
265
+ e
266
+ )]);
267
+ }
268
+ function D(n, e, r) {
269
+ switch (e.kind) {
270
+ case "required":
271
+ return n;
272
+ case "minLength":
273
+ if (!(n instanceof t.ZodString))
274
+ throw new l([o("RULE_TYPE_MISMATCH", "minLength requires a string base", ["rules", r], "error", r)]);
275
+ return n.min(e.value, c(e));
276
+ case "maxLength":
277
+ if (!(n instanceof t.ZodString))
278
+ throw new l([o("RULE_TYPE_MISMATCH", "maxLength requires a string base", ["rules", r], "error", r)]);
279
+ return n.max(e.value, c(e));
280
+ case "length":
281
+ if (!(n instanceof t.ZodString))
282
+ throw new l([o("RULE_TYPE_MISMATCH", "length requires a string base", ["rules", r], "error", r)]);
283
+ return n.length(e.value, c(e));
284
+ case "regex":
285
+ if (!(n instanceof t.ZodString))
286
+ throw new l([o("RULE_TYPE_MISMATCH", "regex requires a string base", ["rules", r], "error", r)]);
287
+ return n.regex(C(e, r), c(e));
288
+ case "email":
289
+ if (!(n instanceof t.ZodString))
290
+ throw new l([o("RULE_TYPE_MISMATCH", "email requires a string base", ["rules", r], "error", r)]);
291
+ return n.email(c(e));
292
+ case "url":
293
+ if (!(n instanceof t.ZodString))
294
+ throw new l([o("RULE_TYPE_MISMATCH", "url requires a string base", ["rules", r], "error", r)]);
295
+ return n.url(c(e));
296
+ case "uuid":
297
+ if (!(n instanceof t.ZodString))
298
+ throw new l([o("RULE_TYPE_MISMATCH", "uuid requires a string base", ["rules", r], "error", r)]);
299
+ return n.uuid(c(e));
300
+ case "min":
301
+ if (n instanceof t.ZodNumber)
302
+ return e.inclusive === !1 ? n.gt(e.value, c(e)) : n.gte(e.value, c(e));
303
+ throw new l([o("RULE_TYPE_MISMATCH", "min requires a number base", ["rules", r], "error", r)]);
304
+ case "max":
305
+ if (n instanceof t.ZodNumber)
306
+ return e.inclusive === !1 ? n.lt(e.value, c(e)) : n.lte(e.value, c(e));
307
+ throw new l([o("RULE_TYPE_MISMATCH", "max requires a number base", ["rules", r], "error", r)]);
308
+ case "integer":
309
+ if (n instanceof t.ZodNumber)
310
+ return n.int(c(e));
311
+ throw new l([o("RULE_TYPE_MISMATCH", "integer requires a number base", ["rules", r], "error", r)]);
312
+ case "finite":
313
+ if (n instanceof t.ZodNumber)
314
+ return n.finite(c(e));
315
+ throw new l([o("RULE_TYPE_MISMATCH", "finite requires a number base", ["rules", r], "error", r)]);
316
+ case "multipleOf":
317
+ if (n instanceof t.ZodNumber)
318
+ return n.multipleOf(e.value, c(e));
319
+ throw new l([o("RULE_TYPE_MISMATCH", "multipleOf requires a number base", ["rules", r], "error", r)]);
320
+ case "dateMin":
321
+ if (!(n instanceof t.ZodDate))
322
+ throw new l([o("RULE_TYPE_MISMATCH", "dateMin requires a date base", ["rules", r], "error", r)]);
323
+ return n.min(w(e.value, r, e.kind), c(e));
324
+ case "dateMax":
325
+ if (!(n instanceof t.ZodDate))
326
+ throw new l([o("RULE_TYPE_MISMATCH", "dateMax requires a date base", ["rules", r], "error", r)]);
327
+ return n.max(w(e.value, r, e.kind), c(e));
328
+ case "compare":
329
+ case "custom":
330
+ return n;
331
+ }
332
+ }
333
+ function O(n) {
334
+ let e = A(n), r;
335
+ for (const [s, i] of n.rules.entries())
336
+ e = D(e, i, s), i.kind === "required" && (r = i);
337
+ return n.base.type === "date" && (e = t.preprocess((s) => typeof s == "string" ? new Date(s) : s, e)), n.nullable && (e = e.nullable()), n.optional && (e = e.optional()), r && (e = e.refine((s) => s != null && (typeof s != "string" || s.trim().length > 0), c(r))), e;
338
+ }
339
+ function P(n) {
340
+ return n ? Array.isArray(n) ? n.filter(Boolean) : [n] : [];
341
+ }
342
+ function H(n, e, r, s) {
343
+ const i = (g) => {
344
+ if (g instanceof Date)
345
+ return Number.isNaN(g.getTime()) ? void 0 : { kind: "date", value: g.getTime() };
346
+ if (s === "date" && typeof g == "string") {
347
+ const h = new Date(g);
348
+ return Number.isNaN(h.getTime()) ? void 0 : { kind: "date", value: h.getTime() };
349
+ }
350
+ if (typeof g == "number" || typeof g == "string")
351
+ return { kind: typeof g == "number" ? "number" : "string", value: g };
352
+ }, a = i(n), f = i(e);
353
+ if (!a || !f || a.kind !== f.kind)
354
+ return !1;
355
+ switch (r) {
356
+ case "eq":
357
+ return Object.is(a.value, f.value);
358
+ case "neq":
359
+ return !Object.is(a.value, f.value);
360
+ case "gt":
361
+ return a.value > f.value;
362
+ case "gte":
363
+ return a.value >= f.value;
364
+ case "lt":
365
+ return a.value < f.value;
366
+ case "lte":
367
+ return a.value <= f.value;
368
+ }
369
+ }
370
+ function $(n, e = {}) {
371
+ var h;
372
+ const r = [], s = [];
373
+ let i, a;
374
+ for (const [k, m] of n.rules.entries()) {
375
+ if (m.kind === "required") {
376
+ i = !0, a = m.message;
377
+ continue;
378
+ }
379
+ if (m.kind === "compare") {
380
+ s.push((b, v) => H(b, v[m.field], m.operator, n.base.type) ? void 0 : m.message ?? `字段 ${m.field} 比较失败`);
381
+ continue;
382
+ }
383
+ if (m.kind === "custom") {
384
+ const b = (h = e.custom) == null ? void 0 : h[m.key];
385
+ if (!b) {
386
+ r.push(o(
387
+ "RULE_CUSTOM_VALIDATOR_MISSING",
388
+ `Custom validator not registered: ${m.key}`,
389
+ ["rules", k],
390
+ "error",
391
+ k
392
+ ));
393
+ continue;
394
+ }
395
+ s.push((v, y) => b(v, y, m.params));
396
+ }
397
+ }
398
+ n.optional && i && r.push(o(
399
+ "RULE_OPTIONAL_REQUIRED_CONFLICT",
400
+ "A rule set cannot be both optional and required",
401
+ ["optional"]
402
+ ));
403
+ const f = O(n), g = s.length === 0 ? void 0 : async (k, m) => {
404
+ const b = [];
405
+ for (const v of s)
406
+ b.push(...P(await v(k, m)));
407
+ return b;
408
+ };
409
+ return { schema: f, required: i, requiredMessage: a, validator: g, diagnostics: r };
410
+ }
411
+ export {
412
+ _ as RULE_SET_VERSION,
413
+ l as RuleCompileError,
414
+ $ as compileRules,
415
+ M as formatRuleZodIssues,
416
+ V as parseRuleSet,
417
+ o as ruleDiagnostic,
418
+ U as ruleSetSchema,
419
+ O as rulesToZod,
420
+ x as zodToRules
421
+ };
@@ -0,0 +1,2 @@
1
+ export declare const RULE_SET_VERSION: 1;
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAG,CAAU,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { ZodIssue } from 'zod';
2
+ import { RuleDiagnostic, RuleDiagnosticSeverity } from './types';
3
+ export declare function ruleDiagnostic(code: string, message: string, path?: (string | number)[], severity?: RuleDiagnosticSeverity, ruleIndex?: number): RuleDiagnostic;
4
+ export declare function formatRuleZodIssues(issues: ZodIssue[]): RuleDiagnostic[];
5
+ export declare class RuleCompileError extends Error {
6
+ readonly diagnostics: RuleDiagnostic[];
7
+ constructor(diagnostics: RuleDiagnostic[]);
8
+ }
9
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAErE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAO,EAC9B,QAAQ,GAAE,sBAAgC,EAC1C,SAAS,CAAC,EAAE,MAAM,GACjB,cAAc,CAEhB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,cAAc,EAAE,CAMxE;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aACb,WAAW,EAAE,cAAc,EAAE;gBAA7B,WAAW,EAAE,cAAc,EAAE;CAI1D"}
@@ -0,0 +1,4 @@
1
+ import { ZodToRulesResult } from './types';
2
+ import { z } from 'zod';
3
+ export declare function zodToRules(schema: z.ZodTypeAny): ZodToRulesResult;
4
+ //# sourceMappingURL=from-zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-zod.d.ts","sourceRoot":"","sources":["../../src/from-zod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2B,gBAAgB,EAAE,MAAM,SAAS,CAAA;AACxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA8IvB,wBAAgB,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,GAAG,gBAAgB,CAqEjE"}
@@ -0,0 +1,6 @@
1
+ import { RuleParseResult, RuleSet } from './types';
2
+ import { z } from 'zod';
3
+ declare const ruleSetSchema: z.ZodType<RuleSet>;
4
+ export declare function parseRuleSet(input: unknown): RuleParseResult;
5
+ export { ruleSetSchema };
6
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,eAAe,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA4DvB,QAAA,MAAM,aAAa,EAMO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;AAE5C,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAU5D;AAED,OAAO,EAAE,aAAa,EAAE,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { CompiledRuleSet, RuleCompileContext, RuleSet } from './types';
2
+ export declare function compileRules(ruleSet: RuleSet, context?: RuleCompileContext): CompiledRuleSet;
3
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAEf,kBAAkB,EAElB,OAAO,EAER,MAAM,SAAS,CAAA;AA4ChB,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,kBAAuB,GAC/B,eAAe,CAuDjB"}
@@ -0,0 +1,4 @@
1
+ import { RuleSet } from './types';
2
+ import { z } from 'zod';
3
+ export declare function rulesToZod(ruleSet: RuleSet): z.ZodTypeAny;
4
+ //# sourceMappingURL=to-zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-zod.d.ts","sourceRoot":"","sources":["../../src/to-zod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,OAAO,EAAE,MAAM,SAAS,CAAA;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA6HvB,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,CAAC,UAAU,CA+BzD"}
@@ -0,0 +1,132 @@
1
+ import { RULE_SET_VERSION } from './constants';
2
+ export type RulePrimitive = string | number | boolean | null;
3
+ export type RuleJsonValue = RulePrimitive | RuleJsonValue[] | {
4
+ [key: string]: RuleJsonValue;
5
+ };
6
+ export type RuleBase = {
7
+ type: 'string';
8
+ } | {
9
+ type: 'number';
10
+ } | {
11
+ type: 'boolean';
12
+ } | {
13
+ type: 'date';
14
+ } | {
15
+ type: 'enum';
16
+ values: [string, ...string[]];
17
+ } | {
18
+ type: 'literal';
19
+ value: RulePrimitive;
20
+ };
21
+ export type RuleDescriptor = {
22
+ kind: 'required';
23
+ message?: string;
24
+ } | {
25
+ kind: 'minLength';
26
+ value: number;
27
+ message?: string;
28
+ } | {
29
+ kind: 'maxLength';
30
+ value: number;
31
+ message?: string;
32
+ } | {
33
+ kind: 'length';
34
+ value: number;
35
+ message?: string;
36
+ } | {
37
+ kind: 'regex';
38
+ source: string;
39
+ flags?: string;
40
+ message?: string;
41
+ } | {
42
+ kind: 'email';
43
+ message?: string;
44
+ } | {
45
+ kind: 'url';
46
+ message?: string;
47
+ } | {
48
+ kind: 'uuid';
49
+ message?: string;
50
+ } | {
51
+ kind: 'min';
52
+ value: number;
53
+ inclusive?: boolean;
54
+ message?: string;
55
+ } | {
56
+ kind: 'max';
57
+ value: number;
58
+ inclusive?: boolean;
59
+ message?: string;
60
+ } | {
61
+ kind: 'integer';
62
+ message?: string;
63
+ } | {
64
+ kind: 'finite';
65
+ message?: string;
66
+ } | {
67
+ kind: 'multipleOf';
68
+ value: number;
69
+ message?: string;
70
+ } | {
71
+ kind: 'dateMin';
72
+ value: string;
73
+ message?: string;
74
+ } | {
75
+ kind: 'dateMax';
76
+ value: string;
77
+ message?: string;
78
+ } | {
79
+ kind: 'compare';
80
+ field: string;
81
+ operator: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte';
82
+ message?: string;
83
+ } | {
84
+ kind: 'custom';
85
+ key: string;
86
+ params?: RuleJsonValue;
87
+ message?: string;
88
+ };
89
+ export interface RuleSet {
90
+ version: typeof RULE_SET_VERSION;
91
+ base: RuleBase;
92
+ rules: RuleDescriptor[];
93
+ optional?: boolean;
94
+ nullable?: boolean;
95
+ }
96
+ export type RuleDiagnosticSeverity = 'error' | 'warning';
97
+ export interface RuleDiagnostic {
98
+ code: string;
99
+ severity: RuleDiagnosticSeverity;
100
+ path: (string | number)[];
101
+ message: string;
102
+ ruleIndex?: number;
103
+ }
104
+ export type RuleValidationResult = string | string[] | void | null | undefined;
105
+ export type RuleValidator = (value: unknown, values: Record<string, unknown>) => RuleValidationResult | Promise<RuleValidationResult>;
106
+ export type RuleCustomValidator = (value: unknown, values: Record<string, unknown>, params: RuleJsonValue | undefined) => RuleValidationResult | Promise<RuleValidationResult>;
107
+ export interface RuleCompileContext {
108
+ custom?: Record<string, RuleCustomValidator>;
109
+ }
110
+ export interface CompiledRuleSet {
111
+ schema: import('zod').ZodTypeAny;
112
+ required?: boolean;
113
+ requiredMessage?: string;
114
+ validator?: RuleValidator;
115
+ diagnostics: RuleDiagnostic[];
116
+ }
117
+ export interface RuleParseSuccess {
118
+ success: true;
119
+ data: RuleSet;
120
+ diagnostics: [];
121
+ }
122
+ export interface RuleParseFailure {
123
+ success: false;
124
+ data?: undefined;
125
+ diagnostics: RuleDiagnostic[];
126
+ }
127
+ export type RuleParseResult = RuleParseSuccess | RuleParseFailure;
128
+ export interface ZodToRulesResult {
129
+ ruleSet?: RuleSet;
130
+ diagnostics: RuleDiagnostic[];
131
+ }
132
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from './src/constants'
2
+ export * from './src/diagnostics'
3
+ export * from './src/from-zod'
4
+ export * from './src/parse'
5
+ export * from './src/rules'
6
+ export * from './src/to-zod'
7
+ export type * from './src/types'