@ripetchor/vivi 0.0.7 → 0.0.9
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/README.md +57 -9
- package/dist/index.d.mts +15 -1
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,18 +13,20 @@ WARNING: This package is primarily intended for personal use. It may contain bug
|
|
|
13
13
|
|
|
14
14
|
## Other Validators
|
|
15
15
|
|
|
16
|
+
- `v.unknown()`
|
|
17
|
+
- `v.fallback(validator, defaultValue)`
|
|
18
|
+
- `v.email(options?)`
|
|
16
19
|
- `v.nullable(validator)`
|
|
17
20
|
- `v.optional(validator)`
|
|
18
|
-
- `v.array(validator, options?)`
|
|
19
|
-
- `v.object(shape, options?)`
|
|
20
|
-
- `v.union([validators], options?)`
|
|
21
21
|
- `v.literal(value, options?)`
|
|
22
|
-
- `v.instance(Class, options?)`
|
|
23
22
|
- `v.date(options?)`
|
|
24
|
-
- `v.
|
|
25
|
-
- `v.
|
|
26
|
-
- `v.
|
|
27
|
-
- `v.
|
|
23
|
+
- `v.union([validators], options?)`
|
|
24
|
+
- `v.instance(Class, options?)`
|
|
25
|
+
- `v.object(shape, options?)`
|
|
26
|
+
- `v.array(validator, options?)`
|
|
27
|
+
- `v.map(keyValidator, valueValidator, options?)`
|
|
28
|
+
- `v.set(validator, options?)`
|
|
29
|
+
- `v.refine(validator, refinementFns[], options?)`
|
|
28
30
|
- `v.pipe(validator, ...transformFns)`
|
|
29
31
|
|
|
30
32
|
## Usage Examples
|
|
@@ -143,7 +145,7 @@ const result = refinedUserSchema.safeParse({
|
|
|
143
145
|
password: "secret123",
|
|
144
146
|
confirmPassword: "secret321",
|
|
145
147
|
});
|
|
146
|
-
console.log(result); // [ {
|
|
148
|
+
console.log(result); // [ { path: ["confirmPassword"], message: "Passwordsdo not match"} ]
|
|
147
149
|
```
|
|
148
150
|
|
|
149
151
|
- `true` → validation passes
|
|
@@ -325,3 +327,49 @@ console.log(flattenErrors(result.error.issues));
|
|
|
325
327
|
// agreeToTerms: 'Expected literal true'
|
|
326
328
|
// }
|
|
327
329
|
```
|
|
330
|
+
|
|
331
|
+
## Custom validator
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
import { customValidator, ViviError, type ParseFn, type Path } from '@ripetchor/vivi';
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
interface User {
|
|
338
|
+
name: string;
|
|
339
|
+
age: number;
|
|
340
|
+
email: string;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const parseFn: ParseFn<User> = (input: unknown, path: Path): User => {
|
|
344
|
+
if (typeof input !== "object" || input === null) {
|
|
345
|
+
throw ViviError.single("Expected object", path);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const obj = input as Record<string, unknown>;
|
|
349
|
+
|
|
350
|
+
const name = obj.name;
|
|
351
|
+
if (typeof name !== "string" || name.trim() === "") {
|
|
352
|
+
throw ViviError.single("Name must be a non-empty string", [...path, "name"]);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const age = obj.age;
|
|
356
|
+
if (typeof age !== "number" || age < 0) {
|
|
357
|
+
throw ViviError.single("Age must be a non-negative number", [...path, "age"]);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const email = obj.email;
|
|
361
|
+
if (typeof email !== "string" || !/^\S+@\S+\.\S+$/.test(email)) {
|
|
362
|
+
throw ViviError.single("Invalid email", [...path, "email"]);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return { name: name.trim(), age, email };
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
const userValidator = customValidator<User>(parseFn);
|
|
369
|
+
|
|
370
|
+
const result = userValidator.safeParse({ name: " Alice ", age: 25, email: "alice@example.com" });
|
|
371
|
+
|
|
372
|
+
if (result.success) {
|
|
373
|
+
console.log(result.data); // { name: "Alice", age: 25, email: "alice@example.com" }
|
|
374
|
+
}
|
|
375
|
+
```
|
package/dist/index.d.mts
CHANGED
|
@@ -74,6 +74,12 @@ declare function instanceValidator<T>(ctor: new (...args: any[]) => T, options?:
|
|
|
74
74
|
//#region src/literal-validator.d.ts
|
|
75
75
|
declare function literalValidator<T extends string | number | boolean>(value: T, options?: ValidatorOptions): ViviValidator<T>;
|
|
76
76
|
//#endregion
|
|
77
|
+
//#region src/map-validator.d.ts
|
|
78
|
+
interface MapValidatorOptions extends ValidatorOptions {
|
|
79
|
+
abort?: boolean;
|
|
80
|
+
}
|
|
81
|
+
declare function mapValidator<K$1, V>(keyValidator: ViviValidator<K$1>, valueValidator: ViviValidator<V>, options?: MapValidatorOptions): ViviValidator<Map<K$1, V>>;
|
|
82
|
+
//#endregion
|
|
77
83
|
//#region src/null-validator.d.ts
|
|
78
84
|
declare function nullValidator(options?: ValidatorOptions): ViviValidator<null>;
|
|
79
85
|
//#endregion
|
|
@@ -128,6 +134,12 @@ interface RefineOptions {
|
|
|
128
134
|
}
|
|
129
135
|
declare function refine<T>(validator: ViviValidator<T>, refinements: RefineFn<T>[], options?: RefineOptions): ViviValidator<T>;
|
|
130
136
|
//#endregion
|
|
137
|
+
//#region src/set-validator.d.ts
|
|
138
|
+
interface SetValidatorOptions extends ValidatorOptions {
|
|
139
|
+
abort?: boolean;
|
|
140
|
+
}
|
|
141
|
+
declare function setValidator<T>(validator: ViviValidator<T>, options?: SetValidatorOptions): ViviValidator<Set<T>>;
|
|
142
|
+
//#endregion
|
|
131
143
|
//#region src/shared/create-validator.d.ts
|
|
132
144
|
declare function createValidator<T>(parseFn: ParseFn<T>): ViviValidator<T>;
|
|
133
145
|
//#endregion
|
|
@@ -222,9 +234,11 @@ declare const v: {
|
|
|
222
234
|
refine: typeof refine;
|
|
223
235
|
pipe: typeof pipe;
|
|
224
236
|
match: typeof match;
|
|
237
|
+
map: typeof mapValidator;
|
|
238
|
+
set: typeof setValidator;
|
|
225
239
|
};
|
|
226
240
|
declare namespace v {
|
|
227
241
|
type infer<T extends ViviValidator<unknown>> = Infer<T>;
|
|
228
242
|
}
|
|
229
243
|
//#endregion
|
|
230
|
-
export { ViviError, abs, arrayValidator, between, bigintValidator, booleanValidator, ceil, clamp, createValidator as customValidator, dateValidator, v as default, v, emailValidator, endsWith, even, fallback, finite, flattenErrors, floor, gt, includes, instanceValidator, integer, issuesToObject, issuesToString, length, literalValidator, lowercase, lt, match, max, maxLength, min, minLength, negative, nonEmpty, normalizeSpaces, notIncludes, nullValidator, nullableValidator, numberValidator, objectValidator, odd, optionalValidator, pattern, pipe, positive, refine, replace, round, startsWith, stringValidator, toLowerCase, toUpperCase, trim, trimmed, truncateEnd, truncateStart, undefinedValidator, unionValidator, unknownValidator, uppercase, uuid4 };
|
|
244
|
+
export { type ObjectShape, type ParseFn, type Path, type Prettify, type ValidatorOptions, ViviError, type ViviIssue, type ViviValidator, abs, arrayValidator, between, bigintValidator, booleanValidator, ceil, clamp, createValidator as customValidator, dateValidator, v as default, v, emailValidator, endsWith, even, fallback, finite, flattenErrors, floor, gt, includes, instanceValidator, integer, issuesToObject, issuesToString, length, literalValidator, lowercase, lt, mapValidator, match, max, maxLength, min, minLength, negative, nonEmpty, normalizeSpaces, notIncludes, nullValidator, nullableValidator, numberValidator, objectValidator, odd, optionalValidator, pattern, pipe, positive, refine, replace, round, setValidator, startsWith, stringValidator, toLowerCase, toUpperCase, trim, trimmed, truncateEnd, truncateStart, undefinedValidator, unionValidator, unknownValidator, uppercase, uuid4 };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=class e extends Error{issues;constructor(t){super(`Vivi validation error`),this.name=e.name,this.issues=t}static single(t,n){return new e([{message:t,path:n}])}merge(t){return new e([...this.issues,...t.issues])}};function t(e,t,n){for(let r=0;r<t.length;r++){let i=t[r],a=[];for(let e=0;e<n.length;e++)a.push(n[e]);for(let e=0;e<i.path.length;e++)a.push(i.path[e]);e.push({message:i.message,path:a})}}function n(t){return{parse(e,n=[]){return t(e,n)},safeParse(n){try{return{success:!0,data:t(n,[])}}catch(t){if(t instanceof e)return{success:!1,error:t};let n=t instanceof Error?t.message:`Unknown validation error`;return{success:!1,error:e.single(n,[])}}}}}function r(e,t,n){return typeof e==`function`?e(n):e??t}function i(i,a){return n((n,o)=>{if(!Array.isArray(n))throw e.single(r(a?.error,`Expected array`,n),o);let s=[],c=[];for(let r=0;r<n.length;r++){let l=i.safeParse(n[r]);if(l.success)s[r]=l.data;else if(t(c,l.error.issues,o.concat(r)),a?.abort)throw new e(c)}if(c.length>0)throw new e(c);return s})}function a(t){return n((n,i)=>{if(typeof n!=`bigint`)throw e.single(r(t?.error,`Expected bigint`,n),i);return n})}function o(t){return n((n,i)=>{if(typeof n!=`boolean`)throw e.single(r(t?.error,`Expected boolean`,n),i);return n})}function s(t){return n((n,i)=>{if(!(n instanceof Date)||isNaN(n.getTime()))throw e.single(r(t?.error,`Expected Date`,n),i);return n})}const c=/^(?!\.)(?!.*\.\.)([a-z0-9_'+\-\.]*)[a-z0-9_+\-]@([a-z0-9][a-z0-9\-]*\.)+[a-z]{2,}$/i;function l(t){let i=t?.pattern??c;return n((n,a)=>{if(typeof n!=`string`)throw e.single(r(t?.error,`Expected string`,n),a);if(!i.test(n))throw e.single(r(t?.error,`Invalid email format`,n),a);return n})}function u(t,r){return n((n,i)=>{try{return t.parse(n,i)}catch(t){if(t instanceof e)return r;throw t}})}function d(t,i){return n((n,a)=>{if(!(n instanceof t))throw e.single(r(i?.error,`Expected instance of ${t.name}`,n),a);return n})}function f(t,i){return n((n,a)=>{if(!Object.is(n,t))throw e.single(r(i?.error,`Expected literal ${String(t)}`,n),a);return t})}function p(t){return n((n,i)=>{if(!Object.is(n,null))throw e.single(r(t?.error,`Expected null`,n),i);return null})}function
|
|
2
|
-
`)}function
|
|
1
|
+
var e=class e extends Error{issues;constructor(t){super(`Vivi validation error`),this.name=e.name,this.issues=t}static single(t,n){return new e([{message:t,path:n}])}merge(t){return new e([...this.issues,...t.issues])}};function t(e,t,n){for(let r=0;r<t.length;r++){let i=t[r],a=[];for(let e=0;e<n.length;e++)a.push(n[e]);for(let e=0;e<i.path.length;e++)a.push(i.path[e]);e.push({message:i.message,path:a})}}function n(t){return{parse(e,n=[]){return t(e,n)},safeParse(n){try{return{success:!0,data:t(n,[])}}catch(t){if(t instanceof e)return{success:!1,error:t};let n=t instanceof Error?t.message:`Unknown validation error`;return{success:!1,error:e.single(n,[])}}}}}function r(e,t,n){return typeof e==`function`?e(n):e??t}function i(i,a){return n((n,o)=>{if(!Array.isArray(n))throw e.single(r(a?.error,`Expected array`,n),o);let s=[],c=[];for(let r=0;r<n.length;r++){let l=i.safeParse(n[r]);if(l.success)s[r]=l.data;else if(t(c,l.error.issues,o.concat(r)),a?.abort)throw new e(c)}if(c.length>0)throw new e(c);return s})}function a(t){return n((n,i)=>{if(typeof n!=`bigint`)throw e.single(r(t?.error,`Expected bigint`,n),i);return n})}function o(t){return n((n,i)=>{if(typeof n!=`boolean`)throw e.single(r(t?.error,`Expected boolean`,n),i);return n})}function s(t){return n((n,i)=>{if(!(n instanceof Date)||isNaN(n.getTime()))throw e.single(r(t?.error,`Expected Date`,n),i);return n})}const c=/^(?!\.)(?!.*\.\.)([a-z0-9_'+\-\.]*)[a-z0-9_+\-]@([a-z0-9][a-z0-9\-]*\.)+[a-z]{2,}$/i;function l(t){let i=t?.pattern??c;return n((n,a)=>{if(typeof n!=`string`)throw e.single(r(t?.error,`Expected string`,n),a);if(!i.test(n))throw e.single(r(t?.error,`Invalid email format`,n),a);return n})}function u(t,r){return n((n,i)=>{try{return t.parse(n,i)}catch(t){if(t instanceof e)return r;throw t}})}function d(t,i){return n((n,a)=>{if(!(n instanceof t))throw e.single(r(i?.error,`Expected instance of ${t.name}`,n),a);return n})}function f(t,i){return n((n,a)=>{if(!Object.is(n,t))throw e.single(r(i?.error,`Expected literal ${String(t)}`,n),a);return t})}function p(i,a,o){return n((n,s)=>{if(!(n instanceof Map))throw e.single(r(o?.error,`Expected Map`,n),s);let c=n,l=new Map,u=[],d=Array.from(c.entries());for(let n=0;n<d.length;n++){let[r,c]=d[n],f=s.concat(`[${n}]`),p=i.safeParse(r),m=a.safeParse(c);if(!p.success&&(t(u,p.error.issues,f.concat(`key`)),o?.abort)||!m.success&&(t(u,m.error.issues,f.concat(`value`)),o?.abort))throw new e(u);p.success&&m.success&&l.set(p.data,m.data)}if(u.length>0)throw new e(u);return l})}function m(t){return n((n,i)=>{if(!Object.is(n,null))throw e.single(r(t?.error,`Expected null`,n),i);return null})}function h(e){return n((t,n)=>Object.is(t,null)?null:e.parse(t,n))}function g(t){return n((n,i)=>{if(typeof n!=`number`)throw e.single(r(t?.error,`Expected number`,n),i);return n})}function _(t,n,i){if(typeof t!=`object`||!t||Array.isArray(t))throw e.single(r(i,`Expected object`,t),n)}function ee(n,r,i,a,o,s,c){let l=i.safeParse(r);if(l.success)c[n]=l.data;else if(t(o,l.error.issues,a.concat(n)),s)throw new e(o)}function te(t,n,i,a,o,s,c){switch(i){case`passthrough`:c[t]=n;break;case`exact`:if(a.push({message:r(void 0,`Unexpected property`,n),path:o.concat(t)}),s)throw new e(a);break}}function v(t,n,i,a,o,s){for(let c=0;c<n.length;c++){let l=n[c];if(!(l in t)){let t=i[l],n=t.safeParse(void 0).success,c=t.safeParse(null).success;if(!n&&!c&&(a.push({message:r(void 0,`Missing required property`,void 0),path:o.concat(l)}),s)||c&&!n&&(a.push({message:r(void 0,`Missing required property`,void 0),path:o.concat(l)}),s))throw new e(a)}}}function y(t,r){let i=r?.mode??`strip`,a=Object.keys(t);return n((n,o)=>{_(n,o,r?.error);let s=n,c={},l=[],u=Object.keys(s);for(let e=0;e<u.length;e++){let n=u[e],a=s[n],d=t[n];d?ee(n,a,d,o,l,r?.abort,c):te(n,a,i,l,o,r?.abort,c)}if(v(s,a,t,l,o,r?.abort),l.length>0)throw new e(l);return c})}function b(e){return n((t,n)=>{if(!Object.is(t,void 0))return e.parse(t,n)})}function x(e,...t){return n((n,r)=>{let i=e.parse(n,r);for(let e=0;e<t.length;e++)i=t[e](i);return i})}function S(e,t){let n=[];if(Object.is(e,!1))n.push({path:t,message:`Refinement failed`});else if(typeof e==`string`)n.push({path:t,message:e});else if(e&&typeof e==`object`&&`message`in e){let r=e,i=r.path?t.concat(r.path):t;n.push({path:i,message:r.message})}else if(Array.isArray(e))for(let r=0;r<e.length;r++){let i=e[r],a=i.path?t.concat(i.path):t;n.push({path:a,message:i.message})}return n}function C(t,r,i){return n((n,a)=>{let o=t.parse(n,a),s=[];for(let e=0;e<r.length;e++){let t=S(r[e](o),a);for(let e=0;e<t.length;e++)s.push(t[e]);if(i?.abort&&t.length>0)break}if(s.length>0)throw new e(s);return o})}function w(i,a){return n((n,o)=>{if(!(n instanceof Set))throw e.single(r(a?.error,`Expected Set`,n),o);let s=new Set,c=[],l=Array.from(n);for(let n=0;n<l.length;n++){let r=l[n],u=[];if(o&&o.length)for(let e=0;e<o.length;e++)u.push(o[e]);u.push(`[${n}]`);let d=i.safeParse(r);if(d.success)s.add(d.data);else if(t(c,d.error.issues,u),a&&a.abort)throw new e(c)}if(c.length>0)throw new e(c);return s})}function T(e,t,n){return e.success?t(e.data):n(e.error)}function E(t){return n((n,i)=>{if(typeof n!=`string`)throw e.single(r(t?.error,`Expected string`,n),i);return n})}function D(t){return n((n,i)=>{if(!Object.is(n,void 0))throw e.single(r(t?.error,`Expected undefined`,n),i)})}function O(i,a){return n((n,o)=>{let s=[];for(let e=0;e<i.length;e++){let r=i[e].safeParse(n);if(r.success)return r.data;t(s,r.error.issues,o)}throw s.length>0?new e(s):e.single(r(a?.error,`No union variant matched`,n),o)})}function k(){return n(e=>e)}function A(e){return e.map(e=>{let t=e.path.join(`.`);return t?`${t}: ${e.message}`:e.message}).join(`
|
|
2
|
+
`)}function j(e){let t={};for(let n of e){if(n.path.length===0)continue;let e=t;for(let t=0;t<n.path.length;t++){let r=n.path[t];t===n.path.length-1?e[r]=n.message:((!e[r]||typeof e[r]!=`object`)&&(e[r]={}),e=e[r])}}return t}function M(e){let t={};for(let n of e)n.path.length!==0&&(t[n.path.join(`.`)]=n.message);return t}function N(e,t){return function(n){return n>=e||t||`Must be >= ${e}`}}function P(e,t){return function(n){return n<=e||t||`Must be <= ${e}`}}function F(e,t){return function(n){return n>e||t||`Must be > ${e}`}}function I(e,t){return function(n){return n<e||t||`Must be < ${e}`}}function L(e){return function(t){return Number.isInteger(t)||e||`Must be an integer`}}function R(e){return function(t){return Number.isFinite(t)||e||`Must be a finite number`}}function z(e){return function(t){return t>0||e||`Must be positive`}}function B(e){return function(t){return t<0||e||`Must be negative`}}function V(e,t,n){return function(r){return r>=e&&r<=t||n||`Must be between ${e} and ${t}`}}function H(e){return function(t){return t%2==0||e||`Must be an even number`}}function U(e){return function(t){return t%2!=0||e||`Must be an odd number`}}function W(e,t){return function(n){return n.length>=e||t||`Must have at least ${e} characters`}}function G(e,t){return function(n){return n.length<=e||t||`Must have at most ${e} characters`}}function K(e,t){return function(n){return n.length===e||t||`Must have exactly ${e} characters`}}function ne(e,t){return function(n){return e.test(n)||t||`Invalid format`}}function q(e,t){return function(n){return n.startsWith(e)||t||`Must start with "${e}"`}}function J(e,t){return function(n){return n.endsWith(e)||t||`Must end with "${e}"`}}function Y(e){return function(t){return t.length>0||e||`Must not be empty`}}function X(e,t){return function(n){return n.includes(e)||t||`Must include "${e}"`}}function Z(e,t){return function(n){return!n.includes(e)||t||`Must not include "${e}"`}}function re(e){return function(t){return t.trim()===t||e||`Must not have leading or trailing spaces`}}function ie(e){return function(t){return t===t.toLowerCase()||e||`Must be lowercase`}}function ae(e){return function(t){return t===t.toUpperCase()||e||`Must be uppercase`}}function oe(e){let t=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;return function(n){return t.test(n)||e||`Must be a valid UUID v4`}}function se(){return function(e){return Math.round(e)}}function ce(){return function(e){return Math.floor(e)}}function le(){return function(e){return Math.ceil(e)}}function ue(e,t){return function(n){return Math.min(Math.max(n,e),t)}}function de(){return function(e){return Math.abs(e)}}function fe(){return function(e){return e.trim()}}function pe(){return function(e){return e.toLowerCase()}}function me(){return function(e){return e.toUpperCase()}}function Q(e,t,n){return function(r){if(typeof e==`string`){let i=``;return n?.global&&(i+=`g`),n?.ignoreCase&&(i+=`i`),r.replace(new RegExp(e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),i),t)}else return r.replace(e,t)}}function he(e,t=``){return function(n){return n.length>e?n.slice(0,e)+t:n}}function ge(e,t=``){return function(n){return n.length<=e?n:t+n.slice(n.length-e)}}function _e(){return function(e){return e.replace(/\s+/g,` `).trim()}}const $={array:i,bigint:a,boolean:o,date:s,email:l,fallback:u,instance:d,literal:f,null:m,nullable:h,number:g,object:y,optional:b,string:E,undefined:D,union:O,unknown:k,refine:C,pipe:x,match:T,map:p,set:w};var ve=$;export{e as ViviError,de as abs,i as arrayValidator,V as between,a as bigintValidator,o as booleanValidator,le as ceil,ue as clamp,n as customValidator,s as dateValidator,ve as default,l as emailValidator,J as endsWith,H as even,u as fallback,R as finite,M as flattenErrors,ce as floor,F as gt,X as includes,d as instanceValidator,L as integer,j as issuesToObject,A as issuesToString,K as length,f as literalValidator,ie as lowercase,I as lt,p as mapValidator,T as match,P as max,G as maxLength,N as min,W as minLength,B as negative,Y as nonEmpty,_e as normalizeSpaces,Z as notIncludes,m as nullValidator,h as nullableValidator,g as numberValidator,y as objectValidator,U as odd,b as optionalValidator,ne as pattern,x as pipe,z as positive,C as refine,Q as replace,se as round,w as setValidator,q as startsWith,E as stringValidator,pe as toLowerCase,me as toUpperCase,fe as trim,re as trimmed,he as truncateEnd,ge as truncateStart,D as undefinedValidator,O as unionValidator,k as unknownValidator,ae as uppercase,oe as uuid4,$ as v};
|