@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.
Files changed (183) hide show
  1. package/.c8rc +9 -0
  2. package/.commitlintrc +5 -0
  3. package/.editorconfig +13 -0
  4. package/.eslintignore +1 -0
  5. package/.eslintrc.cjs +27 -0
  6. package/.husky/commit-msg +4 -0
  7. package/.husky/pre-commit +9 -0
  8. package/.mocharc.cjs +7 -0
  9. package/.prettierrc +7 -0
  10. package/LICENSE +21 -0
  11. package/README.md +523 -0
  12. package/mocha.setup.js +10 -0
  13. package/package.json +57 -0
  14. package/src/adapter/adapter-loader.d.ts +16 -0
  15. package/src/adapter/adapter-loader.js +63 -0
  16. package/src/adapter/adapter-loader.spec.js +31 -0
  17. package/src/adapter/adapter-registry.d.ts +14 -0
  18. package/src/adapter/adapter-registry.js +36 -0
  19. package/src/adapter/adapter-registry.spec.js +36 -0
  20. package/src/adapter/adapter.d.ts +118 -0
  21. package/src/adapter/adapter.js +181 -0
  22. package/src/adapter/adapter.spec.js +144 -0
  23. package/src/adapter/builtin/memory-adapter.d.ts +118 -0
  24. package/src/adapter/builtin/memory-adapter.js +342 -0
  25. package/src/adapter/builtin/memory-adapter.spec.js +2925 -0
  26. package/src/adapter/decorator/data-sanitizing-decorator.d.ts +13 -0
  27. package/src/adapter/decorator/data-sanitizing-decorator.js +44 -0
  28. package/src/adapter/decorator/data-sanitizing-decorator.spec.js +59 -0
  29. package/src/adapter/decorator/data-validation-decorator.d.ts +13 -0
  30. package/src/adapter/decorator/data-validation-decorator.js +41 -0
  31. package/src/adapter/decorator/data-validation-decorator.spec.js +59 -0
  32. package/src/adapter/decorator/default-values-decorator.d.ts +13 -0
  33. package/src/adapter/decorator/default-values-decorator.js +57 -0
  34. package/src/adapter/decorator/default-values-decorator.spec.js +141 -0
  35. package/src/adapter/decorator/fields-filtering-decorator.d.ts +13 -0
  36. package/src/adapter/decorator/fields-filtering-decorator.js +72 -0
  37. package/src/adapter/decorator/fields-filtering-decorator.spec.js +119 -0
  38. package/src/adapter/decorator/inclusion-decorator.d.ts +13 -0
  39. package/src/adapter/decorator/inclusion-decorator.js +78 -0
  40. package/src/adapter/decorator/inclusion-decorator.spec.js +117 -0
  41. package/src/adapter/decorator/index.d.ts +5 -0
  42. package/src/adapter/decorator/index.js +5 -0
  43. package/src/adapter/index.d.ts +3 -0
  44. package/src/adapter/index.js +3 -0
  45. package/src/definition/datasource/datasource-definition-validator.d.ts +14 -0
  46. package/src/definition/datasource/datasource-definition-validator.js +33 -0
  47. package/src/definition/datasource/datasource-definition-validator.spec.js +63 -0
  48. package/src/definition/datasource/datasource-definition.d.ts +7 -0
  49. package/src/definition/datasource/index.d.ts +2 -0
  50. package/src/definition/datasource/index.js +1 -0
  51. package/src/definition/definition-registry.d.ts +50 -0
  52. package/src/definition/definition-registry.js +98 -0
  53. package/src/definition/definition-registry.spec.js +78 -0
  54. package/src/definition/index.d.ts +3 -0
  55. package/src/definition/index.js +3 -0
  56. package/src/definition/model/index.d.ts +7 -0
  57. package/src/definition/model/index.js +6 -0
  58. package/src/definition/model/model-data-sanitizer.d.ts +15 -0
  59. package/src/definition/model/model-data-sanitizer.js +33 -0
  60. package/src/definition/model/model-data-validator.d.ts +32 -0
  61. package/src/definition/model/model-data-validator.js +144 -0
  62. package/src/definition/model/model-data-validator.spec.js +1889 -0
  63. package/src/definition/model/model-definition-utils.d.ts +161 -0
  64. package/src/definition/model/model-definition-utils.js +371 -0
  65. package/src/definition/model/model-definition-utils.spec.js +1474 -0
  66. package/src/definition/model/model-definition-validator.d.ts +14 -0
  67. package/src/definition/model/model-definition-validator.js +83 -0
  68. package/src/definition/model/model-definition-validator.spec.js +143 -0
  69. package/src/definition/model/model-definition.d.ts +28 -0
  70. package/src/definition/model/properties/data-type.d.ts +11 -0
  71. package/src/definition/model/properties/data-type.js +11 -0
  72. package/src/definition/model/properties/default-values-definition-validator.d.ts +15 -0
  73. package/src/definition/model/properties/default-values-definition-validator.js +53 -0
  74. package/src/definition/model/properties/default-values-definition-validator.spec.js +136 -0
  75. package/src/definition/model/properties/index.d.ts +5 -0
  76. package/src/definition/model/properties/index.js +4 -0
  77. package/src/definition/model/properties/primary-keys-definition-validator.d.ts +15 -0
  78. package/src/definition/model/properties/primary-keys-definition-validator.js +55 -0
  79. package/src/definition/model/properties/primary-keys-definition-validator.spec.js +145 -0
  80. package/src/definition/model/properties/properties-definition-validator.d.ts +15 -0
  81. package/src/definition/model/properties/properties-definition-validator.js +194 -0
  82. package/src/definition/model/properties/properties-definition-validator.spec.js +373 -0
  83. package/src/definition/model/properties/property-definition.d.ts +20 -0
  84. package/src/definition/model/relations/index.d.ts +3 -0
  85. package/src/definition/model/relations/index.js +2 -0
  86. package/src/definition/model/relations/relation-definition.d.ts +254 -0
  87. package/src/definition/model/relations/relation-type.d.ts +9 -0
  88. package/src/definition/model/relations/relation-type.js +9 -0
  89. package/src/definition/model/relations/relations-definition-validator.d.ts +15 -0
  90. package/src/definition/model/relations/relations-definition-validator.js +449 -0
  91. package/src/definition/model/relations/relations-definition-validator.spec.js +772 -0
  92. package/src/errors/index.d.ts +3 -0
  93. package/src/errors/index.js +3 -0
  94. package/src/errors/invalid-argument-error.d.ts +6 -0
  95. package/src/errors/invalid-argument-error.js +6 -0
  96. package/src/errors/invalid-argument-error.spec.js +33 -0
  97. package/src/errors/invalid-operator-value-error.d.ts +13 -0
  98. package/src/errors/invalid-operator-value-error.js +24 -0
  99. package/src/errors/invalid-operator-value-error.spec.js +11 -0
  100. package/src/errors/not-implemented-error.d.ts +6 -0
  101. package/src/errors/not-implemented-error.js +6 -0
  102. package/src/errors/not-implemented-error.spec.js +33 -0
  103. package/src/filter/fields-clause-tool.d.ts +38 -0
  104. package/src/filter/fields-clause-tool.js +88 -0
  105. package/src/filter/fields-clause-tool.spec.js +133 -0
  106. package/src/filter/filter.d.ts +335 -0
  107. package/src/filter/include-clause-tool.d.ts +53 -0
  108. package/src/filter/include-clause-tool.js +364 -0
  109. package/src/filter/include-clause-tool.spec.js +653 -0
  110. package/src/filter/index.d.ts +7 -0
  111. package/src/filter/index.js +6 -0
  112. package/src/filter/operator-clause-tool.d.ts +223 -0
  113. package/src/filter/operator-clause-tool.js +515 -0
  114. package/src/filter/operator-clause-tool.spec.js +1064 -0
  115. package/src/filter/order-clause-tool.d.ts +32 -0
  116. package/src/filter/order-clause-tool.js +97 -0
  117. package/src/filter/order-clause-tool.spec.js +438 -0
  118. package/src/filter/slice-clause-tool.d.ts +30 -0
  119. package/src/filter/slice-clause-tool.js +65 -0
  120. package/src/filter/slice-clause-tool.spec.js +117 -0
  121. package/src/filter/where-clause-tool.d.ts +23 -0
  122. package/src/filter/where-clause-tool.js +165 -0
  123. package/src/filter/where-clause-tool.spec.js +280 -0
  124. package/src/index.d.ts +9 -0
  125. package/src/index.js +8 -0
  126. package/src/relations/belongs-to-resolver.d.ts +46 -0
  127. package/src/relations/belongs-to-resolver.js +242 -0
  128. package/src/relations/belongs-to-resolver.spec.js +1047 -0
  129. package/src/relations/has-many-resolver.d.ts +67 -0
  130. package/src/relations/has-many-resolver.js +317 -0
  131. package/src/relations/has-many-resolver.spec.js +2911 -0
  132. package/src/relations/has-one-resolver.d.ts +67 -0
  133. package/src/relations/has-one-resolver.js +311 -0
  134. package/src/relations/has-one-resolver.spec.js +2274 -0
  135. package/src/relations/index.d.ts +4 -0
  136. package/src/relations/index.js +4 -0
  137. package/src/relations/references-many-resolver.d.ts +27 -0
  138. package/src/relations/references-many-resolver.js +113 -0
  139. package/src/relations/references-many-resolver.spec.js +631 -0
  140. package/src/repository/index.d.ts +2 -0
  141. package/src/repository/index.js +2 -0
  142. package/src/repository/repository-registry.d.ts +29 -0
  143. package/src/repository/repository-registry.js +57 -0
  144. package/src/repository/repository-registry.spec.js +38 -0
  145. package/src/repository/repository.d.ts +164 -0
  146. package/src/repository/repository.js +207 -0
  147. package/src/repository/repository.spec.js +202 -0
  148. package/src/schema.d.ts +37 -0
  149. package/src/schema.js +41 -0
  150. package/src/types.d.ts +30 -0
  151. package/src/utils/capitalize.d.ts +6 -0
  152. package/src/utils/capitalize.js +10 -0
  153. package/src/utils/capitalize.spec.js +14 -0
  154. package/src/utils/clone-deep.d.ts +6 -0
  155. package/src/utils/clone-deep.js +61 -0
  156. package/src/utils/clone-deep.spec.js +28 -0
  157. package/src/utils/exclude-object-keys.d.ts +10 -0
  158. package/src/utils/exclude-object-keys.js +20 -0
  159. package/src/utils/exclude-object-keys.spec.js +49 -0
  160. package/src/utils/get-ctor-name.d.ts +6 -0
  161. package/src/utils/get-ctor-name.js +11 -0
  162. package/src/utils/get-ctor-name.spec.js +17 -0
  163. package/src/utils/get-value-by-path.d.ts +12 -0
  164. package/src/utils/get-value-by-path.js +23 -0
  165. package/src/utils/get-value-by-path.spec.js +36 -0
  166. package/src/utils/index.d.ts +10 -0
  167. package/src/utils/index.js +10 -0
  168. package/src/utils/is-ctor.d.ts +7 -0
  169. package/src/utils/is-ctor.js +10 -0
  170. package/src/utils/is-ctor.spec.js +26 -0
  171. package/src/utils/is-pure-object.d.ts +6 -0
  172. package/src/utils/is-pure-object.js +15 -0
  173. package/src/utils/is-pure-object.spec.js +25 -0
  174. package/src/utils/select-object-keys.d.ts +10 -0
  175. package/src/utils/select-object-keys.js +37 -0
  176. package/src/utils/select-object-keys.spec.js +40 -0
  177. package/src/utils/singularize.d.ts +6 -0
  178. package/src/utils/singularize.js +22 -0
  179. package/src/utils/singularize.spec.js +23 -0
  180. package/src/utils/string-to-regexp.d.ts +10 -0
  181. package/src/utils/string-to-regexp.js +22 -0
  182. package/src/utils/string-to-regexp.spec.js +35 -0
  183. 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
+ }