bigal 12.1.5 → 13.0.0-beta2
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/.devcontainer/devcontainer.json +16 -0
- package/.husky/pre-commit +4 -0
- package/.prettierrc.cjs +34 -0
- package/CHANGELOG.md +5 -0
- package/dist/index.cjs +2626 -0
- package/dist/index.d.cts +892 -0
- package/dist/index.d.mts +892 -0
- package/dist/index.d.ts +892 -0
- package/dist/index.mjs +2605 -0
- package/eslint.config.mjs +25 -0
- package/package.json +44 -35
- package/tsconfig.build.json +7 -0
- package/Entity.d.ts +0 -16
- package/Entity.js +0 -13
- package/Entity.js.map +0 -1
- package/IReadonlyRepository.d.ts +0 -36
- package/IReadonlyRepository.js +0 -3
- package/IReadonlyRepository.js.map +0 -1
- package/IRepository.d.ts +0 -99
- package/IRepository.js +0 -3
- package/IRepository.js.map +0 -1
- package/ReadonlyRepository.d.ts +0 -69
- package/ReadonlyRepository.js +0 -687
- package/ReadonlyRepository.js.map +0 -1
- package/Repository.d.ts +0 -69
- package/Repository.js +0 -171
- package/Repository.js.map +0 -1
- package/SqlHelper.d.ts +0 -144
- package/SqlHelper.js +0 -1081
- package/SqlHelper.js.map +0 -1
- package/decorators/ColumnBaseOptions.d.ts +0 -10
- package/decorators/ColumnBaseOptions.js +0 -3
- package/decorators/ColumnBaseOptions.js.map +0 -1
- package/decorators/ColumnCollectionOptions.d.ts +0 -15
- package/decorators/ColumnCollectionOptions.js +0 -3
- package/decorators/ColumnCollectionOptions.js.map +0 -1
- package/decorators/ColumnModelOptions.d.ts +0 -7
- package/decorators/ColumnModelOptions.js +0 -3
- package/decorators/ColumnModelOptions.js.map +0 -1
- package/decorators/ColumnTypeOptions.d.ts +0 -21
- package/decorators/ColumnTypeOptions.js +0 -3
- package/decorators/ColumnTypeOptions.js.map +0 -1
- package/decorators/TableOptions.d.ts +0 -14
- package/decorators/TableOptions.js +0 -3
- package/decorators/TableOptions.js.map +0 -1
- package/decorators/column.d.ts +0 -9
- package/decorators/column.js +0 -93
- package/decorators/column.js.map +0 -1
- package/decorators/createDateColumn.d.ts +0 -6
- package/decorators/createDateColumn.js +0 -50
- package/decorators/createDateColumn.js.map +0 -1
- package/decorators/index.d.ts +0 -6
- package/decorators/index.js +0 -23
- package/decorators/index.js.map +0 -1
- package/decorators/primaryColumn.d.ts +0 -8
- package/decorators/primaryColumn.js +0 -66
- package/decorators/primaryColumn.js.map +0 -1
- package/decorators/table.d.ts +0 -5
- package/decorators/table.js +0 -40
- package/decorators/table.js.map +0 -1
- package/decorators/updateDateColumn.d.ts +0 -6
- package/decorators/updateDateColumn.js +0 -51
- package/decorators/updateDateColumn.js.map +0 -1
- package/decorators/versionColumn.d.ts +0 -6
- package/decorators/versionColumn.js +0 -51
- package/decorators/versionColumn.js.map +0 -1
- package/errors/QueryError.d.ts +0 -8
- package/errors/QueryError.js +0 -13
- package/errors/QueryError.js.map +0 -1
- package/errors/index.d.ts +0 -1
- package/errors/index.js +0 -18
- package/errors/index.js.map +0 -1
- package/index.d.ts +0 -35
- package/index.js +0 -220
- package/index.js.map +0 -1
- package/metadata/ColumnBaseMetadata.d.ts +0 -93
- package/metadata/ColumnBaseMetadata.js +0 -19
- package/metadata/ColumnBaseMetadata.js.map +0 -1
- package/metadata/ColumnCollectionMetadata.d.ts +0 -36
- package/metadata/ColumnCollectionMetadata.js +0 -63
- package/metadata/ColumnCollectionMetadata.js.map +0 -1
- package/metadata/ColumnMetadata.d.ts +0 -4
- package/metadata/ColumnMetadata.js +0 -3
- package/metadata/ColumnMetadata.js.map +0 -1
- package/metadata/ColumnModelMetadata.d.ts +0 -18
- package/metadata/ColumnModelMetadata.js +0 -43
- package/metadata/ColumnModelMetadata.js.map +0 -1
- package/metadata/ColumnModifierMetadata.d.ts +0 -46
- package/metadata/ColumnModifierMetadata.js +0 -3
- package/metadata/ColumnModifierMetadata.js.map +0 -1
- package/metadata/ColumnTypeMetadata.d.ts +0 -43
- package/metadata/ColumnTypeMetadata.js +0 -26
- package/metadata/ColumnTypeMetadata.js.map +0 -1
- package/metadata/MetadataStorage.d.ts +0 -13
- package/metadata/MetadataStorage.js +0 -19
- package/metadata/MetadataStorage.js.map +0 -1
- package/metadata/ModelMetadata.d.ts +0 -36
- package/metadata/ModelMetadata.js +0 -81
- package/metadata/ModelMetadata.js.map +0 -1
- package/metadata/index.d.ts +0 -10
- package/metadata/index.js +0 -33
- package/metadata/index.js.map +0 -1
- package/query/Comparer.d.ts +0 -1
- package/query/Comparer.js +0 -3
- package/query/Comparer.js.map +0 -1
- package/query/CountArgs.d.ts +0 -7
- package/query/CountArgs.js +0 -3
- package/query/CountArgs.js.map +0 -1
- package/query/CountResult.d.ts +0 -5
- package/query/CountResult.js +0 -3
- package/query/CountResult.js.map +0 -1
- package/query/CreateOptions.d.ts +0 -9
- package/query/CreateOptions.js +0 -3
- package/query/CreateOptions.js.map +0 -1
- package/query/CreateUpdateOptions.d.ts +0 -4
- package/query/CreateUpdateOptions.js +0 -3
- package/query/CreateUpdateOptions.js.map +0 -1
- package/query/DeleteOptions.d.ts +0 -12
- package/query/DeleteOptions.js +0 -3
- package/query/DeleteOptions.js.map +0 -1
- package/query/DestroyResult.d.ts +0 -5
- package/query/DestroyResult.js +0 -3
- package/query/DestroyResult.js.map +0 -1
- package/query/DoNotReturnRecords.d.ts +0 -3
- package/query/DoNotReturnRecords.js +0 -3
- package/query/DoNotReturnRecords.js.map +0 -1
- package/query/FindArgs.d.ts +0 -6
- package/query/FindArgs.js +0 -3
- package/query/FindArgs.js.map +0 -1
- package/query/FindOneArgs.d.ts +0 -11
- package/query/FindOneArgs.js +0 -3
- package/query/FindOneArgs.js.map +0 -1
- package/query/FindOneResult.d.ts +0 -12
- package/query/FindOneResult.js +0 -3
- package/query/FindOneResult.js.map +0 -1
- package/query/FindResult.d.ts +0 -15
- package/query/FindResult.js +0 -3
- package/query/FindResult.js.map +0 -1
- package/query/OnConflictOptions.d.ts +0 -25
- package/query/OnConflictOptions.js +0 -3
- package/query/OnConflictOptions.js.map +0 -1
- package/query/PaginateOptions.d.ts +0 -4
- package/query/PaginateOptions.js +0 -3
- package/query/PaginateOptions.js.map +0 -1
- package/query/PopulateArgs.d.ts +0 -13
- package/query/PopulateArgs.js +0 -3
- package/query/PopulateArgs.js.map +0 -1
- package/query/ReturnSelect.d.ts +0 -5
- package/query/ReturnSelect.js +0 -3
- package/query/ReturnSelect.js.map +0 -1
- package/query/Sort.d.ts +0 -15
- package/query/Sort.js +0 -3
- package/query/Sort.js.map +0 -1
- package/query/WhereQuery.d.ts +0 -21
- package/query/WhereQuery.js +0 -3
- package/query/WhereQuery.js.map +0 -1
- package/query/index.d.ts +0 -15
- package/query/index.js +0 -32
- package/query/index.js.map +0 -1
- package/types/ClassLike.d.ts +0 -8
- package/types/ClassLike.js +0 -3
- package/types/ClassLike.js.map +0 -1
- package/types/CreateUpdateParams.d.ts +0 -9
- package/types/CreateUpdateParams.js +0 -3
- package/types/CreateUpdateParams.js.map +0 -1
- package/types/EntityPrimitiveOrId.d.ts +0 -2
- package/types/EntityPrimitiveOrId.js +0 -3
- package/types/EntityPrimitiveOrId.js.map +0 -1
- package/types/ExcludeEntityCollections.d.ts +0 -5
- package/types/ExcludeEntityCollections.js +0 -3
- package/types/ExcludeEntityCollections.js.map +0 -1
- package/types/ExcludeFunctions.d.ts +0 -4
- package/types/ExcludeFunctions.js +0 -3
- package/types/ExcludeFunctions.js.map +0 -1
- package/types/GetValueType.d.ts +0 -1
- package/types/GetValueType.js +0 -3
- package/types/GetValueType.js.map +0 -1
- package/types/IncludeFunctions.d.ts +0 -4
- package/types/IncludeFunctions.js +0 -3
- package/types/IncludeFunctions.js.map +0 -1
- package/types/IsValueOfType.d.ts +0 -1
- package/types/IsValueOfType.js +0 -3
- package/types/IsValueOfType.js.map +0 -1
- package/types/OmitEntityCollections.d.ts +0 -7
- package/types/OmitEntityCollections.js +0 -3
- package/types/OmitEntityCollections.js.map +0 -1
- package/types/OmitFunctions.d.ts +0 -7
- package/types/OmitFunctions.js +0 -3
- package/types/OmitFunctions.js.map +0 -1
- package/types/PickAsType.d.ts +0 -3
- package/types/PickAsType.js +0 -3
- package/types/PickAsType.js.map +0 -1
- package/types/PickByValueType.d.ts +0 -5
- package/types/PickByValueType.js +0 -3
- package/types/PickByValueType.js.map +0 -1
- package/types/PickFunctions.d.ts +0 -4
- package/types/PickFunctions.js +0 -3
- package/types/PickFunctions.js.map +0 -1
- package/types/Populated.d.ts +0 -9
- package/types/Populated.js +0 -3
- package/types/Populated.js.map +0 -1
- package/types/QueryResult.d.ts +0 -9
- package/types/QueryResult.js +0 -3
- package/types/QueryResult.js.map +0 -1
- package/types/QueryResultOptionalPopulated.d.ts +0 -9
- package/types/QueryResultOptionalPopulated.js +0 -3
- package/types/QueryResultOptionalPopulated.js.map +0 -1
- package/types/QueryResultPopulated.d.ts +0 -9
- package/types/QueryResultPopulated.js +0 -3
- package/types/QueryResultPopulated.js.map +0 -1
- package/types/index.d.ts +0 -17
- package/types/index.js +0 -34
- package/types/index.js.map +0 -1
package/ReadonlyRepository.js
DELETED
|
@@ -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
|