@stacksjs/validation 0.70.45 → 0.70.54
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/LICENSE.md +21 -0
- package/dist/conditional.d.ts +59 -0
- package/dist/file-validator.d.ts +65 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +1 -1
- package/dist/object-with-context.d.ts +37 -0
- package/dist/schema.d.ts +34 -1
- package/package.json +4 -4
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Open Web Foundation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Validator } from '@stacksjs/ts-validation';
|
|
2
|
+
/**
|
|
3
|
+
* Mixin: add `.when()` / `.sometimes()` to a validator instance.
|
|
4
|
+
*
|
|
5
|
+
* Mutates the validator in place (assigning the new methods) so the
|
|
6
|
+
* existing chainable surface (`.required()`, `.minLength()`, etc.)
|
|
7
|
+
* keeps returning `this`. Returns the same instance with the augmented
|
|
8
|
+
* type so callers see the new methods on the fluent chain.
|
|
9
|
+
*/
|
|
10
|
+
export declare function withConditionals<V extends Validator<any>>(validator: V): V & ConditionalAPI<V>;
|
|
11
|
+
/**
|
|
12
|
+
* Evaluate a single `when` clause against a parent object.
|
|
13
|
+
*
|
|
14
|
+
* Returns `true` when the conditional should fire (and its refinement
|
|
15
|
+
* should be applied). Pure function — no side effects, safe to call
|
|
16
|
+
* during introspection too.
|
|
17
|
+
*/
|
|
18
|
+
export declare function shouldApplyConditional(record: ConditionalRecord<Validator<any>>, parent: Record<string, unknown> | null | undefined): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Apply every matching conditional on `base` against `parent`, in
|
|
21
|
+
* registration order. Returns the (possibly refined) validator that
|
|
22
|
+
* should be used to validate the field.
|
|
23
|
+
*
|
|
24
|
+
* The base validator is NEVER mutated — ts-validation methods like
|
|
25
|
+
* `.required()` and `.min(3)` MUTATE `this` and return it, so calling
|
|
26
|
+
* refine functions directly on the base would leak across `validate()`
|
|
27
|
+
* invocations (each call would compound the previous refinements,
|
|
28
|
+
* making "VAT required for EU customers" sticky across requests).
|
|
29
|
+
* {@link cloneValidator} produces an isolated instance the refine
|
|
30
|
+
* pipeline can safely mutate without polluting the schema definition.
|
|
31
|
+
*/
|
|
32
|
+
export declare function applyConditionals<V extends Validator<any>>(base: V, parent: Record<string, unknown> | null | undefined): V;
|
|
33
|
+
/**
|
|
34
|
+
* A single `.when()` clause attached to a field validator. Multiple
|
|
35
|
+
* `.when()` calls stack — they're evaluated in registration order and
|
|
36
|
+
* each matching one further refines the base validator.
|
|
37
|
+
*/
|
|
38
|
+
export declare interface ConditionalRecord<V extends Validator<any>> {
|
|
39
|
+
field: string
|
|
40
|
+
match: unknown | ((value: unknown) => boolean)
|
|
41
|
+
refine: (validator: V) => V
|
|
42
|
+
}
|
|
43
|
+
/** Anything that has a mutable conditionals array — duck-typed so this
|
|
44
|
+
* works across all the ts-validation validator subclasses. */
|
|
45
|
+
export declare interface ValidatorWithConditionals<V extends Validator<any>> {
|
|
46
|
+
__conditionals?: ConditionalRecord<V>[]
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Conditional-rules surface — apps reach these methods through
|
|
50
|
+
* `.when()` / `.sometimes()` on any validator the schema proxy returns.
|
|
51
|
+
*/
|
|
52
|
+
export declare interface ConditionalAPI<V extends Validator<any>> {
|
|
53
|
+
when: (
|
|
54
|
+
field: string,
|
|
55
|
+
match: unknown | ((value: unknown) => boolean),
|
|
56
|
+
refine: (validator: V) => V,
|
|
57
|
+
) => V & ConditionalAPI<V>
|
|
58
|
+
sometimes: () => V & ConditionalAPI<V>
|
|
59
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** Factory matching ts-validation's `v.string()` / `v.number()` style. */
|
|
2
|
+
export declare function file(): FileValidator;
|
|
3
|
+
/**
|
|
4
|
+
* `schema.file()` — chainable validator for uploaded files
|
|
5
|
+
* (stacksjs/stacks#1856).
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the ergonomics of `schema.string()` / `schema.number()` /
|
|
8
|
+
* `schema.enum()` from ts-validation but targets the `UploadedFile`
|
|
9
|
+
* shape that `req.file('avatar')` / `req.files` return. Conforms to the
|
|
10
|
+
* `{ rule: { validate(value): { valid, errors? } } }` contract that the
|
|
11
|
+
* Action layer ({@link `@stacksjs/router`} → `validateActionInput`)
|
|
12
|
+
* iterates, so file validations slot into the same `validations:` block
|
|
13
|
+
* as the rest of the field rules:
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* new Action({
|
|
18
|
+
* method: 'POST',
|
|
19
|
+
* validations: {
|
|
20
|
+
* avatar: { rule: schema.file().image().maxBytes(2 * 1024 * 1024) },
|
|
21
|
+
* },
|
|
22
|
+
* async handle(req) {
|
|
23
|
+
* const file = req.file('avatar')!
|
|
24
|
+
* const { url } = await Storage.put(file, { disk: 'public', dir: 'avatars' })
|
|
25
|
+
* // …
|
|
26
|
+
* },
|
|
27
|
+
* })
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* The validator is intentionally narrow on the input it accepts: a
|
|
31
|
+
* structural shape with `size: number` and either `mimetype` or
|
|
32
|
+
* `mimeType`, optionally with `originalName` / `name`. Both the
|
|
33
|
+
* router's wrapping `UploadedFile` class and the raw multipart-parse
|
|
34
|
+
* shape satisfy it.
|
|
35
|
+
*/
|
|
36
|
+
/** Shape this validator runs against. */
|
|
37
|
+
export declare interface FileLike {
|
|
38
|
+
size: number
|
|
39
|
+
mimetype?: string
|
|
40
|
+
mimeType?: string
|
|
41
|
+
originalName?: string
|
|
42
|
+
name?: string
|
|
43
|
+
}
|
|
44
|
+
declare interface ValidationError { message: string }
|
|
45
|
+
declare interface ValidationResult { valid: boolean, errors?: ValidationError[] }
|
|
46
|
+
/**
|
|
47
|
+
* Chainable file validator. Each method returns `this` so callers can
|
|
48
|
+
* stack constraints in any order; rules accumulate into an internal
|
|
49
|
+
* list and run sequentially on `.validate()`.
|
|
50
|
+
*
|
|
51
|
+
* Designed to be cheap to construct — most validators in an Action's
|
|
52
|
+
* `validations:` block are built once at module load. No I/O happens
|
|
53
|
+
* here; image dimension / content-sniffing rules belong in a separate
|
|
54
|
+
* `@stacksjs/storage/image` opt-in (deliverable 5 of #1856).
|
|
55
|
+
*/
|
|
56
|
+
export declare class FileValidator {
|
|
57
|
+
required(): this;
|
|
58
|
+
image(): this;
|
|
59
|
+
mimeTypes(allowed: string[]): this;
|
|
60
|
+
maxBytes(max: number): this;
|
|
61
|
+
minBytes(min: number): this;
|
|
62
|
+
extensions(allowed: string[]): this;
|
|
63
|
+
custom(rule: (file: FileLike) => string | null): this;
|
|
64
|
+
validate(value: unknown): ValidationResult;
|
|
65
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
ConditionalAPI,
|
|
3
|
+
ConditionalRecord,
|
|
4
|
+
ObjectWithContextValidator,
|
|
5
|
+
ValidatorWithConditionals,
|
|
6
|
+
} from './schema';
|
|
1
7
|
// Type guard utilities
|
|
2
8
|
export declare function isString(value: unknown): value is string;
|
|
3
9
|
export declare function isNumber(value: unknown): value is number;
|
|
@@ -16,6 +22,14 @@ export declare function isNullOrUndefined(value: unknown): value is null | undef
|
|
|
16
22
|
// `export *` re-exports from `@stacksjs/ts-validation` (which also exports
|
|
17
23
|
// a `schema` symbol) and see whichever binding was registered first.
|
|
18
24
|
export { schema } from './schema';
|
|
25
|
+
// Conditional validation surface — `.when()` / `.sometimes()` mixins +
|
|
26
|
+
// context-aware object validator (stacksjs/stacks#1890).
|
|
27
|
+
export {
|
|
28
|
+
applyConditionals,
|
|
29
|
+
objectWithContext,
|
|
30
|
+
shouldApplyConditional,
|
|
31
|
+
withConditionals,
|
|
32
|
+
} from './schema';
|
|
19
33
|
// Re-export everything from @stacksjs/ts-validation. The explicit `schema`
|
|
20
34
|
// export above shadows ts-validation's own `schema` for `import { schema }
|
|
21
35
|
// from '@stacksjs/validation'` consumers — which is what we want, since the
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
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};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ConditionalAPI } from './conditional';
|
|
2
|
+
import type { ValidationResult, Validator } from '@stacksjs/ts-validation';
|
|
3
|
+
/**
|
|
4
|
+
* Build a Stacks-flavored object validator that respects conditional
|
|
5
|
+
* rules on its child validators. Drop-in for `v.object(...)` in
|
|
6
|
+
* `@stacksjs/ts-validation` — same call shape, broader behavior.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* objectWithContext({
|
|
11
|
+
* payment_method: schema.enum(['card', 'bank']),
|
|
12
|
+
* card_token: schema.string().when('payment_method', 'card', s => s.required()),
|
|
13
|
+
* bank_account: schema.string().when('payment_method', 'bank', s => s.required()),
|
|
14
|
+
* username: schema.string().sometimes().minLength(3),
|
|
15
|
+
* }).validate(input)
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function objectWithContext<T extends Record<string, Validator<any>>>(initialShape?: T): ObjectWithContextValidator<T> & ConditionalAPI<ObjectWithContextValidator<T>>;
|
|
19
|
+
/**
|
|
20
|
+
* Validator-shaped object returned by `schema.object()`. Mirrors the
|
|
21
|
+
* subset of ts-validation's `ObjectValidatorType` that Stacks code
|
|
22
|
+
* actually uses today (`validate`, `shape`, `optional`, `required`).
|
|
23
|
+
*
|
|
24
|
+
* Extra method:
|
|
25
|
+
* - `getShape()` — exposes the underlying shape map so OpenAPI export
|
|
26
|
+
* and other introspection passes can walk the per-field validators
|
|
27
|
+
* (and their `__conditionals` arrays).
|
|
28
|
+
*/
|
|
29
|
+
export declare interface ObjectWithContextValidator<T extends Record<string, Validator<any>>> {
|
|
30
|
+
readonly name: 'object'
|
|
31
|
+
validate: (value: unknown) => ValidationResult
|
|
32
|
+
getShape: () => T
|
|
33
|
+
required: () => ObjectWithContextValidator<T> & ConditionalAPI<ObjectWithContextValidator<T>>
|
|
34
|
+
optional: () => ObjectWithContextValidator<T> & ConditionalAPI<ObjectWithContextValidator<T>>
|
|
35
|
+
isPartOfShape: boolean
|
|
36
|
+
shape: (shape: T) => ObjectWithContextValidator<T>
|
|
37
|
+
}
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,2 +1,35 @@
|
|
|
1
|
+
import { file, FileValidator } from './file-validator';
|
|
2
|
+
import { objectWithContext } from './object-with-context';
|
|
3
|
+
import { withConditionals } from './conditional';
|
|
4
|
+
import type { ConditionalAPI } from './conditional';
|
|
5
|
+
import type { ObjectWithContextValidator } from './object-with-context';
|
|
1
6
|
import type { ValidationInstance } from '@stacksjs/ts-validation';
|
|
2
|
-
export
|
|
7
|
+
export type { FileLike } from './file-validator';
|
|
8
|
+
export type { ConditionalAPI, ConditionalRecord, ValidatorWithConditionals } from './conditional';
|
|
9
|
+
export type { ObjectWithContextValidator } from './object-with-context';
|
|
10
|
+
/**
|
|
11
|
+
* `Object.assign({}, v, { file })` would defeat the ts-validation
|
|
12
|
+
* proxy's late-binding. Wrapping with `new Proxy` keeps every existing
|
|
13
|
+
* `schema.<method>()` call going through the upstream proxy while only
|
|
14
|
+
* intercepting the slots we own (`file`, `object`, and the conditional
|
|
15
|
+
* mixin on primitive factories).
|
|
16
|
+
*/
|
|
17
|
+
export declare const schema: SchemaWithFile;
|
|
18
|
+
/**
|
|
19
|
+
* Extended `ValidationInstance` that adds `schema.file()` on top of the
|
|
20
|
+
* ts-validation surface (stacksjs/stacks#1856). Upstream ts-validation
|
|
21
|
+
* has `string()`, `number()`, `enum()`, etc. but no `file()` validator;
|
|
22
|
+
* we layer one here without forking ts-validation so the rest of the
|
|
23
|
+
* surface keeps working unchanged.
|
|
24
|
+
*
|
|
25
|
+
* The runtime value is the ts-validation proxy with `file` patched in,
|
|
26
|
+
* `object` swapped for the context-aware variant (stacksjs/stacks#1890),
|
|
27
|
+
* and every primitive factory wrapped to attach `.when()` / `.sometimes()`
|
|
28
|
+
* to the returned validator.
|
|
29
|
+
*/
|
|
30
|
+
export declare interface SchemaWithFile extends ValidationInstance {
|
|
31
|
+
file: () => FileValidator
|
|
32
|
+
}
|
|
33
|
+
export { file, FileValidator } from './file-validator';
|
|
34
|
+
export { applyConditionals, shouldApplyConditional, withConditionals } from './conditional';
|
|
35
|
+
export { objectWithContext } from './object-with-context';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/validation",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.70.
|
|
4
|
+
"version": "0.70.54",
|
|
5
5
|
"description": "The Stacks Validation ways.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
7
|
"contributors": [
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"prepublishOnly": "bun run build"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@stacksjs/ts-validation": "^0.
|
|
51
|
+
"@stacksjs/ts-validation": "^0.5.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"better-dx": "^0.2.12",
|
|
55
|
-
"@stacksjs/strings": "
|
|
56
|
-
"@stacksjs/types": "
|
|
55
|
+
"@stacksjs/strings": "0.70.54",
|
|
56
|
+
"@stacksjs/types": "0.70.54"
|
|
57
57
|
}
|
|
58
58
|
}
|