@e22m4u/js-repository 0.1.1 → 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.
- package/.eslintrc.cjs +41 -17
- package/.husky/commit-msg +1 -4
- package/.husky/pre-commit +0 -3
- package/.mocharc.cjs +2 -2
- package/README.md +2 -2
- package/docs/assets/main.js +2 -2
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/assets/style.css +35 -15
- package/docs/classes/Adapter.html +19 -19
- package/docs/classes/AdapterLoader.html +8 -8
- package/docs/classes/AdapterRegistry.html +8 -8
- package/docs/classes/BelongsToResolver.html +9 -9
- package/docs/classes/DatasourceDefinitionValidator.html +8 -8
- package/docs/classes/DefinitionRegistry.html +12 -12
- package/docs/classes/FieldsClauseTool.html +10 -10
- package/docs/classes/HasManyResolver.html +10 -10
- package/docs/classes/HasOneResolver.html +10 -10
- package/docs/classes/IncludeClauseTool.html +12 -12
- package/docs/classes/InvalidArgumentError.html +7 -5
- package/docs/classes/InvalidOperatorValueError.html +7 -5
- package/docs/classes/ModelDataSanitizer.html +8 -8
- package/docs/classes/ModelDataValidator.html +9 -9
- package/docs/classes/ModelDefinitionUtils.html +23 -23
- package/docs/classes/ModelDefinitionValidator.html +8 -8
- package/docs/classes/NotImplementedError.html +7 -5
- package/docs/classes/OperatorClauseTool.html +32 -32
- package/docs/classes/OrderClauseTool.html +10 -10
- package/docs/classes/PrimaryKeysDefinitionValidator.html +8 -8
- package/docs/classes/PropertiesDefinitionValidator.html +8 -8
- package/docs/classes/ReferencesManyResolver.html +8 -8
- package/docs/classes/RelationsDefinitionValidator.html +8 -8
- package/docs/classes/Repository.html +28 -24
- package/docs/classes/RepositoryRegistry.html +9 -9
- package/docs/classes/Schema.html +10 -10
- package/docs/classes/SliceClauseTool.html +10 -10
- package/docs/classes/WhereClauseTool.html +9 -9
- package/docs/enums/DataType.html +2 -2
- package/docs/enums/DecoratorTargetType.html +11 -0
- package/docs/enums/RelationType.html +2 -2
- package/docs/functions/capitalize.html +1 -1
- package/docs/functions/cloneDeep.html +2 -2
- package/docs/functions/excludeObjectKeys.html +2 -2
- package/docs/functions/getCtorName.html +1 -1
- package/docs/functions/getDecoratorTargetType.html +2 -0
- package/docs/functions/getValueByPath.html +1 -1
- package/docs/functions/isCtor.html +3 -2
- package/docs/functions/isPureObject.html +1 -1
- package/docs/functions/selectObjectKeys.html +2 -2
- package/docs/functions/singularize.html +1 -1
- package/docs/functions/stringToRegexp.html +2 -2
- package/docs/index.html +3 -3
- package/docs/interfaces/AndClause.html +2 -2
- package/docs/interfaces/Constructor.html +4 -0
- package/docs/interfaces/OrClause.html +2 -2
- package/docs/modules.html +4 -1
- package/docs/types/AnyObject.html +1 -1
- package/docs/types/BelongsToDefinition.html +1 -1
- package/docs/types/DEFAULT_PRIMARY_KEY_PROPERTY_NAME.html +1 -1
- package/docs/types/DatasourceDefinition.html +1 -1
- package/docs/types/FieldsClause.html +1 -1
- package/docs/types/FilterClause.html +1 -1
- package/docs/types/Flatten.html +1 -1
- package/docs/types/FullPropertyDefinition.html +1 -1
- package/docs/types/HasManyDefinition.html +1 -1
- package/docs/types/HasOneDefinition.html +1 -1
- package/docs/types/Identity.html +2 -2
- package/docs/types/IncludeClause.html +1 -1
- package/docs/types/ItemFilterClause.html +2 -2
- package/docs/types/ModelData.html +1 -1
- package/docs/types/ModelDefinition.html +1 -1
- package/docs/types/ModelId.html +1 -1
- package/docs/types/NestedIncludeClause.html +1 -1
- package/docs/types/NormalizedFieldsClause.html +1 -1
- package/docs/types/NormalizedIncludeClause.html +1 -1
- package/docs/types/OperatorClause.html +3 -3
- package/docs/types/OptionalUnlessRequiredId.html +2 -2
- package/docs/types/OrderClause.html +1 -1
- package/docs/types/PartialBy.html +2 -2
- package/docs/types/PartialWithoutId.html +2 -2
- package/docs/types/PolyBelongsToDefinition.html +1 -1
- package/docs/types/PolyHasManyDefinitionWithTargetKeys.html +1 -1
- package/docs/types/PolyHasManyDefinitionWithTargetRelationName.html +1 -1
- package/docs/types/PolyHasOneDefinitionWithTargetKeys.html +1 -1
- package/docs/types/PolyHasOneDefinitionWithTargetRelationName.html +1 -1
- package/docs/types/PropertiesClause.html +3 -3
- package/docs/types/PropertyDefinition.html +1 -1
- package/docs/types/PropertyDefinitionMap.html +1 -1
- package/docs/types/ReferencesManyDefinition.html +1 -1
- package/docs/types/RelationDefinition.html +1 -1
- package/docs/types/RelationDefinitionMap.html +1 -1
- package/docs/types/WhereClause.html +2 -2
- package/docs/types/WithoutId.html +2 -2
- package/mocha.setup.js +8 -3
- package/package.json +23 -19
- package/src/adapter/decorator/data-sanitizing-decorator.d.ts +2 -1
- package/src/adapter/decorator/data-validation-decorator.d.ts +2 -1
- package/src/adapter/decorator/data-validation-decorator.js +18 -10
- package/src/adapter/decorator/data-validation-decorator.spec.js +40 -0
- package/src/adapter/decorator/default-values-decorator.d.ts +2 -1
- package/src/adapter/decorator/fields-filtering-decorator.d.ts +2 -1
- package/src/adapter/decorator/inclusion-decorator.d.ts +2 -1
- package/src/definition/model/index.js +1 -0
- package/src/definition/model/model-data-validator.d.ts +4 -16
- package/src/definition/model/model-data-validator.js +92 -11
- package/src/definition/model/model-data-validator.spec.js +1140 -442
- package/src/definition/model/model-definition.js +1 -0
- package/src/definition/model/properties/index.d.ts +1 -0
- package/src/definition/model/properties/index.js +2 -0
- package/src/definition/model/properties/properties-definition-validator.js +47 -0
- package/src/definition/model/properties/properties-definition-validator.spec.js +50 -0
- package/src/definition/model/properties/property-definition.d.ts +2 -0
- package/src/definition/model/properties/property-definition.js +1 -0
- package/src/definition/model/properties/property-validator/index.d.ts +2 -0
- package/src/definition/model/properties/property-validator/index.js +2 -0
- package/src/definition/model/properties/property-validator/property-validator-registry.d.ts +29 -0
- package/src/definition/model/properties/property-validator/property-validator-registry.js +69 -0
- package/src/definition/model/properties/property-validator/property-validator-registry.spec.js +120 -0
- package/src/definition/model/properties/property-validator/property-validator.d.ts +30 -0
- package/src/definition/model/properties/property-validator/property-validator.js +1 -0
- package/src/definition/model/relations/index.js +1 -0
- package/src/definition/model/relations/relation-definition.js +1 -0
- package/src/filter/filter-clause.d.ts +4 -4
- package/src/index.d.ts +1 -1
- package/src/index.js +1 -0
- package/src/repository/repository.d.ts +9 -3
- package/src/repository/repository.js +0 -1
- package/src/schema.d.ts +10 -1
- package/src/schema.js +13 -0
- package/src/schema.spec.ts +115 -0
- package/src/types.d.ts +8 -0
- package/src/types.js +1 -0
- package/src/utils/get-decorator-target-type.d.ts +27 -0
- package/src/utils/get-decorator-target-type.js +63 -0
- package/src/utils/get-decorator-target-type.spec.js +77 -0
- package/src/utils/index.d.ts +1 -0
- package/src/utils/index.js +1 -0
- package/src/utils/is-ctor.d.ts +2 -1
- package/src/utils/is-ctor.js +2 -1
- package/src/utils/is-ctor.spec.js +1 -1
- package/tsconfig.json +3 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
+
}
|
package/src/definition/model/properties/property-validator/property-validator-registry.spec.js
ADDED
|
@@ -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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -43,8 +43,8 @@ export declare type ItemFilterClause = Pick<FilterClause, 'fields' | 'include'>;
|
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
45
|
export declare type WhereClause =
|
|
46
|
-
& AndClause
|
|
47
|
-
& OrClause
|
|
46
|
+
& Partial<AndClause>
|
|
47
|
+
& Partial<OrClause>
|
|
48
48
|
& PropertiesClause;
|
|
49
49
|
|
|
50
50
|
/**
|
|
@@ -124,7 +124,7 @@ export declare type OperatorClause = {
|
|
|
124
124
|
* ```
|
|
125
125
|
*/
|
|
126
126
|
export interface AndClause {
|
|
127
|
-
and
|
|
127
|
+
and: WhereClause[];
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
/**
|
|
@@ -138,7 +138,7 @@ export interface AndClause {
|
|
|
138
138
|
* ```
|
|
139
139
|
*/
|
|
140
140
|
export interface OrClause {
|
|
141
|
-
or
|
|
141
|
+
or: WhereClause[];
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
/**
|
package/src/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export * from './types.js';
|
|
2
2
|
export * from './schema.js';
|
|
3
3
|
export * from './utils/index.js';
|
|
4
|
-
export * from './filter/index.js';
|
|
5
4
|
export * from './errors/index.js';
|
|
5
|
+
export * from './filter/index.js';
|
|
6
6
|
export * from './adapter/index.js';
|
|
7
7
|
export * from './relations/index.js';
|
|
8
8
|
export * from './definition/index.js';
|
package/src/index.js
CHANGED
|
@@ -14,11 +14,17 @@ import {DEFAULT_PRIMARY_KEY_PROPERTY_NAME} from '../definition/index.js';
|
|
|
14
14
|
* Repository.
|
|
15
15
|
*/
|
|
16
16
|
export declare class Repository<
|
|
17
|
-
Data extends
|
|
17
|
+
Data extends object = ModelData,
|
|
18
18
|
IdType extends ModelId = ModelId,
|
|
19
19
|
IdName extends string = DEFAULT_PRIMARY_KEY_PROPERTY_NAME,
|
|
20
20
|
FlatData extends ModelData = Flatten<Data>,
|
|
21
21
|
> extends Service {
|
|
22
|
+
// it fixes unused generic bug
|
|
23
|
+
private _Data?: Data;
|
|
24
|
+
private _IdType?: IdType;
|
|
25
|
+
private _IdName?: IdName;
|
|
26
|
+
private _FlatData?: FlatData;
|
|
27
|
+
|
|
22
28
|
/**
|
|
23
29
|
* Model name.
|
|
24
30
|
*/
|
|
@@ -162,7 +168,7 @@ type WithoutId<IdName extends string, Data extends ModelData> = Flatten<
|
|
|
162
168
|
/**
|
|
163
169
|
* Makes fields as optional and remove id field.
|
|
164
170
|
*/
|
|
165
|
-
type PartialWithoutId<IdName extends string, Data extends
|
|
171
|
+
type PartialWithoutId<IdName extends string, Data extends object> = Flatten<
|
|
166
172
|
Partial<Omit<Data, IdName>>
|
|
167
173
|
>;
|
|
168
174
|
|
|
@@ -171,5 +177,5 @@ type PartialWithoutId<IdName extends string, Data extends ModelData> = Flatten<
|
|
|
171
177
|
*/
|
|
172
178
|
type OptionalUnlessRequiredId<
|
|
173
179
|
IdName extends string,
|
|
174
|
-
Data extends
|
|
180
|
+
Data extends object,
|
|
175
181
|
> = Flatten<Data extends {[K in IdName]: any} ? PartialBy<Data, IdName> : Data>;
|
|
@@ -3,7 +3,6 @@ import {Adapter} from '../adapter/index.js';
|
|
|
3
3
|
import {AdapterRegistry} from '../adapter/index.js';
|
|
4
4
|
import {InvalidArgumentError} from '../errors/index.js';
|
|
5
5
|
import {DefinitionRegistry} from '../definition/index.js';
|
|
6
|
-
import {ModelDefinitionUtils} from '../definition/index.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Repository.
|
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
|
|
|
@@ -30,8 +31,16 @@ export declare class Schema extends Service {
|
|
|
30
31
|
* @param modelName
|
|
31
32
|
*/
|
|
32
33
|
getRepository<
|
|
33
|
-
Data extends
|
|
34
|
+
Data extends object = ModelData,
|
|
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
|
}
|