@e22m4u/js-repository 0.0.31
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/.c8rc +9 -0
- package/.commitlintrc +5 -0
- package/.editorconfig +13 -0
- package/.eslintignore +1 -0
- package/.eslintrc.cjs +27 -0
- package/.husky/commit-msg +4 -0
- package/.husky/pre-commit +9 -0
- package/.mocharc.cjs +7 -0
- package/.prettierrc +7 -0
- package/LICENSE +21 -0
- package/README.md +523 -0
- package/mocha.setup.js +10 -0
- package/package.json +57 -0
- package/src/adapter/adapter-loader.d.ts +16 -0
- package/src/adapter/adapter-loader.js +63 -0
- package/src/adapter/adapter-loader.spec.js +31 -0
- package/src/adapter/adapter-registry.d.ts +14 -0
- package/src/adapter/adapter-registry.js +36 -0
- package/src/adapter/adapter-registry.spec.js +36 -0
- package/src/adapter/adapter.d.ts +118 -0
- package/src/adapter/adapter.js +181 -0
- package/src/adapter/adapter.spec.js +144 -0
- package/src/adapter/builtin/memory-adapter.d.ts +118 -0
- package/src/adapter/builtin/memory-adapter.js +342 -0
- package/src/adapter/builtin/memory-adapter.spec.js +2925 -0
- package/src/adapter/decorator/data-sanitizing-decorator.d.ts +13 -0
- package/src/adapter/decorator/data-sanitizing-decorator.js +44 -0
- package/src/adapter/decorator/data-sanitizing-decorator.spec.js +59 -0
- package/src/adapter/decorator/data-validation-decorator.d.ts +13 -0
- package/src/adapter/decorator/data-validation-decorator.js +41 -0
- package/src/adapter/decorator/data-validation-decorator.spec.js +59 -0
- package/src/adapter/decorator/default-values-decorator.d.ts +13 -0
- package/src/adapter/decorator/default-values-decorator.js +57 -0
- package/src/adapter/decorator/default-values-decorator.spec.js +141 -0
- package/src/adapter/decorator/fields-filtering-decorator.d.ts +13 -0
- package/src/adapter/decorator/fields-filtering-decorator.js +72 -0
- package/src/adapter/decorator/fields-filtering-decorator.spec.js +119 -0
- package/src/adapter/decorator/inclusion-decorator.d.ts +13 -0
- package/src/adapter/decorator/inclusion-decorator.js +78 -0
- package/src/adapter/decorator/inclusion-decorator.spec.js +117 -0
- package/src/adapter/decorator/index.d.ts +5 -0
- package/src/adapter/decorator/index.js +5 -0
- package/src/adapter/index.d.ts +3 -0
- package/src/adapter/index.js +3 -0
- package/src/definition/datasource/datasource-definition-validator.d.ts +14 -0
- package/src/definition/datasource/datasource-definition-validator.js +33 -0
- package/src/definition/datasource/datasource-definition-validator.spec.js +63 -0
- package/src/definition/datasource/datasource-definition.d.ts +7 -0
- package/src/definition/datasource/index.d.ts +2 -0
- package/src/definition/datasource/index.js +1 -0
- package/src/definition/definition-registry.d.ts +50 -0
- package/src/definition/definition-registry.js +98 -0
- package/src/definition/definition-registry.spec.js +78 -0
- package/src/definition/index.d.ts +3 -0
- package/src/definition/index.js +3 -0
- package/src/definition/model/index.d.ts +7 -0
- package/src/definition/model/index.js +6 -0
- package/src/definition/model/model-data-sanitizer.d.ts +15 -0
- package/src/definition/model/model-data-sanitizer.js +33 -0
- package/src/definition/model/model-data-validator.d.ts +32 -0
- package/src/definition/model/model-data-validator.js +144 -0
- package/src/definition/model/model-data-validator.spec.js +1889 -0
- package/src/definition/model/model-definition-utils.d.ts +161 -0
- package/src/definition/model/model-definition-utils.js +371 -0
- package/src/definition/model/model-definition-utils.spec.js +1474 -0
- package/src/definition/model/model-definition-validator.d.ts +14 -0
- package/src/definition/model/model-definition-validator.js +83 -0
- package/src/definition/model/model-definition-validator.spec.js +143 -0
- package/src/definition/model/model-definition.d.ts +28 -0
- package/src/definition/model/properties/data-type.d.ts +11 -0
- package/src/definition/model/properties/data-type.js +11 -0
- package/src/definition/model/properties/default-values-definition-validator.d.ts +15 -0
- package/src/definition/model/properties/default-values-definition-validator.js +53 -0
- package/src/definition/model/properties/default-values-definition-validator.spec.js +136 -0
- package/src/definition/model/properties/index.d.ts +5 -0
- package/src/definition/model/properties/index.js +4 -0
- package/src/definition/model/properties/primary-keys-definition-validator.d.ts +15 -0
- package/src/definition/model/properties/primary-keys-definition-validator.js +55 -0
- package/src/definition/model/properties/primary-keys-definition-validator.spec.js +145 -0
- package/src/definition/model/properties/properties-definition-validator.d.ts +15 -0
- package/src/definition/model/properties/properties-definition-validator.js +194 -0
- package/src/definition/model/properties/properties-definition-validator.spec.js +373 -0
- package/src/definition/model/properties/property-definition.d.ts +20 -0
- package/src/definition/model/relations/index.d.ts +3 -0
- package/src/definition/model/relations/index.js +2 -0
- package/src/definition/model/relations/relation-definition.d.ts +254 -0
- package/src/definition/model/relations/relation-type.d.ts +9 -0
- package/src/definition/model/relations/relation-type.js +9 -0
- package/src/definition/model/relations/relations-definition-validator.d.ts +15 -0
- package/src/definition/model/relations/relations-definition-validator.js +449 -0
- package/src/definition/model/relations/relations-definition-validator.spec.js +772 -0
- package/src/errors/index.d.ts +3 -0
- package/src/errors/index.js +3 -0
- package/src/errors/invalid-argument-error.d.ts +6 -0
- package/src/errors/invalid-argument-error.js +6 -0
- package/src/errors/invalid-argument-error.spec.js +33 -0
- package/src/errors/invalid-operator-value-error.d.ts +13 -0
- package/src/errors/invalid-operator-value-error.js +24 -0
- package/src/errors/invalid-operator-value-error.spec.js +11 -0
- package/src/errors/not-implemented-error.d.ts +6 -0
- package/src/errors/not-implemented-error.js +6 -0
- package/src/errors/not-implemented-error.spec.js +33 -0
- package/src/filter/fields-clause-tool.d.ts +38 -0
- package/src/filter/fields-clause-tool.js +88 -0
- package/src/filter/fields-clause-tool.spec.js +133 -0
- package/src/filter/filter.d.ts +335 -0
- package/src/filter/include-clause-tool.d.ts +53 -0
- package/src/filter/include-clause-tool.js +364 -0
- package/src/filter/include-clause-tool.spec.js +653 -0
- package/src/filter/index.d.ts +7 -0
- package/src/filter/index.js +6 -0
- package/src/filter/operator-clause-tool.d.ts +223 -0
- package/src/filter/operator-clause-tool.js +515 -0
- package/src/filter/operator-clause-tool.spec.js +1064 -0
- package/src/filter/order-clause-tool.d.ts +32 -0
- package/src/filter/order-clause-tool.js +97 -0
- package/src/filter/order-clause-tool.spec.js +438 -0
- package/src/filter/slice-clause-tool.d.ts +30 -0
- package/src/filter/slice-clause-tool.js +65 -0
- package/src/filter/slice-clause-tool.spec.js +117 -0
- package/src/filter/where-clause-tool.d.ts +23 -0
- package/src/filter/where-clause-tool.js +165 -0
- package/src/filter/where-clause-tool.spec.js +280 -0
- package/src/index.d.ts +9 -0
- package/src/index.js +8 -0
- package/src/relations/belongs-to-resolver.d.ts +46 -0
- package/src/relations/belongs-to-resolver.js +242 -0
- package/src/relations/belongs-to-resolver.spec.js +1047 -0
- package/src/relations/has-many-resolver.d.ts +67 -0
- package/src/relations/has-many-resolver.js +317 -0
- package/src/relations/has-many-resolver.spec.js +2911 -0
- package/src/relations/has-one-resolver.d.ts +67 -0
- package/src/relations/has-one-resolver.js +311 -0
- package/src/relations/has-one-resolver.spec.js +2274 -0
- package/src/relations/index.d.ts +4 -0
- package/src/relations/index.js +4 -0
- package/src/relations/references-many-resolver.d.ts +27 -0
- package/src/relations/references-many-resolver.js +113 -0
- package/src/relations/references-many-resolver.spec.js +631 -0
- package/src/repository/index.d.ts +2 -0
- package/src/repository/index.js +2 -0
- package/src/repository/repository-registry.d.ts +29 -0
- package/src/repository/repository-registry.js +57 -0
- package/src/repository/repository-registry.spec.js +38 -0
- package/src/repository/repository.d.ts +164 -0
- package/src/repository/repository.js +207 -0
- package/src/repository/repository.spec.js +202 -0
- package/src/schema.d.ts +37 -0
- package/src/schema.js +41 -0
- package/src/types.d.ts +30 -0
- package/src/utils/capitalize.d.ts +6 -0
- package/src/utils/capitalize.js +10 -0
- package/src/utils/capitalize.spec.js +14 -0
- package/src/utils/clone-deep.d.ts +6 -0
- package/src/utils/clone-deep.js +61 -0
- package/src/utils/clone-deep.spec.js +28 -0
- package/src/utils/exclude-object-keys.d.ts +10 -0
- package/src/utils/exclude-object-keys.js +20 -0
- package/src/utils/exclude-object-keys.spec.js +49 -0
- package/src/utils/get-ctor-name.d.ts +6 -0
- package/src/utils/get-ctor-name.js +11 -0
- package/src/utils/get-ctor-name.spec.js +17 -0
- package/src/utils/get-value-by-path.d.ts +12 -0
- package/src/utils/get-value-by-path.js +23 -0
- package/src/utils/get-value-by-path.spec.js +36 -0
- package/src/utils/index.d.ts +10 -0
- package/src/utils/index.js +10 -0
- package/src/utils/is-ctor.d.ts +7 -0
- package/src/utils/is-ctor.js +10 -0
- package/src/utils/is-ctor.spec.js +26 -0
- package/src/utils/is-pure-object.d.ts +6 -0
- package/src/utils/is-pure-object.js +15 -0
- package/src/utils/is-pure-object.spec.js +25 -0
- package/src/utils/select-object-keys.d.ts +10 -0
- package/src/utils/select-object-keys.js +37 -0
- package/src/utils/select-object-keys.spec.js +40 -0
- package/src/utils/singularize.d.ts +6 -0
- package/src/utils/singularize.js +22 -0
- package/src/utils/singularize.spec.js +23 -0
- package/src/utils/string-to-regexp.d.ts +10 -0
- package/src/utils/string-to-regexp.js +22 -0
- package/src/utils/string-to-regexp.spec.js +35 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {ModelData} from '../../types.js';
|
|
2
|
+
import {Service} from '@e22m4u/js-service';
|
|
3
|
+
import {DataType} from './properties/index.js';
|
|
4
|
+
import {RelationDefinition} from './relations/index.js';
|
|
5
|
+
import {PropertyDefinitionMap} from './model-definition.js';
|
|
6
|
+
import {RelationDefinitionMap} from './model-definition.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Default primary key property name.
|
|
10
|
+
*/
|
|
11
|
+
export type DEFAULT_PRIMARY_KEY_PROPERTY_NAME = 'id';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Model definition utils.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ModelDefinitionUtils extends Service {
|
|
17
|
+
/**
|
|
18
|
+
* Get primary key as property name.
|
|
19
|
+
*
|
|
20
|
+
* @param modelName
|
|
21
|
+
*/
|
|
22
|
+
getPrimaryKeyAsPropertyName(modelName: string): string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get primary key as column name.
|
|
26
|
+
*
|
|
27
|
+
* @param modelName
|
|
28
|
+
*/
|
|
29
|
+
getPrimaryKeyAsColumnName(modelName: string): string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get table name by model name.
|
|
33
|
+
*
|
|
34
|
+
* @param modelName
|
|
35
|
+
*/
|
|
36
|
+
getTableNameByModelName(modelName: string): string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get column name by property name.
|
|
40
|
+
*
|
|
41
|
+
* @param modelName
|
|
42
|
+
* @param propertyName
|
|
43
|
+
*/
|
|
44
|
+
getColumnNameByPropertyName(modelName: string, propertyName: string): string;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get default property value.
|
|
48
|
+
*
|
|
49
|
+
* @param modelName
|
|
50
|
+
* @param propertyName
|
|
51
|
+
*/
|
|
52
|
+
getDefaultPropertyValue(modelName: string, propertyName: string): unknown;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Set default values to empty properties.
|
|
56
|
+
*
|
|
57
|
+
* @param modelName
|
|
58
|
+
* @param modelData
|
|
59
|
+
* @param onlyProvidedProperties
|
|
60
|
+
*/
|
|
61
|
+
setDefaultValuesToEmptyProperties<T extends ModelData>(
|
|
62
|
+
modelName: string,
|
|
63
|
+
modelData: T,
|
|
64
|
+
onlyProvidedProperties?: boolean,
|
|
65
|
+
): T;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Convert property names to column names.
|
|
69
|
+
*
|
|
70
|
+
* @param modelName
|
|
71
|
+
* @param modelData
|
|
72
|
+
*/
|
|
73
|
+
convertPropertyNamesToColumnNames(
|
|
74
|
+
modelName: string,
|
|
75
|
+
modelData: ModelData,
|
|
76
|
+
): ModelData;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Convert column names to property names.
|
|
80
|
+
*
|
|
81
|
+
* @param modelName
|
|
82
|
+
* @param tableData
|
|
83
|
+
*/
|
|
84
|
+
convertColumnNamesToPropertyNames(
|
|
85
|
+
modelName: string,
|
|
86
|
+
tableData: ModelData,
|
|
87
|
+
): ModelData;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get data type by property name.
|
|
91
|
+
*
|
|
92
|
+
* @param modelName
|
|
93
|
+
* @param propertyName
|
|
94
|
+
*/
|
|
95
|
+
getDataTypeByPropertyName(modelName: string, propertyName: string): DataType;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get own properties definition of primary keys.
|
|
99
|
+
*
|
|
100
|
+
* @param modelName
|
|
101
|
+
*/
|
|
102
|
+
getOwnPropertiesDefinitionOfPrimaryKeys(
|
|
103
|
+
modelName: string,
|
|
104
|
+
): PropertyDefinitionMap;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get own properties definition without primary keys.
|
|
108
|
+
*
|
|
109
|
+
* @param modelName
|
|
110
|
+
*/
|
|
111
|
+
getOwnPropertiesDefinitionWithoutPrimaryKeys(
|
|
112
|
+
modelName: string,
|
|
113
|
+
): PropertyDefinitionMap;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get properties definition in base model hierarchy.
|
|
117
|
+
*
|
|
118
|
+
* @param modelName
|
|
119
|
+
*/
|
|
120
|
+
getPropertiesDefinitionInBaseModelHierarchy(
|
|
121
|
+
modelName: string,
|
|
122
|
+
): PropertyDefinitionMap;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get own relations definition.
|
|
126
|
+
*
|
|
127
|
+
* @param modelName
|
|
128
|
+
*/
|
|
129
|
+
getOwnRelationsDefinition(modelName: string): RelationDefinitionMap;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Get relations definition in base model hierarchy.
|
|
133
|
+
*
|
|
134
|
+
* @param modelName
|
|
135
|
+
*/
|
|
136
|
+
getRelationsDefinitionInBaseModelHierarchy(
|
|
137
|
+
modelName: string,
|
|
138
|
+
): RelationDefinitionMap;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get relation definition by name.
|
|
142
|
+
*
|
|
143
|
+
* @param modelName
|
|
144
|
+
* @param relationName
|
|
145
|
+
*/
|
|
146
|
+
getRelationDefinitionByName(
|
|
147
|
+
modelName: string,
|
|
148
|
+
relationName: string,
|
|
149
|
+
): RelationDefinition;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Exclude object keys by relation names.
|
|
153
|
+
*
|
|
154
|
+
* @param modelName
|
|
155
|
+
* @param modelData
|
|
156
|
+
*/
|
|
157
|
+
excludeObjectKeysByRelationNames<T extends ModelData>(
|
|
158
|
+
modelName: string,
|
|
159
|
+
modelData: T,
|
|
160
|
+
): Partial<T>;
|
|
161
|
+
}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import {Service} from '@e22m4u/js-service';
|
|
2
|
+
import {DataType} from './properties/index.js';
|
|
3
|
+
import {cloneDeep} from '../../utils/index.js';
|
|
4
|
+
import {excludeObjectKeys} from '../../utils/index.js';
|
|
5
|
+
import {InvalidArgumentError} from '../../errors/index.js';
|
|
6
|
+
import {DefinitionRegistry} from '../definition-registry.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Default primary key property name.
|
|
10
|
+
*
|
|
11
|
+
* @type {string}
|
|
12
|
+
*/
|
|
13
|
+
export const DEFAULT_PRIMARY_KEY_PROPERTY_NAME = 'id';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Model definition utils.
|
|
17
|
+
*/
|
|
18
|
+
export class ModelDefinitionUtils extends Service {
|
|
19
|
+
/**
|
|
20
|
+
* Get primary key as property name.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} modelName
|
|
23
|
+
* @returns {string}
|
|
24
|
+
*/
|
|
25
|
+
getPrimaryKeyAsPropertyName(modelName) {
|
|
26
|
+
const propDefs =
|
|
27
|
+
this.getPropertiesDefinitionInBaseModelHierarchy(modelName);
|
|
28
|
+
const propNames = Object.keys(propDefs).filter(propName => {
|
|
29
|
+
const propDef = propDefs[propName];
|
|
30
|
+
return propDef && typeof propDef === 'object' && propDef.primaryKey;
|
|
31
|
+
});
|
|
32
|
+
if (propNames.length < 1) {
|
|
33
|
+
const isDefaultPrimaryKeyAlreadyInUse = Object.keys(propDefs).includes(
|
|
34
|
+
DEFAULT_PRIMARY_KEY_PROPERTY_NAME,
|
|
35
|
+
);
|
|
36
|
+
if (isDefaultPrimaryKeyAlreadyInUse)
|
|
37
|
+
throw new InvalidArgumentError(
|
|
38
|
+
'The property name %v of the model %v is defined as a regular property. ' +
|
|
39
|
+
'In this case, a primary key should be defined explicitly. ' +
|
|
40
|
+
'Do use the option "primaryKey" to specify the primary key.',
|
|
41
|
+
DEFAULT_PRIMARY_KEY_PROPERTY_NAME,
|
|
42
|
+
modelName,
|
|
43
|
+
);
|
|
44
|
+
return DEFAULT_PRIMARY_KEY_PROPERTY_NAME;
|
|
45
|
+
}
|
|
46
|
+
return propNames[0];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get primary key as column name.
|
|
51
|
+
*
|
|
52
|
+
* @param {string} modelName
|
|
53
|
+
* @returns {string}
|
|
54
|
+
*/
|
|
55
|
+
getPrimaryKeyAsColumnName(modelName) {
|
|
56
|
+
const pkPropName = this.getPrimaryKeyAsPropertyName(modelName);
|
|
57
|
+
let pkColName;
|
|
58
|
+
try {
|
|
59
|
+
pkColName = this.getColumnNameByPropertyName(modelName, pkPropName);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (!(error instanceof InvalidArgumentError)) throw error;
|
|
62
|
+
}
|
|
63
|
+
if (pkColName === undefined) return pkPropName;
|
|
64
|
+
return pkColName;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get table name by model name.
|
|
69
|
+
*
|
|
70
|
+
* @param {string} modelName
|
|
71
|
+
* @returns {string}
|
|
72
|
+
*/
|
|
73
|
+
getTableNameByModelName(modelName) {
|
|
74
|
+
const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
|
|
75
|
+
return modelDef.tableName ?? modelName;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get column name by property name.
|
|
80
|
+
*
|
|
81
|
+
* @param {string} modelName
|
|
82
|
+
* @param {string} propertyName
|
|
83
|
+
* @returns {string}
|
|
84
|
+
*/
|
|
85
|
+
getColumnNameByPropertyName(modelName, propertyName) {
|
|
86
|
+
const propDefs =
|
|
87
|
+
this.getPropertiesDefinitionInBaseModelHierarchy(modelName);
|
|
88
|
+
const propDef = propDefs[propertyName];
|
|
89
|
+
if (!propDef)
|
|
90
|
+
throw new InvalidArgumentError(
|
|
91
|
+
'The model %v does not have the property %v.',
|
|
92
|
+
modelName,
|
|
93
|
+
propertyName,
|
|
94
|
+
);
|
|
95
|
+
if (propDef && typeof propDef === 'object')
|
|
96
|
+
return propDef.columnName ?? propertyName;
|
|
97
|
+
return propertyName;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Get default property value.
|
|
102
|
+
*
|
|
103
|
+
* @param {string} modelName
|
|
104
|
+
* @param {string} propertyName
|
|
105
|
+
* @returns {*}
|
|
106
|
+
*/
|
|
107
|
+
getDefaultPropertyValue(modelName, propertyName) {
|
|
108
|
+
const propDefs =
|
|
109
|
+
this.getPropertiesDefinitionInBaseModelHierarchy(modelName);
|
|
110
|
+
const propDef = propDefs[propertyName];
|
|
111
|
+
if (!propDef)
|
|
112
|
+
throw new InvalidArgumentError(
|
|
113
|
+
'The model %v does not have the property %v.',
|
|
114
|
+
modelName,
|
|
115
|
+
propertyName,
|
|
116
|
+
);
|
|
117
|
+
if (propDef && typeof propDef === 'object')
|
|
118
|
+
return propDef.default instanceof Function
|
|
119
|
+
? propDef.default()
|
|
120
|
+
: propDef.default;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Set default values for empty properties.
|
|
125
|
+
*
|
|
126
|
+
* @param {string} modelName
|
|
127
|
+
* @param {object} modelData
|
|
128
|
+
* @param {boolean|undefined} onlyProvidedProperties
|
|
129
|
+
* @returns {object}
|
|
130
|
+
*/
|
|
131
|
+
setDefaultValuesToEmptyProperties(
|
|
132
|
+
modelName,
|
|
133
|
+
modelData,
|
|
134
|
+
onlyProvidedProperties = false,
|
|
135
|
+
) {
|
|
136
|
+
const propDefs =
|
|
137
|
+
this.getPropertiesDefinitionInBaseModelHierarchy(modelName);
|
|
138
|
+
const propNames = onlyProvidedProperties
|
|
139
|
+
? Object.keys(modelData)
|
|
140
|
+
: Object.keys(propDefs);
|
|
141
|
+
const extendedData = cloneDeep(modelData);
|
|
142
|
+
propNames.forEach(propName => {
|
|
143
|
+
const value = extendedData[propName];
|
|
144
|
+
if (value != null) return;
|
|
145
|
+
const propDef = propDefs[propName];
|
|
146
|
+
if (
|
|
147
|
+
propDef &&
|
|
148
|
+
typeof propDef === 'object' &&
|
|
149
|
+
propDef.default !== undefined
|
|
150
|
+
) {
|
|
151
|
+
extendedData[propName] = this.getDefaultPropertyValue(
|
|
152
|
+
modelName,
|
|
153
|
+
propName,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
return extendedData;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Convert property names to column names.
|
|
162
|
+
*
|
|
163
|
+
* @param {string} modelName
|
|
164
|
+
* @param {object} modelData
|
|
165
|
+
* @returns {object}
|
|
166
|
+
*/
|
|
167
|
+
convertPropertyNamesToColumnNames(modelName, modelData) {
|
|
168
|
+
const propDefs =
|
|
169
|
+
this.getPropertiesDefinitionInBaseModelHierarchy(modelName);
|
|
170
|
+
const propNames = Object.keys(propDefs);
|
|
171
|
+
const convertedData = cloneDeep(modelData);
|
|
172
|
+
propNames.forEach(propName => {
|
|
173
|
+
if (!(propName in convertedData)) return;
|
|
174
|
+
const colName = this.getColumnNameByPropertyName(modelName, propName);
|
|
175
|
+
if (propName === colName) return;
|
|
176
|
+
const propValue = convertedData[propName];
|
|
177
|
+
delete convertedData[propName];
|
|
178
|
+
convertedData[colName] = propValue;
|
|
179
|
+
});
|
|
180
|
+
return convertedData;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Convert column names to property names.
|
|
185
|
+
*
|
|
186
|
+
* @param {string} modelName
|
|
187
|
+
* @param {object} tableData
|
|
188
|
+
* @returns {object}
|
|
189
|
+
*/
|
|
190
|
+
convertColumnNamesToPropertyNames(modelName, tableData) {
|
|
191
|
+
const propDefs =
|
|
192
|
+
this.getPropertiesDefinitionInBaseModelHierarchy(modelName);
|
|
193
|
+
const propNames = Object.keys(propDefs);
|
|
194
|
+
const convertedData = cloneDeep(tableData);
|
|
195
|
+
propNames.forEach(propName => {
|
|
196
|
+
const colName = this.getColumnNameByPropertyName(modelName, propName);
|
|
197
|
+
if (!(colName in convertedData) || colName === propName) return;
|
|
198
|
+
const colValue = convertedData[colName];
|
|
199
|
+
delete convertedData[colName];
|
|
200
|
+
convertedData[propName] = colValue;
|
|
201
|
+
});
|
|
202
|
+
return convertedData;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Get data type by property name.
|
|
207
|
+
*
|
|
208
|
+
* @param {string} modelName
|
|
209
|
+
* @param {string} propertyName
|
|
210
|
+
* @returns {string}
|
|
211
|
+
*/
|
|
212
|
+
getDataTypeByPropertyName(modelName, propertyName) {
|
|
213
|
+
const propDefs =
|
|
214
|
+
this.getPropertiesDefinitionInBaseModelHierarchy(modelName);
|
|
215
|
+
const propDef = propDefs[propertyName];
|
|
216
|
+
if (!propDef) {
|
|
217
|
+
const pkPropName = this.getPrimaryKeyAsPropertyName(modelName);
|
|
218
|
+
if (pkPropName === propertyName) return DataType.ANY;
|
|
219
|
+
throw new InvalidArgumentError(
|
|
220
|
+
'The model %v does not have the property %v.',
|
|
221
|
+
modelName,
|
|
222
|
+
propertyName,
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
if (typeof propDef === 'string') return propDef;
|
|
226
|
+
return propDef.type;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Get own properties definition of primary keys.
|
|
231
|
+
*
|
|
232
|
+
* @param {string} modelName
|
|
233
|
+
* @returns {object}
|
|
234
|
+
*/
|
|
235
|
+
getOwnPropertiesDefinitionOfPrimaryKeys(modelName) {
|
|
236
|
+
const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
|
|
237
|
+
const propDefs = modelDef.properties ?? {};
|
|
238
|
+
const pkPropNames = Object.keys(propDefs).filter(propName => {
|
|
239
|
+
const propDef = propDefs[propName];
|
|
240
|
+
return typeof propDef === 'object' && propDef.primaryKey;
|
|
241
|
+
});
|
|
242
|
+
return pkPropNames.reduce((a, k) => ({...a, [k]: propDefs[k]}), {});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Get own properties definition without primary keys.
|
|
247
|
+
*
|
|
248
|
+
* @param {string} modelName
|
|
249
|
+
* @returns {object}
|
|
250
|
+
*/
|
|
251
|
+
getOwnPropertiesDefinitionWithoutPrimaryKeys(modelName) {
|
|
252
|
+
const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
|
|
253
|
+
const propDefs = modelDef.properties ?? {};
|
|
254
|
+
return Object.keys(propDefs).reduce((result, propName) => {
|
|
255
|
+
const propDef = propDefs[propName];
|
|
256
|
+
if (typeof propDef === 'object' && propDef.primaryKey) return result;
|
|
257
|
+
return {...result, [propName]: propDef};
|
|
258
|
+
}, {});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Get properties definition in base model hierarchy.
|
|
263
|
+
*
|
|
264
|
+
* @param {string} modelName
|
|
265
|
+
* @returns {object}
|
|
266
|
+
*/
|
|
267
|
+
getPropertiesDefinitionInBaseModelHierarchy(modelName) {
|
|
268
|
+
let result = {};
|
|
269
|
+
let pkPropDefs = {};
|
|
270
|
+
const recursion = (currModelName, prevModelName = undefined) => {
|
|
271
|
+
if (currModelName === prevModelName)
|
|
272
|
+
throw new InvalidArgumentError(
|
|
273
|
+
'The model %v has a circular inheritance.',
|
|
274
|
+
currModelName,
|
|
275
|
+
);
|
|
276
|
+
if (Object.keys(pkPropDefs).length === 0) {
|
|
277
|
+
pkPropDefs =
|
|
278
|
+
this.getOwnPropertiesDefinitionOfPrimaryKeys(currModelName);
|
|
279
|
+
result = {...result, ...pkPropDefs};
|
|
280
|
+
}
|
|
281
|
+
const regularPropDefs =
|
|
282
|
+
this.getOwnPropertiesDefinitionWithoutPrimaryKeys(currModelName);
|
|
283
|
+
result = {...regularPropDefs, ...result};
|
|
284
|
+
const modelDef =
|
|
285
|
+
this.getService(DefinitionRegistry).getModel(currModelName);
|
|
286
|
+
if (modelDef.base) recursion(modelDef.base, currModelName);
|
|
287
|
+
};
|
|
288
|
+
recursion(modelName);
|
|
289
|
+
return result;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Get own relations definition.
|
|
294
|
+
*
|
|
295
|
+
* @param {string} modelName
|
|
296
|
+
* @returns {object}
|
|
297
|
+
*/
|
|
298
|
+
getOwnRelationsDefinition(modelName) {
|
|
299
|
+
const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
|
|
300
|
+
return modelDef.relations ?? {};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Get relations definition in base model hierarchy.
|
|
305
|
+
*
|
|
306
|
+
* @param {string} modelName
|
|
307
|
+
* @returns {object}
|
|
308
|
+
*/
|
|
309
|
+
getRelationsDefinitionInBaseModelHierarchy(modelName) {
|
|
310
|
+
let result = {};
|
|
311
|
+
const recursion = (currModelName, prevModelName = undefined) => {
|
|
312
|
+
if (currModelName === prevModelName)
|
|
313
|
+
throw new InvalidArgumentError(
|
|
314
|
+
'The model %v has a circular inheritance.',
|
|
315
|
+
currModelName,
|
|
316
|
+
);
|
|
317
|
+
const modelDef =
|
|
318
|
+
this.getService(DefinitionRegistry).getModel(currModelName);
|
|
319
|
+
const ownRelDefs = modelDef.relations ?? {};
|
|
320
|
+
result = {...ownRelDefs, ...result};
|
|
321
|
+
if (modelDef.base) recursion(modelDef.base, currModelName);
|
|
322
|
+
};
|
|
323
|
+
recursion(modelName);
|
|
324
|
+
return result;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Get relation definition by name.
|
|
329
|
+
*
|
|
330
|
+
* @param {string} modelName
|
|
331
|
+
* @param {string} relationName
|
|
332
|
+
* @returns {object}
|
|
333
|
+
*/
|
|
334
|
+
getRelationDefinitionByName(modelName, relationName) {
|
|
335
|
+
const relDefs = this.getRelationsDefinitionInBaseModelHierarchy(modelName);
|
|
336
|
+
const relNames = Object.keys(relDefs);
|
|
337
|
+
let foundDef;
|
|
338
|
+
for (const relName of relNames) {
|
|
339
|
+
if (relName === relationName) {
|
|
340
|
+
foundDef = relDefs[relName];
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (!foundDef)
|
|
345
|
+
throw new InvalidArgumentError(
|
|
346
|
+
'The model %v does not have relation name %v.',
|
|
347
|
+
modelName,
|
|
348
|
+
relationName,
|
|
349
|
+
);
|
|
350
|
+
return foundDef;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Exclude object keys by relation names.
|
|
355
|
+
*
|
|
356
|
+
* @param {string} modelName
|
|
357
|
+
* @param {object} modelData
|
|
358
|
+
* @returns {object}
|
|
359
|
+
*/
|
|
360
|
+
excludeObjectKeysByRelationNames(modelName, modelData) {
|
|
361
|
+
if (!modelData || typeof modelData !== 'object' || Array.isArray(modelData))
|
|
362
|
+
throw new InvalidArgumentError(
|
|
363
|
+
'The second argument of ModelDefinitionUtils.excludeObjectKeysByRelationNames ' +
|
|
364
|
+
'must be an Object, but %v given.',
|
|
365
|
+
modelData,
|
|
366
|
+
);
|
|
367
|
+
const relDefs = this.getRelationsDefinitionInBaseModelHierarchy(modelName);
|
|
368
|
+
const relNames = Object.keys(relDefs);
|
|
369
|
+
return excludeObjectKeys(modelData, relNames);
|
|
370
|
+
}
|
|
371
|
+
}
|