@mikro-orm/core 7.0.0-dev.6 → 7.0.0-dev.60

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 (122) hide show
  1. package/EntityManager.d.ts +85 -32
  2. package/EntityManager.js +281 -178
  3. package/MikroORM.d.ts +8 -8
  4. package/MikroORM.js +31 -74
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.d.ts +2 -1
  7. package/cache/FileCacheAdapter.js +5 -4
  8. package/connections/Connection.d.ts +11 -7
  9. package/connections/Connection.js +16 -13
  10. package/decorators/Embedded.d.ts +5 -11
  11. package/decorators/Entity.d.ts +18 -3
  12. package/decorators/Indexed.d.ts +2 -2
  13. package/decorators/ManyToMany.d.ts +2 -0
  14. package/decorators/ManyToOne.d.ts +4 -0
  15. package/decorators/OneToOne.d.ts +4 -0
  16. package/decorators/Property.d.ts +53 -9
  17. package/decorators/Transactional.d.ts +3 -1
  18. package/decorators/Transactional.js +6 -3
  19. package/decorators/index.d.ts +1 -1
  20. package/drivers/DatabaseDriver.d.ts +11 -5
  21. package/drivers/DatabaseDriver.js +13 -4
  22. package/drivers/IDatabaseDriver.d.ts +29 -5
  23. package/entity/ArrayCollection.d.ts +6 -4
  24. package/entity/ArrayCollection.js +26 -9
  25. package/entity/BaseEntity.d.ts +0 -1
  26. package/entity/BaseEntity.js +0 -3
  27. package/entity/Collection.d.ts +3 -4
  28. package/entity/Collection.js +34 -17
  29. package/entity/EntityAssigner.d.ts +1 -1
  30. package/entity/EntityAssigner.js +9 -1
  31. package/entity/EntityFactory.d.ts +7 -0
  32. package/entity/EntityFactory.js +40 -22
  33. package/entity/EntityHelper.js +25 -8
  34. package/entity/EntityLoader.d.ts +5 -4
  35. package/entity/EntityLoader.js +69 -36
  36. package/entity/EntityRepository.d.ts +1 -1
  37. package/entity/EntityValidator.js +2 -2
  38. package/entity/Reference.d.ts +9 -7
  39. package/entity/Reference.js +32 -5
  40. package/entity/WrappedEntity.d.ts +0 -2
  41. package/entity/WrappedEntity.js +1 -5
  42. package/entity/defineEntity.d.ts +555 -0
  43. package/entity/defineEntity.js +529 -0
  44. package/entity/index.d.ts +2 -0
  45. package/entity/index.js +2 -0
  46. package/entity/utils.d.ts +7 -0
  47. package/entity/utils.js +15 -3
  48. package/enums.d.ts +18 -5
  49. package/enums.js +13 -0
  50. package/errors.d.ts +6 -1
  51. package/errors.js +14 -4
  52. package/events/EventSubscriber.d.ts +3 -1
  53. package/hydration/ObjectHydrator.d.ts +4 -4
  54. package/hydration/ObjectHydrator.js +35 -24
  55. package/index.d.ts +2 -1
  56. package/index.js +1 -1
  57. package/logging/DefaultLogger.d.ts +1 -1
  58. package/logging/SimpleLogger.d.ts +1 -1
  59. package/metadata/EntitySchema.d.ts +8 -4
  60. package/metadata/EntitySchema.js +40 -20
  61. package/metadata/MetadataDiscovery.d.ts +5 -7
  62. package/metadata/MetadataDiscovery.js +150 -155
  63. package/metadata/MetadataStorage.js +1 -1
  64. package/metadata/MetadataValidator.js +4 -3
  65. package/metadata/discover-entities.d.ts +5 -0
  66. package/metadata/discover-entities.js +39 -0
  67. package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
  68. package/naming-strategy/AbstractNamingStrategy.js +7 -1
  69. package/naming-strategy/NamingStrategy.d.ts +11 -1
  70. package/package.json +14 -7
  71. package/platforms/Platform.d.ts +5 -8
  72. package/platforms/Platform.js +4 -17
  73. package/serialization/EntitySerializer.d.ts +2 -0
  74. package/serialization/EntitySerializer.js +29 -11
  75. package/serialization/EntityTransformer.js +22 -12
  76. package/serialization/SerializationContext.js +14 -11
  77. package/types/BigIntType.d.ts +9 -6
  78. package/types/BigIntType.js +3 -0
  79. package/types/BlobType.d.ts +0 -1
  80. package/types/BlobType.js +0 -3
  81. package/types/BooleanType.d.ts +2 -1
  82. package/types/BooleanType.js +3 -0
  83. package/types/DecimalType.d.ts +6 -4
  84. package/types/DecimalType.js +1 -1
  85. package/types/DoubleType.js +1 -1
  86. package/types/JsonType.d.ts +1 -1
  87. package/types/JsonType.js +7 -2
  88. package/types/Type.d.ts +2 -1
  89. package/types/Type.js +1 -1
  90. package/types/Uint8ArrayType.d.ts +0 -1
  91. package/types/Uint8ArrayType.js +0 -3
  92. package/types/index.d.ts +1 -1
  93. package/typings.d.ts +94 -50
  94. package/typings.js +31 -31
  95. package/unit-of-work/ChangeSetComputer.js +8 -3
  96. package/unit-of-work/ChangeSetPersister.d.ts +4 -2
  97. package/unit-of-work/ChangeSetPersister.js +37 -16
  98. package/unit-of-work/UnitOfWork.d.ts +8 -1
  99. package/unit-of-work/UnitOfWork.js +110 -53
  100. package/utils/AbstractSchemaGenerator.js +3 -1
  101. package/utils/Configuration.d.ts +201 -184
  102. package/utils/Configuration.js +143 -151
  103. package/utils/ConfigurationLoader.d.ts +9 -22
  104. package/utils/ConfigurationLoader.js +53 -76
  105. package/utils/Cursor.d.ts +3 -3
  106. package/utils/Cursor.js +3 -0
  107. package/utils/DataloaderUtils.d.ts +15 -5
  108. package/utils/DataloaderUtils.js +53 -7
  109. package/utils/EntityComparator.d.ts +8 -4
  110. package/utils/EntityComparator.js +105 -58
  111. package/utils/QueryHelper.d.ts +9 -1
  112. package/utils/QueryHelper.js +66 -5
  113. package/utils/RawQueryFragment.d.ts +36 -4
  114. package/utils/RawQueryFragment.js +34 -13
  115. package/utils/TransactionManager.d.ts +65 -0
  116. package/utils/TransactionManager.js +223 -0
  117. package/utils/Utils.d.ts +13 -12
  118. package/utils/Utils.js +106 -66
  119. package/utils/index.d.ts +1 -0
  120. package/utils/index.js +1 -0
  121. package/utils/upsert-utils.d.ts +7 -2
  122. package/utils/upsert-utils.js +52 -1
package/utils/Utils.js CHANGED
@@ -1,13 +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
6
  import { tokenize } from 'esprima';
9
7
  import { clone } from './clone.js';
10
- import { ARRAY_OPERATORS, JSON_KEY_OPERATORS, GroupOperator, PlainObject, QueryOperator, ReferenceKind } from '../enums.js';
8
+ import { ARRAY_OPERATORS, GroupOperator, JSON_KEY_OPERATORS, PlainObject, QueryOperator, ReferenceKind, } from '../enums.js';
11
9
  import { helper } from '../entity/wrap.js';
12
10
  export const ObjectBindingPattern = Symbol('ObjectBindingPattern');
13
11
  function compareConstructors(a, b) {
@@ -435,7 +433,11 @@ export class Utils {
435
433
  return data;
436
434
  }
437
435
  if (Utils.isEntity(data, true)) {
438
- return helper(data).getPrimaryKey();
436
+ const wrapped = helper(data);
437
+ if (wrapped.__meta.compositePK) {
438
+ return wrapped.getPrimaryKeys();
439
+ }
440
+ return wrapped.getPrimaryKey();
439
441
  }
440
442
  if (strict && meta && Utils.getObjectKeysSize(data) !== meta.primaryKeys.length) {
441
443
  return null;
@@ -444,7 +446,7 @@ export class Utils {
444
446
  if (meta.compositePK) {
445
447
  return this.getCompositeKeyValue(data, meta);
446
448
  }
447
- return data[meta.primaryKeys[0]] || data[meta.serializedPrimaryKey] || null;
449
+ return data[meta.primaryKeys[0]] ?? data[meta.serializedPrimaryKey] ?? null;
448
450
  }
449
451
  return null;
450
452
  }
@@ -483,7 +485,7 @@ export class Utils {
483
485
  static splitPrimaryKeys(key) {
484
486
  return key.split(this.PK_SEPARATOR);
485
487
  }
486
- static getPrimaryKeyValues(entity, primaryKeys, allowScalar = false, convertCustomTypes = false) {
488
+ static getPrimaryKeyValues(entity, meta, allowScalar = false, convertCustomTypes = false) {
487
489
  /* v8 ignore next 3 */
488
490
  if (entity == null) {
489
491
  return entity;
@@ -494,15 +496,28 @@ export class Utils {
494
496
  }
495
497
  return val;
496
498
  }
497
- const pk = Utils.isEntity(entity, true)
498
- ? helper(entity).getPrimaryKey(convertCustomTypes)
499
- : primaryKeys.reduce((o, pk) => { o[pk] = entity[pk]; return o; }, {});
500
- if (primaryKeys.length > 1) {
499
+ let pk;
500
+ if (Utils.isEntity(entity, true)) {
501
+ pk = helper(entity).getPrimaryKey(convertCustomTypes);
502
+ }
503
+ else {
504
+ pk = meta.primaryKeys.reduce((o, pk) => {
505
+ const targetMeta = meta.properties[pk].targetMeta;
506
+ if (targetMeta && Utils.isPlainObject(entity[pk])) {
507
+ o[pk] = Utils.getPrimaryKeyValues(entity[pk], targetMeta, allowScalar, convertCustomTypes);
508
+ }
509
+ else {
510
+ o[pk] = entity[pk];
511
+ }
512
+ return o;
513
+ }, {});
514
+ }
515
+ if (meta.primaryKeys.length > 1) {
501
516
  return toArray(pk);
502
517
  }
503
518
  if (allowScalar) {
504
519
  if (Utils.isPlainObject(pk)) {
505
- return pk[primaryKeys[0]];
520
+ return pk[(meta.primaryKeys)[0]];
506
521
  }
507
522
  return pk;
508
523
  }
@@ -546,7 +561,7 @@ export class Utils {
546
561
  return o;
547
562
  }, {});
548
563
  }
549
- static getOrderedPrimaryKeys(id, meta, platform, convertCustomTypes = false) {
564
+ static getOrderedPrimaryKeys(id, meta, platform, convertCustomTypes = false, allowScalar = false) {
550
565
  const data = (Utils.isPrimaryKey(id) ? { [meta.primaryKeys[0]]: id } : id);
551
566
  const pks = meta.primaryKeys.map((pk, idx) => {
552
567
  const prop = meta.properties[pk];
@@ -556,11 +571,14 @@ export class Utils {
556
571
  value = prop.customType.convertToJSValue(value, platform);
557
572
  }
558
573
  if (prop.kind !== ReferenceKind.SCALAR && prop.targetMeta) {
559
- const value2 = this.getOrderedPrimaryKeys(value, prop.targetMeta, platform, convertCustomTypes);
574
+ const value2 = this.getOrderedPrimaryKeys(value, prop.targetMeta, platform, convertCustomTypes, allowScalar);
560
575
  value = value2.length > 1 ? value2 : value2[0];
561
576
  }
562
577
  return value;
563
578
  });
579
+ if (allowScalar && pks.length === 1) {
580
+ return pks[0];
581
+ }
564
582
  // we need to flatten the PKs as composite PKs can be build from another composite PKs
565
583
  // and this method is used to get the PK hash in identity map, that expects flat array
566
584
  return Utils.flatten(pks);
@@ -625,8 +643,12 @@ export class Utils {
625
643
  || !!process.env.TS_JEST // check if ts-jest is used (works only with v27.0.4+)
626
644
  || !!process.env.VITEST // check if vitest is used
627
645
  || !!process.versions.bun // check if bun is used
628
- || process.argv.slice(1).some(arg => arg.includes('ts-node')) // registering ts-node runner
629
- || process.execArgv.some(arg => arg === 'ts-node/esm'); // check for ts-node/esm module loader
646
+ || process.argv.slice(1).some(arg => arg.match(/\.([mc]?ts|tsx)$/)) // executing `.ts` file
647
+ || process.execArgv.some(arg => {
648
+ return arg.includes('ts-node') // check for ts-node loader
649
+ || arg.includes('@swc-node/register') // check for swc-node/register loader
650
+ || arg.includes('node_modules/tsx/'); // check for tsx loader
651
+ });
630
652
  }
631
653
  /**
632
654
  * Uses some dark magic to get source path to caller where decorator is used.
@@ -644,7 +666,8 @@ export class Utils {
644
666
  // but those are also present in node, so we need to check this only if they weren't found.
645
667
  if (line === -1) {
646
668
  // here we handle bun which stack is different from nodejs so we search for reflect-metadata
647
- const reflectLine = stack.findIndex(line => Utils.normalizePath(line).includes('node_modules/reflect-metadata/Reflect.js'));
669
+ // Different bun versions might have different stack traces. The "last index" works for both 1.2.6 and 1.2.7.
670
+ const reflectLine = stack.findLastIndex(line => Utils.normalizePath(line).includes('node_modules/reflect-metadata/Reflect.js'));
648
671
  if (reflectLine === -1 || reflectLine + 2 >= stack.length || !stack[reflectLine + 1].includes('bun:wrap')) {
649
672
  return name;
650
673
  }
@@ -673,11 +696,11 @@ export class Utils {
673
696
  return simple;
674
697
  }
675
698
  const objectType = Object.prototype.toString.call(value);
676
- const type = objectType.match(/\[object (\w+)]/)[1];
699
+ const type = objectType.match(/^\[object (.+)]$/)[1];
677
700
  if (type === 'Uint8Array') {
678
701
  return 'Buffer';
679
702
  }
680
- return ['Date', 'Buffer', 'RegExp'].includes(type) ? type : type.toLowerCase();
703
+ return type;
681
704
  }
682
705
  /**
683
706
  * Checks whether the value is POJO (e.g. `{ foo: 'bar' }`, and not instance of `Foo`)
@@ -761,8 +784,9 @@ export class Utils {
761
784
  }
762
785
  return Utils.normalizePath(path);
763
786
  }
764
- static hash(data, length) {
765
- const hash = createHash('md5').update(data).digest('hex');
787
+ static hash(data, length, algorithm) {
788
+ const hashAlgorithm = algorithm || 'sha256';
789
+ const hash = createHash(hashAlgorithm).update(data).digest('hex');
766
790
  if (length) {
767
791
  return hash.substring(0, length);
768
792
  }
@@ -794,12 +818,32 @@ export class Utils {
794
818
  static randomInt(min, max) {
795
819
  return Math.round(Math.random() * (max - min)) + min;
796
820
  }
797
- static async pathExists(path, options = {}) {
798
- if (globby.hasMagic(path)) {
799
- const found = await globby(path, options);
821
+ static glob(input, cwd) {
822
+ if (Array.isArray(input)) {
823
+ return input.flatMap(paths => this.glob(paths, cwd));
824
+ }
825
+ const hasGlobChars = /[*?[\]]/.test(input);
826
+ if (!hasGlobChars) {
827
+ try {
828
+ const s = statSync(cwd ? Utils.normalizePath(cwd, input) : input);
829
+ if (s.isDirectory()) {
830
+ const files = globSync(join(input, '**'), { cwd, withFileTypes: true });
831
+ return files.filter(f => f.isFile()).map(f => join(f.parentPath, f.name));
832
+ }
833
+ }
834
+ catch {
835
+ // ignore
836
+ }
837
+ }
838
+ const files = globSync(input, { cwd, withFileTypes: true });
839
+ return files.filter(f => f.isFile()).map(f => join(f.parentPath, f.name));
840
+ }
841
+ static pathExists(path) {
842
+ if (/[*?[\]]/.test(path)) {
843
+ const found = globSync(path);
800
844
  return found.length > 0;
801
845
  }
802
- return this.pathExistsSync(path);
846
+ return existsSync(path);
803
847
  }
804
848
  /**
805
849
  * Extracts all possible values of a TS enum. Works with both string and numeric enums.
@@ -863,18 +907,25 @@ export class Utils {
863
907
  }
864
908
  return createRequire(resolve(from))(id);
865
909
  }
866
- static async dynamicImport(id) {
867
- /* v8 ignore next 7 */
868
- if (platform() === 'win32') {
869
- try {
870
- id = pathToFileURL(id).toString();
871
- }
872
- catch {
873
- // ignore
874
- }
910
+ /**
911
+ * Resolve path to a module.
912
+ * @param id The module to require
913
+ * @param [from] Location to start the node resolution
914
+ */
915
+ static resolveModulePath(id, from = process.cwd()) {
916
+ if (!extname(from)) {
917
+ from = join(from, '__fake.js');
875
918
  }
919
+ const path = Utils.normalizePath(createRequire(resolve(from)).resolve(id));
920
+ const parts = path.split('/');
921
+ const idx = parts.lastIndexOf(id) + 1;
922
+ parts.splice(idx, parts.length - idx);
923
+ return parts.join('/');
924
+ }
925
+ static async dynamicImport(id) {
876
926
  /* v8 ignore next */
877
- return this.dynamicImportProvider(id);
927
+ const specifier = id.startsWith('file://') ? id : pathToFileURL(id).href;
928
+ return this.dynamicImportProvider(specifier);
878
929
  }
879
930
  /* v8 ignore next 3 */
880
931
  static setDynamicImportProvider(provider) {
@@ -885,9 +936,6 @@ export class Utils {
885
936
  mkdirSync(path, { recursive: true });
886
937
  }
887
938
  }
888
- static pathExistsSync(path) {
889
- return existsSync(path);
890
- }
891
939
  static readJSONSync(path) {
892
940
  const file = readFileSync(path);
893
941
  return JSON.parse(file.toString());
@@ -899,8 +947,13 @@ export class Utils {
899
947
  /* v8 ignore next 5 */
900
948
  }
901
949
  catch {
902
- // this works in production build where we do not have the `src` folder
903
- return this.requireFrom('../package.json', import.meta.dirname).version;
950
+ try {
951
+ // this works in production build where we do not have the `src` folder
952
+ return this.requireFrom('../package.json', import.meta.dirname).version;
953
+ }
954
+ catch {
955
+ return 'N/A';
956
+ }
904
957
  }
905
958
  }
906
959
  static createFunction(context, code) {
@@ -1035,8 +1088,10 @@ export class Utils {
1035
1088
  }
1036
1089
  catch (err) {
1037
1090
  if (err.message.includes(allowError)) {
1038
- // eslint-disable-next-line no-console
1039
- console.warn(warning);
1091
+ if (warning) {
1092
+ // eslint-disable-next-line no-console
1093
+ console.warn(warning);
1094
+ }
1040
1095
  return undefined;
1041
1096
  }
1042
1097
  throw err;
@@ -1044,37 +1099,22 @@ export class Utils {
1044
1099
  }
1045
1100
  static async tryImport({ module, warning }) {
1046
1101
  try {
1047
- return await this.dynamicImport(module);
1102
+ return await import(module);
1048
1103
  }
1049
1104
  catch (err) {
1050
- // eslint-disable-next-line no-console
1051
- console.warn(warning);
1052
- return undefined;
1105
+ if (err.code === 'ERR_MODULE_NOT_FOUND') {
1106
+ if (warning) {
1107
+ // eslint-disable-next-line no-console
1108
+ console.warn(warning);
1109
+ }
1110
+ return undefined;
1111
+ }
1112
+ throw err;
1053
1113
  }
1054
1114
  }
1055
1115
  static stripRelativePath(str) {
1056
1116
  return str.replace(/^(?:\.\.\/|\.\/)+/, '/');
1057
1117
  }
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
1118
  static xor(a, b) {
1079
1119
  return (a || b) && !(a && b);
1080
1120
  }
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';
@@ -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 { RawQueryFragment } from '../utils/RawQueryFragment.js';
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
+ };
@@ -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 => !p.lazy && !p.embeddable && Array.isArray(uniqueFields) && !uniqueFields.includes(p.name)).map(p => p.name);
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
+ }