ivl 0.1.6 → 0.2.5

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) =>
@@ -1,4 +1,4 @@
1
- // Generated by dts-bundle-generator v8.1.1
1
+ // Generated by dts-bundle-generator v9.5.1
2
2
 
3
3
  export type RULE_SYNC = (value: unknown, ...overload: unknown[]) => boolean;
4
4
  export type RULE = (value: unknown, ...overload: unknown[]) => boolean | Promise<boolean>;
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // Generated by dts-bundle-generator v8.1.1
1
+ // Generated by dts-bundle-generator v9.5.1
2
2
 
3
3
  export type RULE_SYNC = (value: unknown, ...overload: unknown[]) => boolean;
4
4
  export type RULE = (value: unknown, ...overload: unknown[]) => boolean | Promise<boolean>;
@@ -19,7 +19,6 @@ export type CHECKABLE_OBJECT = {
19
19
  };
20
20
  /**
21
21
  * @arg {boolean} strict --- Don't allow object to have keys not included in the schema
22
- * @arg {boolean} break_early --- Return the first error found
23
22
  */
24
23
  export type SCHEMA_OPTIONS = {
25
24
  strict?: boolean;
@@ -28,9 +27,67 @@ export type CHECKED_SCHEMA_SYNC = {
28
27
  [index: string]: string[];
29
28
  };
30
29
  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;
30
+ /**
31
+ * Detect if a RULES object has any async rules in it
32
+ *
33
+ * @param {Record<string, RULE>} rules a rules object
34
+ * @returns {boolean} true if any of the rules is an async function otherwise false
35
+ */
36
+ export declare const hasAsyncFunction: (rules: Record<string, RULE>) => boolean;
37
+ /**
38
+ * Check the input against all provided validation rules asynchronously
39
+ *
40
+ * @param {unknown} value the value to check
41
+ * @param {RULES} rules rules object to use for validating the provided value
42
+ * @param {unknown[]} overload array of extra values the validator rules might need to properly validate the value
43
+ * @returns {string[]} a list of rule names which failed validation
44
+ */
45
+ export declare const getValueErrorsAsync: (value: unknown, rules: RULES, ...overload: unknown[]) => Promise<string[]>;
46
+ /**
47
+ * Check a schema against all provided validation rules asynchronously
48
+ *
49
+ * @param {CHECKABLE_OBJECT} object object to be validated
50
+ * @param {SCHEMA} schema schema to validate against
51
+ * @param {SCHEMA_OPTIONS} options options affecting how the rules are run
52
+ * @param {unknown[]} overload array of extra values the validator rules might need to properly validate the value
53
+ * @returns {CHECKED_SCHEMA} an object containing keys and their respective lists of failed rule names
54
+ */
55
+ export declare const getSchemaErrorsAsync: (object: CHECKABLE_OBJECT, schema: SCHEMA, options?: SCHEMA_OPTIONS, ...overload: unknown[]) => CHECKED_SCHEMA;
56
+ /**
57
+ *
58
+ * @param {unknown} value the value to check
59
+ * @param {RULES_SYNC} rules rules object to use for validating the provided value
60
+ * @param {unknown[]} overload array of extra values the validator rules might need to properly validate the value
61
+ * @returns {string[]} a list of rule names which failed validation
62
+ */
33
63
  export declare const getValueErrorsSync: (value: unknown, rules: RULES_SYNC, ...overload: unknown[]) => string[];
64
+ /**
65
+ * Check a schema against all provided validation rules asynchronously
66
+ *
67
+ * @param {CHECKABLE_OBJECT} object object to be validated
68
+ * @param {SCHEMA} schema schema to validate against
69
+ * @param {SCHEMA_OPTIONS} options options affecting how the rules are run
70
+ * @param {unknown[]} overload array of extra values the validator rules might need to properly validate the value
71
+ * @returns {CHECKED_SCHEMA} an object containing keys and their respective lists of failed rule names
72
+ */
34
73
  export declare const getSchemaErrorsSync: (object: CHECKABLE_OBJECT, schema: SCHEMA_SYNC, options?: SCHEMA_OPTIONS, ...overload: unknown[]) => CHECKED_SCHEMA_SYNC;
74
+ /**
75
+ *
76
+ * @param {unknown} value the value to check
77
+ * @param {RULES|RULES_SYNC} rules rules object to use for validating the provided value
78
+ * @param {unknown[]} overload array of extra values the validator rules might need to properly validate the value
79
+ * @returns {string[]} a list of rule names which failed validation
80
+ */
81
+ export declare const getValueErrors: (value: unknown, rules: RULES | RULES_SYNC, ...overload: unknown[]) => string[] | Promise<string[]>;
82
+ /**
83
+ * Check a schema against all provided validation rules
84
+ *
85
+ * @param {CHECKABLE_OBJECT} object object to be validated
86
+ * @param {SCHEMA} schema schema to validate against
87
+ * @param {SCHEMA_OPTIONS} options options affecting how the rules are run
88
+ * @param {unknown[]} overload array of extra values the validator rules might need to properly validate the value
89
+ * @returns {CHECKED_SCHEMA} an object containing keys and their respective lists of failed rule names
90
+ */
91
+ export declare const getSchemaErrors: (object: CHECKABLE_OBJECT, schema: SCHEMA_SYNC | SCHEMA, options?: SCHEMA_OPTIONS, ...overload: unknown[]) => CHECKED_SCHEMA_SYNC | CHECKED_SCHEMA;
35
92
 
36
93
  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 Z={strict:!1},$=(z)=>Object.values(z).some((q)=>typeof q==="function"&&q.constructor.name==="AsyncFunction"),J=async(z,q,...W)=>{const G={};return Object.entries(q).forEach(([x,Q])=>{G[x]=Promise.resolve(!1).then(()=>Q(z,...W)).then((R)=>G[x]=R).catch((R)=>{return console.warn(`Rule validation functions for "${x}" didn't exit cleanly`,R),G[x]=!1})}),await Promise.allSettled(Object.values(G)),Object.entries(G).reduce((x,[Q,R])=>R?x:[...x,Q],[])},K=async(z,q,W=Z,...G)=>{const x={};if(Object.entries(q).forEach(([Q,R])=>{x[Q]=J(z[Q],R,...G).then((X)=>{x[Q]=X}).catch((X)=>{x[Q]=X})}),W.strict){const Q=Object.keys(z),R=new Set(Object.keys(q));Q.filter((Y)=>!R.has(Y)).forEach((Y)=>{x[Y]=["Key not allowed"]})}return await Promise.allSettled(Object.values(x)),x},B=(z,q,...W)=>Object.entries(q).reduce((G,[x,Q])=>{try{return Q(z,...W)?G:[...G,x]}catch(R){return console.warn(`Rule validation function for "${x}" didn't exit cleanly`,R),[...G,x]}},[]),f=(z,q,W=Z,...G)=>{const x=Object.entries(q).reduce((Q,[R,X])=>({...Q,[R]:B(z[R],X,...G)}),{});if(W.strict){const Q=Object.keys(z),R=new Set(Object.keys(q));Q.filter((Y)=>!R.has(Y)).forEach((Y)=>{x[Y]=["Key not allowed"]})}return x},U=(z,q,...W)=>{if($(q))return J(z,q,...W);return B(z,q,...W)},I=(z,q,W=Z,...G)=>{if(Object.values(q).some($))return K(z,q,W,...G);return f(z,q,W,...G)};export{$ as hasAsyncFunction,B as getValueErrorsSync,J as getValueErrorsAsync,U as getValueErrors,f as getSchemaErrorsSync,K as getSchemaErrorsAsync,I as getSchemaErrors};
@@ -1,4 +1,4 @@
1
- // Generated by dts-bundle-generator v8.1.1
1
+ // Generated by dts-bundle-generator v9.5.1
2
2
 
3
3
  export declare const EMAIL_PATTERN: RegExp;
4
4
  export declare const MYSQL_TIMESTAMP_PATTERN: RegExp;
@@ -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,}(\/[^ \t\r\n\v\f]*)?$/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)?)$/,j=/^(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d(?::[0-5]\d(?:\.\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\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,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,17 +1,17 @@
1
1
  {
2
2
  "name": "ivl",
3
- "version": "0.1.6",
3
+ "version": "0.2.5",
4
4
  "author": {
5
5
  "name": "Oskar Voorel",
6
6
  "email": "oskar@voorel.com"
7
7
  },
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git+https://github.com/Oskar-V/validator.git"
10
+ "url": "git+https://github.com/Oskar-V/ivl.git"
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",
@@ -33,13 +33,13 @@
33
33
  }
34
34
  },
35
35
  "bugs": {
36
- "url": "https://github.com/Oskar-V/validator/issues/new"
36
+ "url": "https://github.com/Oskar-V/ivl/issues/new"
37
37
  },
38
38
  "description": "Lightweight input validation",
39
39
  "files": [
40
40
  "lib"
41
41
  ],
42
- "homepage": "https://github.com/Oskar-V/validator",
42
+ "homepage": "https://github.com/Oskar-V/ivl",
43
43
  "keywords": [
44
44
  "validation",
45
45
  "typescript",