check-rule-mate 0.0.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 ADDED
@@ -0,0 +1,210 @@
1
+ # check-rule-mate
2
+
3
+ ## Overview
4
+
5
+ A lightweight and reusable JavaScript "library" for data validation. This library was esigned to simplify the process of validating form inputs using flexible rules and error handling. Validating your data by allowing you to define flexible rules, custom error messages, and reusable helper functions—all in a structured format.
6
+
7
+ The core goal is to provide a **reusable and easy-to-extend** for handling various form inputs, including fields like name, email, birthdate, phone number, and more.
8
+
9
+ Test the core functionalities here: [check-rule-mate Demo](https://johnrock16.github.io/check-rule-mate/)
10
+ (Note: Creating or modifying custom validators is not supported in the demo, as it requires JavaScript implementation.)
11
+
12
+
13
+ ## Features
14
+
15
+ - **Custom Validation Rules**: Easily define custom rules for form fields.
16
+ - **Modular Design**: Separation of rule definitions and error messages for easy management.
17
+ - **Easy Integration**: Can be used in any JavaScript environment.
18
+ - **Clear Error Handling**: Handles errors and displays messages.
19
+ - **Extendable**: Create your custom validators and rules and extend as you want.
20
+
21
+ ## Advanced Features
22
+
23
+ - **Modifiers:** Extend rules for specific use cases (e.g., age validation in a date rule).
24
+ - **Dynamic Parameters:** Use $variable to access field data within rules.
25
+ - **Modular Rules and Validators:** Create multiple files for rules and helpers, organizing them by context or form.
26
+
27
+ ## Table of Contents
28
+
29
+ - [Getting Started](#Getting-Started)
30
+ - [Installation](#Installation)
31
+ - [Running Tests](#Running-Tests)
32
+ - [How It Works](#How-It-Works)
33
+ - [Basic Example](#Basic-Example)
34
+ - [Defining Validation Components](#Defining-Validation-Components)
35
+ - [1. Data Rules](#Data-Rules)
36
+ - [2. General Rules](#General-Rules)
37
+ - [3. Validation Helpers](#Validation-Helpers)
38
+ - [4. Error Messages](#Error-Messages)
39
+ - [5. Example Usage](#Example-Usage)
40
+ - [Vanilla](#vanilla)
41
+ - [Express](#express)
42
+ - [Frontend](#frontend)
43
+
44
+ ## Getting Started
45
+ ### Installation
46
+
47
+ To install and start the library, run:
48
+ ```bash
49
+ npm install
50
+ npm start
51
+ ```
52
+
53
+ ### Running Tests
54
+
55
+ Execute the test suite with:
56
+ ```bash
57
+ npm test
58
+ ```
59
+
60
+ ## How It Works
61
+ ### Basic Example
62
+
63
+ Here’s an example of validating a set of fields:
64
+ ```javascript
65
+ const { myValidator } = require('./dataValidator/validators');
66
+ const { dataValidate } = require('./dataValidator/dataValidate');
67
+ const MY_RULES = require('./dataValidator/rules/validators/myValidatorRules.json');
68
+ const CONTACT_US = require('./dataValidator/rules/data/contactUs.json');
69
+ const MY_VALIDATION_ERROR_MESSAGES = require('./i18n/en_US/errors/myValidatorRules.json');
70
+
71
+ const fields = {
72
+ name: "John",
73
+ lastName: "Doe",
74
+ email: "email@email.com",
75
+ emailConfirm: "email@email.com",
76
+ phone: "",
77
+ subject: "I need a coffee",
78
+ message: "Give me coffee"
79
+ };
80
+
81
+ // This should return { ok: true }
82
+ const result = dataValidate(fields, {
83
+ validationHelpers: myValidator,
84
+ rules: MY_RULES,
85
+ dataRule: CONTACT_US,
86
+ dataErrorMessages: MY_VALIDATION_ERROR_MESSAGES,
87
+ });
88
+ ```
89
+
90
+ #### Parameters for dataValidate:
91
+
92
+ - **fields**: The object containing data to be validated.
93
+ - **validationHelpers**: Functions to validate field data (see /dataValidator/validators).
94
+ - **rules**: General validation rules for your application.
95
+ - **dataRule**: Specific rules linking fields to validation logic.
96
+ - **dataErrorMessages**: Custom error messages returned upon validation failure.
97
+
98
+ ## Defining Validation Components
99
+
100
+ ### Data Rules
101
+
102
+ Define rules for specific datasets, such as forms. Example for a "Contact Us" form:
103
+ ```json
104
+ {
105
+ "name": { "rule": "name", "required": true },
106
+ "lastName": { "rule": "name", "required": true },
107
+ "email": { "rule": "email", "required": true },
108
+ "emailConfirm": { "rule": "email--confirm", "required": true },
109
+ "phone": { "rule": "phone", "required": false },
110
+ "subject": { "rule": "hasText", "required": true },
111
+ "message": { "rule": "hasText", "required": true }
112
+ }
113
+ ```
114
+
115
+ ### General Rules
116
+
117
+ Define reusable validation logic. Example:
118
+
119
+ ```json
120
+ {
121
+ "name": {
122
+ "validate": ["hasText"],
123
+ "error": { "hasText": "common.hasText" }
124
+ },
125
+ "email": {
126
+ "regex": "/^[a-z0-9.]+@[a-z0-9]+\\.[a-z]+(\\.[a-z]+)?$/i",
127
+ "validate": ["regex"],
128
+ "error": { "regex": "email.regex" },
129
+ "modifier": {
130
+ "confirm": {
131
+ "validate": ["regex", "equals"],
132
+ "params": { "equals": ["$email"] },
133
+ "error": { "equals": "email.equals" }
134
+ }
135
+ }
136
+ },
137
+ "date": {
138
+ "regex": "/^\\d{4}[\/\\-](0?[1-9]|1[012])[\/\\-](0?[1-9]|[12][0-9]|3[01])$/",
139
+ "validate": ["regex", "validDate"],
140
+ "error": {
141
+ "regex": "common.dateFormat",
142
+ "validDate": "date.validDate"
143
+ },
144
+ "modifier": {
145
+ "age": {
146
+ "validate": ["regex", "validateAge"],
147
+ "params": {
148
+ "validateAge": [18, 130]
149
+ },
150
+ "error": {
151
+ "regex": "common.dateFormat",
152
+ "validateAge": "date.modifier.age.validateAge"
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ ```
159
+ #### Key Components:
160
+
161
+ - **validate**: Array of functions to execute for validation.
162
+ - **error**: Error messages for validation failures.
163
+ - **regex**: Regular expression for validation.
164
+ - **modifier**: Overrides specific rules with additional validations.
165
+ - **params**: Parameters for validation functions (e.g., $email accesses email field data).
166
+
167
+
168
+ ### Validation Helpers
169
+ Helper functions perform actual validation. Example:
170
+
171
+ ```javascript
172
+ const myValidator = function (value, rule, modifier = null, data = null) {
173
+ function regex() {
174
+ const regexTemplate = rule.modifier?.[modifier]?.regex || rule.regex;
175
+ const regex = new RegExp(regexTemplate);
176
+ return regex.test(value);
177
+ }
178
+
179
+ function hasText() {
180
+ return value.trim().length > 0;
181
+ }
182
+
183
+ function equals(key) {
184
+ return value === data[key];
185
+ }
186
+
187
+ return { regex, hasText, equals };
188
+ };
189
+ ```
190
+
191
+ ### Error Messages
192
+
193
+ Define custom error messages in a structured format:
194
+ ``` json
195
+ {
196
+ "common": { "hasText": "Please fill out this field." },
197
+ "email": { "regex": "Enter a valid email address." }
198
+ }
199
+ ```
200
+
201
+ ### Example Usage
202
+
203
+ Explore examples in the examples folder folder.
204
+
205
+ #### Vanilla
206
+ Here you are free to test anything you want about form validation, also We have a lot of tests scenarios in __tests__ which could be a great start.
207
+ #### Express:
208
+ See how the check-rule-mate works in back-end using a middleware.
209
+ #### Frontend:
210
+ Here you can found the DEMO page and it's a type of "playground" to test how RULES works and validations works. (Here you can't create customized javascript so custom validatorHelpers are disabled by default)
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "check-rule-mate",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "main": "./dist/main.cjs.js",
6
+ "type": "commonjs",
7
+ "scripts": {
8
+ "start": "node ./examples/vanilla/src/index.js",
9
+ "build": "node build",
10
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
11
+ "example:vanilla": "node ./examples/vanilla/src/index.js",
12
+ "example:express": "node ./examples/express/src/main.js"
13
+ },
14
+ "author": "João Rocha",
15
+ "license": "ISC",
16
+ "devDependencies": {
17
+ "esbuild": "^0.24.0",
18
+ "express": "^4.21.2",
19
+ "jest": "^29.7.0"
20
+ }
21
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Validate your data fields using your rules, data rules and validators.
3
+ * @param {[DataField]} data - All the data fields to be validate
4
+ * @param {DataValidatorConfigs} config - The configs which will be followed during validation
5
+ * @returns {DataValidatorSuccessResponse | DataValidatorErrorResponse} - The response of your validation
6
+ */
7
+ export function dataValidate(data, {validationHelpers = {}, rules, dataRule, dataErrorMessages = {}}) {
8
+ const dataErrors = {};
9
+
10
+ function getObjectValueByPath(obj, path) {
11
+ if (!obj || typeof path !== 'string') return undefined;
12
+
13
+ const keys = path.split('.');
14
+ let current = obj;
15
+
16
+ for (const key of keys) {
17
+ if (current[key] === undefined) return undefined;
18
+ current = current[key];
19
+ }
20
+
21
+ return current;
22
+ }
23
+
24
+ function inputValidation(dataAttribute, data = null) {
25
+ const { rule, required } = dataRule[dataAttribute.key];
26
+
27
+ if ((rule && required) || (!required && dataAttribute.value != '')) {
28
+ if (rule) {
29
+ const INPUT_RULE = rule.split('--')[0];
30
+ const RULE_MODIFIER = rule.split('--').length > 1 ? rule.split('--')[1] : '';
31
+ const dataAttributeValidation = dataAttributeValidator(dataAttribute.value, rules[INPUT_RULE], RULE_MODIFIER, validationHelpers, data);
32
+ const { isValid, errorMessage, errorType } = dataAttributeValidation.validate();
33
+ if (!isValid) {
34
+ dataErrors[dataAttribute.key] = {
35
+ name: dataAttribute.key,
36
+ error: true,
37
+ errorMessage: getObjectValueByPath(dataErrorMessages, errorMessage) || errorMessage,
38
+ errorType: errorType
39
+ }
40
+ }
41
+ return isValid;
42
+ }
43
+ }
44
+ return true;
45
+ }
46
+
47
+ function validate() {
48
+ let dataArr = Object.keys(data).map((key) => ({ key, value: data[key] }));
49
+ if (dataArr && dataArr.length > 0) {
50
+ if(!Object.keys(dataRule).every((key) => data.hasOwnProperty(key))) {
51
+ return { error: true, errorMessage: "Missing properties"}
52
+ }
53
+ const dataValidators = [...dataArr].map((input) => inputValidation(input, data));
54
+
55
+ if (dataValidators.some((element) => !element)) {
56
+ return { error: true, dataErrors: dataErrors };
57
+ }
58
+
59
+ const dataRuleArr = Object.keys(dataRule).map((key) => ({ key, required: dataRule[key].required}));
60
+ const dataAttributesKey = dataArr.map((attribute) => attribute.key);
61
+ const dataAttributesRequired = dataRuleArr.filter((rule) => rule.required).map((rule) => rule.key);
62
+
63
+ if (!dataAttributesRequired.every((fieldRequired) => dataAttributesKey.includes(fieldRequired))) {
64
+ return { error: true };
65
+ }
66
+ } else if (!dataArr || dataArr.length === 0) {
67
+ return { error: true, errorMessage: "Missing fields for dataRules"}
68
+ }
69
+ return { ok: true };
70
+ }
71
+
72
+ return validate();
73
+ }
74
+
75
+ /**
76
+ * A function to validate each attribute from a object [dataField]
77
+ * @param {string} value - The value to be validated
78
+ * @param {string} rule - The rule to be used during validation
79
+ * @param {string} modifier - The modifier of the rule if have
80
+ * @param {Function} customValidation - The function which will validate the value
81
+ * @param {[DataField]} data - The entire data fields
82
+ * @returns {{validate: Function}} the built function to validate all this parameters
83
+ */
84
+ function dataAttributeValidator (value, rule, modifier = null, customValidation = null, data = null) {
85
+ function validateRules(rule) {
86
+ let errorMessage;
87
+ let errorType;
88
+ const isValid = !rule.validate.some((validation) => {
89
+ let isInvalid = true;
90
+ if ((rule.params && rule.params[validation] && rule.params[validation].length > 0)) {
91
+ const params = rule.params[validation].map((param) => (typeof param === 'string' && param[0] === '$') ? param.substring(1, param.length) : param);
92
+ isInvalid = !this[validation](...params)
93
+ } else {
94
+ isInvalid = !this[validation]()
95
+ }
96
+ if (isInvalid && !errorMessage && rule?.error[validation]) {
97
+ errorMessage = rule.error[validation];
98
+ errorType = validation;
99
+ }
100
+ return isInvalid;
101
+ });
102
+ return {isValid, errorMessage, errorType}
103
+ }
104
+
105
+ function validate() {
106
+ if (customValidation && typeof customValidation === 'function') {
107
+ const validation = customValidation(value, rule, modifier, data);
108
+ Object.keys(validation).forEach((key) => {
109
+ this[key] = validation[key];
110
+ })
111
+ }
112
+
113
+ return modifier ? validateRules.call(this, rule.modifier[modifier]) : validateRules.call(this, rule);
114
+ }
115
+
116
+ return({
117
+ validate
118
+ });
119
+ }
package/src/main.js ADDED
@@ -0,0 +1,5 @@
1
+ import { dataValidate } from './js/dataValidate.js';
2
+
3
+ export {
4
+ dataValidate,
5
+ }
package/src/types.js ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @module typedefs
3
+ * This file contains all typedefs used in the project.
4
+ */
5
+
6
+ /**
7
+ * @typedef {Object} DataField
8
+ * @property {string} name - The name and key of the field
9
+ * @property {string} value - the value of the field
10
+ */
11
+
12
+ /**
13
+ * @typedef {Object} DataValidatorConfigs
14
+ * @property {ValidationHelpers} validationHelpers - The validator functions to help your validations
15
+ * @property {Object} rules - The rules you want to use through validation
16
+ * @property {dataRule} dataRule - The rules you want to use per field
17
+ * @property {Object} dataErrorMessages - The error messages you want to show during errors
18
+ */
19
+
20
+ /**
21
+ * @typedef {Function} ValidatorHelper
22
+ * @param {any} value - The value to be validate
23
+ * @param {string} rule - The rules to be followed during validation
24
+ * @param {string} modifier - If rule has a modifier applied
25
+ * @param {[DataField]} data - The data fields object
26
+ * @returns {boolean} The validation result of the value
27
+ */
28
+
29
+ /**
30
+ * @typedef {Object.<string, ValidatorHelper>} ValidationHelpers
31
+ */
32
+
33
+ /**
34
+ * @typedef {Object} DataRule
35
+ * @property {dataRuleFiVeld} field - The field which will use the rule
36
+ */
37
+
38
+ /**
39
+ * @typedef {Object} DataRuleField
40
+ * @property {string} rule - The validation rule for the field (e.g., "name", "email", "phone", "hasText").
41
+ * @property {boolean} required - Indicates whether the field is required.
42
+ */
43
+
44
+ /**
45
+ * @typedef {Object.<string, DataRule>} DataRule - A dynamic object where the keys are field names and the values define the field rules.
46
+ */
47
+
48
+ /**
49
+ * Represents a successful response.
50
+ *
51
+ * @typedef {Object} DataValidatorSuccessResponse
52
+ * @property {boolean} ok - Indicates the operation was successful.
53
+ */
54
+
55
+ /**
56
+ * Represents an error response.
57
+ *
58
+ * @typedef {Object} DataValidatorErrorResponse
59
+ * @property {boolean} error - Indicates an error occurred.
60
+ * @property {string} [errorMessage] - A message describing the error (optional).
61
+ * @property {Object} [dataErrors] - Additional error details (optional).
62
+ */