@esmj/schema
Advanced tools
| import'./chunk-PHNKAD7Q.mjs';export{c as extend,b as hookOriginal,a as s}from'./chunk-NCHMO7B3.mjs'; |
| import {c}from'./chunk-NCHMO7B3.mjs';c((i,s,c)=>{if(c?.type==="string"){let r=i;r.min=function(t,{message:n}={}){return this.refine(e=>e.length>=t,{message:n||(e=>`String must be at least ${t} characters long (received ${e.length} characters: "${e}")`)})},r.max=function(t,{message:n}={}){return this.refine(e=>e.length<=t,{message:n||(e=>`String must be at most ${t} characters long (received ${e.length} characters: "${e}")`)})},r.length=function(t,{message:n}={}){return this.refine(e=>e.length===t,{message:n||(e=>`String must be exactly ${t} characters long (received ${e.length} characters: "${e}")`)})},r.nonEmpty=function({message:t}={}){return this.refine(n=>n.length>0,{message:t||"String must not be empty (received empty string)"})},r.startsWith=function(t,{message:n}={}){return this.refine(e=>e.startsWith(t),{message:n||(e=>`String must start with "${t}" (received: "${e}")`)})},r.endsWith=function(t,{message:n}={}){return this.refine(e=>e.endsWith(t),{message:n||(e=>`String must end with "${t}" (received: "${e}")`)})},r.includes=function(t,{message:n}={}){return this.refine(e=>e.includes(t),{message:n||(e=>`String must include "${t}" (received: "${e}")`)})},r.toLowerCase=function(){return this.transform(t=>t.toLowerCase())},r.toUpperCase=function(){return this.transform(t=>t.toUpperCase())},r.trim=function(){return this.transform(t=>t.trim())},r.padStart=function(t,n=" "){return this.transform(e=>e.padStart(t,n))},r.padEnd=function(t,n=" "){return this.transform(e=>e.padEnd(t,n))},r.replace=function(t,n){return this.transform(e=>e.replace(t,n))};}return i}); |
| var P={abortEarly:true};function d(e,s){if(!s)return e;let o=e?.cause?.key?`${s}.${e.cause.key}`:`${s}`;return {message:`Error parsing key "${o}": ${e.message}`,cause:{key:o}}}function b(e,s,o){!e.errors||e.errors.length===0||e.errors.forEach(i=>{let f=d(i,o);s.push(f);});}function y(e){return {...P,...e}}var x=e=>typeof e=="string"||e instanceof String,k=e=>typeof e=="number"||e instanceof Number,w=e=>e===true||e===false,E=e=>e instanceof Date&&!Number.isNaN(e.getTime()),_=e=>Array.isArray(e),g=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),R={object(e,s){let o=l(g,{...s,type:"object"});return o._getDescription=()=>`object({ ${Object.entries(e).map(([f,c])=>`${f}: ${c._getDescription()}`).join(", ")} })`,h(o,"_parse",(i,f,c)=>{let t=i(f,c),{abortEarly:r}=y(c);if(t.success===false)return t;let a={},n=[];for(let u in e){let p=e[u]._parse(t.data[u],c);if(p.success)a[u]=p.data;else {if(p=p,r!==false){let m=d(p.error,u);return {success:false,error:m,errors:[m]}}b(p,n,u);}}return n.length>0?{success:false,error:n[0],errors:n}:{success:true,data:a}}),o},string(e){return l(x,{...e,type:"string"})},number(e){return l(k,{...e,type:"number"})},boolean(e){return l(w,{...e,type:"boolean"})},date(e){return l(E,{...e,type:"date"})},enum(e,s){let o=t=>e.includes(t),i=t=>`Invalid ${f} value. Expected ${e.map(r=>`"${r}"`).join(" | ")}, received "${t}".`,f="enum",c=l(o,{message:i,...s,type:f});return c._getDescription=()=>`enum(${e.map(t=>`"${t}"`).join(" | ")})`,c},array(e,s){let o=l(_,{...s,type:"array"});return o._getDescription=()=>`array(${e._getDescription()})`,h(o,"_parse",(i,f,c)=>{let t=i(f,c),{abortEarly:r}=y(c);if(t.success===false)return t;let a=[],n=[];for(let u=0;u<t.data.length;u++){let p=e._parse(t.data[u],c);if(p.success)a.push(p.data);else {if(p=p,r!==false){let m=d(p.error,u);return {success:false,error:m,errors:[m]}}b(p,n,u);}}return n.length>0?{success:false,error:n[0],errors:n}:{success:true,data:a}}),o},any(){return l(()=>true)},preprocess(e,s){return h(s,"_parse",(o,i)=>(i=e(i),o(i))),s},union(e,s){return l(c=>{for(let t=0;t<e.length;t++){let r=e[t]._parse(c);if(r.success)return r}return false},{message:c=>`Invalid union value. Expected the value to match one of the schemas:${e.map((t,r)=>` ${r+1}. ${t._getDescription()}`).join(",")} but received "${typeof c}" with value: ${g(c)?JSON.stringify(c):`"${c}"`}`,...s,type:"union"})}};function O(e){return s=>`The value "${s}" must be type of ${e} but is type of "${typeof s}".`}function h(e,s,o){let i=e[s];e[s]=(...f)=>o(i,...f);}function l(e,{type:s="any",name:o,message:i}={}){i=i||O(s);let f={name:o,message:i,type:s},c={_getName(){return o},_getType(){return s},_getDescription(){return this._getName()??this._getType()},_parse(t,r){let a=e(t);if(a===true)return {success:true,data:t};if(typeof a=="object"&&a?.success===true)return a;let n={message:typeof i=="function"?i(t):i};return {success:false,error:n,errors:[n]}},parse(t,r){let a=c._parse(t,r);if(!a.success)throw a=a,new Error(a.error.message,{cause:a.error.cause});return a.data},safeParse(t,r){return c._parse(t,r)},transform(t){return h(this,"_parse",(r,a,n)=>{let u=r(a,n);return u.success&&(u.data=t(u.data)),u}),this},optional(){return h(this,"_parse",(t,r,a)=>{let n=t(r,a);return !n.success&&r===void 0&&(n.data=void 0,n.success=true),n}),this},nullable(){return h(this,"_parse",(t,r,a)=>{let n=t(r,a);return !n.success&&r===null&&(n.data=null,n.success=true),n}),this},nullish(){return h(this,"_parse",(t,r,a)=>{let n=t(r,a);return !n.success&&r==null&&(n.success=true,n.data=r),n}),this},default(t){return h(this,"_parse",(r,a,n)=>(a===void 0&&(a=t,a=typeof t=="function"?t():t),r(a,n))),this},pipe(t){return h(this,"_parse",(r,a,n)=>{let u=r(a,n);return u.success?t._parse(u.data,n):u}),this},refine(t,{message:r,type:a}={}){return a&&(r=r||O(a),s=a),h(this,"_parse",(n,u,p)=>{let m=n(u,p);y(p);if(!m.success)return m;let I=t(m.data);if(I===true||typeof I=="object"&&I?.success===true)return m;let T={message:typeof r=="function"?r(u):r};return {success:false,error:T,errors:[T]}}),this}};return S.length>0?S.reduce((t,r)=>r(t,e,f)??t,c):c}var S=[];function $(e){S.push(e);}export{R as a,h as b,$ as c}; |
| import {c}from'./chunk-NCHMO7B3.mjs';c((a,o,m)=>{if(m?.type==="array"){let r=a;r.min=function(e,{message:t}={}){return this.refine(n=>n.length>=e,{message:t||`Array must contain at least ${e} items.`})},r.max=function(e,{message:t}={}){return this.refine(n=>n.length<=e,{message:t||`Array must contain at most ${e} items.`})},r.length=function(e,{message:t}={}){return this.refine(n=>n.length===e,{message:t||`Array must contain exactly ${e} items.`})},r.nonEmpty=function({message:e}={}){return this.refine(t=>t.length>0,{message:e||"Array must not be empty."})},r.unique=function({message:e}={}){return this.refine(t=>{let n=new Set;try{return t.every(c=>{let s=JSON.stringify(c);return n.has(s)?!1:(n.add(s),!0)})}catch{return new Set(t).size===t.length}},{message:e||"Array items must be unique."})},r.sort=function(){return this.transform(e=>[...e].sort())},r.reverse=function(){return this.transform(e=>[...e].reverse())};}return a}); |
| import {c}from'./chunk-NCHMO7B3.mjs';c((i,c,m)=>{if(m?.type==="number"){let n=i;n.min=function(e,{message:t}={}){return this.refine(r=>r>=e,{message:t||`Number must be greater than or equal to ${e}.`})},n.max=function(e,{message:t}={}){return this.refine(r=>r<=e,{message:t||`Number must be less than or equal to ${e}.`})},n.positive=function({message:e}={}){return this.refine(t=>t>0,{message:e||"Number must be positive."})},n.negative=function({message:e}={}){return this.refine(t=>t<0,{message:e||"Number must be negative."})},n.int=function({message:e}={}){return this.refine(t=>Number.isInteger(t),{message:e||"Number must be an integer."})},n.float=function({message:e}={}){return this.refine(t=>Number.isFinite(t)&&!Number.isInteger(t),{message:e||"Number must be a floating point (non-integer)."})},n.multipleOf=function(e,{message:t}={}){return this.refine(r=>r%e===0,{message:t||`Number must be a multiple of ${e}.`})},n.finite=function({message:e}={}){return this.refine(t=>Number.isFinite(t),{message:e||"Number must be finite."})};}return i}); |
| import'./chunk-PHNKAD7Q.mjs';import'./chunk-SHVCROKM.mjs';import'./chunk-BV6SWQSH.mjs';export{c as extend,b as hookOriginal,a as s}from'./chunk-NCHMO7B3.mjs'; |
| export{c as extend,b as hookOriginal,a as s}from'./chunk-NCHMO7B3.mjs'; |
| import'./chunk-SHVCROKM.mjs';export{c as extend,b as hookOriginal,a as s}from'./chunk-NCHMO7B3.mjs'; |
| import'./chunk-BV6SWQSH.mjs';export{c as extend,b as hookOriginal,a as s}from'./chunk-NCHMO7B3.mjs'; |
+8
-8
| { | ||
| "name": "@esmj/schema", | ||
| "version": "0.5.0", | ||
| "version": "0.5.1", | ||
| "description": "Tiny extendable package for schema validation.", | ||
@@ -23,4 +23,4 @@ "type": "module", | ||
| ], | ||
| "main": "dist/index", | ||
| "module": "dist/index", | ||
| "main": "./dist/index.cjs", | ||
| "module": "./dist/index.mjs", | ||
| "exports": { | ||
@@ -30,3 +30,3 @@ ".": { | ||
| "import": "./dist/index.mjs", | ||
| "require": "./dist/index.js" | ||
| "require": "./dist/index.cjs" | ||
| }, | ||
@@ -36,3 +36,3 @@ "./full": { | ||
| "import": "./dist/full.mjs", | ||
| "require": "./dist/full.js" | ||
| "require": "./dist/full.cjs" | ||
| }, | ||
@@ -42,3 +42,3 @@ "./string": { | ||
| "import": "./dist/string.mjs", | ||
| "require": "./dist/string.js" | ||
| "require": "./dist/string.cjs" | ||
| }, | ||
@@ -48,3 +48,3 @@ "./number": { | ||
| "import": "./dist/number.mjs", | ||
| "require": "./dist/number.js" | ||
| "require": "./dist/number.cjs" | ||
| }, | ||
@@ -54,3 +54,3 @@ "./array": { | ||
| "import": "./dist/array.mjs", | ||
| "require": "./dist/array.js" | ||
| "require": "./dist/array.cjs" | ||
| } | ||
@@ -57,0 +57,0 @@ }, |
| import'./chunk-JFGD5PND.js';export{c as extend,b as hookOriginal,a as s}from'./chunk-5ARMWSHU.js'; |
| var P={abortEarly:true};function d(e,s){if(!s)return e;let o=e?.cause?.key?`${s}.${e.cause.key}`:`${s}`;return {message:`Error parsing key "${o}": ${e.message}`,cause:{key:o}}}function b(e,s,o){!e.errors||e.errors.length===0||e.errors.forEach(i=>{let f=d(i,o);s.push(f);});}function y(e){return {...P,...e}}var x=e=>typeof e=="string"||e instanceof String,k=e=>typeof e=="number"||e instanceof Number,w=e=>e===true||e===false,E=e=>e instanceof Date&&!Number.isNaN(e.getTime()),_=e=>Array.isArray(e),g=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),R={object(e,s){let o=l(g,{...s,type:"object"});return o._getDescription=()=>`object({ ${Object.entries(e).map(([f,c])=>`${f}: ${c._getDescription()}`).join(", ")} })`,h(o,"_parse",(i,f,c)=>{let t=i(f,c),{abortEarly:r}=y(c);if(t.success===false)return t;let a={},n=[];for(let u in e){let p=e[u]._parse(t.data[u],c);if(p.success)a[u]=p.data;else {if(p=p,r!==false){let m=d(p.error,u);return {success:false,error:m,errors:[m]}}b(p,n,u);}}return n.length>0?{success:false,error:n[0],errors:n}:{success:true,data:a}}),o},string(e){return l(x,{...e,type:"string"})},number(e){return l(k,{...e,type:"number"})},boolean(e){return l(w,{...e,type:"boolean"})},date(e){return l(E,{...e,type:"date"})},enum(e,s){let o=t=>e.includes(t),i=t=>`Invalid ${f} value. Expected ${e.map(r=>`"${r}"`).join(" | ")}, received "${t}".`,f="enum",c=l(o,{message:i,...s,type:f});return c._getDescription=()=>`enum(${e.map(t=>`"${t}"`).join(" | ")})`,c},array(e,s){let o=l(_,{...s,type:"array"});return o._getDescription=()=>`array(${e._getDescription()})`,h(o,"_parse",(i,f,c)=>{let t=i(f,c),{abortEarly:r}=y(c);if(t.success===false)return t;let a=[],n=[];for(let u=0;u<t.data.length;u++){let p=e._parse(t.data[u],c);if(p.success)a.push(p.data);else {if(p=p,r!==false){let m=d(p.error,u);return {success:false,error:m,errors:[m]}}b(p,n,u);}}return n.length>0?{success:false,error:n[0],errors:n}:{success:true,data:a}}),o},any(){return l(()=>true)},preprocess(e,s){return h(s,"_parse",(o,i)=>(i=e(i),o(i))),s},union(e,s){return l(c=>{for(let t=0;t<e.length;t++){let r=e[t]._parse(c);if(r.success)return r}return false},{message:c=>`Invalid union value. Expected the value to match one of the schemas:${e.map((t,r)=>` ${r+1}. ${t._getDescription()}`).join(",")} but received "${typeof c}" with value: ${g(c)?JSON.stringify(c):`"${c}"`}`,...s,type:"union"})}};function O(e){return s=>`The value "${s}" must be type of ${e} but is type of "${typeof s}".`}function h(e,s,o){let i=e[s];e[s]=(...f)=>o(i,...f);}function l(e,{type:s="any",name:o,message:i}={}){i=i||O(s);let f={name:o,message:i,type:s},c={_getName(){return o},_getType(){return s},_getDescription(){return this._getName()??this._getType()},_parse(t,r){let a=e(t);if(a===true)return {success:true,data:t};if(typeof a=="object"&&a?.success===true)return a;let n={message:typeof i=="function"?i(t):i};return {success:false,error:n,errors:[n]}},parse(t,r){let a=c._parse(t,r);if(!a.success)throw a=a,new Error(a.error.message,{cause:a.error.cause});return a.data},safeParse(t,r){return c._parse(t,r)},transform(t){return h(this,"_parse",(r,a,n)=>{let u=r(a,n);return u.success&&(u.data=t(u.data)),u}),this},optional(){return h(this,"_parse",(t,r,a)=>{let n=t(r,a);return !n.success&&r===void 0&&(n.data=void 0,n.success=true),n}),this},nullable(){return h(this,"_parse",(t,r,a)=>{let n=t(r,a);return !n.success&&r===null&&(n.data=null,n.success=true),n}),this},nullish(){return h(this,"_parse",(t,r,a)=>{let n=t(r,a);return !n.success&&r==null&&(n.success=true,n.data=r),n}),this},default(t){return h(this,"_parse",(r,a,n)=>(a===void 0&&(a=t,a=typeof t=="function"?t():t),r(a,n))),this},pipe(t){return h(this,"_parse",(r,a,n)=>{let u=r(a,n);return u.success?t._parse(u.data,n):u}),this},refine(t,{message:r,type:a}={}){return a&&(r=r||O(a),s=a),h(this,"_parse",(n,u,p)=>{let m=n(u,p);y(p);if(!m.success)return m;let I=t(m.data);if(I===true||typeof I=="object"&&I?.success===true)return m;let T={message:typeof r=="function"?r(u):r};return {success:false,error:T,errors:[T]}}),this}};return S.length>0?S.reduce((t,r)=>r(t,e,f)??t,c):c}var S=[];function $(e){S.push(e);}export{R as a,h as b,$ as c}; |
| import {c}from'./chunk-5ARMWSHU.js';c((i,s,c)=>{if(c?.type==="string"){let r=i;r.min=function(t,{message:n}={}){return this.refine(e=>e.length>=t,{message:n||(e=>`String must be at least ${t} characters long (received ${e.length} characters: "${e}")`)})},r.max=function(t,{message:n}={}){return this.refine(e=>e.length<=t,{message:n||(e=>`String must be at most ${t} characters long (received ${e.length} characters: "${e}")`)})},r.length=function(t,{message:n}={}){return this.refine(e=>e.length===t,{message:n||(e=>`String must be exactly ${t} characters long (received ${e.length} characters: "${e}")`)})},r.nonEmpty=function({message:t}={}){return this.refine(n=>n.length>0,{message:t||"String must not be empty (received empty string)"})},r.startsWith=function(t,{message:n}={}){return this.refine(e=>e.startsWith(t),{message:n||(e=>`String must start with "${t}" (received: "${e}")`)})},r.endsWith=function(t,{message:n}={}){return this.refine(e=>e.endsWith(t),{message:n||(e=>`String must end with "${t}" (received: "${e}")`)})},r.includes=function(t,{message:n}={}){return this.refine(e=>e.includes(t),{message:n||(e=>`String must include "${t}" (received: "${e}")`)})},r.toLowerCase=function(){return this.transform(t=>t.toLowerCase())},r.toUpperCase=function(){return this.transform(t=>t.toUpperCase())},r.trim=function(){return this.transform(t=>t.trim())},r.padStart=function(t,n=" "){return this.transform(e=>e.padStart(t,n))},r.padEnd=function(t,n=" "){return this.transform(e=>e.padEnd(t,n))},r.replace=function(t,n){return this.transform(e=>e.replace(t,n))};}return i}); |
| import {c}from'./chunk-5ARMWSHU.js';c((a,o,m)=>{if(m?.type==="array"){let r=a;r.min=function(e,{message:t}={}){return this.refine(n=>n.length>=e,{message:t||`Array must contain at least ${e} items.`})},r.max=function(e,{message:t}={}){return this.refine(n=>n.length<=e,{message:t||`Array must contain at most ${e} items.`})},r.length=function(e,{message:t}={}){return this.refine(n=>n.length===e,{message:t||`Array must contain exactly ${e} items.`})},r.nonEmpty=function({message:e}={}){return this.refine(t=>t.length>0,{message:e||"Array must not be empty."})},r.unique=function({message:e}={}){return this.refine(t=>{let n=new Set;try{return t.every(c=>{let s=JSON.stringify(c);return n.has(s)?!1:(n.add(s),!0)})}catch{return new Set(t).size===t.length}},{message:e||"Array items must be unique."})},r.sort=function(){return this.transform(e=>[...e].sort())},r.reverse=function(){return this.transform(e=>[...e].reverse())};}return a}); |
| import {c}from'./chunk-5ARMWSHU.js';c((i,c,m)=>{if(m?.type==="number"){let n=i;n.min=function(e,{message:t}={}){return this.refine(r=>r>=e,{message:t||`Number must be greater than or equal to ${e}.`})},n.max=function(e,{message:t}={}){return this.refine(r=>r<=e,{message:t||`Number must be less than or equal to ${e}.`})},n.positive=function({message:e}={}){return this.refine(t=>t>0,{message:e||"Number must be positive."})},n.negative=function({message:e}={}){return this.refine(t=>t<0,{message:e||"Number must be negative."})},n.int=function({message:e}={}){return this.refine(t=>Number.isInteger(t),{message:e||"Number must be an integer."})},n.float=function({message:e}={}){return this.refine(t=>Number.isFinite(t)&&!Number.isInteger(t),{message:e||"Number must be a floating point (non-integer)."})},n.multipleOf=function(e,{message:t}={}){return this.refine(r=>r%e===0,{message:t||`Number must be a multiple of ${e}.`})},n.finite=function({message:e}={}){return this.refine(t=>Number.isFinite(t),{message:e||"Number must be finite."})};}return i}); |
| import'./chunk-JFGD5PND.js';import'./chunk-QEBUM44M.js';import'./chunk-6ABUMTDR.js';export{c as extend,b as hookOriginal,a as s}from'./chunk-5ARMWSHU.js'; |
| export{c as extend,b as hookOriginal,a as s}from'./chunk-5ARMWSHU.js'; |
| import'./chunk-QEBUM44M.js';export{c as extend,b as hookOriginal,a as s}from'./chunk-5ARMWSHU.js'; |
| import'./chunk-6ABUMTDR.js';export{c as extend,b as hookOriginal,a as s}from'./chunk-5ARMWSHU.js'; |
| import { s } from '../src/full.ts'; | ||
| // Advanced form validation example | ||
| const addressSchema = s.object({ | ||
| street: s.string().min(3).max(100), | ||
| city: s.string().min(2).max(50), | ||
| zipCode: s.string().length(5).refine((val) => /^\d{5}$/.test(val), { | ||
| message: 'ZIP code must be 5 digits', | ||
| }), | ||
| country: s.enum(['US', 'CA', 'MX', 'UK']), | ||
| }); | ||
| const userProfileSchema = s.object({ | ||
| // Personal info | ||
| firstName: s.string().trim().min(2).max(50), | ||
| lastName: s.string().trim().min(2).max(50), | ||
| email: s | ||
| .string() | ||
| .trim() | ||
| .toLowerCase() | ||
| .refine((value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value), { | ||
| message: 'Invalid email address', | ||
| }), | ||
| // Contact | ||
| phone: s | ||
| .string() | ||
| .optional() | ||
| .transform((val) => val?.replace(/\D/g, '')) | ||
| .refine((val) => !val || val.length === 10, { | ||
| message: 'Phone number must be 10 digits', | ||
| }), | ||
| // Address | ||
| address: addressSchema.optional(), | ||
| // Preferences | ||
| role: s.enum(['admin', 'editor', 'viewer']).default('viewer'), | ||
| tags: s.array(s.string()).min(1).max(5).unique(), | ||
| isActive: s.boolean().default(true), | ||
| // Metadata | ||
| createdAt: s.date(), | ||
| updatedAt: s.date().optional(), | ||
| }); | ||
| console.log('=== Valid User Profile ==='); | ||
| const validProfile = { | ||
| firstName: ' John ', | ||
| lastName: 'Doe', | ||
| email: ' JOHN.DOE@EXAMPLE.COM ', | ||
| phone: '(555) 123-4567', | ||
| address: { | ||
| street: '123 Main St', | ||
| city: 'New York', | ||
| zipCode: '10001', | ||
| country: 'US' as const, | ||
| }, | ||
| role: 'admin' as const, | ||
| tags: ['developer', 'typescript', 'node'], | ||
| isActive: true, | ||
| createdAt: new Date(), | ||
| }; | ||
| console.log('Input:', validProfile); | ||
| console.log('Parsed:', userProfileSchema.parse(validProfile)); | ||
| console.log('\n=== Invalid User Profile (missing required fields) ==='); | ||
| const invalidProfile = { | ||
| firstName: 'John', | ||
| // lastName missing | ||
| email: 'invalid-email', | ||
| tags: [], | ||
| createdAt: new Date(), | ||
| }; | ||
| console.log('Result:', userProfileSchema.safeParse(invalidProfile)); | ||
| console.log('\n=== Invalid ZIP Code ==='); | ||
| const invalidZipProfile = { | ||
| ...validProfile, | ||
| address: { | ||
| street: '123 Main St', | ||
| city: 'New York', | ||
| zipCode: 'ABC12', // Invalid: not digits | ||
| country: 'US' as const, | ||
| }, | ||
| }; | ||
| console.log('Result:', userProfileSchema.safeParse(invalidZipProfile)); | ||
| // API response validation | ||
| const apiResponseSchema = s.object({ | ||
| status: s.enum(['success', 'error']), | ||
| data: s | ||
| .object({ | ||
| users: s.array( | ||
| s.object({ | ||
| id: s.number().positive().int(), | ||
| name: s.string(), | ||
| email: s.string(), | ||
| }), | ||
| ), | ||
| total: s.number().positive().int(), | ||
| }) | ||
| .optional(), | ||
| error: s | ||
| .object({ | ||
| code: s.string(), | ||
| message: s.string(), | ||
| }) | ||
| .optional(), | ||
| }); | ||
| console.log('\n=== API Response Validation (Success) ==='); | ||
| const successResponse = { | ||
| status: 'success' as const, | ||
| data: { | ||
| users: [ | ||
| { id: 1, name: 'John', email: 'john@example.com' }, | ||
| { id: 2, name: 'Jane', email: 'jane@example.com' }, | ||
| ], | ||
| total: 2, | ||
| }, | ||
| }; | ||
| console.log('Result:', apiResponseSchema.parse(successResponse)); | ||
| console.log('\n=== API Response Validation (Error) ==='); | ||
| const errorResponse = { | ||
| status: 'error' as const, | ||
| error: { | ||
| code: 'NOT_FOUND', | ||
| message: 'User not found', | ||
| }, | ||
| }; | ||
| console.log('Result:', apiResponseSchema.parse(errorResponse)); |
| import { s } from '../src/full.ts'; | ||
| // String validations with transformations | ||
| console.log('=== String Validations ==='); | ||
| console.log( | ||
| 'trim + startsWith + endsWith:', | ||
| s | ||
| .string() | ||
| .trim() | ||
| .startsWith('Hello') | ||
| .endsWith('World') | ||
| .safeParse(' Hello, World '), | ||
| ); | ||
| console.log( | ||
| 'startsWith + endsWith (without trim):', | ||
| s.string().startsWith('Hello').endsWith('World').safeParse(' Hello, World '), | ||
| ); | ||
| // Array validations | ||
| console.log('\n=== Array Validations ==='); | ||
| console.log( | ||
| 'Array with min/max:', | ||
| s.array(s.string()).min(2).max(5).safeParse(['Hello', 'World']), | ||
| ); | ||
| // Number validations | ||
| console.log('\n=== Number Validations ==='); | ||
| console.log('Integer + positive:', s.number().int().positive().safeParse(42)); | ||
| console.log('Float validation:', s.number().float().safeParse(3.14)); | ||
| // Union with extended methods | ||
| console.log('\n=== Union Validations ==='); | ||
| console.log( | ||
| 'Union with string validation:', | ||
| s | ||
| .union([ | ||
| s.string({ message: 'stringSchema' }).startsWith('Hello'), | ||
| s.number(), | ||
| ]) | ||
| .safeParse('World'), | ||
| ); |
| import { s, extend, type StringSchemaInterface } from '../src/index.ts'; | ||
| // Extend StringSchemaInterface to add custom methods | ||
| declare module '../src/index.ts' { | ||
| interface StringSchemaInterface { | ||
| email(options?: { message?: string }): StringSchemaInterface; | ||
| url(options?: { message?: string }): StringSchemaInterface; | ||
| uuid(options?: { message?: string }): StringSchemaInterface; | ||
| } | ||
| } | ||
| // Implement the extensions | ||
| extend((schema, _, options) => { | ||
| if (options?.type === 'string') { | ||
| const stringSchema = schema as StringSchemaInterface; | ||
| // Email validation | ||
| stringSchema.email = function ({ message } = {}) { | ||
| return this.refine( | ||
| (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value), | ||
| { | ||
| message: message || ((value: string) => `"${value}" is not a valid email address`), | ||
| }, | ||
| ); | ||
| }; | ||
| // URL validation | ||
| stringSchema.url = function ({ message } = {}) { | ||
| return this.refine( | ||
| (value) => { | ||
| try { | ||
| new URL(value); | ||
| return true; | ||
| } catch { | ||
| return false; | ||
| } | ||
| }, | ||
| { | ||
| message: message || ((value: string) => `"${value}" is not a valid URL`), | ||
| }, | ||
| ); | ||
| }; | ||
| // UUID validation | ||
| stringSchema.uuid = function ({ message } = {}) { | ||
| return this.refine( | ||
| (value) => | ||
| /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test( | ||
| value, | ||
| ), | ||
| { | ||
| message: message || ((value: string) => `"${value}" is not a valid UUID`), | ||
| }, | ||
| ); | ||
| }; | ||
| } | ||
| return schema; | ||
| }); | ||
| // Now use the extended schema | ||
| console.log('=== Email Validation ==='); | ||
| const emailSchema = s.string().email(); | ||
| console.log('Valid email:', emailSchema.safeParse('user@example.com')); | ||
| console.log('Invalid email:', emailSchema.safeParse('not-an-email')); | ||
| console.log('Empty string:', emailSchema.safeParse('')); | ||
| console.log('\n=== URL Validation ==='); | ||
| const urlSchema = s.string().url(); | ||
| console.log('Valid URL:', urlSchema.safeParse('https://example.com')); | ||
| console.log('Valid URL with path:', urlSchema.safeParse('https://example.com/path')); | ||
| console.log('Invalid URL:', urlSchema.safeParse('not a url')); | ||
| console.log('\n=== UUID Validation ==='); | ||
| const uuidSchema = s.string().uuid(); | ||
| console.log( | ||
| 'Valid UUID:', | ||
| uuidSchema.safeParse('550e8400-e29b-41d4-a716-446655440000'), | ||
| ); | ||
| console.log('Invalid UUID:', uuidSchema.safeParse('not-a-uuid')); | ||
| console.log( | ||
| 'Invalid UUID format:', | ||
| uuidSchema.safeParse('550e8400-e29b-41d4-a716'), | ||
| ); | ||
| // Combine extensions in a schema | ||
| console.log('\n=== Combined Schema ==='); | ||
| const userSchema = s.object({ | ||
| id: s.string().uuid(), | ||
| email: s.string().trim().toLowerCase().email(), | ||
| website: s.string().url().optional(), | ||
| }); | ||
| console.log( | ||
| 'Valid user:', | ||
| userSchema.parse({ | ||
| id: '550e8400-e29b-41d4-a716-446655440000', | ||
| email: ' USER@EXAMPLE.COM ', | ||
| website: 'https://example.com', | ||
| }), | ||
| ); | ||
| console.log( | ||
| '\nInvalid user (bad email):', | ||
| userSchema.safeParse({ | ||
| id: '550e8400-e29b-41d4-a716-446655440000', | ||
| email: 'not-an-email', | ||
| }), | ||
| ); | ||
| // Custom error messages | ||
| console.log('\n=== Custom Error Messages ==='); | ||
| const customEmailSchema = s | ||
| .string() | ||
| .email({ message: 'Please enter a valid email address' }); | ||
| console.log( | ||
| 'Custom error:', | ||
| customEmailSchema.safeParse('invalid'), | ||
| ); |
| import { s } from '../src/full.ts'; | ||
| // Custom email validation using refine | ||
| const emailSchema = s | ||
| .string() | ||
| .trim() | ||
| .toLowerCase() | ||
| .refine((value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value), { | ||
| message: 'Invalid email address format', | ||
| }); | ||
| console.log('=== Custom Email Validation ==='); | ||
| console.log('Valid email:', emailSchema.safeParse('user@example.com')); | ||
| console.log('Invalid email:', emailSchema.safeParse('not-an-email')); | ||
| console.log( | ||
| 'Email with whitespace:', | ||
| emailSchema.safeParse(' User@Example.COM '), | ||
| ); | ||
| // Custom URL validation | ||
| const urlSchema = s.string().refine( | ||
| (value) => { | ||
| try { | ||
| new URL(value); | ||
| return true; | ||
| } catch { | ||
| return false; | ||
| } | ||
| }, | ||
| { | ||
| message: (value) => `"${value}" is not a valid URL`, | ||
| }, | ||
| ); | ||
| console.log('\n=== Custom URL Validation ==='); | ||
| console.log('Valid URL:', urlSchema.safeParse('https://example.com')); | ||
| console.log('Invalid URL:', urlSchema.safeParse('not a url')); | ||
| // Custom age validation | ||
| const ageSchema = s | ||
| .number() | ||
| .int() | ||
| .positive() | ||
| .refine((value) => value >= 18, { | ||
| message: (value) => | ||
| `Age must be at least 18 (received ${value} years old)`, | ||
| }) | ||
| .refine((value) => value <= 120, { | ||
| message: (value) => `Age seems unrealistic (received ${value} years old)`, | ||
| }); | ||
| console.log('\n=== Custom Age Validation ==='); | ||
| console.log('Valid age:', ageSchema.safeParse(25)); | ||
| console.log('Too young:', ageSchema.safeParse(15)); | ||
| console.log('Too old:', ageSchema.safeParse(150)); | ||
| // Custom password validation | ||
| const passwordSchema = s | ||
| .string() | ||
| .min(8, { message: 'Password must be at least 8 characters' }) | ||
| .refine((value) => /[A-Z]/.test(value), { | ||
| message: 'Password must contain at least one uppercase letter', | ||
| }) | ||
| .refine((value) => /[a-z]/.test(value), { | ||
| message: 'Password must contain at least one lowercase letter', | ||
| }) | ||
| .refine((value) => /[0-9]/.test(value), { | ||
| message: 'Password must contain at least one number', | ||
| }) | ||
| .refine((value) => /[^A-Za-z0-9]/.test(value), { | ||
| message: 'Password must contain at least one special character', | ||
| }); | ||
| console.log('\n=== Custom Password Validation ==='); | ||
| console.log('Valid password:', passwordSchema.safeParse('MyP@ssw0rd')); | ||
| console.log('Too short:', passwordSchema.safeParse('Pass1!')); | ||
| console.log('No uppercase:', passwordSchema.safeParse('myp@ssw0rd')); | ||
| console.log('No special char:', passwordSchema.safeParse('MyPassw0rd')); | ||
| // Custom object validation with cross-field checks | ||
| const registrationSchema = s | ||
| .object({ | ||
| password: s.string().min(8), | ||
| confirmPassword: s.string(), | ||
| email: emailSchema, | ||
| age: ageSchema, | ||
| }) | ||
| .refine((data) => data.password === data.confirmPassword, { | ||
| message: 'Passwords do not match', | ||
| }); | ||
| console.log('\n=== Cross-Field Validation ==='); | ||
| console.log( | ||
| 'Valid registration:', | ||
| registrationSchema.safeParse({ | ||
| password: 'MyP@ssw0rd', | ||
| confirmPassword: 'MyP@ssw0rd', | ||
| email: 'user@example.com', | ||
| age: 25, | ||
| }), | ||
| ); | ||
| console.log( | ||
| 'Password mismatch:', | ||
| registrationSchema.safeParse({ | ||
| password: 'MyP@ssw0rd', | ||
| confirmPassword: 'Different123!', | ||
| email: 'user@example.com', | ||
| age: 25, | ||
| }), | ||
| ); |
| { | ||
| "compilerOptions": { | ||
| "target": "es2022", | ||
| "module": "es2022", | ||
| "moduleResolution": "node", | ||
| "esModuleInterop": true, | ||
| "allowImportingTsExtensions": true, | ||
| "resolveJsonModule": true, | ||
| "noEmit": true | ||
| }, | ||
| "include": ["src/**/*"] | ||
| } |
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 2 instances in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 2 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
0
-100%0
-100%107940
-9.4%27
-15.62%326
-53.56%