@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 +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/entity-registry.d.ts +32 -0
- package/dist/lib/entity-registry.d.ts.map +1 -0
- package/dist/lib/entity-registry.js +42 -0
- package/dist/lib/entity-registry.js.map +1 -0
- package/dist/lib/entity-utils.d.ts +23 -0
- package/dist/lib/entity-utils.d.ts.map +1 -1
- package/dist/lib/entity-utils.js +76 -4
- package/dist/lib/entity-utils.js.map +1 -1
- package/dist/lib/entity.d.ts +13 -2
- package/dist/lib/entity.d.ts.map +1 -1
- package/dist/lib/entity.js +22 -7
- package/dist/lib/entity.js.map +1 -1
- package/dist/lib/property.d.ts +48 -0
- package/dist/lib/property.d.ts.map +1 -1
- package/dist/lib/property.js +52 -2
- package/dist/lib/property.js.map +1 -1
- package/dist/lib/test-entities.d.ts +474 -0
- package/dist/lib/test-entities.d.ts.map +1 -0
- package/dist/lib/test-entities.js +987 -0
- package/dist/lib/test-entities.js.map +1 -0
- package/dist/lib/types.d.ts +21 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/package.json +1 -1
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';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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":"AAEA,OAAO,EAIL,YAAY,EAGZ,eAAe,EACf,mBAAmB,EACpB,MAAM,YAAY,CAAC;AASpB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"entity-utils.d.ts","sourceRoot":"","sources":["../../src/lib/entity-utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,YAAY,EAGZ,eAAe,EACf,mBAAmB,EACpB,MAAM,YAAY,CAAC;AASpB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAwBvC,qBAAa,WAAW;IACtB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM;IAmB5C;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAa/B;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,aAAa,CAAC,aAAa,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;IAShE;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,kBAAkB,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO;IAU1D;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,eAAe,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO;IAUvD,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO;IAQhD,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAoChD,MAAM,CAAC,kBAAkB,CACvB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,eAAe,GAAG,SAAS;IA8B9B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO;IA2B9C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,MAAM,EAC1B,SAAS,EAAE,CAAC,EACZ,SAAS,EAAE,CAAC,GACX;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,EAAE;IAoC/D,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAaxE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4DG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO;IA8DnD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAsF7B;;;OAGG;mBACkB,cAAc;IAgHnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;WACU,KAAK,CAAC,CAAC,SAAS,MAAM,EACjC,WAAW,EAAE,KAAK,IAAI,EAAE,GAAG,KAAK,CAAC,EACjC,WAAW,EAAE,OAAO,EACpB,YAAY,GAAE,YAAiB,GAC9B,OAAO,CAAC,CAAC,CAAC;IA4Bb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;WACU,SAAS,CAAC,CAAC,SAAS,MAAM,EACrC,WAAW,EAAE,KAAK,IAAI,EAAE,GAAG,KAAK,CAAC,EACjC,WAAW,EAAE,OAAO,EACpB,YAAY,CAAC,EAAE,YAAY,GAC1B,mBAAmB,CAAC,CAAC,CAAC;IAsBzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;WACU,YAAY,CAAC,CAAC,SAAS,MAAM,EACxC,WAAW,EAAE,KAAK,IAAI,EAAE,GAAG,KAAK,CAAC,EACjC,WAAW,EAAE,OAAO,EACpB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GACjC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IActB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;WACU,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAC5C,WAAW,EAAE,KAAK,IAAI,EAAE,GAAG,KAAK,CAAC,EACjC,WAAW,EAAE,OAAO,EACpB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAC7B,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAwC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;WACU,MAAM,CAAC,CAAC,SAAS,MAAM,EAClC,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAC7B,OAAO,CAAC,CAAC,CAAC;IAuCb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;WACU,UAAU,CAAC,CAAC,SAAS,MAAM,EACtC,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAC7B,mBAAmB,CAAC,CAAC,CAAC;IAsBzB;;;OAGG;mBACkB,gBAAgB;IAqFrC;;;;OAIG;mBACkB,sBAAsB;IAsB3C;;;OAGG;mBACkB,6BAA6B;IA+ClD;;;;OAIG;mBACkB,qBAAqB;IAuC1C;;;OAGG;mBACkB,qBAAqB;IAoD1C;;;OAGG;mBACkB,kBAAkB;mBAyBlB,uBAAuB;IAoB5C;;;;;;;;;;;;;;;;;OAiBG;WACU,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAuBxE;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,EAAE;IAI5D;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI;IAQ5E;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO;IAI1D;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,MAAM,EACjC,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC5C,IAAI;IAQP;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA6BnC"}
|
package/dist/lib/entity-utils.js
CHANGED
|
@@ -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
|
-
|
|
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
|