BREAKING CHANGE: cereale moves from legacy `experimentalDecorators` to TC39
standard decorators, which is what makes validation rules type-checked against
the fields they are attached to.
class User {
@IsString() name!: string; // fine
@IsString() age!: number; // Type 'number' is not assignable to 'string'
}
Legacy decorators receive (target: any, key: string) and lose the field type
entirely, so this was impossible in v1. Standard decorators receive
ClassFieldDecoratorContext<This, Value>, which carries it. Rules now checked:
scalar rules against scalar fields; { each: true } against arrays, in both
directions; @JsonType against the field's class; @JsonSerialize/@JsonDeserialize
against the field's type; @IsIn and @IsEnum against the field's value type.
17 tests invoke the real compiler to assert the wrong code stays rejected — a
guarantee nobody checks is one that quietly stops holding.
Positioning follows the capability: validated domain objects, not validated
data. The README now leads with the Zod comparison. Cereale does not infer your
type from a schema — you still write the field type and the rule — but it
guarantees the two cannot disagree, which is what class-validator never offered.
Removed
- metadata-storage.ts and its WeakMap singleton. Metadata lives on
context.metadata now, which also removes the dual ESM/CJS double-singleton
hazard. Inheritance merging becomes structural rather than reconstructed on
every read, so the subclass-shadowing defect fixed by hand in 0.1.0 cannot
reoccur by construction.
- registerDecorator, replaced by defineRule(Class, 'field', constraint).
Unchanged: the engine, options, naming strategies, access control, error
helpers, the sync API, and the performance work. 193 tests pass.
Toolchain note: standard decorators are transformed by tsc and esbuild, but not
yet by oxc. The library builds with tsc and consumers on esbuild/Vite are fine;
Vitest 4 uses oxc, so the test runner needs an esbuild transform plugin. This is
recorded in vitest.config.ts and the README, and is the reason 1.x should stay
available for oxc-based toolchains.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAcqrz3FcadkYr3xG32CjK
3 lines
23 KiB
JavaScript
3 lines
23 KiB
JavaScript
"use strict";var Cereale=(()=>{var L=Object.defineProperty;var In=Object.getOwnPropertyDescriptor;var An=Object.getOwnPropertyNames;var Nn=Object.prototype.hasOwnProperty;var Mn=(n,e)=>{for(var t in e)L(n,t,{get:e[t],enumerable:!0})},Pn=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of An(e))!Nn.call(n,r)&&r!==t&&L(n,r,{get:()=>e[r],enumerable:!(o=In(e,r))||o.enumerable});return n};var Rn=n=>Pn(L({},"__esModule",{value:!0}),n);var gt={};Mn(gt,{Allow:()=>Yn,ArrayContains:()=>Ye,ArrayMaxSize:()=>He,ArrayMinSize:()=>Ge,ArrayNotContains:()=>Qe,ArrayNotEmpty:()=>Ze,ArrayUnique:()=>Xe,Contains:()=>Fe,Email:()=>Oe,EndsWith:()=>Ue,Equals:()=>Be,IsAlpha:()=>Ce,IsAlphanumeric:()=>Te,IsArray:()=>We,IsBigInt:()=>re,IsBoolean:()=>oe,IsDate:()=>ae,IsDateString:()=>Ee,IsDefined:()=>se,IsDivisibleBy:()=>me,IsEmpty:()=>ue,IsEnum:()=>Le,IsHexColor:()=>Ve,IsIP:()=>ve,IsIn:()=>_e,IsInstance:()=>qe,IsInt:()=>te,IsJSON:()=>Ie,IsLatitude:()=>ge,IsLongitude:()=>he,IsLowercase:()=>$e,IsNotEmpty:()=>le,IsNotIn:()=>Ke,IsNumber:()=>ee,IsNumberString:()=>Se,IsObject:()=>ie,IsOptional:()=>Hn,IsPort:()=>ye,IsSemVer:()=>De,IsString:()=>ne,IsUUID:()=>Re,IsUppercase:()=>ke,IsUrl:()=>Ae,JsonAlias:()=>jn,JsonDeserialize:()=>Wn,JsonIgnore:()=>_n,JsonMapper:()=>G,JsonMappingError:()=>b,JsonPolymorphic:()=>Gn,JsonProperty:()=>Bn,JsonReadOnly:()=>Kn,JsonSerialize:()=>qn,JsonType:()=>Zn,JsonValidationError:()=>C,JsonWriteOnly:()=>Ln,Length:()=>we,Matches:()=>Ne,Max:()=>de,MaxDate:()=>et,MaxLength:()=>xe,Min:()=>ce,MinDate:()=>nt,MinLength:()=>be,Negative:()=>fe,NotContains:()=>Je,NotEquals:()=>je,Positive:()=>pe,REDACTED:()=>yn,StartsWith:()=>ze,Validate:()=>tt,ValidateIf:()=>Xn,ValidateNested:()=>Qn,addConstraint:()=>E,collectErrorMessages:()=>rt,configure:()=>Jn,defineRule:()=>Fn,flattenErrors:()=>Z,formatErrors:()=>ot,fromJson:()=>kn,fromJsonArray:()=>Sn,fromJsonArraySync:()=>yt,fromJsonSync:()=>mt,fromRequest:()=>En,getConfig:()=>zn,modelOf:()=>R,modelOfInstance:()=>v,modelVersion:()=>T,propertyModel:()=>h,resetConfig:()=>Un,resolveNamingStrategy:()=>F,resolveOptions:()=>x,toInstance:()=>P,toInstanceArray:()=>nn,toInstanceArraySync:()=>$n,toInstanceSync:()=>Q,toJson:()=>Dn,toJsonSync:()=>ft,toPlain:()=>Y,toPlainSync:()=>Tn,validate:()=>M,validateOrReject:()=>Cn,validateOrRejectSync:()=>pt,validateSync:()=>j});Symbol.metadata??=Symbol.for("Symbol.metadata");var S=Symbol.for("cereale.model"),on=0;function T(){return on}function vn(n){if(!Object.hasOwn(n,S)){let e=n[S],t={};for(let[o,r]of Object.entries(e??{}))t[o]={...r,constraints:[...r.constraints]};n[S]=t}return n[S]}function h(n,e){on++;let t=vn(n);return t[e]??={constraints:[]}}function E(n,e,t,o){o?.each&&(t.each=!0),o?.message&&(t.message=o.message,t.hasCustomMessage=!0),h(n,e).constraints.push(t)}function R(n){return typeof n!="function"?{}:n[Symbol.metadata]?.[S]??{}}function v(n){let e=Object.getPrototypeOf(n);if(!e)return{};let t=Object.getOwnPropertyDescriptor(e,"constructor");return R(t?.value)}function Fn(n,e,t,o){let r=n;r[Symbol.metadata]??=Object.create(null),E(r[Symbol.metadata],e,t,o)}function I(n){return n.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").replace(/[_\-\s]+/g," ").trim().split(" ").filter(Boolean).map(e=>e.toLowerCase())}var rn=n=>n&&n.charAt(0).toUpperCase()+n.slice(1),q={identity:n=>n,camelCase:n=>{let e=I(n);return e.length===0?n:e[0]+e.slice(1).map(rn).join("")},PascalCase:n=>I(n).map(rn).join("")||n,snake_case:n=>I(n).join("_")||n,SCREAMING_SNAKE_CASE:n=>I(n).join("_").toUpperCase()||n,"kebab-case":n=>I(n).join("-")||n};function F(n){if(!n)return q.identity;if(typeof n=="function")return n;let e=q[n];if(!e)throw new Error(`Unknown naming strategy ${JSON.stringify(n)}. Use one of: ${Object.keys(q).join(", ")}, or pass your own function.`);return e}var an={namingStrategy:"identity",unknownKeys:"allow",validate:!0,maxDepth:64},O={...an};function Jn(n){O={...O,...n}}function zn(){return{...O}}function Un(){O={...an}}function x(n){return n?{namingStrategy:n.namingStrategy??O.namingStrategy,unknownKeys:n.unknownKeys??O.unknownKeys,validate:n.validate??O.validate,maxDepth:n.maxDepth??O.maxDepth}:O}function d(n,e){return((t,o)=>{let r=String(o.name);E(o.metadata,r,n(r),e)})}function p(n,e,t){return(o=>d(r=>({name:n,validate:e,message:t(r)}),o))}function A(n,e,t){return p(n,o=>typeof o=="string"&&e.test(o),t)}function Bn(n){return((e,t)=>{h(t.metadata,String(t.name)).name=n})}function jn(...n){return((e,t)=>{let o=h(t.metadata,String(t.name));o.aliases=[...o.aliases??[],...n]})}function W(n){return((e,t)=>{h(t.metadata,String(t.name)).access=n})}var _n=()=>W("none"),Kn=()=>W("readonly"),Ln=()=>W("writeonly");function qn(n){return((e,t)=>{h(t.metadata,String(t.name)).serializer=n})}function Wn(n){return((e,t)=>{h(t.metadata,String(t.name)).deserializer=n})}function Zn(n){return((e,t)=>{h(t.metadata,String(t.name)).type=n})}function Gn(n,e,t){return((o,r)=>{let a={discriminator:n,subTypes:e,onUnknown:t?.onUnknown??"keep",...t?.fallback?{fallback:t.fallback}:{}};h(r.metadata,String(r.name)).polymorphic=a})}function Hn(){return((n,e)=>{h(e.metadata,String(e.name)).optional=!0})}function Xn(n){return((e,t)=>{h(t.metadata,String(t.name)).condition=n})}function Yn(){return((n,e)=>{h(e.metadata,String(e.name))})}function Qn(n){return((e,t)=>{let o=String(t.name);h(t.metadata,o).nested=!0,n?.each&&E(t.metadata,o,{name:"nestedEach",validate:r=>Array.isArray(r),message:`${o} must be an array`})})}var ne=p("isString",n=>typeof n=="string",n=>`${n} must be a string`),ee=p("isNumber",n=>typeof n=="number"&&!isNaN(n),n=>`${n} must be a number`),te=p("isInt",n=>Number.isInteger(n),n=>`${n} must be an integer`),oe=p("isBoolean",n=>typeof n=="boolean",n=>`${n} must be a boolean`),re=p("isBigInt",n=>typeof n=="bigint",n=>`${n} must be a bigint`),ae=p("isDate",n=>n instanceof Date&&!isNaN(n.getTime()),n=>`${n} must be a valid Date object`),ie=p("isObject",n=>typeof n=="object"&&n!==null&&!Array.isArray(n),n=>`${n} must be an object`),se=p("isDefined",n=>n!=null,n=>`${n} should not be null or undefined`),le=p("isNotEmpty",n=>n!=null&&n!=="",n=>`${n} should not be empty`),ue=p("isEmpty",n=>n==null||n===""?!0:Array.isArray(n)?n.length===0:typeof n=="object"?Object.keys(n).length===0:!1,n=>`${n} must be empty`);function ce(n,e){return d(t=>({name:"min",validate:o=>typeof o=="number"&&o>=n,message:`${t} must be at least ${n}`,constraints:[n]}),e)}function de(n,e){return d(t=>({name:"max",validate:o=>typeof o=="number"&&o<=n,message:`${t} must be at most ${n}`,constraints:[n]}),e)}var pe=p("positive",n=>typeof n=="number"&&n>0,n=>`${n} must be positive`),fe=p("negative",n=>typeof n=="number"&&n<0,n=>`${n} must be negative`);function me(n,e){return d(t=>({name:"isDivisibleBy",validate:o=>typeof o=="number"&&Number.isFinite(o)&&n!==0&&o%n===0,message:`${t} must be divisible by ${n}`,constraints:[n]}),e)}var ye=p("isPort",n=>{let e=typeof n=="string"&&n.trim()!==""?Number(n):n;return typeof e=="number"&&Number.isInteger(e)&&e>=0&&e<=65535},n=>`${n} must be a valid port number`),ge=p("isLatitude",n=>typeof n=="number"&&Number.isFinite(n)&&n>=-90&&n<=90,n=>`${n} must be a latitude between -90 and 90`),he=p("isLongitude",n=>typeof n=="number"&&Number.isFinite(n)&&n>=-180&&n<=180,n=>`${n} must be a longitude between -180 and 180`);function be(n,e){return d(t=>({name:"minLength",validate:o=>typeof o=="string"&&o.length>=n,message:`${t} must be longer than or equal to ${n} characters`,constraints:[n]}),e)}function xe(n,e){return d(t=>({name:"maxLength",validate:o=>typeof o=="string"&&o.length<=n,message:`${t} must be shorter than or equal to ${n} characters`,constraints:[n]}),e)}function we(n,e,t){return d(o=>({name:"length",validate:r=>typeof r=="string"&&r.length>=n&&(e===void 0||r.length<=e),message:e===void 0?`${o} must be at least ${n} characters`:`${o} must be between ${n} and ${e} characters`,constraints:e===void 0?[n]:[n,e]}),t)}var Oe=A("isEmail",/^[^\s@]+@[^\s@]+\.[^\s@]+$/,n=>`${n} must be a valid email`),Ce=A("isAlpha",/^[A-Za-z]+$/,n=>`${n} must contain only letters`),Te=A("isAlphanumeric",/^[A-Za-z0-9]+$/,n=>`${n} must contain only letters and numbers`),De=A("isSemVer",/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/,n=>`${n} must be a valid semantic version`),Ve=A("isHexColor",/^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i,n=>`${n} must be a hex color`),$e=p("isLowercase",n=>typeof n=="string"&&n===n.toLowerCase(),n=>`${n} must be lowercase`),ke=p("isUppercase",n=>typeof n=="string"&&n===n.toUpperCase(),n=>`${n} must be uppercase`),Se=p("isNumberString",n=>typeof n=="string"&&n.trim()!==""&&Number.isFinite(Number(n)),n=>`${n} must be a number string`),Ee=p("isDateString",n=>typeof n=="string"&&!isNaN(Date.parse(n)),n=>`${n} must be a valid ISO 8601 date string`),Ie=p("isJson",n=>{if(typeof n!="string")return!1;try{return JSON.parse(n),!0}catch{return!1}},n=>`${n} must be a JSON string`),Ae=p("isUrl",n=>{try{return new URL(n),!0}catch{return!1}},n=>`${n} must be a valid URL`);function Ne(n,e){let t=n.flags.includes("g")||n.flags.includes("y")?new RegExp(n.source,n.flags.replace(/[gy]/g,"")):n;return d(o=>({name:"matches",validate:r=>typeof r=="string"&&t.test(r),message:`${o} must match ${n} regular expression`,constraints:[n]}),e)}var Me="00000000-0000-0000-0000-000000000000",Pe="ffffffff-ffff-ffff-ffff-ffffffffffff";function Re(n,e){let t=n?new RegExp(`^[0-9a-f]{8}-[0-9a-f]{4}-${n}[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`,"i"):/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;return d(o=>({name:"isUuid",validate:r=>typeof r!="string"?!1:!n&&(r.toLowerCase()===Me||r.toLowerCase()===Pe)?!0:t.test(r),message:`${o} must be a valid UUID${n?` (version ${n})`:""}`,...n?{constraints:[n]}:{}}),e)}var sn=/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/,ln=n=>{try{return new URL(`http://[${n}]`).hostname===`[${n.toLowerCase()}]`||/^[0-9a-f:.]+$/i.test(n)&&n.includes(":")}catch{return!1}};function ve(n,e){return d(t=>({name:"isIp",validate:o=>typeof o!="string"?!1:n===4?sn.test(o):n===6?ln(o):sn.test(o)||ln(o),message:`${t} must be a valid IP${n?`v${n}`:""} address`,...n?{constraints:[n]}:{}}),e)}function z(n,e,t){function o(r,a){return d(i=>({name:n,validate:s=>typeof s=="string"&&e(s,r),message:t(i,r),constraints:[r]}),a)}return o}var Fe=z("contains",(n,e)=>n.includes(e),(n,e)=>`${n} must contain ${JSON.stringify(e)}`),Je=z("notContains",(n,e)=>!n.includes(e),(n,e)=>`${n} must not contain ${JSON.stringify(e)}`),ze=z("startsWith",(n,e)=>n.startsWith(e),(n,e)=>`${n} must start with ${JSON.stringify(e)}`),Ue=z("endsWith",(n,e)=>n.endsWith(e),(n,e)=>`${n} must end with ${JSON.stringify(e)}`);function Be(n,e){return d(t=>({name:"equals",validate:o=>o===n,message:`${t} must be equal to ${JSON.stringify(n)}`,constraints:[n]}),e)}function je(n,e){return d(t=>({name:"notEquals",validate:o=>o!==n,message:`${t} must not be equal to ${JSON.stringify(n)}`,constraints:[n]}),e)}function _e(n,e){return d(t=>({name:"isIn",validate:o=>n.includes(o),message:`${t} must be one of the following values: ${n.join(", ")}`,constraints:[n]}),e)}function Ke(n,e){return d(t=>({name:"isNotIn",validate:o=>!n.includes(o),message:`${t} must not be one of the following values: ${n.join(", ")}`,constraints:[n]}),e)}function Le(n,e){let t=Object.keys(n).filter(o=>typeof n[n[o]]!="number").map(o=>n[o]);return d(o=>({name:"isEnum",validate:r=>t.includes(r),message:`${o} must be one of the following values: ${t.join(", ")}`,constraints:[t]}),e)}function qe(n,e){return d(t=>({name:"isInstance",validate:o=>o instanceof n,message:`${t} must be an instance of ${n.name}`,constraints:[n]}),e)}function $(n,e,t,o){return r=>d(a=>({name:n,validate:i=>Array.isArray(i)&&e(i),message:t(a),...o?{constraints:o}:{}}),r)}var We=n=>d(e=>({name:"isArray",validate:t=>Array.isArray(t),message:`${e} must be an array`}),n),Ze=n=>$("arrayNotEmpty",e=>e.length>0,e=>`${e} should not be empty`)(n),Ge=(n,e)=>$("arrayMinSize",t=>t.length>=n,t=>`${t} must contain at least ${n} elements`,[n])(e),He=(n,e)=>$("arrayMaxSize",t=>t.length<=n,t=>`${t} must contain at most ${n} elements`,[n])(e);function Xe(n,e){return $("arrayUnique",t=>{let o=n?t.map(n):t;return new Set(o).size===o.length},t=>`${t} must not contain duplicate values`)(e)}function Ye(n,e){return $("arrayContains",t=>n.every(o=>t.includes(o)),t=>`${t} must contain the following values: ${n.join(", ")}`,[n])(e)}function Qe(n,e){return $("arrayNotContains",t=>n.every(o=>!t.includes(o)),t=>`${t} must not contain any of the following values: ${n.join(", ")}`,[n])(e)}var J=n=>typeof n=="function"?n():n;function nt(n,e){return d(()=>({name:"minDate",validate:t=>t instanceof Date&&!isNaN(t.getTime())&&t.getTime()>=J(n).getTime(),message:t=>`${t.property} must not be earlier than ${J(n).toISOString()}`,constraints:[n]}),e)}function et(n,e){return d(()=>({name:"maxDate",validate:t=>t instanceof Date&&!isNaN(t.getTime())&&t.getTime()<=J(n).getTime(),message:t=>`${t.property} must not be later than ${J(n).toISOString()}`,constraints:[n]}),e)}function tt(n,e,t){let o=Array.isArray(e)?e:[],r=Array.isArray(e)?t:e;if(typeof n=="function"&&!n.prototype?.validate){let s=n;return d(()=>({name:"custom",validate:(l,u)=>s(l,u),message:l=>`${l.property} is invalid`,constraints:o}),r)}let i=new n;return d(()=>({name:n.name,validate:(s,l)=>i.validate(s,l),message:s=>i.defaultMessage?i.defaultMessage(s):`${s.property} is invalid`,constraints:o}),r)}function Z(n){let e={},t=(o,r)=>{for(let a of o){let i=a.property.startsWith("[")?`${r}${a.property}`:r?`${r}.${a.property}`:a.property,s=Object.values(a.constraints);s.length>0&&(e[i]??=[]).push(...s),a.children?.length&&t(a.children,i)}};return t(n,""),e}function ot(n){let e=Z(n);return Object.entries(e).flatMap(([t,o])=>o.map(r=>`${t}: ${r}`)).join(`
|
|
`)}function rt(n){return Object.values(Z(n)).flat()}var C=class extends Error{constructor(t,o){super(t);this.errors=o;this.name="JsonValidationError"}toString(){return`${this.message}: ${JSON.stringify(this.errors,null,2)}`}},b=class extends Error{constructor(e){super(e),this.name="JsonMappingError"}},at=new Set(["__proto__","constructor","prototype"]),yn="[redacted]";function gn(n,e){return n[e]?.access??"readwrite"}function hn(n,e,t){return n[e]?.name??t(e)}var un=new WeakMap;function it(n,e,t){let o=un.get(n);(!o||o.version!==T())&&(o={version:T(),byStrategy:new Map},un.set(n,o));let r=o.byStrategy.get(t.namingKey);r||(r=new Map,o.byStrategy.set(t.namingKey,r));let a=r.get(e);if(!a){let i=gn(n,e),s=n[e]?.serializer;a={name:hn(n,e,t.naming),skip:i==="none"||i==="writeonly",...s?{serializer:s}:{}},r.set(e,a)}return a}var cn=new WeakMap;function st(n,e){let t=cn.get(n);(!t||t.version!==T())&&(t={version:T(),byStrategy:new Map},cn.set(n,t));let o=t.byStrategy.get(e.namingKey);if(o)return o;let r=new Map,a=new Set,i=new Map,s=(u,c)=>{let y=r.get(u);if(y&&y!==c)throw new b(`Properties "${y}" and "${c}" both map to the JSON name ${JSON.stringify(u)}. Give one of them a distinct @JsonProperty name.`);r.set(u,c)};for(let[u,c]of Object.entries(n)){let y=[hn(n,u,e.naming),...c.aliases??[]],m=gn(n,u);if(m==="none"||m==="readonly"){for(let f of y)a.add(f);continue}for(let f of y)s(f,u);(c.deserializer||c.polymorphic||c.type)&&i.set(u,{...c.deserializer?{deserializer:c.deserializer}:{},...c.polymorphic?{polymorphic:c.polymorphic}:{},...c.type?{typeFn:c.type}:{}})}let l={accept:r,blocked:a,props:i};return t.byStrategy.set(e.namingKey,l),l}function N(n){return n!==null&&typeof n=="object"&&typeof n.then=="function"}async function H(n){for(;n.length>0;){let e=n.splice(0,n.length);await Promise.all(e)}}function X(n,e,t){if(n.length!==0){for(let o of n)o.catch(()=>{});throw n.length=0,new b(`${e} requires every serializer, deserializer and validator to be synchronous, but one returned a Promise. Use ${t} instead, or make the hook synchronous.`)}}function U(n,e,t,o,r){if(n==null||typeof n!="object")return n;if(o>t.maxDepth)throw new b(`Maximum nesting depth of ${t.maxDepth} exceeded while serializing. Raise it with the maxDepth option if this structure is legitimate.`);if(n instanceof Date)return n.toISOString();if(e.has(n))throw new b("Circular reference detected during serialization. Break the cycle with @JsonIgnore() on the back-reference, or supply a @JsonSerialize() serializer for that property.");e.add(n);try{if(Array.isArray(n)){let s=[];for(let l of n)s.push(U(l,e,t,o+1,r));return s}let a=v(n),i={};for(let s of Object.keys(n)){let l=it(a,s,t);if(l.skip)continue;let u=n[s];if(l.serializer&&u!==null&&u!==void 0){let c=bn(l.serializer).serialize(u);if(N(c)){let y=l.name;i[y]=void 0,r.push(c.then(m=>{i[y]=m}))}else i[l.name]=c}else i[l.name]=U(u,e,t,o+1,r)}return i}finally{e.delete(n)}}function k(n,e,t,o,r){if(e==null)return e;if(o>t.maxDepth)throw new b(`Maximum nesting depth of ${t.maxDepth} exceeded while deserializing. Raise it with the maxDepth option if this structure is legitimate.`);if(Array.isArray(e))return e.map(s=>k(n,s,t,o+1,r));if(typeof e!="object")return e;let a=new n,i=st(R(n),t);for(let s of Object.keys(e)){if(at.has(s)||i.blocked.has(s))continue;let l=i.accept.get(s);if(l===void 0){if(t.unknownKeys==="strip")continue;if(t.unknownKeys==="error")throw new b(`Unknown property ${JSON.stringify(s)} for ${n.name}. Allowed: ${[...i.accept.keys()].map(f=>JSON.stringify(f)).join(", ")||"(none declared)"}.`);a[s]=e[s];continue}let u=e[s],c=i.props.get(l);if(c?.deserializer){let f=bn(c.deserializer).deserialize(u);if(N(f)){let g=l;a[g]=void 0,r.push(f.then(D=>{a[g]=D}))}else a[l]=f;continue}let y=c?.polymorphic;if(y&&u!==null&&u!==void 0){let{discriminator:f,subTypes:g,onUnknown:D,fallback:V}=y,en=w=>{if(w==null||typeof w!="object")return w;let tn=g.find(K=>w[f]===K.name);if(tn)return k(tn.value,w,t,o+1,r);if(V)return k(V,w,t,o+1,r);if(D==="error")throw new b(`Unknown discriminator value ${JSON.stringify(w[f])} for property "${l}". Known values: ${g.map(K=>JSON.stringify(K.name)).join(", ")}.`);return w};a[l]=Array.isArray(u)?u.map(en):en(u);continue}let m=c?.typeFn;if(m&&u!==null&&u!==void 0){let f=m();a[l]=k(f,u,t,o+1,r);continue}a[l]=u}return a}var dn=new WeakMap;function lt(n){let e=[],t=new Set;for(let o of n){if(typeof o.message=="string"){let r=`${o.name}|${String(o.constraints)}|${o.message}|${o.each??!1}`;if(t.has(r))continue;t.add(r)}e.push(o)}return e}function ut(n){let e=dn.get(n);if(e&&e.version===T())return e.plan;let t=[];for(let[o,r]of Object.entries(n)){let a=r.access??"readwrite";t.push({key:o,constraints:lt(r.constraints),isOptional:!!r.optional,isNested:!!r.nested,redact:a==="writeonly"||a==="none",...r.condition?{condition:r.condition}:{}})}return dn.set(n,{version:T(),plan:t}),t}var pn=new WeakMap;function bn(n){let e=pn.get(n);return e||(e=new n,pn.set(n,e)),e}function fn(n,e,t){if(!(e in n)){n[e]=t;return}let o=2;for(;`${e}_${o}`in n;)o++;n[`${e}_${o}`]=t}function mn(n,e,t){let o=typeof n.message=="function"?n.message(e):n.message;return n.each&&!n.hasCustomMessage&&(o=t>=0?`each element in ${o} (failed at index ${t})`:`each element in ${o}`),o}function ct(n,e,t){for(let o=0;o<e.length;o++){t.value=e[o];let r=n.validate(e[o],t);if(N(r)){let a={object:t.object,property:t.property,constraints:t.constraints},i=dt(n,e,o,r,a);return t.value=e,i}if(!r)return t.value=e,{ok:!1,index:o}}return t.value=e,{ok:!0,index:-1}}async function dt(n,e,t,o,r){if(!await o)return{ok:!1,index:t};for(let a=t+1;a<e.length;a++)if(!await n.validate(e[a],{...r,value:e[a]}))return{ok:!1,index:a};return{ok:!0,index:-1}}function xn(n){let e=[];for(let t of n){let o=t.children?xn(t.children):void 0;o&&o.length>0?t.children=o:delete t.children,(Object.keys(t.constraints).length>0||t.children)&&e.push(t)}return e}function B(n,e,t,o,r){let a=[];if(n==null||typeof n!="object")return a;if(t>o)throw new b(`Maximum nesting depth of ${o} exceeded while validating. Raise it with the maxDepth option if this structure is legitimate.`);if(e.has(n))return a;e.add(n);try{if(Array.isArray(n)){for(let i=0;i<n.length;i++){let s=B(n[i],e,t+1,o,r);s.length>0&&a.push({property:`[${i}]`,value:n[i],constraints:{},children:s})}return a}for(let i of ut(v(n))){let s=i.key,l=n[s];if(i.condition&&!i.condition(n)||i.isOptional&&l==null)continue;let u={property:s,value:i.redact?yn:l,constraints:{}},c={value:l,object:n,property:s,constraints:[]},y=!1;for(let m of i.constraints){c.constraints=m.constraints||[];let f=m.each&&Array.isArray(l)?ct(m,l,c):(()=>{let g=m.validate(l,c);return N(g)?g.then(D=>({ok:D,index:-1})):{ok:g,index:-1}})();if(N(f)){y=!0;let g={value:l,object:n,property:s,constraints:m.constraints||[]};r.push(f.then(({ok:D,index:V})=>{D||(V>=0&&(g.value=l[V]),fn(u.constraints,m.name,mn(m,g,V)))}));continue}if(!f.ok){f.index>=0&&(c.value=l[f.index]);let g=mn(m,c,f.index);c.value=l,fn(u.constraints,m.name,g)}}if(i.isNested&&l!==null&&l!==void 0){let m=B(l,e,t+1,o,r);m.length>0&&(u.children=m)}(y||Object.keys(u.constraints).length>0||u.children)&&a.push(u)}return a}finally{e.delete(n)}}function wn(n){let e=x(n);return{naming:F(e.namingStrategy),namingKey:e.namingStrategy,maxDepth:e.maxDepth}}function On(n){let e=x(n);return{naming:F(e.namingStrategy),namingKey:e.namingStrategy,unknownKeys:e.unknownKeys,maxDepth:e.maxDepth}}async function M(n,e){let t=[],o=B(n,new Set,0,x(e).maxDepth,t);return t.length===0?o:(await H(t),xn(o))}function j(n,e){let t=[],o=B(n,new Set,0,x(e).maxDepth,t);return X(t,"validateSync()","validate()"),o}async function Cn(n,e){let t=await M(n,e);if(t.length>0)throw new C("Validation failed",t)}function pt(n,e){let t=j(n,e);if(t.length>0)throw new C("Validation failed",t)}async function Y(n,e){if(n==null)return n;if(x(e).validate){let r=await M(n,e);if(r.length>0)throw new C("Validation failed during serialization",r)}let t=[],o=U(n,new Set,wn(e),0,t);return await H(t),o}function Tn(n,e){if(n==null)return n;if(x(e).validate){let r=j(n,e);if(r.length>0)throw new C("Validation failed during serialization",r)}let t=[],o=U(n,new Set,wn(e),0,t);return X(t,"toPlainSync()","toPlain()"),o}async function Dn(n,e){return JSON.stringify(await Y(n,e))}function ft(n,e){return JSON.stringify(Tn(n,e))}async function P(n,e,t){let o=[],r=k(n,e,On(t),0,o);if(await H(o),x(t).validate){let a=await M(r,t);if(a.length>0)throw new C("Validation failed during deserialization",a)}return r}function Q(n,e,t){let o=[],r=k(n,e,On(t),0,o);if(X(o,"toInstanceSync()","toInstance()"),x(t).validate){let a=j(r,t);if(a.length>0)throw new C("Validation failed during deserialization",a)}return r}function Vn(n,e){if(!Array.isArray(e))throw new b(`Expected an array to map to ${n.name}[], received ${typeof e}.`)}async function nn(n,e,t){return Vn(n,e),await P(n,e,t)}function $n(n,e,t){return Vn(n,e),Q(n,e,t)}async function kn(n,e,t){return P(n,_(e),t)}function mt(n,e,t){return Q(n,_(e),t)}async function Sn(n,e,t){return nn(n,_(e),t)}function yt(n,e,t){return $n(n,_(e),t)}function _(n){try{return JSON.parse(n)}catch(e){throw new b(`Input is not valid JSON: ${e instanceof Error?e.message:String(e)}`)}}async function En(n,e,t){let o;try{o=await e.json()}catch(r){throw new b(`Request body is not valid JSON: ${r instanceof Error?r.message:String(r)}`)}return P(n,o,t)}var G=class{static toPlain=Y;static toJson=Dn;static toInstance=P;static toInstanceArray=nn;static fromJson=kn;static fromJsonArray=Sn;static fromRequest=En;static validate=M;static validateOrReject=Cn};return Rn(gt);})();
|