@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.
Files changed (39) hide show
  1. package/README.md +6 -1
  2. package/docs/assets/navigation.js +1 -1
  3. package/docs/assets/search.js +1 -1
  4. package/docs/classes/PropertyUniquenessValidator.html +16 -0
  5. package/docs/index.html +5 -1
  6. package/docs/modules.html +2 -0
  7. package/docs/types/CountMethod.html +2 -0
  8. package/docs/types/FullPropertyDefinition.html +2 -2
  9. package/docs/types/PropertyDefinition.html +1 -1
  10. package/package.json +4 -4
  11. package/src/adapter/adapter.js +2 -0
  12. package/src/adapter/adapter.spec.js +8 -2
  13. package/src/adapter/decorator/index.d.ts +1 -0
  14. package/src/adapter/decorator/index.js +1 -0
  15. package/src/adapter/decorator/property-uniqueness-decorator.d.ts +14 -0
  16. package/src/adapter/decorator/property-uniqueness-decorator.js +76 -0
  17. package/src/adapter/decorator/property-uniqueness-decorator.spec.js +135 -0
  18. package/src/definition/definition-registry.spec.js +1 -0
  19. package/src/definition/model/properties/index.d.ts +1 -0
  20. package/src/definition/model/properties/index.js +1 -0
  21. package/src/definition/model/properties/properties-definition-validator.js +15 -0
  22. package/src/definition/model/properties/properties-definition-validator.spec.js +46 -5
  23. package/src/definition/model/properties/property-definition.d.ts +3 -0
  24. package/src/definition/model/properties/property-transformer/builtin/index.d.ts +3 -0
  25. package/src/definition/model/properties/property-transformer/builtin/index.js +3 -0
  26. package/src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.d.ts +6 -0
  27. package/src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.js +19 -0
  28. package/src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.spec.js +39 -0
  29. package/src/definition/model/properties/property-transformer/builtin/to-title-case-transformer.d.ts +6 -0
  30. package/src/definition/model/properties/property-transformer/builtin/to-title-case-transformer.js +22 -0
  31. package/src/definition/model/properties/property-transformer/builtin/to-title-case-transformer.spec.js +41 -0
  32. package/src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.d.ts +6 -0
  33. package/src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.js +19 -0
  34. package/src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.spec.js +39 -0
  35. package/src/definition/model/properties/property-transformer/property-transformer-registry.js +6 -0
  36. package/src/definition/model/properties/property-transformer/property-transformer-registry.spec.js +6 -0
  37. package/src/definition/model/properties/property-uniqueness-validator.d.ts +31 -0
  38. package/src/definition/model/properties/property-uniqueness-validator.js +131 -0
  39. 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
+ }