@itzworking/decorated-class 0.0.162 → 0.0.197

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.
Files changed (147) hide show
  1. package/{dist → dist-cjs}/decorators/attribute/attribute.js +0 -16
  2. package/{dist → dist-cjs}/decorators/attribute/types/attribute-type.js +0 -1
  3. package/{dist → dist-cjs}/decorators/attribute/utils/update-attributes.js +3 -2
  4. package/{dist → dist-cjs}/decorators/validation/utils/register-constraint.js +0 -56
  5. package/dist-cjs/types.js +2 -0
  6. package/{dist → dist-cjs}/validator/list-validation-errors.js +0 -1
  7. package/dist-es/decorated-class.js +77 -0
  8. package/dist-es/decorators/attribute/attribute.js +29 -0
  9. package/dist-es/decorators/attribute/index.js +4 -0
  10. package/dist-es/decorators/attribute/is-attribute.js +4 -0
  11. package/dist-es/decorators/attribute/list-attributes.js +11 -0
  12. package/dist-es/decorators/attribute/symbol.js +1 -0
  13. package/dist-es/decorators/attribute/types/attribute-decorator.js +1 -0
  14. package/dist-es/decorators/attribute/types/attribute-definition.js +1 -0
  15. package/dist-es/decorators/attribute/types/attribute-type-alias.js +2 -0
  16. package/dist-es/decorators/attribute/types/attribute-type.js +10 -0
  17. package/dist-es/decorators/attribute/types/index.js +5 -0
  18. package/dist-es/decorators/attribute/types/primitive-type.js +8 -0
  19. package/dist-es/decorators/attribute/utils/index.js +1 -0
  20. package/dist-es/decorators/attribute/utils/update-attributes.js +30 -0
  21. package/dist-es/decorators/index.js +4 -0
  22. package/dist-es/decorators/validation/index.js +7 -0
  23. package/dist-es/decorators/validation/max.js +17 -0
  24. package/dist-es/decorators/validation/min.js +17 -0
  25. package/dist-es/decorators/validation/not-blank.js +11 -0
  26. package/dist-es/decorators/validation/not-null.js +2 -0
  27. package/dist-es/decorators/validation/pattern.js +12 -0
  28. package/dist-es/decorators/validation/types/index.js +2 -0
  29. package/dist-es/decorators/validation/types/validation-definition.js +1 -0
  30. package/dist-es/decorators/validation/types/validation-type.js +1 -0
  31. package/dist-es/decorators/validation/utils/index.js +1 -0
  32. package/dist-es/decorators/validation/utils/register-constraint.js +43 -0
  33. package/dist-es/errors/attributes-not-valid-error.js +9 -0
  34. package/dist-es/errors/index.js +3 -0
  35. package/dist-es/errors/invalid-target-error.js +6 -0
  36. package/dist-es/errors/unsupported-decorator-error.js +15 -0
  37. package/dist-es/index.js +5 -0
  38. package/dist-es/types.js +1 -0
  39. package/dist-es/validator/index.js +1 -0
  40. package/dist-es/validator/list-validation-errors.js +49 -0
  41. package/dist-es/validator/validate.js +8 -0
  42. package/dist-es/validator/validator.js +6 -0
  43. package/{dist → dist-types}/decorated-class.d.ts +0 -1
  44. package/{dist → dist-types}/decorators/attribute/attribute.d.ts +0 -1
  45. package/{dist → dist-types}/decorators/attribute/index.d.ts +0 -1
  46. package/{dist → dist-types}/decorators/attribute/is-attribute.d.ts +0 -1
  47. package/{dist → dist-types}/decorators/attribute/list-attributes.d.ts +0 -1
  48. package/{dist → dist-types}/decorators/attribute/symbol.d.ts +0 -1
  49. package/{dist → dist-types}/decorators/attribute/types/attribute-decorator.d.ts +0 -1
  50. package/{dist → dist-types}/decorators/attribute/types/attribute-definition.d.ts +0 -1
  51. package/{dist → dist-types}/decorators/attribute/types/attribute-type-alias.d.ts +0 -1
  52. package/{dist → dist-types}/decorators/attribute/types/attribute-type.d.ts +0 -1
  53. package/{dist → dist-types}/decorators/attribute/types/index.d.ts +0 -1
  54. package/{dist → dist-types}/decorators/attribute/types/primitive-type.d.ts +0 -1
  55. package/{dist → dist-types}/decorators/attribute/utils/index.d.ts +0 -1
  56. package/{dist → dist-types}/decorators/attribute/utils/update-attributes.d.ts +0 -1
  57. package/{dist → dist-types}/decorators/index.d.ts +0 -1
  58. package/{dist → dist-types}/decorators/validation/index.d.ts +0 -1
  59. package/{dist → dist-types}/decorators/validation/max.d.ts +0 -1
  60. package/{dist → dist-types}/decorators/validation/min.d.ts +0 -1
  61. package/{dist → dist-types}/decorators/validation/not-blank.d.ts +0 -1
  62. package/{dist → dist-types}/decorators/validation/not-null.d.ts +0 -1
  63. package/{dist → dist-types}/decorators/validation/pattern.d.ts +0 -1
  64. package/{dist → dist-types}/decorators/validation/types/index.d.ts +0 -1
  65. package/{dist → dist-types}/decorators/validation/types/validation-definition.d.ts +0 -1
  66. package/{dist → dist-types}/decorators/validation/types/validation-type.d.ts +0 -1
  67. package/{dist → dist-types}/decorators/validation/utils/index.d.ts +0 -1
  68. package/{dist → dist-types}/decorators/validation/utils/register-constraint.d.ts +0 -1
  69. package/{dist → dist-types}/errors/attributes-not-valid-error.d.ts +0 -1
  70. package/{dist → dist-types}/errors/index.d.ts +0 -1
  71. package/{dist → dist-types}/errors/invalid-target-error.d.ts +0 -1
  72. package/{dist → dist-types}/errors/unsupported-decorator-error.d.ts +0 -1
  73. package/{dist → dist-types}/index.d.ts +0 -1
  74. package/{dist → dist-types}/types.d.ts +0 -1
  75. package/dist-types/validator/index.d.ts +1 -0
  76. package/{dist → dist-types}/validator/list-validation-errors.d.ts +0 -1
  77. package/{dist → dist-types}/validator/validate.d.ts +0 -1
  78. package/{dist → dist-types}/validator/validator.d.ts +0 -1
  79. package/package.json +21 -21
  80. package/dist/decorated-class.d.ts.map +0 -1
  81. package/dist/decorators/attribute/attribute.d.ts.map +0 -1
  82. package/dist/decorators/attribute/index.d.ts.map +0 -1
  83. package/dist/decorators/attribute/is-attribute.d.ts.map +0 -1
  84. package/dist/decorators/attribute/list-attributes.d.ts.map +0 -1
  85. package/dist/decorators/attribute/symbol.d.ts.map +0 -1
  86. package/dist/decorators/attribute/types/attribute-decorator.d.ts.map +0 -1
  87. package/dist/decorators/attribute/types/attribute-definition.d.ts.map +0 -1
  88. package/dist/decorators/attribute/types/attribute-type-alias.d.ts.map +0 -1
  89. package/dist/decorators/attribute/types/attribute-type.d.ts.map +0 -1
  90. package/dist/decorators/attribute/types/index.d.ts.map +0 -1
  91. package/dist/decorators/attribute/types/primitive-type.d.ts.map +0 -1
  92. package/dist/decorators/attribute/utils/index.d.ts.map +0 -1
  93. package/dist/decorators/attribute/utils/update-attributes.d.ts.map +0 -1
  94. package/dist/decorators/index.d.ts.map +0 -1
  95. package/dist/decorators/validation/index.d.ts.map +0 -1
  96. package/dist/decorators/validation/max.d.ts.map +0 -1
  97. package/dist/decorators/validation/min.d.ts.map +0 -1
  98. package/dist/decorators/validation/not-blank.d.ts.map +0 -1
  99. package/dist/decorators/validation/not-null.d.ts.map +0 -1
  100. package/dist/decorators/validation/pattern.d.ts.map +0 -1
  101. package/dist/decorators/validation/types/index.d.ts.map +0 -1
  102. package/dist/decorators/validation/types/validation-definition.d.ts.map +0 -1
  103. package/dist/decorators/validation/types/validation-type.d.ts.map +0 -1
  104. package/dist/decorators/validation/utils/index.d.ts.map +0 -1
  105. package/dist/decorators/validation/utils/register-constraint.d.ts.map +0 -1
  106. package/dist/errors/attributes-not-valid-error.d.ts.map +0 -1
  107. package/dist/errors/index.d.ts.map +0 -1
  108. package/dist/errors/invalid-target-error.d.ts.map +0 -1
  109. package/dist/errors/unsupported-decorator-error.d.ts.map +0 -1
  110. package/dist/index.d.ts.map +0 -1
  111. package/dist/types.d.ts.map +0 -1
  112. package/dist/types.js +0 -3
  113. package/dist/validator/index.d.ts +0 -2
  114. package/dist/validator/index.d.ts.map +0 -1
  115. package/dist/validator/list-validation-errors.d.ts.map +0 -1
  116. package/dist/validator/validate.d.ts.map +0 -1
  117. package/dist/validator/validator.d.ts.map +0 -1
  118. /package/{dist → dist-cjs}/decorated-class.js +0 -0
  119. /package/{dist → dist-cjs}/decorators/attribute/index.js +0 -0
  120. /package/{dist → dist-cjs}/decorators/attribute/is-attribute.js +0 -0
  121. /package/{dist → dist-cjs}/decorators/attribute/list-attributes.js +0 -0
  122. /package/{dist → dist-cjs}/decorators/attribute/symbol.js +0 -0
  123. /package/{dist → dist-cjs}/decorators/attribute/types/attribute-decorator.js +0 -0
  124. /package/{dist → dist-cjs}/decorators/attribute/types/attribute-definition.js +0 -0
  125. /package/{dist → dist-cjs}/decorators/attribute/types/attribute-type-alias.js +0 -0
  126. /package/{dist → dist-cjs}/decorators/attribute/types/index.js +0 -0
  127. /package/{dist → dist-cjs}/decorators/attribute/types/primitive-type.js +0 -0
  128. /package/{dist → dist-cjs}/decorators/attribute/utils/index.js +0 -0
  129. /package/{dist → dist-cjs}/decorators/index.js +0 -0
  130. /package/{dist → dist-cjs}/decorators/validation/index.js +0 -0
  131. /package/{dist → dist-cjs}/decorators/validation/max.js +0 -0
  132. /package/{dist → dist-cjs}/decorators/validation/min.js +0 -0
  133. /package/{dist → dist-cjs}/decorators/validation/not-blank.js +0 -0
  134. /package/{dist → dist-cjs}/decorators/validation/not-null.js +0 -0
  135. /package/{dist → dist-cjs}/decorators/validation/pattern.js +0 -0
  136. /package/{dist → dist-cjs}/decorators/validation/types/index.js +0 -0
  137. /package/{dist → dist-cjs}/decorators/validation/types/validation-definition.js +0 -0
  138. /package/{dist → dist-cjs}/decorators/validation/types/validation-type.js +0 -0
  139. /package/{dist → dist-cjs}/decorators/validation/utils/index.js +0 -0
  140. /package/{dist → dist-cjs}/errors/attributes-not-valid-error.js +0 -0
  141. /package/{dist → dist-cjs}/errors/index.js +0 -0
  142. /package/{dist → dist-cjs}/errors/invalid-target-error.js +0 -0
  143. /package/{dist → dist-cjs}/errors/unsupported-decorator-error.js +0 -0
  144. /package/{dist → dist-cjs}/index.js +0 -0
  145. /package/{dist → dist-cjs}/validator/index.js +0 -0
  146. /package/{dist → dist-cjs}/validator/validate.js +0 -0
  147. /package/{dist → dist-cjs}/validator/validator.js +0 -0
@@ -31,19 +31,3 @@ const Attribute = (attributeType, options = {}) => {
31
31
  return (0, utils_1.updateAttributes)(attributeType, isValidType, options);
32
32
  };
33
33
  exports.Attribute = Attribute;
34
- // export const OldAttribute = {
35
- // List: (type: PrimitiveType | any) =>
36
- // updateAttributes(
37
- // "List",
38
- // (value: any) =>
39
- // value === undefined || value === null || Array.isArray(value),
40
- // type
41
- // ),
42
- // Object: (type: any) =>
43
- // updateAttributes(
44
- // "Object",
45
- // (value: any) =>
46
- // value === undefined || value === null || typeof value === type,
47
- // type
48
- // ),
49
- // };
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AttributeType = void 0;
4
- const primitive_type_1 = require("./primitive-type");
5
4
  var AttributeType;
6
5
  (function (AttributeType) {
7
6
  AttributeType["String"] = "String";
@@ -4,6 +4,9 @@ exports.updateAttributes = void 0;
4
4
  require("reflect-metadata");
5
5
  const symbol_1 = require("../symbol");
6
6
  const updateAttributes = (attributeType, isValidType, options = {}) => (target, context) => {
7
+ if (!target) {
8
+ return;
9
+ }
7
10
  const attributes = Reflect.getOwnMetadata(symbol_1.symbol, target) || [];
8
11
  const attributeName = typeof context === "string" ? context : context.name;
9
12
  let currentAttribute = attributes.find((attribute) => attribute.attributeName === attributeName);
@@ -15,7 +18,6 @@ const updateAttributes = (attributeType, isValidType, options = {}) => (target,
15
18
  attributeName,
16
19
  attributeType,
17
20
  constraints: [],
18
- // isMethod: typeof target[attributeName] === "function",
19
21
  nestedType: options?.nestedType,
20
22
  isValidTypeInTarget,
21
23
  };
@@ -23,7 +25,6 @@ const updateAttributes = (attributeType, isValidType, options = {}) => (target,
23
25
  }
24
26
  else {
25
27
  currentAttribute.attributeType = attributeType;
26
- // currentAttribute.isMethod = typeof target[attributeName] === "function";
27
28
  currentAttribute.nestedType = options?.nestedType;
28
29
  currentAttribute.isValidTypeInTarget = isValidTypeInTarget;
29
30
  }
@@ -3,34 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerConstraint = exports.registerConstraintWithoutProps = exports.registerConstraintWithProps = void 0;
4
4
  const symbol_1 = require("../../attribute/symbol");
5
5
  const errors_1 = require("../../../errors");
6
- /**
7
- * Registers a constraint validator with properties.
8
- *
9
- * This utility function allows the creation and registration of a constraint validator
10
- * that takes a parameter, such as @Max(5), which can be applied as a decorator on a class attribute.
11
- *
12
- * @param constraintId - A unique identifier for the constraint. This ID will be used to reference
13
- * the constraint validator when validating properties.
14
- * @param constraintValidator - The constraint validator function that validates the property based
15
- * on the given parameter. It returns a function that accepts the property
16
- * value and performs the validation.
17
- *
18
- * @example
19
- * ```typescript
20
- * // Register the constraint validator with a unique ID
21
- * const Max = registerConstraintWithProps(
22
- * "Max",
23
- * (max: number) => (value: any) => typeof value === "number" && value <= max
24
- * );
25
- *
26
- * // Use the constraint as a decorator on a class attribute
27
- * class ExampleClass {
28
- * @Attribute(AttributeType.Integer)
29
- * @Max(5)
30
- * numberValue: number;
31
- * }
32
- * ```
33
- */
34
6
  const registerConstraintWithProps = (constraintId, constraintValidator) => {
35
7
  return (props) => (target, context) => {
36
8
  const attributes = Reflect.getOwnMetadata(symbol_1.symbol, target) || [];
@@ -69,34 +41,6 @@ const registerConstraintWithProps = (constraintId, constraintValidator) => {
69
41
  };
70
42
  };
71
43
  exports.registerConstraintWithProps = registerConstraintWithProps;
72
- /**
73
- * Registers a constraint validator without properties.
74
- *
75
- * This utility function allows the creation and registration of a constraint validator
76
- * that does not take any parameters, such as @NotBlank, which can be applied as a decorator
77
- * on a class attribute.
78
- *
79
- * @param constraintId - A unique identifier for the constraint. This ID will be used to reference
80
- * the constraint validator when validating properties.
81
- * @param constraintValidator - The constraint validator function that validates the property without
82
- * any parameters. It accepts only the property value.
83
- *
84
- * @example
85
- * ```typescript
86
- * // Register the constraint validator with a unique ID
87
- * const NotBlank = registerConstraintWithoutProps(
88
- * 'NotBlank',
89
- * (value: any) => typeof value === 'string' && value.trim().length > 0
90
- * );
91
- *
92
- * // Use the constraint as a decorator on a class attribute
93
- * class ExampleClass {
94
- * @Attribute(AttributeType.String)
95
- * @NotBlank
96
- * textValue: string;
97
- * }
98
- * ```
99
- */
100
44
  const registerConstraintWithoutProps = (constraintId, constraintValidator) => {
101
45
  return (0, exports.registerConstraintWithProps)(constraintId, () => constraintValidator)();
102
46
  };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -15,7 +15,6 @@ const listValidationErrors = (target) => {
15
15
  validations.push({
16
16
  attributeName: attribute.attributeName,
17
17
  constraintId: "AttributeTypeIsDefined",
18
- // constraintProps: "",
19
18
  message: `${attribute.attributeName} has no @Attribute(AttributeType) defined`,
20
19
  });
21
20
  continue;
@@ -0,0 +1,77 @@
1
+ import { AttributeType, listAttributes, PrimitiveType } from "./decorators";
2
+ const parseBoolean = (value) => {
3
+ switch (value) {
4
+ case true:
5
+ case "true":
6
+ case 1:
7
+ case "1":
8
+ case "on":
9
+ case "yes":
10
+ return true;
11
+ case false:
12
+ case "false":
13
+ case 0:
14
+ case "0":
15
+ case "off":
16
+ case "no":
17
+ return false;
18
+ default:
19
+ return undefined;
20
+ }
21
+ };
22
+ const isPrimitiveType = (type) => {
23
+ return Object.values(PrimitiveType).includes(type);
24
+ };
25
+ const parseType = (value, type, nestedType) => {
26
+ if (type === AttributeType.Float) {
27
+ return parseFloat(value);
28
+ }
29
+ if (type === AttributeType.Integer) {
30
+ return parseInt(value);
31
+ }
32
+ if (type === AttributeType.Boolean) {
33
+ return parseBoolean(value);
34
+ }
35
+ if (type === AttributeType.Date) {
36
+ return new Date(value);
37
+ }
38
+ if (type === AttributeType.Object &&
39
+ nestedType &&
40
+ nestedType.prototype instanceof DecoratedClass) {
41
+ return new nestedType(value);
42
+ }
43
+ if (type === AttributeType.List) {
44
+ if (!value || !Array.isArray(value)) {
45
+ return undefined;
46
+ }
47
+ if (nestedType) {
48
+ if (isPrimitiveType(nestedType)) {
49
+ return value.map((item) => parseType(item, nestedType));
50
+ }
51
+ else if (nestedType.prototype instanceof DecoratedClass) {
52
+ return value.map((item) => parseType(item, AttributeType.Object, nestedType));
53
+ }
54
+ }
55
+ }
56
+ return value;
57
+ };
58
+ export class DecoratedClass {
59
+ constructor(props = {}) {
60
+ if (!props) {
61
+ return;
62
+ }
63
+ const attributes = listAttributes(this);
64
+ const self = this;
65
+ for (const attribute of attributes) {
66
+ const { attributeName: key, attributeType, nestedType } = attribute;
67
+ if (self[key] !== undefined || props[key] === undefined) {
68
+ continue;
69
+ }
70
+ const value = parseType(props[key], attributeType, nestedType);
71
+ if (value === undefined) {
72
+ continue;
73
+ }
74
+ self[key] = value;
75
+ }
76
+ }
77
+ }
@@ -0,0 +1,29 @@
1
+ import { updateAttributes } from "./utils";
2
+ import { AttributeType } from "./types";
3
+ export const Attribute = (attributeType, options = {}) => {
4
+ let isValidType = () => true;
5
+ if (attributeType === AttributeType.String) {
6
+ isValidType = (value) => value === undefined || value === null || typeof value === "string";
7
+ }
8
+ else if (attributeType === AttributeType.Integer) {
9
+ isValidType = (value) => value === undefined ||
10
+ value === null ||
11
+ (Number(value) === value && value % 1 === 0);
12
+ }
13
+ else if (attributeType === AttributeType.Float) {
14
+ isValidType = (value) => value === undefined || value === null || Number(value) === value;
15
+ }
16
+ else if (attributeType === AttributeType.Boolean) {
17
+ isValidType = (value) => value === undefined || value === null || typeof value === "boolean";
18
+ }
19
+ else if (attributeType === AttributeType.Date) {
20
+ isValidType = (value) => value === undefined || value === null || value instanceof Date;
21
+ }
22
+ else if (attributeType === AttributeType.List) {
23
+ isValidType = (value) => value === undefined || value === null || Array.isArray(value);
24
+ }
25
+ else if (attributeType === AttributeType.Object) {
26
+ isValidType = (value) => value === undefined || value === null || typeof value === "object";
27
+ }
28
+ return updateAttributes(attributeType, isValidType, options);
29
+ };
@@ -0,0 +1,4 @@
1
+ export * from "./types";
2
+ export * from "./attribute";
3
+ export * from "./is-attribute";
4
+ export * from "./list-attributes";
@@ -0,0 +1,4 @@
1
+ import { symbol } from "./symbol";
2
+ export const isAttribute = (target, propertyKey) => {
3
+ return !!Reflect.getMetadata(symbol, target, propertyKey);
4
+ };
@@ -0,0 +1,11 @@
1
+ import { symbol } from "./symbol";
2
+ export const listAttributes = (target) => {
3
+ let attributes = [];
4
+ let targetToUse = Object.getPrototypeOf(target);
5
+ while (targetToUse && targetToUse !== Object.prototype) {
6
+ const parentAttributes = Reflect.getOwnMetadata(symbol, targetToUse) || [];
7
+ attributes = [...parentAttributes, ...attributes];
8
+ targetToUse = Object.getPrototypeOf(targetToUse);
9
+ }
10
+ return attributes;
11
+ };
@@ -0,0 +1 @@
1
+ export const symbol = Symbol("itw_attribute");
@@ -0,0 +1,2 @@
1
+ import { AttributeType as AT } from "./attribute-type";
2
+ export { AT };
@@ -0,0 +1,10 @@
1
+ export var AttributeType;
2
+ (function (AttributeType) {
3
+ AttributeType["String"] = "String";
4
+ AttributeType["Float"] = "Float";
5
+ AttributeType["Integer"] = "Integer";
6
+ AttributeType["Boolean"] = "Boolean";
7
+ AttributeType["Date"] = "Date";
8
+ AttributeType["List"] = "List";
9
+ AttributeType["Object"] = "Object";
10
+ })(AttributeType || (AttributeType = {}));
@@ -0,0 +1,5 @@
1
+ export * from "./attribute-decorator";
2
+ export * from "./attribute-definition";
3
+ export * from "./attribute-type";
4
+ export * from "./attribute-type-alias";
5
+ export * from "./primitive-type";
@@ -0,0 +1,8 @@
1
+ export var PrimitiveType;
2
+ (function (PrimitiveType) {
3
+ PrimitiveType["String"] = "String";
4
+ PrimitiveType["Integer"] = "Integer";
5
+ PrimitiveType["Float"] = "Float";
6
+ PrimitiveType["Boolean"] = "Boolean";
7
+ PrimitiveType["Date"] = "Date";
8
+ })(PrimitiveType || (PrimitiveType = {}));
@@ -0,0 +1 @@
1
+ export * from "./update-attributes";
@@ -0,0 +1,30 @@
1
+ import "reflect-metadata";
2
+ import { symbol } from "../symbol";
3
+ export const updateAttributes = (attributeType, isValidType, options = {}) => (target, context) => {
4
+ if (!target) {
5
+ return;
6
+ }
7
+ const attributes = Reflect.getOwnMetadata(symbol, target) || [];
8
+ const attributeName = typeof context === "string" ? context : context.name;
9
+ let currentAttribute = attributes.find((attribute) => attribute.attributeName === attributeName);
10
+ const isValidTypeInTarget = (target) => isValidType(typeof target[attributeName] === "function"
11
+ ? target[attributeName]()
12
+ : target[attributeName]);
13
+ if (!currentAttribute) {
14
+ currentAttribute = {
15
+ attributeName,
16
+ attributeType,
17
+ constraints: [],
18
+ nestedType: options?.nestedType,
19
+ isValidTypeInTarget,
20
+ };
21
+ attributes.push(currentAttribute);
22
+ }
23
+ else {
24
+ currentAttribute.attributeType = attributeType;
25
+ currentAttribute.nestedType = options?.nestedType;
26
+ currentAttribute.isValidTypeInTarget = isValidTypeInTarget;
27
+ }
28
+ Reflect.defineMetadata(symbol, attributes, target);
29
+ Reflect.defineMetadata(symbol, currentAttribute, target, attributeName);
30
+ };
@@ -0,0 +1,4 @@
1
+ import "reflect-metadata";
2
+ export * from "./attribute";
3
+ export * from "./attribute/types/primitive-type";
4
+ export * from "./validation";
@@ -0,0 +1,7 @@
1
+ export * from "./types";
2
+ export * from "./utils";
3
+ export * from "./max";
4
+ export * from "./min";
5
+ export * from "./not-blank";
6
+ export * from "./not-null";
7
+ export * from "./pattern";
@@ -0,0 +1,17 @@
1
+ import { registerConstraintWithProps } from "./utils";
2
+ import { UnsupportedDecoratorError } from "../../errors";
3
+ export const Max = registerConstraintWithProps("Max", (max) => (value) => {
4
+ if (value === null || value === undefined) {
5
+ return true;
6
+ }
7
+ if (typeof value === "string") {
8
+ return value.length <= max;
9
+ }
10
+ if (typeof value === "number") {
11
+ return value <= max;
12
+ }
13
+ if (Array.isArray(value)) {
14
+ return value.length <= max;
15
+ }
16
+ throw new UnsupportedDecoratorError();
17
+ });
@@ -0,0 +1,17 @@
1
+ import { registerConstraintWithProps } from "./utils";
2
+ import { UnsupportedDecoratorError } from "../../errors";
3
+ export const Min = registerConstraintWithProps("Min", (min) => (value) => {
4
+ if (value === null || value === undefined) {
5
+ return true;
6
+ }
7
+ if (typeof value === "string") {
8
+ return value.length >= min;
9
+ }
10
+ if (typeof value === "number") {
11
+ return value >= min;
12
+ }
13
+ if (Array.isArray(value)) {
14
+ return value.length >= min;
15
+ }
16
+ throw new UnsupportedDecoratorError();
17
+ });
@@ -0,0 +1,11 @@
1
+ import { registerConstraintWithoutProps } from "./utils";
2
+ import { UnsupportedDecoratorError } from "../../errors";
3
+ export const NotBlank = registerConstraintWithoutProps("NotBlank", (value) => {
4
+ if (value === null || value === undefined) {
5
+ return true;
6
+ }
7
+ if (typeof value !== "string") {
8
+ throw new UnsupportedDecoratorError();
9
+ }
10
+ return value.trim().length > 0;
11
+ });
@@ -0,0 +1,2 @@
1
+ import { registerConstraintWithoutProps } from "./utils";
2
+ export const NotNull = registerConstraintWithoutProps("NotNull", (value) => value !== null && value !== undefined);
@@ -0,0 +1,12 @@
1
+ import { registerConstraintWithProps } from "./utils";
2
+ import { UnsupportedDecoratorError } from "../../errors";
3
+ export const Pattern = registerConstraintWithProps("Pattern", (pattern) => (value) => {
4
+ if (value === null || value === undefined) {
5
+ return true;
6
+ }
7
+ if (typeof value !== "string") {
8
+ throw new UnsupportedDecoratorError();
9
+ }
10
+ const r = value.match(pattern);
11
+ return !!r && r.length > 0;
12
+ });
@@ -0,0 +1,2 @@
1
+ export * from "./validation-definition";
2
+ export * from "./validation-type";
@@ -0,0 +1 @@
1
+ export * from "./register-constraint";
@@ -0,0 +1,43 @@
1
+ import { symbol } from "../../attribute/symbol";
2
+ import { UnsupportedDecoratorError } from "../../../errors";
3
+ export const registerConstraintWithProps = (constraintId, constraintValidator) => {
4
+ return (props) => (target, context) => {
5
+ const attributes = Reflect.getOwnMetadata(symbol, target) || [];
6
+ const attributeName = typeof context === "string" ? context : context.name;
7
+ let currentAttribute = attributes.find((attribute) => attribute.attributeName === attributeName);
8
+ const constraint = {
9
+ constraintId,
10
+ isValid: (target) => {
11
+ try {
12
+ return constraintValidator(props)(typeof target[attributeName] === "function"
13
+ ? target[attributeName]()
14
+ : target[attributeName], target);
15
+ }
16
+ catch (e) {
17
+ if (e instanceof UnsupportedDecoratorError) {
18
+ e.setErrorProps(constraintId, `${target.constructor.name}.${attributeName}`, typeof target[attributeName]);
19
+ }
20
+ throw e;
21
+ }
22
+ },
23
+ constraintProps: props,
24
+ };
25
+ if (!currentAttribute) {
26
+ currentAttribute = {
27
+ attributeName,
28
+ constraints: [constraint],
29
+ isValidTypeInTarget: () => false,
30
+ };
31
+ attributes.push(currentAttribute);
32
+ }
33
+ else {
34
+ currentAttribute.constraints.push(constraint);
35
+ }
36
+ Reflect.defineMetadata(symbol, attributes, target);
37
+ Reflect.defineMetadata(symbol, currentAttribute, target, attributeName);
38
+ };
39
+ };
40
+ export const registerConstraintWithoutProps = (constraintId, constraintValidator) => {
41
+ return registerConstraintWithProps(constraintId, () => constraintValidator)();
42
+ };
43
+ export const registerConstraint = registerConstraintWithoutProps;
@@ -0,0 +1,9 @@
1
+ export class AttributesNotValidError extends Error {
2
+ validations;
3
+ constructor(validations) {
4
+ super(validations.map((error) => error.message).join(", "));
5
+ this.name = "AttributesNotValidError";
6
+ this.validations = validations;
7
+ Object.setPrototypeOf(this, AttributesNotValidError.prototype);
8
+ }
9
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./attributes-not-valid-error";
2
+ export * from "./invalid-target-error";
3
+ export * from "./unsupported-decorator-error";
@@ -0,0 +1,6 @@
1
+ export class InvalidTargetError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "InvalidTargetError";
5
+ }
6
+ }
@@ -0,0 +1,15 @@
1
+ export class UnsupportedDecoratorError extends Error {
2
+ decorator;
3
+ attributePath;
4
+ attributeType;
5
+ constructor() {
6
+ super("UnsupportedDecoratorError");
7
+ this.name = "UnsupportedDecoratorError";
8
+ }
9
+ setErrorProps(decorator, attributePath, attributeType) {
10
+ this.decorator = decorator;
11
+ this.attributePath = attributePath;
12
+ this.attributeType = attributeType;
13
+ this.message = `@${decorator} is not supported for ${attributePath}`;
14
+ }
15
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./types";
2
+ export * from "./decorators";
3
+ export * from "./errors";
4
+ export * from "./validator";
5
+ export * from "./decorated-class";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export * from "./validator";
@@ -0,0 +1,49 @@
1
+ import { listAttributes } from "../decorators/attribute";
2
+ import { InvalidTargetError } from "../errors";
3
+ import { DecoratedClass } from "../decorated-class";
4
+ export const listValidationErrors = (target) => {
5
+ if (!target) {
6
+ throw new InvalidTargetError("Target is not defined");
7
+ }
8
+ const attributes = listAttributes(target);
9
+ const validations = [];
10
+ for (const attribute of attributes) {
11
+ if (!attribute.attributeType) {
12
+ validations.push({
13
+ attributeName: attribute.attributeName,
14
+ constraintId: "AttributeTypeIsDefined",
15
+ message: `${attribute.attributeName} has no @Attribute(AttributeType) defined`,
16
+ });
17
+ continue;
18
+ }
19
+ if (!attribute.isValidTypeInTarget(target)) {
20
+ const attributeToUse = attribute.attributeType === "Object" && attribute.nestedType
21
+ ? attribute.nestedType
22
+ : attribute.attributeType;
23
+ validations.push({
24
+ attributeName: attribute.attributeName,
25
+ constraintId: "CorrectAttributeType",
26
+ constraintProps: attributeToUse,
27
+ message: `${attribute.attributeName} is not of type ${attributeToUse}`,
28
+ });
29
+ continue;
30
+ }
31
+ if (attribute.attributeType === "Object" &&
32
+ attribute.nestedType &&
33
+ attribute.nestedType.prototype instanceof DecoratedClass &&
34
+ target[attribute.attributeName]) {
35
+ validations.push(...listValidationErrors(target[attribute.attributeName]));
36
+ }
37
+ for (const validation of attribute.constraints) {
38
+ if (!validation.isValid(target)) {
39
+ validations.push({
40
+ attributeName: attribute.attributeName,
41
+ constraintId: validation.constraintId,
42
+ constraintProps: validation.constraintProps,
43
+ message: `Attribute ${attribute.attributeName} is not valid`,
44
+ });
45
+ }
46
+ }
47
+ }
48
+ return validations;
49
+ };
@@ -0,0 +1,8 @@
1
+ import { AttributesNotValidError } from "../errors";
2
+ import { listValidationErrors } from "./list-validation-errors";
3
+ export const validate = (target) => {
4
+ const validations = listValidationErrors(target);
5
+ if (validations.length) {
6
+ throw new AttributesNotValidError(validations);
7
+ }
8
+ };
@@ -0,0 +1,6 @@
1
+ import { validate } from "./validate";
2
+ import { listValidationErrors } from "./list-validation-errors";
3
+ export const validator = {
4
+ validate: (target) => validate(target),
5
+ listValidationErrors: (target) => listValidationErrors(target),
6
+ };
@@ -2,4 +2,3 @@ export type DecoratedClassConstructorProps = any;
2
2
  export declare abstract class DecoratedClass {
3
3
  protected constructor(props?: DecoratedClassConstructorProps);
4
4
  }
5
- //# sourceMappingURL=decorated-class.d.ts.map
@@ -3,4 +3,3 @@ import { DecoratedClass } from "../../decorated-class";
3
3
  export declare const Attribute: (attributeType: AttributeType, options?: {
4
4
  nestedType?: PrimitiveType | DecoratedClass | any;
5
5
  }) => import("./types").AttributeDecorator;
6
- //# sourceMappingURL=attribute.d.ts.map
@@ -2,4 +2,3 @@ export * from "./types";
2
2
  export * from "./attribute";
3
3
  export * from "./is-attribute";
4
4
  export * from "./list-attributes";
5
- //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1 @@
1
1
  export declare const isAttribute: (target: any, propertyKey: string) => boolean;
2
- //# sourceMappingURL=is-attribute.d.ts.map
@@ -1,3 +1,2 @@
1
1
  import { AttributeDefinition } from "./types";
2
2
  export declare const listAttributes: (target: any) => AttributeDefinition[];
3
- //# sourceMappingURL=list-attributes.d.ts.map
@@ -1,2 +1 @@
1
1
  export declare const symbol: unique symbol;
2
- //# sourceMappingURL=symbol.d.ts.map