ivl 0.1.6 → 0.2.0

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 CHANGED
@@ -2,7 +2,14 @@
2
2
  This is a lightweight library for user input validation.
3
3
  Main focus is on speed and flexibility of the validation rules
4
4
 
5
- Supports asynchronous rule validation by default. Use `getInputErrorsSync` and `getSchemaErrorsSync` for better performance if you don't need to support asynchronous checks on your inputs.
5
+ By default it automatically detects and supports async rules in your rule sets.
6
+
7
+ If your rule set and/or object are very large or complex, you may want to use
8
+ `getInputErrorsSync`/`getSchemaErrorsSync` or `getInputErrorsAsync`/`getSchemaErrorsAsync` for improved performance on synchronous and asynchronous rule sets respectively.
9
+
10
+ Use synchronous versions of the functions for better performance if you don't need to support asynchronous checks on your inputs.
11
+
12
+
6
13
  # Main functionality
7
14
  Write your own custom validators to exactly match your use case using a simple object:
8
15
  ```javascript
@@ -14,8 +21,24 @@ console.log(getInputErrors(50, my_rules)); // []
14
21
  console.log(getInputErrors(11, my_rules)); // ["Input must be more than 40", "Input must be divisible by 10"]
15
22
  console.log(getInputErrors(30, my_rules)) // ["Input must be more than 40"]
16
23
 
24
+ ```
25
+ # Installing
26
+ ### Bun.js
27
+ ```typescript
28
+ bun add ivl
29
+ ```
30
+
31
+ ### yarn
32
+ ```typescript
33
+ yarn add ivl
17
34
  ```
18
35
 
36
+ ### npm
37
+ ```typescript
38
+ npm install ivl
39
+ ```
40
+ ---
41
+ # Usage examples
19
42
  ## Frontend example
20
43
  ```javascript
21
44
  // src/index.ts
@@ -39,10 +62,10 @@ const EMAIL_REQUIREMENTS: RULES = {
39
62
 
40
63
  const PASSWORD_REQUIREMENTS: RULES = {
41
64
  "Must be string": isType('string'),
42
- "Must be at least 8 characters": minLength(Infinity, 8),
65
+ "Must be at least 8 characters": minLength(8),
43
66
  "Must contain at least one upper case character": matchesRegex(/(?=.*[A-Z])/),
44
67
  "Must contain at least one lower case character": matchesRegex(/(?=.*[a-z])/),
45
- }
68
+ };
46
69
 
47
70
  // You can of course expand on your existing rules:
48
71
  const STRONG_PASSWORD_REQUIREMENTS: RULES = {
@@ -92,7 +115,7 @@ const PASSWORD_REQUIREMENTS = {
92
115
  export const LOGIN_SCHEMA: SCHEMA = {
93
116
  email: EMAIL_REQUIREMENTS,
94
117
  password: PASSWORD_REQUIREMENTS
95
- }
118
+ };
96
119
 
97
120
  export const REGISTER_SCHEMA: SCHEMA = {
98
121
  organization_name: {} // Pass in an empty rule set, so the value can be whatever
@@ -101,13 +124,13 @@ export const REGISTER_SCHEMA: SCHEMA = {
101
124
  "Email already registered": existsInDatabase('email','users', false)
102
125
  },
103
126
  password: PASSWORD_REQUIREMENTS
104
- }
127
+ };
105
128
 
106
129
  export const INVITATION_PARAM: SCHEMA = {
107
130
  code: {
108
131
  "Not a valid invitation": existsInDatabase('code', 'invitation')
109
132
  }
110
- }
133
+ };
111
134
 
112
135
  ```
113
136
 
@@ -118,7 +141,7 @@ import { jwt } from 'hono/jwt';
118
141
  import { validator } from 'hono/validator';
119
142
  import { getSchemaErrors } from 'ivl';
120
143
  import type { SCHEMA } from 'ivl';
121
- import { LOGIN_SCHEMA, REGISTER_SCHEMA, INVITATION_PARAM } from './rules.ts'
144
+ import { LOGIN_SCHEMA, REGISTER_SCHEMA, INVITATION_PARAM } from './rules.ts';
122
145
 
123
146
  // Wrapper for hono validator middleware
124
147
  const validateWrapper = (schema: SCHEMA, error: ClientErrorStatusCode | RedirectStatusCode = 400, strict = true) =>
package/lib/index.d.ts CHANGED
@@ -28,9 +28,12 @@ export type CHECKED_SCHEMA_SYNC = {
28
28
  [index: string]: string[];
29
29
  };
30
30
  export type CHECKED_SCHEMA = Promise<CHECKED_SCHEMA_SYNC>;
31
- export declare const getValueErrors: (value: unknown, rules: RULES, ...overload: unknown[]) => Promise<string[]>;
32
- export declare const getSchemaErrors: (object: CHECKABLE_OBJECT, schema: SCHEMA, options?: SCHEMA_OPTIONS, ...overload: unknown[]) => CHECKED_SCHEMA;
31
+ export declare const hasAsyncFunction: (obj: Record<string, unknown>) => boolean;
32
+ export declare const getValueErrorsAsync: (value: unknown, rules: RULES, ...overload: unknown[]) => Promise<string[]>;
33
+ export declare const getSchemaErrorsAsync: (object: CHECKABLE_OBJECT, schema: SCHEMA, options?: SCHEMA_OPTIONS, ...overload: unknown[]) => CHECKED_SCHEMA;
33
34
  export declare const getValueErrorsSync: (value: unknown, rules: RULES_SYNC, ...overload: unknown[]) => string[];
34
35
  export declare const getSchemaErrorsSync: (object: CHECKABLE_OBJECT, schema: SCHEMA_SYNC, options?: SCHEMA_OPTIONS, ...overload: unknown[]) => CHECKED_SCHEMA_SYNC;
36
+ export declare const getValueErrors: (value: unknown, rules: RULES | RULES_SYNC, ...overload: unknown[]) => string[] | Promise<string[]>;
37
+ export declare const getSchemaErrors: (object: CHECKABLE_OBJECT, schema: SCHEMA_SYNC | SCHEMA, options?: SCHEMA_OPTIONS, ...overload: unknown[]) => CHECKED_SCHEMA_SYNC | CHECKED_SCHEMA;
35
38
 
36
39
  export {};
package/lib/index.js CHANGED
@@ -1 +1 @@
1
- var W={strict:!1},X=async(B,G,...J)=>{const q={};return Object.entries(G).forEach(([x,f])=>{q[x]=Promise.resolve(!1).then(()=>f(B,...J)).then((z)=>q[x]=z).catch(()=>q[x]=!1)}),await Promise.allSettled(Object.values(q)),Object.entries(q).reduce((x,[f,z])=>z?x:[...x,f],[])},Z=async(B,G,J=W,...q)=>{const x={};if(Object.entries(G).forEach(([f,z])=>{x[f]=X(B[f],z,...q).then((K)=>{x[f]=K}).catch((K)=>{x[f]=K})}),J.strict){const f=Object.keys(B),z=new Set(Object.keys(G));f.filter((Q)=>!z.has(Q)).forEach((Q)=>{x[Q]=["Key not allowed"]})}return await Promise.allSettled(Object.values(x)),x},Y=(B,G,...J)=>Object.entries(G).reduce((q,[x,f])=>{try{return f(B,...J)?q:[...q,x]}catch(z){return[...q,x]}},[]),$=(B,G,J=W,...q)=>{const x=Object.entries(G).reduce((f,[z,K])=>({...f,[z]:Y(B[z],K,...q)}),{});if(J.strict){const f=Object.keys(B),z=new Set(Object.keys(G));f.filter((Q)=>!z.has(Q)).forEach((Q)=>{x[Q]=["Key not allowed"]})}return x};export{Y as getValueErrorsSync,X as getValueErrors,$ as getSchemaErrorsSync,Z as getSchemaErrors};
1
+ var W={strict:!1},X=(q)=>Object.values(q).some((x)=>typeof x==="function"&&x.constructor.name==="AsyncFunction"),Y=async(q,x,...G)=>{const z={};return Object.entries(x).forEach(([f,B])=>{z[f]=Promise.resolve(!1).then(()=>B(q,...G)).then((J)=>z[f]=J).catch(()=>z[f]=!1)}),await Promise.allSettled(Object.values(z)),Object.entries(z).reduce((f,[B,J])=>J?f:[...f,B],[])},$=async(q,x,G=W,...z)=>{const f={};if(Object.entries(x).forEach(([B,J])=>{f[B]=Y(q[B],J,...z).then((K)=>{f[B]=K}).catch((K)=>{f[B]=K})}),G.strict){const B=Object.keys(q),J=new Set(Object.keys(x));B.filter((Q)=>!J.has(Q)).forEach((Q)=>{f[Q]=["Key not allowed"]})}return await Promise.allSettled(Object.values(f)),f},Z=(q,x,...G)=>Object.entries(x).reduce((z,[f,B])=>{try{return B(q,...G)?z:[...z,f]}catch(J){return[...z,f]}},[]),R=(q,x,G=W,...z)=>{const f=Object.entries(x).reduce((B,[J,K])=>({...B,[J]:Z(q[J],K,...z)}),{});if(G.strict){const B=Object.keys(q),J=new Set(Object.keys(x));B.filter((Q)=>!J.has(Q)).forEach((Q)=>{f[Q]=["Key not allowed"]})}return f},C=(q,x,...G)=>{if(X(x))return Y(q,x,...G);return Z(q,x,...G)},H=(q,x,G=W,...z)=>{if(Object.values(x).some(X))return $(q,x,G,...z);return R(q,x,G,...z)};export{X as hasAsyncFunction,Z as getValueErrorsSync,Y as getValueErrorsAsync,C as getValueErrors,R as getSchemaErrorsSync,$ as getSchemaErrorsAsync,H as getSchemaErrors};
@@ -7,5 +7,9 @@ export declare const ISO_8601_DATETIME_PATTERN_STRICT: RegExp;
7
7
  export declare const ISO_8601_DATETIME_PATTERN: RegExp;
8
8
  export declare const ISO_8601_TIME_PATTERN: RegExp;
9
9
  export declare const RFC_2822_TIMESTAMP_PATTERN: RegExp;
10
+ export declare const CONTAINS_LOWERCASE_CHARACTER_PATTERN: RegExp;
11
+ export declare const CONTAINS_UPPERCASE_CHARACTER_PATTERN: RegExp;
12
+ export declare const CONTAINS_DIGIT_CHARACTER_PATTERN: RegExp;
13
+ export declare const CONTAINS_SYMBOL_CHARACTER_PATTERN: RegExp;
10
14
 
11
15
  export {};
@@ -1 +1 @@
1
- var x=/^[\w.%+-]+@[\w.-]+\.[a-zA-Z]{1,}$/,c=/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/,d=/^(https?:\/\/)?([^\s$.?#].[^\s]*)\.[a-z]{2,}(\/[^\s]*)?$/i,f=/^(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))$/,j=/^(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d)$/,k=/^(2[0-3]|[01][0-9]):?([0-5][0-9]):?([0-5][0-9])(Z|[+-](?:2[0-3]|[01][0-9])(?::?(?:[0-5][0-9]))?)$/,l=/^(?:(Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+)?(0[1-9]|[1-2]?[0-9]|3[01])\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(19[0-9]{2}|[2-9][0-9]{3})\s+(2[0-3]|[0-1][0-9]):([0-5][0-9])(?::(60|[0-5][0-9]))?\s+([-\+][0-9]{2}[0-5][0-9]|(?:UT|GMT|(?:E|C|M|P)(?:ST|DT)|[A-IK-Z]))(\s+|\(([^\(\)]+|\\\(|\\\))*\))*$/;export{d as URL_PATTERN,l as RFC_2822_TIMESTAMP_PATTERN,c as MYSQL_TIMESTAMP_PATTERN,k as ISO_8601_TIME_PATTERN,f as ISO_8601_DATETIME_PATTERN_STRICT,j as ISO_8601_DATETIME_PATTERN,x as EMAIL_PATTERN};
1
+ var x=/^[\w.%+-]+@[\w.-]+\.[a-zA-Z]{1,}$/,c=/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/,d=/^(https?:\/\/)?([^\s$.?#].[^\s]*)\.[a-z]{2,}(\/[^\s]*)?$/i,f=/^(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))$/,j=/^(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d)$/,k=/^(2[0-3]|[01][0-9]):?([0-5][0-9]):?([0-5][0-9])(Z|[+-](?:2[0-3]|[01][0-9])(?::?(?:[0-5][0-9]))?)$/,l=/^(?:(Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+)?(0[1-9]|[1-2]?[0-9]|3[01])\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(19[0-9]{2}|[2-9][0-9]{3})\s+(2[0-3]|[0-1][0-9]):([0-5][0-9])(?::(60|[0-5][0-9]))?\s+([-\+][0-9]{2}[0-5][0-9]|(?:UT|GMT|(?:E|C|M|P)(?:ST|DT)|[A-IK-Z]))(\s+|\(([^\(\)]+|\\\(|\\\))*\))*$/,m=/(?=.*[a-z])/,p=/(?=.*[A-Z])/,q=/(?=.*\d)/,r=/[^\w]/;export{d as URL_PATTERN,l as RFC_2822_TIMESTAMP_PATTERN,c as MYSQL_TIMESTAMP_PATTERN,k as ISO_8601_TIME_PATTERN,f as ISO_8601_DATETIME_PATTERN_STRICT,j as ISO_8601_DATETIME_PATTERN,x as EMAIL_PATTERN,p as CONTAINS_UPPERCASE_CHARACTER_PATTERN,r as CONTAINS_SYMBOL_CHARACTER_PATTERN,m as CONTAINS_LOWERCASE_CHARACTER_PATTERN,q as CONTAINS_DIGIT_CHARACTER_PATTERN};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ivl",
3
- "version": "0.1.6",
3
+ "version": "0.2.0",
4
4
  "author": {
5
5
  "name": "Oskar Voorel",
6
6
  "email": "oskar@voorel.com"
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "main": "lib/index.js",
13
13
  "devDependencies": {
14
- "@types/bun": "^1.0.0",
14
+ "@types/bun": "latest",
15
15
  "bun-plugin-dts": "^0.2.1",
16
16
  "mitata": "^0.1.11",
17
17
  "typescript": "^5.2.2",