@e22m4u/js-repository 0.1.2 → 0.1.3

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 (107) hide show
  1. package/.husky/commit-msg +1 -4
  2. package/.husky/pre-commit +0 -3
  3. package/README.md +2 -2
  4. package/docs/classes/Adapter.html +14 -14
  5. package/docs/classes/AdapterLoader.html +2 -2
  6. package/docs/classes/AdapterRegistry.html +2 -2
  7. package/docs/classes/BelongsToResolver.html +3 -3
  8. package/docs/classes/DatasourceDefinitionValidator.html +2 -2
  9. package/docs/classes/DefinitionRegistry.html +7 -7
  10. package/docs/classes/FieldsClauseTool.html +4 -4
  11. package/docs/classes/HasManyResolver.html +4 -4
  12. package/docs/classes/HasOneResolver.html +4 -4
  13. package/docs/classes/IncludeClauseTool.html +6 -6
  14. package/docs/classes/InvalidArgumentError.html +1 -1
  15. package/docs/classes/InvalidOperatorValueError.html +2 -2
  16. package/docs/classes/ModelDataSanitizer.html +2 -2
  17. package/docs/classes/ModelDataValidator.html +3 -3
  18. package/docs/classes/ModelDefinitionUtils.html +17 -17
  19. package/docs/classes/ModelDefinitionValidator.html +2 -2
  20. package/docs/classes/NotImplementedError.html +1 -1
  21. package/docs/classes/OperatorClauseTool.html +14 -14
  22. package/docs/classes/OrderClauseTool.html +4 -4
  23. package/docs/classes/PrimaryKeysDefinitionValidator.html +2 -2
  24. package/docs/classes/PropertiesDefinitionValidator.html +2 -2
  25. package/docs/classes/ReferencesManyResolver.html +2 -2
  26. package/docs/classes/RelationsDefinitionValidator.html +2 -2
  27. package/docs/classes/Repository.html +17 -17
  28. package/docs/classes/RepositoryRegistry.html +3 -3
  29. package/docs/classes/Schema.html +4 -4
  30. package/docs/classes/SliceClauseTool.html +4 -4
  31. package/docs/classes/WhereClauseTool.html +3 -3
  32. package/docs/enums/DataType.html +2 -2
  33. package/docs/enums/DecoratorTargetType.html +2 -2
  34. package/docs/enums/RelationType.html +2 -2
  35. package/docs/functions/capitalize.html +1 -1
  36. package/docs/functions/cloneDeep.html +1 -1
  37. package/docs/functions/excludeObjectKeys.html +1 -1
  38. package/docs/functions/getCtorName.html +1 -1
  39. package/docs/functions/getDecoratorTargetType.html +1 -1
  40. package/docs/functions/getValueByPath.html +1 -1
  41. package/docs/functions/isCtor.html +1 -1
  42. package/docs/functions/isPureObject.html +1 -1
  43. package/docs/functions/selectObjectKeys.html +1 -1
  44. package/docs/functions/singularize.html +1 -1
  45. package/docs/functions/stringToRegexp.html +1 -1
  46. package/docs/index.html +2 -2
  47. package/docs/interfaces/AndClause.html +2 -2
  48. package/docs/interfaces/Constructor.html +2 -2
  49. package/docs/interfaces/OrClause.html +2 -2
  50. package/docs/types/AnyObject.html +1 -1
  51. package/docs/types/BelongsToDefinition.html +1 -1
  52. package/docs/types/DEFAULT_PRIMARY_KEY_PROPERTY_NAME.html +1 -1
  53. package/docs/types/DatasourceDefinition.html +1 -1
  54. package/docs/types/FieldsClause.html +1 -1
  55. package/docs/types/FilterClause.html +1 -1
  56. package/docs/types/Flatten.html +1 -1
  57. package/docs/types/FullPropertyDefinition.html +1 -1
  58. package/docs/types/HasManyDefinition.html +1 -1
  59. package/docs/types/HasOneDefinition.html +1 -1
  60. package/docs/types/Identity.html +1 -1
  61. package/docs/types/IncludeClause.html +1 -1
  62. package/docs/types/ItemFilterClause.html +1 -1
  63. package/docs/types/ModelData.html +1 -1
  64. package/docs/types/ModelDefinition.html +1 -1
  65. package/docs/types/ModelId.html +1 -1
  66. package/docs/types/NestedIncludeClause.html +1 -1
  67. package/docs/types/NormalizedFieldsClause.html +1 -1
  68. package/docs/types/NormalizedIncludeClause.html +1 -1
  69. package/docs/types/OperatorClause.html +1 -1
  70. package/docs/types/OptionalUnlessRequiredId.html +1 -1
  71. package/docs/types/OrderClause.html +1 -1
  72. package/docs/types/PartialBy.html +1 -1
  73. package/docs/types/PartialWithoutId.html +1 -1
  74. package/docs/types/PolyBelongsToDefinition.html +1 -1
  75. package/docs/types/PolyHasManyDefinitionWithTargetKeys.html +1 -1
  76. package/docs/types/PolyHasManyDefinitionWithTargetRelationName.html +1 -1
  77. package/docs/types/PolyHasOneDefinitionWithTargetKeys.html +1 -1
  78. package/docs/types/PolyHasOneDefinitionWithTargetRelationName.html +1 -1
  79. package/docs/types/PropertiesClause.html +1 -1
  80. package/docs/types/PropertyDefinition.html +1 -1
  81. package/docs/types/PropertyDefinitionMap.html +1 -1
  82. package/docs/types/ReferencesManyDefinition.html +1 -1
  83. package/docs/types/RelationDefinition.html +1 -1
  84. package/docs/types/RelationDefinitionMap.html +1 -1
  85. package/docs/types/WhereClause.html +1 -1
  86. package/docs/types/WithoutId.html +1 -1
  87. package/package.json +20 -21
  88. package/src/adapter/decorator/data-validation-decorator.js +18 -10
  89. package/src/adapter/decorator/data-validation-decorator.spec.js +40 -0
  90. package/src/definition/model/model-data-validator.d.ts +4 -16
  91. package/src/definition/model/model-data-validator.js +92 -11
  92. package/src/definition/model/model-data-validator.spec.js +1140 -442
  93. package/src/definition/model/properties/index.d.ts +1 -0
  94. package/src/definition/model/properties/index.js +1 -0
  95. package/src/definition/model/properties/properties-definition-validator.js +47 -0
  96. package/src/definition/model/properties/properties-definition-validator.spec.js +50 -0
  97. package/src/definition/model/properties/property-definition.d.ts +2 -0
  98. package/src/definition/model/properties/property-validator/index.d.ts +2 -0
  99. package/src/definition/model/properties/property-validator/index.js +2 -0
  100. package/src/definition/model/properties/property-validator/property-validator-registry.d.ts +29 -0
  101. package/src/definition/model/properties/property-validator/property-validator-registry.js +69 -0
  102. package/src/definition/model/properties/property-validator/property-validator-registry.spec.js +120 -0
  103. package/src/definition/model/properties/property-validator/property-validator.d.ts +30 -0
  104. package/src/definition/model/properties/property-validator/property-validator.js +1 -0
  105. package/src/schema.d.ts +9 -0
  106. package/src/schema.js +13 -0
  107. package/src/schema.spec.ts +44 -0
@@ -1,4 +1,5 @@
1
1
  export * from './data-type.js';
2
2
  export * from './property-definition.js';
3
+ export * from './property-validator/index.js';
3
4
  export * from './properties-definition-validator.js';
4
5
  export * from './primary-keys-definition-validator.js';
@@ -1,4 +1,5 @@
1
1
  export * from './data-type.js';
2
2
  export * from './property-definition.js';
3
+ export * from './property-validator/index.js';
3
4
  export * from './properties-definition-validator.js';
4
5
  export * from './primary-keys-definition-validator.js';
@@ -2,6 +2,7 @@ import {Service} from '@e22m4u/js-service';
2
2
  import {DataType as Type} from './data-type.js';
3
3
  import {capitalize} from '../../../utils/index.js';
4
4
  import {InvalidArgumentError} from '../../../errors/index.js';
5
+ import {PropertyValidatorRegistry} from './property-validator/index.js';
5
6
  import {PrimaryKeysDefinitionValidator} from './primary-keys-definition-validator.js';
6
7
 
7
8
  /**
@@ -203,5 +204,51 @@ export class PropertiesDefinitionValidator extends Service {
203
204
  );
204
205
  }
205
206
  }
207
+ if (propDef.validate != null) {
208
+ const propertyValidatorRegistry = this.getService(
209
+ PropertyValidatorRegistry,
210
+ );
211
+ if (propDef.validate && typeof propDef.validate === 'string') {
212
+ if (!propertyValidatorRegistry.hasValidator(propDef.validate))
213
+ throw new InvalidArgumentError(
214
+ 'The property validator %v is not found.',
215
+ propDef.validate,
216
+ );
217
+ } else if (Array.isArray(propDef.validate)) {
218
+ for (const validatorName of propDef.validate) {
219
+ if (typeof validatorName !== 'string')
220
+ throw new InvalidArgumentError(
221
+ 'The provided option "validate" of the property %v in the model %v ' +
222
+ 'has an Array value that should have a non-empty String, ' +
223
+ 'but %v given.',
224
+ propName,
225
+ modelName,
226
+ validatorName,
227
+ );
228
+ if (!propertyValidatorRegistry.hasValidator(validatorName))
229
+ throw new InvalidArgumentError(
230
+ 'The property validator %v is not found.',
231
+ validatorName,
232
+ );
233
+ }
234
+ } else if (typeof propDef.validate === 'object') {
235
+ for (const validatorName in propDef.validate) {
236
+ if (!propertyValidatorRegistry.hasValidator(validatorName))
237
+ throw new InvalidArgumentError(
238
+ 'The property validator %v is not found.',
239
+ validatorName,
240
+ );
241
+ }
242
+ } else {
243
+ throw new InvalidArgumentError(
244
+ 'The provided option "validate" of the property %v in the model %v ' +
245
+ 'should be a non-empty String, an Array of String or an Object, ' +
246
+ 'but %v given.',
247
+ propName,
248
+ modelName,
249
+ propDef.validate,
250
+ );
251
+ }
252
+ }
206
253
  }
207
254
  }
@@ -2,12 +2,15 @@ import chai from 'chai';
2
2
  import {expect} from 'chai';
3
3
  import {DataType} from './data-type.js';
4
4
  import {format} from '@e22m4u/js-format';
5
+ import {PropertyValidatorRegistry} from './property-validator/index.js';
5
6
  import {PropertiesDefinitionValidator} from './properties-definition-validator.js';
6
7
  import {PrimaryKeysDefinitionValidator} from './primary-keys-definition-validator.js';
7
8
 
8
9
  const S = new PropertiesDefinitionValidator();
9
10
  const sandbox = chai.spy.sandbox();
10
11
 
12
+ S.getService(PropertyValidatorRegistry).addValidator('myValidator', () => true);
13
+
11
14
  describe('PropertiesDefinitionValidator', function () {
12
15
  afterEach(function () {
13
16
  sandbox.restore();
@@ -386,5 +389,52 @@ describe('PropertiesDefinitionValidator', function () {
386
389
  expect(V.validate).to.have.been.called.once;
387
390
  expect(V.validate).to.have.been.called.with.exactly('model', propDefs);
388
391
  });
392
+
393
+ it('the option "validate" should have a non-empty String, an Array of String or an Object', function () {
394
+ const validate = v => () => {
395
+ const foo = {
396
+ type: DataType.ANY,
397
+ validate: v,
398
+ };
399
+ S.validate('model', {foo});
400
+ };
401
+ const error = v =>
402
+ format(
403
+ 'The provided option "validate" of the property "foo" in the model "model" ' +
404
+ 'should be a non-empty String, an Array of String or an Object, ' +
405
+ 'but %s given.',
406
+ v,
407
+ );
408
+ expect(validate('')).to.throw(error('""'));
409
+ expect(validate(10)).to.throw(error('10'));
410
+ expect(validate(0)).to.throw(error('0'));
411
+ expect(validate(true)).to.throw(error('true'));
412
+ expect(validate(false)).to.throw(error('false'));
413
+ expect(validate(() => undefined)).to.throw(error('Function'));
414
+ validate('myValidator')();
415
+ validate(['myValidator'])();
416
+ validate([])();
417
+ validate({myValidator: true})();
418
+ validate({})();
419
+ validate(null)();
420
+ validate(undefined)();
421
+ });
422
+
423
+ it('the option "validate" requires only existing validator names', function () {
424
+ const validate = v => () => {
425
+ const foo = {
426
+ type: DataType.ANY,
427
+ validate: v,
428
+ };
429
+ S.validate('model', {foo});
430
+ };
431
+ const error = v => format('The property validator %s is not found.', v);
432
+ expect(validate('unknown')).to.throw(error('"unknown"'));
433
+ expect(validate({unknown: true})).to.throw(error('"unknown"'));
434
+ expect(validate(['unknown'])).to.throw(error('"unknown"'));
435
+ validate('myValidator')();
436
+ validate(['myValidator'])();
437
+ validate({myValidator: true})();
438
+ });
389
439
  });
390
440
  });
@@ -1,4 +1,5 @@
1
1
  import {DataType} from './data-type.js';
2
+ import {PropertyValidateOptions} from './property-validator/index.js';
2
3
 
3
4
  /**
4
5
  * Full property definition.
@@ -12,6 +13,7 @@ export declare type FullPropertyDefinition = {
12
13
  columnType?: string;
13
14
  required?: boolean;
14
15
  default?: unknown;
16
+ validate?: PropertyValidateOptions;
15
17
  };
16
18
 
17
19
  /**
@@ -0,0 +1,2 @@
1
+ export * from './property-validator.js';
2
+ export * from './property-validator-registry.js';
@@ -0,0 +1,2 @@
1
+ export * from './property-validator.js';
2
+ export * from './property-validator-registry.js';
@@ -0,0 +1,29 @@
1
+ import {Service} from '@e22m4u/js-service';
2
+ import {PropertyValidator} from './property-validator.js';
3
+
4
+ /**
5
+ * Property validator registry.
6
+ */
7
+ export declare class PropertyValidatorRegistry extends Service {
8
+ /**
9
+ * Add validator.
10
+ *
11
+ * @param name
12
+ * @param validator
13
+ */
14
+ addValidator(name: string, validator: PropertyValidator): this;
15
+
16
+ /**
17
+ * Has validator.
18
+ *
19
+ * @param name
20
+ */
21
+ hasValidator(name: string): boolean;
22
+
23
+ /**
24
+ * Get validator.
25
+ *
26
+ * @param name
27
+ */
28
+ getValidator(name: string): PropertyValidator;
29
+ }
@@ -0,0 +1,69 @@
1
+ import {Service} from '@e22m4u/js-service';
2
+ import {InvalidArgumentError} from '../../../../errors/index.js';
3
+
4
+ /**
5
+ * Property validator registry.
6
+ */
7
+ export class PropertyValidatorRegistry extends Service {
8
+ /**
9
+ * Validators.
10
+ *
11
+ * @type {object}
12
+ */
13
+ _validators = {};
14
+
15
+ /**
16
+ * Add validator.
17
+ *
18
+ * @param {string} name
19
+ * @param {Function} validator
20
+ * @returns {PropertyValidatorRegistry}
21
+ */
22
+ addValidator(name, validator) {
23
+ if (!name || typeof name !== 'string')
24
+ throw new InvalidArgumentError(
25
+ 'A name of the property validator must ' +
26
+ 'be a non-empty String, but %v given.',
27
+ name,
28
+ );
29
+ if (name in this._validators)
30
+ throw new InvalidArgumentError(
31
+ 'The property validator %v is already defined.',
32
+ name,
33
+ );
34
+ if (typeof validator !== 'function')
35
+ throw new InvalidArgumentError(
36
+ 'The property validator %v must be a Function, but %v given.',
37
+ name,
38
+ validator,
39
+ );
40
+ this._validators[name] = validator;
41
+ return this;
42
+ }
43
+
44
+ /**
45
+ * Has validator.
46
+ *
47
+ * @param {string} name
48
+ * @returns {boolean}
49
+ */
50
+ hasValidator(name) {
51
+ return Boolean(this._validators[name]);
52
+ }
53
+
54
+ /**
55
+ * Get validator.
56
+ *
57
+ * @param {string} name
58
+ * @returns {Function}
59
+ */
60
+ getValidator(name) {
61
+ const validator = this._validators[name];
62
+ if (!validator)
63
+ throw new InvalidArgumentError(
64
+ 'The property validator %v is not defined.',
65
+ name,
66
+ );
67
+ return validator;
68
+ }
69
+ }
@@ -0,0 +1,120 @@
1
+ import {expect} from 'chai';
2
+ import {format} from '@e22m4u/js-format';
3
+ import {PropertyValidatorRegistry} from './property-validator-registry.js';
4
+
5
+ describe('PropertyValidatorRegistry', function () {
6
+ describe('addValidator', function () {
7
+ it('adds a given validator with the name', function () {
8
+ const s = new PropertyValidatorRegistry();
9
+ const myValidator = () => {};
10
+ const res = s.addValidator('myValidator', myValidator);
11
+ expect(res).to.be.eq(s);
12
+ expect(s['_validators']).to.be.eql({myValidator});
13
+ });
14
+
15
+ it('requires the given name to be a non-empty string', function () {
16
+ const s = new PropertyValidatorRegistry();
17
+ const throwable = v => () => s.addValidator(v, () => undefined);
18
+ const error = v =>
19
+ format(
20
+ 'A name of the property validator must ' +
21
+ 'be a non-empty String, but %s given.',
22
+ v,
23
+ );
24
+ expect(throwable('')).to.throw(error('""'));
25
+ expect(throwable(10)).to.throw(error('10'));
26
+ expect(throwable(0)).to.throw(error('0'));
27
+ expect(throwable(false)).to.throw(error('false'));
28
+ expect(throwable(undefined)).to.throw(error('undefined'));
29
+ expect(throwable(null)).to.throw(error('null'));
30
+ expect(throwable({})).to.throw(error('Object'));
31
+ expect(throwable([])).to.throw(error('Array'));
32
+ expect(throwable(() => undefined)).to.throw(error('Function'));
33
+ throwable('str')();
34
+ });
35
+
36
+ it('throws an error if the given name already exists', function () {
37
+ const s = new PropertyValidatorRegistry();
38
+ s.addValidator('test', () => undefined);
39
+ const throwable = () => s.addValidator('test', () => undefined);
40
+ expect(throwable).to.throw(
41
+ 'The property validator "test" is already defined.',
42
+ );
43
+ });
44
+
45
+ it('requires the given validator to be a function', function () {
46
+ const s = new PropertyValidatorRegistry();
47
+ const throwable = v => () => s.addValidator('test', v);
48
+ const error = v =>
49
+ format(
50
+ 'The property validator "test" must be a Function, but %s given.',
51
+ v,
52
+ );
53
+ expect(throwable('str')).to.throw(error('"str"'));
54
+ expect(throwable('')).to.throw(error('""'));
55
+ expect(throwable(10)).to.throw(error('10'));
56
+ expect(throwable(0)).to.throw(error('0'));
57
+ expect(throwable(false)).to.throw(error('false'));
58
+ expect(throwable(undefined)).to.throw(error('undefined'));
59
+ expect(throwable(null)).to.throw(error('null'));
60
+ expect(throwable({})).to.throw(error('Object'));
61
+ expect(throwable([])).to.throw(error('Array'));
62
+ throwable(() => undefined)();
63
+ });
64
+ });
65
+
66
+ describe('hasValidator', function () {
67
+ it('returns false for a not existing name', function () {
68
+ const s = new PropertyValidatorRegistry();
69
+ expect(s.hasValidator('str')).to.be.false;
70
+ expect(s.hasValidator('')).to.be.false;
71
+ expect(s.hasValidator(10)).to.be.false;
72
+ expect(s.hasValidator(0)).to.be.false;
73
+ expect(s.hasValidator(true)).to.be.false;
74
+ expect(s.hasValidator(false)).to.be.false;
75
+ expect(s.hasValidator(null)).to.be.false;
76
+ expect(s.hasValidator(undefined)).to.be.false;
77
+ expect(s.hasValidator({})).to.be.false;
78
+ expect(s.hasValidator([])).to.be.false;
79
+ expect(s.hasValidator(() => undefined)).to.be.false;
80
+ });
81
+
82
+ it('returns true for an existing name', function () {
83
+ const s = new PropertyValidatorRegistry();
84
+ expect(s.hasValidator('test')).to.be.false;
85
+ s.addValidator('test', () => undefined);
86
+ expect(s.hasValidator('test')).to.be.true;
87
+ });
88
+ });
89
+
90
+ describe('getValidator', function () {
91
+ it('returns validator by its name', function () {
92
+ const s = new PropertyValidatorRegistry();
93
+ const validator1 = () => undefined;
94
+ const validator2 = () => undefined;
95
+ s.addValidator('foo', validator1);
96
+ s.addValidator('bar', validator2);
97
+ const res1 = s.getValidator('foo');
98
+ const res2 = s.getValidator('bar');
99
+ expect(res1).to.be.eq(validator1);
100
+ expect(res2).to.be.eq(validator2);
101
+ });
102
+
103
+ it('throws an error for a not existed name', function () {
104
+ const s = new PropertyValidatorRegistry();
105
+ const throwable = v => () => s.getValidator(v);
106
+ const error = v => format('The property validator %s is not defined.', v);
107
+ expect(throwable('str')).to.throw(error('"str"'));
108
+ expect(throwable('')).to.throw(error('""'));
109
+ expect(throwable(10)).to.throw(error('10'));
110
+ expect(throwable(0)).to.throw(error('0'));
111
+ expect(throwable(true)).to.throw(error('true'));
112
+ expect(throwable(false)).to.throw(error('false'));
113
+ expect(throwable(null)).to.throw(error('null'));
114
+ expect(throwable(undefined)).to.throw(error('undefined'));
115
+ expect(throwable({})).to.throw(error('Object'));
116
+ expect(throwable([])).to.throw(error('Array'));
117
+ expect(throwable(() => undefined)).to.throw(error('Function'));
118
+ });
119
+ });
120
+ });
@@ -0,0 +1,30 @@
1
+ import {ServiceContainer} from '@e22m4u/js-service';
2
+ import {FullPropertyDefinition} from '../property-definition.js';
3
+
4
+ /**
5
+ * Property validator context.
6
+ */
7
+ export type PropertyValidatorContext = {
8
+ validatorName: string,
9
+ modelName: string,
10
+ propName: string,
11
+ propDef: FullPropertyDefinition,
12
+ container: ServiceContainer,
13
+ }
14
+
15
+ /**
16
+ * Property validator.
17
+ */
18
+ export type PropertyValidator = (
19
+ value: unknown,
20
+ options: unknown,
21
+ context: PropertyValidatorContext,
22
+ ) => Promise<boolean> | boolean;
23
+
24
+ /**
25
+ * Property validate options.
26
+ */
27
+ export type PropertyValidateOptions =
28
+ | string
29
+ | string[]
30
+ | {[key: string]: unknown};
package/src/schema.d.ts CHANGED
@@ -3,6 +3,7 @@ import {ModelData} from './types.js';
3
3
  import {Service} from '@e22m4u/js-service';
4
4
  import {Repository} from './repository/index.js';
5
5
  import {ModelDefinition} from './definition/index.js';
6
+ import {PropertyValidator} from './definition/index.js';
6
7
  import {DatasourceDefinition} from './definition/index.js';
7
8
  import {DEFAULT_PRIMARY_KEY_PROPERTY_NAME} from './definition/index.js';
8
9
 
@@ -34,4 +35,12 @@ export declare class Schema extends Service {
34
35
  IdType extends ModelId = ModelId,
35
36
  IdName extends string = DEFAULT_PRIMARY_KEY_PROPERTY_NAME,
36
37
  >(modelName: string): Repository<Data, IdType, IdName>;
38
+
39
+ /**
40
+ * Add property validator.
41
+ *
42
+ * @param name
43
+ * @param validator
44
+ */
45
+ addPropertyValidator(name: string, validator: PropertyValidator): this;
37
46
  }
package/src/schema.js CHANGED
@@ -2,6 +2,7 @@ import {Service} from '@e22m4u/js-service';
2
2
  import {Repository} from './repository/index.js';
3
3
  import {DefinitionRegistry} from './definition/index.js';
4
4
  import {RepositoryRegistry} from './repository/index.js';
5
+ import {PropertyValidatorRegistry} from './definition/index.js';
5
6
 
6
7
  /**
7
8
  * Schema.
@@ -38,4 +39,16 @@ export class Schema extends Service {
38
39
  getRepository(modelName) {
39
40
  return this.getService(RepositoryRegistry).getRepository(modelName);
40
41
  }
42
+
43
+ /**
44
+ * Add property validator.
45
+ *
46
+ * @param {string} name
47
+ * @param {Function} validator
48
+ * @returns {this}
49
+ */
50
+ addPropertyValidator(name, validator) {
51
+ this.getService(PropertyValidatorRegistry).addValidator(name, validator);
52
+ return this;
53
+ }
41
54
  }
@@ -2,9 +2,19 @@ import {expect} from 'chai';
2
2
  import {Schema} from './schema.js';
3
3
  import {Repository} from './repository/index.js';
4
4
  import {DefinitionRegistry} from './definition/index.js';
5
+ import {PropertyValidatorRegistry} from './definition/index.js';
5
6
 
6
7
  describe('Schema', function () {
7
8
  describe('defineDatasource', function () {
9
+ it('returns this', function () {
10
+ const schema = new Schema();
11
+ const res = schema.defineDatasource({
12
+ name: 'datasource',
13
+ adapter: 'memory',
14
+ });
15
+ expect(res).to.be.eq(schema);
16
+ });
17
+
8
18
  it('sets the datasource definition', function () {
9
19
  const schema = new Schema();
10
20
  schema.defineDatasource({name: 'datasource', adapter: 'memory'});
@@ -25,6 +35,12 @@ describe('Schema', function () {
25
35
  });
26
36
 
27
37
  describe('defineModel', function () {
38
+ it('returns this', function () {
39
+ const schema = new Schema();
40
+ const res = schema.defineModel({name: 'model'});
41
+ expect(res).to.be.eq(schema);
42
+ });
43
+
28
44
  it('sets the model definition', function () {
29
45
  const schema = new Schema();
30
46
  schema.defineModel({name: 'model'});
@@ -68,4 +84,32 @@ describe('Schema', function () {
68
84
  expect(res1).to.be.eq(res2);
69
85
  });
70
86
  });
87
+
88
+ describe('addPropertyValidator', function () {
89
+ it('returns this', function () {
90
+ const schema = new Schema();
91
+ const res = schema.addPropertyValidator('validator', () => true);
92
+ expect(res).to.be.eq(schema);
93
+ });
94
+
95
+ it('adds a new property validator', function () {
96
+ const schema = new Schema();
97
+ const validator = () => true;
98
+ schema.addPropertyValidator('validator', validator);
99
+ const res = schema.getService(PropertyValidatorRegistry)
100
+ .getValidator('validator');
101
+ expect(res).to.be.eq(validator);
102
+ });
103
+
104
+ it('throws an error for already existing validator name', function () {
105
+ const schema = new Schema();
106
+ const validator = () => true;
107
+ schema.addPropertyValidator('validator', validator);
108
+ const throwable =
109
+ () => schema.addPropertyValidator('validator', validator);
110
+ expect(throwable).to.throw(
111
+ 'The property validator "validator" is already defined.',
112
+ );
113
+ });
114
+ });
71
115
  });