@mikro-orm/core 6.3.5-dev.2 → 6.3.5-dev.21

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/README.md CHANGED
@@ -143,7 +143,7 @@ There is also auto-generated [CHANGELOG.md](CHANGELOG.md) file based on commit m
143
143
  - [Using `QueryBuilder`](https://mikro-orm.io/docs/query-builder)
144
144
  - [Preloading Deeply Nested Structures via populate](https://mikro-orm.io/docs/nested-populate)
145
145
  - [Property Validation](https://mikro-orm.io/docs/property-validation)
146
- - [Lifecycle Hooks](https://mikro-orm.io/docs/lifecycle-hooks)
146
+ - [Lifecycle Hooks](https://mikro-orm.io/docs/events#hooks)
147
147
  - [Vanilla JS Support](https://mikro-orm.io/docs/usage-with-js)
148
148
  - [Schema Generator](https://mikro-orm.io/docs/schema-generator)
149
149
  - [Entity Generator](https://mikro-orm.io/docs/entity-generator)
@@ -163,6 +163,7 @@ You can find example integrations for some popular frameworks in the [`mikro-orm
163
163
  - [NextJS + MySQL](https://github.com/jonahallibone/mikro-orm-nextjs)
164
164
  - [Accounts.js REST and GraphQL authentication + SQLite](https://github.com/darkbasic/mikro-orm-accounts-example)
165
165
  - [Nest + Shopify + PostgreSQL + GraphQL](https://github.com/Cloudshelf/Shopify_CSConnector)
166
+ - [Elysia.js + libSQL + Bun](https://github.com/mikro-orm/elysia-bun-example-app)
166
167
 
167
168
  ### JavaScript Examples
168
169
 
@@ -77,7 +77,7 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
77
77
  else if (prop.runtimeType === 'boolean') {
78
78
  ret.push(` entity${entityKey} = !!data${dataKey};`);
79
79
  }
80
- else if (prop.runtimeType === 'Date') {
80
+ else if (prop.runtimeType === 'Date' && !this.platform.isNumericProperty(prop)) {
81
81
  ret.push(` if (data${dataKey} instanceof Date) {`);
82
82
  ret.push(` entity${entityKey} = data${dataKey};`);
83
83
  if (!tz || tz === 'local') {
@@ -64,7 +64,6 @@ export declare class MetadataDiscovery {
64
64
  private getMappedType;
65
65
  private initUnsigned;
66
66
  private initIndexes;
67
- private isNumericProperty;
68
67
  private getEntityClassOrSchema;
69
68
  private shouldForceConstructorUsage;
70
69
  }
@@ -104,7 +104,7 @@ class MetadataDiscovery {
104
104
  this.inferTypeFromDefault(prop);
105
105
  this.initColumnType(prop);
106
106
  // change tracking on scalars is used only for "auto" flushMode
107
- if (this.config.get('flushMode') !== 'auto') {
107
+ if (this.config.get('flushMode') !== 'auto' && [enums_1.ReferenceKind.SCALAR, enums_1.ReferenceKind.EMBEDDED].includes(prop.kind)) {
108
108
  prop.trackChanges = false;
109
109
  }
110
110
  }
@@ -920,7 +920,7 @@ class MetadataDiscovery {
920
920
  }
921
921
  initAutoincrement(meta) {
922
922
  const pks = meta.getPrimaryProps();
923
- if (pks.length === 1 && this.isNumericProperty(pks[0])) {
923
+ if (pks.length === 1 && this.platform.isNumericProperty(pks[0])) {
924
924
  /* istanbul ignore next */
925
925
  pks[0].autoincrement ??= true;
926
926
  }
@@ -1226,7 +1226,7 @@ class MetadataDiscovery {
1226
1226
  });
1227
1227
  return;
1228
1228
  }
1229
- prop.unsigned ??= (prop.primary || prop.unsigned) && this.isNumericProperty(prop) && this.platform.supportsUnsigned();
1229
+ prop.unsigned ??= (prop.primary || prop.unsigned) && this.platform.isNumericProperty(prop) && this.platform.supportsUnsigned();
1230
1230
  }
1231
1231
  initIndexes(meta, prop) {
1232
1232
  const hasIndex = meta.indexes.some(idx => idx.properties?.length === 1 && idx.properties[0] === prop.name);
@@ -1234,13 +1234,6 @@ class MetadataDiscovery {
1234
1234
  prop.index ??= true;
1235
1235
  }
1236
1236
  }
1237
- isNumericProperty(prop) {
1238
- if (prop.customType) {
1239
- return this.platform.isNumericColumn(prop.customType);
1240
- }
1241
- const numericMappedType = prop.columnTypes?.[0] && this.platform.isNumericColumn(this.platform.getMappedType(prop.columnTypes[0]));
1242
- return numericMappedType || prop.type === 'number' || this.platform.isBigIntProperty(prop);
1243
- }
1244
1237
  async getEntityClassOrSchema(path, name) {
1245
1238
  const exports = await Utils_1.Utils.dynamicImport(path);
1246
1239
  const targets = Object.values(exports)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "6.3.5-dev.2",
3
+ "version": "6.3.5-dev.21",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -64,7 +64,7 @@
64
64
  "esprima": "4.0.1",
65
65
  "fs-extra": "11.2.0",
66
66
  "globby": "11.1.0",
67
- "mikro-orm": "6.3.5-dev.2",
67
+ "mikro-orm": "6.3.5-dev.21",
68
68
  "reflect-metadata": "0.2.2"
69
69
  }
70
70
  }
@@ -129,6 +129,14 @@ export declare abstract class Platform {
129
129
  length?: number;
130
130
  }): string;
131
131
  extractSimpleType(type: string): string;
132
+ /**
133
+ * This should be used only to compare types, it can strip some information like the length.
134
+ */
135
+ normalizeColumnType(type: string, options?: {
136
+ length?: number;
137
+ precision?: number;
138
+ scale?: number;
139
+ }): string;
132
140
  getMappedType(type: string): Type<unknown>;
133
141
  getDefaultMappedType(type: string): Type<unknown>;
134
142
  supportsMultipleCascadePaths(): boolean;
@@ -172,6 +180,7 @@ export declare abstract class Platform {
172
180
  setConfig(config: Configuration): void;
173
181
  getConfig(): Configuration;
174
182
  getTimezone(): string | undefined;
183
+ isNumericProperty(prop: EntityProperty, ignoreCustomType?: boolean): boolean;
175
184
  isNumericColumn(mappedType: Type<unknown>): boolean;
176
185
  supportsUnsigned(): boolean;
177
186
  /**
@@ -192,6 +192,12 @@ class Platform {
192
192
  extractSimpleType(type) {
193
193
  return type.toLowerCase().match(/[^(), ]+/)[0];
194
194
  }
195
+ /**
196
+ * This should be used only to compare types, it can strip some information like the length.
197
+ */
198
+ normalizeColumnType(type, options = {}) {
199
+ return type.toLowerCase();
200
+ }
195
201
  getMappedType(type) {
196
202
  const mappedType = this.config.get('discovery').getMappedType?.(type, this);
197
203
  return mappedType ?? this.getDefaultMappedType(type);
@@ -300,6 +306,7 @@ class Platform {
300
306
  }
301
307
  parseDate(value) {
302
308
  const date = new Date(value);
309
+ /* istanbul ignore next */
303
310
  if (isNaN(date.getTime())) {
304
311
  return value;
305
312
  }
@@ -415,6 +422,10 @@ class Platform {
415
422
  getTimezone() {
416
423
  return this.timezone;
417
424
  }
425
+ isNumericProperty(prop, ignoreCustomType = false) {
426
+ const numericMappedType = prop.columnTypes?.[0] && this.isNumericColumn(this.getMappedType(prop.columnTypes[0]));
427
+ return numericMappedType || prop.type === 'number' || this.isBigIntProperty(prop);
428
+ }
418
429
  isNumericColumn(mappedType) {
419
430
  return [types_1.IntegerType, types_1.SmallIntType, types_1.BigIntType, types_1.TinyIntType].some(t => mappedType instanceof t);
420
431
  }
@@ -1,8 +1,9 @@
1
- import { StringType } from './StringType';
2
1
  import type { EntityProperty } from '../typings';
3
2
  import type { Platform } from '../platforms/Platform';
4
- export declare class UnknownType extends StringType {
3
+ import { Type } from './Type';
4
+ export declare class UnknownType extends Type<unknown | null | undefined, unknown | null | undefined> {
5
5
  getColumnType(prop: EntityProperty, platform: Platform): string;
6
6
  get runtimeType(): string;
7
7
  compareAsType(): string;
8
+ ensureComparable(): boolean;
8
9
  }
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UnknownType = void 0;
4
- const StringType_1 = require("./StringType");
5
- class UnknownType extends StringType_1.StringType {
4
+ const Type_1 = require("./Type");
5
+ class UnknownType extends Type_1.Type {
6
6
  getColumnType(prop, platform) {
7
7
  return prop.columnTypes?.[0] ?? platform.getVarcharTypeDeclarationSQL(prop);
8
8
  }
@@ -12,5 +12,8 @@ class UnknownType extends StringType_1.StringType {
12
12
  compareAsType() {
13
13
  return 'unknown';
14
14
  }
15
+ ensureComparable() {
16
+ return false;
17
+ }
15
18
  }
16
19
  exports.UnknownType = UnknownType;
package/typings.d.ts CHANGED
@@ -108,9 +108,9 @@ export type OperatorMap<T> = {
108
108
  $re?: string;
109
109
  $ilike?: string;
110
110
  $fulltext?: string;
111
- $overlap?: string[] | object;
112
- $contains?: string[] | object;
113
- $contained?: string[] | object;
111
+ $overlap?: string[] | string | object;
112
+ $contains?: string[] | string | object;
113
+ $contained?: string[] | string | object;
114
114
  $exists?: boolean;
115
115
  $hasKey?: string;
116
116
  $hasKeys?: string[];
@@ -72,7 +72,6 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
72
72
  persistOnCreate: true;
73
73
  forceEntityConstructor: false;
74
74
  forceUndefined: false;
75
- forceUtcTimezone: false;
76
75
  ensureDatabase: true;
77
76
  ensureIndexes: false;
78
77
  batchSize: number;
@@ -330,7 +329,7 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
330
329
  persistOnCreate: boolean;
331
330
  forceEntityConstructor: boolean | (Constructor<AnyEntity> | string)[];
332
331
  forceUndefined: boolean;
333
- forceUtcTimezone: boolean;
332
+ forceUtcTimezone?: boolean;
334
333
  timezone?: string;
335
334
  ensureDatabase: boolean | EnsureDatabaseOptions;
336
335
  ensureIndexes: boolean;
@@ -67,7 +67,6 @@ class Configuration {
67
67
  persistOnCreate: true,
68
68
  forceEntityConstructor: false,
69
69
  forceUndefined: false,
70
- forceUtcTimezone: false,
71
70
  ensureDatabase: true,
72
71
  ensureIndexes: false,
73
72
  batchSize: 300,
@@ -214,6 +213,7 @@ class Configuration {
214
213
  this.cache.set(name, ext());
215
214
  return this.cache.get(name);
216
215
  }
216
+ /* istanbul ignore next */
217
217
  return undefined;
218
218
  }
219
219
  /**
@@ -85,7 +85,8 @@ class ConfigurationLoader {
85
85
  paths.push(process.env.MIKRO_ORM_CLI_CONFIG);
86
86
  }
87
87
  paths.push(...(settings.configPaths || []));
88
- if (settings.useTsNode !== false || settings.alwaysAllowTs) {
88
+ const alwaysAllowTs = settings.alwaysAllowTs ?? process.versions.bun;
89
+ if (settings.useTsNode !== false || alwaysAllowTs) {
89
90
  paths.push('./src/mikro-orm.config.ts');
90
91
  paths.push('./mikro-orm.config.ts');
91
92
  }
@@ -96,7 +97,7 @@ class ConfigurationLoader {
96
97
  paths.push(`./${path}/mikro-orm.config.js`);
97
98
  paths.push('./mikro-orm.config.js');
98
99
  const tsNode = Utils_1.Utils.detectTsNode();
99
- return Utils_1.Utils.unique(paths).filter(p => p.endsWith('.js') || tsNode || settings.alwaysAllowTs);
100
+ return Utils_1.Utils.unique(paths).filter(p => p.endsWith('.js') || tsNode || alwaysAllowTs);
100
101
  }
101
102
  static isESM() {
102
103
  const config = ConfigurationLoader.getPackageConfig();
@@ -104,6 +105,10 @@ class ConfigurationLoader {
104
105
  return type === 'module';
105
106
  }
106
107
  static registerTsNode(configPath = 'tsconfig.json') {
108
+ /* istanbul ignore next */
109
+ if (process.versions.bun) {
110
+ return true;
111
+ }
107
112
  const tsConfigPath = (0, node_path_1.isAbsolute)(configPath) ? configPath : (0, node_path_1.join)(process.cwd(), configPath);
108
113
  const tsNode = Utils_1.Utils.tryRequire({
109
114
  module: 'ts-node',
@@ -300,7 +300,7 @@ class EntityComparator {
300
300
  lines.push(` ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
301
301
  lines.push(` }`);
302
302
  }
303
- else if (prop.runtimeType === 'Date') {
303
+ else if (prop.runtimeType === 'Date' && !this.platform.isNumericProperty(prop)) {
304
304
  lines.push(` if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
305
305
  context.set('parseDate', (value) => this.platform.parseDate(value));
306
306
  parseDate('ret' + this.wrap(prop.name), this.propName(prop.fieldNames[0]));
@@ -16,8 +16,15 @@ export declare class RequestContext {
16
16
  /**
17
17
  * Creates new RequestContext instance and runs the code inside its domain.
18
18
  * If the handler is async, the return value needs to be awaited.
19
+ * Uses `AsyncLocalStorage.run()`, suitable for regular express style middlewares with a `next` callback.
19
20
  */
20
21
  static create<T>(em: EntityManager | EntityManager[], next: (...args: any[]) => T, options?: CreateContextOptions): T;
22
+ /**
23
+ * Creates new RequestContext instance and runs the code inside its domain.
24
+ * If the handler is async, the return value needs to be awaited.
25
+ * Uses `AsyncLocalStorage.enterWith()`, suitable for elysia style middlewares without a `next` callback.
26
+ */
27
+ static enter(em: EntityManager | EntityManager[], options?: CreateContextOptions): void;
21
28
  /**
22
29
  * Returns current RequestContext (if available).
23
30
  */
@@ -22,11 +22,21 @@ class RequestContext {
22
22
  /**
23
23
  * Creates new RequestContext instance and runs the code inside its domain.
24
24
  * If the handler is async, the return value needs to be awaited.
25
+ * Uses `AsyncLocalStorage.run()`, suitable for regular express style middlewares with a `next` callback.
25
26
  */
26
27
  static create(em, next, options = {}) {
27
28
  const ctx = this.createContext(em, options);
28
29
  return this.storage.run(ctx, next);
29
30
  }
31
+ /**
32
+ * Creates new RequestContext instance and runs the code inside its domain.
33
+ * If the handler is async, the return value needs to be awaited.
34
+ * Uses `AsyncLocalStorage.enterWith()`, suitable for elysia style middlewares without a `next` callback.
35
+ */
36
+ static enter(em, options = {}) {
37
+ const ctx = this.createContext(em, options);
38
+ this.storage.enterWith(ctx);
39
+ }
30
40
  /**
31
41
  * Returns current RequestContext (if available).
32
42
  */
package/utils/Utils.js CHANGED
@@ -46,7 +46,8 @@ function compareObjects(a, b) {
46
46
  return false;
47
47
  }
48
48
  if (isRawSql(a) && isRawSql(b)) {
49
- return false;
49
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
50
+ return a.sql === b.sql && compareArrays(a.params, b.params);
50
51
  }
51
52
  if (a.valueOf !== Object.prototype.valueOf && typeof a.valueOf === 'function' && typeof b.valueOf === 'function') {
52
53
  return a.valueOf() === b.valueOf();
@@ -631,6 +632,7 @@ class Utils {
631
632
  || !!process[Symbol.for('ts-node.register.instance')] // check if internal ts-node symbol exists
632
633
  || !!process.env.TS_JEST // check if ts-jest is used (works only with v27.0.4+)
633
634
  || !!process.env.VITEST // check if vitest is used
635
+ || !!process.versions.bun // check if bun is used
634
636
  || process.argv.slice(1).some(arg => arg.includes('ts-node')) // registering ts-node runner
635
637
  || process.execArgv.some(arg => arg === 'ts-node/esm') // check for ts-node/esm module loader
636
638
  || (require.extensions && !!require.extensions['.ts']); // check if the extension is registered