@oh-my-pi/omptype 18.1.22 → 18.2.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/CHANGELOG.md +6 -0
- package/THIRD-PARTY-NOTICES.txt +54 -25
- package/dist/js/zod.js +118 -8
- package/dist/types/zod.d.ts +13 -1
- package/package.json +1 -1
- package/src/zod.ts +142 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.2.1] - 2026-09-15
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `trim()`, `superRefine()`, and one-argument `record()` support to the Zod compatibility facade ([#12011](https://github.com/can1357/oh-my-pi/pull/12011) by [@bnivanov](https://github.com/bnivanov)).
|
|
10
|
+
|
|
5
11
|
## [17.3.1] - 2026-08-13
|
|
6
12
|
|
|
7
13
|
### Fixed
|
package/THIRD-PARTY-NOTICES.txt
CHANGED
|
@@ -10843,7 +10843,7 @@ RUST RUNTIME DEPENDENCY LICENSES
|
|
|
10843
10843
|
|
|
10844
10844
|
Generated from Cargo.lock by cargo-about 0.8.2 in locked, offline, workspace, all-feature, all-target mode, then restricted using cargo metadata to normal and build edges reachable from the workspace (development-only edges are excluded). cargo-deny independently evaluates the complete all-target graph.
|
|
10845
10845
|
|
|
10846
|
-
Native Opus (
|
|
10846
|
+
Native Opus (opus/opusic-sys) and PCRE2 (pcre2/pcre2-sys) are covered by the exact crate license payloads below. inferno 0.12.8 is package-scoped as CDDL-1.0: its CDDL-covered source remains available in the locked crates.io source archive at https://crates.io/crates/inferno/0.12.8 and https://github.com/jonhoo/inferno. The full locked license text follows below.
|
|
10847
10847
|
|
|
10848
10848
|
-------------------------------------------------------------------------------
|
|
10849
10849
|
License: Apache License 2.0 (Apache-2.0)
|
|
@@ -12509,6 +12509,58 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
12509
12509
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
12510
12510
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
12511
12511
|
|
|
12512
|
+
-------------------------------------------------------------------------------
|
|
12513
|
+
License: BSD 3-Clause "New" or "Revised" License (BSD-3-Clause)
|
|
12514
|
+
Used by:
|
|
12515
|
+
- opusic-sys 0.7.5 (https://github.com/DoumanAsh/opusic-sys)
|
|
12516
|
+
|
|
12517
|
+
Full license text:
|
|
12518
|
+
|
|
12519
|
+
Copyright 2001-2023 Xiph.Org, Skype Limited, Octasic,
|
|
12520
|
+
Jean-Marc Valin, Timothy B. Terriberry,
|
|
12521
|
+
CSIRO, Gregory Maxwell, Mark Borgerding,
|
|
12522
|
+
Erik de Castro Lopo, Mozilla, Amazon
|
|
12523
|
+
|
|
12524
|
+
Redistribution and use in source and binary forms, with or without
|
|
12525
|
+
modification, are permitted provided that the following conditions
|
|
12526
|
+
are met:
|
|
12527
|
+
|
|
12528
|
+
- Redistributions of source code must retain the above copyright
|
|
12529
|
+
notice, this list of conditions and the following disclaimer.
|
|
12530
|
+
|
|
12531
|
+
- Redistributions in binary form must reproduce the above copyright
|
|
12532
|
+
notice, this list of conditions and the following disclaimer in the
|
|
12533
|
+
documentation and/or other materials provided with the distribution.
|
|
12534
|
+
|
|
12535
|
+
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
|
12536
|
+
names of specific contributors, may be used to endorse or promote
|
|
12537
|
+
products derived from this software without specific prior written
|
|
12538
|
+
permission.
|
|
12539
|
+
|
|
12540
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
12541
|
+
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
12542
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
12543
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
|
12544
|
+
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
12545
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
12546
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
12547
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
12548
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
12549
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
12550
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
12551
|
+
|
|
12552
|
+
Opus is subject to the royalty-free patent licenses which are
|
|
12553
|
+
specified at:
|
|
12554
|
+
|
|
12555
|
+
Xiph.Org Foundation:
|
|
12556
|
+
https://datatracker.ietf.org/ipr/1524/
|
|
12557
|
+
|
|
12558
|
+
Microsoft Corporation:
|
|
12559
|
+
https://datatracker.ietf.org/ipr/1914/
|
|
12560
|
+
|
|
12561
|
+
Broadcom Corporation:
|
|
12562
|
+
https://datatracker.ietf.org/ipr/1526/
|
|
12563
|
+
|
|
12512
12564
|
-------------------------------------------------------------------------------
|
|
12513
12565
|
License: BSD 3-Clause "New" or "Revised" License (BSD-3-Clause)
|
|
12514
12566
|
Used by:
|
|
@@ -13290,29 +13342,6 @@ jurisdiction of the Federal Courts of the Northern District of
|
|
|
13290
13342
|
California and the state courts of the State of California, with
|
|
13291
13343
|
venue lying in Santa Clara County, California.
|
|
13292
13344
|
|
|
13293
|
-
-------------------------------------------------------------------------------
|
|
13294
|
-
License: ISC License (ISC)
|
|
13295
|
-
Used by:
|
|
13296
|
-
- audiopus_sys 0.2.2 (https://github.com/lakelezz/audiopus_sys.git)
|
|
13297
|
-
|
|
13298
|
-
Full license text:
|
|
13299
|
-
|
|
13300
|
-
ISC License
|
|
13301
|
-
|
|
13302
|
-
Copyright (c) 2019, Lakelezz
|
|
13303
|
-
|
|
13304
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
13305
|
-
purpose with or without fee is hereby granted, provided that the above
|
|
13306
|
-
copyright notice and this permission notice appear in all copies.
|
|
13307
|
-
|
|
13308
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
13309
|
-
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
13310
|
-
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
13311
|
-
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13312
|
-
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
13313
|
-
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
13314
|
-
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
13315
|
-
|
|
13316
13345
|
-------------------------------------------------------------------------------
|
|
13317
13346
|
License: ISC License (ISC)
|
|
13318
13347
|
Used by:
|
|
@@ -18734,7 +18763,7 @@ DEALINGS IN THE SOFTWARE.
|
|
|
18734
18763
|
-------------------------------------------------------------------------------
|
|
18735
18764
|
License: MIT License (MIT)
|
|
18736
18765
|
Used by:
|
|
18737
|
-
- opus 0.
|
|
18766
|
+
- opus 0.4.0 (https://github.com/SpaceManiac/opus-rs)
|
|
18738
18767
|
|
|
18739
18768
|
Full license text:
|
|
18740
18769
|
|
package/dist/js/zod.js
CHANGED
|
@@ -88,6 +88,25 @@ function decorate(schema, optional = false) {
|
|
|
88
88
|
return next(restrictBase(schema, ir));
|
|
89
89
|
return next(restrictBase(schema, { ...ir, min: bound, xmin: false }));
|
|
90
90
|
}
|
|
91
|
+
if (ir.k === "morph" &&
|
|
92
|
+
!schema.hasSteps &&
|
|
93
|
+
ir.out !== undefined &&
|
|
94
|
+
(ir.out.k === "string" || ir.out.k === "array")) {
|
|
95
|
+
if (!Number.isSafeInteger(bound) || bound < 0)
|
|
96
|
+
throw new OmpTypeError("min length must be a nonnegative safe integer");
|
|
97
|
+
const out = { ...ir.out, min: ir.out.min === undefined ? bound : Math.max(ir.out.min, bound) };
|
|
98
|
+
return next(restrictBase(schema, { ...ir, out }));
|
|
99
|
+
}
|
|
100
|
+
if (ir.k === "morph" && (schema.hasSteps || ir.out === undefined)) {
|
|
101
|
+
if (!Number.isSafeInteger(bound) || bound < 0)
|
|
102
|
+
throw new OmpTypeError("min length must be a nonnegative safe integer");
|
|
103
|
+
return next(schema.narrow((value, ctx) => {
|
|
104
|
+
if (typeof value === "string" || Array.isArray(value)) {
|
|
105
|
+
return value.length >= bound || ctx.mustBe(`at least ${bound} characters`);
|
|
106
|
+
}
|
|
107
|
+
return ctx.mustBe("a string or array");
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
91
110
|
throw new OmpTypeError(`cannot apply min to ${ir.k}`);
|
|
92
111
|
},
|
|
93
112
|
max(bound) {
|
|
@@ -104,6 +123,25 @@ function decorate(schema, optional = false) {
|
|
|
104
123
|
return next(restrictBase(schema, ir));
|
|
105
124
|
return next(restrictBase(schema, { ...ir, max: bound, xmax: false }));
|
|
106
125
|
}
|
|
126
|
+
if (ir.k === "morph" &&
|
|
127
|
+
!schema.hasSteps &&
|
|
128
|
+
ir.out !== undefined &&
|
|
129
|
+
(ir.out.k === "string" || ir.out.k === "array")) {
|
|
130
|
+
if (!Number.isSafeInteger(bound) || bound < 0)
|
|
131
|
+
throw new OmpTypeError("max length must be a nonnegative safe integer");
|
|
132
|
+
const out = { ...ir.out, max: ir.out.max === undefined ? bound : Math.min(ir.out.max, bound) };
|
|
133
|
+
return next(restrictBase(schema, { ...ir, out }));
|
|
134
|
+
}
|
|
135
|
+
if (ir.k === "morph" && (schema.hasSteps || ir.out === undefined)) {
|
|
136
|
+
if (!Number.isSafeInteger(bound) || bound < 0)
|
|
137
|
+
throw new OmpTypeError("max length must be a nonnegative safe integer");
|
|
138
|
+
return next(schema.narrow((value, ctx) => {
|
|
139
|
+
if (typeof value === "string" || Array.isArray(value)) {
|
|
140
|
+
return value.length <= bound || ctx.mustBe(`at most ${bound} characters`);
|
|
141
|
+
}
|
|
142
|
+
return ctx.mustBe("a string or array");
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
107
145
|
throw new OmpTypeError(`cannot apply max to ${ir.k}`);
|
|
108
146
|
},
|
|
109
147
|
int() {
|
|
@@ -125,10 +163,15 @@ function decorate(schema, optional = false) {
|
|
|
125
163
|
return this.min(0);
|
|
126
164
|
},
|
|
127
165
|
regex(expression, message) {
|
|
128
|
-
|
|
129
|
-
|
|
166
|
+
const ir = schema.ir;
|
|
167
|
+
const isStringLike = ir.k === "string" ||
|
|
168
|
+
(ir.k === "morph" && (ir.out?.k === "string" || (ir.out === undefined && ir.input.k === "string")));
|
|
169
|
+
if (!isStringLike)
|
|
170
|
+
throw new OmpTypeError(`cannot apply regex to ${ir.k}`);
|
|
130
171
|
const expectation = message ?? `matching ${expression}`;
|
|
131
172
|
const narrowed = schema.narrow((value, ctx) => {
|
|
173
|
+
if (typeof value !== "string")
|
|
174
|
+
return ctx.mustBe("a string");
|
|
132
175
|
expression.lastIndex = 0;
|
|
133
176
|
const matches = expression.test(value);
|
|
134
177
|
expression.lastIndex = 0;
|
|
@@ -137,9 +180,26 @@ function decorate(schema, optional = false) {
|
|
|
137
180
|
return next(narrowed);
|
|
138
181
|
},
|
|
139
182
|
url() {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
183
|
+
const ir = schema.ir;
|
|
184
|
+
if (ir.k === "string")
|
|
185
|
+
return next(restrictBase(schema, { ...ir, url: true }));
|
|
186
|
+
if (ir.k === "morph" && !schema.hasSteps && ir.out !== undefined && ir.out.k === "string") {
|
|
187
|
+
return next(restrictBase(schema, { ...ir, out: { ...ir.out, url: true } }));
|
|
188
|
+
}
|
|
189
|
+
if (ir.k === "morph" && (schema.hasSteps || ir.out === undefined)) {
|
|
190
|
+
return next(schema.narrow((value, ctx) => {
|
|
191
|
+
if (typeof value !== "string")
|
|
192
|
+
return ctx.mustBe("a string");
|
|
193
|
+
try {
|
|
194
|
+
new URL(value);
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
return ctx.mustBe("a valid URL");
|
|
199
|
+
}
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
202
|
+
throw new OmpTypeError(`cannot apply url to ${ir.k}`);
|
|
143
203
|
},
|
|
144
204
|
optional() {
|
|
145
205
|
const widened = schema.or(type.raw("undefined"));
|
|
@@ -164,6 +224,54 @@ function decorate(schema, optional = false) {
|
|
|
164
224
|
const expectation = refinementMessage(messageOrOptions);
|
|
165
225
|
return next(schema.narrow((value, ctx) => Boolean(predicate(value)) || ctx.mustBe(expectation)));
|
|
166
226
|
},
|
|
227
|
+
superRefine(refinement) {
|
|
228
|
+
return next(schema.narrow((value, ctx) => {
|
|
229
|
+
const proxy = {
|
|
230
|
+
addIssue(issue) {
|
|
231
|
+
ctx.error({
|
|
232
|
+
expected: issue.message,
|
|
233
|
+
path: issue.path ?? [],
|
|
234
|
+
...(issue.actual !== undefined ? { actual: issue.actual } : {}),
|
|
235
|
+
});
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
refinement(value, proxy);
|
|
239
|
+
return true;
|
|
240
|
+
}));
|
|
241
|
+
},
|
|
242
|
+
trim() {
|
|
243
|
+
const ir = schema.ir;
|
|
244
|
+
if (ir.k === "string" && !schema.hasSteps) {
|
|
245
|
+
let trimmed = schemaFromIR({
|
|
246
|
+
k: "morph",
|
|
247
|
+
input: { k: "string" },
|
|
248
|
+
fn: v => v.trim(),
|
|
249
|
+
out: ir,
|
|
250
|
+
});
|
|
251
|
+
if (schema.hasDefault)
|
|
252
|
+
trimmed = trimmed.default(schema.defaultValue);
|
|
253
|
+
return next(trimmed);
|
|
254
|
+
}
|
|
255
|
+
if (ir.k === "morph" || schema.hasSteps) {
|
|
256
|
+
let trimmed = schemaFromIR({
|
|
257
|
+
k: "morph",
|
|
258
|
+
input: { k: "unknown" },
|
|
259
|
+
fn: v => {
|
|
260
|
+
const r = schema(v);
|
|
261
|
+
if (r instanceof type.errors)
|
|
262
|
+
return r;
|
|
263
|
+
if (typeof r !== "string")
|
|
264
|
+
throw new OmpTypeError("trim requires a string output");
|
|
265
|
+
return r.trim();
|
|
266
|
+
},
|
|
267
|
+
out: { k: "string" },
|
|
268
|
+
});
|
|
269
|
+
if (schema.hasDefault)
|
|
270
|
+
trimmed = trimmed.default(schema.defaultValue);
|
|
271
|
+
return next(trimmed);
|
|
272
|
+
}
|
|
273
|
+
throw new OmpTypeError(`cannot apply trim to ${ir.k}`);
|
|
274
|
+
},
|
|
167
275
|
transform(transformer) {
|
|
168
276
|
return decorate(schema.pipe(value => transformer(value)), optional);
|
|
169
277
|
},
|
|
@@ -228,13 +336,15 @@ export { enumSchema as enum };
|
|
|
228
336
|
export const union = (schemas) => decorate(schemaFromIR({ k: "union", members: schemas.map(schema => embed(schema)) }));
|
|
229
337
|
export const array = (element) => decorate(schemaFromIR({ k: "array", el: embed(element) }));
|
|
230
338
|
export const object = (shape) => objectSchema(shape);
|
|
231
|
-
export
|
|
339
|
+
export function record(keyOrValueSchema, valueSchema) {
|
|
340
|
+
const keySchema = (valueSchema === undefined ? string() : keyOrValueSchema);
|
|
341
|
+
const valSchema = (valueSchema === undefined ? keyOrValueSchema : valueSchema);
|
|
232
342
|
if (!isStringKeyIR(keySchema.ir))
|
|
233
343
|
throw new OmpTypeError("record keys must use a string schema");
|
|
234
344
|
const base = schemaFromIR({
|
|
235
345
|
k: "object",
|
|
236
346
|
props: [],
|
|
237
|
-
index: embed(
|
|
347
|
+
index: embed(valSchema),
|
|
238
348
|
extras: "keep",
|
|
239
349
|
});
|
|
240
350
|
const checked = base.narrow((value, ctx) => {
|
|
@@ -245,7 +355,7 @@ export const record = (keySchema, valueSchema) => {
|
|
|
245
355
|
return true;
|
|
246
356
|
});
|
|
247
357
|
return decorate(checked);
|
|
248
|
-
}
|
|
358
|
+
}
|
|
249
359
|
export const unknown = () => decorate(schemaFromIR(type.unknown.ir));
|
|
250
360
|
export const any = () => decorate(schemaFromIR(type.unknown.ir));
|
|
251
361
|
const nullSchema = () => decorate(type.raw("null"));
|
package/dist/types/zod.d.ts
CHANGED
|
@@ -6,6 +6,15 @@ interface RefineOptions {
|
|
|
6
6
|
message?: string;
|
|
7
7
|
error?: string;
|
|
8
8
|
}
|
|
9
|
+
export interface SuperRefineIssue {
|
|
10
|
+
code?: string;
|
|
11
|
+
path?: PropertyKey[];
|
|
12
|
+
message: string;
|
|
13
|
+
actual?: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface SuperRefineContext {
|
|
16
|
+
addIssue(issue: SuperRefineIssue): void;
|
|
17
|
+
}
|
|
9
18
|
export interface ZodLikeIssue {
|
|
10
19
|
path: PropertyKey[];
|
|
11
20
|
message: string;
|
|
@@ -39,6 +48,8 @@ export interface ZodLikeSchema<out Out> extends Type<Out, unknown> {
|
|
|
39
48
|
default(value: Exclude<Out, undefined> | (() => Exclude<Out, undefined>)): ZodLikeSchema<Exclude<Out, undefined>>;
|
|
40
49
|
describe(description: string): ZodLikeSchema<Out>;
|
|
41
50
|
refine(predicate: (value: Out) => unknown, messageOrOptions?: string | RefineOptions): ZodLikeSchema<Out>;
|
|
51
|
+
superRefine(refinement: (value: Out, ctx: SuperRefineContext) => void): ZodLikeSchema<Out>;
|
|
52
|
+
trim(): ZodLikeSchema<Out>;
|
|
42
53
|
transform<Next>(transformer: (value: Out) => Next): ZodLikeSchema<Next>;
|
|
43
54
|
catch(fallback: Out | (() => Out)): ZodLikeSchema<Out>;
|
|
44
55
|
strict(): ZodLikeSchema<Out>;
|
|
@@ -71,7 +82,8 @@ export { enumSchema as enum };
|
|
|
71
82
|
export declare const union: <const Schemas extends readonly [ZodLikeSchema<unknown>, ZodLikeSchema<unknown>, ...ZodLikeSchema<unknown>[]]>(schemas: Schemas) => ZodLikeSchema<UnionOutput<Schemas>>;
|
|
72
83
|
export declare const array: <Element>(element: ZodLikeSchema<Element>) => ZodLikeSchema<Element[]>;
|
|
73
84
|
export declare const object: <const S extends Shape>(shape: S) => ZodLikeSchema<Simplify<ObjectOutput<S>>>;
|
|
74
|
-
export declare
|
|
85
|
+
export declare function record<Key extends string, Value>(keySchema: ZodLikeSchema<Key>, valueSchema: ZodLikeSchema<Value>): ZodLikeSchema<Record<string, Value>>;
|
|
86
|
+
export declare function record<Value>(valueSchema: ZodLikeSchema<Value>): ZodLikeSchema<Record<string, Value>>;
|
|
75
87
|
export declare const unknown: () => ZodLikeSchema<unknown>;
|
|
76
88
|
export declare const any: () => ZodLikeSchema<unknown>;
|
|
77
89
|
declare const nullSchema: () => ZodLikeSchema<null>;
|
package/package.json
CHANGED
package/src/zod.ts
CHANGED
|
@@ -20,6 +20,17 @@ interface Decoratable<out Out> extends EmbeddableSchema {
|
|
|
20
20
|
default(value: Out | (() => Out)): Decoratable<Out>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
export interface SuperRefineIssue {
|
|
24
|
+
code?: string;
|
|
25
|
+
path?: PropertyKey[];
|
|
26
|
+
message: string;
|
|
27
|
+
actual?: unknown;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface SuperRefineContext {
|
|
31
|
+
addIssue(issue: SuperRefineIssue): void;
|
|
32
|
+
}
|
|
33
|
+
|
|
23
34
|
export interface ZodLikeIssue {
|
|
24
35
|
path: PropertyKey[];
|
|
25
36
|
message: string;
|
|
@@ -48,6 +59,8 @@ export interface ZodLikeSchema<out Out> extends Type<Out, unknown> {
|
|
|
48
59
|
default(value: Exclude<Out, undefined> | (() => Exclude<Out, undefined>)): ZodLikeSchema<Exclude<Out, undefined>>;
|
|
49
60
|
describe(description: string): ZodLikeSchema<Out>;
|
|
50
61
|
refine(predicate: (value: Out) => unknown, messageOrOptions?: string | RefineOptions): ZodLikeSchema<Out>;
|
|
62
|
+
superRefine(refinement: (value: Out, ctx: SuperRefineContext) => void): ZodLikeSchema<Out>;
|
|
63
|
+
trim(): ZodLikeSchema<Out>;
|
|
51
64
|
transform<Next>(transformer: (value: Out) => Next): ZodLikeSchema<Next>;
|
|
52
65
|
catch(fallback: Out | (() => Out)): ZodLikeSchema<Out>;
|
|
53
66
|
strict(): ZodLikeSchema<Out>;
|
|
@@ -140,6 +153,29 @@ function decorate<Out>(schema: Decoratable<Out>, optional = false): ZodLikeSchem
|
|
|
140
153
|
if (ir.min !== undefined && ir.min >= bound) return next(restrictBase(schema, ir));
|
|
141
154
|
return next(restrictBase(schema, { ...ir, min: bound, xmin: false }));
|
|
142
155
|
}
|
|
156
|
+
if (
|
|
157
|
+
ir.k === "morph" &&
|
|
158
|
+
!schema.hasSteps &&
|
|
159
|
+
ir.out !== undefined &&
|
|
160
|
+
(ir.out.k === "string" || ir.out.k === "array")
|
|
161
|
+
) {
|
|
162
|
+
if (!Number.isSafeInteger(bound) || bound < 0)
|
|
163
|
+
throw new OmpTypeError("min length must be a nonnegative safe integer");
|
|
164
|
+
const out = { ...ir.out, min: ir.out.min === undefined ? bound : Math.max(ir.out.min, bound) };
|
|
165
|
+
return next(restrictBase(schema, { ...ir, out }));
|
|
166
|
+
}
|
|
167
|
+
if (ir.k === "morph" && (schema.hasSteps || ir.out === undefined)) {
|
|
168
|
+
if (!Number.isSafeInteger(bound) || bound < 0)
|
|
169
|
+
throw new OmpTypeError("min length must be a nonnegative safe integer");
|
|
170
|
+
return next(
|
|
171
|
+
schema.narrow((value, ctx) => {
|
|
172
|
+
if (typeof value === "string" || Array.isArray(value)) {
|
|
173
|
+
return value.length >= bound || ctx.mustBe(`at least ${bound} characters`);
|
|
174
|
+
}
|
|
175
|
+
return ctx.mustBe("a string or array");
|
|
176
|
+
}),
|
|
177
|
+
);
|
|
178
|
+
}
|
|
143
179
|
throw new OmpTypeError(`cannot apply min to ${ir.k}`);
|
|
144
180
|
},
|
|
145
181
|
max(bound: number): ZodLikeSchema<Out> {
|
|
@@ -154,6 +190,29 @@ function decorate<Out>(schema: Decoratable<Out>, optional = false): ZodLikeSchem
|
|
|
154
190
|
if (ir.max !== undefined && ir.max <= bound) return next(restrictBase(schema, ir));
|
|
155
191
|
return next(restrictBase(schema, { ...ir, max: bound, xmax: false }));
|
|
156
192
|
}
|
|
193
|
+
if (
|
|
194
|
+
ir.k === "morph" &&
|
|
195
|
+
!schema.hasSteps &&
|
|
196
|
+
ir.out !== undefined &&
|
|
197
|
+
(ir.out.k === "string" || ir.out.k === "array")
|
|
198
|
+
) {
|
|
199
|
+
if (!Number.isSafeInteger(bound) || bound < 0)
|
|
200
|
+
throw new OmpTypeError("max length must be a nonnegative safe integer");
|
|
201
|
+
const out = { ...ir.out, max: ir.out.max === undefined ? bound : Math.min(ir.out.max, bound) };
|
|
202
|
+
return next(restrictBase(schema, { ...ir, out }));
|
|
203
|
+
}
|
|
204
|
+
if (ir.k === "morph" && (schema.hasSteps || ir.out === undefined)) {
|
|
205
|
+
if (!Number.isSafeInteger(bound) || bound < 0)
|
|
206
|
+
throw new OmpTypeError("max length must be a nonnegative safe integer");
|
|
207
|
+
return next(
|
|
208
|
+
schema.narrow((value, ctx) => {
|
|
209
|
+
if (typeof value === "string" || Array.isArray(value)) {
|
|
210
|
+
return value.length <= bound || ctx.mustBe(`at most ${bound} characters`);
|
|
211
|
+
}
|
|
212
|
+
return ctx.mustBe("a string or array");
|
|
213
|
+
}),
|
|
214
|
+
);
|
|
215
|
+
}
|
|
157
216
|
throw new OmpTypeError(`cannot apply max to ${ir.k}`);
|
|
158
217
|
},
|
|
159
218
|
int(): ZodLikeSchema<Out> {
|
|
@@ -171,19 +230,41 @@ function decorate<Out>(schema: Decoratable<Out>, optional = false): ZodLikeSchem
|
|
|
171
230
|
return this.min(0);
|
|
172
231
|
},
|
|
173
232
|
regex(expression: RegExp, message?: string): ZodLikeSchema<Out> {
|
|
174
|
-
|
|
233
|
+
const ir = schema.ir;
|
|
234
|
+
const isStringLike =
|
|
235
|
+
ir.k === "string" ||
|
|
236
|
+
(ir.k === "morph" && (ir.out?.k === "string" || (ir.out === undefined && ir.input.k === "string")));
|
|
237
|
+
if (!isStringLike) throw new OmpTypeError(`cannot apply regex to ${ir.k}`);
|
|
175
238
|
const expectation = message ?? `matching ${expression}`;
|
|
176
239
|
const narrowed = schema.narrow((value, ctx) => {
|
|
240
|
+
if (typeof value !== "string") return ctx.mustBe("a string");
|
|
177
241
|
expression.lastIndex = 0;
|
|
178
|
-
const matches = expression.test(value
|
|
242
|
+
const matches = expression.test(value);
|
|
179
243
|
expression.lastIndex = 0;
|
|
180
244
|
return matches || ctx.mustBe(expectation);
|
|
181
245
|
});
|
|
182
246
|
return next(narrowed);
|
|
183
247
|
},
|
|
184
248
|
url(): ZodLikeSchema<Out> {
|
|
185
|
-
|
|
186
|
-
return next(restrictBase(schema, { ...
|
|
249
|
+
const ir = schema.ir;
|
|
250
|
+
if (ir.k === "string") return next(restrictBase(schema, { ...ir, url: true }));
|
|
251
|
+
if (ir.k === "morph" && !schema.hasSteps && ir.out !== undefined && ir.out.k === "string") {
|
|
252
|
+
return next(restrictBase(schema, { ...ir, out: { ...ir.out, url: true } }));
|
|
253
|
+
}
|
|
254
|
+
if (ir.k === "morph" && (schema.hasSteps || ir.out === undefined)) {
|
|
255
|
+
return next(
|
|
256
|
+
schema.narrow((value, ctx) => {
|
|
257
|
+
if (typeof value !== "string") return ctx.mustBe("a string");
|
|
258
|
+
try {
|
|
259
|
+
new URL(value);
|
|
260
|
+
return true;
|
|
261
|
+
} catch {
|
|
262
|
+
return ctx.mustBe("a valid URL");
|
|
263
|
+
}
|
|
264
|
+
}),
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
throw new OmpTypeError(`cannot apply url to ${ir.k}`);
|
|
187
268
|
},
|
|
188
269
|
optional(): ZodLikeSchema<Out | undefined> & OptionalSchemaMarker {
|
|
189
270
|
const widened = schema.or(type.raw("undefined")) as Decoratable<Out | undefined>;
|
|
@@ -210,6 +291,52 @@ function decorate<Out>(schema: Decoratable<Out>, optional = false): ZodLikeSchem
|
|
|
210
291
|
const expectation = refinementMessage(messageOrOptions);
|
|
211
292
|
return next(schema.narrow((value, ctx) => Boolean(predicate(value)) || ctx.mustBe(expectation)));
|
|
212
293
|
},
|
|
294
|
+
superRefine(refinement: (value: Out, ctx: SuperRefineContext) => void): ZodLikeSchema<Out> {
|
|
295
|
+
return next(
|
|
296
|
+
schema.narrow((value, ctx) => {
|
|
297
|
+
const proxy: SuperRefineContext = {
|
|
298
|
+
addIssue(issue) {
|
|
299
|
+
ctx.error({
|
|
300
|
+
expected: issue.message,
|
|
301
|
+
path: issue.path ?? [],
|
|
302
|
+
...(issue.actual !== undefined ? { actual: issue.actual } : {}),
|
|
303
|
+
});
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
refinement(value, proxy);
|
|
307
|
+
return true;
|
|
308
|
+
}),
|
|
309
|
+
);
|
|
310
|
+
},
|
|
311
|
+
trim(): ZodLikeSchema<Out> {
|
|
312
|
+
const ir = schema.ir;
|
|
313
|
+
if (ir.k === "string" && !schema.hasSteps) {
|
|
314
|
+
let trimmed = schemaFromIR<Out>({
|
|
315
|
+
k: "morph",
|
|
316
|
+
input: { k: "string" },
|
|
317
|
+
fn: v => (v as string).trim(),
|
|
318
|
+
out: ir,
|
|
319
|
+
});
|
|
320
|
+
if (schema.hasDefault) trimmed = trimmed.default(schema.defaultValue as Out | (() => Out));
|
|
321
|
+
return next(trimmed);
|
|
322
|
+
}
|
|
323
|
+
if (ir.k === "morph" || schema.hasSteps) {
|
|
324
|
+
let trimmed = schemaFromIR<Out>({
|
|
325
|
+
k: "morph",
|
|
326
|
+
input: { k: "unknown" },
|
|
327
|
+
fn: v => {
|
|
328
|
+
const r = schema(v);
|
|
329
|
+
if (r instanceof type.errors) return r;
|
|
330
|
+
if (typeof r !== "string") throw new OmpTypeError("trim requires a string output");
|
|
331
|
+
return r.trim();
|
|
332
|
+
},
|
|
333
|
+
out: { k: "string" },
|
|
334
|
+
});
|
|
335
|
+
if (schema.hasDefault) trimmed = trimmed.default(schema.defaultValue as Out | (() => Out));
|
|
336
|
+
return next(trimmed);
|
|
337
|
+
}
|
|
338
|
+
throw new OmpTypeError(`cannot apply trim to ${ir.k}`);
|
|
339
|
+
},
|
|
213
340
|
transform<Next>(transformer: (value: Out) => Next): ZodLikeSchema<Next> {
|
|
214
341
|
return decorate(
|
|
215
342
|
schema.pipe(value => transformer(value)),
|
|
@@ -303,15 +430,22 @@ export const array = <Element>(element: ZodLikeSchema<Element>): ZodLikeSchema<E
|
|
|
303
430
|
decorate(schemaFromIR({ k: "array", el: embed(element) }));
|
|
304
431
|
export const object = <const S extends Shape>(shape: S): ZodLikeSchema<Simplify<ObjectOutput<S>>> =>
|
|
305
432
|
objectSchema(shape);
|
|
306
|
-
export
|
|
433
|
+
export function record<Key extends string, Value>(
|
|
307
434
|
keySchema: ZodLikeSchema<Key>,
|
|
308
435
|
valueSchema: ZodLikeSchema<Value>,
|
|
309
|
-
): ZodLikeSchema<Record<string, Value
|
|
436
|
+
): ZodLikeSchema<Record<string, Value>>;
|
|
437
|
+
export function record<Value>(valueSchema: ZodLikeSchema<Value>): ZodLikeSchema<Record<string, Value>>;
|
|
438
|
+
export function record<Key extends string, Value>(
|
|
439
|
+
keyOrValueSchema: ZodLikeSchema<Key> | ZodLikeSchema<Value>,
|
|
440
|
+
valueSchema?: ZodLikeSchema<Value>,
|
|
441
|
+
): ZodLikeSchema<Record<string, Value>> {
|
|
442
|
+
const keySchema = (valueSchema === undefined ? string() : keyOrValueSchema) as ZodLikeSchema<Key>;
|
|
443
|
+
const valSchema = (valueSchema === undefined ? keyOrValueSchema : valueSchema) as ZodLikeSchema<Value>;
|
|
310
444
|
if (!isStringKeyIR(keySchema.ir)) throw new OmpTypeError("record keys must use a string schema");
|
|
311
445
|
const base = schemaFromIR<Record<string, Value>>({
|
|
312
446
|
k: "object",
|
|
313
447
|
props: [],
|
|
314
|
-
index: embed(
|
|
448
|
+
index: embed(valSchema),
|
|
315
449
|
extras: "keep",
|
|
316
450
|
});
|
|
317
451
|
const checked = base.narrow((value, ctx: NarrowContext) => {
|
|
@@ -321,7 +455,7 @@ export const record = <Key extends string, Value>(
|
|
|
321
455
|
return true;
|
|
322
456
|
});
|
|
323
457
|
return decorate(checked);
|
|
324
|
-
}
|
|
458
|
+
}
|
|
325
459
|
export const unknown = (): ZodLikeSchema<unknown> => decorate(schemaFromIR(type.unknown.ir));
|
|
326
460
|
export const any = (): ZodLikeSchema<unknown> => decorate(schemaFromIR(type.unknown.ir));
|
|
327
461
|
const nullSchema = (): ZodLikeSchema<null> => decorate(type.raw("null") as unknown as Decoratable<null>);
|