@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.
- package/README.md +35 -4
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Adapter.html +1 -1
- package/docs/classes/AdapterLoader.html +1 -1
- package/docs/classes/AdapterRegistry.html +1 -1
- package/docs/classes/BelongsToResolver.html +1 -1
- package/docs/classes/DatasourceDefinitionValidator.html +1 -1
- package/docs/classes/DefinitionRegistry.html +1 -1
- package/docs/classes/FieldsClauseTool.html +1 -1
- package/docs/classes/HasManyResolver.html +1 -1
- package/docs/classes/HasOneResolver.html +1 -1
- package/docs/classes/IncludeClauseTool.html +1 -1
- package/docs/classes/InvalidArgumentError.html +1 -1
- package/docs/classes/InvalidOperatorValueError.html +1 -1
- package/docs/classes/ModelDataSanitizer.html +1 -1
- package/docs/classes/ModelDataTransformer.html +16 -0
- package/docs/classes/ModelDataValidator.html +2 -2
- package/docs/classes/ModelDefinitionUtils.html +1 -1
- package/docs/classes/ModelDefinitionValidator.html +1 -1
- package/docs/classes/NotImplementedError.html +1 -1
- package/docs/classes/OperatorClauseTool.html +1 -1
- package/docs/classes/OrderClauseTool.html +1 -1
- package/docs/classes/PrimaryKeysDefinitionValidator.html +1 -1
- package/docs/classes/PropertiesDefinitionValidator.html +1 -1
- package/docs/classes/PropertyTransformerRegistry.html +20 -0
- package/docs/classes/PropertyValidatorRegistry.html +1 -1
- package/docs/classes/ReferencesManyResolver.html +1 -1
- package/docs/classes/RelationsDefinitionValidator.html +1 -1
- package/docs/classes/Repository.html +1 -1
- package/docs/classes/RepositoryRegistry.html +1 -1
- package/docs/classes/Schema.html +1 -1
- package/docs/classes/SliceClauseTool.html +1 -1
- package/docs/classes/WhereClauseTool.html +1 -1
- package/docs/enums/DataType.html +1 -1
- package/docs/enums/DecoratorTargetType.html +1 -1
- package/docs/enums/RelationType.html +1 -1
- package/docs/functions/capitalize.html +1 -1
- package/docs/functions/cloneDeep.html +1 -1
- package/docs/functions/excludeObjectKeys.html +1 -1
- package/docs/functions/getCtorName.html +1 -1
- package/docs/functions/getDecoratorTargetType.html +1 -1
- package/docs/functions/getValueByPath.html +1 -1
- package/docs/functions/isCtor.html +1 -1
- package/docs/functions/isPureObject.html +1 -1
- package/docs/functions/selectObjectKeys.html +1 -1
- package/docs/functions/singularize.html +1 -1
- package/docs/functions/stringToRegexp.html +1 -1
- package/docs/index.html +20 -5
- package/docs/interfaces/AndClause.html +1 -1
- package/docs/interfaces/Constructor.html +1 -1
- package/docs/interfaces/OrClause.html +1 -1
- package/docs/modules.html +6 -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 +1 -1
- package/docs/types/IncludeClause.html +1 -1
- package/docs/types/ItemFilterClause.html +1 -1
- 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 +1 -1
- package/docs/types/OptionalUnlessRequiredId.html +1 -1
- package/docs/types/OrderClause.html +1 -1
- package/docs/types/PartialBy.html +1 -1
- package/docs/types/PartialWithoutId.html +1 -1
- 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 +1 -1
- package/docs/types/PropertyDefinition.html +1 -1
- package/docs/types/PropertyDefinitionMap.html +1 -1
- package/docs/types/PropertyTransformOptions.html +2 -0
- package/docs/types/PropertyTransformer.html +2 -0
- package/docs/types/PropertyTransformerContext.html +2 -0
- package/docs/types/PropertyValidateOptions.html +1 -1
- package/docs/types/PropertyValidator.html +2 -2
- package/docs/types/PropertyValidatorContext.html +2 -2
- 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 +1 -1
- package/docs/types/WithoutId.html +1 -1
- package/package.json +3 -3
- package/src/adapter/adapter.js +2 -0
- package/src/adapter/adapter.spec.js +9 -3
- package/src/adapter/decorator/data-transformation-decorator.d.ts +14 -0
- package/src/adapter/decorator/data-transformation-decorator.js +54 -0
- package/src/adapter/decorator/data-transformation-decorator.spec.js +95 -0
- package/src/adapter/decorator/data-validation-decorator.js +11 -18
- package/src/adapter/decorator/data-validation-decorator.spec.js +48 -60
- package/src/adapter/decorator/default-values-decorator.spec.js +89 -113
- package/src/adapter/decorator/index.d.ts +1 -0
- package/src/adapter/decorator/index.js +1 -0
- package/src/definition/model/index.d.ts +1 -0
- package/src/definition/model/index.js +1 -0
- package/src/definition/model/model-data-transformer.d.ts +15 -0
- package/src/definition/model/model-data-transformer.js +96 -0
- package/src/definition/model/model-data-transformer.spec.js +534 -0
- package/src/definition/model/model-data-validator.d.ts +1 -5
- package/src/definition/model/model-data-validator.js +51 -53
- package/src/definition/model/model-data-validator.spec.js +772 -719
- 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 +47 -0
- package/src/definition/model/properties/properties-definition-validator.spec.js +52 -0
- package/src/definition/model/properties/property-transformer/builtin/index.d.ts +1 -0
- package/src/definition/model/properties/property-transformer/builtin/index.js +1 -0
- package/src/definition/model/properties/property-transformer/builtin/trim-transformer.d.ts +6 -0
- package/src/definition/model/properties/property-transformer/builtin/trim-transformer.js +19 -0
- package/src/definition/model/properties/property-transformer/builtin/trim-transformer.spec.js +39 -0
- package/src/definition/model/properties/property-transformer/index.d.ts +2 -0
- package/src/definition/model/properties/property-transformer/index.js +2 -0
- package/src/definition/model/properties/property-transformer/property-transformer-registry.d.ts +29 -0
- package/src/definition/model/properties/property-transformer/property-transformer-registry.js +72 -0
- package/src/definition/model/properties/property-transformer/property-transformer-registry.spec.js +129 -0
- package/src/definition/model/properties/property-transformer/property-transformer.d.ts +25 -0
- package/src/definition/model/properties/property-transformer/property-transformer.js +1 -0
- package/src/definition/model/properties/property-validator/builtin/max-length-validator.js +1 -1
- package/src/definition/model/properties/property-validator/builtin/max-length-validator.spec.js +10 -3
- package/src/definition/model/properties/property-validator/builtin/min-length-validator.js +1 -1
- package/src/definition/model/properties/property-validator/builtin/min-length-validator.spec.js +10 -3
- package/src/definition/model/properties/property-validator/builtin/regexp-validator.js +1 -1
- package/src/definition/model/properties/property-validator/builtin/regexp-validator.spec.js +10 -3
- package/src/definition/model/properties/property-validator/property-validator-registry.spec.js +51 -39
- 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(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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(
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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(
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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,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
|
+
}
|