@mikro-orm/core 7.0.0-dev.6 → 7.0.0-dev.61
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 +85 -32
- package/EntityManager.js +281 -178
- package/MikroORM.d.ts +8 -8
- package/MikroORM.js +31 -74
- package/README.md +3 -2
- package/cache/FileCacheAdapter.d.ts +2 -1
- package/cache/FileCacheAdapter.js +5 -4
- package/connections/Connection.d.ts +11 -7
- package/connections/Connection.js +16 -13
- package/decorators/Embeddable.d.ts +2 -0
- package/decorators/Embedded.d.ts +5 -11
- package/decorators/Entity.d.ts +20 -3
- package/decorators/Indexed.d.ts +2 -2
- package/decorators/ManyToMany.d.ts +2 -0
- package/decorators/ManyToOne.d.ts +4 -0
- package/decorators/OneToOne.d.ts +4 -0
- package/decorators/Property.d.ts +53 -9
- package/decorators/Transactional.d.ts +3 -1
- package/decorators/Transactional.js +6 -3
- package/decorators/index.d.ts +1 -1
- package/drivers/DatabaseDriver.d.ts +11 -5
- package/drivers/DatabaseDriver.js +13 -4
- package/drivers/IDatabaseDriver.d.ts +29 -5
- package/entity/ArrayCollection.d.ts +6 -4
- package/entity/ArrayCollection.js +27 -12
- package/entity/BaseEntity.d.ts +0 -1
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +3 -4
- package/entity/Collection.js +34 -17
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +9 -1
- package/entity/EntityFactory.d.ts +7 -0
- package/entity/EntityFactory.js +63 -40
- package/entity/EntityHelper.js +26 -9
- package/entity/EntityLoader.d.ts +5 -4
- package/entity/EntityLoader.js +69 -36
- package/entity/EntityRepository.d.ts +1 -1
- package/entity/EntityValidator.js +2 -2
- package/entity/Reference.d.ts +9 -7
- package/entity/Reference.js +32 -5
- package/entity/WrappedEntity.d.ts +0 -2
- package/entity/WrappedEntity.js +1 -5
- package/entity/defineEntity.d.ts +555 -0
- package/entity/defineEntity.js +529 -0
- package/entity/index.d.ts +2 -0
- package/entity/index.js +2 -0
- package/entity/utils.d.ts +7 -0
- package/entity/utils.js +15 -3
- package/enums.d.ts +18 -5
- package/enums.js +13 -0
- package/errors.d.ts +6 -1
- package/errors.js +14 -4
- package/events/EventSubscriber.d.ts +3 -1
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +35 -24
- package/index.d.ts +2 -1
- package/index.js +1 -1
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/SimpleLogger.d.ts +1 -1
- package/metadata/EntitySchema.d.ts +8 -4
- package/metadata/EntitySchema.js +41 -23
- package/metadata/MetadataDiscovery.d.ts +5 -7
- package/metadata/MetadataDiscovery.js +151 -159
- package/metadata/MetadataStorage.js +1 -1
- package/metadata/MetadataValidator.js +4 -3
- package/metadata/discover-entities.d.ts +5 -0
- package/metadata/discover-entities.js +39 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
- package/naming-strategy/AbstractNamingStrategy.js +7 -1
- package/naming-strategy/NamingStrategy.d.ts +11 -1
- package/package.json +14 -8
- package/platforms/Platform.d.ts +5 -8
- package/platforms/Platform.js +4 -17
- package/serialization/EntitySerializer.d.ts +2 -0
- package/serialization/EntitySerializer.js +29 -11
- package/serialization/EntityTransformer.js +22 -12
- package/serialization/SerializationContext.js +14 -11
- package/types/BigIntType.d.ts +9 -6
- package/types/BigIntType.js +3 -0
- package/types/BlobType.d.ts +0 -1
- package/types/BlobType.js +0 -3
- package/types/BooleanType.d.ts +2 -1
- package/types/BooleanType.js +3 -0
- package/types/DecimalType.d.ts +6 -4
- package/types/DecimalType.js +1 -1
- package/types/DoubleType.js +1 -1
- package/types/JsonType.d.ts +1 -1
- package/types/JsonType.js +7 -2
- package/types/Type.d.ts +2 -1
- package/types/Type.js +1 -1
- package/types/Uint8ArrayType.d.ts +0 -1
- package/types/Uint8ArrayType.js +0 -3
- package/types/index.d.ts +1 -1
- package/typings.d.ts +95 -52
- package/typings.js +31 -31
- package/unit-of-work/ChangeSetComputer.js +8 -3
- package/unit-of-work/ChangeSetPersister.d.ts +4 -2
- package/unit-of-work/ChangeSetPersister.js +37 -16
- package/unit-of-work/UnitOfWork.d.ts +8 -1
- package/unit-of-work/UnitOfWork.js +110 -53
- package/utils/AbstractSchemaGenerator.js +3 -1
- package/utils/Configuration.d.ts +201 -184
- package/utils/Configuration.js +143 -151
- package/utils/ConfigurationLoader.d.ts +9 -22
- package/utils/ConfigurationLoader.js +53 -76
- package/utils/Cursor.d.ts +3 -3
- package/utils/Cursor.js +3 -0
- package/utils/DataloaderUtils.d.ts +15 -5
- package/utils/DataloaderUtils.js +53 -7
- package/utils/EntityComparator.d.ts +8 -4
- package/utils/EntityComparator.js +105 -58
- package/utils/QueryHelper.d.ts +9 -1
- package/utils/QueryHelper.js +66 -5
- package/utils/RawQueryFragment.d.ts +36 -4
- package/utils/RawQueryFragment.js +34 -13
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +223 -0
- package/utils/Utils.d.ts +16 -31
- package/utils/Utils.js +129 -107
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/upsert-utils.d.ts +7 -2
- package/utils/upsert-utils.js +52 -1
package/utils/Utils.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
|
-
import globby from 'globby';
|
|
3
2
|
import { extname, isAbsolute, join, normalize, relative, resolve } from 'node:path';
|
|
4
|
-
import { platform } from 'node:os';
|
|
5
3
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
|
-
import { existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { existsSync, globSync, statSync, mkdirSync, readFileSync } from 'node:fs';
|
|
7
5
|
import { createHash } from 'node:crypto';
|
|
8
|
-
import { tokenize } from 'esprima';
|
|
9
6
|
import { clone } from './clone.js';
|
|
10
|
-
import { ARRAY_OPERATORS,
|
|
7
|
+
import { ARRAY_OPERATORS, GroupOperator, JSON_KEY_OPERATORS, PlainObject, QueryOperator, ReferenceKind, } from '../enums.js';
|
|
11
8
|
import { helper } from '../entity/wrap.js';
|
|
12
|
-
export const ObjectBindingPattern = Symbol('ObjectBindingPattern');
|
|
13
9
|
function compareConstructors(a, b) {
|
|
14
10
|
if (a.constructor === b.constructor) {
|
|
15
11
|
return true;
|
|
@@ -359,53 +355,37 @@ export class Utils {
|
|
|
359
355
|
}
|
|
360
356
|
}
|
|
361
357
|
/**
|
|
362
|
-
* Returns array of functions argument names. Uses
|
|
358
|
+
* Returns array of functions argument names. Uses basic regex for source code analysis, might not work with advanced syntax.
|
|
363
359
|
*/
|
|
364
|
-
static
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
try {
|
|
370
|
-
return tokenize(func.toString(), { tolerant: true });
|
|
360
|
+
static getConstructorParams(func) {
|
|
361
|
+
const source = func.toString();
|
|
362
|
+
const i = source.indexOf('constructor');
|
|
363
|
+
if (i === -1) {
|
|
364
|
+
return undefined;
|
|
371
365
|
}
|
|
372
|
-
|
|
373
|
-
|
|
366
|
+
const start = source.indexOf('(', i);
|
|
367
|
+
if (start === -1) {
|
|
368
|
+
return undefined;
|
|
374
369
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
const ret = [];
|
|
381
|
-
const tokens = this.tokenize(func);
|
|
382
|
-
let inside = 0;
|
|
383
|
-
let currentBlockStart = 0;
|
|
384
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
385
|
-
const token = tokens[i];
|
|
386
|
-
if (token.type === 'Identifier' && token.value === methodName) {
|
|
387
|
-
inside = 1;
|
|
388
|
-
currentBlockStart = i;
|
|
389
|
-
continue;
|
|
370
|
+
let depth = 0;
|
|
371
|
+
let end = start;
|
|
372
|
+
for (; end < source.length; end++) {
|
|
373
|
+
if (source[end] === '(') {
|
|
374
|
+
depth++;
|
|
390
375
|
}
|
|
391
|
-
if (
|
|
392
|
-
|
|
393
|
-
currentBlockStart = i;
|
|
394
|
-
continue;
|
|
376
|
+
if (source[end] === ')') {
|
|
377
|
+
depth--;
|
|
395
378
|
}
|
|
396
|
-
if (
|
|
379
|
+
if (depth === 0) {
|
|
397
380
|
break;
|
|
398
381
|
}
|
|
399
|
-
if (inside === 2 && token.type === 'Punctuator' && token.value === '{' && i === currentBlockStart + 1) {
|
|
400
|
-
ret.push(ObjectBindingPattern);
|
|
401
|
-
i = tokens.findIndex((t, idx) => idx > i + 2 && t.type === 'Punctuator' && t.value === '}');
|
|
402
|
-
continue;
|
|
403
|
-
}
|
|
404
|
-
if (inside === 2 && token.type === 'Identifier') {
|
|
405
|
-
ret.push(token.value);
|
|
406
|
-
}
|
|
407
382
|
}
|
|
408
|
-
|
|
383
|
+
const raw = source.slice(start + 1, end);
|
|
384
|
+
return raw
|
|
385
|
+
.split(',')
|
|
386
|
+
.map(s => s.trim().replace(/=.*$/, '').trim())
|
|
387
|
+
.filter(Boolean)
|
|
388
|
+
.map(raw => raw.startsWith('{') && raw.endsWith('}') ? '' : raw);
|
|
409
389
|
}
|
|
410
390
|
/**
|
|
411
391
|
* Checks whether the argument looks like primary key (string, number or ObjectId).
|
|
@@ -435,7 +415,11 @@ export class Utils {
|
|
|
435
415
|
return data;
|
|
436
416
|
}
|
|
437
417
|
if (Utils.isEntity(data, true)) {
|
|
438
|
-
|
|
418
|
+
const wrapped = helper(data);
|
|
419
|
+
if (wrapped.__meta.compositePK) {
|
|
420
|
+
return wrapped.getPrimaryKeys();
|
|
421
|
+
}
|
|
422
|
+
return wrapped.getPrimaryKey();
|
|
439
423
|
}
|
|
440
424
|
if (strict && meta && Utils.getObjectKeysSize(data) !== meta.primaryKeys.length) {
|
|
441
425
|
return null;
|
|
@@ -444,7 +428,7 @@ export class Utils {
|
|
|
444
428
|
if (meta.compositePK) {
|
|
445
429
|
return this.getCompositeKeyValue(data, meta);
|
|
446
430
|
}
|
|
447
|
-
return data[meta.primaryKeys[0]]
|
|
431
|
+
return data[meta.primaryKeys[0]] ?? data[meta.serializedPrimaryKey] ?? null;
|
|
448
432
|
}
|
|
449
433
|
return null;
|
|
450
434
|
}
|
|
@@ -483,7 +467,7 @@ export class Utils {
|
|
|
483
467
|
static splitPrimaryKeys(key) {
|
|
484
468
|
return key.split(this.PK_SEPARATOR);
|
|
485
469
|
}
|
|
486
|
-
static getPrimaryKeyValues(entity,
|
|
470
|
+
static getPrimaryKeyValues(entity, meta, allowScalar = false, convertCustomTypes = false) {
|
|
487
471
|
/* v8 ignore next 3 */
|
|
488
472
|
if (entity == null) {
|
|
489
473
|
return entity;
|
|
@@ -494,15 +478,28 @@ export class Utils {
|
|
|
494
478
|
}
|
|
495
479
|
return val;
|
|
496
480
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
481
|
+
let pk;
|
|
482
|
+
if (Utils.isEntity(entity, true)) {
|
|
483
|
+
pk = helper(entity).getPrimaryKey(convertCustomTypes);
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
pk = meta.primaryKeys.reduce((o, pk) => {
|
|
487
|
+
const targetMeta = meta.properties[pk].targetMeta;
|
|
488
|
+
if (targetMeta && Utils.isPlainObject(entity[pk])) {
|
|
489
|
+
o[pk] = Utils.getPrimaryKeyValues(entity[pk], targetMeta, allowScalar, convertCustomTypes);
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
o[pk] = entity[pk];
|
|
493
|
+
}
|
|
494
|
+
return o;
|
|
495
|
+
}, {});
|
|
496
|
+
}
|
|
497
|
+
if (meta.primaryKeys.length > 1) {
|
|
501
498
|
return toArray(pk);
|
|
502
499
|
}
|
|
503
500
|
if (allowScalar) {
|
|
504
501
|
if (Utils.isPlainObject(pk)) {
|
|
505
|
-
return pk[primaryKeys[0]];
|
|
502
|
+
return pk[(meta.primaryKeys)[0]];
|
|
506
503
|
}
|
|
507
504
|
return pk;
|
|
508
505
|
}
|
|
@@ -546,7 +543,7 @@ export class Utils {
|
|
|
546
543
|
return o;
|
|
547
544
|
}, {});
|
|
548
545
|
}
|
|
549
|
-
static getOrderedPrimaryKeys(id, meta, platform, convertCustomTypes = false) {
|
|
546
|
+
static getOrderedPrimaryKeys(id, meta, platform, convertCustomTypes = false, allowScalar = false) {
|
|
550
547
|
const data = (Utils.isPrimaryKey(id) ? { [meta.primaryKeys[0]]: id } : id);
|
|
551
548
|
const pks = meta.primaryKeys.map((pk, idx) => {
|
|
552
549
|
const prop = meta.properties[pk];
|
|
@@ -556,11 +553,14 @@ export class Utils {
|
|
|
556
553
|
value = prop.customType.convertToJSValue(value, platform);
|
|
557
554
|
}
|
|
558
555
|
if (prop.kind !== ReferenceKind.SCALAR && prop.targetMeta) {
|
|
559
|
-
const value2 = this.getOrderedPrimaryKeys(value, prop.targetMeta, platform, convertCustomTypes);
|
|
556
|
+
const value2 = this.getOrderedPrimaryKeys(value, prop.targetMeta, platform, convertCustomTypes, allowScalar);
|
|
560
557
|
value = value2.length > 1 ? value2 : value2[0];
|
|
561
558
|
}
|
|
562
559
|
return value;
|
|
563
560
|
});
|
|
561
|
+
if (allowScalar && pks.length === 1) {
|
|
562
|
+
return pks[0];
|
|
563
|
+
}
|
|
564
564
|
// we need to flatten the PKs as composite PKs can be build from another composite PKs
|
|
565
565
|
// and this method is used to get the PK hash in identity map, that expects flat array
|
|
566
566
|
return Utils.flatten(pks);
|
|
@@ -625,8 +625,12 @@ export class Utils {
|
|
|
625
625
|
|| !!process.env.TS_JEST // check if ts-jest is used (works only with v27.0.4+)
|
|
626
626
|
|| !!process.env.VITEST // check if vitest is used
|
|
627
627
|
|| !!process.versions.bun // check if bun is used
|
|
628
|
-
|| process.argv.slice(1).some(arg => arg.
|
|
629
|
-
|| process.execArgv.some(arg =>
|
|
628
|
+
|| process.argv.slice(1).some(arg => arg.match(/\.([mc]?ts|tsx)$/)) // executing `.ts` file
|
|
629
|
+
|| process.execArgv.some(arg => {
|
|
630
|
+
return arg.includes('ts-node') // check for ts-node loader
|
|
631
|
+
|| arg.includes('@swc-node/register') // check for swc-node/register loader
|
|
632
|
+
|| arg.includes('node_modules/tsx/'); // check for tsx loader
|
|
633
|
+
});
|
|
630
634
|
}
|
|
631
635
|
/**
|
|
632
636
|
* Uses some dark magic to get source path to caller where decorator is used.
|
|
@@ -644,7 +648,8 @@ export class Utils {
|
|
|
644
648
|
// but those are also present in node, so we need to check this only if they weren't found.
|
|
645
649
|
if (line === -1) {
|
|
646
650
|
// here we handle bun which stack is different from nodejs so we search for reflect-metadata
|
|
647
|
-
|
|
651
|
+
// Different bun versions might have different stack traces. The "last index" works for both 1.2.6 and 1.2.7.
|
|
652
|
+
const reflectLine = stack.findLastIndex(line => Utils.normalizePath(line).includes('node_modules/reflect-metadata/Reflect.js'));
|
|
648
653
|
if (reflectLine === -1 || reflectLine + 2 >= stack.length || !stack[reflectLine + 1].includes('bun:wrap')) {
|
|
649
654
|
return name;
|
|
650
655
|
}
|
|
@@ -673,11 +678,11 @@ export class Utils {
|
|
|
673
678
|
return simple;
|
|
674
679
|
}
|
|
675
680
|
const objectType = Object.prototype.toString.call(value);
|
|
676
|
-
const type = objectType.match(
|
|
681
|
+
const type = objectType.match(/^\[object (.+)]$/)[1];
|
|
677
682
|
if (type === 'Uint8Array') {
|
|
678
683
|
return 'Buffer';
|
|
679
684
|
}
|
|
680
|
-
return
|
|
685
|
+
return type;
|
|
681
686
|
}
|
|
682
687
|
/**
|
|
683
688
|
* Checks whether the value is POJO (e.g. `{ foo: 'bar' }`, and not instance of `Foo`)
|
|
@@ -761,8 +766,9 @@ export class Utils {
|
|
|
761
766
|
}
|
|
762
767
|
return Utils.normalizePath(path);
|
|
763
768
|
}
|
|
764
|
-
static hash(data, length) {
|
|
765
|
-
const
|
|
769
|
+
static hash(data, length, algorithm) {
|
|
770
|
+
const hashAlgorithm = algorithm || 'sha256';
|
|
771
|
+
const hash = createHash(hashAlgorithm).update(data).digest('hex');
|
|
766
772
|
if (length) {
|
|
767
773
|
return hash.substring(0, length);
|
|
768
774
|
}
|
|
@@ -794,12 +800,32 @@ export class Utils {
|
|
|
794
800
|
static randomInt(min, max) {
|
|
795
801
|
return Math.round(Math.random() * (max - min)) + min;
|
|
796
802
|
}
|
|
797
|
-
static
|
|
798
|
-
if (
|
|
799
|
-
|
|
803
|
+
static glob(input, cwd) {
|
|
804
|
+
if (Array.isArray(input)) {
|
|
805
|
+
return input.flatMap(paths => this.glob(paths, cwd));
|
|
806
|
+
}
|
|
807
|
+
const hasGlobChars = /[*?[\]]/.test(input);
|
|
808
|
+
if (!hasGlobChars) {
|
|
809
|
+
try {
|
|
810
|
+
const s = statSync(cwd ? Utils.normalizePath(cwd, input) : input);
|
|
811
|
+
if (s.isDirectory()) {
|
|
812
|
+
const files = globSync(join(input, '**'), { cwd, withFileTypes: true });
|
|
813
|
+
return files.filter(f => f.isFile()).map(f => join(f.parentPath, f.name));
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
catch {
|
|
817
|
+
// ignore
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
const files = globSync(input, { cwd, withFileTypes: true });
|
|
821
|
+
return files.filter(f => f.isFile()).map(f => join(f.parentPath, f.name));
|
|
822
|
+
}
|
|
823
|
+
static pathExists(path) {
|
|
824
|
+
if (/[*?[\]]/.test(path)) {
|
|
825
|
+
const found = globSync(path);
|
|
800
826
|
return found.length > 0;
|
|
801
827
|
}
|
|
802
|
-
return
|
|
828
|
+
return existsSync(path);
|
|
803
829
|
}
|
|
804
830
|
/**
|
|
805
831
|
* Extracts all possible values of a TS enum. Works with both string and numeric enums.
|
|
@@ -863,18 +889,25 @@ export class Utils {
|
|
|
863
889
|
}
|
|
864
890
|
return createRequire(resolve(from))(id);
|
|
865
891
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
}
|
|
892
|
+
/**
|
|
893
|
+
* Resolve path to a module.
|
|
894
|
+
* @param id The module to require
|
|
895
|
+
* @param [from] Location to start the node resolution
|
|
896
|
+
*/
|
|
897
|
+
static resolveModulePath(id, from = process.cwd()) {
|
|
898
|
+
if (!extname(from)) {
|
|
899
|
+
from = join(from, '__fake.js');
|
|
875
900
|
}
|
|
901
|
+
const path = Utils.normalizePath(createRequire(resolve(from)).resolve(id));
|
|
902
|
+
const parts = path.split('/');
|
|
903
|
+
const idx = parts.lastIndexOf(id) + 1;
|
|
904
|
+
parts.splice(idx, parts.length - idx);
|
|
905
|
+
return parts.join('/');
|
|
906
|
+
}
|
|
907
|
+
static async dynamicImport(id) {
|
|
876
908
|
/* v8 ignore next */
|
|
877
|
-
|
|
909
|
+
const specifier = id.startsWith('file://') ? id : pathToFileURL(id).href;
|
|
910
|
+
return this.dynamicImportProvider(specifier);
|
|
878
911
|
}
|
|
879
912
|
/* v8 ignore next 3 */
|
|
880
913
|
static setDynamicImportProvider(provider) {
|
|
@@ -885,9 +918,6 @@ export class Utils {
|
|
|
885
918
|
mkdirSync(path, { recursive: true });
|
|
886
919
|
}
|
|
887
920
|
}
|
|
888
|
-
static pathExistsSync(path) {
|
|
889
|
-
return existsSync(path);
|
|
890
|
-
}
|
|
891
921
|
static readJSONSync(path) {
|
|
892
922
|
const file = readFileSync(path);
|
|
893
923
|
return JSON.parse(file.toString());
|
|
@@ -899,8 +929,13 @@ export class Utils {
|
|
|
899
929
|
/* v8 ignore next 5 */
|
|
900
930
|
}
|
|
901
931
|
catch {
|
|
902
|
-
|
|
903
|
-
|
|
932
|
+
try {
|
|
933
|
+
// this works in production build where we do not have the `src` folder
|
|
934
|
+
return this.requireFrom('../package.json', import.meta.dirname).version;
|
|
935
|
+
}
|
|
936
|
+
catch {
|
|
937
|
+
return 'N/A';
|
|
938
|
+
}
|
|
904
939
|
}
|
|
905
940
|
}
|
|
906
941
|
static createFunction(context, code) {
|
|
@@ -1035,8 +1070,10 @@ export class Utils {
|
|
|
1035
1070
|
}
|
|
1036
1071
|
catch (err) {
|
|
1037
1072
|
if (err.message.includes(allowError)) {
|
|
1038
|
-
|
|
1039
|
-
|
|
1073
|
+
if (warning) {
|
|
1074
|
+
// eslint-disable-next-line no-console
|
|
1075
|
+
console.warn(warning);
|
|
1076
|
+
}
|
|
1040
1077
|
return undefined;
|
|
1041
1078
|
}
|
|
1042
1079
|
throw err;
|
|
@@ -1044,37 +1081,22 @@ export class Utils {
|
|
|
1044
1081
|
}
|
|
1045
1082
|
static async tryImport({ module, warning }) {
|
|
1046
1083
|
try {
|
|
1047
|
-
return await
|
|
1084
|
+
return await import(module);
|
|
1048
1085
|
}
|
|
1049
1086
|
catch (err) {
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1087
|
+
if (err.code === 'ERR_MODULE_NOT_FOUND') {
|
|
1088
|
+
if (warning) {
|
|
1089
|
+
// eslint-disable-next-line no-console
|
|
1090
|
+
console.warn(warning);
|
|
1091
|
+
}
|
|
1092
|
+
return undefined;
|
|
1093
|
+
}
|
|
1094
|
+
throw err;
|
|
1053
1095
|
}
|
|
1054
1096
|
}
|
|
1055
1097
|
static stripRelativePath(str) {
|
|
1056
1098
|
return str.replace(/^(?:\.\.\/|\.\/)+/, '/');
|
|
1057
1099
|
}
|
|
1058
|
-
/**
|
|
1059
|
-
* simple process.argv parser, supports only properties with long names, prefixed with `--`
|
|
1060
|
-
*/
|
|
1061
|
-
static parseArgs() {
|
|
1062
|
-
let lastKey;
|
|
1063
|
-
return process.argv.slice(2).reduce((args, arg) => {
|
|
1064
|
-
if (arg.includes('=')) {
|
|
1065
|
-
const [key, value] = arg.split('=');
|
|
1066
|
-
args[key.substring(2)] = value;
|
|
1067
|
-
}
|
|
1068
|
-
else if (lastKey) {
|
|
1069
|
-
args[lastKey] = arg;
|
|
1070
|
-
lastKey = undefined;
|
|
1071
|
-
}
|
|
1072
|
-
else if (arg.startsWith('--')) {
|
|
1073
|
-
lastKey = arg.substring(2);
|
|
1074
|
-
}
|
|
1075
|
-
return args;
|
|
1076
|
-
}, {});
|
|
1077
|
-
}
|
|
1078
1100
|
static xor(a, b) {
|
|
1079
1101
|
return (a || b) && !(a && b);
|
|
1080
1102
|
}
|
package/utils/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './DataloaderUtils.js';
|
|
|
5
5
|
export * from './Utils.js';
|
|
6
6
|
export * from './RequestContext.js';
|
|
7
7
|
export * from './TransactionContext.js';
|
|
8
|
+
export * from './TransactionManager.js';
|
|
8
9
|
export * from './QueryHelper.js';
|
|
9
10
|
export * from './NullHighlighter.js';
|
|
10
11
|
export * from './EntityComparator.js';
|
package/utils/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from './DataloaderUtils.js';
|
|
|
5
5
|
export * from './Utils.js';
|
|
6
6
|
export * from './RequestContext.js';
|
|
7
7
|
export * from './TransactionContext.js';
|
|
8
|
+
export * from './TransactionManager.js';
|
|
8
9
|
export * from './QueryHelper.js';
|
|
9
10
|
export * from './NullHighlighter.js';
|
|
10
11
|
export * from './EntityComparator.js';
|
package/utils/upsert-utils.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import type { EntityData, EntityMetadata } from '../typings.js';
|
|
1
|
+
import type { EntityData, EntityMetadata, FilterQuery } from '../typings.js';
|
|
2
2
|
import type { UpsertOptions } from '../drivers/IDatabaseDriver.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type RawQueryFragment } from '../utils/RawQueryFragment.js';
|
|
4
4
|
/** @internal */
|
|
5
5
|
export declare function getOnConflictFields<T>(meta: EntityMetadata<T> | undefined, data: EntityData<T>, uniqueFields: (keyof T)[] | RawQueryFragment, options: UpsertOptions<T>): (keyof T)[];
|
|
6
6
|
/** @internal */
|
|
7
7
|
export declare function getOnConflictReturningFields<T, P extends string>(meta: EntityMetadata<T> | undefined, data: EntityData<T>, uniqueFields: (keyof T)[] | RawQueryFragment, options: UpsertOptions<T, P>): (keyof T)[] | '*';
|
|
8
|
+
/** @internal */
|
|
9
|
+
export declare function getWhereCondition<T extends object>(meta: EntityMetadata<T>, onConflictFields: (keyof T)[] | RawQueryFragment | undefined, data: EntityData<T>, where: FilterQuery<T>): {
|
|
10
|
+
where: FilterQuery<T>;
|
|
11
|
+
propIndex: number | false;
|
|
12
|
+
};
|
package/utils/upsert-utils.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isRaw } from '../utils/RawQueryFragment.js';
|
|
2
|
+
import { Utils } from './Utils.js';
|
|
1
3
|
function expandEmbeddedProperties(prop, key) {
|
|
2
4
|
if (prop.object) {
|
|
3
5
|
return [prop.name];
|
|
@@ -71,7 +73,15 @@ export function getOnConflictReturningFields(meta, data, uniqueFields, options)
|
|
|
71
73
|
if (!meta) {
|
|
72
74
|
return '*';
|
|
73
75
|
}
|
|
74
|
-
const keys = meta.comparableProps.filter(p =>
|
|
76
|
+
const keys = meta.comparableProps.filter(p => {
|
|
77
|
+
if (p.lazy || p.embeddable) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
if (p.autoincrement) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
return Array.isArray(uniqueFields) && !uniqueFields.includes(p.name);
|
|
84
|
+
}).map(p => p.name);
|
|
75
85
|
if (meta.versionProperty) {
|
|
76
86
|
keys.push(meta.versionProperty);
|
|
77
87
|
}
|
|
@@ -88,3 +98,44 @@ export function getOnConflictReturningFields(meta, data, uniqueFields, options)
|
|
|
88
98
|
}
|
|
89
99
|
return keys.filter(key => !(key in data));
|
|
90
100
|
}
|
|
101
|
+
function getPropertyValue(obj, key) {
|
|
102
|
+
if (key.indexOf('.') === -1) {
|
|
103
|
+
return obj[key];
|
|
104
|
+
}
|
|
105
|
+
const parts = key.split('.');
|
|
106
|
+
let curr = obj;
|
|
107
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
108
|
+
curr[parts[i]] ??= {};
|
|
109
|
+
curr = curr[parts[i]];
|
|
110
|
+
}
|
|
111
|
+
return curr[parts[parts.length - 1]];
|
|
112
|
+
}
|
|
113
|
+
/** @internal */
|
|
114
|
+
export function getWhereCondition(meta, onConflictFields, data, where) {
|
|
115
|
+
const unique = onConflictFields ?? meta.props.filter(p => p.unique).map(p => p.name);
|
|
116
|
+
const propIndex = !isRaw(unique) && unique.findIndex(p => data[p] ?? data[p.substring(0, p.indexOf('.'))] != null);
|
|
117
|
+
if (onConflictFields || where == null) {
|
|
118
|
+
if (propIndex !== false && propIndex >= 0) {
|
|
119
|
+
let key = unique[propIndex];
|
|
120
|
+
if (key.includes('.')) {
|
|
121
|
+
const prop = meta.properties[key.substring(0, key.indexOf('.'))];
|
|
122
|
+
if (prop) {
|
|
123
|
+
key = `${prop.fieldNames[0]}${key.substring(key.indexOf('.'))}`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
where = { [key]: getPropertyValue(data, unique[propIndex]) };
|
|
127
|
+
}
|
|
128
|
+
else if (meta.uniques.length > 0) {
|
|
129
|
+
for (const u of meta.uniques) {
|
|
130
|
+
if (Utils.asArray(u.properties).every(p => data[p] != null)) {
|
|
131
|
+
where = Utils.asArray(u.properties).reduce((o, key) => {
|
|
132
|
+
o[key] = data[key];
|
|
133
|
+
return o;
|
|
134
|
+
}, {});
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return { where, propIndex };
|
|
141
|
+
}
|