@es-joy/jsoe 0.26.1 → 0.27.0

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.
Files changed (124) hide show
  1. package/.gitignore +10 -0
  2. package/.npmignore +9 -0
  3. package/CHANGES.md +43 -0
  4. package/README.md +3 -3
  5. package/badges/coverage-badge.svg +1 -1
  6. package/dist/formats/schema.d.ts.map +1 -1
  7. package/dist/fundamentalTypes/arrayType.d.ts.map +1 -1
  8. package/dist/fundamentalTypes/stringType.d.ts.map +1 -1
  9. package/dist/index.js +2 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/typeChoices.d.ts.map +1 -1
  12. package/dist/types.d.ts.map +1 -1
  13. package/eslint.config.js +36 -27
  14. package/package.json +12 -11
  15. package/pnpm-workspace.yaml +3 -2
  16. package/src/formats/schema.js +35 -6
  17. package/src/fundamentalTypes/arrayType.js +30 -6
  18. package/src/fundamentalTypes/stringType.js +5 -0
  19. package/src/typeChoices.js +3 -1
  20. package/src/types.js +7 -0
  21. package/vendor/typeson-registry/dist/index.js +83 -10
  22. package/vendor/zod/classic/checks.d.ts +1 -1
  23. package/vendor/zod/classic/checks.js +1 -1
  24. package/vendor/zod/classic/external.d.ts +1 -1
  25. package/vendor/zod/classic/external.js +1 -1
  26. package/vendor/zod/classic/from-json-schema.js +245 -24
  27. package/vendor/zod/classic/schemas.d.ts +17 -1
  28. package/vendor/zod/classic/schemas.js +77 -29
  29. package/vendor/zod/core/api.d.ts +6 -4
  30. package/vendor/zod/core/api.js +17 -2
  31. package/vendor/zod/core/checks.d.ts +1 -1
  32. package/vendor/zod/core/checks.js +0 -96
  33. package/vendor/zod/core/compile.d.ts +18 -4
  34. package/vendor/zod/core/compile.js +146 -67
  35. package/vendor/zod/core/doc.js +7 -2
  36. package/vendor/zod/core/errors.js +2 -5
  37. package/vendor/zod/core/json-schema-generator.js +2 -2
  38. package/vendor/zod/core/json-schema-processors.d.ts +17 -0
  39. package/vendor/zod/core/json-schema-processors.js +195 -64
  40. package/vendor/zod/core/memoizer.js +72 -23
  41. package/vendor/zod/core/parse.js +37 -16
  42. package/vendor/zod/core/regexes.d.ts +2 -0
  43. package/vendor/zod/core/regexes.js +8 -4
  44. package/vendor/zod/core/schemas.d.ts +42 -7
  45. package/vendor/zod/core/schemas.js +301 -94
  46. package/vendor/zod/core/to-json-schema.d.ts +7 -3
  47. package/vendor/zod/core/to-json-schema.js +8 -7
  48. package/vendor/zod/core/util.d.ts +25 -4
  49. package/vendor/zod/core/util.js +160 -143
  50. package/vendor/zod/core/versions.d.ts +1 -1
  51. package/vendor/zod/core/versions.js +2 -2
  52. package/vendor/zod/core/visit.js +12 -0
  53. package/vendor/zod/locales/ar.js +1 -0
  54. package/vendor/zod/locales/az.js +1 -0
  55. package/vendor/zod/locales/be.js +1 -0
  56. package/vendor/zod/locales/bg.js +1 -0
  57. package/vendor/zod/locales/bn.js +1 -0
  58. package/vendor/zod/locales/ca.js +1 -0
  59. package/vendor/zod/locales/ckb.js +1 -0
  60. package/vendor/zod/locales/cs.js +1 -0
  61. package/vendor/zod/locales/da.js +1 -0
  62. package/vendor/zod/locales/de.js +1 -0
  63. package/vendor/zod/locales/el.js +1 -0
  64. package/vendor/zod/locales/en.js +1 -0
  65. package/vendor/zod/locales/eo.js +1 -0
  66. package/vendor/zod/locales/es.js +1 -0
  67. package/vendor/zod/locales/fa.js +1 -0
  68. package/vendor/zod/locales/fi.js +1 -0
  69. package/vendor/zod/locales/fr-CA.js +1 -0
  70. package/vendor/zod/locales/fr.js +1 -0
  71. package/vendor/zod/locales/gu.js +1 -0
  72. package/vendor/zod/locales/he.js +1 -0
  73. package/vendor/zod/locales/hi.js +1 -0
  74. package/vendor/zod/locales/hr.js +1 -0
  75. package/vendor/zod/locales/hu.js +1 -0
  76. package/vendor/zod/locales/hy.js +1 -0
  77. package/vendor/zod/locales/id.js +1 -0
  78. package/vendor/zod/locales/index.d.ts +1 -0
  79. package/vendor/zod/locales/index.js +1 -0
  80. package/vendor/zod/locales/is.js +1 -0
  81. package/vendor/zod/locales/it.js +1 -0
  82. package/vendor/zod/locales/ja.js +1 -0
  83. package/vendor/zod/locales/ka.js +1 -0
  84. package/vendor/zod/locales/km.js +1 -0
  85. package/vendor/zod/locales/kn.js +1 -0
  86. package/vendor/zod/locales/ko.js +1 -0
  87. package/vendor/zod/locales/lt.js +1 -0
  88. package/vendor/zod/locales/mk.js +1 -0
  89. package/vendor/zod/locales/ms.js +1 -0
  90. package/vendor/zod/locales/ne.js +1 -0
  91. package/vendor/zod/locales/nl.js +1 -0
  92. package/vendor/zod/locales/nn.js +1 -0
  93. package/vendor/zod/locales/no.js +1 -0
  94. package/vendor/zod/locales/ota.js +1 -0
  95. package/vendor/zod/locales/pl.js +1 -0
  96. package/vendor/zod/locales/ps.js +1 -0
  97. package/vendor/zod/locales/pt-BR.js +1 -0
  98. package/vendor/zod/locales/pt.js +1 -0
  99. package/vendor/zod/locales/ro.js +1 -0
  100. package/vendor/zod/locales/ru.js +1 -0
  101. package/vendor/zod/locales/sk.js +1 -0
  102. package/vendor/zod/locales/sl.js +1 -0
  103. package/vendor/zod/locales/sv.js +1 -0
  104. package/vendor/zod/locales/ta.js +1 -0
  105. package/vendor/zod/locales/tg.d.ts +4 -0
  106. package/vendor/zod/locales/tg.js +116 -0
  107. package/vendor/zod/locales/th.js +1 -0
  108. package/vendor/zod/locales/tk.js +1 -0
  109. package/vendor/zod/locales/tr.js +1 -0
  110. package/vendor/zod/locales/uk.js +1 -0
  111. package/vendor/zod/locales/ur.js +1 -0
  112. package/vendor/zod/locales/uz.js +1 -0
  113. package/vendor/zod/locales/vi.js +1 -0
  114. package/vendor/zod/locales/yo.js +1 -0
  115. package/vendor/zod/locales/zh-CN.js +1 -0
  116. package/vendor/zod/locales/zh-TW.js +1 -0
  117. package/vendor/zod/mini/checks.d.ts +1 -1
  118. package/vendor/zod/mini/checks.js +1 -1
  119. package/vendor/zod/mini/external.d.ts +1 -1
  120. package/vendor/zod/mini/external.js +1 -1
  121. package/vendor/zod/mini/schemas.d.ts +8 -0
  122. package/vendor/zod/mini/schemas.js +19 -2
  123. package/vendor/zodexy/dist/esm/index.js +34 -1
  124. package/vendor/zodexy/dist/schema.zodexy.json +18 -0
@@ -101,7 +101,7 @@ export interface ToJSONSchemaContext {
101
101
  * covers both passes in `finalize`: the ref flattening and the `$defs` build.
102
102
  *
103
103
  * The passes are valid only while nothing they read has changed, so both are cleared in
104
- * `process()` when the map grows, and in `JSONSchemaGenerator.emit()`, which can also change
104
+ * `processSchema()` when the map grows, and in `JSONSchemaGenerator.emit()`, which can also change
105
105
  * the `cycles` and `reused` they branch on.
106
106
  *
107
107
  * One case is deliberately not covered: an `override` callback that writes to
@@ -132,9 +132,14 @@ export declare function initializeContext(params: JSONSchemaGeneratorParams): To
132
132
  * custom JSON Schema was written into `json`, in which case the caller must not write its own.
133
133
  */
134
134
  export declare function handleUnrepresentable(schema: schemas.$ZodType, ctx: ToJSONSchemaContext, json: JSONSchema.BaseSchema, params: ProcessParams, message: string): boolean;
135
- export declare function process<T extends schemas.$ZodType>(schema: T, ctx: ToJSONSchemaContext, _params?: ProcessParams): JSONSchema.BaseSchema;
135
+ export declare function processSchema<T extends schemas.$ZodType>(schema: T, ctx: ToJSONSchemaContext, _params?: ProcessParams): JSONSchema.BaseSchema;
136
+ /** @deprecated Renamed to `processSchema`. An export alias declares no binding, so it is safe to keep. */
137
+ export { processSchema as process };
136
138
  export declare function extractDefs<T extends schemas.$ZodType>(ctx: ToJSONSchemaContext, schema: T): void;
137
139
  export declare function finalize<T extends schemas.$ZodType>(ctx: ToJSONSchemaContext, schema: T): ZodStandardJSONSchemaPayload<T>;
140
+ export declare function isTransforming(_schema: schemas.$ZodType, _ctx?: {
141
+ seen: Set<schemas.$ZodType>;
142
+ }): boolean;
138
143
  export type ZodStandardSchemaWithJSON<T> = StandardSchemaWithJSONProps<core.input<T>, core.output<T>>;
139
144
  export interface ZodStandardJSONSchemaPayload<T> extends JSONSchema.BaseSchema {
140
145
  "~standard": ZodStandardSchemaWithJSON<T>;
@@ -150,4 +155,3 @@ export declare const createToJSONSchemaMethod: <T extends schemas.$ZodType>(sche
150
155
  */
151
156
  type StandardJSONSchemaMethodParams = Parameters<StandardJSONSchemaV1["~standard"]["jsonSchema"]["input"]>[0];
152
157
  export declare const createStandardJSONSchemaMethod: <T extends schemas.$ZodType>(schema: T, io: "input" | "output", processors?: Record<string, Processor>) => (params?: StandardJSONSchemaMethodParams) => JSONSchema.BaseSchema;
153
- export {};
@@ -59,7 +59,8 @@ export function handleUnrepresentable(schema, ctx, json, params, message) {
59
59
  Object.assign(json, result);
60
60
  return true;
61
61
  }
62
- export function process(schema, ctx, _params = { path: [], schemaPath: [] }) {
62
+ // never rename this back to `process`: bundler polyfills inject a top-level `const process` that a lexical declaration of the same name collides with (#6397)
63
+ export function processSchema(schema, ctx, _params = { path: [], schemaPath: [] }) {
63
64
  var _a;
64
65
  const def = schema._zod.def;
65
66
  // check for schema in seens
@@ -105,7 +106,7 @@ export function process(schema, ctx, _params = { path: [], schemaPath: [] }) {
105
106
  // Also set ref if processor didn't (for inheritance)
106
107
  if (!result.ref)
107
108
  result.ref = parent;
108
- process(parent, ctx, params);
109
+ processSchema(parent, ctx, params);
109
110
  ctx.seen.get(parent).isParent = true;
110
111
  }
111
112
  }
@@ -126,6 +127,8 @@ export function process(schema, ctx, _params = { path: [], schemaPath: [] }) {
126
127
  const _result = ctx.seen.get(schema);
127
128
  return _result.schema;
128
129
  }
130
+ /** @deprecated Renamed to `processSchema`. An export alias declares no binding, so it is safe to keep. */
131
+ export { processSchema as process };
129
132
  // Escape a reference token for use in a JSON Pointer fragment (RFC 6901): `~` becomes `~0` and `/` becomes `~1`. The `~` replacement must run first.
130
133
  function encodeJSONPointerSegment(segment) {
131
134
  return segment.replace(/~/g, "~0").replace(/\//g, "~1");
@@ -242,8 +245,6 @@ export function extractDefs(ctx, schema
242
245
  if (seen.count > 1) {
243
246
  if (ctx.reused === "ref") {
244
247
  extractToDef(entry);
245
- // biome-ignore lint:
246
- continue;
247
248
  }
248
249
  }
249
250
  }
@@ -571,7 +572,7 @@ export function finalize(ctx, schema) {
571
572
  throw new Error("Error converting schema to JSON.");
572
573
  }
573
574
  }
574
- function isTransforming(_schema, _ctx) {
575
+ export function isTransforming(_schema, _ctx) {
575
576
  const ctx = _ctx ?? { seen: new Set() };
576
577
  if (ctx.seen.has(_schema))
577
578
  return false;
@@ -637,14 +638,14 @@ function isTransforming(_schema, _ctx) {
637
638
  */
638
639
  export const createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
639
640
  const ctx = initializeContext({ ...params, processors });
640
- process(schema, ctx);
641
+ processSchema(schema, ctx);
641
642
  extractDefs(ctx, schema);
642
643
  return finalize(ctx, schema);
643
644
  };
644
645
  export const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {
645
646
  const { libraryOptions, target } = params ?? {};
646
647
  const ctx = initializeContext({ ...(libraryOptions ?? {}), target, io, processors });
647
- process(schema, ctx);
648
+ processSchema(schema, ctx);
648
649
  extractDefs(ctx, schema);
649
650
  return finalize(ctx, schema);
650
651
  };
@@ -27,8 +27,13 @@ type ToZodKeyMismatch<Expected, Received> = schemas.$ZodType & {
27
27
  received: Received;
28
28
  };
29
29
  };
30
+ declare const toZodDummy: unique symbol;
31
+ type ToZodNormalize<T> = [T] extends [(...args: any[]) => any] ? T : [T] extends [object] ? {
32
+ [K in keyof T]: ToZodNormalize<T[K]>;
33
+ } : T | typeof toZodDummy;
34
+ type ToZodEqual<Output, T> = AssertEqual<Output, T> extends true ? true : IsAny<Output> extends true ? false : IsAny<T> extends true ? false : AssertEqual<ToZodNormalize<Output>, ToZodNormalize<T>>;
30
35
  type ToZodShape<Shape, T> = {
31
- [K in keyof Shape]: Shape[K] extends schemas.$ZodType ? K extends keyof T ? AssertEqual<Shape[K]["_zod"]["output"], T[K]> extends true ? Shape[K] : ToZodKeyMismatch<T[K], Shape[K]["_zod"]["output"]> : ToZodKeyMismatch<never, Shape[K]["_zod"]["output"]> : Shape[K];
36
+ [K in keyof Shape]: Shape[K] extends schemas.$ZodType ? K extends keyof T ? ToZodEqual<Shape[K]["_zod"]["output"], T[K]> extends true ? Shape[K] : ToZodKeyMismatch<T[K], Shape[K]["_zod"]["output"]> : ToZodKeyMismatch<never, Shape[K]["_zod"]["output"]> : Shape[K];
32
37
  } & {
33
38
  [K in Exclude<keyof T, keyof Shape>]: ToZodKeyMismatch<T[K], never>;
34
39
  };
@@ -44,6 +49,7 @@ export type MakeRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K
44
49
  export type Exactly<T, X> = T & Record<Exclude<keyof X, keyof T>, never>;
45
50
  export type NoUndefined<T> = T extends undefined ? never : T;
46
51
  export type Whatever = {} | undefined | null;
52
+ export type Widen<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T extends bigint ? bigint : T;
47
53
  export type LoosePartial<T extends object> = InexactPartial<T> & {
48
54
  [k: string]: unknown;
49
55
  };
@@ -131,7 +137,7 @@ export type PropValues = Record<string, Set<Primitive>>;
131
137
  export type PrimitiveSet = Set<Primitive>;
132
138
  export declare function assertEqual<A, B>(val: AssertEqual<A, B>): AssertEqual<A, B>;
133
139
  export declare function assertNotEqual<A, B>(val: AssertNotEqual<A, B>): AssertNotEqual<A, B>;
134
- export declare function toZod<T>(): <S extends schemas.$ZodType>(schema: AssertEqual<S["_zod"]["output"], T> extends true ? S : ToZodTarget<S, T>) => S;
140
+ export declare function toZod<T>(): <S extends schemas.$ZodType>(schema: ToZodEqual<S["_zod"]["output"], T> extends true ? S : ToZodTarget<S, T>) => S;
135
141
  export declare function assertIs<T>(_arg: T): void;
136
142
  export declare function assertNever(_x: never): never;
137
143
  export declare function assert<T>(_: any): asserts _ is T;
@@ -147,6 +153,17 @@ export declare function floatSafeRemainder(val: number, step: number): number;
147
153
  export declare function defineLazy<T, K extends keyof T>(object: T, key: K, getter: () => T[K]): void;
148
154
  export declare function objectClone(obj: object): any;
149
155
  export declare function assignProp<T extends object, K extends PropertyKey>(target: T, prop: K, value: K extends keyof T ? T[K] : any): void;
156
+ /** A def's `shape` accessor, carrying whichever object it currently answers from. */
157
+ export interface ShapeGetter {
158
+ (): Record<PropertyKey, any>;
159
+ raw: Record<PropertyKey, any>;
160
+ }
161
+ /**
162
+ * Whichever object a def's `shape` currently answers from: the one the caller passed until the first read, the frozen copy after it.
163
+ *
164
+ * Its keys and descriptors read without invoking anything, which is what lets a discriminated union check its discriminator, and the cycle walk read a shape, without resolving a getter that references the schema being constructed. A def that answers `shape` from an accessor of its own has none.
165
+ */
166
+ export declare function rawShape(def: any): Record<PropertyKey, any> | undefined;
150
167
  export declare function mergeDefs(...defs: Record<string, any>[]): any;
151
168
  export declare function cloneDef(schema: schemas.$ZodType): any;
152
169
  export declare function getElementAtPath(obj: any, path: (string | number)[] | null | undefined): any;
@@ -229,9 +246,13 @@ export declare abstract class Class {
229
246
  */
230
247
  export declare function members(proto: object, table: object): void;
231
248
  /** Shadows a prototype member with an own value, so a getter that builds from the instance runs once. */
232
- export declare function own<T>(inst: object, key: string, value: T, enumerable?: boolean): T;
249
+ export declare function own<T>(inst: object, key: PropertyKey, value: T, enumerable?: boolean): T;
233
250
  /** Like {@link own}, for a member that was never an own data property and has to stay out of `Object.keys`. */
234
- export declare function hide<T>(inst: object, key: string, value: T): T;
251
+ export declare function hide<T>(inst: object, key: PropertyKey, value: T): T;
252
+ /** Adds members a table derives from the instance: each builds on first read and shadows as own data, and assignment shadows the same way, as when these were own properties. */
253
+ export declare function derived<T>(computes: {
254
+ [K in keyof T]?: (inst: T) => T[K];
255
+ }, table: ProtoOf<T>): ProtoOf<T>;
235
256
  /** A trait's prototype members: a partial view of its own interface, with `this` typed as the instance. */
236
257
  export type ProtoOf<T> = {
237
258
  [K in keyof T]?: (T[K] extends (...args: infer A) => infer R ? (...args: A) => R : T[K]) | undefined;
@@ -29,18 +29,23 @@ export function jsonStringifyReplacer(_, value) {
29
29
  return value.toString();
30
30
  return value;
31
31
  }
32
+ // the accessor lives on a shared prototype: an own accessor makes every box a dictionary-mode object (~360 B and a slow load per read against ~100 B and an inlined getter here)
33
+ class Cached {
34
+ constructor(getter) {
35
+ this._getter = getter;
36
+ this._value = undefined;
37
+ }
38
+ get value() {
39
+ const getter = this._getter;
40
+ if (getter !== undefined) {
41
+ this._value = getter();
42
+ this._getter = undefined;
43
+ }
44
+ return this._value;
45
+ }
46
+ }
32
47
  export function cached(getter) {
33
- const set = false;
34
- return {
35
- get value() {
36
- if (!set) {
37
- const value = getter();
38
- Object.defineProperty(this, "value", { value });
39
- return value;
40
- }
41
- throw new Error("cached value already set");
42
- },
43
- };
48
+ return new Cached(getter);
44
49
  }
45
50
  export function nullish(input) {
46
51
  return input === null || input === undefined;
@@ -95,6 +100,71 @@ export function assignProp(target, prop, value) {
95
100
  configurable: true,
96
101
  });
97
102
  }
103
+ /**
104
+ * Whichever object a def's `shape` currently answers from: the one the caller passed until the first read, the frozen copy after it.
105
+ *
106
+ * Its keys and descriptors read without invoking anything, which is what lets a discriminated union check its discriminator, and the cycle walk read a shape, without resolving a getter that references the schema being constructed. A def that answers `shape` from an accessor of its own has none.
107
+ */
108
+ export function rawShape(def) {
109
+ const desc = Object.getOwnPropertyDescriptor(def, "shape");
110
+ return desc?.get ? desc.get.raw : desc?.value;
111
+ }
112
+ // where a builder reads its source's keys and descriptors, resolving only a shape a def answers for itself. A shape resolves by object spread, so only its enumerable keys are ever part of it.
113
+ function sourceShape(schema) {
114
+ return rawShape(schema._zod.def) ?? schema._zod.def.shape;
115
+ }
116
+ // a key whose value is not settled yet, self-caching so every read after the first gets the same one
117
+ function deferProp(target, key, getter) {
118
+ Object.defineProperty(target, key, {
119
+ get() {
120
+ const value = getter();
121
+ assignProp(this, key, value);
122
+ return value;
123
+ },
124
+ enumerable: true,
125
+ configurable: true,
126
+ });
127
+ }
128
+ // Writes a settled key. A plain assignment is much cheaper than `defineProperty` and produces the same descriptor, but it runs whatever setter already answers to the key — an accessor this shape deferred, or an inherited one, which `__proto__` has on every object and prototype pollution can add for any name.
129
+ function putProp(target, key, value) {
130
+ if (key in target)
131
+ assignProp(target, key, value);
132
+ else
133
+ target[key] = value;
134
+ }
135
+ /**
136
+ * Copies `keys` of `source`'s shape onto `target`, each value passed through `wrap`.
137
+ *
138
+ * A key the source has resolved is copied through now, so the derived shape states it outright and nothing has to resolve it to learn what it holds. A key the source still defers stays deferred, and reads back through the source's own `shape`, so it resolves once and both shapes get that one schema.
139
+ */
140
+ function mirrorShape(target, source, keys, wrap) {
141
+ const raw = sourceShape(source);
142
+ for (const key of keys) {
143
+ const desc = Object.getOwnPropertyDescriptor(raw, key);
144
+ if (!desc.enumerable)
145
+ continue;
146
+ if (desc.get) {
147
+ deferProp(target, key, () => {
148
+ const value = source._zod.def.shape[key];
149
+ return wrap ? wrap(value, key) : value;
150
+ });
151
+ }
152
+ else
153
+ putProp(target, key, wrap ? wrap(desc.value, key) : desc.value);
154
+ }
155
+ }
156
+ // same, for a plain shape a caller passed rather than a schema's
157
+ function mirrorProps(target, source) {
158
+ for (const key of Reflect.ownKeys(source)) {
159
+ const desc = Object.getOwnPropertyDescriptor(source, key);
160
+ if (!desc.enumerable)
161
+ continue;
162
+ if (desc.get)
163
+ deferProp(target, key, () => source[key]);
164
+ else
165
+ putProp(target, key, desc.value);
166
+ }
167
+ }
98
168
  export function mergeDefs(...defs) {
99
169
  const mergedDescriptors = {};
100
170
  for (const def of defs) {
@@ -346,24 +416,23 @@ export function pick(schema, mask) {
346
416
  if (hasChecks) {
347
417
  throw new Error(".pick() cannot be used on object schemas containing refinements");
348
418
  }
349
- const def = mergeDefs(schema._zod.def, {
350
- get shape() {
351
- const newShape = {};
352
- // `for...in` skips symbols, so a symbol in the mask would select nothing
353
- for (const key of Reflect.ownKeys(mask)) {
354
- if (!Object.prototype.hasOwnProperty.call(currDef.shape, key)) {
355
- throw new Error(`Unrecognized key: "${String(key)}"`);
356
- }
357
- if (!mask[key])
358
- continue;
359
- assignProp(newShape, key, currDef.shape[key]);
360
- }
361
- assignProp(this, "shape", newShape); // self-caching
362
- return newShape;
363
- },
364
- checks: [],
365
- });
366
- return clone(schema, def);
419
+ const newShape = {};
420
+ mirrorShape(newShape, schema, maskedKeys(schema, mask));
421
+ return clone(schema, mergeDefs(currDef, { shape: newShape, checks: [] }));
422
+ }
423
+ // the mask keys that select something, checked against the source's shape without resolving it
424
+ function maskedKeys(schema, mask) {
425
+ const raw = sourceShape(schema);
426
+ const keys = [];
427
+ // `for...in` skips symbols, so a symbol in the mask would select nothing
428
+ for (const key of Reflect.ownKeys(mask)) {
429
+ if (!Object.getOwnPropertyDescriptor(raw, key)?.enumerable) {
430
+ throw new Error(`Unrecognized key: "${String(key)}"`);
431
+ }
432
+ if (mask[key])
433
+ keys.push(key);
434
+ }
435
+ return keys;
367
436
  }
368
437
  export function omit(schema, mask) {
369
438
  const currDef = schema._zod.def;
@@ -372,23 +441,10 @@ export function omit(schema, mask) {
372
441
  if (hasChecks) {
373
442
  throw new Error(".omit() cannot be used on object schemas containing refinements");
374
443
  }
375
- const def = mergeDefs(schema._zod.def, {
376
- get shape() {
377
- const newShape = { ...schema._zod.def.shape };
378
- for (const key of Reflect.ownKeys(mask)) {
379
- if (!Object.prototype.hasOwnProperty.call(currDef.shape, key)) {
380
- throw new Error(`Unrecognized key: "${String(key)}"`);
381
- }
382
- if (!mask[key])
383
- continue;
384
- delete newShape[key];
385
- }
386
- assignProp(this, "shape", newShape); // self-caching
387
- return newShape;
388
- },
389
- checks: [],
390
- });
391
- return clone(schema, def);
444
+ const omitted = new Set(maskedKeys(schema, mask));
445
+ const newShape = {};
446
+ mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)).filter((key) => !omitted.has(key)));
447
+ return clone(schema, mergeDefs(currDef, { shape: newShape, checks: [] }));
392
448
  }
393
449
  export function extend(schema, shape) {
394
450
  if (!isPlainObject(shape)) {
@@ -398,34 +454,27 @@ export function extend(schema, shape) {
398
454
  const hasChecks = checks && checks.length > 0;
399
455
  if (hasChecks) {
400
456
  // Only throw if new shape overlaps with existing shape. Use getOwnPropertyDescriptor to check key existence without accessing values
401
- const existingShape = schema._zod.def.shape;
457
+ const existingShape = sourceShape(schema);
402
458
  for (const key of Reflect.ownKeys(shape)) {
403
459
  if (Object.getOwnPropertyDescriptor(existingShape, key) !== undefined) {
404
460
  throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.");
405
461
  }
406
462
  }
407
463
  }
408
- const def = mergeDefs(schema._zod.def, {
409
- get shape() {
410
- const _shape = { ...schema._zod.def.shape, ...shape };
411
- assignProp(this, "shape", _shape); // self-caching
412
- return _shape;
413
- },
414
- });
415
- return clone(schema, def);
464
+ return clone(schema, mergeDefs(schema._zod.def, { shape: extended(schema, shape) }));
465
+ }
466
+ // the source's keys, then the caller's overlaid on top
467
+ function extended(schema, shape) {
468
+ const newShape = {};
469
+ mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)));
470
+ mirrorProps(newShape, shape);
471
+ return newShape;
416
472
  }
417
473
  export function safeExtend(schema, shape) {
418
474
  if (!isPlainObject(shape)) {
419
475
  throw new Error("Invalid input to safeExtend: expected a plain object");
420
476
  }
421
- const def = mergeDefs(schema._zod.def, {
422
- get shape() {
423
- const _shape = { ...schema._zod.def.shape, ...shape };
424
- assignProp(this, "shape", _shape); // self-caching
425
- return _shape;
426
- },
427
- });
428
- return clone(schema, def);
477
+ return clone(schema, mergeDefs(schema._zod.def, { shape: extended(schema, shape) }));
429
478
  }
430
479
  export function merge(a, b) {
431
480
  if (!b?._zod?.def) {
@@ -434,12 +483,11 @@ export function merge(a, b) {
434
483
  if (a._zod.def.checks?.length) {
435
484
  throw new Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");
436
485
  }
486
+ const newShape = {};
487
+ mirrorShape(newShape, a, Reflect.ownKeys(sourceShape(a)));
488
+ mirrorShape(newShape, b, Reflect.ownKeys(sourceShape(b)));
437
489
  const def = mergeDefs(a._zod.def, {
438
- get shape() {
439
- const _shape = { ...a._zod.def.shape, ...b._zod.def.shape };
440
- assignProp(this, "shape", _shape); // self-caching
441
- return _shape;
442
- },
490
+ shape: newShape,
443
491
  get catchall() {
444
492
  return b._zod.def.catchall;
445
493
  },
@@ -454,78 +502,19 @@ export function partial(Class, schema, mask, name = "partial") {
454
502
  if (hasChecks) {
455
503
  throw new Error(`.${name}() cannot be used on object schemas containing refinements`);
456
504
  }
457
- const def = mergeDefs(schema._zod.def, {
458
- get shape() {
459
- const oldShape = schema._zod.def.shape;
460
- const shape = { ...oldShape };
461
- if (mask) {
462
- for (const key of Reflect.ownKeys(mask)) {
463
- if (!Object.prototype.hasOwnProperty.call(oldShape, key)) {
464
- throw new Error(`Unrecognized key: "${String(key)}"`);
465
- }
466
- if (!mask[key])
467
- continue;
468
- // if (oldShape[key]!._zod.optin === "optional") continue;
469
- shape[key] = Class
470
- ? new Class({
471
- type: "optional",
472
- innerType: oldShape[key],
473
- })
474
- : oldShape[key];
475
- }
476
- }
477
- else {
478
- // the spread copies symbol keys; `for...in` would not reach them
479
- for (const key of Reflect.ownKeys(oldShape)) {
480
- // if (oldShape[key]!._zod.optin === "optional") continue;
481
- shape[key] = Class
482
- ? new Class({
483
- type: "optional",
484
- innerType: oldShape[key],
485
- })
486
- : oldShape[key];
487
- }
488
- }
489
- assignProp(this, "shape", shape); // self-caching
490
- return shape;
491
- },
492
- checks: [],
493
- });
494
- return clone(schema, def);
505
+ const selected = mask ? new Set(maskedKeys(schema, mask)) : undefined;
506
+ const newShape = {};
507
+ mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)), Class &&
508
+ ((value, key) => (selected && !selected.has(key) ? value : new Class({ type: "optional", innerType: value }))));
509
+ return clone(schema, mergeDefs(schema._zod.def, { shape: newShape, checks: [] }));
495
510
  }
496
511
  export function required(Class, schema, mask) {
497
- const def = mergeDefs(schema._zod.def, {
498
- get shape() {
499
- const oldShape = schema._zod.def.shape;
500
- const shape = { ...oldShape };
501
- if (mask) {
502
- for (const key of Reflect.ownKeys(mask)) {
503
- if (!Object.prototype.hasOwnProperty.call(shape, key)) {
504
- throw new Error(`Unrecognized key: "${String(key)}"`);
505
- }
506
- if (!mask[key])
507
- continue;
508
- // overwrite with non-optional
509
- shape[key] = new Class({
510
- type: "nonoptional",
511
- innerType: oldShape[key],
512
- });
513
- }
514
- }
515
- else {
516
- for (const key of Reflect.ownKeys(oldShape)) {
517
- // overwrite with non-optional
518
- shape[key] = new Class({
519
- type: "nonoptional",
520
- innerType: oldShape[key],
521
- });
522
- }
523
- }
524
- assignProp(this, "shape", shape); // self-caching
525
- return shape;
526
- },
527
- });
528
- return clone(schema, def);
512
+ const selected = mask ? new Set(maskedKeys(schema, mask)) : undefined;
513
+ const newShape = {};
514
+ mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)), (value, key) =>
515
+ // overwrite with non-optional
516
+ selected && !selected.has(key) ? value : new Class({ type: "nonoptional", innerType: value }));
517
+ return clone(schema, mergeDefs(schema._zod.def, { shape: newShape }));
529
518
  }
530
519
  // invalid_type | too_big | too_small | invalid_format | not_multiple_of | unrecognized_keys | invalid_union | invalid_key | invalid_element | invalid_value | custom
531
520
  export function aborted(x, startIndex = 0) {
@@ -587,13 +576,19 @@ export function finalizeIssue(iss, ctx, config) {
587
576
  unwrapMessage(config.customError?.(iss)) ??
588
577
  unwrapMessage(config.localeError?.(iss)) ??
589
578
  "Invalid input");
590
- const { inst: _inst, schema: _schema, continue: _continue, input: _input, ...rest } = iss;
591
- rest.path ?? (rest.path = []);
592
- rest.message = message;
579
+ // an explicit own-key copy beats object rest with excluded keys, which v8 routes through a generic runtime call; Object.keys rather than for-in so an issue pushed with a prototype does not leak inherited keys, and an own __proto__ key is dropped rather than assigned through the setter
580
+ const full = {};
581
+ for (const k of Object.keys(iss)) {
582
+ if (k === "inst" || k === "schema" || k === "continue" || k === "input" || k === "__proto__")
583
+ continue;
584
+ full[k] = iss[k];
585
+ }
586
+ full.path ?? (full.path = []);
587
+ full.message = message;
593
588
  if (ctx?.reportInput) {
594
- rest.input = _input;
589
+ full.input = iss.input;
595
590
  }
596
- return rest;
591
+ return full;
597
592
  }
598
593
  export function getSizableOrigin(input) {
599
594
  if (input instanceof Set)
@@ -730,6 +725,10 @@ export function members(proto, table) {
730
725
  else
731
726
  defineBound(proto, key, desc.value);
732
727
  }
728
+ // for..in sees no symbol keys, so well-known members like Symbol.iterator install here
729
+ for (const sym of Object.getOwnPropertySymbols(table)) {
730
+ defineBound(proto, sym, table[sym]);
731
+ }
733
732
  }
734
733
  /** Shadows a prototype member with an own value, so a getter that builds from the instance runs once. */
735
734
  export function own(inst, key, value, enumerable = true) {
@@ -740,6 +739,24 @@ export function own(inst, key, value, enumerable = true) {
740
739
  export function hide(inst, key, value) {
741
740
  return own(inst, key, value, false);
742
741
  }
742
+ /** Adds members a table derives from the instance: each builds on first read and shadows as own data, and assignment shadows the same way, as when these were own properties. */
743
+ export /*@__NO_SIDE_EFFECTS__*/ function derived(computes, table) {
744
+ for (const key in computes) {
745
+ const compute = computes[key];
746
+ // an object literal's accessor is configurable and enumerable, and `members` copies the descriptor as written
747
+ Object.defineProperty(table, key, {
748
+ configurable: true,
749
+ enumerable: true,
750
+ get() {
751
+ return own(this, key, compute(this));
752
+ },
753
+ set(value) {
754
+ own(this, key, value);
755
+ },
756
+ });
757
+ }
758
+ return table;
759
+ }
743
760
  function defineBound(proto, key, fn) {
744
761
  Object.defineProperty(proto, key, {
745
762
  configurable: true,
@@ -1,5 +1,5 @@
1
1
  export declare const version: {
2
2
  readonly major: 4;
3
- readonly minor: 5;
3
+ readonly minor: 6;
4
4
  readonly patch: number;
5
5
  };
@@ -1,5 +1,5 @@
1
1
  export const version = {
2
2
  major: 4,
3
- minor: 5,
4
- patch: 4,
3
+ minor: 6,
4
+ patch: 1,
5
5
  };
@@ -135,6 +135,18 @@ export function visit(schema, fnOrHandlers) {
135
135
  const { _cachedInner, ...rest } = def;
136
136
  return clone(s, { ...rest, getter: () => run(original()) });
137
137
  }
138
+ case "properties": {
139
+ const oldShape = def.shape;
140
+ let changed = false;
141
+ const newShape = {};
142
+ for (const k of Reflect.ownKeys(oldShape)) {
143
+ const mapped = run(oldShape[k]);
144
+ if (mapped !== oldShape[k])
145
+ changed = true;
146
+ newShape[k] = mapped;
147
+ }
148
+ return changed ? clone(s, { ...def, shape: newShape }) : s;
149
+ }
138
150
  // A leaf by choice: `parts` are regex fragments, not data positions.
139
151
  case "template_literal":
140
152
  // Leaves.
@@ -39,6 +39,7 @@ const error = () => {
39
39
  json_string: "نَص على هيئة JSON",
40
40
  e164: "رقم هاتف بمعيار E.164",
41
41
  credit_card: "رقم بطاقة الائتمان",
42
+ iban: "IBAN",
42
43
  jwt: "JWT",
43
44
  template_literal: "مدخل",
44
45
  };
@@ -39,6 +39,7 @@ const error = () => {
39
39
  json_string: "JSON string",
40
40
  e164: "E.164 number",
41
41
  credit_card: "kredit kartı nömrəsi",
42
+ iban: "IBAN",
42
43
  jwt: "JWT",
43
44
  template_literal: "input",
44
45
  };
@@ -89,6 +89,7 @@ const error = () => {
89
89
  json_string: "JSON радок",
90
90
  e164: "нумар E.164",
91
91
  credit_card: "нумар крэдытнай карты",
92
+ iban: "IBAN",
92
93
  jwt: "JWT",
93
94
  template_literal: "увод",
94
95
  };
@@ -39,6 +39,7 @@ const error = () => {
39
39
  json_string: "JSON низ",
40
40
  e164: "E.164 номер",
41
41
  credit_card: "номер на кредитна карта",
42
+ iban: "IBAN",
42
43
  jwt: "JWT",
43
44
  template_literal: "вход",
44
45
  };
@@ -39,6 +39,7 @@ const error = () => {
39
39
  json_string: "JSON স্ট্রিং",
40
40
  e164: "E.164 নম্বর",
41
41
  credit_card: "ক্রেডিট কার্ড নম্বর",
42
+ iban: "IBAN",
42
43
  jwt: "JWT",
43
44
  template_literal: "ইনপুট",
44
45
  };
@@ -39,6 +39,7 @@ const error = () => {
39
39
  json_string: "cadena JSON",
40
40
  e164: "número E.164",
41
41
  credit_card: "número de targeta de crèdit",
42
+ iban: "IBAN",
42
43
  jwt: "JWT",
43
44
  template_literal: "entrada",
44
45
  };
@@ -39,6 +39,7 @@ const error = () => {
39
39
  json_string: "دەقی JSON",
40
40
  e164: "ژمارەی E.164",
41
41
  credit_card: "ژمارەی کارتی کرێدیت",
42
+ iban: "IBAN",
42
43
  jwt: "JWT",
43
44
  template_literal: "تێکردە",
44
45
  };
@@ -39,6 +39,7 @@ const error = () => {
39
39
  json_string: "řetězec ve formátu JSON",
40
40
  e164: "číslo E.164",
41
41
  credit_card: "číslo kreditní karty",
42
+ iban: "IBAN",
42
43
  jwt: "JWT",
43
44
  template_literal: "vstup",
44
45
  };