@stacksjs/validation 0.70.73 → 0.70.74

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- var q=import.meta.require;import{v as b}from"@stacksjs/ts-validation";var h=new Set(["image/jpeg","image/png","image/webp","image/gif","image/avif"]);function F(B){return B.mimetype??B.mimeType}function f(B){return B.originalName??B.name}function g(B){let D=f(B);if(!D)return null;let J=D.lastIndexOf(".");if(J<=0||J===D.length-1)return null;let L=D.slice(J+1).toLowerCase();return/^[a-z0-9]+$/.test(L)?L:null}class A{_required=!1;_rules=[];required(){return this._required=!0,this}image(){return this._rules.push((B)=>{let D=F(B);if(!D||!h.has(D.toLowerCase()))return`must be an image (got ${D||"no mimetype"})`;return null}),this}mimeTypes(B){let D=new Set(B.map((J)=>J.toLowerCase()));return this._rules.push((J)=>{let L=F(J);if(!L||!D.has(L.toLowerCase()))return`must be one of: ${B.join(", ")} (got ${L||"no mimetype"})`;return null}),this}maxBytes(B){return this._rules.push((D)=>{if(typeof D.size!=="number")return"has no size \u2014 cannot enforce maxBytes";if(D.size>B)return`is too large: ${D.size} bytes exceeds the ${B}-byte cap`;return null}),this}minBytes(B){return this._rules.push((D)=>{if(typeof D.size!=="number")return"has no size \u2014 cannot enforce minBytes";if(D.size<B)return`is too small: ${D.size} bytes is below the ${B}-byte minimum`;return null}),this}extensions(B){let D=new Set(B.map((J)=>J.toLowerCase().replace(/^\./,"")));return this._rules.push((J)=>{let L=g(J);if(!L||!D.has(L))return`must have one of these extensions: ${B.join(", ")} (got ${L?`.${L}`:"no extension"})`;return null}),this}custom(B){return this._rules.push(B),this}validate(B){if(B===null||B===void 0){if(this._required)return{valid:!1,errors:[{message:"is required"}]};return{valid:!0}}if(typeof B!=="object"||typeof B.size!=="number")return{valid:!1,errors:[{message:"must be an uploaded file"}]};let D=B,J=[];for(let L of this._rules){let U=L(D);if(U)J.push({message:U})}return J.length===0?{valid:!0}:{valid:!1,errors:J}}}function C(){return new A}function T(B){let D=B;return D.when=function(L,U,Q){if(!this.__conditionals)this.__conditionals=[];return this.__conditionals.push({field:L,match:U,refine:Q}),this},D.sometimes=function(){return this.optional(),this},D}function H(B,D){if(D===null||D===void 0)return!1;let J=D[B.field];if(typeof B.match==="function")return B.match(J);return J===B.match}function V(B,D){let J=B.__conditionals;if(!J||J.length===0)return B;let L=null;for(let U of J){if(!H(U,D))continue;if(L===null)L=y(B);L=U.refine(L)}return L??B}function y(B){let D=Object.create(Object.getPrototypeOf(B));Object.assign(D,B);let J=B.rules;if(Array.isArray(J))D.rules=J.slice();return D}function I(B){let D=B??{},J=!0,L={name:"object",isPartOfShape:!1,shape(Q){return D=Q,L},getShape(){return D},required(){return J=!0,U},optional(){return J=!1,U},validate(Q){let Z=Q===void 0||Q===null;if(!J&&Z)return{valid:!0,errors:this.isPartOfShape?{}:[]};if(J&&Z)return this.isPartOfShape?{valid:!1,errors:{object:[{message:"value is required"}]}}:{valid:!1,errors:[{message:"value is required"}]};if(typeof Q!=="object"||Array.isArray(Q))return this.isPartOfShape?{valid:!1,errors:{object:[{message:"Must be an object"}]}}:{valid:!1,errors:[{message:"Must be an object"}]};let $=Q,X={},G=!1;for(let N of Object.keys(D)){let _=D[N];if(!_)continue;let Y=V(_,$),S=$[N],P=Y.validate(S);if(P.valid)continue;if(G=!0,!Array.isArray(P.errors))for(let[w,k]of Object.entries(P.errors))X[`${N}.${w}`]=k;else X[N]=P.errors}if(G)return{valid:!1,errors:X};return{valid:!0,errors:{}}}},U=T(L);return U}var v=new Set(["array","bigint","binary","blob","boolean","custom","date","datetime","decimal","double","enum","float","integer","json","number","password","smallint","string","text","time","timestamp","timestampTz","unix"]);function m(B){return(...D)=>{let J=B(...D);return T(J)}}var W=new Proxy(b,{get(B,D,J){if(D==="file")return C;if(D==="object")return I;if(typeof D==="string"&&v.has(D)){let L=Reflect.get(B,D,J);if(typeof L==="function")return m(L)}return Reflect.get(B,D,J)}});export*from"@stacksjs/ts-validation";var M=[];function O(B){M=B}function XB(){return M}import{HttpError as z}from"@stacksjs/error-handling";import{path as R}from"@stacksjs/path";import{snakeCase as p}from"@stacksjs/strings";import{getErrorMessage as K}from"@stacksjs/utils";import{MessageProvider as E,setCustomMessages as x}from"@stacksjs/ts-validation";function c(B,D={}){let J=[];for(let L of B){let Q=L.startsWith("/")?L.lastIndexOf("/"):-1,Z=L.indexOf("*"),$=Z===-1?Q:L.lastIndexOf("/",Z),X=$>0?L.slice(0,$):".",G=$>0?L.slice($+1):L,N=new Bun.Glob(G);for(let _ of N.scanSync({cwd:X,onlyFiles:!0}))J.push(D.absolute?`${X}/${_}`:_)}return J}function YB(B){if(B===void 0)return!1;return Object.keys(B).length>0}async function d(B,D){let L=c([R.userModelsPath("*.ts"),R.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}).find((X)=>X.endsWith(`${B}.ts`));if(!L)throw new z(404,`Model ${B} not found`);let Q=(await import(L)).default.attributes,Z={},$={};for(let X in Q)if(Object.prototype.hasOwnProperty.call(Q,X)){let G=Q[X];if(!G)continue;let N="isRequired"in(G.validation?.rule??{})?(G.validation?.rule).isRequired:!1;if(G.default!==void 0&&N===!1)continue;Z[p(X)]=G.validation?.rule;let _=G.validation?.message;if(_)for(let Y in _){let S=`${X}.${Y}`;$[S]=_[Y]||""}}try{x(new E($));let G=await W.object(Z).validate(D);if(!G.valid)throw O(G.errors),new z(422,"Validation failed",{errors:G.errors});return G}catch(X){if(X instanceof z)throw X;throw new z(500,K(X)||"An unexpected validation error occurred")}}var j=new Map;function PB(B,D){j.set(B,D)}function VB(B){return j.get(B)}function IB(B,D,J){return async(L)=>{try{let{db:U}=await import("@stacksjs/database"),Q=U.selectFrom(B).where(D,"=",L);if(J)Q=Q.where("id","!=",J);return await Q.selectAll().executeTakeFirst()?`The ${D} has already been taken`:!0}catch{return!0}}}function SB(B,D){return async(J)=>{try{let{db:L}=await import("@stacksjs/database");return await L.selectFrom(B).where(D,"=",J).selectAll().executeTakeFirst()?!0:`The selected ${D} does not exist`}catch{return!0}}}async function AB(B,D,J){let L=await d(B,D);if(J&&Object.keys(J).length>0){let U={};if(await Promise.all(Object.entries(J).map(async([Q,Z])=>{let $=await Z(D[Q],D);if($!==!0)U[Q]=typeof $==="string"?$:`${Q} validation failed`})),Object.keys(U).length>0)throw new z(422,"Validation failed",{errors:U})}return L}async function n(B){if(!B||typeof B!=="object")return{};if(typeof B.all==="function"){let L=B.all();return L instanceof Promise?await L:L}let D=B,J={};if(D.url)try{new URL(D.url).searchParams.forEach((U,Q)=>{J[Q]=U})}catch{}if(D.query&&typeof D.query==="object")Object.assign(J,D.query);if(D.jsonBody&&typeof D.jsonBody==="object")Object.assign(J,D.jsonBody);if(D.formBody&&typeof D.formBody==="object")Object.assign(J,D.formBody);if(D.params&&typeof D.params==="object")Object.assign(J,D.params);if(Object.keys(J).length===0&&!("all"in B)&&!("jsonBody"in B))return B;return J}async function CB(B,D){let J=await n(B),L={},U={};for(let[Q,Z]of Object.entries(D)){if(!Z)continue;if(typeof Z.rule==="object"||typeof Z.rule==="function"){L[Q]=Z.rule;let $=Z.message;if(typeof $==="string")U[`${Q}.default`]=$;else if($&&typeof $==="object")for(let[X,G]of Object.entries($))U[`${Q}.${X}`]=G}else L[Q]=Z}try{if(Object.keys(U).length>0)x(new E(U));let Z=await W.object(L).validate(J);if(!Z.valid){let X={};for(let G of Z.errors||[]){let N=G.field??"_";if(!X[N])X[N]=[];X[N].push(G.message)}throw new z(422,"Validation failed",{errors:X})}return Z.value??J}catch(Q){if(Q instanceof z)throw Q;throw new z(500,K(Q)||"An unexpected validation error occurred")}}async function HB(B,D){let J={},L={};for(let U in B)if(Object.prototype.hasOwnProperty.call(B,U)){let Q=B[U]?.rule;if(Q)J[U]=Q;let Z=B[U]?.message;for(let $ in Z){let X=`${U}.${$}`;L[X]=B[U]?.message[$]||""}}try{let Q=await W.object().shape(J).validate(D);if(!Q.valid)throw new z(422,"Validation failed",{errors:Q.errors});return Q}catch(U){if(U instanceof z)throw U;throw new z(500,K(U)||"An unexpected validation error occurred")}}function qB(B){return typeof B==="string"}function FB(B){return typeof B==="number"&&!Number.isNaN(B)}function MB(B){return typeof B==="boolean"}function OB(B){return typeof B==="object"&&B!==null&&!Array.isArray(B)}function RB(B){return Array.isArray(B)}function EB(B){return typeof B==="function"}function xB(B){return B===void 0}function jB(B){return B===null}function wB(B){return B===null||B===void 0}export{T as withConditionals,AB as validateFieldAsync,d as validateField,CB as validate,IB as unique,H as shouldApplyConditional,W as schema,O as reportError,PB as registerRule,I as objectWithContext,xB as isUndefined,qB as isString,YB as isObjectNotEmpty,OB as isObject,FB as isNumber,wB as isNullOrUndefined,jB as isNull,EB as isFunction,MB as isBoolean,RB as isArray,XB as getErrors,VB as getCustomRule,SB as exists,HB as customValidate,V as applyConditionals};
2
+ var F=import.meta.require;import{v as b}from"@stacksjs/ts-validation";var h=new Set(["image/jpeg","image/png","image/webp","image/gif","image/avif"]);function q(B){return B.mimetype??B.mimeType}function f(B){return B.originalName??B.name}function g(B){let D=f(B);if(!D)return null;let J=D.lastIndexOf(".");if(J<=0||J===D.length-1)return null;let L=D.slice(J+1).toLowerCase();return/^[a-z0-9]+$/.test(L)?L:null}class A{_required=!1;_rules=[];required(){return this._required=!0,this}image(){return this._rules.push((B)=>{let D=q(B);if(!D||!h.has(D.toLowerCase()))return`must be an image (got ${D||"no mimetype"})`;return null}),this}mimeTypes(B){let D=new Set(B.map((J)=>J.toLowerCase()));return this._rules.push((J)=>{let L=q(J);if(!L||!D.has(L.toLowerCase()))return`must be one of: ${B.join(", ")} (got ${L||"no mimetype"})`;return null}),this}maxBytes(B){return this._rules.push((D)=>{if(typeof D.size!=="number")return"has no size \u2014 cannot enforce maxBytes";if(D.size>B)return`is too large: ${D.size} bytes exceeds the ${B}-byte cap`;return null}),this}minBytes(B){return this._rules.push((D)=>{if(typeof D.size!=="number")return"has no size \u2014 cannot enforce minBytes";if(D.size<B)return`is too small: ${D.size} bytes is below the ${B}-byte minimum`;return null}),this}extensions(B){let D=new Set(B.map((J)=>J.toLowerCase().replace(/^\./,"")));return this._rules.push((J)=>{let L=g(J);if(!L||!D.has(L))return`must have one of these extensions: ${B.join(", ")} (got ${L?`.${L}`:"no extension"})`;return null}),this}custom(B){return this._rules.push(B),this}validate(B){if(B===null||B===void 0){if(this._required)return{valid:!1,errors:[{message:"is required"}]};return{valid:!0}}if(typeof B!=="object"||typeof B.size!=="number")return{valid:!1,errors:[{message:"must be an uploaded file"}]};let D=B,J=[];for(let L of this._rules){let U=L(D);if(U)J.push({message:U})}return J.length===0?{valid:!0}:{valid:!1,errors:J}}}function C(){return new A}function T(B){let D=B;return D.when=function(L,U,Q){if(!this.__conditionals)this.__conditionals=[];return this.__conditionals.push({field:L,match:U,refine:Q}),this},D.sometimes=function(){return this.optional(),this},D}function H(B,D){if(D===null||D===void 0)return!1;let J=D[B.field];if(typeof B.match==="function")return B.match(J);return J===B.match}function V(B,D){let J=B.__conditionals;if(!J||J.length===0)return B;let L=null;for(let U of J){if(!H(U,D))continue;if(L===null)L=y(B);L=U.refine(L)}return L??B}function y(B){let D=Object.create(Object.getPrototypeOf(B));Object.assign(D,B);let J=B.rules;if(Array.isArray(J))D.rules=J.slice();return D}function I(B){let D=B??{},J=!0,L={name:"object",get isRequired(){return J},getRules:()=>[],test(Q){return this.validate(Q).valid},isPartOfShape:!1,shape(Q){return D=Q,L},getShape(){return D},required(){return J=!0,U},optional(){return J=!1,U},validate(Q){let Z=Q===void 0||Q===null;if(!J&&Z)return{valid:!0,errors:this.isPartOfShape?{}:[]};if(J&&Z)return this.isPartOfShape?{valid:!1,errors:{object:[{message:"value is required"}]}}:{valid:!1,errors:[{message:"value is required"}]};if(typeof Q!=="object"||Array.isArray(Q))return this.isPartOfShape?{valid:!1,errors:{object:[{message:"Must be an object"}]}}:{valid:!1,errors:[{message:"Must be an object"}]};let $=Q,X={},G=!1;for(let N of Object.keys(D)){let _=D[N];if(!_)continue;let Y=V(_,$),S=$[N],P=Y.validate(S);if(P.valid)continue;if(G=!0,!Array.isArray(P.errors))for(let[w,k]of Object.entries(P.errors))X[`${N}.${w}`]=k;else X[N]=P.errors}if(G)return{valid:!1,errors:X};return{valid:!0,errors:{}}}},U=T(L);return U}var v=new Set(["array","bigint","binary","blob","boolean","custom","date","datetime","decimal","double","enum","float","integer","json","number","password","smallint","string","text","time","timestamp","timestampTz","unix"]);function m(B){return(...D)=>{let J=B(...D);return T(J)}}var W=new Proxy(b,{get(B,D,J){if(D==="file")return C;if(D==="object")return I;if(typeof D==="string"&&v.has(D)){let L=Reflect.get(B,D,J);if(typeof L==="function")return m(L)}return Reflect.get(B,D,J)}});export*from"@stacksjs/ts-validation";var M=[];function O(B){M=B}function XB(){return M}import{HttpError as z}from"@stacksjs/error-handling";import{path as R}from"@stacksjs/path";import{snakeCase as p}from"@stacksjs/strings";import{getErrorMessage as K}from"@stacksjs/utils";import{MessageProvider as E,setCustomMessages as x}from"@stacksjs/ts-validation";function c(B,D={}){let J=[];for(let L of B){let Q=L.startsWith("/")?L.lastIndexOf("/"):-1,Z=L.indexOf("*"),$=Z===-1?Q:L.lastIndexOf("/",Z),X=$>0?L.slice(0,$):".",G=$>0?L.slice($+1):L,N=new Bun.Glob(G);for(let _ of N.scanSync({cwd:X,onlyFiles:!0}))J.push(D.absolute?`${X}/${_}`:_)}return J}function YB(B){if(B===void 0)return!1;return Object.keys(B).length>0}async function d(B,D){let L=c([R.userModelsPath("*.ts"),R.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}).find((X)=>X.endsWith(`${B}.ts`));if(!L)throw new z(404,`Model ${B} not found`);let Q=(await import(L)).default.attributes,Z={},$={};for(let X in Q)if(Object.prototype.hasOwnProperty.call(Q,X)){let G=Q[X];if(!G)continue;let N="isRequired"in(G.validation?.rule??{})?(G.validation?.rule).isRequired:!1;if(G.default!==void 0&&N===!1)continue;Z[p(X)]=G.validation?.rule;let _=G.validation?.message;if(_)for(let Y in _){let S=`${X}.${Y}`;$[S]=_[Y]||""}}try{x(new E($));let G=await W.object(Z).validate(D);if(!G.valid)throw O(G.errors),new z(422,"Validation failed",{errors:G.errors});return G}catch(X){if(X instanceof z)throw X;throw new z(500,K(X)||"An unexpected validation error occurred")}}var j=new Map;function PB(B,D){j.set(B,D)}function VB(B){return j.get(B)}function IB(B,D,J){return async(L)=>{try{let{db:U}=await import("@stacksjs/database"),Q=U.selectFrom(B).where(D,"=",L);if(J)Q=Q.where("id","!=",J);return await Q.selectAll().executeTakeFirst()?`The ${D} has already been taken`:!0}catch{return!0}}}function SB(B,D){return async(J)=>{try{let{db:L}=await import("@stacksjs/database");return await L.selectFrom(B).where(D,"=",J).selectAll().executeTakeFirst()?!0:`The selected ${D} does not exist`}catch{return!0}}}async function AB(B,D,J){let L=await d(B,D);if(J&&Object.keys(J).length>0){let U={};if(await Promise.all(Object.entries(J).map(async([Q,Z])=>{let $=await Z(D[Q],D);if($!==!0)U[Q]=typeof $==="string"?$:`${Q} validation failed`})),Object.keys(U).length>0)throw new z(422,"Validation failed",{errors:U})}return L}async function n(B){if(!B||typeof B!=="object")return{};if(typeof B.all==="function"){let L=B.all();return L instanceof Promise?await L:L}let D=B,J={};if(D.url)try{new URL(D.url).searchParams.forEach((U,Q)=>{J[Q]=U})}catch{}if(D.query&&typeof D.query==="object")Object.assign(J,D.query);if(D.jsonBody&&typeof D.jsonBody==="object")Object.assign(J,D.jsonBody);if(D.formBody&&typeof D.formBody==="object")Object.assign(J,D.formBody);if(D.params&&typeof D.params==="object")Object.assign(J,D.params);if(Object.keys(J).length===0&&!("all"in B)&&!("jsonBody"in B))return B;return J}async function CB(B,D){let J=await n(B),L={},U={};for(let[Q,Z]of Object.entries(D)){if(!Z)continue;if(typeof Z.rule==="object"||typeof Z.rule==="function"){L[Q]=Z.rule;let $=Z.message;if(typeof $==="string")U[`${Q}.default`]=$;else if($&&typeof $==="object")for(let[X,G]of Object.entries($))U[`${Q}.${X}`]=G}else L[Q]=Z}try{if(Object.keys(U).length>0)x(new E(U));let Z=await W.object(L).validate(J);if(!Z.valid){let X={};for(let G of Z.errors||[]){let N=G.field??"_";if(!X[N])X[N]=[];X[N].push(G.message)}throw new z(422,"Validation failed",{errors:X})}return Z.value??J}catch(Q){if(Q instanceof z)throw Q;throw new z(500,K(Q)||"An unexpected validation error occurred")}}async function HB(B,D){let J={},L={};for(let U in B)if(Object.prototype.hasOwnProperty.call(B,U)){let Q=B[U]?.rule;if(Q)J[U]=Q;let Z=B[U]?.message;for(let $ in Z){let X=`${U}.${$}`;L[X]=B[U]?.message[$]||""}}try{let Q=await W.object().shape(J).validate(D);if(!Q.valid)throw new z(422,"Validation failed",{errors:Q.errors});return Q}catch(U){if(U instanceof z)throw U;throw new z(500,K(U)||"An unexpected validation error occurred")}}function FB(B){return typeof B==="string"}function qB(B){return typeof B==="number"&&!Number.isNaN(B)}function MB(B){return typeof B==="boolean"}function OB(B){return typeof B==="object"&&B!==null&&!Array.isArray(B)}function RB(B){return Array.isArray(B)}function EB(B){return typeof B==="function"}function xB(B){return B===void 0}function jB(B){return B===null}function wB(B){return B===null||B===void 0}export{T as withConditionals,AB as validateFieldAsync,d as validateField,CB as validate,IB as unique,H as shouldApplyConditional,W as schema,O as reportError,PB as registerRule,I as objectWithContext,xB as isUndefined,FB as isString,YB as isObjectNotEmpty,OB as isObject,qB as isNumber,wB as isNullOrUndefined,jB as isNull,EB as isFunction,MB as isBoolean,RB as isArray,XB as getErrors,VB as getCustomRule,SB as exists,HB as customValidate,V as applyConditionals};
@@ -26,12 +26,12 @@ export declare function objectWithContext<T extends Record<string, Validator<any
26
26
  * and other introspection passes can walk the per-field validators
27
27
  * (and their `__conditionals` arrays).
28
28
  */
29
- export declare interface ObjectWithContextValidator<T extends Record<string, Validator<any>>> {
29
+ export declare interface ObjectWithContextValidator<T extends Record<string, Validator<any>>> extends Validator<Record<string, unknown>> {
30
30
  readonly name: 'object'
31
31
  validate: (value: unknown) => ValidationResult
32
32
  getShape: () => T
33
- required: () => ObjectWithContextValidator<T> & ConditionalAPI<ObjectWithContextValidator<T>>
34
- optional: () => ObjectWithContextValidator<T> & ConditionalAPI<ObjectWithContextValidator<T>>
33
+ required: () => this
34
+ optional: () => this
35
35
  isPartOfShape: boolean
36
36
  shape: (shape: T) => ObjectWithContextValidator<T>
37
37
  }
package/dist/schema.d.ts CHANGED
@@ -27,8 +27,9 @@ export declare const schema: SchemaWithFile;
27
27
  * and every primitive factory wrapped to attach `.when()` / `.sometimes()`
28
28
  * to the returned validator.
29
29
  */
30
- export declare interface SchemaWithFile extends ValidationInstance {
30
+ export type SchemaWithFile = Omit<ValidationInstance, 'object'> & {
31
31
  file: () => FileValidator
32
+ object: typeof objectWithContext
32
33
  }
33
34
  export { file, FileValidator } from './file-validator';
34
35
  export { applyConditionals, shouldApplyConditional, withConditionals } from './conditional';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/validation",
3
3
  "type": "module",
4
- "version": "0.70.73",
4
+ "version": "0.70.74",
5
5
  "description": "The Stacks Validation ways.",
6
6
  "author": "Chris Breuer",
7
7
  "contributors": [
@@ -55,8 +55,8 @@
55
55
  "@stacksjs/ts-validation": "^0.5.0"
56
56
  },
57
57
  "devDependencies": {
58
- "better-dx": "^0.2.12",
59
- "@stacksjs/strings": "0.70.73",
60
- "@stacksjs/types": "0.70.73"
58
+ "better-dx": "^0.2.16",
59
+ "@stacksjs/strings": "0.70.74",
60
+ "@stacksjs/types": "0.70.74"
61
61
  }
62
62
  }