@e22m4u/js-repository 0.1.7 → 0.1.9
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/README.md +6 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/PropertyUniquenessValidator.html +16 -0
- package/docs/index.html +5 -1
- package/docs/modules.html +2 -0
- package/docs/types/CountMethod.html +2 -0
- package/docs/types/FullPropertyDefinition.html +2 -2
- package/docs/types/PropertyDefinition.html +1 -1
- package/package.json +4 -4
- package/src/adapter/adapter.js +2 -0
- package/src/adapter/adapter.spec.js +8 -2
- package/src/adapter/decorator/index.d.ts +1 -0
- package/src/adapter/decorator/index.js +1 -0
- package/src/adapter/decorator/property-uniqueness-decorator.d.ts +14 -0
- package/src/adapter/decorator/property-uniqueness-decorator.js +76 -0
- package/src/adapter/decorator/property-uniqueness-decorator.spec.js +135 -0
- package/src/definition/definition-registry.spec.js +1 -0
- package/src/definition/model/properties/index.d.ts +1 -0
- package/src/definition/model/properties/index.js +1 -0
- package/src/definition/model/properties/properties-definition-validator.js +15 -0
- package/src/definition/model/properties/properties-definition-validator.spec.js +46 -5
- package/src/definition/model/properties/property-definition.d.ts +3 -0
- package/src/definition/model/properties/property-transformer/builtin/index.d.ts +3 -0
- package/src/definition/model/properties/property-transformer/builtin/index.js +3 -0
- package/src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.d.ts +6 -0
- package/src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.js +19 -0
- package/src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.spec.js +39 -0
- package/src/definition/model/properties/property-transformer/builtin/to-title-case-transformer.d.ts +6 -0
- package/src/definition/model/properties/property-transformer/builtin/to-title-case-transformer.js +22 -0
- package/src/definition/model/properties/property-transformer/builtin/to-title-case-transformer.spec.js +41 -0
- package/src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.d.ts +6 -0
- package/src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.js +19 -0
- package/src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.spec.js +39 -0
- package/src/definition/model/properties/property-transformer/property-transformer-registry.js +6 -0
- package/src/definition/model/properties/property-transformer/property-transformer-registry.spec.js +6 -0
- package/src/definition/model/properties/property-uniqueness-validator.d.ts +31 -0
- package/src/definition/model/properties/property-uniqueness-validator.js +131 -0
- package/src/definition/model/properties/property-uniqueness-validator.spec.js +943 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import {Service} from '@e22m4u/js-service';
|
|
2
|
+
import {isPureObject} from '../../../utils/index.js';
|
|
3
|
+
import {InvalidArgumentError} from '../../../errors/index.js';
|
|
4
|
+
import {ModelDefinitionUtils} from '../model-definition-utils.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Property uniqueness validator.
|
|
8
|
+
*/
|
|
9
|
+
export class PropertyUniquenessValidator extends Service {
|
|
10
|
+
/**
|
|
11
|
+
* Validate.
|
|
12
|
+
*
|
|
13
|
+
* @param {Function} countMethod
|
|
14
|
+
* @param {string} methodName
|
|
15
|
+
* @param {string} modelName
|
|
16
|
+
* @param {object} modelData
|
|
17
|
+
* @param {*} modelId
|
|
18
|
+
* @returns {Promise<undefined>}
|
|
19
|
+
*/
|
|
20
|
+
async validate(
|
|
21
|
+
countMethod,
|
|
22
|
+
methodName,
|
|
23
|
+
modelName,
|
|
24
|
+
modelData,
|
|
25
|
+
modelId = undefined,
|
|
26
|
+
) {
|
|
27
|
+
if (typeof countMethod !== 'function')
|
|
28
|
+
throw new InvalidArgumentError(
|
|
29
|
+
'The parameter "countMethod" of the PropertyUniquenessValidator ' +
|
|
30
|
+
'must be a Function, but %v given.',
|
|
31
|
+
countMethod,
|
|
32
|
+
);
|
|
33
|
+
if (!methodName || typeof methodName !== 'string')
|
|
34
|
+
throw new InvalidArgumentError(
|
|
35
|
+
'The parameter "methodName" of the PropertyUniquenessValidator ' +
|
|
36
|
+
'must be a non-empty String, but %v given.',
|
|
37
|
+
methodName,
|
|
38
|
+
);
|
|
39
|
+
if (!modelName || typeof modelName !== 'string')
|
|
40
|
+
throw new InvalidArgumentError(
|
|
41
|
+
'The parameter "modelName" of the PropertyUniquenessValidator ' +
|
|
42
|
+
'must be a non-empty String, but %v given.',
|
|
43
|
+
modelName,
|
|
44
|
+
);
|
|
45
|
+
if (!isPureObject(modelData))
|
|
46
|
+
throw new InvalidArgumentError(
|
|
47
|
+
'The data of the model %v should be an Object, but %v given.',
|
|
48
|
+
modelName,
|
|
49
|
+
modelData,
|
|
50
|
+
);
|
|
51
|
+
const propDefs =
|
|
52
|
+
this.getService(
|
|
53
|
+
ModelDefinitionUtils,
|
|
54
|
+
).getPropertiesDefinitionInBaseModelHierarchy(modelName);
|
|
55
|
+
const isPartial = methodName === 'patch' || methodName === 'patchById';
|
|
56
|
+
const propNames = Object.keys(isPartial ? modelData : propDefs);
|
|
57
|
+
const idProp =
|
|
58
|
+
this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
|
|
59
|
+
modelName,
|
|
60
|
+
);
|
|
61
|
+
const createError = (propName, propValue) =>
|
|
62
|
+
new InvalidArgumentError(
|
|
63
|
+
'An existing document of the model %v already has ' +
|
|
64
|
+
'the property %v with the value %v and should be unique.',
|
|
65
|
+
modelName,
|
|
66
|
+
propName,
|
|
67
|
+
propValue,
|
|
68
|
+
);
|
|
69
|
+
let willBeReplaced = undefined;
|
|
70
|
+
for (const propName of propNames) {
|
|
71
|
+
const propDef = propDefs[propName];
|
|
72
|
+
if (!propDef || typeof propDef === 'string' || !propDef.unique) continue;
|
|
73
|
+
const propValue = modelData[propName];
|
|
74
|
+
// create
|
|
75
|
+
if (methodName === 'create') {
|
|
76
|
+
const count = await countMethod({[propName]: propValue});
|
|
77
|
+
if (count > 0) throw createError(propName, propValue);
|
|
78
|
+
}
|
|
79
|
+
// replaceById
|
|
80
|
+
else if (methodName === 'replaceById') {
|
|
81
|
+
const count = await countMethod({
|
|
82
|
+
[idProp]: {neq: modelId},
|
|
83
|
+
[propName]: propValue,
|
|
84
|
+
});
|
|
85
|
+
if (count > 0) throw createError(propName, propValue);
|
|
86
|
+
}
|
|
87
|
+
// replaceOrCreate
|
|
88
|
+
else if (methodName === 'replaceOrCreate') {
|
|
89
|
+
const idFromData = modelData[idProp];
|
|
90
|
+
if (willBeReplaced == null && idFromData != null) {
|
|
91
|
+
const count = await countMethod({[idProp]: idFromData});
|
|
92
|
+
willBeReplaced = count > 0;
|
|
93
|
+
}
|
|
94
|
+
// replaceById by replaceOrCreate
|
|
95
|
+
if (willBeReplaced) {
|
|
96
|
+
const count = await countMethod({
|
|
97
|
+
[idProp]: {neq: idFromData},
|
|
98
|
+
[propName]: propValue,
|
|
99
|
+
});
|
|
100
|
+
if (count > 0) throw createError(propName, propValue);
|
|
101
|
+
}
|
|
102
|
+
// create by replaceOrCreate
|
|
103
|
+
else {
|
|
104
|
+
const count = await countMethod({[propName]: propValue});
|
|
105
|
+
if (count > 0) throw createError(propName, propValue);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// patch
|
|
109
|
+
else if (methodName === 'patch') {
|
|
110
|
+
const count = await countMethod({[propName]: propValue});
|
|
111
|
+
if (count > 0) throw createError(propName, propValue);
|
|
112
|
+
}
|
|
113
|
+
// patchById
|
|
114
|
+
else if (methodName === 'patchById') {
|
|
115
|
+
const count = await countMethod({
|
|
116
|
+
[idProp]: {neq: modelId},
|
|
117
|
+
[propName]: propValue,
|
|
118
|
+
});
|
|
119
|
+
if (count > 0) throw createError(propName, propValue);
|
|
120
|
+
}
|
|
121
|
+
// unsupported method
|
|
122
|
+
else {
|
|
123
|
+
throw new InvalidArgumentError(
|
|
124
|
+
'The PropertyUniquenessValidator does not ' +
|
|
125
|
+
'support the adapter method %v.',
|
|
126
|
+
methodName,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|