@rtpaulino/entity 0.22.0 → 0.23.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/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import 'reflect-metadata';
2
2
  export * from './lib/entity.js';
3
3
  export * from './lib/entity-utils.js';
4
4
  export * from './lib/entity-di.js';
5
+ export * from './lib/entity-registry.js';
5
6
  export * from './lib/types.js';
6
7
  export * from './lib/property.js';
7
8
  export * from './lib/validation-error.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import 'reflect-metadata';
2
2
  export * from './lib/entity.js';
3
3
  export * from './lib/entity-utils.js';
4
4
  export * from './lib/entity-di.js';
5
+ export * from './lib/entity-registry.js';
5
6
  export * from './lib/types.js';
6
7
  export * from './lib/property.js';
7
8
  export * from './lib/validation-error.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import 'reflect-metadata';\n\nexport * from './lib/entity.js';\nexport * from './lib/entity-utils.js';\nexport * from './lib/entity-di.js';\nexport * from './lib/types.js';\nexport * from './lib/property.js';\nexport * from './lib/validation-error.js';\nexport * from './lib/problem.js';\nexport * from './lib/validation-utils.js';\nexport * from './lib/primitive-deserializers.js';\nexport * from './lib/validators.js';\nexport * from './lib/zod-property.js';\nexport * from './lib/injected-property.js';\n"],"names":[],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,cAAc,kBAAkB;AAChC,cAAc,wBAAwB;AACtC,cAAc,qBAAqB;AACnC,cAAc,iBAAiB;AAC/B,cAAc,oBAAoB;AAClC,cAAc,4BAA4B;AAC1C,cAAc,mBAAmB;AACjC,cAAc,4BAA4B;AAC1C,cAAc,mCAAmC;AACjD,cAAc,sBAAsB;AACpC,cAAc,wBAAwB;AACtC,cAAc,6BAA6B"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import 'reflect-metadata';\n\nexport * from './lib/entity.js';\nexport * from './lib/entity-utils.js';\nexport * from './lib/entity-di.js';\nexport * from './lib/entity-registry.js';\nexport * from './lib/types.js';\nexport * from './lib/property.js';\nexport * from './lib/validation-error.js';\nexport * from './lib/problem.js';\nexport * from './lib/validation-utils.js';\nexport * from './lib/primitive-deserializers.js';\nexport * from './lib/validators.js';\nexport * from './lib/zod-property.js';\nexport * from './lib/injected-property.js';\n"],"names":[],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,cAAc,kBAAkB;AAChC,cAAc,wBAAwB;AACtC,cAAc,qBAAqB;AACnC,cAAc,2BAA2B;AACzC,cAAc,iBAAiB;AAC/B,cAAc,oBAAoB;AAClC,cAAc,4BAA4B;AAC1C,cAAc,mBAAmB;AACjC,cAAc,4BAA4B;AAC1C,cAAc,mCAAmC;AACjD,cAAc,sBAAsB;AACpC,cAAc,wBAAwB;AACtC,cAAc,6BAA6B"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Registry for entity classes decorated with @Entity()
3
+ * Stores entity constructors by name for discriminated entity deserialization
4
+ */
5
+ export declare class EntityRegistry {
6
+ private static readonly registry;
7
+ /**
8
+ * Registers an entity class with a name
9
+ * @param name - The name to register the entity under
10
+ * @param entityClass - The entity class constructor
11
+ * @throws Error if an entity with this name is already registered
12
+ */
13
+ static register(name: string, entityClass: Function): void;
14
+ /**
15
+ * Gets an entity class by name
16
+ * @param name - The name of the entity to retrieve
17
+ * @returns The entity class constructor, or undefined if not found
18
+ */
19
+ static get(name: string): Function | undefined;
20
+ /**
21
+ * Checks if an entity with the given name is registered
22
+ * @param name - The name to check
23
+ * @returns true if an entity with this name is registered
24
+ */
25
+ static has(name: string): boolean;
26
+ /**
27
+ * Gets all registered entity names
28
+ * @returns Array of all registered entity names
29
+ */
30
+ static getAllNames(): string[];
31
+ }
32
+ //# sourceMappingURL=entity-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-registry.d.ts","sourceRoot":"","sources":["../../src/lib/entity-registry.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IAE/D;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,GAAG,IAAI;IAW1D;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAI9C;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC;;;OAGG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM,EAAE;CAG/B"}
@@ -0,0 +1,42 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unsafe-function-type */ /**
2
+ * Registry for entity classes decorated with @Entity()
3
+ * Stores entity constructors by name for discriminated entity deserialization
4
+ */ export class EntityRegistry {
5
+ static{
6
+ this.registry = new Map();
7
+ }
8
+ /**
9
+ * Registers an entity class with a name
10
+ * @param name - The name to register the entity under
11
+ * @param entityClass - The entity class constructor
12
+ * @throws Error if an entity with this name is already registered
13
+ */ static register(name, entityClass) {
14
+ const existing = this.registry.get(name);
15
+ if (existing && existing !== entityClass) {
16
+ throw new Error(`Entity name conflict: An entity with name '${name}' is already registered. ` + `Existing: ${existing.name}, New: ${entityClass.name}`);
17
+ }
18
+ this.registry.set(name, entityClass);
19
+ }
20
+ /**
21
+ * Gets an entity class by name
22
+ * @param name - The name of the entity to retrieve
23
+ * @returns The entity class constructor, or undefined if not found
24
+ */ static get(name) {
25
+ return this.registry.get(name);
26
+ }
27
+ /**
28
+ * Checks if an entity with the given name is registered
29
+ * @param name - The name to check
30
+ * @returns true if an entity with this name is registered
31
+ */ static has(name) {
32
+ return this.registry.has(name);
33
+ }
34
+ /**
35
+ * Gets all registered entity names
36
+ * @returns Array of all registered entity names
37
+ */ static getAllNames() {
38
+ return Array.from(this.registry.keys());
39
+ }
40
+ }
41
+
42
+ //# sourceMappingURL=entity-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/entity-registry.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n\n/**\n * Registry for entity classes decorated with @Entity()\n * Stores entity constructors by name for discriminated entity deserialization\n */\nexport class EntityRegistry {\n private static readonly registry = new Map<string, Function>();\n\n /**\n * Registers an entity class with a name\n * @param name - The name to register the entity under\n * @param entityClass - The entity class constructor\n * @throws Error if an entity with this name is already registered\n */\n static register(name: string, entityClass: Function): void {\n const existing = this.registry.get(name);\n if (existing && existing !== entityClass) {\n throw new Error(\n `Entity name conflict: An entity with name '${name}' is already registered. ` +\n `Existing: ${existing.name}, New: ${entityClass.name}`,\n );\n }\n this.registry.set(name, entityClass);\n }\n\n /**\n * Gets an entity class by name\n * @param name - The name of the entity to retrieve\n * @returns The entity class constructor, or undefined if not found\n */\n static get(name: string): Function | undefined {\n return this.registry.get(name);\n }\n\n /**\n * Checks if an entity with the given name is registered\n * @param name - The name to check\n * @returns true if an entity with this name is registered\n */\n static has(name: string): boolean {\n return this.registry.has(name);\n }\n\n /**\n * Gets all registered entity names\n * @returns Array of all registered entity names\n */\n static getAllNames(): string[] {\n return Array.from(this.registry.keys());\n }\n}\n"],"names":["EntityRegistry","registry","Map","register","name","entityClass","existing","get","Error","set","has","getAllNames","Array","from","keys"],"mappings":"AAAA,qDAAqD,GACrD,6DAA6D,GAE7D;;;CAGC,GACD,OAAO,MAAMA;;aACaC,WAAW,IAAIC;;IAEvC;;;;;GAKC,GACD,OAAOC,SAASC,IAAY,EAAEC,WAAqB,EAAQ;QACzD,MAAMC,WAAW,IAAI,CAACL,QAAQ,CAACM,GAAG,CAACH;QACnC,IAAIE,YAAYA,aAAaD,aAAa;YACxC,MAAM,IAAIG,MACR,CAAC,2CAA2C,EAAEJ,KAAK,yBAAyB,CAAC,GAC3E,CAAC,UAAU,EAAEE,SAASF,IAAI,CAAC,OAAO,EAAEC,YAAYD,IAAI,EAAE;QAE5D;QACA,IAAI,CAACH,QAAQ,CAACQ,GAAG,CAACL,MAAMC;IAC1B;IAEA;;;;GAIC,GACD,OAAOE,IAAIH,IAAY,EAAwB;QAC7C,OAAO,IAAI,CAACH,QAAQ,CAACM,GAAG,CAACH;IAC3B;IAEA;;;;GAIC,GACD,OAAOM,IAAIN,IAAY,EAAW;QAChC,OAAO,IAAI,CAACH,QAAQ,CAACS,GAAG,CAACN;IAC3B;IAEA;;;GAGC,GACD,OAAOO,cAAwB;QAC7B,OAAOC,MAAMC,IAAI,CAAC,IAAI,CAACZ,QAAQ,CAACa,IAAI;IACtC;AACF"}
@@ -30,6 +30,24 @@ export declare class EntityUtils {
30
30
  * @private
31
31
  */
32
32
  private static getEntityOptions;
33
+ /**
34
+ * Gets the registered name for an entity class or instance
35
+ *
36
+ * @param entityOrClass - The entity class constructor or instance
37
+ * @returns The entity name, or undefined if not found
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * @Entity({ name: 'CustomUser' })
42
+ * class User {
43
+ * name: string;
44
+ * }
45
+ *
46
+ * console.log(EntityUtils.getEntityName(User)); // 'CustomUser'
47
+ * console.log(EntityUtils.getEntityName(new User())); // 'CustomUser'
48
+ * ```
49
+ */
50
+ static getEntityName(entityOrClass: unknown): string | undefined;
33
51
  /**
34
52
  * Checks if a given entity is marked as a collection entity
35
53
  *
@@ -407,6 +425,11 @@ export declare class EntityUtils {
407
425
  * @private
408
426
  */
409
427
  private static deserializeSingleValue;
428
+ /**
429
+ * Deserializes a discriminated entity value by reading the discriminator and looking up the entity class
430
+ * @private
431
+ */
432
+ private static deserializeDiscriminatedValue;
410
433
  /**
411
434
  * Validates a property value by running validators and nested entity validation.
412
435
  * Prepends the property path to all returned problems.
@@ -1 +1 @@
1
- {"version":3,"file":"entity-utils.d.ts","sourceRoot":"","sources":["../../src/lib/entity-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entity-utils.d.ts","sourceRoot":"","sources":["../../src/lib/entity-utils.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ import { Problem } from './problem.js';
7
7
  import { prependPropertyPath, prependArrayIndex, createValidationError, combinePropertyPaths } from './validation-utils.js';
8
8
  import { isPrimitiveConstructor, deserializePrimitive } from './primitive-deserializers.js';
9
9
  import { ok } from 'assert';
10
+ import { EntityRegistry } from './entity-registry.js';
10
11
  /**
11
12
  * WeakMap to store validation problems for entity instances
12
13
  */ const problemsStorage = new WeakMap();
@@ -60,6 +61,29 @@ export class EntityUtils {
60
61
  return options ?? {};
61
62
  }
62
63
  /**
64
+ * Gets the registered name for an entity class or instance
65
+ *
66
+ * @param entityOrClass - The entity class constructor or instance
67
+ * @returns The entity name, or undefined if not found
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * @Entity({ name: 'CustomUser' })
72
+ * class User {
73
+ * name: string;
74
+ * }
75
+ *
76
+ * console.log(EntityUtils.getEntityName(User)); // 'CustomUser'
77
+ * console.log(EntityUtils.getEntityName(new User())); // 'CustomUser'
78
+ * ```
79
+ */ static getEntityName(entityOrClass) {
80
+ if (!this.isEntity(entityOrClass)) {
81
+ return undefined;
82
+ }
83
+ const options = this.getEntityOptions(entityOrClass);
84
+ return options.name;
85
+ }
86
+ /**
63
87
  * Checks if a given entity is marked as a collection entity
64
88
  *
65
89
  * @param entityOrClass - The entity instance or class to check
@@ -334,7 +358,7 @@ export class EntityUtils {
334
358
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
335
359
  return value.map((item)=>options.serialize(item));
336
360
  }
337
- return value.map((item)=>this.serializeValue(item));
361
+ return value.map((item)=>this.serializeValue(item, options));
338
362
  }
339
363
  if (options?.serialize) {
340
364
  return options.serialize(value);
@@ -346,7 +370,25 @@ export class EntityUtils {
346
370
  return value.toString();
347
371
  }
348
372
  if (this.isEntity(value)) {
349
- return this.toJSON(value);
373
+ const serialized = this.toJSON(value);
374
+ // If this is a discriminated entity property, add the discriminator inline
375
+ if (options?.discriminated === true) {
376
+ const discriminatorProperty = options.discriminatorProperty;
377
+ ok(discriminatorProperty, 'Discriminator property must be defined');
378
+ const entityClass = Object.getPrototypeOf(value).constructor;
379
+ const entityName = this.getEntityName(entityClass);
380
+ if (!entityName) {
381
+ throw new Error(`Cannot serialize discriminated entity: Entity class '${entityClass.name}' is not registered. Ensure it's decorated with @Entity().`);
382
+ }
383
+ if (typeof serialized !== 'object' || Array.isArray(serialized) || serialized === null) {
384
+ throw new Error(`Cannot serialize discriminated entity: Expected serialized value to be an object.`);
385
+ }
386
+ return {
387
+ ...serialized,
388
+ [discriminatorProperty]: entityName
389
+ };
390
+ }
391
+ return serialized;
350
392
  }
351
393
  if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
352
394
  return value;
@@ -792,10 +834,9 @@ export class EntityUtils {
792
834
  * Deserializes a single value according to the type metadata
793
835
  * @private
794
836
  */ static async deserializeValue(value, options, parseOptions) {
795
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
796
- const typeConstructor = options.type();
797
837
  const isArray = options.array === true;
798
838
  const isSparse = options.sparse === true;
839
+ const isDiscriminated = options.discriminated === true;
799
840
  if (isArray) {
800
841
  if (!Array.isArray(value)) {
801
842
  throw createValidationError(`Expects an array but received ${typeof value}`);
@@ -816,7 +857,11 @@ export class EntityUtils {
816
857
  try {
817
858
  if (options.deserialize) {
818
859
  result.push(options.deserialize(item));
860
+ } else if (isDiscriminated) {
861
+ result.push(await this.deserializeDiscriminatedValue(item, options));
819
862
  } else {
863
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
864
+ const typeConstructor = options.type();
820
865
  result.push(await this.deserializeSingleValue(item, typeConstructor, parseOptions));
821
866
  }
822
867
  } catch (error) {
@@ -837,6 +882,11 @@ export class EntityUtils {
837
882
  if (options.deserialize) {
838
883
  return options.deserialize(value);
839
884
  }
885
+ if (isDiscriminated) {
886
+ return await this.deserializeDiscriminatedValue(value, options);
887
+ }
888
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
889
+ const typeConstructor = options.type();
840
890
  return await this.deserializeSingleValue(value, typeConstructor, parseOptions);
841
891
  }
842
892
  /**
@@ -853,6 +903,28 @@ export class EntityUtils {
853
903
  throw createValidationError(`Has unknown type constructor. Supported types are: String, Number, Boolean, Date, BigInt, and @Entity() classes. Use passthrough: true to explicitly allow unknown types.`);
854
904
  }
855
905
  /**
906
+ * Deserializes a discriminated entity value by reading the discriminator and looking up the entity class
907
+ * @private
908
+ */ static async deserializeDiscriminatedValue(value, options) {
909
+ if (value == null) {
910
+ throw createValidationError(`Cannot deserialize discriminated entity from null or undefined`);
911
+ }
912
+ if (typeof value !== 'object' || Array.isArray(value)) {
913
+ throw createValidationError(`Discriminated entity must be an object, received ${typeof value}`);
914
+ }
915
+ const discriminatorProperty = options.discriminatorProperty;
916
+ ok(discriminatorProperty, 'Discriminator property must be defined');
917
+ const discriminatorValue = value[discriminatorProperty];
918
+ if (typeof discriminatorValue !== 'string' || discriminatorValue.trim() === '') {
919
+ throw createValidationError(`Missing or invalid discriminator property '${discriminatorProperty}'. Expected a non-empty string.`);
920
+ }
921
+ const entityClass = EntityRegistry.get(discriminatorValue);
922
+ if (!entityClass) {
923
+ throw createValidationError(`Unknown entity type '${discriminatorValue}'. No entity registered with this name.`);
924
+ }
925
+ return await this.parse(entityClass, value, {});
926
+ }
927
+ /**
856
928
  * Validates a property value by running validators and nested entity validation.
857
929
  * Prepends the property path to all returned problems.
858
930
  * @private