bigal 12.1.4 → 13.0.0-beta1

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 (213) hide show
  1. package/.devcontainer/devcontainer.json +16 -0
  2. package/.husky/pre-commit +4 -0
  3. package/.prettierrc.cjs +34 -0
  4. package/CHANGELOG.md +9 -0
  5. package/dist/index.cjs +2626 -0
  6. package/dist/index.d.cts +892 -0
  7. package/dist/index.d.mts +892 -0
  8. package/dist/index.d.ts +892 -0
  9. package/dist/index.mjs +2605 -0
  10. package/eslint.config.mjs +25 -0
  11. package/package.json +46 -37
  12. package/tsconfig.build.json +7 -0
  13. package/Entity.d.ts +0 -16
  14. package/Entity.js +0 -13
  15. package/Entity.js.map +0 -1
  16. package/IReadonlyRepository.d.ts +0 -36
  17. package/IReadonlyRepository.js +0 -3
  18. package/IReadonlyRepository.js.map +0 -1
  19. package/IRepository.d.ts +0 -99
  20. package/IRepository.js +0 -3
  21. package/IRepository.js.map +0 -1
  22. package/ReadonlyRepository.d.ts +0 -69
  23. package/ReadonlyRepository.js +0 -687
  24. package/ReadonlyRepository.js.map +0 -1
  25. package/Repository.d.ts +0 -69
  26. package/Repository.js +0 -171
  27. package/Repository.js.map +0 -1
  28. package/SqlHelper.d.ts +0 -144
  29. package/SqlHelper.js +0 -1081
  30. package/SqlHelper.js.map +0 -1
  31. package/decorators/ColumnBaseOptions.d.ts +0 -10
  32. package/decorators/ColumnBaseOptions.js +0 -3
  33. package/decorators/ColumnBaseOptions.js.map +0 -1
  34. package/decorators/ColumnCollectionOptions.d.ts +0 -15
  35. package/decorators/ColumnCollectionOptions.js +0 -3
  36. package/decorators/ColumnCollectionOptions.js.map +0 -1
  37. package/decorators/ColumnModelOptions.d.ts +0 -7
  38. package/decorators/ColumnModelOptions.js +0 -3
  39. package/decorators/ColumnModelOptions.js.map +0 -1
  40. package/decorators/ColumnTypeOptions.d.ts +0 -21
  41. package/decorators/ColumnTypeOptions.js +0 -3
  42. package/decorators/ColumnTypeOptions.js.map +0 -1
  43. package/decorators/TableOptions.d.ts +0 -14
  44. package/decorators/TableOptions.js +0 -3
  45. package/decorators/TableOptions.js.map +0 -1
  46. package/decorators/column.d.ts +0 -9
  47. package/decorators/column.js +0 -93
  48. package/decorators/column.js.map +0 -1
  49. package/decorators/createDateColumn.d.ts +0 -6
  50. package/decorators/createDateColumn.js +0 -50
  51. package/decorators/createDateColumn.js.map +0 -1
  52. package/decorators/index.d.ts +0 -6
  53. package/decorators/index.js +0 -23
  54. package/decorators/index.js.map +0 -1
  55. package/decorators/primaryColumn.d.ts +0 -8
  56. package/decorators/primaryColumn.js +0 -66
  57. package/decorators/primaryColumn.js.map +0 -1
  58. package/decorators/table.d.ts +0 -5
  59. package/decorators/table.js +0 -40
  60. package/decorators/table.js.map +0 -1
  61. package/decorators/updateDateColumn.d.ts +0 -6
  62. package/decorators/updateDateColumn.js +0 -51
  63. package/decorators/updateDateColumn.js.map +0 -1
  64. package/decorators/versionColumn.d.ts +0 -6
  65. package/decorators/versionColumn.js +0 -51
  66. package/decorators/versionColumn.js.map +0 -1
  67. package/errors/QueryError.d.ts +0 -8
  68. package/errors/QueryError.js +0 -13
  69. package/errors/QueryError.js.map +0 -1
  70. package/errors/index.d.ts +0 -1
  71. package/errors/index.js +0 -18
  72. package/errors/index.js.map +0 -1
  73. package/index.d.ts +0 -35
  74. package/index.js +0 -220
  75. package/index.js.map +0 -1
  76. package/metadata/ColumnBaseMetadata.d.ts +0 -93
  77. package/metadata/ColumnBaseMetadata.js +0 -19
  78. package/metadata/ColumnBaseMetadata.js.map +0 -1
  79. package/metadata/ColumnCollectionMetadata.d.ts +0 -36
  80. package/metadata/ColumnCollectionMetadata.js +0 -63
  81. package/metadata/ColumnCollectionMetadata.js.map +0 -1
  82. package/metadata/ColumnMetadata.d.ts +0 -4
  83. package/metadata/ColumnMetadata.js +0 -3
  84. package/metadata/ColumnMetadata.js.map +0 -1
  85. package/metadata/ColumnModelMetadata.d.ts +0 -18
  86. package/metadata/ColumnModelMetadata.js +0 -43
  87. package/metadata/ColumnModelMetadata.js.map +0 -1
  88. package/metadata/ColumnModifierMetadata.d.ts +0 -46
  89. package/metadata/ColumnModifierMetadata.js +0 -3
  90. package/metadata/ColumnModifierMetadata.js.map +0 -1
  91. package/metadata/ColumnTypeMetadata.d.ts +0 -43
  92. package/metadata/ColumnTypeMetadata.js +0 -26
  93. package/metadata/ColumnTypeMetadata.js.map +0 -1
  94. package/metadata/MetadataStorage.d.ts +0 -13
  95. package/metadata/MetadataStorage.js +0 -19
  96. package/metadata/MetadataStorage.js.map +0 -1
  97. package/metadata/ModelMetadata.d.ts +0 -36
  98. package/metadata/ModelMetadata.js +0 -81
  99. package/metadata/ModelMetadata.js.map +0 -1
  100. package/metadata/index.d.ts +0 -10
  101. package/metadata/index.js +0 -33
  102. package/metadata/index.js.map +0 -1
  103. package/query/Comparer.d.ts +0 -1
  104. package/query/Comparer.js +0 -3
  105. package/query/Comparer.js.map +0 -1
  106. package/query/CountArgs.d.ts +0 -7
  107. package/query/CountArgs.js +0 -3
  108. package/query/CountArgs.js.map +0 -1
  109. package/query/CountResult.d.ts +0 -5
  110. package/query/CountResult.js +0 -3
  111. package/query/CountResult.js.map +0 -1
  112. package/query/CreateOptions.d.ts +0 -9
  113. package/query/CreateOptions.js +0 -3
  114. package/query/CreateOptions.js.map +0 -1
  115. package/query/CreateUpdateOptions.d.ts +0 -4
  116. package/query/CreateUpdateOptions.js +0 -3
  117. package/query/CreateUpdateOptions.js.map +0 -1
  118. package/query/DeleteOptions.d.ts +0 -12
  119. package/query/DeleteOptions.js +0 -3
  120. package/query/DeleteOptions.js.map +0 -1
  121. package/query/DestroyResult.d.ts +0 -5
  122. package/query/DestroyResult.js +0 -3
  123. package/query/DestroyResult.js.map +0 -1
  124. package/query/DoNotReturnRecords.d.ts +0 -3
  125. package/query/DoNotReturnRecords.js +0 -3
  126. package/query/DoNotReturnRecords.js.map +0 -1
  127. package/query/FindArgs.d.ts +0 -6
  128. package/query/FindArgs.js +0 -3
  129. package/query/FindArgs.js.map +0 -1
  130. package/query/FindOneArgs.d.ts +0 -11
  131. package/query/FindOneArgs.js +0 -3
  132. package/query/FindOneArgs.js.map +0 -1
  133. package/query/FindOneResult.d.ts +0 -12
  134. package/query/FindOneResult.js +0 -3
  135. package/query/FindOneResult.js.map +0 -1
  136. package/query/FindResult.d.ts +0 -15
  137. package/query/FindResult.js +0 -3
  138. package/query/FindResult.js.map +0 -1
  139. package/query/OnConflictOptions.d.ts +0 -25
  140. package/query/OnConflictOptions.js +0 -3
  141. package/query/OnConflictOptions.js.map +0 -1
  142. package/query/PaginateOptions.d.ts +0 -4
  143. package/query/PaginateOptions.js +0 -3
  144. package/query/PaginateOptions.js.map +0 -1
  145. package/query/PopulateArgs.d.ts +0 -13
  146. package/query/PopulateArgs.js +0 -3
  147. package/query/PopulateArgs.js.map +0 -1
  148. package/query/ReturnSelect.d.ts +0 -5
  149. package/query/ReturnSelect.js +0 -3
  150. package/query/ReturnSelect.js.map +0 -1
  151. package/query/Sort.d.ts +0 -15
  152. package/query/Sort.js +0 -3
  153. package/query/Sort.js.map +0 -1
  154. package/query/WhereQuery.d.ts +0 -21
  155. package/query/WhereQuery.js +0 -3
  156. package/query/WhereQuery.js.map +0 -1
  157. package/query/index.d.ts +0 -15
  158. package/query/index.js +0 -32
  159. package/query/index.js.map +0 -1
  160. package/types/ClassLike.d.ts +0 -8
  161. package/types/ClassLike.js +0 -3
  162. package/types/ClassLike.js.map +0 -1
  163. package/types/CreateUpdateParams.d.ts +0 -9
  164. package/types/CreateUpdateParams.js +0 -3
  165. package/types/CreateUpdateParams.js.map +0 -1
  166. package/types/EntityPrimitiveOrId.d.ts +0 -2
  167. package/types/EntityPrimitiveOrId.js +0 -3
  168. package/types/EntityPrimitiveOrId.js.map +0 -1
  169. package/types/ExcludeEntityCollections.d.ts +0 -5
  170. package/types/ExcludeEntityCollections.js +0 -3
  171. package/types/ExcludeEntityCollections.js.map +0 -1
  172. package/types/ExcludeFunctions.d.ts +0 -4
  173. package/types/ExcludeFunctions.js +0 -3
  174. package/types/ExcludeFunctions.js.map +0 -1
  175. package/types/GetValueType.d.ts +0 -1
  176. package/types/GetValueType.js +0 -3
  177. package/types/GetValueType.js.map +0 -1
  178. package/types/IncludeFunctions.d.ts +0 -4
  179. package/types/IncludeFunctions.js +0 -3
  180. package/types/IncludeFunctions.js.map +0 -1
  181. package/types/IsValueOfType.d.ts +0 -1
  182. package/types/IsValueOfType.js +0 -3
  183. package/types/IsValueOfType.js.map +0 -1
  184. package/types/OmitEntityCollections.d.ts +0 -7
  185. package/types/OmitEntityCollections.js +0 -3
  186. package/types/OmitEntityCollections.js.map +0 -1
  187. package/types/OmitFunctions.d.ts +0 -7
  188. package/types/OmitFunctions.js +0 -3
  189. package/types/OmitFunctions.js.map +0 -1
  190. package/types/PickAsType.d.ts +0 -3
  191. package/types/PickAsType.js +0 -3
  192. package/types/PickAsType.js.map +0 -1
  193. package/types/PickByValueType.d.ts +0 -5
  194. package/types/PickByValueType.js +0 -3
  195. package/types/PickByValueType.js.map +0 -1
  196. package/types/PickFunctions.d.ts +0 -4
  197. package/types/PickFunctions.js +0 -3
  198. package/types/PickFunctions.js.map +0 -1
  199. package/types/Populated.d.ts +0 -9
  200. package/types/Populated.js +0 -3
  201. package/types/Populated.js.map +0 -1
  202. package/types/QueryResult.d.ts +0 -9
  203. package/types/QueryResult.js +0 -3
  204. package/types/QueryResult.js.map +0 -1
  205. package/types/QueryResultOptionalPopulated.d.ts +0 -9
  206. package/types/QueryResultOptionalPopulated.js +0 -3
  207. package/types/QueryResultOptionalPopulated.js.map +0 -1
  208. package/types/QueryResultPopulated.d.ts +0 -9
  209. package/types/QueryResultPopulated.js +0 -3
  210. package/types/QueryResultPopulated.js.map +0 -1
  211. package/types/index.d.ts +0 -17
  212. package/types/index.js +0 -34
  213. package/types/index.js.map +0 -1
@@ -1,687 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ReadonlyRepository = void 0;
7
- const lodash_1 = __importDefault(require("lodash"));
8
- const SqlHelper_1 = require("./SqlHelper");
9
- class ReadonlyRepository {
10
- constructor({ modelMetadata, type, pool, readonlyPool, repositoriesByModelNameLowered }) {
11
- this._floatProperties = [];
12
- this._intProperties = [];
13
- this._modelMetadata = modelMetadata;
14
- this._type = type;
15
- this._pool = pool;
16
- this._readonlyPool = readonlyPool ?? pool;
17
- this._repositoriesByModelNameLowered = repositoriesByModelNameLowered;
18
- for (const column of modelMetadata.columns) {
19
- if (column.type === 'float') {
20
- this._floatProperties.push(column.propertyName);
21
- }
22
- else if (column.type === 'integer') {
23
- this._intProperties.push(column.propertyName);
24
- }
25
- }
26
- }
27
- get model() {
28
- return this._modelMetadata;
29
- }
30
- /**
31
- * Gets a single object
32
- * @param {object} [args] - Arguments
33
- * @param {string[]} [args.select] - Array of model property names to return from the query.
34
- * @param {object} [args.where] - Object representing the where query
35
- * @param {string|object} [args.sort] - Property name(s) to sort by
36
- */
37
- findOne(args = {}) {
38
- const { stack } = new Error(`${this.model.name}.findOne()`);
39
- let select;
40
- let where = {};
41
- let sort = null;
42
- let poolOverride;
43
- // Args can be a FindOneArgs type or a query object. If args has a key other than select, where, or sort, treat it as a query object
44
- for (const [name, value] of Object.entries(args)) {
45
- let isWhereCriteria = false;
46
- switch (name) {
47
- case 'select':
48
- if (value) {
49
- select = new Set(value);
50
- }
51
- break;
52
- case 'where':
53
- where = value;
54
- break;
55
- case 'sort':
56
- sort = value;
57
- break;
58
- case 'pool':
59
- poolOverride = value;
60
- break;
61
- default:
62
- select = undefined;
63
- where = args;
64
- sort = null;
65
- isWhereCriteria = true;
66
- break;
67
- }
68
- if (isWhereCriteria) {
69
- break;
70
- }
71
- }
72
- const populates = [];
73
- const manuallySetFields = [];
74
- const sorts = sort ? this._convertSortsToOrderBy(sort) : [];
75
- // eslint-disable-next-line @typescript-eslint/no-this-alias
76
- const modelInstance = this;
77
- return {
78
- /**
79
- * Filters the query
80
- * @param {object} value - Object representing the where query
81
- */
82
- where(value) {
83
- where = value;
84
- return this;
85
- },
86
- /**
87
- * Populates/hydrates relations
88
- * @param {string} propertyName - Name of property to join
89
- * @param {object} [options] - Populate options
90
- * @param {object} [options.where] - Object representing the where query
91
- * @param {string[]} [options.select] - Array of model property names to return from the query.
92
- * @param {string|object} [options.sort] - Property name(s) to sort by
93
- * @param {string|number} [options.skip] - Number of records to skip
94
- * @param {string|number} [options.limit] - Number of results to return
95
- */
96
- populate(propertyName, options) {
97
- // Add the column if the property is a single relation and not included in the list of select columns
98
- if (select && !select.has(propertyName)) {
99
- for (const column of modelInstance.model.columns) {
100
- if (column.model && column.propertyName === propertyName) {
101
- select.add(column.propertyName);
102
- }
103
- }
104
- }
105
- populates.push({
106
- propertyName,
107
- where: options?.where,
108
- select: options?.select,
109
- sort: options?.sort,
110
- skip: options?.skip,
111
- limit: options?.limit,
112
- pool: options?.pool ?? poolOverride,
113
- });
114
- return this;
115
- },
116
- /**
117
- * Sorts the query
118
- * @param {string|object} [value]
119
- */
120
- sort(value) {
121
- if (value) {
122
- sorts.push(...modelInstance._convertSortsToOrderBy(value));
123
- }
124
- return this;
125
- },
126
- UNSAFE_withOriginalFieldType(_propertyName) {
127
- return this;
128
- },
129
- UNSAFE_withFieldValue(propertyName, value) {
130
- manuallySetFields.push({
131
- propertyName,
132
- value,
133
- });
134
- return this;
135
- },
136
- async then(resolve, reject) {
137
- try {
138
- if (lodash_1.default.isString(where)) {
139
- return await reject(new Error('The query cannot be a string, it must be an object'));
140
- }
141
- const { query, params } = (0, SqlHelper_1.getSelectQueryAndParams)({
142
- repositoriesByModelNameLowered: modelInstance._repositoriesByModelNameLowered,
143
- model: modelInstance.model,
144
- select: select ? Array.from(select) : undefined,
145
- where,
146
- sorts,
147
- limit: 1,
148
- skip: 0,
149
- });
150
- const pool = poolOverride ?? modelInstance._readonlyPool;
151
- const results = await pool.query(query, params);
152
- const firstResult = lodash_1.default.first(results.rows);
153
- if (firstResult) {
154
- const result = modelInstance._buildInstance(firstResult);
155
- if (populates.length) {
156
- await modelInstance.populateFields([result], populates);
157
- }
158
- for (const manuallySetField of manuallySetFields) {
159
- // @ts-expect-error - Ignoring unknown is not a key
160
- result[manuallySetField.propertyName] = manuallySetField.value;
161
- }
162
- return await resolve(result);
163
- }
164
- return await resolve(null);
165
- }
166
- catch (ex) {
167
- const typedException = ex;
168
- if (typedException.stack) {
169
- typedException.stack += `\n${stack ?? ''}`;
170
- }
171
- else {
172
- typedException.stack = stack;
173
- }
174
- return reject(typedException);
175
- }
176
- },
177
- };
178
- }
179
- /**
180
- * Gets a collection of objects
181
- * @param {object} [args] - Arguments
182
- * @param {string[]} [args.select] - Array of model property names to return from the query.
183
- * @param {object} [args.where] - Object representing the where query
184
- * @param {string|object} [args.sort] - Property name(s) to sort by
185
- * @param {string|number} [args.skip] - Number of records to skip
186
- * @param {string|number} [args.limit] - Number of results to return
187
- */
188
- find(args = {}) {
189
- const { stack } = new Error(`${this.model.name}.find()`);
190
- let select;
191
- let where = {};
192
- let sort = null;
193
- let skip = null;
194
- let limit = null;
195
- let poolOverride;
196
- // Args can be a FindArgs type or a query object. If args has a key other than select, where, or sort, treat it as a query object
197
- for (const [name, value] of Object.entries(args)) {
198
- let isWhereCriteria = false;
199
- switch (name) {
200
- case 'select':
201
- if (value) {
202
- select = new Set(value);
203
- }
204
- break;
205
- case 'where':
206
- where = value;
207
- break;
208
- case 'sort':
209
- sort = value;
210
- break;
211
- case 'skip':
212
- skip = value;
213
- break;
214
- case 'limit':
215
- limit = value;
216
- break;
217
- case 'pool':
218
- poolOverride = value;
219
- break;
220
- default:
221
- select = undefined;
222
- where = args;
223
- sort = null;
224
- skip = null;
225
- limit = null;
226
- isWhereCriteria = true;
227
- break;
228
- }
229
- if (isWhereCriteria) {
230
- break;
231
- }
232
- }
233
- const populates = [];
234
- const sorts = sort ? this._convertSortsToOrderBy(sort) : [];
235
- // eslint-disable-next-line @typescript-eslint/no-this-alias
236
- const modelInstance = this;
237
- return {
238
- /**
239
- * Filters the query
240
- * @param {object} value - Object representing the where query
241
- */
242
- where(value) {
243
- where = value;
244
- return this;
245
- },
246
- /**
247
- * Populates/hydrates relations
248
- * @param {string} propertyName - Name of property to join
249
- * @param {object} [options] - Populate options
250
- * @param {object} [options.where] - Object representing the where query
251
- * @param {string[]} [options.select] - Array of model property names to return from the query.
252
- * @param {string|object} [options.sort] - Property name(s) to sort by
253
- * @param {string|number} [options.skip] - Number of records to skip
254
- * @param {string|number} [options.limit] - Number of results to return
255
- */
256
- populate(propertyName, options) {
257
- // Add the column if the property is a single relation and not included in the list of select columns
258
- if (select && !select.has(propertyName)) {
259
- for (const column of modelInstance.model.columns) {
260
- if (column.model && column.propertyName === propertyName) {
261
- select.add(column.propertyName);
262
- }
263
- }
264
- }
265
- populates.push({
266
- propertyName,
267
- where: options?.where,
268
- select: options?.select,
269
- sort: options?.sort,
270
- skip: options?.skip,
271
- limit: options?.limit,
272
- pool: options?.pool ?? poolOverride,
273
- });
274
- return this;
275
- },
276
- /**
277
- * Sorts the query
278
- * @param {string|string[]|object} [value]
279
- */
280
- sort(value) {
281
- if (value) {
282
- sorts.push(...modelInstance._convertSortsToOrderBy(value));
283
- }
284
- return this;
285
- },
286
- /**
287
- * Limits results returned by the query
288
- * @param {number} value
289
- */
290
- limit(value) {
291
- limit = value;
292
- return this;
293
- },
294
- /**
295
- * Skips records returned by the query
296
- * @param {number} value
297
- */
298
- skip(value) {
299
- skip = value;
300
- return this;
301
- },
302
- UNSAFE_withOriginalFieldType(_propertyName) {
303
- return this;
304
- },
305
- /**
306
- * Pages records returned by the query
307
- * @param {number} [page=1] - Page to return - Starts at 1
308
- * @param {number} [limit=10] - Number of records to return
309
- */
310
- paginate({ page = 1, limit: paginateLimit = 10 }) {
311
- const safePage = Math.max(page, 1);
312
- return this.skip(safePage * paginateLimit - paginateLimit).limit(paginateLimit);
313
- },
314
- async then(resolve, reject) {
315
- try {
316
- if (lodash_1.default.isString(where)) {
317
- return await reject(new Error('The query cannot be a string, it must be an object'));
318
- }
319
- const { query, params } = (0, SqlHelper_1.getSelectQueryAndParams)({
320
- repositoriesByModelNameLowered: modelInstance._repositoriesByModelNameLowered,
321
- model: modelInstance.model,
322
- select: select ? Array.from(select) : undefined,
323
- where,
324
- sorts,
325
- skip: skip ?? 0,
326
- limit: limit ?? 0,
327
- });
328
- const pool = poolOverride ?? modelInstance._readonlyPool;
329
- const results = await pool.query(query, params);
330
- const entities = modelInstance._buildInstances(results.rows);
331
- if (populates.length) {
332
- await modelInstance.populateFields(entities, populates);
333
- }
334
- return await resolve(entities);
335
- }
336
- catch (ex) {
337
- const typedException = ex;
338
- if (typedException.stack) {
339
- typedException.stack += `\n${stack ?? ''}`;
340
- }
341
- else {
342
- typedException.stack = stack;
343
- }
344
- return reject(typedException);
345
- }
346
- },
347
- };
348
- }
349
- /**
350
- * Gets a count of rows matching the where query
351
- * @param {object} [args] - Arguments
352
- * @param {object} [args.where] - Object representing the where query
353
- * @param {object} [args.pool] - Override the db pool to use for the query
354
- * @returns {number} Number of records matching the where criteria
355
- */
356
- count(args = {}) {
357
- const { stack } = new Error(`${this.model.name}.count()`);
358
- let where = {};
359
- let poolOverride;
360
- // Args can be a FindOneArgs type or a query object. If args has a key other than select, where, or sort, treat it as a query object
361
- for (const [name, value] of Object.entries(args)) {
362
- let isWhereCriteria = false;
363
- switch (name) {
364
- case 'where':
365
- where = value;
366
- break;
367
- case 'pool':
368
- poolOverride = value;
369
- break;
370
- default:
371
- where = args;
372
- isWhereCriteria = true;
373
- break;
374
- }
375
- if (isWhereCriteria) {
376
- break;
377
- }
378
- }
379
- // eslint-disable-next-line @typescript-eslint/no-this-alias
380
- const modelInstance = this;
381
- return {
382
- /**
383
- * Filters the query
384
- * @param {object} value - Object representing the where query
385
- */
386
- where(value) {
387
- // eslint-disable-next-line no-param-reassign
388
- where = value;
389
- return this;
390
- },
391
- async then(resolve, reject) {
392
- try {
393
- const { query, params } = (0, SqlHelper_1.getCountQueryAndParams)({
394
- repositoriesByModelNameLowered: modelInstance._repositoriesByModelNameLowered,
395
- model: modelInstance.model,
396
- where,
397
- });
398
- const pool = poolOverride ?? modelInstance._readonlyPool;
399
- const result = await pool.query(query, params);
400
- const firstResult = lodash_1.default.first(result.rows);
401
- const originalValue = firstResult ? firstResult.count : 0;
402
- return await resolve(Number(originalValue));
403
- }
404
- catch (ex) {
405
- const typedException = ex;
406
- if (typedException.stack) {
407
- typedException.stack += `\n${stack ?? ''}`;
408
- }
409
- else {
410
- typedException.stack = stack;
411
- }
412
- return reject(typedException);
413
- }
414
- },
415
- };
416
- }
417
- _buildInstance(row) {
418
- if (lodash_1.default.isNil(row)) {
419
- return row;
420
- }
421
- const instance = new this._type();
422
- Object.assign(instance, row);
423
- // NOTE: Number fields may be strings coming from the db. In those cases, try to convert the value to Number
424
- for (const name of this._floatProperties) {
425
- const originalValue = row[name];
426
- if (!lodash_1.default.isNil(originalValue) && typeof originalValue === 'string') {
427
- try {
428
- const value = Number(originalValue);
429
- if (lodash_1.default.isFinite(value) && value.toString() === originalValue) {
430
- // @ts-expect-error - string cannot be used to index type T
431
- instance[name] = value;
432
- }
433
- }
434
- catch (ex) {
435
- // Ignore and leave value as original
436
- }
437
- }
438
- }
439
- for (const name of this._intProperties) {
440
- const originalValue = row[name];
441
- if (!lodash_1.default.isNil(originalValue) && typeof originalValue === 'string') {
442
- try {
443
- const value = Number(originalValue);
444
- if (lodash_1.default.isFinite(value) && value.toString() === originalValue) {
445
- const valueAsInt = lodash_1.default.toInteger(value);
446
- if (Number.isSafeInteger(valueAsInt)) {
447
- // @ts-expect-error - string cannot be used to index type T
448
- instance[name] = valueAsInt;
449
- }
450
- }
451
- }
452
- catch (ex) {
453
- // Ignore and leave value as original
454
- }
455
- }
456
- }
457
- return instance;
458
- }
459
- _buildInstances(rows) {
460
- if (lodash_1.default.isNil(rows)) {
461
- return [];
462
- }
463
- return rows.map((row) => this._buildInstance(row));
464
- }
465
- _convertSortsToOrderBy(sorts) {
466
- const result = [];
467
- if (sorts) {
468
- if (Array.isArray(sorts)) {
469
- for (const sort of sorts) {
470
- const parts = sort.trim().split(' ');
471
- const propertyName = parts.shift();
472
- result.push({
473
- propertyName,
474
- descending: /desc/i.test(parts.join('')),
475
- });
476
- }
477
- }
478
- else if (lodash_1.default.isString(sorts)) {
479
- for (const sort of sorts.split(',')) {
480
- const parts = sort.trim().split(' ');
481
- const propertyName = parts.shift();
482
- result.push({
483
- propertyName,
484
- descending: /desc/i.test(parts.join('')),
485
- });
486
- }
487
- }
488
- else if (lodash_1.default.isObject(sorts)) {
489
- for (const [propertyName, orderValue] of Object.entries(sorts)) {
490
- let descending = false;
491
- const order = orderValue;
492
- if (order && (order === -1 || /desc/i.test(`${order}`))) {
493
- descending = true;
494
- }
495
- result.push({
496
- propertyName: propertyName,
497
- descending,
498
- });
499
- }
500
- }
501
- }
502
- return result;
503
- }
504
- // NOTE: This will mutate `entities`
505
- async populateFields(entities, populates) {
506
- if (!entities.length) {
507
- return;
508
- }
509
- const populateQueries = [];
510
- for (const populate of populates) {
511
- const column = this.model.columnsByPropertyName[populate.propertyName];
512
- if (!column) {
513
- throw new Error(`Unable to find ${populate.propertyName} on ${this.model.name} model for populating.`);
514
- }
515
- const modelColumn = column;
516
- const collectionColumn = column;
517
- if (modelColumn.model) {
518
- populateQueries.push(this.populateSingleAssociation(entities, populate, modelColumn));
519
- }
520
- else if (collectionColumn.collection) {
521
- const populateRepository = this._repositoriesByModelNameLowered[collectionColumn.collection.toLowerCase()];
522
- if (!populateRepository) {
523
- throw new Error(`Unable to find populate repository for collection by name ${collectionColumn.collection}. From ${column.target}#${populate.propertyName}`);
524
- }
525
- const { primaryKeyColumn } = this.model;
526
- if (!primaryKeyColumn) {
527
- throw new Error(`Unable to populate ${column.target}#${column.propertyName}. There is no primary key defined in ${this.model.name}`);
528
- }
529
- const entityIds = new Set();
530
- for (const entity of entities) {
531
- const id = entity[primaryKeyColumn.propertyName];
532
- if (lodash_1.default.isNil(id)) {
533
- throw new Error(`Primary key (${primaryKeyColumn.propertyName}) has no value for entity ${column.target}.`);
534
- }
535
- entityIds.add(id);
536
- }
537
- if (collectionColumn.through) {
538
- const populateModelPrimaryKeyColumn = populateRepository.model.primaryKeyColumn;
539
- if (!populateModelPrimaryKeyColumn) {
540
- throw new Error(`Unable to populate ${collectionColumn.collection} objects from ${column.target}#${column.propertyName}. There is no primary key defined in ${collectionColumn.collection}`);
541
- }
542
- populateQueries.push(this.populateManyManyCollection(entities, primaryKeyColumn.propertyName, Array.from(entityIds), populateModelPrimaryKeyColumn.propertyName, populate, collectionColumn, populateRepository));
543
- }
544
- else {
545
- populateQueries.push(this.populateOneManyCollection(entities, primaryKeyColumn.propertyName, Array.from(entityIds), populate, collectionColumn, populateRepository));
546
- }
547
- }
548
- }
549
- if (populateQueries.length) {
550
- await Promise.all(populateQueries);
551
- }
552
- }
553
- async populateSingleAssociation(entities, populate, column) {
554
- const populateRepository = this._repositoriesByModelNameLowered[column.model.toLowerCase()];
555
- if (!populateRepository) {
556
- throw new Error(`Unable to find populate repository by entity name: ${column.model}. From ${column.target}#${column.propertyName}`);
557
- }
558
- if (!populateRepository.model.primaryKeyColumn) {
559
- throw new Error(`Unable to populate ${column.model} from ${column.target}#${column.propertyName}. There is no primary key defined in ${column.model}`);
560
- }
561
- const propertyName = populate.propertyName;
562
- const populateIds = new Set();
563
- for (const entity of entities) {
564
- // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-member-access
565
- const populateId = entity[propertyName];
566
- if (populateId) {
567
- populateIds.add(populateId);
568
- }
569
- }
570
- const populateWhere = {
571
- [populateRepository.model.primaryKeyColumn.propertyName]: Array.from(populateIds),
572
- ...populate.where,
573
- };
574
- const populateResults = await populateRepository.find({
575
- select: populate.select,
576
- where: populateWhere,
577
- sort: populate.sort,
578
- pool: populate.pool,
579
- });
580
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
581
- const populateResultsById = lodash_1.default.keyBy(populateResults, populateRepository.model.primaryKeyColumn.propertyName);
582
- for (const entity of entities) {
583
- // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
584
- entity[propertyName] = populateResultsById[entity[propertyName]];
585
- }
586
- }
587
- async populateOneManyCollection(entities, primaryKeyPropertyName, entityIds, populate, column, populateRepository) {
588
- if (entities.length > 1 && populate.select && !populate.select.includes(column.via)) {
589
- throw new Error(`Unable to populate "${populate.propertyName}" on ${this.model.name}. "${column.via}" is not included in select array.`);
590
- }
591
- const populateWhere = {
592
- [column.via]: entityIds,
593
- ...populate.where,
594
- };
595
- const populateResults = await populateRepository.find({
596
- select: populate.select,
597
- where: populateWhere,
598
- sort: populate.sort,
599
- skip: populate.skip,
600
- limit: populate.limit,
601
- pool: populate.pool,
602
- });
603
- if (entities.length === 1) {
604
- for (const entity of entities) {
605
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
606
- entity[populate.propertyName] = populateResults;
607
- }
608
- }
609
- else {
610
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
611
- const populateResultsByEntityId = lodash_1.default.groupBy(populateResults, column.via);
612
- for (const entity of entities) {
613
- // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment
614
- const id = entity[primaryKeyPropertyName];
615
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
616
- entity[populate.propertyName] = populateResultsByEntityId[id] || [];
617
- }
618
- }
619
- }
620
- async populateManyManyCollection(entities, primaryKeyPropertyName, entityIds, populateModelPrimaryKeyPropertyName, populate, column, populateRepository) {
621
- if (!column.through) {
622
- throw new Error(`Unable to populate multi-map collection: Missing "through" value. From ${column.target}#${populate.propertyName}`);
623
- }
624
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
625
- const throughRepository = this._repositoriesByModelNameLowered[column.through.toLowerCase()];
626
- if (!throughRepository) {
627
- throw new Error(`Unable to find repository for multi-map collection: ${column.through}. From ${column.target}#${populate.propertyName}`);
628
- }
629
- // Other side of the relation
630
- let relatedModelColumn;
631
- for (const populateModelColumn of populateRepository.model.columns) {
632
- const { through } = populateModelColumn;
633
- if (through && through.toLowerCase() === column.through.toLowerCase()) {
634
- relatedModelColumn = populateModelColumn;
635
- break;
636
- }
637
- }
638
- if (!relatedModelColumn) {
639
- throw new Error(`Unable to find property on related model for multi-map collection: ${column.through}. From ${column.target}#${populate.propertyName}`);
640
- }
641
- const mapRecords = await throughRepository.find({
642
- select: [column.via, relatedModelColumn.via],
643
- where: {
644
- [column.via]: entityIds,
645
- },
646
- pool: populate.pool,
647
- });
648
- const populateIds = new Set();
649
- const populateIdsByEntityId = {};
650
- for (const mapRecord of mapRecords) {
651
- const entityId = mapRecord[column.via];
652
- const populatedId = mapRecord[relatedModelColumn.via];
653
- populateIds.add(populatedId);
654
- const entityPopulateIds = populateIdsByEntityId[entityId] ?? [];
655
- entityPopulateIds.push(populatedId);
656
- populateIdsByEntityId[entityId] = entityPopulateIds;
657
- }
658
- const populateWhere = lodash_1.default.merge({
659
- [populateModelPrimaryKeyPropertyName]: Array.from(populateIds),
660
- }, populate.where);
661
- const populateResults = await populateRepository.find({
662
- select: populate.select,
663
- where: populateWhere,
664
- sort: populate.sort,
665
- skip: populate.skip,
666
- limit: populate.limit,
667
- pool: populate.pool,
668
- });
669
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
670
- const populateResultsById = lodash_1.default.keyBy(populateResults, populateModelPrimaryKeyPropertyName);
671
- for (const entity of entities) {
672
- const populatedItems = [];
673
- const entityId = entity[primaryKeyPropertyName];
674
- const populateIdsForEntity = populateIdsByEntityId[entityId] ?? [];
675
- for (const id of populateIdsForEntity) {
676
- const populatedItem = populateResultsById[id];
677
- if (populatedItem) {
678
- populatedItems.push(populatedItem);
679
- }
680
- }
681
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
682
- entity[populate.propertyName] = populatedItems;
683
- }
684
- }
685
- }
686
- exports.ReadonlyRepository = ReadonlyRepository;
687
- //# sourceMappingURL=ReadonlyRepository.js.map