pols-validator 1.1.0 → 2.0.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/dist/index.d.ts CHANGED
@@ -1,6 +1,4 @@
1
- import { Rules } from "./rules";
2
- import { RulesParams } from "./rulesEngine";
3
- export { RulesEngine } from './rulesEngine';
4
- export { EvaluateResponse, validate } from './validate';
5
- export declare const rules: (params?: RulesParams) => Rules;
1
+ import { PRules } from "./rules";
2
+ import { PRulesParams } from "./rulesEngine";
3
+ export declare const rules: (params?: PRulesParams) => PRules;
6
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEvD,eAAO,MAAM,KAAK,YAAa,WAAW,UAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,eAAO,MAAM,KAAK,YAAa,YAAY,WAAuB,CAAA"}
package/dist/index.js CHANGED
@@ -1,10 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rules = exports.validate = exports.RulesEngine = void 0;
3
+ exports.rules = void 0;
4
4
  const rules_1 = require("./rules");
5
- var rulesEngine_1 = require("./rulesEngine");
6
- Object.defineProperty(exports, "RulesEngine", { enumerable: true, get: function () { return rulesEngine_1.RulesEngine; } });
7
- var validate_1 = require("./validate");
8
- Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validate_1.validate; } });
9
- const rules = (params) => new rules_1.Rules(params);
5
+ const rules = (params) => new rules_1.PRules(params);
10
6
  exports.rules = rules;
package/dist/rules.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { RulesEngine } from "./rulesEngine";
2
- export declare class Rules extends RulesEngine {
1
+ import { PRulesEngine } from "./rulesEngine";
2
+ export declare class PRules extends PRulesEngine {
3
3
  isAlphanumeric(): this;
4
4
  isEmailAddress(): this;
5
5
  isDateTime(): this;
@@ -16,7 +16,7 @@ export declare class Rules extends RulesEngine {
16
16
  hasFixedLength(limit: number): this;
17
17
  left(limit: number): this;
18
18
  isArray(): this;
19
- isArrayOfObjects(schema?: (index: number) => Record<string, RulesEngine>, prefix?: (index: number) => string): this;
19
+ isArrayOfObjects(schema?: (index: number) => Record<string, PRules>, prefix?: (index: number) => string): this;
20
20
  isIn(...elements: unknown[]): this;
21
21
  isNotIn(...elements: unknown[]): this;
22
22
  hasElements(): this;
@@ -25,7 +25,7 @@ export declare class Rules extends RulesEngine {
25
25
  lt(limit: number): this;
26
26
  lte(limit: number): this;
27
27
  beforeOrSameAsNow(): this;
28
- isObject(schema?: Record<string, RulesEngine>, prefix?: string): this;
28
+ isObject(schema?: Record<string, PRules>): this;
29
29
  isBoolean(): this;
30
30
  upper(): this;
31
31
  lower(): this;
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAW,MAAM,eAAe,CAAA;AA2CpD,qBAAa,KAAM,SAAQ,WAAW;IACrC,cAAc;IAWd,cAAc;IAQd,UAAU;IAcV,MAAM;IAMN,MAAM;IA4BN,KAAK,CAAC,OAAO,EAAE,MAAM;IAQrB,QAAQ;IAUR,SAAS;IAQT,SAAS;IAIT,eAAe;IAIf,WAAW;IAQX,SAAS,CAAC,KAAK,EAAE,MAAM;IAYvB,SAAS,CAAC,KAAK,EAAE,MAAM;IAYvB,cAAc,CAAC,KAAK,EAAE,MAAM;IAY5B,IAAI,CAAC,KAAK,EAAE,MAAM;IAMlB,OAAO;IAiBP,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;IAoB5G,IAAI,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAa3B,OAAO,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAO9B,WAAW;IAMX,EAAE,CAAC,KAAK,EAAE,MAAM;IAMhB,GAAG,CAAC,KAAK,EAAE,MAAM;IAMjB,EAAE,CAAC,KAAK,EAAE,MAAM;IAMhB,GAAG,CAAC,KAAK,EAAE,MAAM;IAMjB,iBAAiB;IAOjB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM;IAM9D,SAAS;IA+CT,KAAK;IAQL,KAAK;IAQL,SAAS;IAQT,KAAK,CAAC,QAAQ,EAAE,MAAM;IAStB,iBAAiB;IAQjB,QAAQ;IASR,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC;IAMlG,UAAU;IAQV,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAKhC"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAA;AA0C3D,qBAAa,MAAO,SAAQ,YAAY;IACvC,cAAc;IAWd,cAAc;IAQd,UAAU;IAcV,MAAM;IAMN,MAAM;IA4BN,KAAK,CAAC,OAAO,EAAE,MAAM;IAQrB,QAAQ;IAUR,SAAS;IAQT,SAAS;IAIT,eAAe;IAIf,WAAW;IAQX,SAAS,CAAC,KAAK,EAAE,MAAM;IAYvB,SAAS,CAAC,KAAK,EAAE,MAAM;IAYvB,cAAc,CAAC,KAAK,EAAE,MAAM;IAY5B,IAAI,CAAC,KAAK,EAAE,MAAM;IAMlB,OAAO;IAiBP,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;IAoBvG,IAAI,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAa3B,OAAO,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAO9B,WAAW;IAMX,EAAE,CAAC,KAAK,EAAE,MAAM;IAMhB,GAAG,CAAC,KAAK,EAAE,MAAM;IAMjB,EAAE,CAAC,KAAK,EAAE,MAAM;IAMhB,GAAG,CAAC,KAAK,EAAE,MAAM;IAMjB,iBAAiB;IAOjB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMxC,SAAS;IA+CT,KAAK;IAQL,KAAK;IAQL,SAAS;IAQT,KAAK,CAAC,QAAQ,EAAE,MAAM;IAStB,iBAAiB;IAQjB,QAAQ;IASR,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC;IAMlG,UAAU;IAQV,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAKhC"}
package/dist/rules.js CHANGED
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Rules = void 0;
3
+ exports.PRules = void 0;
4
4
  const pols_utils_1 = require("pols-utils");
5
5
  const rulesEngine_1 = require("./rulesEngine");
6
- const validate_1 = require("./validate");
7
- const isObject = (wrapper, schema, prefix) => {
6
+ const isObject = (context, wrapper, schema) => {
8
7
  const message = `'${wrapper.label}' debe ser un objeto`;
9
8
  if (typeof wrapper.value == 'string') {
10
9
  try {
@@ -27,9 +26,9 @@ const isObject = (wrapper, schema, prefix) => {
27
26
  for (const key in schema) {
28
27
  const rulesInside = schema[key];
29
28
  const labelIndise = rulesInside.label ?? key;
30
- rulesInside.label = `${prefix ?? ''}${labelIndise}`;
29
+ rulesInside.label = `${context.label ? `${context.label}${context.separator}` : ''}${labelIndise}`;
31
30
  newWrapperValue[key] = wrapper.value[key];
32
- const result2 = (0, validate_1.validate)(newWrapperValue[key], rulesInside);
31
+ const result2 = rulesInside.validate(newWrapperValue[key]);
33
32
  if (result2.error == true) {
34
33
  errorMessages.push(...result2.messages);
35
34
  }
@@ -44,7 +43,7 @@ const isObject = (wrapper, schema, prefix) => {
44
43
  wrapper.value = newWrapperValue;
45
44
  }
46
45
  };
47
- class Rules extends rulesEngine_1.RulesEngine {
46
+ class PRules extends rulesEngine_1.PRulesEngine {
48
47
  isAlphanumeric() {
49
48
  this.add(this.isAlphanumeric.name, (wrapper) => {
50
49
  if (typeof wrapper.value == 'number') {
@@ -222,7 +221,7 @@ class Rules extends rulesEngine_1.RulesEngine {
222
221
  return this.isArray().add(this.isArrayOfObjects.name, (wrapper) => {
223
222
  const messages = [];
224
223
  for (const [i, value] of wrapper.value.entries()) {
225
- const v = isObject({
224
+ const v = isObject(this, {
226
225
  label: prefix?.(i) ?? `Item ${i}`,
227
226
  value
228
227
  }, schema?.(i));
@@ -298,9 +297,9 @@ class Rules extends rulesEngine_1.RulesEngine {
298
297
  return `'${wrapper.label}' debe ser anterior o igual a 'ahora'`;
299
298
  });
300
299
  }
301
- isObject(schema, prefix) {
300
+ isObject(schema) {
302
301
  return this.add(this.isObject.name, (wrapper) => {
303
- return isObject(wrapper, schema, prefix);
302
+ return isObject(this, wrapper, schema);
304
303
  });
305
304
  }
306
305
  isBoolean() {
@@ -415,4 +414,4 @@ class Rules extends rulesEngine_1.RulesEngine {
415
414
  });
416
415
  }
417
416
  }
418
- exports.Rules = Rules;
417
+ exports.PRules = PRules;
@@ -1,21 +1,35 @@
1
- export type RulesParams = {
1
+ export type PRulesParams = {
2
2
  label?: string;
3
+ separator?: string;
3
4
  } & ({
4
5
  required?: boolean;
5
6
  } | {
6
7
  default?: unknown;
7
8
  });
8
- export type ValidationFunction = (wrapper: Wrapper, ...args: unknown[]) => string | string[] | void | null | undefined;
9
- export type Wrapper<T = unknown> = {
9
+ export type PRulesFunction = (wrapper: PRulesWrapper, ...args: unknown[]) => string | string[] | void | null | undefined;
10
+ export type PRulesWrapper<T = unknown> = {
10
11
  value: T;
11
12
  label: string;
12
13
  };
13
- export declare class RulesEngine {
14
- constructor(params?: RulesParams);
14
+ export type PRulesResponse<T> = {
15
+ error: false;
16
+ success: true;
17
+ result: T;
18
+ } | {
19
+ error: true;
20
+ success: false;
21
+ messages: string[];
22
+ };
23
+ export declare class PRulesEngine {
24
+ prefix: string;
15
25
  label: string;
26
+ separator: string;
16
27
  required: boolean;
17
28
  default: unknown;
18
- collection: ValidationFunction[];
19
- protected add(name: string, validationFunction: ValidationFunction, executeOnce?: boolean): this;
29
+ private collectionFunctions;
30
+ private collectionNames;
31
+ constructor(params?: PRulesParams);
32
+ protected add(name: string, validationFunction: PRulesFunction): this;
33
+ validate: <T>(target: unknown) => PRulesResponse<T>;
20
34
  }
21
35
  //# sourceMappingURL=rulesEngine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rulesEngine.d.ts","sourceRoot":"","sources":["../src/rulesEngine.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACd,GAAG,CAAC;IACJ,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAA;AAEtH,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,OAAO,IAAI;IAClC,KAAK,EAAE,CAAC,CAAA;IACR,KAAK,EAAE,MAAM,CAAA;CACb,CAAA;AAED,qBAAa,WAAW;gBACX,MAAM,CAAC,EAAE,WAAW;IAOhC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,OAAO,CAAQ;IACzB,OAAO,EAAE,OAAO,CAAO;IACvB,UAAU,EAAE,kBAAkB,EAAE,CAAK;IAErC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,UAAQ;CAIvF"}
1
+ {"version":3,"file":"rulesEngine.d.ts","sourceRoot":"","sources":["../src/rulesEngine.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB,GAAG,CAAC;IACJ,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAA;AAExH,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,IAAI;IACxC,KAAK,EAAE,CAAC,CAAA;IACR,KAAK,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC/B,KAAK,EAAE,KAAK,CAAA;IACZ,OAAO,EAAE,IAAI,CAAA;IACb,MAAM,EAAE,CAAC,CAAA;CACT,GAAG;IACH,KAAK,EAAE,IAAI,CAAA;IACX,OAAO,EAAE,KAAK,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CAClB,CAAA;AAED,qBAAa,YAAY;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAQ;IACzB,OAAO,EAAE,OAAO,CAAO;IAEvB,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,eAAe,CAAe;gBAE1B,MAAM,CAAC,EAAE,YAAY;IAOjC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,cAAc;IAQ9D,QAAQ,GAAI,CAAC,UAAU,OAAO,KAAG,cAAc,CAAC,CAAC,CAAC,CAoDjD;CACD"}
@@ -1,21 +1,78 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RulesEngine = void 0;
4
- class RulesEngine {
5
- constructor(params) {
6
- if (!params)
7
- return;
8
- this.label = params.label;
9
- this.required = 'required' in params ? params.required : false;
10
- this.default = 'default' in params ? params.default : null;
11
- }
3
+ exports.PRulesEngine = void 0;
4
+ const pols_utils_1 = require("pols-utils");
5
+ class PRulesEngine {
6
+ prefix;
12
7
  label;
8
+ separator;
13
9
  required = false;
14
10
  default = null;
15
- collection = [];
16
- add(name, validationFunction, executeOnce = false) {
17
- this.collection.push(validationFunction);
11
+ collectionFunctions = [];
12
+ collectionNames = [];
13
+ constructor(params) {
14
+ this.label = params?.label;
15
+ this.separator = params?.separator ?? ' > ';
16
+ this.required = params && 'required' in params ? params?.required : false;
17
+ this.default = params && 'default' in params ? params?.default : null;
18
+ }
19
+ add(name, validationFunction) {
20
+ if (!this.collectionNames.includes(name)) {
21
+ this.collectionNames.push(name);
22
+ this.collectionFunctions.push(validationFunction);
23
+ }
18
24
  return this;
19
25
  }
26
+ validate = (target) => {
27
+ const errorMessages = [];
28
+ if (typeof target == 'string')
29
+ target = target.trim();
30
+ const isEmpty = target == null || (typeof target == 'string' && !target);
31
+ const label = this.label;
32
+ if (this.required && isEmpty) {
33
+ return {
34
+ error: true,
35
+ success: false,
36
+ messages: [`'${label}' es requerido`]
37
+ };
38
+ }
39
+ if (isEmpty) {
40
+ return {
41
+ error: false,
42
+ success: true,
43
+ result: this.default
44
+ };
45
+ }
46
+ const wrapper = {
47
+ value: pols_utils_1.PUtils.clone(target),
48
+ label
49
+ };
50
+ for (const validationFunction of this.collectionFunctions) {
51
+ const result = validationFunction(wrapper);
52
+ if (!result)
53
+ continue;
54
+ if (typeof result == 'string') {
55
+ errorMessages.push(result);
56
+ break;
57
+ }
58
+ else {
59
+ errorMessages.push(...result);
60
+ }
61
+ }
62
+ if (errorMessages.length) {
63
+ return {
64
+ error: true,
65
+ success: false,
66
+ messages: errorMessages
67
+ };
68
+ }
69
+ else {
70
+ return {
71
+ error: false,
72
+ success: true,
73
+ result: wrapper.value
74
+ };
75
+ }
76
+ };
20
77
  }
21
- exports.RulesEngine = RulesEngine;
78
+ exports.PRulesEngine = PRulesEngine;
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "pols-validator",
3
- "version": "1.1.0",
3
+ "version": "2.0.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "npx tsc",
9
- "test": "npx ts-node-dev -r tsconfig-paths/register --project tsconfig.json"
9
+ "test": "npx ts-node-dev -r tsconfig-paths/register --project tsconfig.json",
10
+ "export": "npm run build && npm publish"
10
11
  },
11
12
  "author": "Jean Paul Sánchez mendoza",
12
13
  "license": "ISC",
@@ -21,6 +22,6 @@
21
22
  "typescript-eslint": "^8.11.0"
22
23
  },
23
24
  "dependencies": {
24
- "pols-utils": "^1.1.2"
25
+ "pols-utils": "^1.3.5"
25
26
  }
26
27
  }
package/src/index.ts CHANGED
@@ -1,8 +1,4 @@
1
- import { Rules } from "./rules"
2
- import { RulesParams } from "./rulesEngine"
1
+ import { PRules } from "./rules"
2
+ import { PRulesParams } from "./rulesEngine"
3
3
 
4
- export { RulesEngine } from './rulesEngine'
5
-
6
- export { EvaluateResponse, validate } from './validate'
7
-
8
- export const rules = (params?: RulesParams) => new Rules(params)
4
+ export const rules = (params?: PRulesParams) => new PRules(params)
package/src/rules.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { PDate, PUtils } from "pols-utils"
2
- import { RulesEngine, Wrapper } from "./rulesEngine"
3
- import { validate } from "./validate"
2
+ import { PRulesEngine, PRulesWrapper } from "./rulesEngine"
4
3
 
5
- const isObject = (wrapper: Wrapper, schema?: Record<string, RulesEngine>, prefix?: string) => {
4
+ const isObject = (context: PRules, wrapper: PRulesWrapper, schema?: Record<string, PRules>) => {
6
5
  const message = `'${wrapper.label}' debe ser un objeto`
7
6
 
8
7
  if (typeof wrapper.value == 'string') {
@@ -24,11 +23,11 @@ const isObject = (wrapper: Wrapper, schema?: Record<string, RulesEngine>, prefix
24
23
  for (const key in schema) {
25
24
  const rulesInside = schema[key]
26
25
  const labelIndise = rulesInside.label ?? key
27
- rulesInside.label = `${prefix ?? ''}${labelIndise}`
26
+ rulesInside.label = `${context.label ? `${context.label}${context.separator}` : ''}${labelIndise}`
28
27
 
29
28
  newWrapperValue[key] = wrapper.value[key]
30
29
 
31
- const result2 = validate(newWrapperValue[key], rulesInside)
30
+ const result2 = rulesInside.validate(newWrapperValue[key])
32
31
  if (result2.error == true) {
33
32
  errorMessages.push(...result2.messages)
34
33
  } else {
@@ -42,9 +41,9 @@ const isObject = (wrapper: Wrapper, schema?: Record<string, RulesEngine>, prefix
42
41
  }
43
42
  }
44
43
 
45
- export class Rules extends RulesEngine {
44
+ export class PRules extends PRulesEngine {
46
45
  isAlphanumeric() {
47
- this.add(this.isAlphanumeric.name, (wrapper: Wrapper) => {
46
+ this.add(this.isAlphanumeric.name, (wrapper: PRulesWrapper) => {
48
47
  if (typeof wrapper.value == 'number') {
49
48
  wrapper.value = wrapper.value.toString()
50
49
  } else if (typeof wrapper.value != 'string') {
@@ -56,14 +55,14 @@ export class Rules extends RulesEngine {
56
55
 
57
56
  isEmailAddress() {
58
57
  this.isAlphanumeric()
59
- this.add(this.isEmailAddress.name, (wrapper: Wrapper) => {
58
+ this.add(this.isEmailAddress.name, (wrapper: PRulesWrapper) => {
60
59
  if (!(wrapper.value as string).match(/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/)) return `'${wrapper.label}' debe ser una dirección de correo`
61
60
  })
62
61
  return this
63
62
  }
64
63
 
65
64
  isDateTime() {
66
- this.add(this.isDateTime.name, (wrapper: Wrapper) => {
65
+ this.add(this.isDateTime.name, (wrapper: PRulesWrapper) => {
67
66
  const message = `'${wrapper.label}' tiene un formato de fecha y hora no válido`
68
67
  if (typeof wrapper.value == 'string' || typeof wrapper.value == 'number' || wrapper.value instanceof Date || wrapper.value instanceof PDate) {
69
68
  const newDate = new PDate(wrapper.value)
@@ -77,13 +76,13 @@ export class Rules extends RulesEngine {
77
76
  }
78
77
 
79
78
  isDate() {
80
- return this.isDateTime().add(this.isDate.name, (wrapper: Wrapper<PDate>) => {
79
+ return this.isDateTime().add(this.isDate.name, (wrapper: PRulesWrapper<PDate>) => {
81
80
  wrapper.value.clearTime()
82
81
  })
83
82
  }
84
83
 
85
84
  isTime() {
86
- this.add(this.isTime.name, (wrapper: Wrapper) => {
85
+ this.add(this.isTime.name, (wrapper: PRulesWrapper) => {
87
86
  const message = `'${wrapper.label}' contiene un formato de hora no válido`
88
87
  const value = wrapper.value.toString()
89
88
  const parts = value.replace(/[.,]/g, ':').replace('m', '').match(/^([0-2]?[0-9])(:?)([0-5]?[0-9]?)(:?)([0-5]?[0-9]?)([ap]?)\.?m?\.?$/)
@@ -112,14 +111,14 @@ export class Rules extends RulesEngine {
112
111
 
113
112
  match(pattern: RegExp) {
114
113
  this.isAlphanumeric()
115
- this.add(this.match.name, (wrapper: Wrapper) => {
114
+ this.add(this.match.name, (wrapper: PRulesWrapper) => {
116
115
  if (!(wrapper.value as string).match(pattern)) return `'${wrapper.label}' no cumple con el formato de texto deseado`
117
116
  })
118
117
  return this
119
118
  }
120
119
 
121
120
  isNumber() {
122
- this.add(this.isNumber.name, (wrapper: Wrapper) => {
121
+ this.add(this.isNumber.name, (wrapper: PRulesWrapper) => {
123
122
  const message = `'${wrapper.label}' debe ser un número`
124
123
  const value = Number(wrapper.value)
125
124
  if (isNaN(value) || value == Infinity) return message
@@ -130,7 +129,7 @@ export class Rules extends RulesEngine {
130
129
 
131
130
  isInteger() {
132
131
  this.isNumber()
133
- this.add(this.isInteger.name, (wrapper: Wrapper) => {
132
+ this.add(this.isInteger.name, (wrapper: PRulesWrapper) => {
134
133
  if (wrapper.value != Math.floor(wrapper.value as number)) return `'${wrapper.label}' debe ser un número entero`
135
134
  })
136
135
  return this
@@ -146,14 +145,14 @@ export class Rules extends RulesEngine {
146
145
 
147
146
  onlyNumbers() {
148
147
  this.isAlphanumeric()
149
- this.add(this.onlyNumbers.name, (wrapper: Wrapper) => {
148
+ this.add(this.onlyNumbers.name, (wrapper: PRulesWrapper) => {
150
149
  if (!(wrapper.value as string).match(/^[0-9]+$/)) return `'${wrapper.label}' debe contener sólo números`
151
150
  })
152
151
  return this
153
152
  }
154
153
 
155
154
  maxLength(limit: number) {
156
- return this.add(this.maxLength.name, (wrapper: Wrapper) => {
155
+ return this.add(this.maxLength.name, (wrapper: PRulesWrapper) => {
157
156
  if (wrapper.value instanceof Array) {
158
157
  return wrapper.value.length > limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elementos' : 'elementos'}' como máximo` : null
159
158
  } else if (typeof wrapper.value == 'string') {
@@ -165,7 +164,7 @@ export class Rules extends RulesEngine {
165
164
  }
166
165
 
167
166
  minLength(limit: number) {
168
- return this.add(this.minLength.name, (wrapper: Wrapper) => {
167
+ return this.add(this.minLength.name, (wrapper: PRulesWrapper) => {
169
168
  if (wrapper.value instanceof Array) {
170
169
  return wrapper.value.length < limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elementos' : 'elementos'}' como mínimo` : null
171
170
  } else if (typeof wrapper.value == 'string') {
@@ -177,7 +176,7 @@ export class Rules extends RulesEngine {
177
176
  }
178
177
 
179
178
  hasFixedLength(limit: number) {
180
- return this.add(this.hasFixedLength.name, (wrapper: Wrapper) => {
179
+ return this.add(this.hasFixedLength.name, (wrapper: PRulesWrapper) => {
181
180
  if (wrapper.value instanceof Array) {
182
181
  return wrapper.value.length < limit ? `'${wrapper.label}' debe contener sólo '${limit} ${limit == 1 ? 'elementos' : 'elementos'}'` : null
183
182
  } else if (typeof wrapper.value == 'string') {
@@ -189,13 +188,13 @@ export class Rules extends RulesEngine {
189
188
  }
190
189
 
191
190
  left(limit: number) {
192
- return this.isAlphanumeric().add(this.left.name, (wrapper: Wrapper) => {
191
+ return this.isAlphanumeric().add(this.left.name, (wrapper: PRulesWrapper) => {
193
192
  (wrapper.value as string) = (wrapper.value as string).substring(0, limit)
194
193
  })
195
194
  }
196
195
 
197
196
  isArray() {
198
- return this.add(this.isArray.name, (wrapper: Wrapper) => {
197
+ return this.add(this.isArray.name, (wrapper: PRulesWrapper) => {
199
198
  const message = `'${wrapper.label}' debe ser una lista de elementos`
200
199
  if (typeof wrapper.value == 'string') {
201
200
  try {
@@ -211,11 +210,11 @@ export class Rules extends RulesEngine {
211
210
  })
212
211
  }
213
212
 
214
- isArrayOfObjects(schema?: (index: number) => Record<string, RulesEngine>, prefix?: (index: number) => string) {
215
- return this.isArray().add(this.isArrayOfObjects.name, (wrapper: Wrapper<unknown[]>) => {
213
+ isArrayOfObjects(schema?: (index: number) => Record<string, PRules>, prefix?: (index: number) => string) {
214
+ return this.isArray().add(this.isArrayOfObjects.name, (wrapper: PRulesWrapper<unknown[]>) => {
216
215
  const messages: string[] = []
217
216
  for (const [i, value] of wrapper.value.entries()) {
218
- const v = isObject({
217
+ const v = isObject(this, {
219
218
  label: prefix?.(i) ?? `Item ${i}`,
220
219
  value
221
220
  }, schema?.(i))
@@ -232,7 +231,7 @@ export class Rules extends RulesEngine {
232
231
  }
233
232
 
234
233
  isIn(...elements: unknown[]) {
235
- this.add(this.isIn.name, (wrapper: Wrapper) => {
234
+ this.add(this.isIn.name, (wrapper: PRulesWrapper) => {
236
235
  if (wrapper.value instanceof Array) {
237
236
  for (const v of wrapper.value) {
238
237
  if (!elements.includes(v)) return `'${wrapper.label}' no contiene valores válidos`
@@ -245,57 +244,57 @@ export class Rules extends RulesEngine {
245
244
  }
246
245
 
247
246
  isNotIn(...elements: unknown[]) {
248
- this.add(this.isNotIn.name, (wrapper: Wrapper) => {
247
+ this.add(this.isNotIn.name, (wrapper: PRulesWrapper) => {
249
248
  if (elements.includes(wrapper.value)) return `'${wrapper.label}' no tiene un valor válido`
250
249
  })
251
250
  return this
252
251
  }
253
252
 
254
253
  hasElements() {
255
- return this.isArray().add(this.hasElements.name, (wrapper: Wrapper<unknown[]>) => {
254
+ return this.isArray().add(this.hasElements.name, (wrapper: PRulesWrapper<unknown[]>) => {
256
255
  if (!wrapper.value.length) return `'${wrapper.label}' debe contenedor al menos un elemento`
257
256
  })
258
257
  }
259
258
 
260
259
  gt(limit: number) {
261
- return this.isNumber().add(this.gt.name, (wrapper: Wrapper) => {
260
+ return this.isNumber().add(this.gt.name, (wrapper: PRulesWrapper) => {
262
261
  if (wrapper.value as number <= limit) return `'${wrapper.label}' debe ser mayor a '${limit}'`
263
262
  })
264
263
  }
265
264
 
266
265
  gte(limit: number) {
267
- return this.isNumber().add(this.gte.name, (wrapper: Wrapper) => {
266
+ return this.isNumber().add(this.gte.name, (wrapper: PRulesWrapper) => {
268
267
  if (wrapper.value as number < limit) return `'${wrapper.label}' debe ser mayor o igual a '${limit}'`
269
268
  })
270
269
  }
271
270
 
272
271
  lt(limit: number) {
273
- return this.isNumber().add(this.lt.name, (wrapper: Wrapper) => {
272
+ return this.isNumber().add(this.lt.name, (wrapper: PRulesWrapper) => {
274
273
  if (wrapper.value as number >= limit) return `'${wrapper.label}' debe ser menor a '${limit}'`
275
274
  })
276
275
  }
277
276
 
278
277
  lte(limit: number) {
279
- return this.isNumber().add(this.lte.name, (wrapper: Wrapper) => {
278
+ return this.isNumber().add(this.lte.name, (wrapper: PRulesWrapper) => {
280
279
  if (wrapper.value as number > limit) return `'${wrapper.label}' debe ser menor o igual a '${limit}'`
281
280
  })
282
281
  }
283
282
 
284
283
  beforeOrSameAsNow() {
285
- return this.isDateTime().add(this.beforeOrSameAsNow.name, (wrapper: Wrapper<PDate>) => {
284
+ return this.isDateTime().add(this.beforeOrSameAsNow.name, (wrapper: PRulesWrapper<PDate>) => {
286
285
  const now = new PDate
287
286
  if (wrapper.value.time > now.time) return `'${wrapper.label}' debe ser anterior o igual a 'ahora'`
288
287
  })
289
288
  }
290
289
 
291
- isObject(schema?: Record<string, RulesEngine>, prefix?: string) {
292
- return this.add(this.isObject.name, (wrapper: Wrapper) => {
293
- return isObject(wrapper, schema, prefix)
290
+ isObject(schema?: Record<string, PRules>) {
291
+ return this.add(this.isObject.name, (wrapper: PRulesWrapper) => {
292
+ return isObject(this, wrapper, schema)
294
293
  })
295
294
  }
296
295
 
297
296
  isBoolean() {
298
- return this.add(this.isBoolean.name, (wrapper: Wrapper) => {
297
+ return this.add(this.isBoolean.name, (wrapper: PRulesWrapper) => {
299
298
  const message = `'${wrapper.label}' debe ser de tipo booleano`
300
299
  if (typeof wrapper.value == 'string') {
301
300
  const value = wrapper.value.trim().toUpperCase()
@@ -343,7 +342,7 @@ export class Rules extends RulesEngine {
343
342
 
344
343
  upper() {
345
344
  this.isAlphanumeric()
346
- this.add(this.upper.name, (wrapper: Wrapper) => {
345
+ this.add(this.upper.name, (wrapper: PRulesWrapper) => {
347
346
  wrapper.value = (wrapper.value as string).toUpperCase()
348
347
  })
349
348
  return this
@@ -351,7 +350,7 @@ export class Rules extends RulesEngine {
351
350
 
352
351
  lower() {
353
352
  this.isAlphanumeric()
354
- this.add(this.lower.name, (wrapper: Wrapper) => {
353
+ this.add(this.lower.name, (wrapper: PRulesWrapper) => {
355
354
  wrapper.value = (wrapper.value as string).toLowerCase()
356
355
  })
357
356
  return this
@@ -359,7 +358,7 @@ export class Rules extends RulesEngine {
359
358
 
360
359
  decodeURI() {
361
360
  this.isAlphanumeric()
362
- this.add(this.decodeURI.name, (wrapper: Wrapper) => {
361
+ this.add(this.decodeURI.name, (wrapper: PRulesWrapper) => {
363
362
  wrapper.value = decodeURI(wrapper.value as string)
364
363
  })
365
364
  return this
@@ -367,7 +366,7 @@ export class Rules extends RulesEngine {
367
366
 
368
367
  round(decimals: number) {
369
368
  this.isNumber()
370
- this.add(this.round.name, (wrapper: Wrapper) => {
369
+ this.add(this.round.name, (wrapper: PRulesWrapper) => {
371
370
  wrapper.value = PUtils.Number.round(wrapper.value as number, decimals)
372
371
  })
373
372
  return this
@@ -376,7 +375,7 @@ export class Rules extends RulesEngine {
376
375
  /* Reemplaza todos los dobles (o más) espacios juntos por uno simple */
377
376
  cleanDoubleSpaces() {
378
377
  this.isAlphanumeric()
379
- this.add(this.cleanDoubleSpaces.name, (wrapper: Wrapper) => {
378
+ this.add(this.cleanDoubleSpaces.name, (wrapper: PRulesWrapper) => {
380
379
  wrapper.value = (wrapper.value as string).replace(/\s{2,}/g, ' ')
381
380
  })
382
381
  return this
@@ -384,7 +383,7 @@ export class Rules extends RulesEngine {
384
383
 
385
384
  noSpaces() {
386
385
  this.isAlphanumeric()
387
- this.add(this.noSpaces.name, (wrapper: Wrapper) => {
386
+ this.add(this.noSpaces.name, (wrapper: PRulesWrapper) => {
388
387
  if ((wrapper.value as string).match(/\s/)) return `'${wrapper.label}' no debe contener 'espacios'`
389
388
  })
390
389
  return this
@@ -392,21 +391,21 @@ export class Rules extends RulesEngine {
392
391
 
393
392
 
394
393
  replace(search: string | RegExp, replace: string | ((substring: string, ...args: any[]) => string)) {
395
- return this.isAlphanumeric().add(this.replace.name, (wrapper: Wrapper) => {
394
+ return this.isAlphanumeric().add(this.replace.name, (wrapper: PRulesWrapper) => {
396
395
  wrapper.value = (wrapper.value as string).replace(search, replace as any)
397
396
  })
398
397
  }
399
398
 
400
399
  capitalize() {
401
400
  this.isAlphanumeric()
402
- this.add(this.capitalize.name, (wrapper: Wrapper) => {
401
+ this.add(this.capitalize.name, (wrapper: PRulesWrapper) => {
403
402
  wrapper.value = PUtils.String.capitalize(wrapper.value as string)
404
403
  })
405
404
  return this
406
405
  }
407
406
 
408
407
  split(separator: string | RegExp) {
409
- return this.isAlphanumeric().add(this.split.name, (wrapper: Wrapper) => {
408
+ return this.isAlphanumeric().add(this.split.name, (wrapper: PRulesWrapper) => {
410
409
  wrapper.value = (wrapper.value as any).split(separator)
411
410
  })
412
411
  }
@@ -1,33 +1,107 @@
1
- export type RulesParams = {
1
+ import { PUtils } from "pols-utils"
2
+
3
+ export type PRulesParams = {
2
4
  label?: string
5
+ separator?: string
3
6
  } & ({
4
7
  required?: boolean
5
8
  } | {
6
9
  default?: unknown
7
10
  })
8
11
 
9
- export type ValidationFunction = (wrapper: Wrapper, ...args: unknown[]) => string | string[] | void | null | undefined
12
+ export type PRulesFunction = (wrapper: PRulesWrapper, ...args: unknown[]) => string | string[] | void | null | undefined
10
13
 
11
- export type Wrapper<T = unknown> = {
14
+ export type PRulesWrapper<T = unknown> = {
12
15
  value: T
13
16
  label: string
14
17
  }
15
18
 
16
- export class RulesEngine {
17
- constructor(params?: RulesParams) {
18
- if (!params) return
19
- this.label = params.label
20
- this.required = 'required' in params ? params.required : false
21
- this.default = 'default' in params ? params.default : null
22
- }
19
+ export type PRulesResponse<T> = {
20
+ error: false
21
+ success: true
22
+ result: T
23
+ } | {
24
+ error: true
25
+ success: false
26
+ messages: string[]
27
+ }
23
28
 
29
+ export class PRulesEngine {
30
+ prefix: string
24
31
  label: string
32
+ separator: string
25
33
  required: boolean = false
26
34
  default: unknown = null
27
- collection: ValidationFunction[] = []
28
35
 
29
- protected add(name: string, validationFunction: ValidationFunction, executeOnce = false) {
30
- this.collection.push(validationFunction)
36
+ private collectionFunctions: PRulesFunction[] = []
37
+ private collectionNames: string[] = []
38
+
39
+ constructor(params?: PRulesParams) {
40
+ this.label = params?.label
41
+ this.separator = params?.separator ?? ' > '
42
+ this.required = params && 'required' in params ? params?.required : false
43
+ this.default = params && 'default' in params ? params?.default : null
44
+ }
45
+
46
+ protected add(name: string, validationFunction: PRulesFunction) {
47
+ if (!this.collectionNames.includes(name)) {
48
+ this.collectionNames.push(name)
49
+ this.collectionFunctions.push(validationFunction)
50
+ }
31
51
  return this
32
52
  }
53
+
54
+ validate = <T>(target: unknown): PRulesResponse<T> => {
55
+ const errorMessages: string[] = []
56
+
57
+ if (typeof target == 'string') target = target.trim()
58
+
59
+ const isEmpty = target == null || (typeof target == 'string' && !target)
60
+ const label = this.label
61
+
62
+ if (this.required && isEmpty) {
63
+ return {
64
+ error: true,
65
+ success: false,
66
+ messages: [`'${label}' es requerido`]
67
+ }
68
+ }
69
+
70
+ if (isEmpty) {
71
+ return {
72
+ error: false,
73
+ success: true,
74
+ result: this.default as T
75
+ }
76
+ }
77
+
78
+ const wrapper: PRulesWrapper<T> = {
79
+ value: PUtils.clone(target) as T,
80
+ label
81
+ }
82
+ for (const validationFunction of this.collectionFunctions) {
83
+ const result = validationFunction(wrapper)
84
+ if (!result) continue
85
+ if (typeof result == 'string') {
86
+ errorMessages.push(result)
87
+ break
88
+ } else {
89
+ errorMessages.push(...result)
90
+ }
91
+ }
92
+
93
+ if (errorMessages.length) {
94
+ return {
95
+ error: true,
96
+ success: false,
97
+ messages: errorMessages
98
+ }
99
+ } else {
100
+ return {
101
+ error: false,
102
+ success: true,
103
+ result: wrapper.value
104
+ }
105
+ }
106
+ }
33
107
  }
@@ -1,8 +1,8 @@
1
- import { rules, validate } from '../src/index'
1
+ import { rules } from '../src/index'
2
2
 
3
3
  const original = {
4
4
  uno: 'hola',
5
- dos: 1,
5
+ dos: 'er',
6
6
  tres: '67',
7
7
  cuatro: {
8
8
  aaa: '2024-10-28 23:56:00',
@@ -10,13 +10,15 @@ const original = {
10
10
  }
11
11
  }
12
12
 
13
- const resultados = validate(original, rules({ label: 'Mi número' }).isObject({
14
- uno: rules({ label: 'Uno', required: true }),
13
+ const otro = 56
14
+
15
+ const resultados = rules({ label: 'Body' }).isObject({
16
+ uno: rules({ label: 'Uno', required: true }).isNatural(),
15
17
  dos: rules().isBoolean(),
16
18
  tres: rules({ required: true }).isNaturalNoZero(),
17
19
  cuatro: rules({ label: 'Cuatro', default: {} }).isObject({
18
20
  aaa: rules().isDateTime()
19
21
  })
20
- }, `Mi número >`))
22
+ }).validate(original)
21
23
 
22
24
  console.log(original, resultados)
package/src/validate.ts DELETED
@@ -1,66 +0,0 @@
1
- import { PUtils } from "pols-utils"
2
- import { RulesEngine, Wrapper } from "./rulesEngine"
3
-
4
- export type EvaluateResponse<T> = {
5
- error: false
6
- success: true
7
- result: T
8
- } | {
9
- error: true
10
- success: false
11
- messages: string[]
12
- }
13
-
14
- export const validate = <T>(target: unknown, rules: RulesEngine): EvaluateResponse<T> => {
15
- const errorMessages: string[] = []
16
-
17
- if (typeof target == 'string') target = target.trim()
18
-
19
- const isEmpty = target == null || (typeof target == 'string' && !target)
20
- const label = rules.label ?? 'Este valor'
21
-
22
- if (rules.required && isEmpty) {
23
- return {
24
- error: true,
25
- success: false,
26
- messages: [`'${label}' es requerido`]
27
- }
28
- }
29
-
30
- if (isEmpty) {
31
- return {
32
- error: false,
33
- success: true,
34
- result: rules.default as T
35
- }
36
- }
37
-
38
- const wrapper: Wrapper<T> = {
39
- value: PUtils.clone(target) as T,
40
- label
41
- }
42
- for (const validationFunction of rules.collection) {
43
- const result = validationFunction(wrapper)
44
- if (!result) continue
45
- if (typeof result == 'string') {
46
- errorMessages.push(result)
47
- break
48
- } else {
49
- errorMessages.push(...result)
50
- }
51
- }
52
-
53
- if (errorMessages.length) {
54
- return {
55
- error: true,
56
- success: false,
57
- messages: errorMessages
58
- }
59
- } else {
60
- return {
61
- error: false,
62
- success: true,
63
- result: wrapper.value
64
- }
65
- }
66
- }