check-rule-mate 0.5.0 → 0.5.1

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
@@ -61,14 +61,14 @@ This separation makes the system flexible, scalable, and easy to maintain.
61
61
  - [Getting Started](#Getting-Started)
62
62
  - [NPM - Installation](#Installation)
63
63
  - [Repository - Installation](#Repository---Installation)
64
- - [Running Tests](#Running-Tests)
64
+ - [Running Tests](#Repository---Running-Tests)
65
65
  - [How It Works](#How-It-Works)
66
- - [Basic Example](#Basic-Example)
66
+ - [Basic Usage](#Basic-Usage)
67
67
  - [Defining Validation](#Defining-Validation)
68
68
  - [1. Schema](#Defining-a-Schema-What-to-validate)
69
69
  - [2. Rules](#Defining-Rules-How-to-validate)
70
70
  - [3. Validation Helpers](#Validation-Helpers-Execution-Layer)
71
- - [4. Error Messages](#Error-Messages)
71
+ - [4. Error Messages](#Error-Messages-i18n-ready)
72
72
  - [5. Example Usage](#Example-Usage)
73
73
  - [Vanilla](#vanilla)
74
74
  - [Express](#express)
@@ -126,8 +126,9 @@ async function runFormValidate() {
126
126
  schema: CONTACT_US,
127
127
  errorMessages: ERROR_MESSAGES,
128
128
  options: {
129
+ cache: true,
129
130
  abortEarly: false,
130
- propertiesMustMatch: true
131
+ propertiesMustMatch: true,
131
132
  }
132
133
  });
133
134
 
@@ -149,13 +150,15 @@ When is **valid**:
149
150
  ```
150
151
 
151
152
  When is **invalid** and **has errors**:
152
- ```javascript
153
+ ```typescript
153
154
  {
154
- error: true;
155
+ error: true,
155
156
  errors: {
156
157
  [field: string]: {
157
- type: string;
158
- message: string;
158
+ name: string,
159
+ type: string,
160
+ message: string,
161
+ code: string,
159
162
  }[];
160
163
  };
161
164
  }
@@ -175,11 +178,13 @@ Schemas map **data fields** to **rules**.
175
178
  },
176
179
  "email": {
177
180
  "rule": "email",
178
- "required": true
181
+ "required": true,
182
+ "cache": false,
179
183
  },
180
184
  "emailConfirm": {
181
185
  "rule": "email--confirm",
182
- "required": true
186
+ "required": true,
187
+ "cache": false,
183
188
  },
184
189
  "phone": {
185
190
  "rule": "phone",
@@ -191,6 +196,7 @@ Schemas map **data fields** to **rules**.
191
196
  #### Schema Properties
192
197
  - **rule**: Rule name (supports modifiers via `rule--modifier`)
193
198
  - **required**: Whether the field must exist and not be empty
199
+ - **cache**: if this field will have cache or not
194
200
 
195
201
  ### Defining Rules (How to validate)
196
202
 
@@ -350,8 +356,9 @@ This makes localization and message customization straightforward.
350
356
  ### Validation Options
351
357
  ```typescript
352
358
  options: {
353
- abortEarly?: boolean; // Stop on first error
354
- propertiesMustMatch?: boolean; // Schema vs data strictness
359
+ cache?: boolean, // If cache is enabled or not
360
+ abortEarly?: boolean, // Stop on first error
361
+ propertiesMustMatch?: boolean, // Schema vs data strictness
355
362
  }
356
363
  ```
357
364
 
package/dist/main.cjs.js CHANGED
@@ -1 +1 @@
1
- var k=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var j=(u,n)=>{for(var c in n)k(u,c,{get:n[c],enumerable:!0})},I=(u,n,c,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let f of b(n))!P.call(u,f)&&f!==c&&k(u,f,{get:()=>n[f],enumerable:!(i=E(n,f))||i.enumerable});return u};var T=u=>I(k({},"__esModule",{value:!0}),u);var x={};j(x,{createValidator:()=>V});module.exports=T(x);function V(u,{validationHelpers:n={},rules:c,schema:i,errorMessages:f={},options:y={propertiesMustMatch:!0,abortEarly:!1}}){let p={},r=u,d={all:async e=>Promise.all([...e].map(async s=>await h(s,r))),first:async e=>{let s=[];for(let t of e){let l=await h(t,r);if(s.push(l),!l)return s}return s}};function g(e,s){if(!e||typeof s!="string")return;let t=s.split("."),l=e;for(let M of t){if(l[M]===void 0)return;l=l[M]}return l}async function h(e,s=null){if(i[e.key]){let{rule:t,required:l}=i[e.key];if((t&&l||!l&&e.value!="")&&t){let M=t.split("--")[0],a=t.split("--").length>1?t.split("--")[1]:"",O=U(e.value,c[M],a,n,s),{isValid:R,errorMessage:m,errorType:q}=await O.validate();return R||(p[e.key]={name:e.key,error:!0,errorMessage:g(f,m)||m,errorType:q}),R}}else if(y.propertiesMustMatch)return p[e.key]={name:e.key,error:!0,errorMessage:"Invalid property"},!1;return!0}async function w(e){return await h({key:e,value:r[e]},r)?{ok:!0}:{error:!0,errors:p[e]}}async function o(){p={};let e=Object.keys(r).map(s=>({key:s,value:r[s]}));if(e&&e.length>0){if(!Object.keys(i).every(a=>r.hasOwnProperty(a)))return{error:!0,errorMessage:"Missing properties"};if((y!=null&&y.abortEarly?await d.first(e):await d.all(e)).some(a=>!a))return{error:!0,errors:p};let t=Object.keys(i).map(a=>({key:a,required:i[a].required})),l=e.map(a=>a.key);if(!t.filter(a=>a.required).map(a=>a.key).every(a=>l.includes(a)))return{error:!0}}else if(!e||e.length===0)return{error:!0,errorMessage:"Missing fields for schema"};return{ok:!0}}function v(e){r=e}return{validate:o,validateField:w,setData:v}}function U(u,n,c=null,i=null,f=null){async function y(r){let d,g;return{isValid:!(await Promise.all(r.validate.map(async o=>{let v=!0;if(r.params&&r.params[o]&&r.params[o].length>0){let e=r.params[o].map(t=>typeof t=="string"&&t[0]==="$"?t.substring(1,t.length):t);v=await this[o](...e)}else v=await this[o]();return!v&&!d&&(r!=null&&r.error[o])&&(d=r.error[o],g=o),v}))).some(o=>!o),errorMessage:d,errorType:g}}async function p(){if(i&&typeof i=="function"){let d=i(u,n,c,f);Object.keys(d).forEach(g=>{this[g]=d[g]})}return c?await y.call(this,n.modifier[c]):await y.call(this,n)}return{validate:p}}0&&(module.exports={createValidator});
1
+ var V=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var U=(r,n)=>{for(var u in n)V(r,u,{get:n[u],enumerable:!0})},F=(r,n,u,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let y of D(n))!T.call(r,y)&&y!==u&&V(r,y,{get:()=>n[y],enumerable:!(i=j(n,y))||i.enumerable});return r};var L=r=>F(V({},"__esModule",{value:!0}),r);var x={};U(x,{createValidator:()=>E});module.exports=L(x);var m={propertiesMustMatch:!0,abortEarly:!1,cache:!0};function E(r,{validationHelpers:n={},rules:u,schema:i,errorMessages:y={},options:f=m}){f={...m,...f},r=r;let k={},a={},p={all:async e=>Promise.all([...e].map(async s=>await v(s,r))),first:async e=>{let s=[];for(let l of e){let c=await v(l,r);if(s.push(c),!c)return s}return s}};function g(e,s){if(!e||typeof s!="string")return;let l=s.split("."),c=e;for(let d of l){if(c[d]===void 0)return;c=c[d]}return c}async function v(e,s=null){var l,c;if(i[e.key]){let{rule:d,required:t}=i[e.key];if((((l=i[e.key])==null?void 0:l.cache)!==void 0?i[e.key].cache:f.cache)&&s[e.key]===((c=a[e.key])==null?void 0:c.value))return a[e.key].isValid;if((d&&t||!t&&e.value!="")&&d){let O=d.split("--")[0],q=d.split("--").length>1?d.split("--")[1]:"",P=_(e.value,u[O],q,n,s),{isValid:w,errorMessage:R,errorType:I}=await P.validate();return w||(k[e.key]={name:e.key,code:R,type:I,message:g(y,R)||""}),a[e.key]={isValid:w,value:s[e.key]},w}}else if(f.propertiesMustMatch)return k[e.key]={name:e.key,message:"Invalid property"},!1;return!0}async function M(e){return await v({key:e,value:r[e]},r)?{ok:!0}:{error:!0,errors:k[e]}}async function o(){k={};let e=Object.keys(r).map(s=>({key:s,value:r[s]}));if(e&&e.length>0){if(!Object.keys(i).every(t=>r.hasOwnProperty(t)))return{error:!0,errorMessage:"Missing properties"};if((f!=null&&f.abortEarly?await p.first(e):await p.all(e)).some(t=>!t))return{error:!0,errors:k};let l=Object.keys(i).map(t=>({key:t,required:i[t].required})),c=e.map(t=>t.key);if(!l.filter(t=>t.required).map(t=>t.key).every(t=>c.includes(t)))return{error:!0}}else if(!e||e.length===0)return{error:!0,errorMessage:"Missing fields for schema"};return{ok:!0}}function h(e){r=e}return{validate:o,validateField:M,setData:h}}function _(r,n,u=null,i=null,y=null){async function f(a){let p,g;return{isValid:!(await Promise.all(a.validate.map(async o=>{let h=!0;if(a.params&&a.params[o]&&a.params[o].length>0){let e=a.params[o].map(l=>typeof l=="string"&&l[0]==="$"?l.substring(1,l.length):l);h=await this[o](...e)}else h=await this[o]();return!h&&!p&&(a!=null&&a.error[o])&&(p=a.error[o],g=o),h}))).some(o=>!o),errorMessage:p,errorType:g}}async function k(){if(i&&typeof i=="function"){let p=i(r,n,u,y);Object.keys(p).forEach(g=>{this[g]=p[g]})}return u?await f.call(this,n.modifier[u]):await f.call(this,n)}return{validate:k}}0&&(module.exports={createValidator});
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "check-rule-mate",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "",
5
5
  "main": "./dist/main.cjs.js",
6
6
  "type": "commonjs",
7
+ "types": "index.d.ts",
7
8
  "keywords": [
8
9
  "data validation",
9
10
  "data validation js",
package/src/index.d.ts ADDED
@@ -0,0 +1,128 @@
1
+ /**
2
+ * This file contains all type definitions used in the project.
3
+ */
4
+
5
+ /**
6
+ * Represents a single data field.
7
+ */
8
+ export interface DataField {
9
+ /** The name and key of the field */
10
+ name: string
11
+
12
+ /** The value of the field */
13
+ value: string
14
+ }
15
+
16
+ /**
17
+ * Options to control validator behavior.
18
+ */
19
+ export interface ValidatorOptions {
20
+ /** If the form fields don't match the expected structure, triggers an error */
21
+ propertiesMustMatch: boolean
22
+
23
+ /** Stops validation when the first error is caught */
24
+ abortEarly: boolean
25
+
26
+ /** Defines if the schema will use cache by default */
27
+ cache: boolean
28
+ }
29
+
30
+ /**
31
+ * A single validation helper function.
32
+ */
33
+ export type ValidatorHelper = (
34
+ value: any,
35
+ rule: string,
36
+ modifier: string,
37
+ data: DataField[]
38
+ ) => boolean
39
+
40
+ /**
41
+ * A map of validation helper functions.
42
+ */
43
+ export type ValidationHelpers = Record<string, ValidatorHelper>
44
+
45
+ /**
46
+ * Schema rule for a single field.
47
+ */
48
+ export interface SchemaRuleField {
49
+ /** The validation rule for the field (e.g., "name", "email", "phone", "hasText") */
50
+ rule: string
51
+
52
+ /** Indicates whether the field is required */
53
+ required: boolean
54
+
55
+ /** Indicates if the field requires cache or not */
56
+ cache: boolean
57
+ }
58
+
59
+ /**
60
+ * Schema rule object.
61
+ */
62
+ export interface SchemaRule {
63
+ field: SchemaRuleField
64
+ }
65
+
66
+ /**
67
+ * Validation schema mapping field names to rules.
68
+ */
69
+ export type SchemaRules = Record<string, SchemaRule>
70
+
71
+ /**
72
+ * Validator configuration object.
73
+ */
74
+ export interface DataValidatorConfigs {
75
+ /** The validator functions to help your validations */
76
+ validationHelpers: ValidationHelpers
77
+
78
+ /** The rules you want to use through validation */
79
+ rules: object
80
+
81
+ /** The rules you want to use per field */
82
+ schema: SchemaRules
83
+
84
+ /** The error messages you want to show during errors */
85
+ errorMessages: object
86
+
87
+ /** Validator options */
88
+ options: ValidatorOptions
89
+ }
90
+
91
+ /**
92
+ * Represents a successful response.
93
+ */
94
+ export interface DataValidatorSuccessResponse {
95
+ /** Indicates the operation was successful */
96
+ ok: boolean
97
+ }
98
+
99
+ /**
100
+ * Error object.
101
+ */
102
+ export interface CheckError {
103
+ /** Field name */
104
+ name: string
105
+
106
+ /** Error path */
107
+ code?: string
108
+
109
+ /** Error type */
110
+ type?: string
111
+
112
+ /** Error message */
113
+ message?: string
114
+ }
115
+
116
+ /**
117
+ * Represents an error response.
118
+ */
119
+ export interface DataValidatorErrorResponse {
120
+ /** Indicates an error occurred */
121
+ error: boolean
122
+
123
+ /** A message describing the error */
124
+ errorMessage?: string
125
+
126
+ /** Additional error details */
127
+ errors?: Record<string, CheckError>
128
+ }
@@ -1,11 +1,15 @@
1
+ const DEFAUL_OPTIONS = { propertiesMustMatch: true, abortEarly: false, cache: true };
2
+
1
3
  /**
2
4
  * Validate your data fields using your rules, data rules and validators.
3
- * @param {[DataField]} dataParameter - All the data fields to be validate
5
+ * @param {[DataField]} data - All the data fields to be validate
4
6
  * @param {DataValidatorConfigs} config - The configs which will be followed during validation
5
7
  */
6
- export function createValidator(dataParameter, {validationHelpers = {}, rules, schema, errorMessages = {}, options = { propertiesMustMatch: true, abortEarly: false}}) {
8
+ export function createValidator(data, {validationHelpers = {}, rules, schema, errorMessages = {}, options = DEFAUL_OPTIONS}) {
9
+ options = { ...DEFAUL_OPTIONS, ...options};
10
+ data = data;
7
11
  let errors = {};
8
- let data = dataParameter;
12
+ let oldData = {};
9
13
 
10
14
  const validateByStrategies = {
11
15
  all: async (dataArr) => Promise.all([...dataArr].map(async (input) => await inputValidation(input, data))),
@@ -39,6 +43,12 @@ export function createValidator(dataParameter, {validationHelpers = {}, rules, s
39
43
  async function inputValidation(dataAttribute, data = null) {
40
44
  if (schema[dataAttribute.key]) {
41
45
  const { rule, required } = schema[dataAttribute.key];
46
+ const cacheEnabled = schema[dataAttribute.key]?.cache !== undefined ? schema[dataAttribute.key].cache : options.cache;
47
+
48
+ if (cacheEnabled && data[dataAttribute.key] === oldData[dataAttribute.key]?.value) {
49
+ return oldData[dataAttribute.key].isValid;
50
+ }
51
+
42
52
  if ((rule && required) || (!required && dataAttribute.value != '')) {
43
53
  if (rule) {
44
54
  const INPUT_RULE = rule.split('--')[0];
@@ -48,19 +58,19 @@ export function createValidator(dataParameter, {validationHelpers = {}, rules, s
48
58
  if (!isValid) {
49
59
  errors[dataAttribute.key] = {
50
60
  name: dataAttribute.key,
51
- error: true,
52
- errorMessage: getObjectValueByPath(errorMessages, errorMessage) || errorMessage,
53
- errorType: errorType
61
+ code: errorMessage,
62
+ type: errorType,
63
+ message: getObjectValueByPath(errorMessages, errorMessage) || ''
54
64
  }
55
65
  }
66
+ oldData[dataAttribute.key] = {isValid: isValid, value: data[dataAttribute.key]};
56
67
  return isValid;
57
68
  }
58
69
  }
59
70
  } else if (options.propertiesMustMatch) {
60
71
  errors[dataAttribute.key] = {
61
72
  name: dataAttribute.key,
62
- error: true,
63
- errorMessage: "Invalid property"
73
+ message: "Invalid property"
64
74
  }
65
75
  return false;
66
76
  }
package/src/types.js CHANGED
@@ -6,7 +6,7 @@
6
6
  /**
7
7
  * @typedef {Object} DataField
8
8
  * @property {string} name - The name and key of the field
9
- * @property {string} value - the value of the field
9
+ * @property {any} value - the value of the field
10
10
  */
11
11
 
12
12
  /**
@@ -15,13 +15,14 @@
15
15
  * @property {Object} rules - The rules you want to use through validation
16
16
  * @property {SchemaRule} schema - The rules you want to use per field
17
17
  * @property {Object} errorMessages - The error messages you want to show during errors
18
- * @property {ValidatorOption} options - Options
18
+ * @property {ValidatorOptions} options - Options
19
19
  */
20
20
 
21
21
  /**
22
- * @typedef {Object} ValidatorOption
22
+ * @typedef {Object} ValidatorOptions
23
23
  * @property {boolean} propertiesMustMatch - If the form fields doesn't match with the expected structure will triggers an error
24
24
  * @property {boolean} abortEarly - Stops when caughts the first error
25
+ * @property {boolean} cache - Defines if the schema will uses cache as default or not
25
26
  */
26
27
 
27
28
  /**
@@ -39,13 +40,14 @@
39
40
 
40
41
  /**
41
42
  * @typedef {Object} SchemaRule
42
- * @property {SchemaRuleFiVeld} field - The field which will use the rule
43
+ * @property {SchemaRuleField} field - The field which will use the rule
43
44
  */
44
45
 
45
46
  /**
46
47
  * @typedef {Object} SchemaRuleField
47
48
  * @property {string} rule - The validation rule for the field (e.g., "name", "email", "phone", "hasText").
48
49
  * @property {boolean} required - Indicates whether the field is required.
50
+ * @property {boolean} cache - Indicates if the field requires cache or not
49
51
  */
50
52
 
51
53
  /**
@@ -65,5 +67,15 @@
65
67
  * @typedef {Object} DataValidatorErrorResponse
66
68
  * @property {boolean} error - Indicates an error occurred.
67
69
  * @property {string} [errorMessage] - A message describing the error (optional).
68
- * @property {Object} [dataErrors] - Additional error details (optional).
70
+ * @property {Object.<string, CheckError>} [errors] - Additional error details (optional).
71
+ */
72
+
73
+ /**
74
+ * Error Object
75
+ *
76
+ * @typedef {Object} CheckError
77
+ * @property {string} name - Field name
78
+ * @property {string} code - Error path (optional)
79
+ * @property {string} type - Error type (optional)
80
+ * @property {string} message - Error message (optional)
69
81
  */