zod 4.3.3 → 4.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "4.3.3",
3
+ "version": "4.3.5",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Colin McDonnell <zod@colinhacks.com>",
@@ -597,7 +597,7 @@ function convertSchema(schema: JSONSchema.JSONSchema | boolean, ctx: ConversionC
597
597
  }
598
598
  }
599
599
 
600
- // Content keywords that should be captured as metadata
600
+ // Content keywords - store as metadata
601
601
  const contentMetadataKeys = ["contentEncoding", "contentMediaType", "contentSchema"];
602
602
  for (const key of contentMetadataKeys) {
603
603
  if (key in schema) {
@@ -711,3 +711,24 @@ test("$comment and $anchor are captured as metadata", () => {
711
711
  expect(meta?.$comment).toBe("This is a developer note");
712
712
  expect(meta?.$anchor).toBe("my-anchor");
713
713
  });
714
+
715
+ test("contentEncoding and contentMediaType are stored as metadata", () => {
716
+ const customRegistry = z.registry<{ contentEncoding?: string; contentMediaType?: string }>();
717
+
718
+ const schema = fromJSONSchema(
719
+ {
720
+ type: "string",
721
+ contentEncoding: "base64",
722
+ contentMediaType: "image/png",
723
+ },
724
+ { registry: customRegistry }
725
+ );
726
+
727
+ // Should just be a string schema
728
+ expect(schema.parse("aGVsbG8gd29ybGQ=")).toBe("aGVsbG8gd29ybGQ=");
729
+
730
+ // Content keywords should be in metadata
731
+ const meta = customRegistry.get(schema);
732
+ expect(meta?.contentEncoding).toBe("base64");
733
+ expect(meta?.contentMediaType).toBe("image/png");
734
+ });
@@ -524,6 +524,58 @@ test("intersection of loose records", () => {
524
524
  expect(() => schema.parse({ name: "John", N_count: "abc" })).toThrow(); // N_count should be number
525
525
  });
526
526
 
527
+ test("object with looseRecord index signature", () => {
528
+ // Simulates TypeScript index signature: { label: string; [key: `label:${string}`]: string }
529
+ const schema = z.object({ label: z.string() }).and(z.looseRecord(z.string().regex(/^label:[a-z]{2}$/), z.string()));
530
+
531
+ type Schema = z.infer<typeof schema>;
532
+ expectTypeOf<Schema>().toEqualTypeOf<{ label: string } & Record<string, string>>();
533
+
534
+ // Valid: has required property and matching pattern keys
535
+ expect(schema.parse({ label: "Purple", "label:en": "Purple", "label:ru": "Пурпурный" })).toEqual({
536
+ label: "Purple",
537
+ "label:en": "Purple",
538
+ "label:ru": "Пурпурный",
539
+ });
540
+
541
+ // Valid: just required property
542
+ expect(schema.parse({ label: "Purple" })).toEqual({ label: "Purple" });
543
+
544
+ // Invalid: missing required property
545
+ expect(schema.safeParse({ "label:en": "Purple" })).toMatchInlineSnapshot(`
546
+ {
547
+ "error": [ZodError: [
548
+ {
549
+ "expected": "string",
550
+ "code": "invalid_type",
551
+ "path": [
552
+ "label"
553
+ ],
554
+ "message": "Invalid input: expected string, received undefined"
555
+ }
556
+ ]],
557
+ "success": false,
558
+ }
559
+ `);
560
+
561
+ // Invalid: pattern key with wrong value type
562
+ expect(schema.safeParse({ label: "Purple", "label:en": 123 })).toMatchInlineSnapshot(`
563
+ {
564
+ "error": [ZodError: [
565
+ {
566
+ "expected": "string",
567
+ "code": "invalid_type",
568
+ "path": [
569
+ "label:en"
570
+ ],
571
+ "message": "Invalid input: expected string, received number"
572
+ }
573
+ ]],
574
+ "success": false,
575
+ }
576
+ `);
577
+ });
578
+
527
579
  test("numeric string keys", () => {
528
580
  const schema = z.record(z.number(), z.number());
529
581
 
@@ -929,6 +929,117 @@ describe("toJSONSchema", () => {
929
929
  `);
930
930
  });
931
931
 
932
+ test("strict record with regex key uses propertyNames", () => {
933
+ const schema = z.record(z.string().regex(/^label:[a-z]{2}$/), z.string());
934
+
935
+ expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
936
+ {
937
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
938
+ "additionalProperties": {
939
+ "type": "string",
940
+ },
941
+ "propertyNames": {
942
+ "pattern": "^label:[a-z]{2}$",
943
+ "type": "string",
944
+ },
945
+ "type": "object",
946
+ }
947
+ `);
948
+ });
949
+
950
+ test("looseRecord with regex key uses patternProperties", () => {
951
+ const schema = z.looseRecord(z.string().regex(/^label:[a-z]{2}$/), z.string());
952
+
953
+ expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
954
+ {
955
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
956
+ "patternProperties": {
957
+ "^label:[a-z]{2}$": {
958
+ "type": "string",
959
+ },
960
+ },
961
+ "type": "object",
962
+ }
963
+ `);
964
+ });
965
+
966
+ test("looseRecord with multiple regex patterns uses patternProperties", () => {
967
+ const schema = z.looseRecord(
968
+ z
969
+ .string()
970
+ .regex(/^prefix_/)
971
+ .regex(/_suffix$/),
972
+ z.number()
973
+ );
974
+
975
+ expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
976
+ {
977
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
978
+ "patternProperties": {
979
+ "^prefix_": {
980
+ "type": "number",
981
+ },
982
+ "_suffix$": {
983
+ "type": "number",
984
+ },
985
+ },
986
+ "type": "object",
987
+ }
988
+ `);
989
+ });
990
+
991
+ test("looseRecord without regex key uses propertyNames", () => {
992
+ // looseRecord with plain string key should still use propertyNames
993
+ const schema = z.looseRecord(z.string(), z.boolean());
994
+
995
+ expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
996
+ {
997
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
998
+ "additionalProperties": {
999
+ "type": "boolean",
1000
+ },
1001
+ "propertyNames": {
1002
+ "type": "string",
1003
+ },
1004
+ "type": "object",
1005
+ }
1006
+ `);
1007
+ });
1008
+
1009
+ test("intersection of object with looseRecord uses patternProperties", () => {
1010
+ const zLabeled = z.object({ label: z.string() });
1011
+ const zLocalizedLabeled = z.looseRecord(z.string().regex(/^label:[a-z]{2}$/), z.string());
1012
+ const schema = zLabeled.and(zLocalizedLabeled);
1013
+
1014
+ expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1015
+ {
1016
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
1017
+ "allOf": [
1018
+ {
1019
+ "additionalProperties": false,
1020
+ "properties": {
1021
+ "label": {
1022
+ "type": "string",
1023
+ },
1024
+ },
1025
+ "required": [
1026
+ "label",
1027
+ ],
1028
+ "type": "object",
1029
+ },
1030
+ {
1031
+ "patternProperties": {
1032
+ "^label:[a-z]{2}$": {
1033
+ "type": "string",
1034
+ },
1035
+ },
1036
+ "type": "object",
1037
+ },
1038
+ ],
1039
+ }
1040
+ `);
1041
+ });
1042
+
932
1043
  test("tuple", () => {
933
1044
  const schema = z.tuple([z.string(), z.number()]);
934
1045
  expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
@@ -431,26 +431,47 @@ export const recordProcessor: Processor<schemas.$ZodRecord> = (schema, ctx, _jso
431
431
  const json = _json as JSONSchema.ObjectSchema;
432
432
  const def = schema._zod.def as schemas.$ZodRecordDef;
433
433
  json.type = "object";
434
- if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
435
- json.propertyNames = process(def.keyType, ctx as any, {
434
+
435
+ // For looseRecord with regex patterns, use patternProperties
436
+ // This correctly represents "only validate keys matching the pattern" semantics
437
+ // and composes well with allOf (intersections)
438
+ const keyType = def.keyType as schemas.$ZodTypes;
439
+ const keyBag = keyType._zod.bag as schemas.$ZodStringInternals<unknown>["bag"] | undefined;
440
+ const patterns = keyBag?.patterns;
441
+
442
+ if (def.mode === "loose" && patterns && patterns.size > 0) {
443
+ // Use patternProperties for looseRecord with regex patterns
444
+ const valueSchema = process(def.valueType, ctx as any, {
436
445
  ...params,
437
- path: [...params.path, "propertyNames"],
446
+ path: [...params.path, "patternProperties", "*"],
447
+ });
448
+ json.patternProperties = {};
449
+ for (const pattern of patterns) {
450
+ json.patternProperties[pattern.source] = valueSchema;
451
+ }
452
+ } else {
453
+ // Default behavior: use propertyNames + additionalProperties
454
+ if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
455
+ json.propertyNames = process(def.keyType, ctx as any, {
456
+ ...params,
457
+ path: [...params.path, "propertyNames"],
458
+ });
459
+ }
460
+ json.additionalProperties = process(def.valueType, ctx as any, {
461
+ ...params,
462
+ path: [...params.path, "additionalProperties"],
438
463
  });
439
464
  }
440
- json.additionalProperties = process(def.valueType, ctx as any, {
441
- ...params,
442
- path: [...params.path, "additionalProperties"],
443
- });
444
465
 
445
- const keyDef = (def.keyType as schemas.$ZodTypes)._zod.def;
446
- if (keyDef.type === "enum") {
447
- const enumValues = getEnumValues(keyDef.entries);
448
- const validEnumValues = enumValues.filter(
466
+ // Add required for keys with discrete values (enum, literal, etc.)
467
+ const keyValues = keyType._zod.values;
468
+ if (keyValues) {
469
+ const validKeyValues = [...keyValues].filter(
449
470
  (v): v is string | number => typeof v === "string" || typeof v === "number"
450
471
  );
451
472
 
452
- if (validEnumValues.length > 0) {
453
- json.required = validEnumValues as string[];
473
+ if (validKeyValues.length > 0) {
474
+ json.required = validKeyValues as string[];
454
475
  }
455
476
  }
456
477
  };
@@ -1,5 +1,5 @@
1
1
  export const version = {
2
2
  major: 4,
3
3
  minor: 3,
4
- patch: 3 as number,
4
+ patch: 5 as number,
5
5
  } as const;
@@ -1,5 +1,5 @@
1
1
  import * as core from "../core/index.js";
2
- import { util } from "../core/index.js";
2
+ import * as util from "../core/util.js";
3
3
  import * as parse from "./parse.js";
4
4
 
5
5
  type SomeType = core.SomeType;
@@ -12,10 +12,6 @@ export interface ZodMiniType<
12
12
  type: Internals["def"]["type"];
13
13
  check(...checks: (core.CheckFn<core.output<this>> | core.$ZodCheck<core.output<this>>)[]): this;
14
14
  with(...checks: (core.CheckFn<core.output<this>> | core.$ZodCheck<core.output<this>>)[]): this;
15
- refine<Ch extends (arg: core.output<this>) => unknown | Promise<unknown>>(
16
- check: Ch,
17
- params?: string | core.$ZodCustomParams
18
- ): Ch extends (arg: any) => arg is infer R ? core.$ZodNarrow<this, R> : this;
19
15
  clone(def?: Internals["def"], params?: { parent: boolean }): this;
20
16
  register<R extends core.$ZodRegistry>(
21
17
  registry: R,
@@ -72,7 +68,6 @@ export const ZodMiniType: core.$constructor<ZodMiniType> = /*@__PURE__*/ core.$c
72
68
  );
73
69
  };
74
70
  inst.with = inst.check;
75
- inst.refine = (check, params) => inst.check(refine(check, params)) as never;
76
71
  inst.clone = (_def, params) => core.clone(inst, _def, params);
77
72
  inst.brand = () => inst as any;
78
73
  inst.register = ((reg: any, meta: any) => {
@@ -571,7 +571,7 @@ function convertSchema(schema, ctx) {
571
571
  extraMeta[key] = schema[key];
572
572
  }
573
573
  }
574
- // Content keywords that should be captured as metadata
574
+ // Content keywords - store as metadata
575
575
  const contentMetadataKeys = ["contentEncoding", "contentMediaType", "contentSchema"];
576
576
  for (const key of contentMetadataKeys) {
577
577
  if (key in schema) {
@@ -545,7 +545,7 @@ function convertSchema(schema, ctx) {
545
545
  extraMeta[key] = schema[key];
546
546
  }
547
547
  }
548
- // Content keywords that should be captured as metadata
548
+ // Content keywords - store as metadata
549
549
  const contentMetadataKeys = ["contentEncoding", "contentMediaType", "contentSchema"];
550
550
  for (const key of contentMetadataKeys) {
551
551
  if (key in schema) {
@@ -436,22 +436,42 @@ const recordProcessor = (schema, ctx, _json, params) => {
436
436
  const json = _json;
437
437
  const def = schema._zod.def;
438
438
  json.type = "object";
439
- if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
440
- json.propertyNames = (0, to_json_schema_js_1.process)(def.keyType, ctx, {
439
+ // For looseRecord with regex patterns, use patternProperties
440
+ // This correctly represents "only validate keys matching the pattern" semantics
441
+ // and composes well with allOf (intersections)
442
+ const keyType = def.keyType;
443
+ const keyBag = keyType._zod.bag;
444
+ const patterns = keyBag?.patterns;
445
+ if (def.mode === "loose" && patterns && patterns.size > 0) {
446
+ // Use patternProperties for looseRecord with regex patterns
447
+ const valueSchema = (0, to_json_schema_js_1.process)(def.valueType, ctx, {
441
448
  ...params,
442
- path: [...params.path, "propertyNames"],
449
+ path: [...params.path, "patternProperties", "*"],
443
450
  });
451
+ json.patternProperties = {};
452
+ for (const pattern of patterns) {
453
+ json.patternProperties[pattern.source] = valueSchema;
454
+ }
444
455
  }
445
- json.additionalProperties = (0, to_json_schema_js_1.process)(def.valueType, ctx, {
446
- ...params,
447
- path: [...params.path, "additionalProperties"],
448
- });
449
- const keyDef = def.keyType._zod.def;
450
- if (keyDef.type === "enum") {
451
- const enumValues = (0, util_js_1.getEnumValues)(keyDef.entries);
452
- const validEnumValues = enumValues.filter((v) => typeof v === "string" || typeof v === "number");
453
- if (validEnumValues.length > 0) {
454
- json.required = validEnumValues;
456
+ else {
457
+ // Default behavior: use propertyNames + additionalProperties
458
+ if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
459
+ json.propertyNames = (0, to_json_schema_js_1.process)(def.keyType, ctx, {
460
+ ...params,
461
+ path: [...params.path, "propertyNames"],
462
+ });
463
+ }
464
+ json.additionalProperties = (0, to_json_schema_js_1.process)(def.valueType, ctx, {
465
+ ...params,
466
+ path: [...params.path, "additionalProperties"],
467
+ });
468
+ }
469
+ // Add required for keys with discrete values (enum, literal, etc.)
470
+ const keyValues = keyType._zod.values;
471
+ if (keyValues) {
472
+ const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
473
+ if (validKeyValues.length > 0) {
474
+ json.required = validKeyValues;
455
475
  }
456
476
  }
457
477
  };
@@ -404,22 +404,42 @@ export const recordProcessor = (schema, ctx, _json, params) => {
404
404
  const json = _json;
405
405
  const def = schema._zod.def;
406
406
  json.type = "object";
407
- if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
408
- json.propertyNames = process(def.keyType, ctx, {
407
+ // For looseRecord with regex patterns, use patternProperties
408
+ // This correctly represents "only validate keys matching the pattern" semantics
409
+ // and composes well with allOf (intersections)
410
+ const keyType = def.keyType;
411
+ const keyBag = keyType._zod.bag;
412
+ const patterns = keyBag?.patterns;
413
+ if (def.mode === "loose" && patterns && patterns.size > 0) {
414
+ // Use patternProperties for looseRecord with regex patterns
415
+ const valueSchema = process(def.valueType, ctx, {
409
416
  ...params,
410
- path: [...params.path, "propertyNames"],
417
+ path: [...params.path, "patternProperties", "*"],
411
418
  });
419
+ json.patternProperties = {};
420
+ for (const pattern of patterns) {
421
+ json.patternProperties[pattern.source] = valueSchema;
422
+ }
412
423
  }
413
- json.additionalProperties = process(def.valueType, ctx, {
414
- ...params,
415
- path: [...params.path, "additionalProperties"],
416
- });
417
- const keyDef = def.keyType._zod.def;
418
- if (keyDef.type === "enum") {
419
- const enumValues = getEnumValues(keyDef.entries);
420
- const validEnumValues = enumValues.filter((v) => typeof v === "string" || typeof v === "number");
421
- if (validEnumValues.length > 0) {
422
- json.required = validEnumValues;
424
+ else {
425
+ // Default behavior: use propertyNames + additionalProperties
426
+ if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
427
+ json.propertyNames = process(def.keyType, ctx, {
428
+ ...params,
429
+ path: [...params.path, "propertyNames"],
430
+ });
431
+ }
432
+ json.additionalProperties = process(def.valueType, ctx, {
433
+ ...params,
434
+ path: [...params.path, "additionalProperties"],
435
+ });
436
+ }
437
+ // Add required for keys with discrete values (enum, literal, etc.)
438
+ const keyValues = keyType._zod.values;
439
+ if (keyValues) {
440
+ const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
441
+ if (validKeyValues.length > 0) {
442
+ json.required = validKeyValues;
423
443
  }
424
444
  }
425
445
  };
@@ -4,5 +4,5 @@ exports.version = void 0;
4
4
  exports.version = {
5
5
  major: 4,
6
6
  minor: 3,
7
- patch: 3,
7
+ patch: 5,
8
8
  };
@@ -1,5 +1,5 @@
1
1
  export const version = {
2
2
  major: 4,
3
3
  minor: 3,
4
- patch: 3,
4
+ patch: 5,
5
5
  };
@@ -127,7 +127,7 @@ exports.function = _function;
127
127
  exports._function = _function;
128
128
  exports.function = _function;
129
129
  const core = __importStar(require("../core/index.cjs"));
130
- const index_js_1 = require("../core/index.cjs");
130
+ const util = __importStar(require("../core/util.cjs"));
131
131
  const parse = __importStar(require("./parse.cjs"));
132
132
  exports.ZodMiniType = core.$constructor("ZodMiniType", (inst, def) => {
133
133
  if (!inst._zod)
@@ -149,7 +149,6 @@ exports.ZodMiniType = core.$constructor("ZodMiniType", (inst, def) => {
149
149
  }, { parent: true });
150
150
  };
151
151
  inst.with = inst.check;
152
- inst.refine = (check, params) => inst.check(refine(check, params));
153
152
  inst.clone = (_def, params) => core.clone(inst, _def, params);
154
153
  inst.brand = () => inst;
155
154
  inst.register = ((reg, meta) => {
@@ -221,7 +220,7 @@ function httpUrl(params) {
221
220
  return core._url(exports.ZodMiniURL, {
222
221
  protocol: /^https?$/,
223
222
  hostname: core.regexes.domain,
224
- ...index_js_1.util.normalizeParams(params),
223
+ ...util.normalizeParams(params),
225
224
  });
226
225
  }
227
226
  exports.ZodMiniEmoji = core.$constructor("ZodMiniEmoji", (inst, def) => {
@@ -518,7 +517,7 @@ function array(element, params) {
518
517
  return new exports.ZodMiniArray({
519
518
  type: "array",
520
519
  element: element,
521
- ...index_js_1.util.normalizeParams(params),
520
+ ...util.normalizeParams(params),
522
521
  });
523
522
  }
524
523
  // .keyof
@@ -530,14 +529,14 @@ function keyof(schema) {
530
529
  exports.ZodMiniObject = core.$constructor("ZodMiniObject", (inst, def) => {
531
530
  core.$ZodObject.init(inst, def);
532
531
  exports.ZodMiniType.init(inst, def);
533
- index_js_1.util.defineLazy(inst, "shape", () => def.shape);
532
+ util.defineLazy(inst, "shape", () => def.shape);
534
533
  });
535
534
  // @__NO_SIDE_EFFECTS__
536
535
  function object(shape, params) {
537
536
  const def = {
538
537
  type: "object",
539
538
  shape: shape ?? {},
540
- ...index_js_1.util.normalizeParams(params),
539
+ ...util.normalizeParams(params),
541
540
  };
542
541
  return new exports.ZodMiniObject(def);
543
542
  }
@@ -548,7 +547,7 @@ function strictObject(shape, params) {
548
547
  type: "object",
549
548
  shape,
550
549
  catchall: never(),
551
- ...index_js_1.util.normalizeParams(params),
550
+ ...util.normalizeParams(params),
552
551
  });
553
552
  }
554
553
  // looseObject
@@ -558,38 +557,38 @@ function looseObject(shape, params) {
558
557
  type: "object",
559
558
  shape,
560
559
  catchall: unknown(),
561
- ...index_js_1.util.normalizeParams(params),
560
+ ...util.normalizeParams(params),
562
561
  });
563
562
  }
564
563
  // object methods
565
564
  // @__NO_SIDE_EFFECTS__
566
565
  function extend(schema, shape) {
567
- return index_js_1.util.extend(schema, shape);
566
+ return util.extend(schema, shape);
568
567
  }
569
568
  // @__NO_SIDE_EFFECTS__
570
569
  function safeExtend(schema, shape) {
571
- return index_js_1.util.safeExtend(schema, shape);
570
+ return util.safeExtend(schema, shape);
572
571
  }
573
572
  // @__NO_SIDE_EFFECTS__
574
573
  function merge(schema, shape) {
575
- return index_js_1.util.extend(schema, shape);
574
+ return util.extend(schema, shape);
576
575
  }
577
576
  // @__NO_SIDE_EFFECTS__
578
577
  function pick(schema, mask) {
579
- return index_js_1.util.pick(schema, mask);
578
+ return util.pick(schema, mask);
580
579
  }
581
580
  // .omit
582
581
  // @__NO_SIDE_EFFECTS__
583
582
  function omit(schema, mask) {
584
- return index_js_1.util.omit(schema, mask);
583
+ return util.omit(schema, mask);
585
584
  }
586
585
  // @__NO_SIDE_EFFECTS__
587
586
  function partial(schema, mask) {
588
- return index_js_1.util.partial(exports.ZodMiniOptional, schema, mask);
587
+ return util.partial(exports.ZodMiniOptional, schema, mask);
589
588
  }
590
589
  // @__NO_SIDE_EFFECTS__
591
590
  function required(schema, mask) {
592
- return index_js_1.util.required(exports.ZodMiniNonOptional, schema, mask);
591
+ return util.required(exports.ZodMiniNonOptional, schema, mask);
593
592
  }
594
593
  // @__NO_SIDE_EFFECTS__
595
594
  function catchall(inst, catchall) {
@@ -604,7 +603,7 @@ function union(options, params) {
604
603
  return new exports.ZodMiniUnion({
605
604
  type: "union",
606
605
  options: options,
607
- ...index_js_1.util.normalizeParams(params),
606
+ ...util.normalizeParams(params),
608
607
  });
609
608
  }
610
609
  exports.ZodMiniXor = core.$constructor("ZodMiniXor", (inst, def) => {
@@ -619,7 +618,7 @@ function xor(options, params) {
619
618
  type: "union",
620
619
  options: options,
621
620
  inclusive: false,
622
- ...index_js_1.util.normalizeParams(params),
621
+ ...util.normalizeParams(params),
623
622
  });
624
623
  }
625
624
  exports.ZodMiniDiscriminatedUnion = core.$constructor("ZodMiniDiscriminatedUnion", (inst, def) => {
@@ -632,7 +631,7 @@ function discriminatedUnion(discriminator, options, params) {
632
631
  type: "union",
633
632
  options,
634
633
  discriminator,
635
- ...index_js_1.util.normalizeParams(params),
634
+ ...util.normalizeParams(params),
636
635
  });
637
636
  }
638
637
  exports.ZodMiniIntersection = core.$constructor("ZodMiniIntersection", (inst, def) => {
@@ -660,7 +659,7 @@ function tuple(items, _paramsOrRest, _params) {
660
659
  type: "tuple",
661
660
  items: items,
662
661
  rest,
663
- ...index_js_1.util.normalizeParams(params),
662
+ ...util.normalizeParams(params),
664
663
  });
665
664
  }
666
665
  exports.ZodMiniRecord = core.$constructor("ZodMiniRecord", (inst, def) => {
@@ -673,7 +672,7 @@ function record(keyType, valueType, params) {
673
672
  type: "record",
674
673
  keyType,
675
674
  valueType: valueType,
676
- ...index_js_1.util.normalizeParams(params),
675
+ ...util.normalizeParams(params),
677
676
  });
678
677
  }
679
678
  // @__NO_SIDE_EFFECTS__
@@ -684,7 +683,7 @@ function partialRecord(keyType, valueType, params) {
684
683
  type: "record",
685
684
  keyType: k,
686
685
  valueType: valueType,
687
- ...index_js_1.util.normalizeParams(params),
686
+ ...util.normalizeParams(params),
688
687
  });
689
688
  }
690
689
  function looseRecord(keyType, valueType, params) {
@@ -693,7 +692,7 @@ function looseRecord(keyType, valueType, params) {
693
692
  keyType,
694
693
  valueType: valueType,
695
694
  mode: "loose",
696
- ...index_js_1.util.normalizeParams(params),
695
+ ...util.normalizeParams(params),
697
696
  });
698
697
  }
699
698
  exports.ZodMiniMap = core.$constructor("ZodMiniMap", (inst, def) => {
@@ -706,7 +705,7 @@ function map(keyType, valueType, params) {
706
705
  type: "map",
707
706
  keyType: keyType,
708
707
  valueType: valueType,
709
- ...index_js_1.util.normalizeParams(params),
708
+ ...util.normalizeParams(params),
710
709
  });
711
710
  }
712
711
  exports.ZodMiniSet = core.$constructor("ZodMiniSet", (inst, def) => {
@@ -718,7 +717,7 @@ function set(valueType, params) {
718
717
  return new exports.ZodMiniSet({
719
718
  type: "set",
720
719
  valueType: valueType,
721
- ...index_js_1.util.normalizeParams(params),
720
+ ...util.normalizeParams(params),
722
721
  });
723
722
  }
724
723
  exports.ZodMiniEnum = core.$constructor("ZodMiniEnum", (inst, def) => {
@@ -732,7 +731,7 @@ function _enum(values, params) {
732
731
  return new exports.ZodMiniEnum({
733
732
  type: "enum",
734
733
  entries,
735
- ...index_js_1.util.normalizeParams(params),
734
+ ...util.normalizeParams(params),
736
735
  });
737
736
  }
738
737
  // @__NO_SIDE_EFFECTS__
@@ -747,7 +746,7 @@ function nativeEnum(entries, params) {
747
746
  return new exports.ZodMiniEnum({
748
747
  type: "enum",
749
748
  entries,
750
- ...index_js_1.util.normalizeParams(params),
749
+ ...util.normalizeParams(params),
751
750
  });
752
751
  }
753
752
  exports.ZodMiniLiteral = core.$constructor("ZodMiniLiteral", (inst, def) => {
@@ -759,7 +758,7 @@ function literal(value, params) {
759
758
  return new exports.ZodMiniLiteral({
760
759
  type: "literal",
761
760
  values: Array.isArray(value) ? value : [value],
762
- ...index_js_1.util.normalizeParams(params),
761
+ ...util.normalizeParams(params),
763
762
  });
764
763
  }
765
764
  exports.ZodMiniFile = core.$constructor("ZodMiniFile", (inst, def) => {
@@ -829,7 +828,7 @@ function _default(innerType, defaultValue) {
829
828
  type: "default",
830
829
  innerType: innerType,
831
830
  get defaultValue() {
832
- return typeof defaultValue === "function" ? defaultValue() : index_js_1.util.shallowClone(defaultValue);
831
+ return typeof defaultValue === "function" ? defaultValue() : util.shallowClone(defaultValue);
833
832
  },
834
833
  });
835
834
  }
@@ -843,7 +842,7 @@ function prefault(innerType, defaultValue) {
843
842
  type: "prefault",
844
843
  innerType: innerType,
845
844
  get defaultValue() {
846
- return typeof defaultValue === "function" ? defaultValue() : index_js_1.util.shallowClone(defaultValue);
845
+ return typeof defaultValue === "function" ? defaultValue() : util.shallowClone(defaultValue);
847
846
  },
848
847
  });
849
848
  }
@@ -856,7 +855,7 @@ function nonoptional(innerType, params) {
856
855
  return new exports.ZodMiniNonOptional({
857
856
  type: "nonoptional",
858
857
  innerType: innerType,
859
- ...index_js_1.util.normalizeParams(params),
858
+ ...util.normalizeParams(params),
860
859
  });
861
860
  }
862
861
  exports.ZodMiniSuccess = core.$constructor("ZodMiniSuccess", (inst, def) => {
@@ -936,7 +935,7 @@ function templateLiteral(parts, params) {
936
935
  return new exports.ZodMiniTemplateLiteral({
937
936
  type: "template_literal",
938
937
  parts,
939
- ...index_js_1.util.normalizeParams(params),
938
+ ...util.normalizeParams(params),
940
939
  });
941
940
  }
942
941
  exports.ZodMiniLazy = core.$constructor("ZodMiniLazy", (inst, def) => {
@@ -973,7 +972,7 @@ exports.ZodMiniCustom = core.$constructor("ZodMiniCustom", (inst, def) => {
973
972
  function check(fn, params) {
974
973
  const ch = new core.$ZodCheck({
975
974
  check: "custom",
976
- ...index_js_1.util.normalizeParams(params),
975
+ ...util.normalizeParams(params),
977
976
  });
978
977
  ch._zod.check = fn;
979
978
  return ch;
@@ -1,11 +1,10 @@
1
1
  import * as core from "../core/index.cjs";
2
- import { util } from "../core/index.cjs";
2
+ import * as util from "../core/util.cjs";
3
3
  type SomeType = core.SomeType;
4
4
  export interface ZodMiniType<out Output = unknown, out Input = unknown, out Internals extends core.$ZodTypeInternals<Output, Input> = core.$ZodTypeInternals<Output, Input>> extends core.$ZodType<Output, Input, Internals> {
5
5
  type: Internals["def"]["type"];
6
6
  check(...checks: (core.CheckFn<core.output<this>> | core.$ZodCheck<core.output<this>>)[]): this;
7
7
  with(...checks: (core.CheckFn<core.output<this>> | core.$ZodCheck<core.output<this>>)[]): this;
8
- refine<Ch extends (arg: core.output<this>) => unknown | Promise<unknown>>(check: Ch, params?: string | core.$ZodCustomParams): Ch extends (arg: any) => arg is infer R ? core.$ZodNarrow<this, R> : this;
9
8
  clone(def?: Internals["def"], params?: {
10
9
  parent: boolean;
11
10
  }): this;
@@ -1,11 +1,10 @@
1
1
  import * as core from "../core/index.js";
2
- import { util } from "../core/index.js";
2
+ import * as util from "../core/util.js";
3
3
  type SomeType = core.SomeType;
4
4
  export interface ZodMiniType<out Output = unknown, out Input = unknown, out Internals extends core.$ZodTypeInternals<Output, Input> = core.$ZodTypeInternals<Output, Input>> extends core.$ZodType<Output, Input, Internals> {
5
5
  type: Internals["def"]["type"];
6
6
  check(...checks: (core.CheckFn<core.output<this>> | core.$ZodCheck<core.output<this>>)[]): this;
7
7
  with(...checks: (core.CheckFn<core.output<this>> | core.$ZodCheck<core.output<this>>)[]): this;
8
- refine<Ch extends (arg: core.output<this>) => unknown | Promise<unknown>>(check: Ch, params?: string | core.$ZodCustomParams): Ch extends (arg: any) => arg is infer R ? core.$ZodNarrow<this, R> : this;
9
8
  clone(def?: Internals["def"], params?: {
10
9
  parent: boolean;
11
10
  }): this;
@@ -1,5 +1,5 @@
1
1
  import * as core from "../core/index.js";
2
- import { util } from "../core/index.js";
2
+ import * as util from "../core/util.js";
3
3
  import * as parse from "./parse.js";
4
4
  export const ZodMiniType = /*@__PURE__*/ core.$constructor("ZodMiniType", (inst, def) => {
5
5
  if (!inst._zod)
@@ -21,7 +21,6 @@ export const ZodMiniType = /*@__PURE__*/ core.$constructor("ZodMiniType", (inst,
21
21
  }, { parent: true });
22
22
  };
23
23
  inst.with = inst.check;
24
- inst.refine = (check, params) => inst.check(refine(check, params));
25
24
  inst.clone = (_def, params) => core.clone(inst, _def, params);
26
25
  inst.brand = () => inst;
27
26
  inst.register = ((reg, meta) => {
@@ -1,19 +0,0 @@
1
- import { describe, expectTypeOf, test } from "vitest";
2
- import type * as core from "../../core/index.js";
3
- import * as z from "../index.js";
4
-
5
- describe("type refinement with type guards", () => {
6
- test("type guard narrows output type", () => {
7
- const schema = z.string().refine((s): s is "a" => s === "a");
8
-
9
- expectTypeOf<core.input<typeof schema>>().toEqualTypeOf<string>();
10
- expectTypeOf<core.output<typeof schema>>().toEqualTypeOf<"a">();
11
- });
12
-
13
- test("non-type-guard refine does not narrow", () => {
14
- const schema = z.string().refine((s) => s.length > 0);
15
-
16
- expectTypeOf<core.input<typeof schema>>().toEqualTypeOf<string>();
17
- expectTypeOf<core.output<typeof schema>>().toEqualTypeOf<string>();
18
- });
19
- });