@e22m4u/js-repository 0.1.5 → 0.1.7

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 (139) hide show
  1. package/README.md +35 -4
  2. package/docs/assets/navigation.js +1 -1
  3. package/docs/assets/search.js +1 -1
  4. package/docs/classes/Adapter.html +1 -1
  5. package/docs/classes/AdapterLoader.html +1 -1
  6. package/docs/classes/AdapterRegistry.html +1 -1
  7. package/docs/classes/BelongsToResolver.html +1 -1
  8. package/docs/classes/DatasourceDefinitionValidator.html +1 -1
  9. package/docs/classes/DefinitionRegistry.html +1 -1
  10. package/docs/classes/FieldsClauseTool.html +1 -1
  11. package/docs/classes/HasManyResolver.html +1 -1
  12. package/docs/classes/HasOneResolver.html +1 -1
  13. package/docs/classes/IncludeClauseTool.html +1 -1
  14. package/docs/classes/InvalidArgumentError.html +1 -1
  15. package/docs/classes/InvalidOperatorValueError.html +1 -1
  16. package/docs/classes/ModelDataSanitizer.html +1 -1
  17. package/docs/classes/ModelDataTransformer.html +16 -0
  18. package/docs/classes/ModelDataValidator.html +2 -2
  19. package/docs/classes/ModelDefinitionUtils.html +1 -1
  20. package/docs/classes/ModelDefinitionValidator.html +1 -1
  21. package/docs/classes/NotImplementedError.html +1 -1
  22. package/docs/classes/OperatorClauseTool.html +1 -1
  23. package/docs/classes/OrderClauseTool.html +1 -1
  24. package/docs/classes/PrimaryKeysDefinitionValidator.html +1 -1
  25. package/docs/classes/PropertiesDefinitionValidator.html +1 -1
  26. package/docs/classes/PropertyTransformerRegistry.html +20 -0
  27. package/docs/classes/PropertyValidatorRegistry.html +1 -1
  28. package/docs/classes/ReferencesManyResolver.html +1 -1
  29. package/docs/classes/RelationsDefinitionValidator.html +1 -1
  30. package/docs/classes/Repository.html +1 -1
  31. package/docs/classes/RepositoryRegistry.html +1 -1
  32. package/docs/classes/Schema.html +1 -1
  33. package/docs/classes/SliceClauseTool.html +1 -1
  34. package/docs/classes/WhereClauseTool.html +1 -1
  35. package/docs/enums/DataType.html +1 -1
  36. package/docs/enums/DecoratorTargetType.html +1 -1
  37. package/docs/enums/RelationType.html +1 -1
  38. package/docs/functions/capitalize.html +1 -1
  39. package/docs/functions/cloneDeep.html +1 -1
  40. package/docs/functions/excludeObjectKeys.html +1 -1
  41. package/docs/functions/getCtorName.html +1 -1
  42. package/docs/functions/getDecoratorTargetType.html +1 -1
  43. package/docs/functions/getValueByPath.html +1 -1
  44. package/docs/functions/isCtor.html +1 -1
  45. package/docs/functions/isPureObject.html +1 -1
  46. package/docs/functions/selectObjectKeys.html +1 -1
  47. package/docs/functions/singularize.html +1 -1
  48. package/docs/functions/stringToRegexp.html +1 -1
  49. package/docs/index.html +20 -5
  50. package/docs/interfaces/AndClause.html +1 -1
  51. package/docs/interfaces/Constructor.html +1 -1
  52. package/docs/interfaces/OrClause.html +1 -1
  53. package/docs/modules.html +6 -1
  54. package/docs/types/AnyObject.html +1 -1
  55. package/docs/types/BelongsToDefinition.html +1 -1
  56. package/docs/types/DEFAULT_PRIMARY_KEY_PROPERTY_NAME.html +1 -1
  57. package/docs/types/DatasourceDefinition.html +1 -1
  58. package/docs/types/FieldsClause.html +1 -1
  59. package/docs/types/FilterClause.html +1 -1
  60. package/docs/types/Flatten.html +1 -1
  61. package/docs/types/FullPropertyDefinition.html +1 -1
  62. package/docs/types/HasManyDefinition.html +1 -1
  63. package/docs/types/HasOneDefinition.html +1 -1
  64. package/docs/types/Identity.html +1 -1
  65. package/docs/types/IncludeClause.html +1 -1
  66. package/docs/types/ItemFilterClause.html +1 -1
  67. package/docs/types/ModelData.html +1 -1
  68. package/docs/types/ModelDefinition.html +1 -1
  69. package/docs/types/ModelId.html +1 -1
  70. package/docs/types/NestedIncludeClause.html +1 -1
  71. package/docs/types/NormalizedFieldsClause.html +1 -1
  72. package/docs/types/NormalizedIncludeClause.html +1 -1
  73. package/docs/types/OperatorClause.html +1 -1
  74. package/docs/types/OptionalUnlessRequiredId.html +1 -1
  75. package/docs/types/OrderClause.html +1 -1
  76. package/docs/types/PartialBy.html +1 -1
  77. package/docs/types/PartialWithoutId.html +1 -1
  78. package/docs/types/PolyBelongsToDefinition.html +1 -1
  79. package/docs/types/PolyHasManyDefinitionWithTargetKeys.html +1 -1
  80. package/docs/types/PolyHasManyDefinitionWithTargetRelationName.html +1 -1
  81. package/docs/types/PolyHasOneDefinitionWithTargetKeys.html +1 -1
  82. package/docs/types/PolyHasOneDefinitionWithTargetRelationName.html +1 -1
  83. package/docs/types/PropertiesClause.html +1 -1
  84. package/docs/types/PropertyDefinition.html +1 -1
  85. package/docs/types/PropertyDefinitionMap.html +1 -1
  86. package/docs/types/PropertyTransformOptions.html +2 -0
  87. package/docs/types/PropertyTransformer.html +2 -0
  88. package/docs/types/PropertyTransformerContext.html +2 -0
  89. package/docs/types/PropertyValidateOptions.html +1 -1
  90. package/docs/types/PropertyValidator.html +2 -2
  91. package/docs/types/PropertyValidatorContext.html +2 -2
  92. package/docs/types/ReferencesManyDefinition.html +1 -1
  93. package/docs/types/RelationDefinition.html +1 -1
  94. package/docs/types/RelationDefinitionMap.html +1 -1
  95. package/docs/types/WhereClause.html +1 -1
  96. package/docs/types/WithoutId.html +1 -1
  97. package/package.json +3 -3
  98. package/src/adapter/adapter.js +2 -0
  99. package/src/adapter/adapter.spec.js +9 -3
  100. package/src/adapter/decorator/data-transformation-decorator.d.ts +14 -0
  101. package/src/adapter/decorator/data-transformation-decorator.js +54 -0
  102. package/src/adapter/decorator/data-transformation-decorator.spec.js +95 -0
  103. package/src/adapter/decorator/data-validation-decorator.js +11 -18
  104. package/src/adapter/decorator/data-validation-decorator.spec.js +48 -60
  105. package/src/adapter/decorator/default-values-decorator.spec.js +89 -113
  106. package/src/adapter/decorator/index.d.ts +1 -0
  107. package/src/adapter/decorator/index.js +1 -0
  108. package/src/definition/model/index.d.ts +1 -0
  109. package/src/definition/model/index.js +1 -0
  110. package/src/definition/model/model-data-transformer.d.ts +15 -0
  111. package/src/definition/model/model-data-transformer.js +96 -0
  112. package/src/definition/model/model-data-transformer.spec.js +534 -0
  113. package/src/definition/model/model-data-validator.d.ts +1 -5
  114. package/src/definition/model/model-data-validator.js +51 -53
  115. package/src/definition/model/model-data-validator.spec.js +772 -719
  116. package/src/definition/model/properties/index.d.ts +1 -0
  117. package/src/definition/model/properties/index.js +1 -0
  118. package/src/definition/model/properties/properties-definition-validator.js +47 -0
  119. package/src/definition/model/properties/properties-definition-validator.spec.js +52 -0
  120. package/src/definition/model/properties/property-transformer/builtin/index.d.ts +1 -0
  121. package/src/definition/model/properties/property-transformer/builtin/index.js +1 -0
  122. package/src/definition/model/properties/property-transformer/builtin/trim-transformer.d.ts +6 -0
  123. package/src/definition/model/properties/property-transformer/builtin/trim-transformer.js +19 -0
  124. package/src/definition/model/properties/property-transformer/builtin/trim-transformer.spec.js +39 -0
  125. package/src/definition/model/properties/property-transformer/index.d.ts +2 -0
  126. package/src/definition/model/properties/property-transformer/index.js +2 -0
  127. package/src/definition/model/properties/property-transformer/property-transformer-registry.d.ts +29 -0
  128. package/src/definition/model/properties/property-transformer/property-transformer-registry.js +72 -0
  129. package/src/definition/model/properties/property-transformer/property-transformer-registry.spec.js +129 -0
  130. package/src/definition/model/properties/property-transformer/property-transformer.d.ts +25 -0
  131. package/src/definition/model/properties/property-transformer/property-transformer.js +1 -0
  132. package/src/definition/model/properties/property-validator/builtin/max-length-validator.js +1 -1
  133. package/src/definition/model/properties/property-validator/builtin/max-length-validator.spec.js +10 -3
  134. package/src/definition/model/properties/property-validator/builtin/min-length-validator.js +1 -1
  135. package/src/definition/model/properties/property-validator/builtin/min-length-validator.spec.js +10 -3
  136. package/src/definition/model/properties/property-validator/builtin/regexp-validator.js +1 -1
  137. package/src/definition/model/properties/property-validator/builtin/regexp-validator.spec.js +10 -3
  138. package/src/definition/model/properties/property-validator/property-validator-registry.spec.js +51 -39
  139. package/src/definition/model/properties/property-validator/property-validator.d.ts +1 -6
@@ -17,6 +17,7 @@ S.defineModel({
17
17
  });
18
18
 
19
19
  const INPUT_DATA = {};
20
+ const INPUT_DATA_WITH_DEFAULTS = {prop: 'value'};
20
21
 
21
22
  class TestAdapter extends Adapter {
22
23
  // eslint-disable-next-line no-unused-vars
@@ -65,139 +66,114 @@ describe('DefaultValuesDecorator', function () {
65
66
  });
66
67
 
67
68
  it('overrides the "create" method method and sets default values to input data', async function () {
68
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
69
- const retval = await A.create('model', INPUT_DATA);
70
- expect(retval).to.be.eql({prop: 'value'});
71
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
72
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
73
- 'model',
74
- INPUT_DATA,
69
+ sandbox.on(
70
+ U,
71
+ 'setDefaultValuesToEmptyProperties',
72
+ (modelName, modelData, onlyProvidedProperties = false) => {
73
+ expect(modelName).to.be.eq('model');
74
+ expect(modelData).to.be.eql(INPUT_DATA);
75
+ expect(onlyProvidedProperties).to.be.false;
76
+ return INPUT_DATA_WITH_DEFAULTS;
77
+ },
75
78
  );
79
+ const res = await A.create('model', INPUT_DATA);
80
+ expect(res).to.be.eql(INPUT_DATA_WITH_DEFAULTS);
81
+ expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
76
82
  });
77
83
 
78
84
  it('overrides the "replaceById" method and sets default values to input data', async function () {
79
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
80
- const retval = await A.replaceById('model', 1, INPUT_DATA);
81
- expect(retval).to.be.eql({prop: 'value'});
82
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
83
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
84
- 'model',
85
- INPUT_DATA,
85
+ sandbox.on(
86
+ U,
87
+ 'setDefaultValuesToEmptyProperties',
88
+ (modelName, modelData, onlyProvidedProperties = false) => {
89
+ expect(modelName).to.be.eq('model');
90
+ expect(modelData).to.be.eql(INPUT_DATA);
91
+ expect(onlyProvidedProperties).to.be.false;
92
+ return INPUT_DATA_WITH_DEFAULTS;
93
+ },
86
94
  );
95
+ const res = await A.replaceById('model', 1, INPUT_DATA);
96
+ expect(res).to.be.eql(INPUT_DATA_WITH_DEFAULTS);
97
+ expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
87
98
  });
88
99
 
89
100
  it('overrides the "replaceOrCreate" method and sets default values to input data', async function () {
90
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
91
- const retval = await A.replaceOrCreate('model', INPUT_DATA);
92
- expect(retval).to.be.eql({prop: 'value'});
93
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
94
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
95
- 'model',
96
- INPUT_DATA,
101
+ sandbox.on(
102
+ U,
103
+ 'setDefaultValuesToEmptyProperties',
104
+ (modelName, modelData, onlyProvidedProperties = false) => {
105
+ expect(modelName).to.be.eq('model');
106
+ expect(modelData).to.be.eql(INPUT_DATA);
107
+ expect(onlyProvidedProperties).to.be.false;
108
+ return INPUT_DATA_WITH_DEFAULTS;
109
+ },
97
110
  );
111
+ const res = await A.replaceOrCreate('model', INPUT_DATA);
112
+ expect(res).to.be.eql(INPUT_DATA_WITH_DEFAULTS);
113
+ expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
98
114
  });
99
115
 
100
- describe('overrides the "patch" method and sets default values to input data', function () {
101
- it('does not set default values to not existing properties of input data', async function () {
102
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
103
- const data = {};
104
- const retval = await A.patch('model', data);
105
- expect(retval).to.be.eql({});
106
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
107
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
108
- 'model',
109
- data,
110
- true,
111
- );
112
- });
113
-
114
- it('does set default values to input properties of null', async function () {
115
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
116
- const data = {prop: null};
117
- const retval = await A.patch('model', data);
118
- expect(retval).to.be.eql({prop: 'value'});
119
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
120
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
121
- 'model',
122
- data,
123
- true,
124
- );
125
- });
126
-
127
- it('does set default values to input properties of undefined', async function () {
128
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
129
- const data = {prop: undefined};
130
- const retval = await A.patch('model', data);
131
- expect(retval).to.be.eql({prop: 'value'});
132
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
133
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
134
- 'model',
135
- data,
136
- true,
137
- );
138
- });
116
+ it('overrides the "patch" method and sets default values to input data', async function () {
117
+ sandbox.on(
118
+ U,
119
+ 'setDefaultValuesToEmptyProperties',
120
+ (modelName, modelData, onlyProvidedProperties = false) => {
121
+ expect(modelName).to.be.eq('model');
122
+ expect(modelData).to.be.eql(INPUT_DATA);
123
+ expect(onlyProvidedProperties).to.be.true;
124
+ return INPUT_DATA_WITH_DEFAULTS;
125
+ },
126
+ );
127
+ const res = await A.patch('model', INPUT_DATA);
128
+ expect(res).to.be.eql(INPUT_DATA_WITH_DEFAULTS);
129
+ expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
139
130
  });
140
131
 
141
- describe('overrides the "patchById" method and sets default values to input data', function () {
142
- it('does not set default values to not existing properties of input data', async function () {
143
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
144
- const data = {};
145
- const retval = await A.patchById('model', 1, data);
146
- expect(retval).to.be.eql({});
147
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
148
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
149
- 'model',
150
- data,
151
- true,
152
- );
153
- });
154
-
155
- it('does set default values to input properties of null', async function () {
156
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
157
- const data = {prop: null};
158
- const retval = await A.patchById('model', 2, data);
159
- expect(retval).to.be.eql({prop: 'value'});
160
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
161
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
162
- 'model',
163
- data,
164
- true,
165
- );
166
- });
167
-
168
- it('does set default values to input properties of undefined', async function () {
169
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
170
- const data = {prop: undefined};
171
- const retval = await A.patchById('model', 3, data);
172
- expect(retval).to.be.eql({prop: 'value'});
173
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
174
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
175
- 'model',
176
- data,
177
- true,
178
- );
179
- });
132
+ it('overrides the "patchById" method and sets default values to input data', async function () {
133
+ sandbox.on(
134
+ U,
135
+ 'setDefaultValuesToEmptyProperties',
136
+ (modelName, modelData, onlyProvidedProperties = false) => {
137
+ expect(modelName).to.be.eq('model');
138
+ expect(modelData).to.be.eql(INPUT_DATA);
139
+ expect(onlyProvidedProperties).to.be.true;
140
+ return INPUT_DATA_WITH_DEFAULTS;
141
+ },
142
+ );
143
+ const res = await A.patchById('model', 1, INPUT_DATA);
144
+ expect(res).to.be.eql(INPUT_DATA_WITH_DEFAULTS);
145
+ expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
180
146
  });
181
147
 
182
148
  it('overrides the "find" method and sets default values to output data', async function () {
183
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
184
- const retval = await A.find('model');
185
- expect(retval).to.be.eql([{prop: 'value'}]);
186
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
187
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
188
- 'model',
189
- INPUT_DATA,
149
+ sandbox.on(
150
+ U,
151
+ 'setDefaultValuesToEmptyProperties',
152
+ (modelName, modelData, onlyProvidedProperties = false) => {
153
+ expect(modelName).to.be.eq('model');
154
+ expect(modelData).to.be.eql(INPUT_DATA);
155
+ expect(onlyProvidedProperties).to.be.false;
156
+ return INPUT_DATA_WITH_DEFAULTS;
157
+ },
190
158
  );
159
+ const res = await A.find('model');
160
+ expect(res).to.be.eql([INPUT_DATA_WITH_DEFAULTS]);
161
+ expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
191
162
  });
192
163
 
193
164
  it('overrides the "findById" method and sets default values to output data', async function () {
194
- sandbox.on(U, 'setDefaultValuesToEmptyProperties');
195
- const retval = await A.findById('model', 1);
196
- expect(retval).to.be.eql({prop: 'value'});
197
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
198
- expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
199
- 'model',
200
- INPUT_DATA,
165
+ sandbox.on(
166
+ U,
167
+ 'setDefaultValuesToEmptyProperties',
168
+ (modelName, modelData, onlyProvidedProperties = false) => {
169
+ expect(modelName).to.be.eq('model');
170
+ expect(modelData).to.be.eql(INPUT_DATA);
171
+ expect(onlyProvidedProperties).to.be.false;
172
+ return INPUT_DATA_WITH_DEFAULTS;
173
+ },
201
174
  );
175
+ const res = await A.findById('model', 1);
176
+ expect(res).to.be.eql(INPUT_DATA_WITH_DEFAULTS);
177
+ expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
202
178
  });
203
179
  });
@@ -3,3 +3,4 @@ export * from './default-values-decorator.js';
3
3
  export * from './data-sanitizing-decorator.js';
4
4
  export * from './data-validation-decorator.js';
5
5
  export * from './fields-filtering-decorator.js';
6
+ export * from './data-transformation-decorator.js';
@@ -3,3 +3,4 @@ export * from './default-values-decorator.js';
3
3
  export * from './data-sanitizing-decorator.js';
4
4
  export * from './data-validation-decorator.js';
5
5
  export * from './fields-filtering-decorator.js';
6
+ export * from './data-transformation-decorator.js';
@@ -3,5 +3,6 @@ export * from './properties/index.js';
3
3
  export * from './model-definition.js';
4
4
  export * from './model-data-validator.js';
5
5
  export * from './model-data-sanitizer.js';
6
+ export * from './model-data-transformer.js';
6
7
  export * from './model-definition-utils.js';
7
8
  export * from './model-definition-validator.js';
@@ -3,5 +3,6 @@ export * from './properties/index.js';
3
3
  export * from './model-definition.js';
4
4
  export * from './model-data-validator.js';
5
5
  export * from './model-data-sanitizer.js';
6
+ export * from './model-data-transformer.js';
6
7
  export * from './model-definition-utils.js';
7
8
  export * from './model-definition-validator.js';
@@ -0,0 +1,15 @@
1
+ import {ModelData} from '../../types.js';
2
+ import {Service} from '@e22m4u/js-service';
3
+
4
+ /**
5
+ * Model data transformer.
6
+ */
7
+ export declare class ModelDataTransformer extends Service {
8
+ /**
9
+ * Transform.
10
+ *
11
+ * @param modelName
12
+ * @param modelData
13
+ */
14
+ transform(modelName: string, modelData: ModelData): ModelData;
15
+ }
@@ -0,0 +1,96 @@
1
+ import {Service} from '@e22m4u/js-service';
2
+ import {cloneDeep} from '../../utils/index.js';
3
+ import {isPureObject} from '../../utils/index.js';
4
+ import {InvalidArgumentError} from '../../errors/index.js';
5
+ import {ModelDefinitionUtils} from './model-definition-utils.js';
6
+ import {PropertyTransformerRegistry} from './properties/index.js';
7
+
8
+ /**
9
+ * Model data transformer.
10
+ */
11
+ export class ModelDataTransformer extends Service {
12
+ /**
13
+ * Transform.
14
+ *
15
+ * @param {string} modelName
16
+ * @param {object} modelData
17
+ * @param {boolean} isPartial
18
+ * @returns {object}
19
+ */
20
+ transform(modelName, modelData, isPartial = false) {
21
+ if (!isPureObject(modelData))
22
+ throw new InvalidArgumentError(
23
+ 'The data of the model %v should be an Object, but %v given.',
24
+ modelName,
25
+ modelData,
26
+ );
27
+ const propDefs =
28
+ this.getService(
29
+ ModelDefinitionUtils,
30
+ ).getPropertiesDefinitionInBaseModelHierarchy(modelName);
31
+ const transformedData = cloneDeep(modelData);
32
+ const propNames = Object.keys(isPartial ? modelData : propDefs);
33
+ propNames.forEach(propName => {
34
+ const propDef = propDefs[propName];
35
+ if (!propDef) return;
36
+ const oldValue = modelData[propName];
37
+ const newValue = this._transformPropertyValue(
38
+ modelName,
39
+ propName,
40
+ propDef,
41
+ oldValue,
42
+ );
43
+ if (oldValue !== newValue) {
44
+ transformedData[propName] = newValue;
45
+ }
46
+ });
47
+ return transformedData;
48
+ }
49
+
50
+ /**
51
+ * Transform property value.
52
+ *
53
+ * @param {string} modelName
54
+ * @param {string} propName
55
+ * @param {string|object} propDef
56
+ * @param {*} propValue
57
+ * @returns {*}
58
+ */
59
+ _transformPropertyValue(modelName, propName, propDef, propValue) {
60
+ if (typeof propDef === 'string' || propDef.transform == null)
61
+ return propValue;
62
+ const transformDef = propDef.transform;
63
+ const transformerRegistry = this.getService(PropertyTransformerRegistry);
64
+ const transformFn = (
65
+ value,
66
+ transformerName,
67
+ transformerOptions = undefined,
68
+ ) => {
69
+ const transformer = transformerRegistry.getTransformer(transformerName);
70
+ const context = {transformerName, modelName, propName};
71
+ return transformer(value, transformerOptions, context);
72
+ };
73
+ if (transformDef && typeof transformDef === 'string') {
74
+ return transformFn(propValue, transformDef);
75
+ } else if (Array.isArray(transformDef)) {
76
+ return transformDef.reduce(
77
+ (value, transformerName) => transformFn(value, transformerName),
78
+ propValue,
79
+ );
80
+ } else if (transformDef !== null && typeof transformDef === 'object') {
81
+ return Object.keys(transformDef).reduce((value, transformerName) => {
82
+ const transformerOptions = transformDef[transformerName];
83
+ return transformFn(value, transformerName, transformerOptions);
84
+ }, propValue);
85
+ } else {
86
+ throw new InvalidArgumentError(
87
+ 'The provided option "transform" of the property %v in the model %v ' +
88
+ 'should be a non-empty String, an Array of String or an Object, ' +
89
+ 'but %v given.',
90
+ propName,
91
+ modelName,
92
+ transformDef,
93
+ );
94
+ }
95
+ }
96
+ }