@mikro-orm/core 7.0.0-rc.2 → 7.0.0
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/EntityManager.d.ts +4 -16
- package/EntityManager.js +248 -181
- package/MikroORM.d.ts +4 -6
- package/MikroORM.js +24 -24
- package/README.md +5 -4
- package/cache/FileCacheAdapter.d.ts +1 -5
- package/cache/FileCacheAdapter.js +22 -24
- package/cache/GeneratedCacheAdapter.d.ts +1 -1
- package/cache/GeneratedCacheAdapter.js +6 -6
- package/cache/MemoryCacheAdapter.d.ts +1 -2
- package/cache/MemoryCacheAdapter.js +8 -8
- package/cache/index.d.ts +1 -1
- package/cache/index.js +0 -1
- package/connections/Connection.d.ts +1 -0
- package/connections/Connection.js +43 -14
- package/drivers/DatabaseDriver.d.ts +0 -2
- package/drivers/DatabaseDriver.js +28 -12
- package/drivers/IDatabaseDriver.d.ts +43 -0
- package/entity/Collection.d.ts +1 -9
- package/entity/Collection.js +124 -108
- package/entity/EntityAssigner.js +23 -11
- package/entity/EntityFactory.d.ts +1 -8
- package/entity/EntityFactory.js +79 -59
- package/entity/EntityHelper.js +25 -16
- package/entity/EntityLoader.d.ts +1 -3
- package/entity/EntityLoader.js +90 -60
- package/entity/Reference.d.ts +2 -3
- package/entity/Reference.js +48 -19
- package/entity/WrappedEntity.d.ts +4 -2
- package/entity/WrappedEntity.js +5 -1
- package/entity/defineEntity.d.ts +42 -85
- package/entity/utils.js +28 -26
- package/entity/validators.js +2 -1
- package/enums.d.ts +2 -1
- package/enums.js +13 -17
- package/errors.d.ts +11 -11
- package/errors.js +8 -8
- package/events/EventManager.d.ts +1 -4
- package/events/EventManager.js +26 -23
- package/events/index.d.ts +1 -1
- package/events/index.js +0 -1
- package/exceptions.js +9 -2
- package/hydration/ObjectHydrator.d.ts +1 -2
- package/hydration/ObjectHydrator.js +41 -27
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/logging/DefaultLogger.js +6 -7
- package/logging/Logger.d.ts +2 -1
- package/logging/colors.js +2 -5
- package/logging/index.d.ts +1 -1
- package/logging/index.js +0 -1
- package/metadata/EntitySchema.d.ts +3 -3
- package/metadata/EntitySchema.js +12 -2
- package/metadata/MetadataDiscovery.d.ts +1 -9
- package/metadata/MetadataDiscovery.js +251 -179
- package/metadata/MetadataProvider.js +26 -1
- package/metadata/MetadataStorage.d.ts +1 -5
- package/metadata/MetadataStorage.js +37 -39
- package/metadata/MetadataValidator.js +20 -5
- package/metadata/discover-entities.js +1 -1
- package/metadata/index.d.ts +1 -1
- package/metadata/index.js +0 -1
- package/metadata/types.d.ts +2 -2
- package/naming-strategy/AbstractNamingStrategy.js +6 -3
- package/naming-strategy/EntityCaseNamingStrategy.js +1 -1
- package/naming-strategy/index.d.ts +1 -1
- package/naming-strategy/index.js +0 -1
- package/not-supported.js +5 -1
- package/package.json +38 -38
- package/platforms/Platform.d.ts +24 -1
- package/platforms/Platform.js +106 -27
- package/serialization/EntitySerializer.js +8 -4
- package/serialization/EntityTransformer.js +4 -1
- package/serialization/SerializationContext.d.ts +4 -8
- package/serialization/SerializationContext.js +21 -16
- package/types/UuidType.d.ts +2 -0
- package/types/UuidType.js +14 -2
- package/types/index.d.ts +2 -1
- package/typings.d.ts +35 -24
- package/typings.js +9 -9
- package/unit-of-work/ChangeSet.js +4 -4
- package/unit-of-work/ChangeSetComputer.d.ts +1 -6
- package/unit-of-work/ChangeSetComputer.js +29 -27
- package/unit-of-work/ChangeSetPersister.d.ts +1 -9
- package/unit-of-work/ChangeSetPersister.js +63 -58
- package/unit-of-work/CommitOrderCalculator.d.ts +1 -4
- package/unit-of-work/CommitOrderCalculator.js +17 -15
- package/unit-of-work/IdentityMap.d.ts +2 -5
- package/unit-of-work/IdentityMap.js +18 -18
- package/unit-of-work/UnitOfWork.d.ts +12 -20
- package/unit-of-work/UnitOfWork.js +228 -191
- package/utils/AbstractMigrator.d.ts +2 -2
- package/utils/AbstractMigrator.js +10 -12
- package/utils/AbstractSchemaGenerator.js +2 -1
- package/utils/AsyncContext.js +1 -1
- package/utils/Configuration.d.ts +90 -189
- package/utils/Configuration.js +97 -77
- package/utils/Cursor.d.ts +3 -3
- package/utils/Cursor.js +8 -6
- package/utils/DataloaderUtils.js +15 -12
- package/utils/EntityComparator.d.ts +8 -15
- package/utils/EntityComparator.js +100 -92
- package/utils/QueryHelper.d.ts +16 -1
- package/utils/QueryHelper.js +108 -50
- package/utils/RawQueryFragment.d.ts +4 -4
- package/utils/RawQueryFragment.js +3 -2
- package/utils/TransactionManager.js +3 -3
- package/utils/Utils.d.ts +2 -2
- package/utils/Utils.js +39 -32
- package/utils/clone.js +5 -0
- package/utils/env-vars.js +6 -5
- package/utils/fs-utils.d.ts +3 -17
- package/utils/fs-utils.js +2 -5
- package/utils/upsert-utils.js +7 -4
package/utils/Configuration.js
CHANGED
|
@@ -128,141 +128,159 @@ const DEFAULTS = {
|
|
|
128
128
|
dynamicImportProvider: /* v8 ignore next */ (id) => import(id),
|
|
129
129
|
};
|
|
130
130
|
export class Configuration {
|
|
131
|
-
options;
|
|
132
|
-
logger;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
131
|
+
#options;
|
|
132
|
+
#logger;
|
|
133
|
+
#slowQueryLogger;
|
|
134
|
+
#driver;
|
|
135
|
+
#platform;
|
|
136
|
+
#cache = new Map();
|
|
137
|
+
#extensions = new Map();
|
|
137
138
|
constructor(options, validate = true) {
|
|
138
139
|
if (options.dynamicImportProvider) {
|
|
139
140
|
globalThis.dynamicImportProvider = options.dynamicImportProvider;
|
|
140
141
|
}
|
|
141
|
-
this
|
|
142
|
+
this.#options = Utils.mergeConfig({}, DEFAULTS, options);
|
|
142
143
|
if (validate) {
|
|
143
144
|
this.validateOptions();
|
|
144
145
|
}
|
|
145
|
-
this
|
|
146
|
-
this
|
|
147
|
-
debugMode: this
|
|
148
|
-
ignoreDeprecations: this
|
|
149
|
-
usesReplicas: (this
|
|
150
|
-
highlighter: this
|
|
151
|
-
writer: this
|
|
146
|
+
this.#options.loggerFactory ??= DefaultLogger.create;
|
|
147
|
+
this.#logger = this.#options.loggerFactory({
|
|
148
|
+
debugMode: this.#options.debug,
|
|
149
|
+
ignoreDeprecations: this.#options.ignoreDeprecations,
|
|
150
|
+
usesReplicas: (this.#options.replicas?.length ?? 0) > 0,
|
|
151
|
+
highlighter: this.#options.highlighter,
|
|
152
|
+
writer: this.#options.logger,
|
|
152
153
|
});
|
|
153
|
-
const cf = this
|
|
154
|
+
const cf = this.#options.compiledFunctions;
|
|
154
155
|
if (cf && cf.__version !== Utils.getORMVersion()) {
|
|
155
|
-
this
|
|
156
|
+
this.#logger.warn('discovery', `Compiled functions were generated with MikroORM v${cf.__version ?? 'unknown'}, but the current version is v${Utils.getORMVersion()}. Please regenerate with \`npx mikro-orm compile\`.`);
|
|
156
157
|
}
|
|
157
|
-
if (this
|
|
158
|
-
this
|
|
159
|
-
this
|
|
160
|
-
this
|
|
158
|
+
if (this.#options.driver) {
|
|
159
|
+
this.#driver = new this.#options.driver(this);
|
|
160
|
+
this.#platform = this.#driver.getPlatform();
|
|
161
|
+
this.#platform.setConfig(this);
|
|
161
162
|
this.init(validate);
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
165
|
getPlatform() {
|
|
165
|
-
return this
|
|
166
|
+
return this.#platform;
|
|
166
167
|
}
|
|
167
168
|
/**
|
|
168
169
|
* Gets specific configuration option. Falls back to specified `defaultValue` if provided.
|
|
169
170
|
*/
|
|
170
171
|
get(key, defaultValue) {
|
|
171
|
-
if (typeof this
|
|
172
|
-
return this
|
|
172
|
+
if (typeof this.#options[key] !== 'undefined') {
|
|
173
|
+
return this.#options[key];
|
|
173
174
|
}
|
|
174
175
|
return defaultValue;
|
|
175
176
|
}
|
|
176
177
|
getAll() {
|
|
177
|
-
return this
|
|
178
|
+
return this.#options;
|
|
178
179
|
}
|
|
179
180
|
/**
|
|
180
181
|
* Overrides specified configuration value.
|
|
181
182
|
*/
|
|
182
183
|
set(key, value) {
|
|
183
|
-
this
|
|
184
|
+
this.#options[key] = value;
|
|
184
185
|
this.sync();
|
|
185
186
|
}
|
|
186
187
|
/**
|
|
187
188
|
* Resets the configuration to its default value
|
|
188
189
|
*/
|
|
189
190
|
reset(key) {
|
|
190
|
-
this
|
|
191
|
+
this.#options[key] = DEFAULTS[key];
|
|
191
192
|
}
|
|
192
193
|
/**
|
|
193
194
|
* Gets Logger instance.
|
|
194
195
|
*/
|
|
195
196
|
getLogger() {
|
|
196
|
-
return this
|
|
197
|
+
return this.#logger;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Gets the logger instance for slow queries.
|
|
201
|
+
* Falls back to the main logger if no custom slow query logger factory is configured.
|
|
202
|
+
*/
|
|
203
|
+
getSlowQueryLogger() {
|
|
204
|
+
this.#slowQueryLogger ??=
|
|
205
|
+
this.#options.slowQueryLoggerFactory?.({
|
|
206
|
+
debugMode: this.#options.debug,
|
|
207
|
+
writer: this.#options.logger,
|
|
208
|
+
highlighter: this.#options.highlighter,
|
|
209
|
+
usesReplicas: (this.#options.replicas?.length ?? 0) > 0,
|
|
210
|
+
}) ?? this.#logger;
|
|
211
|
+
return this.#slowQueryLogger;
|
|
197
212
|
}
|
|
198
213
|
getDataloaderType() {
|
|
199
|
-
if (typeof this
|
|
200
|
-
return this
|
|
214
|
+
if (typeof this.#options.dataloader === 'boolean') {
|
|
215
|
+
return this.#options.dataloader ? DataloaderType.ALL : DataloaderType.NONE;
|
|
201
216
|
}
|
|
202
|
-
return this
|
|
217
|
+
return this.#options.dataloader;
|
|
203
218
|
}
|
|
204
219
|
getSchema(skipDefaultSchema = false) {
|
|
205
|
-
if (skipDefaultSchema && this
|
|
220
|
+
if (skipDefaultSchema && this.#options.schema === this.#platform.getDefaultSchemaName()) {
|
|
206
221
|
return undefined;
|
|
207
222
|
}
|
|
208
|
-
return this
|
|
223
|
+
return this.#options.schema;
|
|
209
224
|
}
|
|
210
225
|
/**
|
|
211
226
|
* Gets current database driver instance.
|
|
212
227
|
*/
|
|
213
228
|
getDriver() {
|
|
214
|
-
return this
|
|
229
|
+
return this.#driver;
|
|
215
230
|
}
|
|
216
231
|
registerExtension(name, cb) {
|
|
217
|
-
this
|
|
232
|
+
this.#extensions.set(name, cb);
|
|
218
233
|
}
|
|
219
234
|
getExtension(name) {
|
|
220
|
-
if (this
|
|
221
|
-
return this
|
|
235
|
+
if (this.#cache.has(name)) {
|
|
236
|
+
return this.#cache.get(name);
|
|
222
237
|
}
|
|
223
|
-
const ext = this
|
|
238
|
+
const ext = this.#extensions.get(name);
|
|
224
239
|
/* v8 ignore next */
|
|
225
240
|
if (!ext) {
|
|
226
241
|
return undefined;
|
|
227
242
|
}
|
|
228
|
-
this
|
|
229
|
-
return this
|
|
243
|
+
this.#cache.set(name, ext());
|
|
244
|
+
return this.#cache.get(name);
|
|
230
245
|
}
|
|
231
246
|
/**
|
|
232
247
|
* Gets instance of NamingStrategy. (cached)
|
|
233
248
|
*/
|
|
234
249
|
getNamingStrategy() {
|
|
235
|
-
return this.getCachedService(this
|
|
250
|
+
return this.getCachedService(this.#options.namingStrategy || this.#platform.getNamingStrategy());
|
|
236
251
|
}
|
|
237
252
|
/**
|
|
238
253
|
* Gets instance of Hydrator. (cached)
|
|
239
254
|
*/
|
|
240
255
|
getHydrator(metadata) {
|
|
241
|
-
return this.getCachedService(this
|
|
256
|
+
return this.getCachedService(this.#options.hydrator, metadata, this.#platform, this);
|
|
242
257
|
}
|
|
243
258
|
/**
|
|
244
259
|
* Gets instance of Comparator. (cached)
|
|
245
260
|
*/
|
|
246
261
|
getComparator(metadata) {
|
|
247
|
-
return this.getCachedService(EntityComparator, metadata, this
|
|
262
|
+
return this.getCachedService(EntityComparator, metadata, this.#platform, this);
|
|
248
263
|
}
|
|
249
264
|
/**
|
|
250
265
|
* Gets instance of MetadataProvider. (cached)
|
|
251
266
|
*/
|
|
252
267
|
getMetadataProvider() {
|
|
253
|
-
return this.getCachedService(this
|
|
268
|
+
return this.getCachedService(this.#options.metadataProvider, this);
|
|
254
269
|
}
|
|
255
270
|
/**
|
|
256
271
|
* Gets instance of metadata CacheAdapter. (cached)
|
|
257
272
|
*/
|
|
258
273
|
getMetadataCacheAdapter() {
|
|
259
|
-
return this.getCachedService(this
|
|
274
|
+
return this.getCachedService(this.#options.metadataCache.adapter, this.#options.metadataCache.options, this.#options.baseDir, this.#options.metadataCache.pretty);
|
|
260
275
|
}
|
|
261
276
|
/**
|
|
262
277
|
* Gets instance of CacheAdapter for result cache. (cached)
|
|
263
278
|
*/
|
|
264
279
|
getResultCacheAdapter() {
|
|
265
|
-
return this.getCachedService(this
|
|
280
|
+
return this.getCachedService(this.#options.resultCache.adapter, {
|
|
281
|
+
expiration: this.#options.resultCache.expiration,
|
|
282
|
+
...this.#options.resultCache.options,
|
|
283
|
+
});
|
|
266
284
|
}
|
|
267
285
|
/**
|
|
268
286
|
* Gets EntityRepository class to be instantiated.
|
|
@@ -271,85 +289,87 @@ export class Configuration {
|
|
|
271
289
|
if (repository) {
|
|
272
290
|
return repository();
|
|
273
291
|
}
|
|
274
|
-
if (this
|
|
275
|
-
return this
|
|
292
|
+
if (this.#options.entityRepository) {
|
|
293
|
+
return this.#options.entityRepository;
|
|
276
294
|
}
|
|
277
|
-
return this
|
|
295
|
+
return this.#platform.getRepositoryClass();
|
|
278
296
|
}
|
|
279
297
|
/**
|
|
280
298
|
* Creates instance of given service and caches it.
|
|
281
299
|
*/
|
|
282
300
|
getCachedService(cls, ...args) {
|
|
283
|
-
if (!this
|
|
284
|
-
this
|
|
301
|
+
if (!this.#cache.has(cls.name)) {
|
|
302
|
+
this.#cache.set(cls.name, new cls(...args));
|
|
285
303
|
}
|
|
286
|
-
return this
|
|
304
|
+
return this.#cache.get(cls.name);
|
|
287
305
|
}
|
|
288
306
|
resetServiceCache() {
|
|
289
|
-
this
|
|
307
|
+
this.#cache.clear();
|
|
290
308
|
}
|
|
291
309
|
init(validate) {
|
|
292
310
|
const useCache = this.getMetadataProvider().useCache();
|
|
293
|
-
const metadataCache = this
|
|
311
|
+
const metadataCache = this.#options.metadataCache;
|
|
294
312
|
if (!useCache) {
|
|
295
313
|
metadataCache.adapter = NullCacheAdapter;
|
|
296
314
|
}
|
|
297
315
|
metadataCache.enabled ??= useCache;
|
|
298
|
-
this
|
|
299
|
-
this
|
|
316
|
+
this.#options.clientUrl ??= this.#platform.getDefaultClientUrl();
|
|
317
|
+
this.#options.implicitTransactions ??= this.#platform.usesImplicitTransactions();
|
|
300
318
|
if (validate && metadataCache.enabled && !metadataCache.adapter) {
|
|
301
319
|
throw new Error('No metadata cache adapter specified, please fill in `metadataCache.adapter` option or use the async MikroORM.init() method which can autoload it.');
|
|
302
320
|
}
|
|
303
321
|
try {
|
|
304
|
-
const url = new URL(this
|
|
322
|
+
const url = new URL(this.#options.clientUrl);
|
|
305
323
|
if (url.pathname) {
|
|
306
|
-
this
|
|
324
|
+
this.#options.dbName = this.get('dbName', decodeURIComponent(url.pathname).substring(1));
|
|
307
325
|
}
|
|
308
326
|
}
|
|
309
327
|
catch {
|
|
310
|
-
const url =
|
|
328
|
+
const url = /:\/\/.*\/([^?]+)/.exec(this.#options.clientUrl);
|
|
311
329
|
if (url) {
|
|
312
|
-
this
|
|
330
|
+
this.#options.dbName = this.get('dbName', decodeURIComponent(url[1]));
|
|
313
331
|
}
|
|
314
332
|
}
|
|
315
|
-
if (validate && !this
|
|
333
|
+
if (validate && !this.#options.dbName && this.#options.clientUrl) {
|
|
316
334
|
throw new Error("No database specified, `clientUrl` option provided but it's missing the pathname.");
|
|
317
335
|
}
|
|
318
|
-
this
|
|
319
|
-
this
|
|
320
|
-
Object.keys(this
|
|
321
|
-
this
|
|
336
|
+
this.#options.schema ??= this.#platform.getDefaultSchemaName();
|
|
337
|
+
this.#options.charset ??= this.#platform.getDefaultCharset();
|
|
338
|
+
Object.keys(this.#options.filters).forEach(key => {
|
|
339
|
+
this.#options.filters[key].default ??= true;
|
|
322
340
|
});
|
|
323
|
-
if (!this
|
|
324
|
-
this
|
|
341
|
+
if (!this.#options.filtersOnRelations) {
|
|
342
|
+
this.#options.autoJoinRefsForFilters ??= false;
|
|
325
343
|
}
|
|
326
|
-
this
|
|
344
|
+
this.#options.subscribers = [...this.#options.subscribers].map(subscriber => {
|
|
327
345
|
return subscriber.constructor.name === 'Function' ? new subscriber() : subscriber;
|
|
328
346
|
});
|
|
329
347
|
this.sync();
|
|
330
348
|
if (!colors.enabled()) {
|
|
331
|
-
this
|
|
349
|
+
this.#options.highlighter = new NullHighlighter();
|
|
332
350
|
}
|
|
333
351
|
}
|
|
334
352
|
sync() {
|
|
335
|
-
setEnv('MIKRO_ORM_COLORS', this
|
|
336
|
-
this
|
|
353
|
+
setEnv('MIKRO_ORM_COLORS', this.#options.colors);
|
|
354
|
+
this.#logger.setDebugMode(this.#options.debug);
|
|
355
|
+
this.#slowQueryLogger = undefined;
|
|
337
356
|
}
|
|
338
357
|
validateOptions() {
|
|
339
358
|
/* v8 ignore next */
|
|
340
|
-
if ('type' in this
|
|
341
|
-
throw new Error(
|
|
359
|
+
if ('type' in this.#options) {
|
|
360
|
+
throw new Error("The `type` option has been removed in v6, please fill in the `driver` option instead or use `defineConfig` helper (to define your ORM config) or `MikroORM` class (to call the `init` method) exported from the driver package (e.g. `import { defineConfig } from '@mikro-orm/mysql'; export default defineConfig({ ... })`).");
|
|
342
361
|
}
|
|
343
|
-
if (!this
|
|
344
|
-
throw new Error(
|
|
362
|
+
if (!this.#options.driver) {
|
|
363
|
+
throw new Error("No driver specified, please fill in the `driver` option or use `defineConfig` helper (to define your ORM config) or `MikroORM` class (to call the `init` method) exported from the driver package (e.g. `import { defineConfig } from '@mikro-orm/mysql'; export defineConfig({ ... })`).");
|
|
345
364
|
}
|
|
346
|
-
if (!this
|
|
365
|
+
if (!this.#options.dbName && !this.#options.clientUrl) {
|
|
347
366
|
throw new Error('No database specified, please fill in `dbName` or `clientUrl` option');
|
|
348
367
|
}
|
|
349
|
-
if (this
|
|
368
|
+
if (this.#options.entities.length === 0 && this.#options.discovery.warnWhenNoEntities) {
|
|
350
369
|
throw new Error('No entities found, please use `entities` option');
|
|
351
370
|
}
|
|
352
|
-
if (typeof this
|
|
371
|
+
if (typeof this.#options.driverOptions === 'function' &&
|
|
372
|
+
this.#options.driverOptions.constructor.name === 'AsyncFunction') {
|
|
353
373
|
throw new Error('`driverOptions` callback cannot be async');
|
|
354
374
|
}
|
|
355
375
|
}
|
package/utils/Cursor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityMetadata, FilterObject, Loaded } from '../typings.js';
|
|
1
|
+
import type { EntityKey, EntityMetadata, FilterObject, Loaded } from '../typings.js';
|
|
2
2
|
import type { FindByCursorOptions, OrderDefinition } from '../drivers/IDatabaseDriver.js';
|
|
3
3
|
import { type QueryOrder } from '../enums.js';
|
|
4
4
|
/**
|
|
@@ -49,11 +49,11 @@ import { type QueryOrder } from '../enums.js';
|
|
|
49
49
|
* ```
|
|
50
50
|
*/
|
|
51
51
|
export declare class Cursor<Entity extends object, Hint extends string = never, Fields extends string = '*', Excludes extends string = never, IncludeCount extends boolean = true> {
|
|
52
|
+
#private;
|
|
52
53
|
readonly items: Loaded<Entity, Hint, Fields, Excludes>[];
|
|
53
54
|
readonly totalCount: IncludeCount extends true ? number : undefined;
|
|
54
55
|
readonly hasPrevPage: boolean;
|
|
55
56
|
readonly hasNextPage: boolean;
|
|
56
|
-
private readonly definition;
|
|
57
57
|
constructor(items: Loaded<Entity, Hint, Fields, Excludes>[], totalCount: IncludeCount extends true ? number : undefined, options: FindByCursorOptions<Entity, Hint, Fields, Excludes, IncludeCount>, meta: EntityMetadata<Entity>);
|
|
58
58
|
get startCursor(): string | null;
|
|
59
59
|
get endCursor(): string | null;
|
|
@@ -69,5 +69,5 @@ export declare class Cursor<Entity extends object, Hint extends string = never,
|
|
|
69
69
|
static for<Entity extends object>(meta: EntityMetadata<Entity>, entity: FilterObject<Entity>, orderBy: OrderDefinition<Entity>): string;
|
|
70
70
|
static encode(value: unknown[]): string;
|
|
71
71
|
static decode(value: string): unknown[];
|
|
72
|
-
static getDefinition<Entity extends object>(meta: EntityMetadata<Entity>, orderBy: OrderDefinition<Entity>): [
|
|
72
|
+
static getDefinition<Entity extends object>(meta: EntityMetadata<Entity>, orderBy: OrderDefinition<Entity>): [EntityKey, QueryOrder][];
|
|
73
73
|
}
|
package/utils/Cursor.js
CHANGED
|
@@ -57,7 +57,7 @@ export class Cursor {
|
|
|
57
57
|
totalCount;
|
|
58
58
|
hasPrevPage;
|
|
59
59
|
hasNextPage;
|
|
60
|
-
definition;
|
|
60
|
+
#definition;
|
|
61
61
|
constructor(items, totalCount, options, meta) {
|
|
62
62
|
this.items = items;
|
|
63
63
|
this.totalCount = totalCount;
|
|
@@ -75,7 +75,7 @@ export class Cursor {
|
|
|
75
75
|
items.pop();
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
this
|
|
78
|
+
this.#definition = Cursor.getDefinition(meta, orderBy);
|
|
79
79
|
}
|
|
80
80
|
get startCursor() {
|
|
81
81
|
if (this.items.length === 0) {
|
|
@@ -118,11 +118,11 @@ export class Cursor {
|
|
|
118
118
|
value = value.unwrap();
|
|
119
119
|
}
|
|
120
120
|
if (object) {
|
|
121
|
-
return
|
|
121
|
+
return { [prop]: value };
|
|
122
122
|
}
|
|
123
123
|
return value;
|
|
124
124
|
};
|
|
125
|
-
const value = this
|
|
125
|
+
const value = this.#definition.map(([key, direction]) => processEntity(entity, key, direction));
|
|
126
126
|
return Cursor.encode(value);
|
|
127
127
|
}
|
|
128
128
|
*[Symbol.iterator]() {
|
|
@@ -151,7 +151,7 @@ export class Cursor {
|
|
|
151
151
|
}
|
|
152
152
|
static decode(value) {
|
|
153
153
|
return JSON.parse(Buffer.from(value, 'base64url').toString('utf8')).map((value) => {
|
|
154
|
-
if (typeof value === 'string' &&
|
|
154
|
+
if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}/.exec(value)) {
|
|
155
155
|
return new Date(value);
|
|
156
156
|
}
|
|
157
157
|
return value;
|
|
@@ -167,7 +167,9 @@ export class Cursor {
|
|
|
167
167
|
}
|
|
168
168
|
const prop = meta.properties[key];
|
|
169
169
|
/* v8 ignore next */
|
|
170
|
-
if (!prop ||
|
|
170
|
+
if (!prop ||
|
|
171
|
+
!([ReferenceKind.SCALAR, ReferenceKind.EMBEDDED, ReferenceKind.MANY_TO_ONE].includes(prop.kind) ||
|
|
172
|
+
(prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner))) {
|
|
171
173
|
continue;
|
|
172
174
|
}
|
|
173
175
|
ret.push([prop.name, order[prop.name]]);
|
package/utils/DataloaderUtils.js
CHANGED
|
@@ -101,26 +101,27 @@ export class DataloaderUtils {
|
|
|
101
101
|
const uniqueName = key.substring(0, key.indexOf('|'));
|
|
102
102
|
const opts = JSON.parse(key.substring(key.indexOf('|') + 1));
|
|
103
103
|
const meta = em.getMetadata().getByUniqueName(uniqueName);
|
|
104
|
-
const res = await em.find(meta.class, opts?.where != null && Object.keys(opts.where).length > 0
|
|
105
|
-
{
|
|
104
|
+
const res = await em.find(meta.class, opts?.where != null && Object.keys(opts.where).length > 0
|
|
105
|
+
? {
|
|
106
106
|
$and: [
|
|
107
107
|
{
|
|
108
108
|
$or: Array.from(filterMap.entries()).map(([prop, pks]) => {
|
|
109
|
-
return
|
|
109
|
+
return { [prop]: Array.from(pks) };
|
|
110
110
|
}),
|
|
111
111
|
},
|
|
112
112
|
opts.where,
|
|
113
113
|
],
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
}
|
|
115
|
+
: {
|
|
116
|
+
// The entries of the filter Map will be used as the values of the $or operator
|
|
117
|
+
$or: Array.from(filterMap.entries()).map(([prop, pks]) => {
|
|
118
|
+
return { [prop]: Array.from(pks) };
|
|
119
|
+
}),
|
|
120
|
+
}, {
|
|
120
121
|
...opts,
|
|
121
122
|
// We need to populate the inverse side of the relationship in order to be able to later retrieve the PK(s) from its item(s)
|
|
122
123
|
populate: [
|
|
123
|
-
...(opts.populate === false ? [] : opts.populate ?? []),
|
|
124
|
+
...(opts.populate === false ? [] : (opts.populate ?? [])),
|
|
124
125
|
...Array.from(filterMap.keys()).filter(
|
|
125
126
|
// We need to do so only if the inverse side is a collection, because we can already retrieve the PK from a reference without having to load it
|
|
126
127
|
prop => meta.properties[prop]?.ref !== true),
|
|
@@ -207,7 +208,9 @@ export class DataloaderUtils {
|
|
|
207
208
|
options.refresh ??= c[1]?.refresh;
|
|
208
209
|
}
|
|
209
210
|
options.where = wrap({ $or });
|
|
210
|
-
const r = await em
|
|
211
|
+
const r = await em
|
|
212
|
+
.getEntityLoader()
|
|
213
|
+
.findChildrenFromPivotTable(owners, prop, options, orderBy, populate, group[0][1]?.ref);
|
|
211
214
|
ret.push(...r);
|
|
212
215
|
}
|
|
213
216
|
return ret;
|
|
@@ -224,7 +227,7 @@ export class DataloaderUtils {
|
|
|
224
227
|
}
|
|
225
228
|
catch {
|
|
226
229
|
/* v8 ignore next */
|
|
227
|
-
throw new Error(
|
|
230
|
+
throw new Error("DataLoader is not found, make sure `dataloader` package is installed in your project's dependencies.");
|
|
228
231
|
}
|
|
229
232
|
}
|
|
230
233
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityData, EntityDictionary, EntityMetadata, EntityName, EntityProperty, IMetadataStorage } from '../typings.js';
|
|
1
|
+
import type { EntityData, EntityDictionary, EntityMetadata, EntityName, EntityProperty, IMetadataStorage, Primary } from '../typings.js';
|
|
2
2
|
import type { Platform } from '../platforms/Platform.js';
|
|
3
3
|
import type { Configuration } from './Configuration.js';
|
|
4
4
|
type Comparator<T> = (a: T, b: T, options?: {
|
|
@@ -6,19 +6,12 @@ type Comparator<T> = (a: T, b: T, options?: {
|
|
|
6
6
|
}) => EntityData<T>;
|
|
7
7
|
type ResultMapper<T> = (result: EntityData<T>) => EntityData<T> | null;
|
|
8
8
|
type SnapshotGenerator<T> = (entity: T) => EntityData<T>;
|
|
9
|
+
type PkGetter<T> = (entity: T) => Primary<T>;
|
|
10
|
+
type PkSerializer<T> = (entity: T) => string;
|
|
9
11
|
type CompositeKeyPart = string | CompositeKeyPart[];
|
|
10
12
|
export declare class EntityComparator {
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
private readonly config?;
|
|
14
|
-
private readonly comparators;
|
|
15
|
-
private readonly mappers;
|
|
16
|
-
private readonly snapshotGenerators;
|
|
17
|
-
private readonly pkGetters;
|
|
18
|
-
private readonly pkGettersConverted;
|
|
19
|
-
private readonly pkSerializers;
|
|
20
|
-
private tmpIndex;
|
|
21
|
-
constructor(metadata: IMetadataStorage, platform: Platform, config?: Configuration | undefined);
|
|
13
|
+
#private;
|
|
14
|
+
constructor(metadata: IMetadataStorage, platform: Platform, config?: Configuration);
|
|
22
15
|
/**
|
|
23
16
|
* Computes difference between two entities.
|
|
24
17
|
*/
|
|
@@ -38,15 +31,15 @@ export declare class EntityComparator {
|
|
|
38
31
|
/**
|
|
39
32
|
* @internal Highly performance-sensitive method.
|
|
40
33
|
*/
|
|
41
|
-
getPkGetter<T>(meta: EntityMetadata<T>):
|
|
34
|
+
getPkGetter<T>(meta: EntityMetadata<T>): PkGetter<T>;
|
|
42
35
|
/**
|
|
43
36
|
* @internal Highly performance-sensitive method.
|
|
44
37
|
*/
|
|
45
|
-
getPkGetterConverted<T>(meta: EntityMetadata<T>):
|
|
38
|
+
getPkGetterConverted<T>(meta: EntityMetadata<T>): PkGetter<T>;
|
|
46
39
|
/**
|
|
47
40
|
* @internal Highly performance-sensitive method.
|
|
48
41
|
*/
|
|
49
|
-
getPkSerializer<T>(meta: EntityMetadata<T>):
|
|
42
|
+
getPkSerializer<T>(meta: EntityMetadata<T>): PkSerializer<T>;
|
|
50
43
|
/**
|
|
51
44
|
* @internal Highly performance-sensitive method.
|
|
52
45
|
*/
|