Skip to content

Commit 343d5e2

Browse files
committed
added the package
1 parent 6a85cbc commit 343d5e2

21 files changed

+1063
-4
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
.idea/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Faisal Rashid
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

lib/cjs/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './packages/validators';
2+
export * from './packages/useValidation';

lib/cjs/index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use strict";
2+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3+
if (k2 === undefined) k2 = k;
4+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5+
}) : (function(o, m, k, k2) {
6+
if (k2 === undefined) k2 = k;
7+
o[k2] = m[k];
8+
}));
9+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
10+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11+
};
12+
Object.defineProperty(exports, "__esModule", { value: true });
13+
__exportStar(require("./packages/validators"), exports);
14+
__exportStar(require("./packages/useValidation"), exports);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Dispatch, SetStateAction } from 'react';
2+
import { ValidationResultType, ValidationType } from './validators';
3+
export declare type UseValidationReturnType<T> = {
4+
validationResult: [
5+
Record<keyof T, ValidationResultType>,
6+
Dispatch<SetStateAction<Record<keyof T, ValidationResultType>>>
7+
][0];
8+
isValidated: boolean;
9+
isFormValid: (form: T) => Promise<boolean>;
10+
validateAll: (form: T) => Promise<Record<keyof T, ValidationResultType>>;
11+
validateFormElement: (form: T, elementKey: keyof T) => Promise<void>;
12+
clearValidations: () => void;
13+
};
14+
export declare const useValidation: <T>(validationRules: Record<keyof T, ValidationType[]>) => UseValidationReturnType<T>;

lib/cjs/packages/useValidation.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"use strict";
2+
var __assign = (this && this.__assign) || function () {
3+
__assign = Object.assign || function(t) {
4+
for (var s, i = 1, n = arguments.length; i < n; i++) {
5+
s = arguments[i];
6+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7+
t[p] = s[p];
8+
}
9+
return t;
10+
};
11+
return __assign.apply(this, arguments);
12+
};
13+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15+
return new (P || (P = Promise))(function (resolve, reject) {
16+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19+
step((generator = generator.apply(thisArg, _arguments || [])).next());
20+
});
21+
};
22+
var __generator = (this && this.__generator) || function (thisArg, body) {
23+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25+
function verb(n) { return function (v) { return step([n, v]); }; }
26+
function step(op) {
27+
if (f) throw new TypeError("Generator is already executing.");
28+
while (_) try {
29+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30+
if (y = 0, t) op = [op[0] & 2, t.value];
31+
switch (op[0]) {
32+
case 0: case 1: t = op; break;
33+
case 4: _.label++; return { value: op[1], done: false };
34+
case 5: _.label++; y = op[1]; op = [0]; continue;
35+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
36+
default:
37+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41+
if (t[2]) _.ops.pop();
42+
_.trys.pop(); continue;
43+
}
44+
op = body.call(thisArg, _);
45+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47+
}
48+
};
49+
Object.defineProperty(exports, "__esModule", { value: true });
50+
exports.useValidation = void 0;
51+
var react_1 = require("react");
52+
var validators_1 = require("./validators");
53+
var useValidation = function (validationRules) {
54+
var _a = react_1.useState({}), validationResult = _a[0], setValidationResult = _a[1];
55+
var _b = react_1.useState(false), isValidated = _b[0], setIsValidated = _b[1];
56+
var validateAll = react_1.useCallback(function (form) { return __awaiter(void 0, void 0, void 0, function () {
57+
var result;
58+
return __generator(this, function (_a) {
59+
switch (_a.label) {
60+
case 0: return [4 /*yield*/, validators_1.validateForm(form, validationRules)];
61+
case 1:
62+
result = _a.sent();
63+
setValidationResult(result);
64+
setIsValidated(true);
65+
return [2 /*return*/, result];
66+
}
67+
});
68+
}); }, [validationRules]);
69+
var validateFormElement = react_1.useCallback(function (form, elementKey) { return __awaiter(void 0, void 0, void 0, function () {
70+
var result;
71+
return __generator(this, function (_a) {
72+
switch (_a.label) {
73+
case 0: return [4 /*yield*/, validators_1.validateCustomInput(form[elementKey], validationRules[elementKey])];
74+
case 1:
75+
result = _a.sent();
76+
setValidationResult(function (prev) {
77+
var _a;
78+
return (__assign(__assign({}, prev), (_a = {}, _a[elementKey] = result, _a)));
79+
});
80+
setIsValidated(true);
81+
return [2 /*return*/];
82+
}
83+
});
84+
}); }, [validationRules]);
85+
var isFormValid = react_1.useCallback(function (form) { return __awaiter(void 0, void 0, void 0, function () {
86+
var validationResult;
87+
return __generator(this, function (_a) {
88+
switch (_a.label) {
89+
case 0: return [4 /*yield*/, validateAll(form)];
90+
case 1:
91+
validationResult = _a.sent();
92+
return [2 /*return*/, !Object.keys(validationResult).some(function (key) { return !validationResult[key].isValid; })];
93+
}
94+
});
95+
}); }, [validateAll]);
96+
var clearValidations = react_1.useCallback(function () {
97+
setValidationResult({});
98+
}, []);
99+
return {
100+
validationResult: validationResult,
101+
isValidated: isValidated,
102+
isFormValid: isFormValid,
103+
validateAll: validateAll,
104+
validateFormElement: validateFormElement,
105+
clearValidations: clearValidations,
106+
};
107+
};
108+
exports.useValidation = useValidation;

lib/cjs/packages/validators.d.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export declare type ValidationType = {
2+
rule: ValidationRule;
3+
errorMessage: string;
4+
meta?: any;
5+
path?: string;
6+
stopCheckingOthersIfInvalid?: boolean;
7+
};
8+
export declare type ValidationResultType = {
9+
isValid: boolean;
10+
messages?: string[];
11+
};
12+
export declare type ValidatorAction = (value: string | number, meta?: any) => boolean | Promise<boolean>;
13+
export declare const validateForm: <T>(formToValidate: T, validationRules: Record<keyof T, ValidationType[]>) => Promise<Record<keyof T, ValidationResultType>>;
14+
export declare enum ValidationRule {
15+
Required = 0,
16+
Email = 1,
17+
Number = 2,
18+
Phone = 3,
19+
NoSpaces = 4,
20+
Regex = 5,
21+
MinimumLength = 6,
22+
MaximumLength = 7,
23+
Remote = 8
24+
}
25+
export declare const validateCustomInput: (value: string | number, validations: ValidationType[]) => Promise<ValidationResultType>;

lib/cjs/packages/validators.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
"use strict";
2+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4+
return new (P || (P = Promise))(function (resolve, reject) {
5+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8+
step((generator = generator.apply(thisArg, _arguments || [])).next());
9+
});
10+
};
11+
var __generator = (this && this.__generator) || function (thisArg, body) {
12+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14+
function verb(n) { return function (v) { return step([n, v]); }; }
15+
function step(op) {
16+
if (f) throw new TypeError("Generator is already executing.");
17+
while (_) try {
18+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19+
if (y = 0, t) op = [op[0] & 2, t.value];
20+
switch (op[0]) {
21+
case 0: case 1: t = op; break;
22+
case 4: _.label++; return { value: op[1], done: false };
23+
case 5: _.label++; y = op[1]; op = [0]; continue;
24+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
25+
default:
26+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30+
if (t[2]) _.ops.pop();
31+
_.trys.pop(); continue;
32+
}
33+
op = body.call(thisArg, _);
34+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36+
}
37+
};
38+
var _a;
39+
Object.defineProperty(exports, "__esModule", { value: true });
40+
exports.validateCustomInput = exports.ValidationRule = exports.validateForm = void 0;
41+
var validateForm = function (formToValidate, validationRules) { return __awaiter(void 0, void 0, void 0, function () {
42+
var result;
43+
return __generator(this, function (_a) {
44+
switch (_a.label) {
45+
case 0:
46+
result = {};
47+
return [4 /*yield*/, Promise.all(Object.keys(validationRules).map(function (key) { return __awaiter(void 0, void 0, void 0, function () {
48+
var rules, _a, _b;
49+
return __generator(this, function (_c) {
50+
switch (_c.label) {
51+
case 0:
52+
rules = validationRules[key];
53+
if (!rules) {
54+
return [2 /*return*/];
55+
}
56+
_a = result;
57+
_b = key;
58+
return [4 /*yield*/, exports.validateCustomInput(formToValidate[key], validationRules[key])];
59+
case 1:
60+
_a[_b] = _c.sent();
61+
return [2 /*return*/];
62+
}
63+
});
64+
}); }))];
65+
case 1:
66+
_a.sent();
67+
return [2 /*return*/, result];
68+
}
69+
});
70+
}); };
71+
exports.validateForm = validateForm;
72+
var ValidationRule;
73+
(function (ValidationRule) {
74+
ValidationRule[ValidationRule["Required"] = 0] = "Required";
75+
ValidationRule[ValidationRule["Email"] = 1] = "Email";
76+
ValidationRule[ValidationRule["Number"] = 2] = "Number";
77+
ValidationRule[ValidationRule["Phone"] = 3] = "Phone";
78+
ValidationRule[ValidationRule["NoSpaces"] = 4] = "NoSpaces";
79+
ValidationRule[ValidationRule["Regex"] = 5] = "Regex";
80+
ValidationRule[ValidationRule["MinimumLength"] = 6] = "MinimumLength";
81+
ValidationRule[ValidationRule["MaximumLength"] = 7] = "MaximumLength";
82+
ValidationRule[ValidationRule["Remote"] = 8] = "Remote";
83+
})(ValidationRule = exports.ValidationRule || (exports.ValidationRule = {}));
84+
var validateCustomInput = function (value, validations) { return __awaiter(void 0, void 0, void 0, function () {
85+
var isValid, validationMessages, _i, validations_1, validation, valueToValidate, passesValidation;
86+
return __generator(this, function (_a) {
87+
switch (_a.label) {
88+
case 0:
89+
if (!validations || !validations.length) {
90+
return [2 /*return*/, { isValid: true }];
91+
}
92+
isValid = true;
93+
validationMessages = [];
94+
_i = 0, validations_1 = validations;
95+
_a.label = 1;
96+
case 1:
97+
if (!(_i < validations_1.length)) return [3 /*break*/, 4];
98+
validation = validations_1[_i];
99+
valueToValidate = value;
100+
if (valueToValidate && validation.path) {
101+
valueToValidate = valueToValidate[validation.path];
102+
}
103+
return [4 /*yield*/, validatorMap[validation.rule](valueToValidate, validation.meta)];
104+
case 2:
105+
passesValidation = _a.sent();
106+
isValid = isValid && passesValidation;
107+
if (!passesValidation) {
108+
validationMessages.push(validation.errorMessage);
109+
if (validation.stopCheckingOthersIfInvalid) {
110+
return [3 /*break*/, 4];
111+
}
112+
}
113+
_a.label = 3;
114+
case 3:
115+
_i++;
116+
return [3 /*break*/, 1];
117+
case 4: return [2 /*return*/, {
118+
isValid: isValid,
119+
messages: validationMessages,
120+
}];
121+
}
122+
});
123+
}); };
124+
exports.validateCustomInput = validateCustomInput;
125+
var requiredValidator = function (value) {
126+
return !!value && value.toString().trim().length > 0;
127+
};
128+
var emailValidator = function (value) {
129+
var emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
130+
return emailRegex.test(value);
131+
};
132+
var numberValidator = function (value) {
133+
return !isNaN(Number(value));
134+
};
135+
var phoneValidator = function (value) {
136+
var mobilePhoneRegex = /^(\+[0-9]+)?\(?([0-9]{3})\)?([ .-]?)([0-9]{3})\3([0-9]{4})$/;
137+
return mobilePhoneRegex.test(value);
138+
};
139+
var noSpaceValidator = function (value) {
140+
return value.indexOf(' ') > -1;
141+
};
142+
var maxLengthValidator = function (value, meta) {
143+
if (!meta) {
144+
console.error('Length was not provided to MaximumLength Validator. Please provide length as the meta property');
145+
return false;
146+
}
147+
return value.length <= meta;
148+
};
149+
var minLengthValidator = function (value, meta) {
150+
if (!meta) {
151+
console.error('Length was not provided to MinimumLength Validator. Please provide length as meta property');
152+
return false;
153+
}
154+
return value.length >= meta;
155+
};
156+
var regexValidator = function (value, meta) {
157+
if (!meta) {
158+
console.error('A regular expression was not provided to Regex Validator. Please provide it as the meta property');
159+
return false;
160+
}
161+
return meta.test(value);
162+
};
163+
var remoteValidator = function (value, meta) { return __awaiter(void 0, void 0, void 0, function () {
164+
return __generator(this, function (_a) {
165+
return [2 /*return*/, meta(value)];
166+
});
167+
}); };
168+
var validatorMap = (_a = {},
169+
_a[ValidationRule.Required] = requiredValidator,
170+
_a[ValidationRule.Email] = emailValidator,
171+
_a[ValidationRule.Number] = numberValidator,
172+
_a[ValidationRule.Phone] = phoneValidator,
173+
_a[ValidationRule.NoSpaces] = noSpaceValidator,
174+
_a[ValidationRule.Regex] = regexValidator,
175+
_a[ValidationRule.MaximumLength] = maxLengthValidator,
176+
_a[ValidationRule.MinimumLength] = minLengthValidator,
177+
_a[ValidationRule.Remote] = remoteValidator,
178+
_a);

lib/esm/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './packages/validators';
2+
export * from './packages/useValidation';

lib/esm/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './packages/validators';
2+
export * from './packages/useValidation';

0 commit comments

Comments
 (0)