@wildo-ai/zod-decorators 1.1.11 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/commons.d.ts.map +1 -1
- package/dist/esm/commons.js.map +1 -1
- package/dist/esm/currencies.shared.schemas.d.ts.map +1 -1
- package/dist/esm/currencies.shared.schemas.js.map +1 -1
- package/dist/esm/files/agent-file-formats.d.ts.map +1 -1
- package/dist/esm/files/agent-file-formats.js.map +1 -1
- package/dist/esm/files/extension-nature-map.d.ts.map +1 -1
- package/dist/esm/files/extension-nature-map.js.map +1 -1
- package/dist/esm/files/file-extensions.enum.d.ts.map +1 -1
- package/dist/esm/files/file-extensions.enum.js.map +1 -1
- package/dist/esm/files/mime-registry.d.ts.map +1 -1
- package/dist/esm/files/mime-registry.js.map +1 -1
- package/dist/esm/files/unified-registry.d.ts.map +1 -1
- package/dist/esm/files/unified-registry.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/install-bigint-json-encoding.d.ts +1 -1
- package/dist/esm/install-bigint-json-encoding.d.ts.map +1 -1
- package/dist/esm/install-bigint-json-encoding.js +1 -1
- package/dist/esm/install-bigint-json-encoding.js.map +1 -1
- package/dist/esm/testing/decorated-test-schemas.d.ts +7 -7
- package/dist/esm/testing/decorated-test-schemas.d.ts.map +1 -1
- package/dist/esm/testing/decorated-test-schemas.js.map +1 -1
- package/dist/esm/testing.d.ts.map +1 -1
- package/dist/esm/testing.js.map +1 -1
- package/dist/esm/zod-address.d.ts.map +1 -1
- package/dist/esm/zod-address.js.map +1 -1
- package/dist/esm/zod-bigdecimal.d.ts +4 -4
- package/dist/esm/zod-bigdecimal.d.ts.map +1 -1
- package/dist/esm/zod-bigdecimal.js.map +1 -1
- package/dist/esm/zod-code.d.ts +4 -4
- package/dist/esm/zod-code.d.ts.map +1 -1
- package/dist/esm/zod-code.js.map +1 -1
- package/dist/esm/zod-color.d.ts.map +1 -1
- package/dist/esm/zod-color.js.map +1 -1
- package/dist/esm/zod-decorators.types.d.ts +116 -9
- package/dist/esm/zod-decorators.types.d.ts.map +1 -1
- package/dist/esm/zod-decorators.types.js +40 -1
- package/dist/esm/zod-decorators.types.js.map +1 -1
- package/dist/esm/zod-document-sequence.d.ts.map +1 -1
- package/dist/esm/zod-document-sequence.js.map +1 -1
- package/dist/esm/zod-duration.d.ts +6 -6
- package/dist/esm/zod-duration.d.ts.map +1 -1
- package/dist/esm/zod-duration.js.map +1 -1
- package/dist/esm/zod-file.d.ts +5 -4
- package/dist/esm/zod-file.d.ts.map +1 -1
- package/dist/esm/zod-file.js +1 -1
- package/dist/esm/zod-file.js.map +1 -1
- package/dist/esm/zod-money.d.ts +4 -4
- package/dist/esm/zod-money.d.ts.map +1 -1
- package/dist/esm/zod-money.js.map +1 -1
- package/dist/esm/zod-phone.d.ts +4 -4
- package/dist/esm/zod-phone.d.ts.map +1 -1
- package/dist/esm/zod-phone.js.map +1 -1
- package/dist/esm/zod-range.d.ts.map +1 -1
- package/dist/esm/zod-range.js.map +1 -1
- package/dist/esm/zod-utils.shared.d.ts +47 -12
- package/dist/esm/zod-utils.shared.d.ts.map +1 -1
- package/dist/esm/zod-utils.shared.js +143 -40
- package/dist/esm/zod-utils.shared.js.map +1 -1
- package/dist/esm/zod-versioned.d.ts.map +1 -1
- package/dist/esm/zod-versioned.js.map +1 -1
- package/dist/esm/zod-wire-date.d.ts +107 -0
- package/dist/esm/zod-wire-date.d.ts.map +1 -0
- package/dist/esm/zod-wire-date.js +162 -0
- package/dist/esm/zod-wire-date.js.map +1 -0
- package/dist/esm/zod-year-month.d.ts +76 -0
- package/dist/esm/zod-year-month.d.ts.map +1 -0
- package/dist/esm/zod-year-month.js +115 -0
- package/dist/esm/zod-year-month.js.map +1 -0
- package/dist/esm/zod.module-override.d.ts +139 -156
- package/dist/esm/zod.module-override.d.ts.map +1 -1
- package/dist/esm/zod.module-override.js +176 -6
- package/dist/esm/zod.module-override.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -5
|
@@ -77,7 +77,8 @@ export const ZodDecorator_ApplyableType = {
|
|
|
77
77
|
// • ZodBigInt × 16 — see its prototype block; every other layer already treats bigint as a leaf.
|
|
78
78
|
// • ZodObject `isDBIndexed`/`isHidden`/`isNotEditable` — a composite field is indexable,
|
|
79
79
|
// hideable and non-editable. The TS2320 clash with `z_file()`'s mixin was the only obstacle
|
|
80
|
-
// and it cost nothing to remove
|
|
80
|
+
// and it cost nothing to remove: a decorator returns `this`, which for `z_file()` is its own
|
|
81
|
+
// interface, so the members it adds are kept.
|
|
81
82
|
// • `isBusinessKey` on ZodBoolean/ZodDate — the map says it mirrors IS_DB_INDEXED's primitive
|
|
82
83
|
// set, and that IS on both. A date is a legitimate natural-key component.
|
|
83
84
|
// • ZodOptional `ttl`/`isPassword`/`isOtp`/`isColor`/`businessKeySet` — natural authoring
|
|
@@ -129,6 +130,7 @@ export const ZodDecorator_ApplyableType = {
|
|
|
129
130
|
// The list/FunctionType/prototype-install/`declare module` augmentations are ONE unit here too.
|
|
130
131
|
[ZodDecorator.IS_LAST_ACTION_RECORD]: ApplyableTypeAllTypes,
|
|
131
132
|
[ZodDecorator.IS_DECIDER]: ApplyableTypeAllTypes,
|
|
133
|
+
[ZodDecorator.IS_ROLE_GRANT]: ApplyableTypeAllTypes,
|
|
132
134
|
// RAG source — deliberately NOT all-types: only TEXT can be a retrieval-corpus source, so the
|
|
133
135
|
// fluent surface is string-backed (plus the wrappers a string field routinely lives under; the
|
|
134
136
|
// string-FORMAT types get the method from the `ZodStringFormat.prototype` install, which — per the
|
|
@@ -170,6 +172,9 @@ export const ZodDecorator_ApplyableType = {
|
|
|
170
172
|
// Every wrapper that can hold an object and whose inner shape `findObjectShape` can reach —
|
|
171
173
|
// Optional, Nullable and Default all already carry the method at runtime via the wrapper loop.
|
|
172
174
|
[ZodDecorator.OBJECT_BUSINESS_KEY_SET]: ['ZodObject', 'ZodOptional', 'ZodNullable', 'ZodDefault'],
|
|
175
|
+
// A compound index names fields of the object it decorates, so it applies to an object with a shape, and only to
|
|
176
|
+
// one: an index belongs to a stored row, and a resource's main schema is always a plain object.
|
|
177
|
+
[ZodDecorator.OBJECT_COMPOUND_INDEX]: ['ZodObject'],
|
|
173
178
|
// A resource reference names its two members, so it applies to an object with a shape, and only to one.
|
|
174
179
|
[ZodDecorator.RESOURCE_REFERENCE]: ['ZodObject'],
|
|
175
180
|
// TTL (Time To Live) - only for Date fields (MongoDB TTL indexes work on Date fields)
|
|
@@ -277,6 +282,7 @@ const STRING_SCHEMA_DECORATOR_SURFACE = [
|
|
|
277
282
|
ZodDecorator.IS_AUDIT_EVIDENCE,
|
|
278
283
|
ZodDecorator.IS_LAST_ACTION_RECORD,
|
|
279
284
|
ZodDecorator.IS_DECIDER,
|
|
285
|
+
ZodDecorator.IS_ROLE_GRANT,
|
|
280
286
|
// RAG source — string-backed by nature (only text can be a corpus source), and a format validator
|
|
281
287
|
// is a legitimate carrier: markdown/documentation fields are routinely `z.string()`, but a
|
|
282
288
|
// `z.url()` pointing at authored content is not excluded from being chunked as text.
|
|
@@ -487,6 +493,25 @@ export const ZodDecorator_FunctionType = {
|
|
|
487
493
|
},
|
|
488
494
|
]);
|
|
489
495
|
},
|
|
496
|
+
// compoundIndex (#3142): one more NON-unique index over several fields of this object. Validated at decoration time,
|
|
497
|
+
// like businessKeySet, so an index cannot name a field the row does not carry; storage would otherwise build an index
|
|
498
|
+
// over a path that is always empty, or the SQL plan would refuse at migration time, far from the declaration.
|
|
499
|
+
compoundIndex: function (fields) {
|
|
500
|
+
if (!Array.isArray(fields) || fields.length < 2) {
|
|
501
|
+
throw new Error(`compoundIndex([...]) needs at least two field names (received ${JSON.stringify(fields)}); a one-field index is .isDBIndexed() on the field.`);
|
|
502
|
+
}
|
|
503
|
+
const repeated = fields.filter((field, index) => fields.indexOf(field) !== index);
|
|
504
|
+
if (repeated.length > 0) {
|
|
505
|
+
throw new Error(`compoundIndex([...]) names a field more than once: ${[...new Set(repeated)].join(', ')}.`);
|
|
506
|
+
}
|
|
507
|
+
const node = this;
|
|
508
|
+
const shape = node.shape ?? node._zod?.def?.shape;
|
|
509
|
+
const missing = fields.filter((field) => !shape || !(field in shape));
|
|
510
|
+
if (missing.length > 0) {
|
|
511
|
+
throw new Error(`compoundIndex([...]) references field(s) not present in the schema shape: ${missing.join(', ')}.`);
|
|
512
|
+
}
|
|
513
|
+
return addDecorators(this, [{ ref: ZodDecorator.OBJECT_COMPOUND_INDEX, params: { fields: [...fields] } }]);
|
|
514
|
+
},
|
|
490
515
|
// isResourceReference (#2471): the object names one row of a resource chosen at run time. Validated at decoration
|
|
491
516
|
// time, like businessKeySet: the object must HAVE the two members the reference is read through, or a form would
|
|
492
517
|
// offer a picker that writes into fields the schema does not carry.
|
|
@@ -526,6 +551,7 @@ export const ZodDecorator_FunctionType = {
|
|
|
526
551
|
// Last-action record — a PURE parameterless marker, like isAuditEvidence: it implies no other decorator.
|
|
527
552
|
isLastActionRecord: function () { return addDecorators(this, [ZodDecorator.IS_LAST_ACTION_RECORD]); },
|
|
528
553
|
isDecider: function () { return addDecorators(this, [ZodDecorator.IS_DECIDER]); },
|
|
554
|
+
isRoleGrant: function () { return addDecorators(this, [ZodDecorator.IS_ROLE_GRANT]); },
|
|
529
555
|
// RAG source (resource-native RAG capability). The config is OPTIONAL — a bare `.ragSource()` is a
|
|
530
556
|
// complete declaration — so unlike impersonalizeWith there is no required-value door to guard;
|
|
531
557
|
// what the shared `applySingleDecorator` chokepoint enforces instead is config validity
|
|
@@ -1238,6 +1264,48 @@ function assertCalendarDateNotDateTime(decorator, currentMetadata) {
|
|
|
1238
1264
|
'Declare a day with isCalendarDate() (and dateUI() for its display), or a moment with dateTimeUI().');
|
|
1239
1265
|
}
|
|
1240
1266
|
}
|
|
1267
|
+
/**
|
|
1268
|
+
* The decorators that mark a value as a SECRET, each with the reason a subject-disclosed backend-only field
|
|
1269
|
+
* (`isBackendOnly({ disclosedToSubject: true })`, #2958) may never carry it. One table, consulted in both application
|
|
1270
|
+
* orders by {@link assertSubjectDisclosureAdmissible}, at the same chokepoint as the RAG-source pairs, so no door into the
|
|
1271
|
+
* metadata bypasses it.
|
|
1272
|
+
*/
|
|
1273
|
+
const SUBJECT_DISCLOSURE_REFUSED_COMPANIONS = new Map([
|
|
1274
|
+
[ZodDecorator.IS_PASSWORD, 'a password never leaves the backend, not even to the person it belongs to.'],
|
|
1275
|
+
[ZodDecorator.IS_OTP, 'a one-time code never leaves the backend once it was sent.'],
|
|
1276
|
+
[ZodDecorator.IS_WRITE_ONLY_SECRET, 'a write-only secret is masked on every response, so it is not disclosed to anyone.'],
|
|
1277
|
+
[ZodDecorator.IS_EPHEMERAL, 'an ephemeral value is shown once, when it is minted, and never again.'],
|
|
1278
|
+
]);
|
|
1279
|
+
/** Whether a stored `IS_BACKEND_ONLY` value declares the subject-disclosure opt-in. */
|
|
1280
|
+
function declaresDisclosedToSubject(value) {
|
|
1281
|
+
return typeof value === 'object' && value !== null && value.disclosedToSubject === true;
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* Refuse `isBackendOnly({ disclosedToSubject: true })` on a field that holds a secret, in either order (#2958): applied to
|
|
1285
|
+
* a field already marked a secret, applied with `isReturnedAtCreation` (a server-minted secret shown once), or a secret
|
|
1286
|
+
* marker applied to a field already opted in. Run after an updater is resolved, so an updater that adds the opt-in is
|
|
1287
|
+
* checked too, and before anything is written.
|
|
1288
|
+
*/
|
|
1289
|
+
function assertSubjectDisclosureAdmissible(decorator, params, currentMetadata) {
|
|
1290
|
+
if (decorator === ZodDecorator.IS_BACKEND_ONLY) {
|
|
1291
|
+
if (!declaresDisclosedToSubject(params))
|
|
1292
|
+
return;
|
|
1293
|
+
if (params.isReturnedAtCreation) {
|
|
1294
|
+
throw new Error('isBackendOnly() cannot declare both disclosedToSubject and isReturnedAtCreation: a value returned once at creation is a '
|
|
1295
|
+
+ 'server-minted secret, and a subject export never discloses a secret.');
|
|
1296
|
+
}
|
|
1297
|
+
for (const [companion, reason] of SUBJECT_DISCLOSURE_REFUSED_COMPANIONS) {
|
|
1298
|
+
if (currentMetadata[companion] !== undefined) {
|
|
1299
|
+
throw new Error(`isBackendOnly({ disclosedToSubject: true }) cannot be combined with ${companion}(): ${reason}`);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
const reason = SUBJECT_DISCLOSURE_REFUSED_COMPANIONS.get(decorator);
|
|
1305
|
+
if (reason !== undefined && declaresDisclosedToSubject(currentMetadata[ZodDecorator.IS_BACKEND_ONLY])) {
|
|
1306
|
+
throw new Error(`${decorator}() cannot be combined with isBackendOnly({ disclosedToSubject: true }): ${reason}`);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1241
1309
|
function applySingleDecorator(schema, decorator, params) {
|
|
1242
1310
|
// Ensure schema exists before accessing Symbol property
|
|
1243
1311
|
if (!schema) {
|
|
@@ -1260,6 +1328,8 @@ function applySingleDecorator(schema, decorator, params) {
|
|
|
1260
1328
|
params = params(currentValue);
|
|
1261
1329
|
resolvedFromUpdater = true;
|
|
1262
1330
|
}
|
|
1331
|
+
// A subject-disclosed backend-only field never holds a secret (#2958). Checked on the RESOLVED params, before any write.
|
|
1332
|
+
assertSubjectDisclosureAdmissible(decorator, params, currentMetadata);
|
|
1263
1333
|
// After function resolution, params is a concrete value (never a function).
|
|
1264
1334
|
// TypeScript can't narrow this from control flow. Use `rp<D>()` for typed
|
|
1265
1335
|
// access in cases that read properties; use `p` for simple assignments.
|
|
@@ -1405,6 +1475,9 @@ function applySingleDecorator(schema, decorator, params) {
|
|
|
1405
1475
|
case ZodDecorator.IS_DECIDER:
|
|
1406
1476
|
currentMetadata[ZodDecorator.IS_DECIDER] = true;
|
|
1407
1477
|
break;
|
|
1478
|
+
case ZodDecorator.IS_ROLE_GRANT:
|
|
1479
|
+
currentMetadata[ZodDecorator.IS_ROLE_GRANT] = true;
|
|
1480
|
+
break;
|
|
1408
1481
|
case ZodDecorator.RAG_SOURCE: {
|
|
1409
1482
|
// NORMALIZE HERE, not in the doors — the impersonalizeWith discipline. A bare `.ragSource()`
|
|
1410
1483
|
// (the common case) stores `{}` rather than `true`/`undefined`, so every reader sees ONE
|
|
@@ -1478,6 +1551,17 @@ function applySingleDecorator(schema, decorator, params) {
|
|
|
1478
1551
|
case ZodDecorator.OBJECT_BUSINESS_KEY_SET:
|
|
1479
1552
|
currentMetadata[ZodDecorator.OBJECT_BUSINESS_KEY_SET] = p;
|
|
1480
1553
|
break;
|
|
1554
|
+
case ZodDecorator.OBJECT_COMPOUND_INDEX: {
|
|
1555
|
+
// ACCUMULATES: each call declares one more index. A fresh array, never a push, so the schema this one was
|
|
1556
|
+
// derived from keeps its own list (decorators are builders, #1308). The same field list twice is one index.
|
|
1557
|
+
const existing = (currentMetadata[ZodDecorator.OBJECT_COMPOUND_INDEX] ?? []);
|
|
1558
|
+
const declared = p;
|
|
1559
|
+
const key = declared.fields.join('\u0000');
|
|
1560
|
+
currentMetadata[ZodDecorator.OBJECT_COMPOUND_INDEX] = existing.some((index) => index.fields.join('\u0000') === key)
|
|
1561
|
+
? existing
|
|
1562
|
+
: [...existing, { fields: [...declared.fields] }];
|
|
1563
|
+
break;
|
|
1564
|
+
}
|
|
1481
1565
|
case ZodDecorator.RESOURCE_REFERENCE:
|
|
1482
1566
|
currentMetadata[ZodDecorator.RESOURCE_REFERENCE] = p;
|
|
1483
1567
|
break;
|
|
@@ -2042,16 +2126,86 @@ function wrapMethodToPreserveMetadata(originalMethod, methodName) {
|
|
|
2042
2126
|
* moves methods back onto prototypes — at which point the guard below stops being theoretical, since
|
|
2043
2127
|
* `ZodString.prototype` is reached by both the STEP 1 pass and `installStringDecoratorSurface`.
|
|
2044
2128
|
* Do NOT cite this function as the reason a decorator survives a chain; it is not.
|
|
2129
|
+
*
|
|
2130
|
+
* ⚠️ zod@4.6 DID move them (2026-11-09), as binding ACCESSORS installed lazily on the first instance. So
|
|
2131
|
+
* this function is now live whenever a schema was built before this module ran, and inert otherwise
|
|
2132
|
+
* (zod's own install then lands after it). It reads and writes through `readPrototypeMethod` /
|
|
2133
|
+
* `installBoundPrototypeMethod`, because a plain `prototype[name]` read binds the method to the
|
|
2134
|
+
* PROTOTYPE — see `readPrototypeMethod` for what that broke.
|
|
2045
2135
|
*/
|
|
2046
2136
|
function patchPrototypeMethodsForMetadataPreservation(prototype, methodNames) {
|
|
2047
2137
|
for (const methodName of methodNames) {
|
|
2048
|
-
const originalMethod = prototype
|
|
2138
|
+
const originalMethod = readPrototypeMethod(prototype, methodName);
|
|
2049
2139
|
if (typeof originalMethod !== 'function')
|
|
2050
2140
|
continue;
|
|
2051
2141
|
if (originalMethod.__prototypeMetadataWrapped)
|
|
2052
2142
|
continue;
|
|
2053
|
-
prototype
|
|
2143
|
+
installBoundPrototypeMethod(prototype, methodName, wrapMethodToPreserveMetadata(originalMethod, methodName));
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Reads a schema method off a PROTOTYPE without binding it to the prototype.
|
|
2148
|
+
*
|
|
2149
|
+
* zod 4.6 moved schema methods onto prototypes, as ACCESSORS: a trait's members are installed lazily on the
|
|
2150
|
+
* constructor's prototype when its first instance is built (`util.members` → `defineBound`), and the getter binds the
|
|
2151
|
+
* method to its receiver and memoizes it there — `own(this, key, fn.bind(this))`. So a plain `prototype[name]` runs
|
|
2152
|
+
* that getter with the PROTOTYPE as `this` and permanently shadows the prototype with a method bound to itself. Every
|
|
2153
|
+
* schema then inherited a `refine` whose `this` was the prototype, and zod's `check` read `this.def` off it: measured
|
|
2154
|
+
* 2026-11-09 under vitest as `Cannot read properties of undefined (reading 'checks')` at `z.string().refine(…)`, which
|
|
2155
|
+
* failed 13 suites of `saas-specifications` at import. It reproduced only when a schema had been built before this
|
|
2156
|
+
* module ran (so the members were already installed), which is why `zod-decorators`' own suite stayed green.
|
|
2157
|
+
*
|
|
2158
|
+
* zod's getter answers the RAW method for a nullish receiver ("vitest's spyOn calls a prototype getter bare"), which is
|
|
2159
|
+
* the read this needs. A data property (zod ≤ 4.3, or our own decorator) is returned as it is.
|
|
2160
|
+
*/
|
|
2161
|
+
function readPrototypeMethod(prototype, methodName) {
|
|
2162
|
+
for (let at = prototype; at && at !== Object.prototype; at = Object.getPrototypeOf(at)) {
|
|
2163
|
+
const descriptor = Object.getOwnPropertyDescriptor(at, methodName);
|
|
2164
|
+
if (!descriptor)
|
|
2165
|
+
continue;
|
|
2166
|
+
if ('value' in descriptor)
|
|
2167
|
+
return descriptor.value;
|
|
2168
|
+
if (!descriptor.get)
|
|
2169
|
+
return undefined;
|
|
2170
|
+
try {
|
|
2171
|
+
return descriptor.get.call(undefined);
|
|
2172
|
+
}
|
|
2173
|
+
catch {
|
|
2174
|
+
// A getter that derives a value from its instance is not a method; there is nothing to wrap.
|
|
2175
|
+
return undefined;
|
|
2176
|
+
}
|
|
2054
2177
|
}
|
|
2178
|
+
return undefined;
|
|
2179
|
+
}
|
|
2180
|
+
/**
|
|
2181
|
+
* Installs a method on a prototype with zod 4.6's own member semantics: bound to the instance on first read and
|
|
2182
|
+
* memoized there, so a detached member (`const opt = schema.optional; opt()`) keeps working as it does for zod's own,
|
|
2183
|
+
* and assignment shadows on the instance.
|
|
2184
|
+
*
|
|
2185
|
+
* Only a receiver that INHERITS from `prototype` is an instance read. Every other receiver gets the unbound method and
|
|
2186
|
+
* nothing is memoized, which is what zod's own getter answers for a nullish one. The test is deliberately not
|
|
2187
|
+
* `this == null`: in sloppy-mode code a getter called with an `undefined` receiver sees `globalThis`, and this module
|
|
2188
|
+
* runs sloppy whenever tsx transforms it to CommonJS (every `wildo.saas.config.ts` imported through tsx — see
|
|
2189
|
+
* `prototype-member-binding.zod46.test.ts`). Measured 2026-11-09: `readPrototypeMethod`'s bare read then memoized
|
|
2190
|
+
* eleven zod methods on `globalThis` and returned a copy bound to it without the wrap marker, the next patch pass wrapped
|
|
2191
|
+
* that copy, and `z.string().refine(…)` threw `this.check is not a function` while `@wildo-ai/zod-decorators` loaded.
|
|
2192
|
+
* The same predicate keeps a plain `prototype[name]` read from binding the method to the prototype itself.
|
|
2193
|
+
*/
|
|
2194
|
+
function installBoundPrototypeMethod(prototype, methodName, method) {
|
|
2195
|
+
Object.defineProperty(prototype, methodName, {
|
|
2196
|
+
configurable: true,
|
|
2197
|
+
enumerable: false,
|
|
2198
|
+
get() {
|
|
2199
|
+
if (!Object.prototype.isPrototypeOf.call(prototype, this))
|
|
2200
|
+
return method;
|
|
2201
|
+
const bound = method.bind(this);
|
|
2202
|
+
Object.defineProperty(this, methodName, { configurable: true, enumerable: true, writable: true, value: bound });
|
|
2203
|
+
return bound;
|
|
2204
|
+
},
|
|
2205
|
+
set(value) {
|
|
2206
|
+
Object.defineProperty(this, methodName, { configurable: true, enumerable: true, writable: true, value });
|
|
2207
|
+
},
|
|
2208
|
+
});
|
|
2055
2209
|
}
|
|
2056
2210
|
/**
|
|
2057
2211
|
* Install the WHOLE string decorator surface on one string-backed prototype.
|
|
@@ -2063,8 +2217,9 @@ function patchPrototypeMethodsForMetadataPreservation(prototype, methodNames) {
|
|
|
2063
2217
|
* the method while the other is not.
|
|
2064
2218
|
*
|
|
2065
2219
|
* Also calls the metadata-preservation patch, matching what each of the three install sites did
|
|
2066
|
-
* before. Note that this call
|
|
2067
|
-
*
|
|
2220
|
+
* before. Note that this call was INERT on zod@4.3.6 and is live on 4.6 only when a schema was built
|
|
2221
|
+
* first — see that function's own docblock; `addChainableMethods` is what preserves metadata through a
|
|
2222
|
+
* chain.
|
|
2068
2223
|
* It is passed through rather than dropped so the two stay coupled if Zod's method placement changes.
|
|
2069
2224
|
*
|
|
2070
2225
|
* @param prototype - a Zod string-schema prototype (`ZodString.prototype`, `ZodUUID.prototype`, …)
|
|
@@ -2173,6 +2328,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2173
2328
|
zodInstance.ZodNumber.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2174
2329
|
zodInstance.ZodNumber.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2175
2330
|
zodInstance.ZodNumber.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2331
|
+
zodInstance.ZodNumber.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2176
2332
|
zodInstance.ZodNumber.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2177
2333
|
zodInstance.ZodNumber.prototype[ZodDecorator.IS_DISCRIMINATOR] = ZodDecorator_FunctionType[ZodDecorator.IS_DISCRIMINATOR];
|
|
2178
2334
|
zodInstance.ZodNumber.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
@@ -2220,6 +2376,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2220
2376
|
zodInstance.ZodBigInt.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2221
2377
|
zodInstance.ZodBigInt.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2222
2378
|
zodInstance.ZodBigInt.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2379
|
+
zodInstance.ZodBigInt.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2223
2380
|
zodInstance.ZodBigInt.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2224
2381
|
zodInstance.ZodBigInt.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
2225
2382
|
zodInstance.ZodBigInt.prototype[ZodDecorator.EXCLUDE_FROM_UPDATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_UPDATE];
|
|
@@ -2243,6 +2400,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2243
2400
|
zodInstance.ZodBoolean.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2244
2401
|
zodInstance.ZodBoolean.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2245
2402
|
zodInstance.ZodBoolean.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2403
|
+
zodInstance.ZodBoolean.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2246
2404
|
zodInstance.ZodBoolean.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2247
2405
|
zodInstance.ZodBoolean.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
2248
2406
|
zodInstance.ZodBoolean.prototype[ZodDecorator.EXCLUDE_FROM_UPDATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_UPDATE];
|
|
@@ -2273,6 +2431,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2273
2431
|
zodInstance.ZodDate.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2274
2432
|
zodInstance.ZodDate.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2275
2433
|
zodInstance.ZodDate.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2434
|
+
zodInstance.ZodDate.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2276
2435
|
zodInstance.ZodDate.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2277
2436
|
zodInstance.ZodDate.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
2278
2437
|
zodInstance.ZodDate.prototype[ZodDecorator.EXCLUDE_FROM_UPDATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_UPDATE];
|
|
@@ -2310,6 +2469,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2310
2469
|
zodInstance.ZodOptional.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2311
2470
|
zodInstance.ZodOptional.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2312
2471
|
zodInstance.ZodOptional.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2472
|
+
zodInstance.ZodOptional.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2313
2473
|
// RAG source — ZodOptional is the ONE wrapper with a hand-enumerated block (its siblings get every
|
|
2314
2474
|
// FunctionType entry from the blanket wrapper loop below), so this line is what keeps
|
|
2315
2475
|
// `z.string().optional().ragSource()` from being the order-dependent half-live trap the
|
|
@@ -2402,6 +2562,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2402
2562
|
zodInstance.ZodEnum.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2403
2563
|
zodInstance.ZodEnum.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2404
2564
|
zodInstance.ZodEnum.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2565
|
+
zodInstance.ZodEnum.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2405
2566
|
zodInstance.ZodEnum.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2406
2567
|
zodInstance.ZodEnum.prototype[ZodDecorator.IS_DISCRIMINATOR] = ZodDecorator_FunctionType[ZodDecorator.IS_DISCRIMINATOR];
|
|
2407
2568
|
zodInstance.ZodEnum.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
@@ -2438,6 +2599,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2438
2599
|
zodInstance.ZodArray.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2439
2600
|
zodInstance.ZodArray.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2440
2601
|
zodInstance.ZodArray.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2602
|
+
zodInstance.ZodArray.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2441
2603
|
zodInstance.ZodArray.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2442
2604
|
zodInstance.ZodArray.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
2443
2605
|
zodInstance.ZodArray.prototype[ZodDecorator.EXCLUDE_FROM_UPDATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_UPDATE];
|
|
@@ -2473,10 +2635,13 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2473
2635
|
* before the object is wrapped (`WorkUnitRefSchema.optional()`), and read through any wrapper. `ZodOptional`,
|
|
2474
2636
|
* whose list is written by hand, does not carry it either.
|
|
2475
2637
|
*
|
|
2638
|
+
* `compoundIndex` (#3142) is excluded for the same reason: it names fields of the OBJECT it decorates, and an index
|
|
2639
|
+
* belongs to the stored row, whose schema is a plain object. It is read from the top-level object only.
|
|
2640
|
+
*
|
|
2476
2641
|
* Keep this a SET with a reason per member, never a silent condition in the loop body. An excluded
|
|
2477
2642
|
* decorator is a decision; a missing one is a bug, and the two must not look alike.
|
|
2478
2643
|
*/
|
|
2479
|
-
const WRAPPER_INSTALL_EXCLUSIONS = new Set([ZodDecorator.IS_PRIMARY_KEY, ZodDecorator.DOCUMENT_SEQUENCE, ZodDecorator.RESOURCE_REFERENCE]);
|
|
2644
|
+
const WRAPPER_INSTALL_EXCLUSIONS = new Set([ZodDecorator.IS_PRIMARY_KEY, ZodDecorator.DOCUMENT_SEQUENCE, ZodDecorator.RESOURCE_REFERENCE, ZodDecorator.OBJECT_COMPOUND_INDEX]);
|
|
2480
2645
|
// Wrapper types (ZodDefault, ZodNullable) need ALL decorators for chaining
|
|
2481
2646
|
// e.g. z.date().default(...).excludeFromCreate().isNotEditable().showWhen(...)
|
|
2482
2647
|
//
|
|
@@ -2514,6 +2679,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2514
2679
|
zi.ZodUnion.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2515
2680
|
zi.ZodUnion.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2516
2681
|
zi.ZodUnion.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2682
|
+
zi.ZodUnion.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2517
2683
|
zi.ZodUnion.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2518
2684
|
zi.ZodUnion.prototype[ZodDecorator.IS_DISCRIMINATOR] = ZodDecorator_FunctionType[ZodDecorator.IS_DISCRIMINATOR];
|
|
2519
2685
|
zi.ZodUnion.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
@@ -2536,6 +2702,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2536
2702
|
zi.ZodObject.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2537
2703
|
zi.ZodObject.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2538
2704
|
zi.ZodObject.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2705
|
+
zi.ZodObject.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2539
2706
|
zi.ZodObject.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2540
2707
|
zi.ZodObject.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
2541
2708
|
zi.ZodObject.prototype[ZodDecorator.EXCLUDE_FROM_UPDATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_UPDATE];
|
|
@@ -2543,6 +2710,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2543
2710
|
zi.ZodObject.prototype[ZodDecorator.IS_CRDT] = ZodDecorator_FunctionType[ZodDecorator.IS_CRDT];
|
|
2544
2711
|
// Composite business key (data-seeding subsystem)
|
|
2545
2712
|
zi.ZodObject.prototype[ZodDecorator.OBJECT_BUSINESS_KEY_SET] = ZodDecorator_FunctionType[ZodDecorator.OBJECT_BUSINESS_KEY_SET];
|
|
2713
|
+
zi.ZodObject.prototype[ZodDecorator.OBJECT_COMPOUND_INDEX] = ZodDecorator_FunctionType[ZodDecorator.OBJECT_COMPOUND_INDEX];
|
|
2546
2714
|
zi.ZodObject.prototype[ZodDecorator.RESOURCE_REFERENCE] = ZodDecorator_FunctionType[ZodDecorator.RESOURCE_REFERENCE];
|
|
2547
2715
|
// Generic form-field decorators (conditional visibility / draft relaxation).
|
|
2548
2716
|
zi.ZodObject.prototype[ZodDecorator.SHOW_WHEN] = ZodDecorator_FunctionType[ZodDecorator.SHOW_WHEN];
|
|
@@ -2568,6 +2736,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2568
2736
|
zi.ZodRecord.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2569
2737
|
zi.ZodRecord.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2570
2738
|
zi.ZodRecord.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2739
|
+
zi.ZodRecord.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2571
2740
|
zi.ZodRecord.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2572
2741
|
zi.ZodRecord.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
2573
2742
|
zi.ZodRecord.prototype[ZodDecorator.EXCLUDE_FROM_UPDATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_UPDATE];
|
|
@@ -2598,6 +2767,7 @@ export function ensureZodDecoratorsLoaded(zodInstance = z) {
|
|
|
2598
2767
|
zi.ZodMap.prototype[ZodDecorator.IS_AUDIT_EVIDENCE] = ZodDecorator_FunctionType[ZodDecorator.IS_AUDIT_EVIDENCE];
|
|
2599
2768
|
zi.ZodMap.prototype[ZodDecorator.IS_LAST_ACTION_RECORD] = ZodDecorator_FunctionType[ZodDecorator.IS_LAST_ACTION_RECORD];
|
|
2600
2769
|
zi.ZodMap.prototype[ZodDecorator.IS_DECIDER] = ZodDecorator_FunctionType[ZodDecorator.IS_DECIDER];
|
|
2770
|
+
zi.ZodMap.prototype[ZodDecorator.IS_ROLE_GRANT] = ZodDecorator_FunctionType[ZodDecorator.IS_ROLE_GRANT];
|
|
2601
2771
|
zi.ZodMap.prototype[ZodDecorator.IS_VIRTUAL] = ZodDecorator_FunctionType[ZodDecorator.IS_VIRTUAL];
|
|
2602
2772
|
zi.ZodMap.prototype[ZodDecorator.EXCLUDE_FROM_CREATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_CREATE];
|
|
2603
2773
|
zi.ZodMap.prototype[ZodDecorator.EXCLUDE_FROM_UPDATE] = ZodDecorator_FunctionType[ZodDecorator.EXCLUDE_FROM_UPDATE];
|