@mikro-orm/core 7.0.2-dev.1 → 7.0.2-dev.11

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.
@@ -54,6 +54,12 @@ export declare class EntitySchema<Entity = any, Base = never, Class extends Enti
54
54
  private internal;
55
55
  private initialized;
56
56
  constructor(meta: EntitySchemaMetadata<Entity, Base, Class>);
57
+ /**
58
+ * Checks if the given value is an EntitySchema instance, using duck-typing
59
+ * as a fallback when `instanceof` fails due to CJS/ESM dual-package hazard
60
+ * (e.g. when using `tsx` or `@swc-node/register` with `"type": "commonjs"` projects).
61
+ */
62
+ static is(item: unknown): item is EntitySchema;
57
63
  static fromMetadata<T = AnyEntity, U = never>(meta: EntityMetadata<T> | DeepPartial<EntityMetadata<T>>): EntitySchema<T, U>;
58
64
  addProperty(name: EntityKey<Entity>, type?: TypeType, options?: PropertyOptions<Entity> | EntityProperty<Entity>): void;
59
65
  addEnum(name: EntityKey<Entity>, type?: TypeType, options?: EnumOptions<Entity>): void;
@@ -27,6 +27,17 @@ export class EntitySchema {
27
27
  EntitySchema.REGISTRY.set(meta.class, this);
28
28
  }
29
29
  }
30
+ /**
31
+ * Checks if the given value is an EntitySchema instance, using duck-typing
32
+ * as a fallback when `instanceof` fails due to CJS/ESM dual-package hazard
33
+ * (e.g. when using `tsx` or `@swc-node/register` with `"type": "commonjs"` projects).
34
+ */
35
+ static is(item) {
36
+ if (item instanceof EntitySchema) {
37
+ return true;
38
+ }
39
+ return item != null && typeof item === 'object' && item.constructor?.name === 'EntitySchema' && 'meta' in item;
40
+ }
30
41
  static fromMetadata(meta) {
31
42
  const schema = new EntitySchema({ ...meta, internal: true });
32
43
  schema.internal = true;
@@ -230,7 +241,7 @@ export class EntitySchema {
230
241
  isPartOfTPTHierarchy() {
231
242
  let parent = this._meta.extends;
232
243
  while (parent) {
233
- const parentSchema = parent instanceof EntitySchema ? parent : EntitySchema.REGISTRY.get(parent);
244
+ const parentSchema = EntitySchema.is(parent) ? parent : EntitySchema.REGISTRY.get(parent);
234
245
  if (!parentSchema) {
235
246
  break;
236
247
  }
@@ -310,7 +321,7 @@ export class EntitySchema {
310
321
  .sort()
311
322
  .join(' | ')
312
323
  : Utils.className(tmp);
313
- const target = tmp instanceof EntitySchema ? tmp.meta.class : tmp;
324
+ const target = EntitySchema.is(tmp) ? tmp.meta.class : tmp;
314
325
  return { type, target };
315
326
  }
316
327
  }
@@ -228,7 +228,7 @@ export class MetadataDiscovery {
228
228
  }
229
229
  tryDiscoverTargets(targets) {
230
230
  for (const target of targets) {
231
- const schema = target instanceof EntitySchema ? target : undefined;
231
+ const schema = EntitySchema.is(target) ? target : undefined;
232
232
  const isDiscoverable = typeof target === 'function' || schema;
233
233
  if (isDiscoverable && target.name) {
234
234
  // Get the actual class for EntitySchema, or use target directly for classes
@@ -254,7 +254,7 @@ export class MetadataDiscovery {
254
254
  // discover parents (base entities) automatically
255
255
  for (const meta of this.#metadata) {
256
256
  let parent = meta.extends;
257
- if (parent instanceof EntitySchema && !this.#metadata.has(parent.init().meta.class)) {
257
+ if (EntitySchema.is(parent) && !this.#metadata.has(parent.init().meta.class)) {
258
258
  this.discoverReferences([parent], false);
259
259
  }
260
260
  if (typeof parent === 'function' && parent.name && !this.#metadata.has(parent)) {
@@ -293,21 +293,23 @@ export class MetadataDiscovery {
293
293
  if (EntitySchema.REGISTRY.has(entity)) {
294
294
  entity = EntitySchema.REGISTRY.get(entity);
295
295
  }
296
- if (entity instanceof EntitySchema) {
296
+ if (EntitySchema.is(entity)) {
297
297
  const meta = Utils.copy(entity.meta, false);
298
298
  return EntitySchema.fromMetadata(meta);
299
299
  }
300
- const path = entity[MetadataStorage.PATH_SYMBOL];
300
+ // After the EntitySchema check, entity must be an EntityClass
301
+ const cls = entity;
302
+ const path = cls[MetadataStorage.PATH_SYMBOL];
301
303
  if (path) {
302
- const meta = Utils.copy(MetadataStorage.getMetadata(entity.name, path), false);
304
+ const meta = Utils.copy(MetadataStorage.getMetadata(cls.name, path), false);
303
305
  meta.path = path;
304
- this.#metadata.set(entity, meta);
306
+ this.#metadata.set(cls, meta);
305
307
  }
306
- const exists = this.#metadata.has(entity);
307
- const meta = this.#metadata.get(entity, true);
308
+ const exists = this.#metadata.has(cls);
309
+ const meta = this.#metadata.get(cls, true);
308
310
  meta.abstract ??= !(exists && meta.name);
309
311
  const schema = EntitySchema.fromMetadata(meta);
310
- schema.setClass(entity);
312
+ schema.setClass(cls);
311
313
  return schema;
312
314
  }
313
315
  getRootEntity(meta) {
@@ -1435,7 +1437,7 @@ export class MetadataDiscovery {
1435
1437
  }
1436
1438
  return metadata.find(m => {
1437
1439
  const ext = meta.extends;
1438
- if (ext instanceof EntitySchema) {
1440
+ if (EntitySchema.is(ext)) {
1439
1441
  return m.class === ext.meta.class || m.className === ext.meta.className;
1440
1442
  }
1441
1443
  return m.class === ext || m.className === Utils.className(ext);
@@ -1610,8 +1612,9 @@ export class MetadataDiscovery {
1610
1612
  !prop.customType) {
1611
1613
  // if the type is an ORM defined mapped type without `ensureComparable: true`,
1612
1614
  // we use just the type name, to have more performant hydration code
1615
+ const brand = Type.getOrmType(prop.type);
1613
1616
  const type = Utils.keys(t).find(type => {
1614
- return !Type.getType(t[type]).ensureComparable(meta, prop) && prop.type === t[type];
1617
+ return (!Type.getType(t[type]).ensureComparable(meta, prop) && (prop.type === t[type] || brand === type));
1615
1618
  });
1616
1619
  if (type) {
1617
1620
  prop.type = type === 'datetime' ? 'Date' : type;
@@ -19,7 +19,7 @@ export class MetadataProvider {
19
19
  .sort()
20
20
  .join(' | ')
21
21
  : Utils.className(tmp);
22
- prop.target = tmp instanceof EntitySchema ? tmp.meta.class : tmp;
22
+ prop.target = EntitySchema.is(tmp) ? tmp.meta.class : tmp;
23
23
  }
24
24
  else if (!prop.type && !((prop.enum || prop.array) && (prop.items?.length ?? 0) > 0)) {
25
25
  throw new Error(`Please provide either 'type' or 'entity' attribute in ${meta.className}.${prop.name}.`);
@@ -65,7 +65,7 @@ export class MetadataStorage {
65
65
  if (meta) {
66
66
  return meta;
67
67
  }
68
- if (entityName instanceof EntitySchema) {
68
+ if (EntitySchema.is(entityName)) {
69
69
  return this.#metadataMap.get(entityName.meta.class) ?? entityName.meta;
70
70
  }
71
71
  return this.#classNameMap[Utils.className(entityName)];
@@ -9,7 +9,7 @@ async function getEntityClassOrSchema(filepath, allTargets, baseDir) {
9
9
  const targets = Object.values(exports);
10
10
  // ignore class implementations that are linked from an EntitySchema
11
11
  for (const item of targets) {
12
- if (item instanceof EntitySchema) {
12
+ if (EntitySchema.is(item)) {
13
13
  for (const item2 of targets) {
14
14
  if (item.meta.class === item2) {
15
15
  targets.splice(targets.indexOf(item2), 1);
@@ -18,7 +18,7 @@ async function getEntityClassOrSchema(filepath, allTargets, baseDir) {
18
18
  }
19
19
  }
20
20
  for (const item of targets) {
21
- const validTarget = item instanceof EntitySchema || (item instanceof Function && MetadataStorage.isKnownEntity(item.name));
21
+ const validTarget = EntitySchema.is(item) || (item instanceof Function && MetadataStorage.isKnownEntity(item.name));
22
22
  if (validTarget && !allTargets.has(item)) {
23
23
  allTargets.set(item, path);
24
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.0.2-dev.1",
3
+ "version": "7.0.2-dev.11",
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
  "keywords": [
6
6
  "data-mapper",
package/types/Type.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import type { Platform } from '../platforms/Platform.js';
2
2
  import type { Constructor, EntityMetadata, EntityProperty } from '../typings.js';
3
+ /** @internal */
4
+ export declare const ORM_TYPE: unique symbol;
3
5
  export interface TransformContext {
4
6
  fromQuery?: boolean;
5
7
  force?: boolean;
@@ -78,4 +80,10 @@ export declare abstract class Type<JSType = string, DBType = JSType> {
78
80
  * Checks whether the argument is instance of `Type`.
79
81
  */
80
82
  static isMappedType(data: any): data is Type<any>;
83
+ /**
84
+ * @internal
85
+ * Returns the built-in type registry key if the given constructor is a branded ORM type
86
+ * (not a user subclass). Uses `Symbol.for()` so it works across CJS/ESM module graphs.
87
+ */
88
+ static getOrmType(cls: object): string | undefined;
81
89
  }
package/types/Type.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { inspect } from '../logging/inspect.js';
2
+ /** @internal */
3
+ export const ORM_TYPE = Symbol.for('@mikro-orm/type');
2
4
  export class Type {
3
5
  static types = new Map();
4
6
  platform;
@@ -64,6 +66,14 @@ export class Type {
64
66
  static isMappedType(data) {
65
67
  return !!data?.__mappedType;
66
68
  }
69
+ /**
70
+ * @internal
71
+ * Returns the built-in type registry key if the given constructor is a branded ORM type
72
+ * (not a user subclass). Uses `Symbol.for()` so it works across CJS/ESM module graphs.
73
+ */
74
+ static getOrmType(cls) {
75
+ return Object.hasOwn(cls, ORM_TYPE) ? cls[ORM_TYPE] : undefined;
76
+ }
67
77
  /** @ignore */
68
78
  [Symbol.for('nodejs.util.inspect.custom')](depth = 2) {
69
79
  const object = { ...this };
package/types/index.js CHANGED
@@ -19,7 +19,7 @@ import { StringType } from './StringType.js';
19
19
  import { TextType } from './TextType.js';
20
20
  import { TimeType } from './TimeType.js';
21
21
  import { TinyIntType } from './TinyIntType.js';
22
- import { Type } from './Type.js';
22
+ import { ORM_TYPE, Type } from './Type.js';
23
23
  import { Uint8ArrayType } from './Uint8ArrayType.js';
24
24
  import { UnknownType } from './UnknownType.js';
25
25
  import { UuidType } from './UuidType.js';
@@ -51,3 +51,13 @@ export const types = {
51
51
  unknown: UnknownType,
52
52
  };
53
53
  export const t = types;
54
+ /**
55
+ * Brand each built-in type constructor with its registry key via a cross-module symbol.
56
+ * Symbol.for() returns the same symbol across CJS/ESM module graphs, so this survives
57
+ * the dual-package hazard (e.g. when using tsx or @swc-node/register with "type": "commonjs").
58
+ * Using Object.defineProperty ensures the brand is an own (non-inherited) property,
59
+ * so subclasses (e.g. MyJsonType extends JsonType) won't be detected as built-in types.
60
+ */
61
+ for (const [key, type] of Object.entries(types)) {
62
+ Object.defineProperty(type, ORM_TYPE, { value: key, enumerable: false });
63
+ }
package/utils/Utils.js CHANGED
@@ -123,7 +123,7 @@ export function parseJsonSafe(value) {
123
123
  }
124
124
  export class Utils {
125
125
  static PK_SEPARATOR = '~~~';
126
- static #ORM_VERSION = '7.0.2-dev.1';
126
+ static #ORM_VERSION = '7.0.2-dev.11';
127
127
  /**
128
128
  * Checks if the argument is instance of `Object`. Returns false for arrays.
129
129
  */