@uql/core 3.1.0 → 3.1.2

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 (170) hide show
  1. package/CHANGELOG.md +134 -176
  2. package/README.md +413 -0
  3. package/package.json +31 -26
  4. package/dist/package.json +0 -131
  5. package/src/@types/index.d.ts +0 -1
  6. package/src/@types/jest.d.ts +0 -6
  7. package/src/browser/http/bus.spec.ts +0 -22
  8. package/src/browser/http/bus.ts +0 -17
  9. package/src/browser/http/http.spec.ts +0 -70
  10. package/src/browser/http/http.ts +0 -55
  11. package/src/browser/http/index.ts +0 -2
  12. package/src/browser/index.ts +0 -4
  13. package/src/browser/options.spec.ts +0 -37
  14. package/src/browser/options.ts +0 -18
  15. package/src/browser/querier/genericClientRepository.spec.ts +0 -105
  16. package/src/browser/querier/genericClientRepository.ts +0 -49
  17. package/src/browser/querier/httpQuerier.ts +0 -82
  18. package/src/browser/querier/index.ts +0 -3
  19. package/src/browser/querier/querier.util.spec.ts +0 -35
  20. package/src/browser/querier/querier.util.ts +0 -18
  21. package/src/browser/type/clientQuerier.ts +0 -45
  22. package/src/browser/type/clientQuerierPool.ts +0 -5
  23. package/src/browser/type/clientRepository.ts +0 -22
  24. package/src/browser/type/index.ts +0 -4
  25. package/src/browser/type/request.ts +0 -25
  26. package/src/dialect/abstractDialect.ts +0 -28
  27. package/src/dialect/abstractSqlDialect-spec.ts +0 -1309
  28. package/src/dialect/abstractSqlDialect.ts +0 -805
  29. package/src/dialect/index.ts +0 -3
  30. package/src/dialect/namingStrategy.spec.ts +0 -52
  31. package/src/dialect/queryContext.ts +0 -69
  32. package/src/entity/decorator/definition.spec.ts +0 -736
  33. package/src/entity/decorator/definition.ts +0 -265
  34. package/src/entity/decorator/entity.ts +0 -8
  35. package/src/entity/decorator/field.ts +0 -9
  36. package/src/entity/decorator/id.ts +0 -9
  37. package/src/entity/decorator/index.ts +0 -5
  38. package/src/entity/decorator/relation.spec.ts +0 -41
  39. package/src/entity/decorator/relation.ts +0 -34
  40. package/src/entity/index.ts +0 -1
  41. package/src/express/@types/express.d.ts +0 -8
  42. package/src/express/@types/index.d.ts +0 -1
  43. package/src/express/index.ts +0 -2
  44. package/src/express/querierMiddleware.ts +0 -217
  45. package/src/express/query.util.spec.ts +0 -40
  46. package/src/express/query.util.ts +0 -21
  47. package/src/index.ts +0 -9
  48. package/src/maria/index.ts +0 -3
  49. package/src/maria/mariaDialect.spec.ts +0 -207
  50. package/src/maria/mariaDialect.ts +0 -42
  51. package/src/maria/mariaQuerierPool.test.ts +0 -23
  52. package/src/maria/mariadbQuerier.test.ts +0 -23
  53. package/src/maria/mariadbQuerier.ts +0 -45
  54. package/src/maria/mariadbQuerierPool.ts +0 -21
  55. package/src/migrate/cli.ts +0 -301
  56. package/src/migrate/generator/index.ts +0 -4
  57. package/src/migrate/generator/mongoSchemaGenerator.spec.ts +0 -112
  58. package/src/migrate/generator/mongoSchemaGenerator.ts +0 -115
  59. package/src/migrate/generator/mysqlSchemaGenerator.spec.ts +0 -34
  60. package/src/migrate/generator/mysqlSchemaGenerator.ts +0 -92
  61. package/src/migrate/generator/postgresSchemaGenerator.spec.ts +0 -44
  62. package/src/migrate/generator/postgresSchemaGenerator.ts +0 -127
  63. package/src/migrate/generator/sqliteSchemaGenerator.spec.ts +0 -33
  64. package/src/migrate/generator/sqliteSchemaGenerator.ts +0 -81
  65. package/src/migrate/index.ts +0 -41
  66. package/src/migrate/introspection/index.ts +0 -4
  67. package/src/migrate/introspection/mongoIntrospector.spec.ts +0 -75
  68. package/src/migrate/introspection/mongoIntrospector.ts +0 -47
  69. package/src/migrate/introspection/mysqlIntrospector.spec.ts +0 -113
  70. package/src/migrate/introspection/mysqlIntrospector.ts +0 -278
  71. package/src/migrate/introspection/postgresIntrospector.spec.ts +0 -112
  72. package/src/migrate/introspection/postgresIntrospector.ts +0 -329
  73. package/src/migrate/introspection/sqliteIntrospector.spec.ts +0 -112
  74. package/src/migrate/introspection/sqliteIntrospector.ts +0 -296
  75. package/src/migrate/migrator-mongo.test.ts +0 -54
  76. package/src/migrate/migrator.spec.ts +0 -255
  77. package/src/migrate/migrator.test.ts +0 -94
  78. package/src/migrate/migrator.ts +0 -719
  79. package/src/migrate/namingStrategy.spec.ts +0 -22
  80. package/src/migrate/schemaGenerator-advanced.spec.ts +0 -138
  81. package/src/migrate/schemaGenerator.spec.ts +0 -190
  82. package/src/migrate/schemaGenerator.ts +0 -478
  83. package/src/migrate/storage/databaseStorage.spec.ts +0 -69
  84. package/src/migrate/storage/databaseStorage.ts +0 -100
  85. package/src/migrate/storage/index.ts +0 -2
  86. package/src/migrate/storage/jsonStorage.ts +0 -58
  87. package/src/migrate/type.ts +0 -1
  88. package/src/mongo/index.ts +0 -3
  89. package/src/mongo/mongoDialect.spec.ts +0 -251
  90. package/src/mongo/mongoDialect.ts +0 -238
  91. package/src/mongo/mongodbQuerier.test.ts +0 -45
  92. package/src/mongo/mongodbQuerier.ts +0 -256
  93. package/src/mongo/mongodbQuerierPool.test.ts +0 -25
  94. package/src/mongo/mongodbQuerierPool.ts +0 -24
  95. package/src/mysql/index.ts +0 -3
  96. package/src/mysql/mysql2Querier.test.ts +0 -20
  97. package/src/mysql/mysql2Querier.ts +0 -49
  98. package/src/mysql/mysql2QuerierPool.test.ts +0 -20
  99. package/src/mysql/mysql2QuerierPool.ts +0 -21
  100. package/src/mysql/mysqlDialect.spec.ts +0 -20
  101. package/src/mysql/mysqlDialect.ts +0 -16
  102. package/src/namingStrategy/defaultNamingStrategy.ts +0 -18
  103. package/src/namingStrategy/index.spec.ts +0 -36
  104. package/src/namingStrategy/index.ts +0 -2
  105. package/src/namingStrategy/snakeCaseNamingStrategy.ts +0 -15
  106. package/src/options.spec.ts +0 -41
  107. package/src/options.ts +0 -18
  108. package/src/postgres/index.ts +0 -3
  109. package/src/postgres/manual-types.d.ts +0 -4
  110. package/src/postgres/pgQuerier.test.ts +0 -25
  111. package/src/postgres/pgQuerier.ts +0 -45
  112. package/src/postgres/pgQuerierPool.test.ts +0 -28
  113. package/src/postgres/pgQuerierPool.ts +0 -21
  114. package/src/postgres/postgresDialect.spec.ts +0 -428
  115. package/src/postgres/postgresDialect.ts +0 -144
  116. package/src/querier/abstractQuerier-test.ts +0 -584
  117. package/src/querier/abstractQuerier.ts +0 -353
  118. package/src/querier/abstractQuerierPool-test.ts +0 -20
  119. package/src/querier/abstractQuerierPool.ts +0 -18
  120. package/src/querier/abstractSqlQuerier-spec.ts +0 -979
  121. package/src/querier/abstractSqlQuerier-test.ts +0 -21
  122. package/src/querier/abstractSqlQuerier.ts +0 -138
  123. package/src/querier/decorator/index.ts +0 -3
  124. package/src/querier/decorator/injectQuerier.spec.ts +0 -74
  125. package/src/querier/decorator/injectQuerier.ts +0 -45
  126. package/src/querier/decorator/serialized.spec.ts +0 -98
  127. package/src/querier/decorator/serialized.ts +0 -13
  128. package/src/querier/decorator/transactional.spec.ts +0 -240
  129. package/src/querier/decorator/transactional.ts +0 -56
  130. package/src/querier/index.ts +0 -4
  131. package/src/repository/genericRepository.spec.ts +0 -111
  132. package/src/repository/genericRepository.ts +0 -74
  133. package/src/repository/index.ts +0 -1
  134. package/src/sqlite/index.ts +0 -3
  135. package/src/sqlite/manual-types.d.ts +0 -4
  136. package/src/sqlite/sqliteDialect.spec.ts +0 -155
  137. package/src/sqlite/sqliteDialect.ts +0 -76
  138. package/src/sqlite/sqliteQuerier.spec.ts +0 -36
  139. package/src/sqlite/sqliteQuerier.test.ts +0 -21
  140. package/src/sqlite/sqliteQuerier.ts +0 -37
  141. package/src/sqlite/sqliteQuerierPool.test.ts +0 -12
  142. package/src/sqlite/sqliteQuerierPool.ts +0 -38
  143. package/src/test/entityMock.ts +0 -375
  144. package/src/test/index.ts +0 -3
  145. package/src/test/it.util.ts +0 -69
  146. package/src/test/spec.util.ts +0 -57
  147. package/src/type/entity.ts +0 -218
  148. package/src/type/index.ts +0 -9
  149. package/src/type/migration.ts +0 -241
  150. package/src/type/namingStrategy.ts +0 -17
  151. package/src/type/querier.ts +0 -143
  152. package/src/type/querierPool.ts +0 -26
  153. package/src/type/query.ts +0 -506
  154. package/src/type/repository.ts +0 -142
  155. package/src/type/universalQuerier.ts +0 -133
  156. package/src/type/utility.ts +0 -21
  157. package/src/util/dialect.util-extra.spec.ts +0 -96
  158. package/src/util/dialect.util.spec.ts +0 -23
  159. package/src/util/dialect.util.ts +0 -134
  160. package/src/util/index.ts +0 -5
  161. package/src/util/object.util.spec.ts +0 -29
  162. package/src/util/object.util.ts +0 -27
  163. package/src/util/raw.ts +0 -11
  164. package/src/util/sql.util-extra.spec.ts +0 -17
  165. package/src/util/sql.util.spec.ts +0 -208
  166. package/src/util/sql.util.ts +0 -104
  167. package/src/util/string.util.spec.ts +0 -46
  168. package/src/util/string.util.ts +0 -35
  169. package/tsconfig.build.json +0 -5
  170. package/tsconfig.json +0 -8
@@ -1 +0,0 @@
1
- export * from '../type/index.js';
@@ -1,3 +0,0 @@
1
- export * from './mongoDialect.js';
2
- export * from './mongodbQuerier.js';
3
- export * from './mongodbQuerierPool.js';
@@ -1,251 +0,0 @@
1
- import { expect } from 'bun:test';
2
- import { ObjectId } from 'mongodb';
3
- import { getMeta } from '../entity/index.js';
4
- import { createSpec, Item, type Spec, Tax, TaxCategory, User } from '../test/index.js';
5
- import { MongoDialect } from './mongoDialect.js';
6
-
7
- class MongoDialectSpec implements Spec {
8
- dialect: MongoDialect;
9
-
10
- beforeEach() {
11
- this.dialect = new MongoDialect();
12
- }
13
-
14
- shouldBuildWhere() {
15
- expect(this.dialect.where(Item, undefined)).toEqual({});
16
-
17
- expect(this.dialect.where(Item, {})).toEqual({});
18
-
19
- expect(this.dialect.where(Item, { code: '123' })).toEqual({ code: '123' });
20
-
21
- expect(this.dialect.where(Item, { $and: [{ code: '123', name: 'abc' }] })).toEqual({
22
- $and: [{ code: '123', name: 'abc' }],
23
- });
24
-
25
- expect(
26
- this.dialect.where(TaxCategory, {
27
- creatorId: 1,
28
- $or: [{ name: { $in: ['a', 'b', 'c'] } }, { name: 'abc' }],
29
- pk: '507f191e810c19729de860ea',
30
- }),
31
- ).toEqual({
32
- creatorId: 1,
33
- $or: [{ name: { $in: ['a', 'b', 'c'] } }, { name: 'abc' }],
34
- _id: new ObjectId('507f191e810c19729de860ea'),
35
- });
36
-
37
- expect(this.dialect.where(Item, '507f191e810c19729de860ea' as any)).toEqual({
38
- _id: new ObjectId('507f191e810c19729de860ea'),
39
- });
40
-
41
- expect(this.dialect.where(Item, { id: '507f191e810c19729de860ea' as any })).toEqual({
42
- _id: new ObjectId('507f191e810c19729de860ea'),
43
- });
44
-
45
- expect(this.dialect.where(Item, { id: new ObjectId('507f191e810c19729de860ea') as any })).toEqual({
46
- _id: new ObjectId('507f191e810c19729de860ea'),
47
- });
48
-
49
- expect(this.dialect.where(TaxCategory, '507f191e810c19729de860ea')).toEqual({
50
- _id: new ObjectId('507f191e810c19729de860ea'),
51
- });
52
-
53
- expect(this.dialect.where(TaxCategory, { pk: '507f191e810c19729de860ea' })).toEqual({
54
- _id: new ObjectId('507f191e810c19729de860ea'),
55
- });
56
-
57
- expect(this.dialect.where(TaxCategory, { pk: new ObjectId('507f191e810c19729de860ea') as any })).toEqual({
58
- _id: new ObjectId('507f191e810c19729de860ea'),
59
- });
60
- }
61
-
62
- shouldSelect() {
63
- expect(this.dialect.select(Tax, { name: true })).toEqual({ name: true });
64
- expect(this.dialect.select(Tax, ['id', 'name'])).toEqual({ id: true, name: true });
65
- }
66
-
67
- shouldBuildSort() {
68
- expect(this.dialect.sort(Item, {})).toEqual({});
69
- expect(this.dialect.sort(Item, { code: 1 })).toEqual({ code: 1 });
70
- expect(this.dialect.sort(Item, { code: -1 })).toEqual({ code: -1 });
71
- expect(this.dialect.sort(Item, { code: 1 })).toEqual({ code: 1 });
72
- expect(this.dialect.sort(Item, [{ field: 'code', sort: -1 }])).toEqual({ code: -1 });
73
- expect(
74
- this.dialect.sort(Item, [
75
- ['name', 1],
76
- ['createdAt', -1],
77
- ]),
78
- ).toEqual({ name: 1, createdAt: -1 });
79
- expect(
80
- this.dialect.sort(Item, [
81
- ['name', -1],
82
- ['createdAt', -1],
83
- ]),
84
- ).toEqual({ name: -1, createdAt: -1 });
85
- }
86
-
87
- shouldNormalizeIds() {
88
- const meta = getMeta(User);
89
- expect(
90
- this.dialect.normalizeIds(meta, [
91
- { _id: 'abc' } as Partial<User> as User,
92
- { _id: 'def' } as Partial<User> as User,
93
- ]),
94
- ).toMatchObject([{ id: 'abc' }, { id: 'def' }]);
95
- expect(this.dialect.normalizeIds(meta, undefined)).toBe(undefined);
96
- expect(this.dialect.normalizeId(meta, undefined)).toBe(undefined);
97
- expect(
98
- this.dialect.normalizeId(meta, { _id: 'abc', company: {}, users: [] } as Partial<User> as User),
99
- ).toMatchObject({
100
- id: 'abc',
101
- company: {},
102
- users: [],
103
- });
104
- }
105
-
106
- shouldBuildAggregationPipeline() {
107
- expect(this.dialect.aggregationPipeline(Item, {})).toEqual([]);
108
-
109
- expect(this.dialect.aggregationPipeline(Item, { $where: {} })).toEqual([]);
110
-
111
- expect(this.dialect.aggregationPipeline(Item, {})).toEqual([]);
112
-
113
- expect(this.dialect.aggregationPipeline(Item, { $sort: { code: 1 } })).toEqual([{ $sort: { code: 1 } }]);
114
-
115
- expect(this.dialect.aggregationPipeline(User, { $select: { users: true } })).toEqual([]);
116
-
117
- expect(
118
- this.dialect.aggregationPipeline(TaxCategory, {
119
- $select: { creator: true },
120
- $where: { pk: '507f1f77bcf86cd799439011' },
121
- $sort: { creatorId: -1 },
122
- }),
123
- ).toEqual([
124
- {
125
- $match: {
126
- _id: new ObjectId('507f1f77bcf86cd799439011'),
127
- },
128
- $sort: {
129
- creatorId: -1,
130
- },
131
- },
132
- {
133
- $lookup: {
134
- from: 'User',
135
- localField: 'creatorId',
136
- foreignField: '_id',
137
- as: 'creator',
138
- },
139
- },
140
- {
141
- $unwind: {
142
- path: '$creator',
143
- preserveNullAndEmptyArrays: true,
144
- },
145
- },
146
- ]);
147
-
148
- expect(
149
- this.dialect.aggregationPipeline(Item, {
150
- $select: { measureUnit: true, tax: true },
151
- $where: { code: '123' },
152
- }),
153
- ).toEqual([
154
- {
155
- $match: {
156
- code: '123',
157
- },
158
- },
159
- {
160
- $lookup: {
161
- as: 'measureUnit',
162
- foreignField: '_id',
163
- from: 'MeasureUnit',
164
- localField: 'measureUnitId',
165
- },
166
- },
167
- {
168
- $unwind: { path: '$measureUnit', preserveNullAndEmptyArrays: true },
169
- },
170
- {
171
- $lookup: {
172
- as: 'tax',
173
- foreignField: '_id',
174
- from: 'Tax',
175
- localField: 'taxId',
176
- },
177
- },
178
- {
179
- $unwind: { path: '$tax', preserveNullAndEmptyArrays: true },
180
- },
181
- ]);
182
-
183
- expect(
184
- this.dialect.aggregationPipeline(User, {
185
- $select: { profile: true },
186
- $where: '65496146f8f7899f63768df1' as any,
187
- $limit: 1,
188
- }),
189
- ).toEqual([
190
- {
191
- $match: {
192
- _id: new ObjectId('65496146f8f7899f63768df1'),
193
- },
194
- },
195
- {
196
- $lookup: {
197
- from: 'user_profile',
198
- pipeline: [
199
- {
200
- $match: {
201
- creatorId: new ObjectId('65496146f8f7899f63768df1'),
202
- },
203
- },
204
- ],
205
- as: 'profile',
206
- },
207
- },
208
- {
209
- $unwind: {
210
- path: '$profile',
211
- preserveNullAndEmptyArrays: true,
212
- },
213
- },
214
- ]);
215
-
216
- expect(
217
- this.dialect.aggregationPipeline(User, {
218
- $select: { profile: true },
219
- $where: { id: '65496146f8f7899f63768df1' as any },
220
- $limit: 1,
221
- }),
222
- ).toEqual([
223
- {
224
- $match: {
225
- _id: new ObjectId('65496146f8f7899f63768df1'),
226
- },
227
- },
228
- {
229
- $lookup: {
230
- from: 'user_profile',
231
- pipeline: [
232
- {
233
- $match: {
234
- creatorId: new ObjectId('65496146f8f7899f63768df1'),
235
- },
236
- },
237
- ],
238
- as: 'profile',
239
- },
240
- },
241
- {
242
- $unwind: {
243
- path: '$profile',
244
- preserveNullAndEmptyArrays: true,
245
- },
246
- },
247
- ]);
248
- }
249
- }
250
-
251
- createSpec(new MongoDialectSpec());
@@ -1,238 +0,0 @@
1
- import { type Document, type Filter, ObjectId, type Sort } from 'mongodb';
2
- import { AbstractDialect } from '../dialect/index.js';
3
- import { getMeta } from '../entity/index.js';
4
- import type {
5
- EntityMeta,
6
- FieldValue,
7
- Query,
8
- QueryOptions,
9
- QuerySelect,
10
- QuerySelectMap,
11
- QuerySort,
12
- QueryWhere,
13
- RelationKey,
14
- Type,
15
- } from '../type/index.js';
16
- import {
17
- buildSortMap,
18
- buldQueryWhereAsMap,
19
- type CallbackKey,
20
- fillOnFields,
21
- filterFieldKeys,
22
- filterRelationKeys,
23
- getKeys,
24
- hasKeys,
25
- } from '../util/index.js';
26
-
27
- export class MongoDialect extends AbstractDialect {
28
- where<E extends Document>(entity: Type<E>, where: QueryWhere<E> = {}, { softDelete }: QueryOptions = {}): Filter<E> {
29
- const meta = getMeta(entity);
30
-
31
- where = buldQueryWhereAsMap(meta, where);
32
-
33
- if (meta.softDelete && (softDelete || softDelete === undefined) && !where[meta.softDelete]) {
34
- const field = meta.fields[meta.softDelete];
35
- where[this.resolveColumnName(meta.softDelete, field)] = null;
36
- }
37
-
38
- return getKeys(where).reduce(
39
- (acc, key) => {
40
- let value = where[key];
41
- if (key === '$and' || key === '$or') {
42
- acc[key] = value.map((filterIt: QueryWhere<E>) => this.where(entity, filterIt));
43
- } else {
44
- const field = meta.fields[key];
45
- if (key === '_id' || key === meta.id) {
46
- key = '_id';
47
- value = this.getIdValue(value);
48
- } else if (field) {
49
- key = this.resolveColumnName(key, field);
50
- }
51
- if (Array.isArray(value)) {
52
- value = {
53
- $in: value,
54
- };
55
- }
56
- acc[key as keyof Filter<E>] = value;
57
- }
58
- return acc;
59
- },
60
- {} as Filter<E>,
61
- );
62
- }
63
-
64
- select<E extends Document>(entity: Type<E>, select: QuerySelect<E>): QuerySelectMap<E> {
65
- if (Array.isArray(select)) {
66
- return select.reduce(
67
- (acc, it) => {
68
- acc[it as string] = true;
69
- return acc;
70
- },
71
- {} satisfies QuerySelectMap<E>,
72
- );
73
- }
74
- return select as QuerySelectMap<E>;
75
- }
76
-
77
- sort<E extends Document>(entity: Type<E>, sort: QuerySort<E>): Sort {
78
- return buildSortMap(sort) as Sort;
79
- }
80
-
81
- aggregationPipeline<E extends Document>(entity: Type<E>, q: Query<E>): MongoAggregationPipelineEntry<E>[] {
82
- const meta = getMeta(entity);
83
-
84
- const where = this.where(entity, q.$where);
85
- const sort = this.sort(entity, q.$sort);
86
- const firstPipelineEntry: MongoAggregationPipelineEntry<E> = {};
87
-
88
- if (hasKeys(where)) {
89
- firstPipelineEntry.$match = where;
90
- }
91
- if (hasKeys(sort)) {
92
- firstPipelineEntry.$sort = sort;
93
- }
94
-
95
- const pipeline: MongoAggregationPipelineEntry<E>[] = [];
96
-
97
- if (hasKeys(firstPipelineEntry)) {
98
- pipeline.push(firstPipelineEntry);
99
- }
100
-
101
- const relKeys = filterRelationKeys(meta, q.$select);
102
-
103
- for (const relKey of relKeys) {
104
- const relOpts = meta.relations[relKey];
105
-
106
- if (relOpts.cardinality === '1m' || relOpts.cardinality === 'mm') {
107
- // '1m' and 'mm' should be resolved in a higher layer because they will need multiple queries
108
- continue;
109
- }
110
-
111
- const relEntity = relOpts.entity();
112
- const relMeta = getMeta(relEntity);
113
-
114
- if (relOpts.cardinality === 'm1') {
115
- const localField = meta.fields[relOpts.references[0].local];
116
- pipeline.push({
117
- $lookup: {
118
- from: this.resolveTableName(relEntity, relMeta),
119
- localField: this.resolveColumnName(relOpts.references[0].local, localField),
120
- foreignField: '_id',
121
- as: relKey,
122
- },
123
- });
124
- } else {
125
- const foreignField = relMeta.fields[relOpts.references[0].foreign];
126
- const foreignFieldName = this.resolveColumnName(relOpts.references[0].foreign, foreignField);
127
- const referenceWhere = this.where(relEntity, where);
128
- const referenceSort = this.sort(relEntity, q.$sort);
129
- const referencePipelineEntry: MongoAggregationPipelineEntry<FieldValue<E>> = {
130
- $match: { [foreignFieldName]: referenceWhere._id },
131
- };
132
- if (hasKeys(referenceSort)) {
133
- referencePipelineEntry.$sort = referenceSort;
134
- }
135
- pipeline.push({
136
- $lookup: {
137
- from: this.resolveTableName(relEntity, relMeta),
138
- pipeline: [referencePipelineEntry],
139
- as: relKey,
140
- },
141
- });
142
- }
143
-
144
- pipeline.push({ $unwind: { path: `$${relKey}`, preserveNullAndEmptyArrays: true } });
145
- }
146
-
147
- return pipeline;
148
- }
149
-
150
- normalizeIds<E extends Document>(meta: EntityMeta<E>, docs: E[]): E[] {
151
- return docs?.map((doc) => this.normalizeId(meta, doc));
152
- }
153
-
154
- normalizeId<E extends Document>(meta: EntityMeta<E>, doc: E): E {
155
- if (!doc) {
156
- return;
157
- }
158
-
159
- const res = doc as any;
160
-
161
- if (res._id) {
162
- res[meta.id] = res._id;
163
- if (meta.id !== '_id') {
164
- delete res._id;
165
- }
166
- }
167
-
168
- for (const key of getKeys(meta.fields)) {
169
- const field = meta.fields[key];
170
- const dbName = this.resolveColumnName(key, field);
171
- if (dbName !== key && res[dbName] !== undefined) {
172
- res[key] = res[dbName];
173
- delete res[dbName];
174
- }
175
- }
176
-
177
- const relKeys = getKeys(meta.relations).filter((key) => res[key]) as RelationKey<E>[];
178
-
179
- for (const relKey of relKeys) {
180
- const relOpts = meta.relations[relKey];
181
- const relMeta = getMeta(relOpts.entity());
182
- res[relKey] = Array.isArray(res[relKey])
183
- ? this.normalizeIds(relMeta, res[relKey])
184
- : this.normalizeId(relMeta, res[relKey]);
185
- }
186
-
187
- return res;
188
- }
189
-
190
- getIdValue<T extends IdValue>(value: T): T {
191
- if (value instanceof ObjectId) {
192
- return value;
193
- }
194
- try {
195
- return new ObjectId(value) as T;
196
- } catch (e) {
197
- return value;
198
- }
199
- }
200
-
201
- getPersistable<E>(meta: EntityMeta<E>, payload: E, callbackKey: CallbackKey): E {
202
- return this.getPersistables(meta, payload, callbackKey)[0];
203
- }
204
-
205
- getPersistables<E>(meta: EntityMeta<E>, payload: E | E[], callbackKey: CallbackKey): E[] {
206
- const payloads = fillOnFields(meta, payload, callbackKey);
207
- const persistableKeys = filterFieldKeys(meta, payloads[0], callbackKey);
208
- return payloads.map((it) =>
209
- persistableKeys.reduce((acc, key) => {
210
- const field = meta.fields[key];
211
- acc[this.resolveColumnName(key, field)] = it[key];
212
- return acc;
213
- }, {} as E),
214
- );
215
- }
216
- }
217
-
218
- type MongoAggregationPipelineEntry<E extends Document> = {
219
- readonly $lookup?: MongoAggregationLookup<E>;
220
- $match?: Filter<E> | Record<string, any>;
221
- $sort?: Sort;
222
- readonly $unwind?: MongoAggregationUnwind;
223
- };
224
-
225
- type MongoAggregationLookup<E extends Document> = {
226
- readonly from?: string;
227
- readonly foreignField?: string;
228
- readonly localField?: string;
229
- readonly pipeline?: MongoAggregationPipelineEntry<FieldValue<E>>[];
230
- readonly as?: RelationKey<E>;
231
- };
232
-
233
- type MongoAggregationUnwind = {
234
- readonly path?: string;
235
- readonly preserveNullAndEmptyArrays?: boolean;
236
- };
237
-
238
- type IdValue = string | ObjectId;
@@ -1,45 +0,0 @@
1
- import { MongoMemoryReplSet } from 'mongodb-memory-server';
2
- import { getEntities, getMeta } from '../entity/index.js';
3
- import { AbstractQuerierIt } from '../querier/abstractQuerier-test.js';
4
- import { createSpec } from '../test/index.js';
5
- import type { MongodbQuerier } from './mongodbQuerier.js';
6
- import { MongodbQuerierPool } from './mongodbQuerierPool.js';
7
-
8
- class MongodbQuerierIt extends AbstractQuerierIt<MongodbQuerier> {
9
- static replSet: MongoMemoryReplSet;
10
-
11
- constructor() {
12
- super(new MongodbQuerierPool('mongodb://127.0.0.1:27017/test'));
13
- }
14
-
15
- override async beforeAll() {
16
- MongodbQuerierIt.replSet = await MongoMemoryReplSet.create({
17
- replSet: { count: 1, storageEngine: 'wiredTiger' },
18
- });
19
- const uri = MongodbQuerierIt.replSet.getUri();
20
- this.pool = new MongodbQuerierPool(uri);
21
- await super.beforeAll();
22
- }
23
-
24
- override async afterAll() {
25
- await super.afterAll();
26
- await this.pool.end();
27
- await MongodbQuerierIt.replSet.stop();
28
- }
29
-
30
- override async createTables() {
31
- const entities = getEntities();
32
- await Promise.all(
33
- entities.map((entity) => {
34
- const meta = getMeta(entity);
35
- return this.querier.conn.db().createCollection(meta.name);
36
- }),
37
- );
38
- }
39
-
40
- override async dropTables() {
41
- await this.querier.conn.db().dropDatabase();
42
- }
43
- }
44
-
45
- createSpec(new MongodbQuerierIt());