From c828f5cfe9ecc0dac15979cc1dec7dfca8229900 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Aug 2026 10:03:16 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=BE=20feat:=20rebuild=20the=20landing?= =?UTF-8?q?=20page,=20and=20stop=20it=20from=20rotting=20again?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old page had been quietly broken for some time. It loaded @babel/standalone from an **unpinned** CDN URL, which rolled over to Babel 8 and dropped the `proposal-class-properties` plugin the page asked for, so Babel.transform threw before it ever reached the decorators — and the decorator config it passed was `{ legacy: true }`, which 0.2.0 had already made wrong. Nothing on the page said so. The copy was still selling the 0.1.0 pitch ("Spring-like"), listed about half the decorators, showed `npm install cereale` for a package the registry returns 404 for, and claimed "Zero overhead" against a README that publishes the real microsecond costs. The rebuild is one self-contained page: hand-written CSS, no Tailwind CDN, no CodeMirror, and a vendored compiler pinned by package.json. It loads nothing from the network. The playground runs the real bundled library across six examples, all verified in a headless browser. The reference covers all 68 decorators and the full API, counted from the bundle at runtime so it cannot drift. The hero's compiler error is not typed into the HTML. scripts/build-docs.mjs compiles the snippets with the real tsc and writes the verbatim diagnostics into docs/diagnostics.js, failing the build if a snippet the page calls a compile error ever compiles — and two snippets that must compile guard against the harness passing vacuously. Three guards keep it honest, all wired into CI: - check:docs fails on any remote subresource - build:docs + git diff fails if docs/ is stale against src/ - check:types compiles a consumer against dist/ with no DOM lib, no @types/node and no skipLibCheck That last one found a real packaging defect: `fromRequest` was declared as taking the global `Request`, so cereale's own published .d.ts raised "Cannot find name 'Request'" in any project whose lib and types did not happen to supply it — inside a dependency, in code they may never call, and unfixable from the outside. It now takes a structural JsonBody, which a Request still satisfies. The library's own type tests had been hiding it by enabling both DOM and skipLibCheck. An adversarial review of the finished page caught four more: the lede claimed *every* rule is type-checked (@IsDefined and @IsNotIn deliberately are not), the guarantee section was wrong about the mechanism (a legacy decorator does get design:type under emitDecoratorMetadata — the real claim is about its type signature), one sample called a Movie method on a Media[] and did not compile, and "nested objects come back as real classes" omitted that you have to declare them. WCAG contrast was measured rather than eyeballed: seven real failures fixed in the two themes. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01SAcqrz3FcadkYr3xG32CjK --- .github/workflows/ci.yml | 9 + CHANGELOG.md | 28 + README.md | 4 + docs/cereale.js | 4 +- docs/diagnostics.js | 29 + docs/index.html | 1082 +++++++++++++++++++++++++++++--------- docs/meta.js | 5 + docs/page.js | 554 +++++++++++++++++++ docs/vendor/README.md | 5 + docs/vendor/babel.min.js | 4 + package-lock.json | 11 + package.json | 11 +- scripts/build-docs.mjs | 81 +++ scripts/check-docs.mjs | 78 +++ scripts/check-types.mjs | 108 ++++ scripts/diagnostics.mjs | 210 ++++++++ src/type-safety.test.ts | 5 +- src/utils.ts | 14 +- 18 files changed, 1970 insertions(+), 272 deletions(-) create mode 100644 docs/diagnostics.js create mode 100644 docs/meta.js create mode 100644 docs/page.js create mode 100644 docs/vendor/README.md create mode 100644 docs/vendor/babel.min.js create mode 100644 scripts/build-docs.mjs create mode 100644 scripts/check-docs.mjs create mode 100644 scripts/check-types.mjs create mode 100644 scripts/diagnostics.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 202390f..250afa6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,3 +41,12 @@ jobs: node --input-type=commonjs -e "const { standardDecorators } = require('./dist/cjs/vite.js'); if (standardDecorators().enforce !== 'pre') throw new Error('CJS cereale/vite broken');" - name: Run Demo run: npm run demo + - name: Published types stand alone + run: npm run check:types + - name: Landing page loads nothing from the network + run: npm run check:docs + - name: Landing page bundle is in sync with src/ + run: | + npm run build:docs + git diff --exit-code -- docs/ \ + || (echo "docs/ is stale — run 'npm run build:docs' and commit the result" && exit 1) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34a0472..3a1cfb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,34 @@ came free with the bookkeeping. of them. - The plugin's TypeScript path emitted a `//# sourceMappingURL=` comment pointing at a file nobody wrote, which Vite followed and failed to read on every transformed module. +- `fromRequest` was declared as taking the global `Request`, so cereale's own published + `.d.ts` raised `Cannot find name 'Request'` in any project whose `lib` and `types` did not + happen to supply it — an error inside a dependency, in code the consumer may never call, + that they could not fix from the outside. It now takes a structural `JsonBody` + (`{ json(): Promise }`), which a `Request` still satisfies. The library's own type + tests had been hiding this by enabling both `DOM` and `skipLibCheck`; `npm run check:types` + now compiles a consumer against `dist/` with neither. + +### The landing page + +`docs/index.html` was rebuilt. Its playground had been dead for some time and said nothing +about it: the page loaded `@babel/standalone` from an **unpinned** CDN URL, which rolled over +to Babel 8 and dropped the `proposal-class-properties` plugin the page asked for, so +`Babel.transform` threw before it ever reached the decorators — and the decorator config it +passed was `{ legacy: true }`, which 0.2.0 had already made wrong. The copy was still selling +the 0.1.0 pitch ("Spring-like"), listed about half the decorators, and claimed "Zero overhead" +against a README that publishes the real microsecond costs. + +The rebuild is one self-contained page: hand-written CSS, no Tailwind CDN, no CodeMirror, and +a vendored compiler pinned by `package.json`. It loads **nothing** from the network, which +`npm run check:docs` now enforces in CI. The playground runs the real bundled library across +six examples; the reference lists all 68 decorators and the full API, counted from the bundle +at runtime so it cannot drift. + +The hero's compiler error is not typed into the HTML — `scripts/build-docs.mjs` compiles the +snippet with the real `tsc` and writes the verbatim diagnostic into `docs/diagnostics.js`, +failing the build if a snippet the page calls a compile error ever compiles. A third snippet +that must compile guards against the harness passing vacuously. ### Positioning diff --git a/README.md b/README.md index fe3fdb5..6717f65 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,10 @@ const user = fromJsonSync(User, body); // a real User user.greet(); // your methods are still there ``` +`docs/index.html` is a self-contained page with an interactive playground that runs this +library in the browser. Build its assets with `npm run build:docs` and open the file — it +loads nothing from the network. + ## Where it fits The stack Cereale replaces is **class-validator + class-transformer**: diff --git a/docs/cereale.js b/docs/cereale.js index a68c825..4c326e4 100644 --- a/docs/cereale.js +++ b/docs/cereale.js @@ -1,2 +1,2 @@ -"use strict";var Cereale=(()=>{var Z=Object.defineProperty;var Fn=Object.getOwnPropertyDescriptor;var Jn=Object.getOwnPropertyNames;var zn=Object.prototype.hasOwnProperty;var Bn=(n,e)=>{for(var t in e)Z(n,t,{get:e[t],enumerable:!0})},Un=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Jn(e))!zn.call(n,r)&&r!==t&&Z(n,r,{get:()=>e[r],enumerable:!(o=Fn(e,r))||o.enumerable});return n};var jn=n=>Un(Z({},"__esModule",{value:!0}),n);var kt={};Bn(kt,{Allow:()=>ae,ArrayContains:()=>at,ArrayMaxSize:()=>ot,ArrayMinSize:()=>tt,ArrayNotContains:()=>it,ArrayNotEmpty:()=>et,ArrayUnique:()=>rt,Contains:()=>Ke,Email:()=>Ve,EndsWith:()=>We,Equals:()=>Ge,IsAlpha:()=>Ee,IsAlphanumeric:()=>Ie,IsArray:()=>nt,IsBigInt:()=>de,IsBoolean:()=>ce,IsDate:()=>pe,IsDateString:()=>ve,IsDefined:()=>ye,IsDivisibleBy:()=>Oe,IsEmpty:()=>ge,IsEnum:()=>Xe,IsHexColor:()=>Ne,IsIP:()=>_e,IsIn:()=>He,IsInstance:()=>Qe,IsInt:()=>ue,IsJSON:()=>Fe,IsLatitude:()=>Te,IsLongitude:()=>ke,IsLowercase:()=>Me,IsNotEmpty:()=>me,IsNotIn:()=>Ye,IsNumber:()=>le,IsNumberString:()=>Pe,IsObject:()=>fe,IsOptional:()=>oe,IsPort:()=>Ce,IsSemVer:()=>Ae,IsString:()=>se,IsUUID:()=>je,IsUppercase:()=>Re,IsUrl:()=>Je,JsonAlias:()=>Zn,JsonDeserialize:()=>ne,JsonIgnore:()=>Hn,JsonMapper:()=>nn,JsonMappingError:()=>h,JsonPolymorphic:()=>te,JsonProperty:()=>Gn,JsonReadOnly:()=>Yn,JsonSerialize:()=>Qn,JsonType:()=>ee,JsonValidationError:()=>D,JsonWriteOnly:()=>Xn,Length:()=>$e,Matches:()=>ze,Max:()=>be,MaxDate:()=>lt,MaxLength:()=>Se,Min:()=>he,MinDate:()=>st,MinLength:()=>De,Negative:()=>xe,NotContains:()=>Le,NotEquals:()=>Ze,Positive:()=>we,REDACTED:()=>xn,StartsWith:()=>qe,Validate:()=>ut,ValidateIf:()=>re,ValidateNested:()=>ie,addConstraint:()=>M,collectErrorMessages:()=>dt,configure:()=>Ln,defineRule:()=>Kn,fieldMetadata:()=>b,flattenErrors:()=>X,formatErrors:()=>ct,fromJson:()=>Rn,fromJsonArray:()=>Pn,fromJsonArraySync:()=>Tt,fromJsonSync:()=>Ct,fromRequest:()=>vn,getConfig:()=>qn,modelOf:()=>z,modelOfInstance:()=>B,modelVersion:()=>S,propertyModel:()=>w,resetConfig:()=>Wn,resolveNamingStrategy:()=>U,resolveOptions:()=>x,toInstance:()=>J,toInstanceArray:()=>an,toInstanceArraySync:()=>Mn,toInstanceSync:()=>rn,toJson:()=>An,toJsonSync:()=>Ot,toPlain:()=>on,toPlainSync:()=>In,validate:()=>F,validateOrReject:()=>En,validateOrRejectSync:()=>xt,validateSync:()=>q});var $=Symbol.metadata??Symbol.for("Symbol.metadata");Symbol.metadata??=$;var N=Symbol.for("cereale.model"),ln=0;function S(){return ln}function _n(n){if(!Object.hasOwn(n,N)){let e=n[N],t={};for(let[o,r]of Object.entries(e??{}))t[o]={...r,constraints:[...r.constraints]};n[N]=t}return n[N]}function b(n){let e=n;if(typeof e!="object"||e===null||typeof e.kind!="string")throw new TypeError('cereale needs TC39 standard decorators, but the compiler emitted legacy ones. Set "experimentalDecorators": false in tsconfig.json (and drop "emitDecoratorMetadata"). The two decorator systems cannot coexist in one program, so a project that still needs legacy decorators for another library cannot use cereale yet.');if(e.kind!=="field")throw new TypeError(`cereale decorators apply to fields, but this one was applied to a ${e.kind}.`+(e.kind==="accessor"?" An `accessor` field keeps its value in a private slot that mapping and validation cannot reach \u2014 declare it as a plain field instead.":""));if(typeof e.metadata!="object"||e.metadata===null)throw new TypeError(`The decorator context for "${String(e.name)}" carries no metadata object, so cereale has nowhere to record the rule. The compiler emitted its decorator helpers without metadata support: make sure cereale is imported before the decorated class is evaluated (importing it installs the Symbol.metadata fallback) and that the build targets ES2022 or later.`);return e.metadata}function w(n,e){ln++;let t=_n(n);return t[e]??={constraints:[]}}function M(n,e,t,o){o?.each&&(t.each=!0),o?.message&&(t.message=o.message,t.hasCustomMessage=!0),w(n,e).constraints.push(t)}function z(n){return typeof n!="function"?{}:n[$]?.[N]??{}}function B(n){let e=Object.getPrototypeOf(n);if(!e)return{};let t=Object.getOwnPropertyDescriptor(e,"constructor");return z(t?.value)}function Kn(n,e,t,o){let r=n;Object.hasOwn(r,$)||(r[$]=Object.create(r[$]??null)),M(r[$],e,t,o)}function R(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 un=n=>n&&n.charAt(0).toUpperCase()+n.slice(1),H={identity:n=>n,camelCase:n=>{let e=R(n);return e.length===0?n:e[0]+e.slice(1).map(un).join("")},PascalCase:n=>R(n).map(un).join("")||n,snake_case:n=>R(n).join("_")||n,SCREAMING_SNAKE_CASE:n=>R(n).join("_").toUpperCase()||n,"kebab-case":n=>R(n).join("-")||n};function U(n){if(!n)return H.identity;if(typeof n=="function")return n;let e=H[n];if(!e)throw new Error(`Unknown naming strategy ${JSON.stringify(n)}. Use one of: ${Object.keys(H).join(", ")}, or pass your own function.`);return e}var cn={namingStrategy:"identity",unknownKeys:"allow",validate:!0,maxDepth:64},k={...cn};function Ln(n){k={...k,...n}}function qn(){return{...k}}function Wn(){k={...cn}}function x(n){return n?{namingStrategy:n.namingStrategy??k.namingStrategy,unknownKeys:n.unknownKeys??k.unknownKeys,validate:n.validate??k.validate,maxDepth:n.maxDepth??k.maxDepth}:k}function y(n,e){return((t,o)=>{let r=String(o.name);M(b(o),r,n(r),e)})}function m(n,e,t){return(o=>y(r=>({name:n,validate:e,message:t(r)}),o))}function P(n,e,t){return m(n,o=>typeof o=="string"&&e.test(o),t)}function Gn(n){return((e,t)=>{w(b(t),String(t.name)).name=n})}function Zn(...n){return((e,t)=>{let o=w(b(t),String(t.name));o.aliases=[...o.aliases??[],...n]})}function Y(n){return((e,t)=>{w(b(t),String(t.name)).access=n})}var Hn=()=>Y("none"),Yn=()=>Y("readonly"),Xn=()=>Y("writeonly");function Qn(n){return((e,t)=>{w(b(t),String(t.name)).serializer=n})}function ne(n){return((e,t)=>{w(b(t),String(t.name)).deserializer=n})}function ee(n){return((e,t)=>{w(b(t),String(t.name)).type=n})}function te(n,e,t){return((o,r)=>{let a={discriminator:n,subTypes:e,onUnknown:t?.onUnknown??"keep",...t?.fallback?{fallback:t.fallback}:{}};w(b(r),String(r.name)).polymorphic=a})}function oe(){return((n,e)=>{w(b(e),String(e.name)).optional=!0})}function re(n){return((e,t)=>{w(b(t),String(t.name)).condition=n})}function ae(){return((n,e)=>{w(b(e),String(e.name))})}function ie(n){return((e,t)=>{let o=b(t),r=String(t.name);w(o,r).nested=!0,n?.each&&M(o,r,{name:"nestedEach",validate:a=>Array.isArray(a),message:`${r} must be an array`})})}var se=m("isString",n=>typeof n=="string",n=>`${n} must be a string`),le=m("isNumber",n=>typeof n=="number"&&!isNaN(n),n=>`${n} must be a number`),ue=m("isInt",n=>Number.isInteger(n),n=>`${n} must be an integer`),ce=m("isBoolean",n=>typeof n=="boolean",n=>`${n} must be a boolean`),de=m("isBigInt",n=>typeof n=="bigint",n=>`${n} must be a bigint`),pe=m("isDate",n=>n instanceof Date&&!isNaN(n.getTime()),n=>`${n} must be a valid Date object`),fe=m("isObject",n=>typeof n=="object"&&n!==null&&!Array.isArray(n),n=>`${n} must be an object`),ye=m("isDefined",n=>n!=null,n=>`${n} should not be null or undefined`),me=m("isNotEmpty",n=>n!=null&&n!=="",n=>`${n} should not be empty`),ge=m("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 he(n,e){return y(t=>({name:"min",validate:o=>typeof o=="number"&&o>=n,message:`${t} must be at least ${n}`,constraints:[n]}),e)}function be(n,e){return y(t=>({name:"max",validate:o=>typeof o=="number"&&o<=n,message:`${t} must be at most ${n}`,constraints:[n]}),e)}var we=m("positive",n=>typeof n=="number"&&n>0,n=>`${n} must be positive`),xe=m("negative",n=>typeof n=="number"&&n<0,n=>`${n} must be negative`);function Oe(n,e){return y(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 Ce=m("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`),Te=m("isLatitude",n=>typeof n=="number"&&Number.isFinite(n)&&n>=-90&&n<=90,n=>`${n} must be a latitude between -90 and 90`),ke=m("isLongitude",n=>typeof n=="number"&&Number.isFinite(n)&&n>=-180&&n<=180,n=>`${n} must be a longitude between -180 and 180`);function De(n,e){return y(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 Se(n,e){return y(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 $e(n,e,t){return y(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 Ve=P("isEmail",/^[^\s@]+@[^\s@]+\.[^\s@]+$/,n=>`${n} must be a valid email`),Ee=P("isAlpha",/^[A-Za-z]+$/,n=>`${n} must contain only letters`),Ie=P("isAlphanumeric",/^[A-Za-z0-9]+$/,n=>`${n} must contain only letters and numbers`),Ae=P("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`),Ne=P("isHexColor",/^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i,n=>`${n} must be a hex color`),Me=m("isLowercase",n=>typeof n=="string"&&n===n.toLowerCase(),n=>`${n} must be lowercase`),Re=m("isUppercase",n=>typeof n=="string"&&n===n.toUpperCase(),n=>`${n} must be uppercase`),Pe=m("isNumberString",n=>typeof n=="string"&&n.trim()!==""&&Number.isFinite(Number(n)),n=>`${n} must be a number string`),ve=m("isDateString",n=>typeof n=="string"&&!isNaN(Date.parse(n)),n=>`${n} must be a valid ISO 8601 date string`),Fe=m("isJson",n=>{if(typeof n!="string")return!1;try{return JSON.parse(n),!0}catch{return!1}},n=>`${n} must be a JSON string`),Je=m("isUrl",n=>{try{return new URL(n),!0}catch{return!1}},n=>`${n} must be a valid URL`);function ze(n,e){let t=n.flags.includes("g")||n.flags.includes("y")?new RegExp(n.source,n.flags.replace(/[gy]/g,"")):n;return y(o=>({name:"matches",validate:r=>typeof r=="string"&&t.test(r),message:`${o} must match ${n} regular expression`,constraints:[n]}),e)}var Be="00000000-0000-0000-0000-000000000000",Ue="ffffffff-ffff-ffff-ffff-ffffffffffff";function je(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 y(o=>({name:"isUuid",validate:r=>typeof r!="string"?!1:!n&&(r.toLowerCase()===Be||r.toLowerCase()===Ue)?!0:t.test(r),message:`${o} must be a valid UUID${n?` (version ${n})`:""}`,...n?{constraints:[n]}:{}}),e)}var dn=/^(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}$/,pn=n=>{try{return new URL(`http://[${n}]`).hostname===`[${n.toLowerCase()}]`||/^[0-9a-f:.]+$/i.test(n)&&n.includes(":")}catch{return!1}};function _e(n,e){return y(t=>({name:"isIp",validate:o=>typeof o!="string"?!1:n===4?dn.test(o):n===6?pn(o):dn.test(o)||pn(o),message:`${t} must be a valid IP${n?`v${n}`:""} address`,...n?{constraints:[n]}:{}}),e)}function _(n,e,t){function o(r,a){return y(i=>({name:n,validate:s=>typeof s=="string"&&e(s,r),message:t(i,r),constraints:[r]}),a)}return o}var Ke=_("contains",(n,e)=>n.includes(e),(n,e)=>`${n} must contain ${JSON.stringify(e)}`),Le=_("notContains",(n,e)=>!n.includes(e),(n,e)=>`${n} must not contain ${JSON.stringify(e)}`),qe=_("startsWith",(n,e)=>n.startsWith(e),(n,e)=>`${n} must start with ${JSON.stringify(e)}`),We=_("endsWith",(n,e)=>n.endsWith(e),(n,e)=>`${n} must end with ${JSON.stringify(e)}`);function Ge(n,e){return y(t=>({name:"equals",validate:o=>o===n,message:`${t} must be equal to ${JSON.stringify(n)}`,constraints:[n]}),e)}function Ze(n,e){return y(t=>({name:"notEquals",validate:o=>o!==n,message:`${t} must not be equal to ${JSON.stringify(n)}`,constraints:[n]}),e)}function He(n,e){return y(t=>({name:"isIn",validate:o=>n.includes(o),message:`${t} must be one of the following values: ${n.join(", ")}`,constraints:[n]}),e)}function Ye(n,e){return y(t=>({name:"isNotIn",validate:o=>!n.includes(o),message:`${t} must not be one of the following values: ${n.join(", ")}`,constraints:[n]}),e)}function Xe(n,e){let t=Object.keys(n).filter(o=>typeof n[n[o]]!="number").map(o=>n[o]);return y(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 y(t=>({name:"isInstance",validate:o=>o instanceof n,message:`${t} must be an instance of ${n.name}`,constraints:[n]}),e)}function V(n,e,t,o){return r=>y(a=>({name:n,validate:i=>Array.isArray(i)&&e(i),message:t(a),...o?{constraints:o}:{}}),r)}var nt=n=>y(e=>({name:"isArray",validate:t=>Array.isArray(t),message:`${e} must be an array`}),n),et=n=>V("arrayNotEmpty",e=>e.length>0,e=>`${e} should not be empty`)(n),tt=(n,e)=>V("arrayMinSize",t=>t.length>=n,t=>`${t} must contain at least ${n} elements`,[n])(e),ot=(n,e)=>V("arrayMaxSize",t=>t.length<=n,t=>`${t} must contain at most ${n} elements`,[n])(e);function rt(n,e){return V("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 at(n,e){return V("arrayContains",t=>n.every(o=>t.includes(o)),t=>`${t} must contain the following values: ${n.join(", ")}`,[n])(e)}function it(n,e){return V("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 st(n,e){return y(()=>({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 lt(n,e){return y(()=>({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 ut(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 y(()=>({name:"custom",validate:(l,u)=>s(l,u),message:l=>`${l.property} is invalid`,constraints:o}),r)}let i=new n;return y(()=>({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 X(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 ct(n){let e=X(n);return Object.entries(e).flatMap(([t,o])=>o.map(r=>`${t}: ${r}`)).join(` -`)}function dt(n){return Object.values(X(n)).flat()}var D=class extends Error{constructor(t,o){super(t);this.errors=o;this.name="JsonValidationError"}toString(){return`${this.message}: ${JSON.stringify(this.errors,null,2)}`}},h=class extends Error{constructor(e){super(e),this.name="JsonMappingError"}},pt=new Set(["__proto__","constructor","prototype"]),xn="[redacted]";function On(n,e){return n[e]?.access??"readwrite"}function Cn(n,e,t){return n[e]?.name??t(e)}var fn=new WeakMap;function ft(n,e,t){let o=fn.get(n);(!o||o.version!==S())&&(o={version:S(),byStrategy:new Map},fn.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=On(n,e),s=n[e]?.serializer;a={name:Cn(n,e,t.naming),skip:i==="none"||i==="writeonly",...s?{serializer:s}:{}},r.set(e,a)}return a}var yn=new WeakMap;function yt(n,e){let t=yn.get(n);(!t||t.version!==S())&&(t={version:S(),byStrategy:new Map},yn.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 p=r.get(u);if(p&&p!==c)throw new h(`Properties "${p}" 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 p=[Cn(n,u,e.naming),...c.aliases??[]],f=On(n,u);if(f==="none"||f==="readonly"){for(let d of p)a.add(d);continue}for(let d of p)s(d,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 v(n){return n!==null&&typeof n=="object"&&typeof n.then=="function"}async function en(n){for(;n.length>0;){let e=n.splice(0,n.length);await Promise.all(e)}}function tn(n,e,t){if(n.length!==0){for(let o of n)o.catch(()=>{});throw n.length=0,new h(`${e} requires every serializer, deserializer and validator to be synchronous, but one returned a Promise. Use ${t} instead, or make the hook synchronous.`)}}var mt={Map:"a Map",Set:"a Set",WeakMap:"a WeakMap",WeakSet:"a WeakSet",WeakRef:"a WeakRef",Promise:"a Promise",ArrayBuffer:"an ArrayBuffer",SharedArrayBuffer:"a SharedArrayBuffer",DataView:"a DataView",Generator:"a generator",AsyncGenerator:"an async generator"};function Tn(n){let e=n[Symbol.toStringTag];if(typeof e=="string"){let t=mt[e];if(t!==void 0)return t;if(ArrayBuffer.isView(n))return`a ${e}`}return n instanceof RegExp?"a RegExp":n instanceof Error?"an Error, whose message and stack are not enumerable":null}function mn(n){switch(typeof n){case"bigint":return kn;case"symbol":return"a symbol";case"function":return"a function";case"object":return n===null?null:Tn(n);default:return null}}var kn="a bigint, which JSON has no representation for";function Q(n){if(n.length===0)return"the value passed in";let e="";for(let t of n)typeof t=="number"?e+=`[${t}]`:e+=e===""?t:`.${t}`;return e}function E(n,e){throw new h(`${Q(e)} is ${n}, which cannot be serialized to JSON. Give the property a @JsonSerialize() serializer that converts it, or drop it from the output with @JsonIgnore().`)}function K(n,e,t,o,r,a){if(n==null)return n;let i=typeof n;if(i!=="object")return i==="bigint"&&E(kn,a),i==="symbol"&&E("a symbol",a),i==="function"&&E("a function",a),n;if(o>t.maxDepth)throw new h(`Maximum nesting depth of ${t.maxDepth} exceeded while serializing at ${Q(a)}. Raise it with the maxDepth option if this structure is legitimate.`);if(n instanceof Date)return n.toISOString();let s=Array.isArray(n);if(!s){let l=Tn(n);l!==null&&E(l,a)}if(e.has(n))throw new h(`Circular reference detected during serialization at ${Q(a)}. Break the cycle with @JsonIgnore() on the back-reference, or supply a @JsonSerialize() serializer for that property.`);e.add(n);try{if(s){let c=[];for(let p=0;p{let A=mn(C);A!==null&&E(A,O),u[g]=C}))}else{let g=mn(d);g!==null&&E(g,a),u[p.name]=d}}else u[p.name]=K(f,e,t,o+1,r,a);a.pop()}return u}finally{e.delete(n)}}function I(n,e,t,o,r){if(e==null)return e;if(o>t.maxDepth)throw new h(`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=>I(n,s,t,o+1,r));if(typeof e!="object")return e;let a=new n,i=yt(z(n),t);for(let s of Object.keys(e)){if(pt.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 h(`Unknown property ${JSON.stringify(s)} for ${n.name}. Allowed: ${[...i.accept.keys()].map(d=>JSON.stringify(d)).join(", ")||"(none declared)"}.`);a[s]=e[s];continue}let u=e[s],c=i.props.get(l);if(c?.deserializer){let d=Dn(c.deserializer).deserialize(u);if(v(d)){let g=l;a[g]=void 0,r.push(d.then(O=>{a[g]=O}))}else a[l]=d;continue}let p=c?.polymorphic;if(p&&u!==null&&u!==void 0){let{discriminator:d,subTypes:g,onUnknown:O,fallback:C}=p,A=T=>{if(T==null||typeof T!="object")return T;let sn=g.find(G=>T[d]===G.name);if(sn)return I(sn.value,T,t,o+1,r);if(C)return I(C,T,t,o+1,r);if(O==="error")throw new h(`Unknown discriminator value ${JSON.stringify(T[d])} for property "${l}". Known values: ${g.map(G=>JSON.stringify(G.name)).join(", ")}.`);return T};a[l]=Array.isArray(u)?u.map(A):A(u);continue}let f=c?.typeFn;if(f&&u!==null&&u!==void 0){let d=f();a[l]=I(d,u,t,o+1,r);continue}a[l]=u}return a}var gn=new WeakMap;function gt(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 ht(n){let e=gn.get(n);if(e&&e.version===S())return e.plan;let t=[];for(let[o,r]of Object.entries(n)){let a=r.access??"readwrite";t.push({key:o,constraints:gt(r.constraints),isOptional:!!r.optional,isNested:!!r.nested,redact:a==="writeonly"||a==="none",...r.condition?{condition:r.condition}:{}})}return gn.set(n,{version:S(),plan:t}),t}var hn=new WeakMap;function Dn(n){let e=hn.get(n);return e||(e=new n,hn.set(n,e)),e}function bn(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 wn(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 bt(n,e,t){for(let o=0;o0?t.children=o:delete t.children,(Object.keys(t.constraints).length>0||t.children)&&e.push(t)}return e}function L(n,e,t,o,r){let a=[];if(n==null||typeof n!="object")return a;if(t>o)throw new h(`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;i0&&a.push({property:`[${i}]`,value:n[i],constraints:{},children:s})}return a}for(let i of ht(B(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?xn:l,constraints:{}},c={value:l,object:n,property:s,constraints:[]},p=!1;for(let f of i.constraints){c.constraints=f.constraints||[];let d=f.each&&Array.isArray(l)?bt(f,l,c):(()=>{let g=f.validate(l,c);return v(g)?g.then(O=>({ok:O,index:-1})):{ok:g,index:-1}})();if(v(d)){p=!0;let g={value:l,object:n,property:s,constraints:f.constraints||[]};r.push(d.then(({ok:O,index:C})=>{O||(C>=0&&(g.value=l[C]),bn(u.constraints,f.name,wn(f,g,C)))}));continue}if(!d.ok){d.index>=0&&(c.value=l[d.index]);let g=wn(f,c,d.index);c.value=l,bn(u.constraints,f.name,g)}}if(i.isNested&&l!==null&&l!==void 0){let f=L(l,e,t+1,o,r);f.length>0&&(u.children=f)}(p||Object.keys(u.constraints).length>0||u.children)&&a.push(u)}return a}finally{e.delete(n)}}function $n(n){let e=x(n);return{naming:U(e.namingStrategy),namingKey:e.namingStrategy,maxDepth:e.maxDepth}}function Vn(n){let e=x(n);return{naming:U(e.namingStrategy),namingKey:e.namingStrategy,unknownKeys:e.unknownKeys,maxDepth:e.maxDepth}}async function F(n,e){let t=[],o=L(n,new Set,0,x(e).maxDepth,t);return t.length===0?o:(await en(t),Sn(o))}function q(n,e){let t=[],o=L(n,new Set,0,x(e).maxDepth,t);return tn(t,"validateSync()","validate()"),o}async function En(n,e){let t=await F(n,e);if(t.length>0)throw new D("Validation failed",t)}function xt(n,e){let t=q(n,e);if(t.length>0)throw new D("Validation failed",t)}async function on(n,e){if(n==null)return n;if(x(e).validate){let r=await F(n,e);if(r.length>0)throw new D("Validation failed during serialization",r)}let t=[],o=K(n,new Set,$n(e),0,t,[]);return await en(t),o}function In(n,e){if(n==null)return n;if(x(e).validate){let r=q(n,e);if(r.length>0)throw new D("Validation failed during serialization",r)}let t=[],o=K(n,new Set,$n(e),0,t,[]);return tn(t,"toPlainSync()","toPlain()"),o}async function An(n,e){return JSON.stringify(await on(n,e))}function Ot(n,e){return JSON.stringify(In(n,e))}async function J(n,e,t){let o=[],r=I(n,e,Vn(t),0,o);if(await en(o),x(t).validate){let a=await F(r,t);if(a.length>0)throw new D("Validation failed during deserialization",a)}return r}function rn(n,e,t){let o=[],r=I(n,e,Vn(t),0,o);if(tn(o,"toInstanceSync()","toInstance()"),x(t).validate){let a=q(r,t);if(a.length>0)throw new D("Validation failed during deserialization",a)}return r}function Nn(n,e){if(!Array.isArray(e))throw new h(`Expected an array to map to ${n.name}[], received ${typeof e}.`)}async function an(n,e,t){return Nn(n,e),await J(n,e,t)}function Mn(n,e,t){return Nn(n,e),rn(n,e,t)}async function Rn(n,e,t){return J(n,W(e),t)}function Ct(n,e,t){return rn(n,W(e),t)}async function Pn(n,e,t){return an(n,W(e),t)}function Tt(n,e,t){return Mn(n,W(e),t)}function W(n){try{return JSON.parse(n)}catch(e){throw new h(`Input is not valid JSON: ${e instanceof Error?e.message:String(e)}`)}}async function vn(n,e,t){let o;try{o=await e.json()}catch(r){throw new h(`Request body is not valid JSON: ${r instanceof Error?r.message:String(r)}`)}return J(n,o,t)}var nn=class{static toPlain=on;static toJson=An;static toInstance=J;static toInstanceArray=an;static fromJson=Rn;static fromJsonArray=Pn;static fromRequest=vn;static validate=F;static validateOrReject=En};return jn(kt);})(); +var Cereale=(()=>{var Z=Object.defineProperty;var Fn=Object.getOwnPropertyDescriptor;var Jn=Object.getOwnPropertyNames;var zn=Object.prototype.hasOwnProperty;var Bn=(n,e)=>{for(var t in e)Z(n,t,{get:e[t],enumerable:!0})},Un=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Jn(e))!zn.call(n,r)&&r!==t&&Z(n,r,{get:()=>e[r],enumerable:!(o=Fn(e,r))||o.enumerable});return n};var jn=n=>Un(Z({},"__esModule",{value:!0}),n);var kt={};Bn(kt,{Allow:()=>ae,ArrayContains:()=>at,ArrayMaxSize:()=>ot,ArrayMinSize:()=>tt,ArrayNotContains:()=>it,ArrayNotEmpty:()=>et,ArrayUnique:()=>rt,Contains:()=>Ke,Email:()=>Ve,EndsWith:()=>We,Equals:()=>Ge,IsAlpha:()=>Ee,IsAlphanumeric:()=>Ie,IsArray:()=>nt,IsBigInt:()=>de,IsBoolean:()=>ce,IsDate:()=>pe,IsDateString:()=>ve,IsDefined:()=>ye,IsDivisibleBy:()=>Oe,IsEmpty:()=>ge,IsEnum:()=>Xe,IsHexColor:()=>Ne,IsIP:()=>_e,IsIn:()=>He,IsInstance:()=>Qe,IsInt:()=>ue,IsJSON:()=>Fe,IsLatitude:()=>Te,IsLongitude:()=>ke,IsLowercase:()=>Me,IsNotEmpty:()=>me,IsNotIn:()=>Ye,IsNumber:()=>le,IsNumberString:()=>Re,IsObject:()=>fe,IsOptional:()=>oe,IsPort:()=>Ce,IsSemVer:()=>Ae,IsString:()=>se,IsUUID:()=>je,IsUppercase:()=>Pe,IsUrl:()=>Je,JsonAlias:()=>Zn,JsonDeserialize:()=>ne,JsonIgnore:()=>Hn,JsonMapper:()=>nn,JsonMappingError:()=>h,JsonPolymorphic:()=>te,JsonProperty:()=>Gn,JsonReadOnly:()=>Yn,JsonSerialize:()=>Qn,JsonType:()=>ee,JsonValidationError:()=>D,JsonWriteOnly:()=>Xn,Length:()=>$e,Matches:()=>ze,Max:()=>be,MaxDate:()=>lt,MaxLength:()=>Se,Min:()=>he,MinDate:()=>st,MinLength:()=>De,Negative:()=>xe,NotContains:()=>Le,NotEquals:()=>Ze,Positive:()=>we,REDACTED:()=>xn,StartsWith:()=>qe,Validate:()=>ut,ValidateIf:()=>re,ValidateNested:()=>ie,addConstraint:()=>M,collectErrorMessages:()=>dt,configure:()=>Ln,defineRule:()=>Kn,fieldMetadata:()=>b,flattenErrors:()=>X,formatErrors:()=>ct,fromJson:()=>Pn,fromJsonArray:()=>Rn,fromJsonArraySync:()=>Tt,fromJsonSync:()=>Ct,fromRequest:()=>vn,getConfig:()=>qn,modelOf:()=>z,modelOfInstance:()=>B,modelVersion:()=>S,propertyModel:()=>w,resetConfig:()=>Wn,resolveNamingStrategy:()=>U,resolveOptions:()=>x,toInstance:()=>J,toInstanceArray:()=>an,toInstanceArraySync:()=>Mn,toInstanceSync:()=>rn,toJson:()=>An,toJsonSync:()=>Ot,toPlain:()=>on,toPlainSync:()=>In,validate:()=>F,validateOrReject:()=>En,validateOrRejectSync:()=>xt,validateSync:()=>q});var $=Symbol.metadata??Symbol.for("Symbol.metadata");Symbol.metadata??=$;var N=Symbol.for("cereale.model"),ln=0;function S(){return ln}function _n(n){if(!Object.hasOwn(n,N)){let e=n[N],t={};for(let[o,r]of Object.entries(e??{}))t[o]={...r,constraints:[...r.constraints]};n[N]=t}return n[N]}function b(n){let e=n;if(typeof e!="object"||e===null||typeof e.kind!="string")throw new TypeError('cereale needs TC39 standard decorators, but the compiler emitted legacy ones. Set "experimentalDecorators": false in tsconfig.json (and drop "emitDecoratorMetadata"). The two decorator systems cannot coexist in one program, so a project that still needs legacy decorators for another library cannot use cereale yet.');if(e.kind!=="field")throw new TypeError(`cereale decorators apply to fields, but this one was applied to a ${e.kind}.`+(e.kind==="accessor"?" An `accessor` field keeps its value in a private slot that mapping and validation cannot reach \u2014 declare it as a plain field instead.":""));if(typeof e.metadata!="object"||e.metadata===null)throw new TypeError(`The decorator context for "${String(e.name)}" carries no metadata object, so cereale has nowhere to record the rule. The compiler emitted its decorator helpers without metadata support: make sure cereale is imported before the decorated class is evaluated (importing it installs the Symbol.metadata fallback) and that the build targets ES2022 or later.`);return e.metadata}function w(n,e){ln++;let t=_n(n);return t[e]??={constraints:[]}}function M(n,e,t,o){o?.each&&(t.each=!0),o?.message&&(t.message=o.message,t.hasCustomMessage=!0),w(n,e).constraints.push(t)}function z(n){return typeof n!="function"?{}:n[$]?.[N]??{}}function B(n){let e=Object.getPrototypeOf(n);if(!e)return{};let t=Object.getOwnPropertyDescriptor(e,"constructor");return z(t?.value)}function Kn(n,e,t,o){let r=n;Object.hasOwn(r,$)||(r[$]=Object.create(r[$]??null)),M(r[$],e,t,o)}function P(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 un=n=>n&&n.charAt(0).toUpperCase()+n.slice(1),H={identity:n=>n,camelCase:n=>{let e=P(n);return e.length===0?n:e[0]+e.slice(1).map(un).join("")},PascalCase:n=>P(n).map(un).join("")||n,snake_case:n=>P(n).join("_")||n,SCREAMING_SNAKE_CASE:n=>P(n).join("_").toUpperCase()||n,"kebab-case":n=>P(n).join("-")||n};function U(n){if(!n)return H.identity;if(typeof n=="function")return n;let e=H[n];if(!e)throw new Error(`Unknown naming strategy ${JSON.stringify(n)}. Use one of: ${Object.keys(H).join(", ")}, or pass your own function.`);return e}var cn={namingStrategy:"identity",unknownKeys:"allow",validate:!0,maxDepth:64},k={...cn};function Ln(n){k={...k,...n}}function qn(){return{...k}}function Wn(){k={...cn}}function x(n){return n?{namingStrategy:n.namingStrategy??k.namingStrategy,unknownKeys:n.unknownKeys??k.unknownKeys,validate:n.validate??k.validate,maxDepth:n.maxDepth??k.maxDepth}:k}function y(n,e){return((t,o)=>{let r=String(o.name);M(b(o),r,n(r),e)})}function m(n,e,t){return(o=>y(r=>({name:n,validate:e,message:t(r)}),o))}function R(n,e,t){return m(n,o=>typeof o=="string"&&e.test(o),t)}function Gn(n){return((e,t)=>{w(b(t),String(t.name)).name=n})}function Zn(...n){return((e,t)=>{let o=w(b(t),String(t.name));o.aliases=[...o.aliases??[],...n]})}function Y(n){return((e,t)=>{w(b(t),String(t.name)).access=n})}var Hn=()=>Y("none"),Yn=()=>Y("readonly"),Xn=()=>Y("writeonly");function Qn(n){return((e,t)=>{w(b(t),String(t.name)).serializer=n})}function ne(n){return((e,t)=>{w(b(t),String(t.name)).deserializer=n})}function ee(n){return((e,t)=>{w(b(t),String(t.name)).type=n})}function te(n,e,t){return((o,r)=>{let a={discriminator:n,subTypes:e,onUnknown:t?.onUnknown??"keep",...t?.fallback?{fallback:t.fallback}:{}};w(b(r),String(r.name)).polymorphic=a})}function oe(){return((n,e)=>{w(b(e),String(e.name)).optional=!0})}function re(n){return((e,t)=>{w(b(t),String(t.name)).condition=n})}function ae(){return((n,e)=>{w(b(e),String(e.name))})}function ie(n){return((e,t)=>{let o=b(t),r=String(t.name);w(o,r).nested=!0,n?.each&&M(o,r,{name:"nestedEach",validate:a=>Array.isArray(a),message:`${r} must be an array`})})}var se=m("isString",n=>typeof n=="string",n=>`${n} must be a string`),le=m("isNumber",n=>typeof n=="number"&&!isNaN(n),n=>`${n} must be a number`),ue=m("isInt",n=>Number.isInteger(n),n=>`${n} must be an integer`),ce=m("isBoolean",n=>typeof n=="boolean",n=>`${n} must be a boolean`),de=m("isBigInt",n=>typeof n=="bigint",n=>`${n} must be a bigint`),pe=m("isDate",n=>n instanceof Date&&!isNaN(n.getTime()),n=>`${n} must be a valid Date object`),fe=m("isObject",n=>typeof n=="object"&&n!==null&&!Array.isArray(n),n=>`${n} must be an object`),ye=m("isDefined",n=>n!=null,n=>`${n} should not be null or undefined`),me=m("isNotEmpty",n=>n!=null&&n!=="",n=>`${n} should not be empty`),ge=m("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 he(n,e){return y(t=>({name:"min",validate:o=>typeof o=="number"&&o>=n,message:`${t} must be at least ${n}`,constraints:[n]}),e)}function be(n,e){return y(t=>({name:"max",validate:o=>typeof o=="number"&&o<=n,message:`${t} must be at most ${n}`,constraints:[n]}),e)}var we=m("positive",n=>typeof n=="number"&&n>0,n=>`${n} must be positive`),xe=m("negative",n=>typeof n=="number"&&n<0,n=>`${n} must be negative`);function Oe(n,e){return y(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 Ce=m("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`),Te=m("isLatitude",n=>typeof n=="number"&&Number.isFinite(n)&&n>=-90&&n<=90,n=>`${n} must be a latitude between -90 and 90`),ke=m("isLongitude",n=>typeof n=="number"&&Number.isFinite(n)&&n>=-180&&n<=180,n=>`${n} must be a longitude between -180 and 180`);function De(n,e){return y(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 Se(n,e){return y(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 $e(n,e,t){return y(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 Ve=R("isEmail",/^[^\s@]+@[^\s@]+\.[^\s@]+$/,n=>`${n} must be a valid email`),Ee=R("isAlpha",/^[A-Za-z]+$/,n=>`${n} must contain only letters`),Ie=R("isAlphanumeric",/^[A-Za-z0-9]+$/,n=>`${n} must contain only letters and numbers`),Ae=R("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`),Ne=R("isHexColor",/^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i,n=>`${n} must be a hex color`),Me=m("isLowercase",n=>typeof n=="string"&&n===n.toLowerCase(),n=>`${n} must be lowercase`),Pe=m("isUppercase",n=>typeof n=="string"&&n===n.toUpperCase(),n=>`${n} must be uppercase`),Re=m("isNumberString",n=>typeof n=="string"&&n.trim()!==""&&Number.isFinite(Number(n)),n=>`${n} must be a number string`),ve=m("isDateString",n=>typeof n=="string"&&!isNaN(Date.parse(n)),n=>`${n} must be a valid ISO 8601 date string`),Fe=m("isJson",n=>{if(typeof n!="string")return!1;try{return JSON.parse(n),!0}catch{return!1}},n=>`${n} must be a JSON string`),Je=m("isUrl",n=>{try{return new URL(n),!0}catch{return!1}},n=>`${n} must be a valid URL`);function ze(n,e){let t=n.flags.includes("g")||n.flags.includes("y")?new RegExp(n.source,n.flags.replace(/[gy]/g,"")):n;return y(o=>({name:"matches",validate:r=>typeof r=="string"&&t.test(r),message:`${o} must match ${n} regular expression`,constraints:[n]}),e)}var Be="00000000-0000-0000-0000-000000000000",Ue="ffffffff-ffff-ffff-ffff-ffffffffffff";function je(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 y(o=>({name:"isUuid",validate:r=>typeof r!="string"?!1:!n&&(r.toLowerCase()===Be||r.toLowerCase()===Ue)?!0:t.test(r),message:`${o} must be a valid UUID${n?` (version ${n})`:""}`,...n?{constraints:[n]}:{}}),e)}var dn=/^(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}$/,pn=n=>{try{return new URL(`http://[${n}]`).hostname===`[${n.toLowerCase()}]`||/^[0-9a-f:.]+$/i.test(n)&&n.includes(":")}catch{return!1}};function _e(n,e){return y(t=>({name:"isIp",validate:o=>typeof o!="string"?!1:n===4?dn.test(o):n===6?pn(o):dn.test(o)||pn(o),message:`${t} must be a valid IP${n?`v${n}`:""} address`,...n?{constraints:[n]}:{}}),e)}function _(n,e,t){function o(r,a){return y(i=>({name:n,validate:s=>typeof s=="string"&&e(s,r),message:t(i,r),constraints:[r]}),a)}return o}var Ke=_("contains",(n,e)=>n.includes(e),(n,e)=>`${n} must contain ${JSON.stringify(e)}`),Le=_("notContains",(n,e)=>!n.includes(e),(n,e)=>`${n} must not contain ${JSON.stringify(e)}`),qe=_("startsWith",(n,e)=>n.startsWith(e),(n,e)=>`${n} must start with ${JSON.stringify(e)}`),We=_("endsWith",(n,e)=>n.endsWith(e),(n,e)=>`${n} must end with ${JSON.stringify(e)}`);function Ge(n,e){return y(t=>({name:"equals",validate:o=>o===n,message:`${t} must be equal to ${JSON.stringify(n)}`,constraints:[n]}),e)}function Ze(n,e){return y(t=>({name:"notEquals",validate:o=>o!==n,message:`${t} must not be equal to ${JSON.stringify(n)}`,constraints:[n]}),e)}function He(n,e){return y(t=>({name:"isIn",validate:o=>n.includes(o),message:`${t} must be one of the following values: ${n.join(", ")}`,constraints:[n]}),e)}function Ye(n,e){return y(t=>({name:"isNotIn",validate:o=>!n.includes(o),message:`${t} must not be one of the following values: ${n.join(", ")}`,constraints:[n]}),e)}function Xe(n,e){let t=Object.keys(n).filter(o=>typeof n[n[o]]!="number").map(o=>n[o]);return y(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 y(t=>({name:"isInstance",validate:o=>o instanceof n,message:`${t} must be an instance of ${n.name}`,constraints:[n]}),e)}function V(n,e,t,o){return r=>y(a=>({name:n,validate:i=>Array.isArray(i)&&e(i),message:t(a),...o?{constraints:o}:{}}),r)}var nt=n=>y(e=>({name:"isArray",validate:t=>Array.isArray(t),message:`${e} must be an array`}),n),et=n=>V("arrayNotEmpty",e=>e.length>0,e=>`${e} should not be empty`)(n),tt=(n,e)=>V("arrayMinSize",t=>t.length>=n,t=>`${t} must contain at least ${n} elements`,[n])(e),ot=(n,e)=>V("arrayMaxSize",t=>t.length<=n,t=>`${t} must contain at most ${n} elements`,[n])(e);function rt(n,e){return V("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 at(n,e){return V("arrayContains",t=>n.every(o=>t.includes(o)),t=>`${t} must contain the following values: ${n.join(", ")}`,[n])(e)}function it(n,e){return V("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 st(n,e){return y(()=>({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 lt(n,e){return y(()=>({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 ut(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 y(()=>({name:"custom",validate:(l,u)=>s(l,u),message:l=>`${l.property} is invalid`,constraints:o}),r)}let i=new n;return y(()=>({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 X(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 ct(n){let e=X(n);return Object.entries(e).flatMap(([t,o])=>o.map(r=>`${t}: ${r}`)).join(` +`)}function dt(n){return Object.values(X(n)).flat()}var D=class extends Error{constructor(t,o){super(t);this.errors=o;this.name="JsonValidationError"}toString(){return`${this.message}: ${JSON.stringify(this.errors,null,2)}`}},h=class extends Error{constructor(e){super(e),this.name="JsonMappingError"}},pt=new Set(["__proto__","constructor","prototype"]),xn="[redacted]";function On(n,e){return n[e]?.access??"readwrite"}function Cn(n,e,t){return n[e]?.name??t(e)}var fn=new WeakMap;function ft(n,e,t){let o=fn.get(n);(!o||o.version!==S())&&(o={version:S(),byStrategy:new Map},fn.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=On(n,e),s=n[e]?.serializer;a={name:Cn(n,e,t.naming),skip:i==="none"||i==="writeonly",...s?{serializer:s}:{}},r.set(e,a)}return a}var yn=new WeakMap;function yt(n,e){let t=yn.get(n);(!t||t.version!==S())&&(t={version:S(),byStrategy:new Map},yn.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 p=r.get(u);if(p&&p!==c)throw new h(`Properties "${p}" 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 p=[Cn(n,u,e.naming),...c.aliases??[]],f=On(n,u);if(f==="none"||f==="readonly"){for(let d of p)a.add(d);continue}for(let d of p)s(d,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 v(n){return n!==null&&typeof n=="object"&&typeof n.then=="function"}async function en(n){for(;n.length>0;){let e=n.splice(0,n.length);await Promise.all(e)}}function tn(n,e,t){if(n.length!==0){for(let o of n)o.catch(()=>{});throw n.length=0,new h(`${e} requires every serializer, deserializer and validator to be synchronous, but one returned a Promise. Use ${t} instead, or make the hook synchronous.`)}}var mt={Map:"a Map",Set:"a Set",WeakMap:"a WeakMap",WeakSet:"a WeakSet",WeakRef:"a WeakRef",Promise:"a Promise",ArrayBuffer:"an ArrayBuffer",SharedArrayBuffer:"a SharedArrayBuffer",DataView:"a DataView",Generator:"a generator",AsyncGenerator:"an async generator"};function Tn(n){let e=n[Symbol.toStringTag];if(typeof e=="string"){let t=mt[e];if(t!==void 0)return t;if(ArrayBuffer.isView(n))return`a ${e}`}return n instanceof RegExp?"a RegExp":n instanceof Error?"an Error, whose message and stack are not enumerable":null}var kn="a bigint, which JSON has no representation for";function mn(n){switch(typeof n){case"bigint":return kn;case"symbol":return"a symbol";case"function":return"a function";case"object":return n===null?null:Tn(n);default:return null}}function Q(n){if(n.length===0)return"the value passed in";let e="";for(let t of n)typeof t=="number"?e+=`[${t}]`:e+=e===""?t:`.${t}`;return e}function E(n,e){throw new h(`${Q(e)} is ${n}, which cannot be serialized to JSON. Give the property a @JsonSerialize() serializer that converts it, or drop it from the output with @JsonIgnore().`)}function K(n,e,t,o,r,a){if(n==null)return n;let i=typeof n;if(i!=="object")return i==="bigint"&&E(kn,a),i==="symbol"&&E("a symbol",a),i==="function"&&E("a function",a),n;if(o>t.maxDepth)throw new h(`Maximum nesting depth of ${t.maxDepth} exceeded while serializing at ${Q(a)}. Raise it with the maxDepth option if this structure is legitimate.`);if(n instanceof Date)return n.toISOString();let s=Array.isArray(n);if(!s){let l=Tn(n);l!==null&&E(l,a)}if(e.has(n))throw new h(`Circular reference detected during serialization at ${Q(a)}. Break the cycle with @JsonIgnore() on the back-reference, or supply a @JsonSerialize() serializer for that property.`);e.add(n);try{if(s){let c=[];for(let p=0;p{let A=mn(C);A!==null&&E(A,O),u[g]=C}))}else{let g=mn(d);g!==null&&E(g,a),u[p.name]=d}}else u[p.name]=K(f,e,t,o+1,r,a);a.pop()}return u}finally{e.delete(n)}}function I(n,e,t,o,r){if(e==null)return e;if(o>t.maxDepth)throw new h(`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=>I(n,s,t,o+1,r));if(typeof e!="object")return e;let a=new n,i=yt(z(n),t);for(let s of Object.keys(e)){if(pt.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 h(`Unknown property ${JSON.stringify(s)} for ${n.name}. Allowed: ${[...i.accept.keys()].map(d=>JSON.stringify(d)).join(", ")||"(none declared)"}.`);a[s]=e[s];continue}let u=e[s],c=i.props.get(l);if(c?.deserializer){let d=Dn(c.deserializer).deserialize(u);if(v(d)){let g=l;a[g]=void 0,r.push(d.then(O=>{a[g]=O}))}else a[l]=d;continue}let p=c?.polymorphic;if(p&&u!==null&&u!==void 0){let{discriminator:d,subTypes:g,onUnknown:O,fallback:C}=p,A=T=>{if(T==null||typeof T!="object")return T;let sn=g.find(G=>T[d]===G.name);if(sn)return I(sn.value,T,t,o+1,r);if(C)return I(C,T,t,o+1,r);if(O==="error")throw new h(`Unknown discriminator value ${JSON.stringify(T[d])} for property "${l}". Known values: ${g.map(G=>JSON.stringify(G.name)).join(", ")}.`);return T};a[l]=Array.isArray(u)?u.map(A):A(u);continue}let f=c?.typeFn;if(f&&u!==null&&u!==void 0){let d=f();a[l]=I(d,u,t,o+1,r);continue}a[l]=u}return a}var gn=new WeakMap;function gt(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 ht(n){let e=gn.get(n);if(e&&e.version===S())return e.plan;let t=[];for(let[o,r]of Object.entries(n)){let a=r.access??"readwrite";t.push({key:o,constraints:gt(r.constraints),isOptional:!!r.optional,isNested:!!r.nested,redact:a==="writeonly"||a==="none",...r.condition?{condition:r.condition}:{}})}return gn.set(n,{version:S(),plan:t}),t}var hn=new WeakMap;function Dn(n){let e=hn.get(n);return e||(e=new n,hn.set(n,e)),e}function bn(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 wn(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 bt(n,e,t){for(let o=0;o0?t.children=o:delete t.children,(Object.keys(t.constraints).length>0||t.children)&&e.push(t)}return e}function L(n,e,t,o,r){let a=[];if(n==null||typeof n!="object")return a;if(t>o)throw new h(`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;i0&&a.push({property:`[${i}]`,value:n[i],constraints:{},children:s})}return a}for(let i of ht(B(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?xn:l,constraints:{}},c={value:l,object:n,property:s,constraints:[]},p=!1;for(let f of i.constraints){c.constraints=f.constraints||[];let d=f.each&&Array.isArray(l)?bt(f,l,c):(()=>{let g=f.validate(l,c);return v(g)?g.then(O=>({ok:O,index:-1})):{ok:g,index:-1}})();if(v(d)){p=!0;let g={value:l,object:n,property:s,constraints:f.constraints||[]};r.push(d.then(({ok:O,index:C})=>{O||(C>=0&&(g.value=l[C]),bn(u.constraints,f.name,wn(f,g,C)))}));continue}if(!d.ok){d.index>=0&&(c.value=l[d.index]);let g=wn(f,c,d.index);c.value=l,bn(u.constraints,f.name,g)}}if(i.isNested&&l!==null&&l!==void 0){let f=L(l,e,t+1,o,r);f.length>0&&(u.children=f)}(p||Object.keys(u.constraints).length>0||u.children)&&a.push(u)}return a}finally{e.delete(n)}}function $n(n){let e=x(n);return{naming:U(e.namingStrategy),namingKey:e.namingStrategy,maxDepth:e.maxDepth}}function Vn(n){let e=x(n);return{naming:U(e.namingStrategy),namingKey:e.namingStrategy,unknownKeys:e.unknownKeys,maxDepth:e.maxDepth}}async function F(n,e){let t=[],o=L(n,new Set,0,x(e).maxDepth,t);return t.length===0?o:(await en(t),Sn(o))}function q(n,e){let t=[],o=L(n,new Set,0,x(e).maxDepth,t);return tn(t,"validateSync()","validate()"),o}async function En(n,e){let t=await F(n,e);if(t.length>0)throw new D("Validation failed",t)}function xt(n,e){let t=q(n,e);if(t.length>0)throw new D("Validation failed",t)}async function on(n,e){if(n==null)return n;if(x(e).validate){let r=await F(n,e);if(r.length>0)throw new D("Validation failed during serialization",r)}let t=[],o=K(n,new Set,$n(e),0,t,[]);return await en(t),o}function In(n,e){if(n==null)return n;if(x(e).validate){let r=q(n,e);if(r.length>0)throw new D("Validation failed during serialization",r)}let t=[],o=K(n,new Set,$n(e),0,t,[]);return tn(t,"toPlainSync()","toPlain()"),o}async function An(n,e){return JSON.stringify(await on(n,e))}function Ot(n,e){return JSON.stringify(In(n,e))}async function J(n,e,t){let o=[],r=I(n,e,Vn(t),0,o);if(await en(o),x(t).validate){let a=await F(r,t);if(a.length>0)throw new D("Validation failed during deserialization",a)}return r}function rn(n,e,t){let o=[],r=I(n,e,Vn(t),0,o);if(tn(o,"toInstanceSync()","toInstance()"),x(t).validate){let a=q(r,t);if(a.length>0)throw new D("Validation failed during deserialization",a)}return r}function Nn(n,e){if(!Array.isArray(e))throw new h(`Expected an array to map to ${n.name}[], received ${typeof e}.`)}async function an(n,e,t){return Nn(n,e),await J(n,e,t)}function Mn(n,e,t){return Nn(n,e),rn(n,e,t)}async function Pn(n,e,t){return J(n,W(e),t)}function Ct(n,e,t){return rn(n,W(e),t)}async function Rn(n,e,t){return an(n,W(e),t)}function Tt(n,e,t){return Mn(n,W(e),t)}function W(n){try{return JSON.parse(n)}catch(e){throw new h(`Input is not valid JSON: ${e instanceof Error?e.message:String(e)}`)}}async function vn(n,e,t){let o;try{o=await e.json()}catch(r){throw new h(`Request body is not valid JSON: ${r instanceof Error?r.message:String(r)}`)}return J(n,o,t)}var nn=class{static toPlain=on;static toJson=An;static toInstance=J;static toInstanceArray=an;static fromJson=Pn;static fromJsonArray=Rn;static fromRequest=vn;static validate=F;static validateOrReject=En};return jn(kt);})(); diff --git a/docs/diagnostics.js b/docs/diagnostics.js new file mode 100644 index 0000000..1f8906f --- /dev/null +++ b/docs/diagnostics.js @@ -0,0 +1,29 @@ +// Generated by scripts/build-docs.mjs from real tsc output — do not edit. +window.CEREALE_DIAGNOSTICS = { + "hero": [ + { + "code": 1240, + "messages": [ + "Unable to resolve signature of property decorator when called as an expression.", + "Argument of type 'ClassFieldDecoratorContext & { name: \"placedAt\"; private: false; static: false; }' is not assignable to parameter of type 'ClassFieldDecoratorContext'.", + "The types returned by 'access.get(...)' are incompatible between these types.", + "Type 'Date' is not assignable to type 'string'." + ], + "line": 12 + } + ], + "compare": [ + { + "code": 1240, + "messages": [ + "Unable to resolve signature of property decorator when called as an expression.", + "Argument of type 'ClassFieldDecoratorContext & { name: \"age\"; private: false; static: false; }' is not assignable to parameter of type 'ClassFieldDecoratorContext'.", + "The types returned by 'access.get(...)' are incompatible between these types.", + "Type 'number' is not assignable to type 'string'." + ], + "line": 4 + } + ], + "instances": [], + "correct": [] +}; diff --git a/docs/index.html b/docs/index.html index c1a7955..1808ef9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,289 +1,845 @@ - - - Cereale - Spring-like JSON Mapping & Validation for TypeScript - - - - - - - - + + +cereale — validated domain objects, not validated data + + + + + - -