@rtpaulino/entity 0.26.1 → 0.28.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.
@@ -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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"}
@@ -349,14 +349,18 @@ export class EntityUtils {
349
349
  continue;
350
350
  }
351
351
  const options = this.getPropertyOptions(entity, key);
352
- result[key] = this.serializeValue(value, options);
352
+ const serializeContext = {
353
+ propertyName: key,
354
+ entity: entity
355
+ };
356
+ result[key] = this.serializeValue(value, options, serializeContext);
353
357
  }
354
358
  return result;
355
359
  }
356
360
  /**
357
361
  * Serializes a single value according to the toJSON rules
358
362
  * @private
359
- */ static serializeValue(value, options) {
363
+ */ static serializeValue(value, options, context) {
360
364
  if (value === null) {
361
365
  return null;
362
366
  }
@@ -370,12 +374,12 @@ export class EntityUtils {
370
374
  if (Array.isArray(value)) {
371
375
  if (options?.serialize) {
372
376
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
373
- return value.map((item)=>options.serialize(item));
377
+ return value.map((item)=>options.serialize(item, context));
374
378
  }
375
- return value.map((item)=>this.serializeValue(item, options));
379
+ return value.map((item)=>this.serializeValue(item, options, context));
376
380
  }
377
381
  if (options?.serialize) {
378
- return options.serialize(value);
382
+ return options.serialize(value, context);
379
383
  }
380
384
  if (value instanceof Date) {
381
385
  return value.toISOString();
@@ -481,10 +485,14 @@ export class EntityUtils {
481
485
  continue;
482
486
  }
483
487
  try {
488
+ const deserializeContext = {
489
+ propertyName: key,
490
+ rawObject: plainObject
491
+ };
484
492
  // Only pass strict to nested deserialization, not skipDefaults/skipMissing
485
493
  data[key] = await this.deserializeValue(value, propertyOptions, {
486
494
  strict
487
- });
495
+ }, deserializeContext);
488
496
  } catch (error) {
489
497
  if (error instanceof ValidationError) {
490
498
  const isWrapperProperty = wrapperPropertyName === key;
@@ -788,13 +796,19 @@ export class EntityUtils {
788
796
  data[key] = value;
789
797
  }
790
798
  // Apply updates, respecting preventUpdates flag
799
+ // Properties with an `undefined` value in the updates object are ignored;
800
+ // use `null` to explicitly clear a property.
791
801
  for (const key of keys){
792
802
  if (key in updates) {
803
+ const updateValue = updates[key];
804
+ if (updateValue === undefined) {
805
+ continue;
806
+ }
793
807
  const propertyOptions = this.getPropertyOptions(instance, key);
794
808
  if (propertyOptions && propertyOptions.preventUpdates === true) {
795
809
  continue;
796
810
  }
797
- data[key] = updates[key];
811
+ data[key] = updateValue;
798
812
  }
799
813
  }
800
814
  const newInstance = new Constructor(data);
@@ -864,7 +878,7 @@ export class EntityUtils {
864
878
  /**
865
879
  * Deserializes a single value according to the type metadata
866
880
  * @private
867
- */ static async deserializeValue(value, options, parseOptions) {
881
+ */ static async deserializeValue(value, options, parseOptions, context) {
868
882
  const isArray = options.array === true;
869
883
  const isSparse = options.sparse === true;
870
884
  const isDiscriminated = options.discriminated === true;
@@ -887,7 +901,7 @@ export class EntityUtils {
887
901
  } else {
888
902
  try {
889
903
  if (options.deserialize) {
890
- result.push(options.deserialize(item));
904
+ result.push(options.deserialize(item, context));
891
905
  } else if (isDiscriminated) {
892
906
  result.push(await this.deserializeDiscriminatedValue(item, options));
893
907
  } else {
@@ -911,7 +925,7 @@ export class EntityUtils {
911
925
  return result;
912
926
  }
913
927
  if (options.deserialize) {
914
- return options.deserialize(value);
928
+ return options.deserialize(value, context);
915
929
  }
916
930
  if (isDiscriminated) {
917
931
  return await this.deserializeDiscriminatedValue(value, options);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/entity-utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n ENTITY_METADATA_KEY,\n ENTITY_OPTIONS_METADATA_KEY,\n ENTITY_VALIDATOR_METADATA_KEY,\n ParseOptions,\n PROPERTY_METADATA_KEY,\n PROPERTY_OPTIONS_METADATA_KEY,\n PropertyOptions,\n SafeOperationResult,\n} from './types.js';\nimport type { EntityOptions } from './entity.js';\nimport {\n getInjectedPropertyNames,\n getInjectedPropertyOptions,\n} from './injected-property.js';\nimport { EntityDI } from './entity-di.js';\nimport { isEqualWith } from 'lodash-es';\nimport { ValidationError } from './validation-error.js';\nimport { Problem } from './problem.js';\nimport {\n prependArrayIndex,\n prependPropertyPath,\n createValidationError,\n} from './validation-utils.js';\nimport {\n isPrimitiveConstructor,\n deserializePrimitive,\n} from './primitive-deserializers.js';\nimport { ok } from 'assert';\nimport { EntityRegistry } from './entity-registry.js';\nimport { PolymorphicRegistry } from './polymorphic-registry.js';\n\n/**\n * WeakMap to store validation problems for entity instances\n */\nconst problemsStorage = new WeakMap<object, Problem[]>();\n\n/**\n * WeakMap to store raw input data for entity instances\n */\nconst rawInputStorage = new WeakMap<object, unknown>();\n\nexport class EntityUtils {\n /**\n * Checks if a given object is an instance of a class decorated with @Entity()\n * or if the provided value is an entity class itself\n *\n * @param obj - The object or class to check\n * @returns true if the object is an entity instance or entity class, false otherwise\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * name: string;\n * }\n *\n * const user = new User();\n * console.log(EntityUtils.isEntity(user)); // true\n * console.log(EntityUtils.isEntity(User)); // true\n * console.log(EntityUtils.isEntity({})); // false\n * ```\n */\n static isEntity(obj: unknown): obj is object {\n if (obj == null) {\n return false;\n }\n\n // Check if obj is a constructor function (class)\n if (typeof obj === 'function') {\n return Reflect.hasMetadata(ENTITY_METADATA_KEY, obj);\n }\n\n // Check if obj is an object instance\n if (typeof obj !== 'object' || Array.isArray(obj)) {\n return false;\n }\n\n const constructor = Object.getPrototypeOf(obj).constructor;\n return Reflect.hasMetadata(ENTITY_METADATA_KEY, constructor);\n }\n\n /**\n * Gets the entity options for a given constructor\n *\n * @param entityOrClass - The entity class constructor or instance\n * @returns EntityOptions object (empty object if no options are defined)\n * @private\n */\n private static getEntityOptions(entityOrClass: unknown): EntityOptions {\n const constructor =\n typeof entityOrClass === 'function'\n ? entityOrClass\n : Object.getPrototypeOf(entityOrClass).constructor;\n\n const options: EntityOptions | undefined = Reflect.getMetadata(\n ENTITY_OPTIONS_METADATA_KEY,\n constructor,\n );\n return options ?? {};\n }\n\n /**\n * Gets the registered name for an entity class or instance\n *\n * @param entityOrClass - The entity class constructor or instance\n * @returns The entity name, or undefined if not found\n *\n * @example\n * ```typescript\n * @Entity({ name: 'CustomUser' })\n * class User {\n * name: string;\n * }\n *\n * console.log(EntityUtils.getEntityName(User)); // 'CustomUser'\n * console.log(EntityUtils.getEntityName(new User())); // 'CustomUser'\n * ```\n */\n static getEntityName(entityOrClass: unknown): string | undefined {\n if (!this.isEntity(entityOrClass)) {\n return undefined;\n }\n\n const options = this.getEntityOptions(entityOrClass);\n return options.name;\n }\n\n /**\n * Checks if a given entity is marked as a collection entity\n *\n * @param entityOrClass - The entity instance or class to check\n * @returns true if the entity is a collection entity, false otherwise\n *\n * @example\n * ```typescript\n * @CollectionEntity()\n * class Tags {\n * @ArrayProperty(() => String)\n * collection: string[];\n * }\n *\n * const tags = new Tags({ collection: ['a', 'b'] });\n * console.log(EntityUtils.isCollectionEntity(tags)); // true\n * console.log(EntityUtils.isCollectionEntity(Tags)); // true\n * ```\n */\n static isCollectionEntity(entityOrClass: unknown): boolean {\n if (!this.isEntity(entityOrClass)) {\n return false;\n }\n\n const options = this.getEntityOptions(entityOrClass);\n\n return options.collection === true;\n }\n\n /**\n * Checks if a given entity is marked as a stringifiable entity\n *\n * @param entityOrClass - The entity instance or class to check\n * @returns true if the entity is a stringifiable entity, false otherwise\n *\n * @example\n * ```typescript\n * @Stringifiable()\n * class UserId {\n * @StringProperty()\n * value: string;\n * }\n *\n * const userId = new UserId({ value: 'user-123' });\n * console.log(EntityUtils.isStringifiable(userId)); // true\n * console.log(EntityUtils.isStringifiable(UserId)); // true\n * ```\n */\n static isStringifiable(entityOrClass: unknown): boolean {\n if (!this.isEntity(entityOrClass)) {\n return false;\n }\n\n const options = this.getEntityOptions(entityOrClass);\n\n return options.stringifiable === true;\n }\n\n /**\n * Gets the \"wrapper\" property name for entities that act as transparent wrappers.\n * When set, this property name is excluded from error paths during validation.\n *\n * @param entityOrClass - The entity instance or class to check\n * @returns The wrapper property name, or undefined if not a wrapper entity\n * @private\n */\n private static getWrapperPropertyName(\n entityOrClass: unknown,\n ): string | undefined {\n if (!this.isEntity(entityOrClass)) {\n return undefined;\n }\n return this.getEntityOptions(entityOrClass).wrapperProperty;\n }\n\n static sameEntity(a: object, b: object): boolean {\n if (!this.isEntity(a) || !this.isEntity(b)) {\n return false;\n }\n\n return Object.getPrototypeOf(a) === Object.getPrototypeOf(b);\n }\n\n static getPropertyKeys(target: object): string[] {\n // Determine if we're dealing with a prototype or an instance\n let currentProto: any;\n\n // Check if target is a prototype by checking if it has a constructor property\n // and if target === target.constructor.prototype\n if (target.constructor && target === target.constructor.prototype) {\n // target is already a prototype\n currentProto = target;\n } else {\n // target is an instance, get its prototype\n currentProto = Object.getPrototypeOf(target);\n }\n\n const keys: string[] = [];\n const seen = new Set<string>();\n\n // Walk the prototype chain to collect all inherited properties\n while (currentProto && currentProto !== Object.prototype) {\n // Use getOwnMetadata to only get metadata directly on this prototype\n const protoKeys: string[] =\n Reflect.getOwnMetadata(PROPERTY_METADATA_KEY, currentProto) || [];\n\n for (const key of protoKeys) {\n if (!seen.has(key)) {\n seen.add(key);\n keys.push(key);\n }\n }\n\n currentProto = Object.getPrototypeOf(currentProto);\n }\n\n return keys;\n }\n\n static getPropertyOptions(\n target: object,\n propertyKey: string,\n ): PropertyOptions | undefined {\n // Determine if we're dealing with a prototype or an instance\n let currentProto: any;\n\n // Check if target is a prototype by checking if it has a constructor property\n // and if target === target.constructor.prototype\n if (target.constructor && target === target.constructor.prototype) {\n // target is already a prototype\n currentProto = target;\n } else {\n // target is an instance, get its prototype\n currentProto = Object.getPrototypeOf(target);\n }\n\n // Walk the prototype chain to find the property options\n while (currentProto && currentProto !== Object.prototype) {\n const protoOptions: Record<string, PropertyOptions> =\n Reflect.getOwnMetadata(PROPERTY_OPTIONS_METADATA_KEY, currentProto) ||\n {};\n\n if (protoOptions[propertyKey]) {\n return protoOptions[propertyKey];\n }\n\n currentProto = Object.getPrototypeOf(currentProto);\n }\n\n return undefined;\n }\n\n static equals(a: unknown, b: unknown): boolean {\n return isEqualWith(a, b, (val1, val2) => {\n if (this.isEntity(val1)) {\n if (!this.sameEntity(val1, val2)) {\n return false;\n }\n\n const diff = this.diff(val1, val2);\n\n return diff.length === 0;\n } else if (\n val1 != null &&\n val2 != null &&\n typeof val1 === 'object' &&\n !Array.isArray(val1) &&\n typeof val2 === 'object' &&\n !Array.isArray(val2) &&\n 'equals' in val1 &&\n typeof val1.equals === 'function'\n ) {\n return val1.equals(val2);\n }\n\n return undefined;\n });\n }\n\n static diff<T extends object>(\n oldEntity: T,\n newEntity: T,\n ): { property: string; oldValue: unknown; newValue: unknown }[] {\n if (!this.sameEntity(oldEntity, newEntity)) {\n throw new Error('Entities must be of the same type to compute diff');\n }\n\n const diffs: { property: string; oldValue: unknown; newValue: unknown }[] =\n [];\n\n const keys = this.getPropertyKeys(oldEntity);\n\n for (const key of keys) {\n const oldValue = (oldEntity as any)[key];\n const newValue = (newEntity as any)[key];\n\n // Check if there's a custom equals function for this property\n const propertyOptions = this.getPropertyOptions(oldEntity, key);\n\n let areEqual: boolean;\n if (oldValue == null && newValue == null) {\n areEqual = oldValue === newValue;\n } else if (oldValue == null || newValue == null) {\n areEqual = false;\n } else {\n areEqual = propertyOptions?.equals\n ? propertyOptions.equals(oldValue, newValue)\n : this.equals(oldValue, newValue);\n }\n\n if (!areEqual) {\n diffs.push({ property: key, oldValue, newValue });\n }\n }\n\n return diffs;\n }\n\n static changes<T extends object>(oldEntity: T, newEntity: T): Partial<T> {\n if (!this.sameEntity(oldEntity, newEntity)) {\n throw new Error('Entities must be of the same type to compute changes');\n }\n\n const diff = this.diff(oldEntity, newEntity);\n\n return diff.reduce((acc, { property, newValue }) => {\n (acc as any)[property] = newValue;\n return acc;\n }, {} as Partial<T>);\n }\n\n /**\n * Serializes an entity to a plain object, converting only properties decorated with @Property()\n *\n * @param entity - The entity instance to serialize\n * @returns A plain object containing only the serialized decorated properties, or an array for collection entities\n *\n * @remarks\n * Serialization rules:\n * - Only properties decorated with @Property() are included\n * - If a property has a custom toJSON() method, it will be used\n * - Nested entities are recursively serialized using EntityUtils.toJSON()\n * - Arrays are mapped with toJSON() applied to each element\n * - Date objects are serialized to ISO strings\n * - bigint values are serialized to strings\n * - undefined values are excluded from the output\n * - null values are included in the output\n * - Circular references are not supported (will cause stack overflow)\n * - Collection entities (@CollectionEntity) are unwrapped to just their array\n *\n * @example\n * ```typescript\n * @Entity()\n * class Address {\n * @Property() street: string;\n * @Property() city: string;\n * }\n *\n * @Entity()\n * class User {\n * @Property() name: string;\n * @Property() address: Address;\n * @Property() createdAt: Date;\n * undecorated: string; // Will not be serialized\n * }\n *\n * const user = new User();\n * user.name = 'John';\n * user.address = new Address();\n * user.address.street = '123 Main St';\n * user.address.city = 'Boston';\n * user.createdAt = new Date('2024-01-01');\n * user.undecorated = 'ignored';\n *\n * const json = EntityUtils.toJSON(user);\n * // {\n * // name: 'John',\n * // address: { street: '123 Main St', city: 'Boston' },\n * // createdAt: '2024-01-01T00:00:00.000Z'\n * // }\n *\n * @CollectionEntity()\n * class Tags {\n * @ArrayProperty(() => String)\n * collection: string[];\n * }\n *\n * const tags = new Tags({ collection: ['a', 'b'] });\n * const json = EntityUtils.toJSON(tags);\n * // ['a', 'b'] - unwrapped to array\n * ```\n */\n static toJSON<T extends object>(entity: T): unknown {\n if (this.isStringifiable(entity)) {\n const valuePropertyOptions = this.getPropertyOptions(entity, 'value');\n if (!valuePropertyOptions) {\n throw new Error(\n `Stringifiable entity 'value' property is missing metadata`,\n );\n }\n if (valuePropertyOptions.array) {\n throw new Error(\n `Stringifiable entity 'value' property must not be an array`,\n );\n }\n if (valuePropertyOptions.type?.() !== String) {\n throw new Error(\n `Stringifiable entity 'value' property must be of type String`,\n );\n }\n\n return this.serializeValue((entity as any).value, valuePropertyOptions);\n }\n\n if (this.isCollectionEntity(entity)) {\n const collectionPropertyOptions = this.getPropertyOptions(\n entity,\n 'collection',\n );\n if (!collectionPropertyOptions) {\n throw new Error(\n `Collection entity 'collection' property is missing metadata`,\n );\n }\n if (!collectionPropertyOptions.array) {\n throw new Error(\n `Collection entity 'collection' property must be an array`,\n );\n }\n\n return this.serializeValue(\n (entity as any).collection,\n collectionPropertyOptions,\n );\n }\n\n const result: Record<string, unknown> = {};\n const keys = this.getPropertyKeys(entity);\n\n for (const key of keys) {\n const value = (entity as any)[key];\n\n // Skip undefined values\n if (value === undefined) {\n continue;\n }\n\n const options = this.getPropertyOptions(entity, key);\n result[key] = this.serializeValue(value, options);\n }\n\n return result;\n }\n\n /**\n * Serializes a single value according to the toJSON rules\n * @private\n */\n private static serializeValue(\n value: unknown,\n options?: PropertyOptions,\n ): unknown {\n if (value === null) {\n return null;\n }\n\n if (value === undefined) {\n return undefined;\n }\n\n const passthrough = options?.passthrough === true;\n if (passthrough) {\n return value;\n }\n\n if (Array.isArray(value)) {\n if (options?.serialize) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return value.map((item) => options.serialize!(item as any));\n }\n return value.map((item) => this.serializeValue(item, options));\n }\n\n if (options?.serialize) {\n return options.serialize(value as any);\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (typeof value === 'bigint') {\n return value.toString();\n }\n\n if (this.isEntity(value)) {\n const serialized = this.toJSON(value);\n\n // If this is a discriminated entity property, add the discriminator inline\n if (options?.discriminated === true) {\n const discriminatorProperty = options.discriminatorProperty;\n ok(discriminatorProperty, 'Discriminator property must be defined');\n\n const entityClass = Object.getPrototypeOf(value).constructor;\n const entityName = this.getEntityName(entityClass);\n\n if (!entityName) {\n throw new Error(\n `Cannot serialize discriminated entity: Entity class '${entityClass.name}' is not registered. Ensure it's decorated with @Entity().`,\n );\n }\n\n if (\n typeof serialized !== 'object' ||\n Array.isArray(serialized) ||\n serialized === null\n ) {\n throw new Error(\n `Cannot serialize discriminated entity: Expected serialized value to be an object.`,\n );\n }\n\n return {\n ...serialized,\n [discriminatorProperty]: entityName,\n } as Record<string, unknown>;\n }\n\n return serialized;\n }\n\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return value;\n }\n\n throw new Error(\n `Cannot serialize value of type '${typeof value}'. Use passthrough: true in @Property() to explicitly allow serialization of unknown types.`,\n );\n }\n\n /**\n * Internal parse implementation with extended options\n * @private\n */\n private static async _parseInternal<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n options: {\n strict?: boolean;\n skipDefaults?: boolean;\n skipMissing?: boolean;\n } = {},\n ): Promise<{\n data: Record<string, unknown>;\n hardProblems: Problem[];\n entityClass: new (data: any) => T;\n }> {\n const wrapperPropertyName = this.getWrapperPropertyName(entityClass);\n\n if (wrapperPropertyName) {\n plainObject = { [wrapperPropertyName]: plainObject };\n }\n if (plainObject == null) {\n throw createValidationError(\n `Expects an object but received ${typeof plainObject}`,\n );\n }\n if (Array.isArray(plainObject)) {\n throw createValidationError(`Expects an object but received array`);\n }\n if (typeof plainObject !== 'object') {\n throw createValidationError(\n `Expects an object but received ${typeof plainObject}`,\n );\n }\n\n // Check for polymorphic base class - resolve to concrete variant if found\n const discriminatorProperty =\n PolymorphicRegistry.getDiscriminatorProperty(entityClass);\n\n if (discriminatorProperty) {\n const discriminatorValue = (plainObject as Record<string, unknown>)[\n discriminatorProperty\n ];\n\n if (discriminatorValue === undefined) {\n throw createValidationError(\n `Missing polymorphic discriminator property '${discriminatorProperty}' ` +\n `for base class '${entityClass.name}'. ` +\n `The discriminator property is required to determine the correct variant class.`,\n );\n }\n\n const variantClass = PolymorphicRegistry.getVariant(\n entityClass,\n discriminatorValue,\n );\n\n if (!variantClass) {\n throw createValidationError(\n `Unknown polymorphic variant '${String(discriminatorValue)}' ` +\n `for base class '${entityClass.name}'. ` +\n `Discriminator property: '${discriminatorProperty}'. ` +\n `Ensure the variant class is decorated with @PolymorphicVariant.`,\n );\n }\n\n // Recursively parse as the concrete variant class\n return this._parseInternal(\n variantClass as new (data: any) => T,\n plainObject,\n options,\n );\n }\n\n const strict = options.strict ?? false;\n const skipDefaults = options.skipDefaults ?? false;\n const skipMissing = options.skipMissing ?? false;\n const keys = this.getPropertyKeys(entityClass.prototype);\n const data: Record<string, unknown> = {};\n const hardProblems: Problem[] = [];\n\n for (const key of keys) {\n const propertyOptions = this.getPropertyOptions(\n entityClass.prototype,\n key,\n );\n\n if (!propertyOptions) {\n hardProblems.push(\n new Problem({\n property: key,\n message: `Property has no metadata. This should not happen if @Property() was used correctly.`,\n }),\n );\n continue;\n }\n\n const value = (plainObject as Record<string, unknown>)[key];\n\n if (propertyOptions.passthrough === true) {\n data[key] = value;\n continue;\n }\n\n const isOptional = propertyOptions.optional === true;\n\n if (!(key in plainObject) || value == null) {\n if (skipMissing) {\n continue;\n }\n\n let valueToSet = value;\n\n if (!skipDefaults && propertyOptions.default !== undefined) {\n valueToSet =\n typeof propertyOptions.default === 'function'\n ? await propertyOptions.default()\n : propertyOptions.default;\n }\n\n if (!isOptional && valueToSet == null) {\n hardProblems.push(\n new Problem({\n property: key,\n message:\n 'Required property is missing, null or undefined from input',\n }),\n );\n }\n data[key] = valueToSet;\n continue;\n }\n\n try {\n // Only pass strict to nested deserialization, not skipDefaults/skipMissing\n data[key] = await this.deserializeValue(value, propertyOptions, {\n strict,\n });\n } catch (error) {\n if (error instanceof ValidationError) {\n const isWrapperProperty = wrapperPropertyName === key;\n if (isWrapperProperty) {\n hardProblems.push(...error.problems);\n } else {\n const problems = prependPropertyPath(key, error.problems);\n hardProblems.push(...problems);\n }\n } else if (error instanceof Error) {\n hardProblems.push(\n new Problem({\n property: wrapperPropertyName === key ? '' : key,\n message: error.message,\n }),\n );\n } else {\n throw error;\n }\n }\n }\n\n return { data, hardProblems, entityClass };\n }\n\n /**\n * Deserializes a plain object to an entity instance\n *\n * @param entityClass - The entity class constructor. Must accept a data object parameter.\n * @param plainObject - The plain object to deserialize\n * @param parseOptions - Parse options (strict mode)\n * @returns Promise resolving to a new instance of the entity with deserialized values\n *\n * @remarks\n * Deserialization rules:\n * - All @Property() decorators must include type metadata for parse() to work\n * - Properties without type metadata will throw an error\n * - Required properties (optional !== true) must be present and not null/undefined\n * - Optional properties (optional === true) can be undefined or null\n * - Arrays are supported with the array: true option\n * - Nested entities are recursively deserialized\n * - Type conversion is strict (no coercion)\n * - Entity constructors must accept a required data parameter\n *\n * Validation behavior:\n * - If strict: true - both HARD and SOFT problems throw ValidationError\n * - If strict: false (default) - HARD problems throw ValidationError, SOFT problems stored\n * - Property validators run first, then entity validators\n * - Validators can be synchronous or asynchronous\n * - Problems are accessible via EntityUtils.getProblems()\n * - Raw input data is accessible via EntityUtils.getRawInput()\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => Number }) age!: number;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const json = { name: 'John', age: 30 };\n * const user = await EntityUtils.parse(User, json);\n * const userStrict = await EntityUtils.parse(User, json, { strict: true });\n * ```\n */\n static async parse<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n parseOptions: ParseOptions = {},\n ): Promise<T> {\n const strict = parseOptions?.strict ?? false;\n\n const {\n data,\n hardProblems,\n entityClass: resolvedEntityClass,\n } = await this._parseInternal(entityClass, plainObject, { strict });\n\n if (hardProblems.length > 0) {\n throw new ValidationError(hardProblems);\n }\n\n await this.addInjectedDependencies(data, resolvedEntityClass.prototype);\n\n const instance = new resolvedEntityClass(data);\n\n rawInputStorage.set(instance, plainObject as Record<string, unknown>);\n\n const problems = await this.validate(instance);\n\n if (problems.length > 0 && strict) {\n throw new ValidationError(problems);\n }\n\n return instance;\n }\n\n /**\n * Safely deserializes a plain object to an entity instance without throwing errors\n *\n * @param entityClass - The entity class constructor. Must accept a data object parameter.\n * @param plainObject - The plain object to deserialize\n * @param parseOptions - Parse options (strict mode)\n * @returns Promise resolving to a result object with success flag, data, and problems\n *\n * @remarks\n * Similar to parse() but returns a result object instead of throwing errors:\n * - On success with strict: true - returns { success: true, data, problems: [] }\n * - On success with strict: false - returns { success: true, data, problems: [...] } (may include soft problems)\n * - On failure - returns { success: false, data: undefined, problems: [...] }\n *\n * All deserialization and validation rules from parse() apply.\n * See parse() documentation for detailed deserialization behavior.\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => Number }) age!: number;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const result = await EntityUtils.safeParse(User, { name: 'John', age: 30 });\n * if (result.success) {\n * console.log(result.data); // User instance\n * console.log(result.problems); // [] or soft problems if not strict\n * } else {\n * console.log(result.problems); // Hard problems\n * }\n * ```\n */\n static async safeParse<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n parseOptions?: ParseOptions,\n ): SafeOperationResult<T> {\n try {\n const data = await this.parse(entityClass, plainObject, parseOptions);\n const problems = this.getProblems(data);\n\n return {\n success: true,\n data,\n problems,\n };\n } catch (error) {\n if (error instanceof ValidationError) {\n return {\n success: false,\n data: undefined,\n problems: error.problems,\n };\n }\n throw error;\n }\n }\n\n /**\n * Partially deserializes a plain object, returning a plain object with only present properties\n *\n * @param entityClass - The entity class constructor\n * @param plainObject - The plain object to deserialize\n * @param options - Options with strict mode\n * @returns Promise resolving to a plain object with deserialized properties (Partial<T>)\n *\n * @remarks\n * Differences from parse():\n * - Returns a plain object, not an entity instance\n * - Ignores missing properties (does not include them in result)\n * - Does NOT apply default values to missing properties\n * - When strict: false (default), properties with HARD problems are excluded from result but problems are tracked\n * - When strict: true, any HARD problem throws ValidationError\n * - Nested entities/arrays are still fully deserialized and validated as normal\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => Number, default: 0 }) age!: number;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const partial = await EntityUtils.partialParse(User, { name: 'John' });\n * // partial = { name: 'John' } (age is not included, default not applied)\n *\n * const partialWithError = await EntityUtils.partialParse(User, { name: 'John', age: 'invalid' });\n * // partialWithError = { name: 'John' } (age excluded due to HARD problem)\n * // Access problems via second return value\n * ```\n */\n static async partialParse<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n options: { strict?: boolean } = {},\n ): Promise<Partial<T>> {\n const result = await this.safePartialParse(\n entityClass,\n plainObject,\n options,\n );\n\n if (!result.success) {\n throw new ValidationError(result.problems);\n }\n\n return result.data;\n }\n\n /**\n * Safely performs partial deserialization without throwing errors\n *\n * @param entityClass - The entity class constructor\n * @param plainObject - The plain object to deserialize\n * @param options - Options with strict mode\n * @returns Promise resolving to a result object with success flag, partial data, and problems\n *\n * @remarks\n * Similar to partialParse() but returns a result object instead of throwing errors:\n * - On success with strict: true - returns { success: true, data: Partial<T>, problems: [] }\n * - On success with strict: false - returns { success: true, data: Partial<T>, problems: [...] } (includes hard problems for excluded properties)\n * - On failure (strict mode only) - returns { success: false, data: undefined, problems: [...] }\n *\n * All partial deserialization rules from partialParse() apply.\n * See partialParse() documentation for detailed behavior.\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => Number }) age!: number;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const result = await EntityUtils.safePartialParse(User, { name: 'John', age: 'invalid' });\n * if (result.success) {\n * console.log(result.data); // { name: 'John' }\n * console.log(result.problems); // [Problem for age property]\n * } else {\n * console.log(result.problems); // Hard problems (only in strict mode)\n * }\n * ```\n */\n static async safePartialParse<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n options?: { strict?: boolean },\n ): Promise<SafeOperationResult<Partial<T>>> {\n const strict = options?.strict ?? false;\n\n const { data, hardProblems } = await this._parseInternal(\n entityClass,\n plainObject,\n { strict, skipDefaults: true, skipMissing: true },\n );\n\n if (strict && hardProblems.length > 0) {\n return {\n success: false,\n data: undefined,\n problems: hardProblems,\n };\n }\n\n const propertyProblems = await this.validateProperties(\n data,\n entityClass.prototype,\n );\n const validationProblems = [...hardProblems, ...propertyProblems];\n\n if (strict && propertyProblems.length > 0) {\n return {\n success: false,\n data: undefined,\n problems: validationProblems,\n };\n }\n\n this.setProblems(data, validationProblems);\n\n return {\n success: true,\n data: data as Partial<T>,\n problems: validationProblems,\n };\n }\n\n /**\n * Updates an entity instance with new values, respecting preventUpdates flags on properties\n *\n * @param instance - The entity instance to update. Must be an Entity.\n * @param updates - Partial object with properties to update\n * @param options - Update options (strict mode)\n * @returns Promise resolving to a new instance with updated values\n *\n * @remarks\n * Update behavior:\n * - Creates a shallow copy of the instance\n * - For each @Property(), copies the value from updates if it exists\n * - Properties with preventUpdates: true will not be copied from updates\n * - Runs entity validators after applying updates\n * - Throws ValidationError if validation fails and strict: true\n * - Soft problems are stored on the instance if strict: false (default)\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => String, preventUpdates: true }) id!: string;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const user = new User({ id: '123', name: 'John' });\n * const updated = await EntityUtils.update(user, { id: '456', name: 'Jane' });\n * // updated.id === '123' (not updated due to preventUpdates: true)\n * // updated.name === 'Jane'\n * ```\n */\n static async update<T extends object>(\n instance: T,\n updates: Partial<T>,\n options?: { strict?: boolean },\n ): Promise<T> {\n if (!this.isEntity(instance)) {\n throw new Error('Cannot update non-entity instance');\n }\n\n const strict = options?.strict ?? false;\n const Constructor = Object.getPrototypeOf(instance).constructor;\n const keys = this.getPropertyKeys(instance);\n const data: Record<string, unknown> = {};\n\n // Copy existing properties\n for (const key of keys) {\n const value = (instance as any)[key];\n data[key] = value;\n }\n\n // Apply updates, respecting preventUpdates flag\n for (const key of keys) {\n if (key in updates) {\n const propertyOptions = this.getPropertyOptions(instance, key);\n if (propertyOptions && propertyOptions.preventUpdates === true) {\n // Skip updating this property\n continue;\n }\n data[key] = (updates as any)[key];\n }\n }\n\n const newInstance = new Constructor(data);\n\n const problems = await this.validate(newInstance);\n\n if (problems.length > 0 && strict) {\n throw new ValidationError(problems);\n }\n\n return newInstance;\n }\n\n /**\n * Safely updates an entity instance without throwing errors\n *\n * @param instance - The entity instance to update. Must be an Entity.\n * @param updates - Partial object with properties to update\n * @param options - Update options (strict mode)\n * @returns Promise resolving to a result object with success flag, data, and problems\n *\n * @remarks\n * Similar to update() but returns a result object instead of throwing errors:\n * - On success with strict: true - returns { success: true, data, problems: [] }\n * - On success with strict: false - returns { success: true, data, problems: [...] } (may include soft problems)\n * - On failure - returns { success: false, data: undefined, problems: [...] }\n *\n * All update and validation rules from update() apply.\n * See update() documentation for detailed update behavior.\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const user = new User({ name: 'John' });\n * const result = await EntityUtils.safeUpdate(user, { name: 'Jane' });\n * if (result.success) {\n * console.log(result.data); // Updated User instance\n * console.log(result.problems); // [] or soft problems if not strict\n * } else {\n * console.log(result.problems); // Hard problems\n * }\n * ```\n */\n static async safeUpdate<T extends object>(\n instance: T,\n updates: Partial<T>,\n options?: { strict?: boolean },\n ): SafeOperationResult<T> {\n try {\n const updatedInstance = await this.update(instance, updates, options);\n const problems = this.getProblems(updatedInstance);\n\n return {\n success: true,\n data: updatedInstance,\n problems,\n };\n } catch (error) {\n if (error instanceof ValidationError) {\n return {\n success: false,\n data: undefined,\n problems: error.problems,\n };\n }\n throw error;\n }\n }\n\n /**\n * Deserializes a single value according to the type metadata\n * @private\n */\n private static async deserializeValue(\n value: unknown,\n options: PropertyOptions,\n parseOptions: ParseOptions,\n ): Promise<unknown> {\n const isArray = options.array === true;\n const isSparse = options.sparse === true;\n const isDiscriminated = options.discriminated === true;\n\n if (isArray) {\n if (!Array.isArray(value)) {\n throw createValidationError(\n `Expects an array but received ${typeof value}`,\n );\n }\n\n const arrayProblems: Problem[] = [];\n const result: unknown[] = [];\n\n for (let index = 0; index < value.length; index++) {\n const item = value[index];\n if (item === null || item === undefined) {\n if (!isSparse) {\n arrayProblems.push(\n new Problem({\n property: `[${index}]`,\n message: 'Cannot be null or undefined.',\n }),\n );\n }\n result.push(item);\n } else {\n try {\n if (options.deserialize) {\n result.push(options.deserialize(item));\n } else if (isDiscriminated) {\n result.push(\n await this.deserializeDiscriminatedValue(item, options),\n );\n } else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const typeConstructor = options.type!();\n result.push(\n await this.deserializeSingleValue(\n item,\n typeConstructor,\n parseOptions,\n ),\n );\n }\n } catch (error) {\n if (error instanceof ValidationError) {\n const problems = prependArrayIndex(index, error);\n arrayProblems.push(...problems);\n } else {\n throw error;\n }\n }\n }\n }\n\n if (arrayProblems.length > 0) {\n throw new ValidationError(arrayProblems);\n }\n\n return result;\n }\n\n if (options.deserialize) {\n return options.deserialize(value);\n }\n\n if (isDiscriminated) {\n return await this.deserializeDiscriminatedValue(value, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const typeConstructor = options.type!();\n return await this.deserializeSingleValue(\n value,\n typeConstructor,\n parseOptions,\n );\n }\n\n /**\n * Deserializes a single non-array value\n * Reports validation errors with empty property (caller will prepend context)\n * @private\n */\n private static async deserializeSingleValue(\n value: unknown,\n typeConstructor: any,\n parseOptions: ParseOptions,\n ): Promise<unknown> {\n if (isPrimitiveConstructor(typeConstructor)) {\n return deserializePrimitive(value, typeConstructor);\n }\n\n if (this.isEntity(typeConstructor)) {\n return await this.parse(\n typeConstructor as new (data: any) => object,\n value as Record<string, unknown>,\n parseOptions,\n );\n }\n\n throw createValidationError(\n `Has unknown type constructor. Supported types are: String, Number, Boolean, Date, BigInt, and @Entity() classes. Use passthrough: true to explicitly allow unknown types.`,\n );\n }\n\n /**\n * Deserializes a discriminated entity value by reading the discriminator and looking up the entity class\n * @private\n */\n private static async deserializeDiscriminatedValue(\n value: unknown,\n options: PropertyOptions,\n ): Promise<unknown> {\n if (value == null) {\n throw createValidationError(\n `Cannot deserialize discriminated entity from null or undefined`,\n );\n }\n\n if (typeof value !== 'object' || Array.isArray(value)) {\n throw createValidationError(\n `Discriminated entity must be an object, received ${typeof value}`,\n );\n }\n\n const discriminatorProperty = options.discriminatorProperty;\n ok(discriminatorProperty, 'Discriminator property must be defined');\n\n const discriminatorValue = (value as Record<string, unknown>)[\n discriminatorProperty\n ];\n\n if (\n typeof discriminatorValue !== 'string' ||\n discriminatorValue.trim() === ''\n ) {\n throw createValidationError(\n `Missing or invalid discriminator property '${discriminatorProperty}'. Expected a non-empty string.`,\n );\n }\n\n const entityClass = EntityRegistry.get(discriminatorValue);\n\n if (!entityClass) {\n throw createValidationError(\n `Unknown entity type '${discriminatorValue}'. No entity registered with this name.`,\n );\n }\n\n return await this.parse(\n entityClass as new (data: any) => object,\n value as Record<string, unknown>,\n {},\n );\n }\n\n /**\n * Validates a property value by running validators and nested entity validation.\n * Prepends the property path to all returned problems.\n * @private\n */\n private static async validatePropertyValue(\n propertyPath: string,\n value: unknown,\n validators: PropertyOptions['validators'],\n ): Promise<Problem[]> {\n const problems: Problem[] = [];\n\n if (validators) {\n for (const validator of validators) {\n const validatorProblems = await validator({ value });\n if (validatorProblems.length > 0) {\n const prepended = prependPropertyPath(\n propertyPath,\n validatorProblems,\n );\n problems.push(...prepended);\n }\n }\n }\n\n if (EntityUtils.isEntity(value)) {\n const existingProblems = problemsStorage.get(value);\n const nestedProblems =\n existingProblems && existingProblems.length > 0\n ? existingProblems\n : await EntityUtils.validate(value);\n\n if (nestedProblems.length > 0) {\n const prepended = prependPropertyPath(propertyPath, nestedProblems);\n problems.push(...prepended);\n }\n }\n\n return problems;\n }\n\n /**\n * Checks if an array contains any entity elements\n * @private\n */\n private static hasEntityElements(value: unknown): boolean {\n if (!Array.isArray(value)) {\n return false;\n }\n return value.some((element) => this.isEntity(element));\n }\n\n /**\n * Runs property validators for a given property value\n * @private\n */\n private static async runPropertyValidators(\n key: string,\n value: unknown,\n options: PropertyOptions,\n ): Promise<Problem[]> {\n const problems: Problem[] = [];\n const isArray = options?.array === true;\n const isPassthrough = options?.passthrough === true;\n\n if (isPassthrough || !isArray) {\n const valueProblems = await this.validatePropertyValue(\n key,\n value,\n options.validators,\n );\n problems.push(...valueProblems);\n } else {\n ok(Array.isArray(value), 'Value must be an array for array property');\n\n const arrayValidators = options.arrayValidators || [];\n for (const validator of arrayValidators) {\n const validatorProblems = await validator({ value });\n if (validatorProblems.length > 0) {\n const prepended = prependPropertyPath(key, validatorProblems);\n problems.push(...prepended);\n }\n }\n\n const validators = options.validators || [];\n if (validators.length > 0 || this.hasEntityElements(value)) {\n for (let i = 0; i < value.length; i++) {\n const element = value[i];\n if (element !== null && element !== undefined) {\n const elementPath = `${key}[${i}]`;\n const elementProblems = await this.validatePropertyValue(\n elementPath,\n element,\n validators,\n );\n problems.push(...elementProblems);\n }\n }\n }\n }\n\n return problems;\n }\n\n /**\n * Validates all properties on an object (entity instance or plain object)\n * @private\n */\n private static async validateProperties(\n dataOrInstance: Record<string, unknown> | object,\n prototype: object,\n ): Promise<Problem[]> {\n const problems: Problem[] = [];\n const keys = Object.keys(dataOrInstance);\n const wrapperProperty = this.getWrapperPropertyName(dataOrInstance);\n\n for (const key of keys) {\n const options = this.getPropertyOptions(prototype, key);\n if (options) {\n const value = (dataOrInstance as any)[key];\n if (value != null) {\n const propertyPath = wrapperProperty === key ? '' : key;\n const validationProblems = await this.runPropertyValidators(\n propertyPath,\n value,\n options,\n );\n problems.push(...validationProblems);\n }\n }\n }\n\n return problems;\n }\n\n private static async addInjectedDependencies(\n data: Record<string, unknown>,\n prototype: object,\n ): Promise<void> {\n const injectedPropertyNames = getInjectedPropertyNames(prototype);\n if (injectedPropertyNames.length === 0) {\n return;\n }\n\n const injectedPropertyOptions = getInjectedPropertyOptions(prototype);\n\n for (const propertyName of injectedPropertyNames) {\n const token = injectedPropertyOptions[propertyName];\n if (token) {\n const dependency = await EntityDI.get(token);\n data[propertyName] = dependency;\n }\n }\n }\n\n /**\n * Validates an entity instance by running all property and entity validators\n *\n * @param instance - The entity instance to validate\n * @returns Promise resolving to array of Problems found during validation (empty if valid)\n *\n * @remarks\n * - Property validators run first, then entity validators\n * - Each validator can be synchronous or asynchronous\n * - Empty array means no problems found\n *\n * @example\n * ```typescript\n * const user = new User({ name: '', age: -5 });\n * const problems = await EntityUtils.validate(user);\n * console.log(problems); // [Problem, Problem, ...]\n * ```\n */\n static async validate<T extends object>(instance: T): Promise<Problem[]> {\n if (!this.isEntity(instance)) {\n throw new Error('Cannot validate non-entity instance');\n }\n\n const problems: Problem[] = [];\n\n const propertyProblems = await this.validateProperties(instance, instance);\n problems.push(...propertyProblems);\n\n const entityValidators = this.getEntityValidators(instance);\n for (const validatorMethod of entityValidators) {\n const validatorProblems = await (instance as any)[validatorMethod]();\n if (Array.isArray(validatorProblems)) {\n problems.push(...validatorProblems);\n }\n }\n\n EntityUtils.setProblems(instance, problems);\n\n return problems;\n }\n\n /**\n * Gets the validation problems for an entity instance\n *\n * @param instance - The entity instance\n * @returns Array of Problems (empty if no problems or instance not parsed)\n *\n * @remarks\n * - Only returns problems from the last parse() call\n * - Returns empty array if instance was not created via parse()\n * - Returns empty array if parse() was called with strict: true\n *\n * @example\n * ```typescript\n * const user = EntityUtils.parse(User, data);\n * const problems = EntityUtils.getProblems(user);\n * console.log(problems); // [Problem, ...]\n * ```\n */\n static getProblems<T extends object>(instance: T): Problem[] {\n return problemsStorage.get(instance) || [];\n }\n\n /**\n * Sets the validation problems for an entity instance\n *\n * @param instance - The entity instance\n * @param problems - Array of Problems to associate with the instance\n *\n * @remarks\n * - Overwrites any existing problems for the instance\n * - Pass an empty array to clear problems\n *\n * @example\n * ```typescript\n * const user = new User({ name: 'John' });\n * EntityUtils.setProblems(user, [new Problem({ property: 'name', message: 'Invalid name' })]);\n * ```\n */\n static setProblems<T extends object>(instance: T, problems: Problem[]): void {\n if (problems.length === 0) {\n problemsStorage.delete(instance);\n } else {\n problemsStorage.set(instance, problems);\n }\n }\n\n /**\n * Gets the raw input data that was used to create an entity instance\n *\n * @param instance - The entity instance\n * @returns The raw input object, or undefined if not available\n *\n * @remarks\n * - Only available for instances created via parse()\n * - Returns a reference to the original input data (not a copy)\n *\n * @example\n * ```typescript\n * const user = EntityUtils.parse(User, { name: 'John', age: 30 });\n * const rawInput = EntityUtils.getRawInput(user);\n * console.log(rawInput); // { name: 'John', age: 30 }\n * ```\n */\n static getRawInput<T extends object>(instance: T): unknown {\n return rawInputStorage.get(instance);\n }\n\n /**\n * Sets the raw input data for an entity instance\n *\n * @param instance - The entity instance\n * @param rawInput - The raw input object to associate with the instance\n *\n * @remarks\n * - Overwrites any existing raw input for the instance\n * - Pass undefined to clear the raw input\n *\n * @example\n * ```typescript\n * const user = new User({ name: 'John' });\n * EntityUtils.setRawInput(user, { name: 'John', age: 30 });\n * ```\n */\n static setRawInput<T extends object>(\n instance: T,\n rawInput: Record<string, unknown> | undefined,\n ): void {\n if (rawInput === undefined) {\n rawInputStorage.delete(instance);\n } else {\n rawInputStorage.set(instance, rawInput);\n }\n }\n\n /**\n * Gets all entity validator method names for an entity\n * @private\n */\n private static getEntityValidators(target: object): string[] {\n let currentProto: any;\n\n if (target.constructor && target === target.constructor.prototype) {\n currentProto = target;\n } else {\n currentProto = Object.getPrototypeOf(target);\n }\n\n const validators: string[] = [];\n const seen = new Set<string>();\n\n while (currentProto && currentProto !== Object.prototype) {\n const protoValidators: string[] =\n Reflect.getOwnMetadata(ENTITY_VALIDATOR_METADATA_KEY, currentProto) ||\n [];\n\n for (const validator of protoValidators) {\n if (!seen.has(validator)) {\n seen.add(validator);\n validators.push(validator);\n }\n }\n\n currentProto = Object.getPrototypeOf(currentProto);\n }\n\n return validators;\n }\n}\n"],"names":["ENTITY_METADATA_KEY","ENTITY_OPTIONS_METADATA_KEY","ENTITY_VALIDATOR_METADATA_KEY","PROPERTY_METADATA_KEY","PROPERTY_OPTIONS_METADATA_KEY","getInjectedPropertyNames","getInjectedPropertyOptions","EntityDI","isEqualWith","ValidationError","Problem","prependArrayIndex","prependPropertyPath","createValidationError","isPrimitiveConstructor","deserializePrimitive","ok","EntityRegistry","PolymorphicRegistry","problemsStorage","WeakMap","rawInputStorage","EntityUtils","isEntity","obj","Reflect","hasMetadata","Array","isArray","constructor","Object","getPrototypeOf","getEntityOptions","entityOrClass","options","getMetadata","getEntityName","undefined","name","isCollectionEntity","collection","isStringifiable","stringifiable","getWrapperPropertyName","wrapperProperty","sameEntity","a","b","getPropertyKeys","target","currentProto","prototype","keys","seen","Set","protoKeys","getOwnMetadata","key","has","add","push","getPropertyOptions","propertyKey","protoOptions","equals","val1","val2","diff","length","oldEntity","newEntity","Error","diffs","oldValue","newValue","propertyOptions","areEqual","property","changes","reduce","acc","toJSON","entity","valuePropertyOptions","array","type","String","serializeValue","value","collectionPropertyOptions","result","passthrough","serialize","map","item","Date","toISOString","toString","serialized","discriminated","discriminatorProperty","entityClass","entityName","_parseInternal","plainObject","wrapperPropertyName","getDiscriminatorProperty","discriminatorValue","variantClass","getVariant","strict","skipDefaults","skipMissing","data","hardProblems","message","isOptional","optional","valueToSet","default","deserializeValue","error","isWrapperProperty","problems","parse","parseOptions","resolvedEntityClass","addInjectedDependencies","instance","set","validate","safeParse","getProblems","success","partialParse","safePartialParse","propertyProblems","validateProperties","validationProblems","setProblems","update","updates","Constructor","preventUpdates","newInstance","safeUpdate","updatedInstance","isSparse","sparse","isDiscriminated","arrayProblems","index","deserialize","deserializeDiscriminatedValue","typeConstructor","deserializeSingleValue","trim","get","validatePropertyValue","propertyPath","validators","validator","validatorProblems","prepended","existingProblems","nestedProblems","hasEntityElements","some","element","runPropertyValidators","isPassthrough","valueProblems","arrayValidators","i","elementPath","elementProblems","dataOrInstance","injectedPropertyNames","injectedPropertyOptions","propertyName","token","dependency","entityValidators","getEntityValidators","validatorMethod","delete","getRawInput","setRawInput","rawInput","protoValidators"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/lib/entity-utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n ENTITY_METADATA_KEY,\n ENTITY_OPTIONS_METADATA_KEY,\n ENTITY_VALIDATOR_METADATA_KEY,\n ParseOptions,\n PROPERTY_METADATA_KEY,\n PROPERTY_OPTIONS_METADATA_KEY,\n PropertyDeserializeContext,\n PropertyOptions,\n PropertySerializeContext,\n SafeOperationResult,\n} from './types.js';\nimport type { EntityOptions } from './entity.js';\nimport {\n getInjectedPropertyNames,\n getInjectedPropertyOptions,\n} from './injected-property.js';\nimport { EntityDI } from './entity-di.js';\nimport { isEqualWith } from 'lodash-es';\nimport { ValidationError } from './validation-error.js';\nimport { Problem } from './problem.js';\nimport {\n prependArrayIndex,\n prependPropertyPath,\n createValidationError,\n} from './validation-utils.js';\nimport {\n isPrimitiveConstructor,\n deserializePrimitive,\n} from './primitive-deserializers.js';\nimport { ok } from 'assert';\nimport { EntityRegistry } from './entity-registry.js';\nimport { PolymorphicRegistry } from './polymorphic-registry.js';\n\n/**\n * WeakMap to store validation problems for entity instances\n */\nconst problemsStorage = new WeakMap<object, Problem[]>();\n\n/**\n * WeakMap to store raw input data for entity instances\n */\nconst rawInputStorage = new WeakMap<object, unknown>();\n\nexport class EntityUtils {\n /**\n * Checks if a given object is an instance of a class decorated with @Entity()\n * or if the provided value is an entity class itself\n *\n * @param obj - The object or class to check\n * @returns true if the object is an entity instance or entity class, false otherwise\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * name: string;\n * }\n *\n * const user = new User();\n * console.log(EntityUtils.isEntity(user)); // true\n * console.log(EntityUtils.isEntity(User)); // true\n * console.log(EntityUtils.isEntity({})); // false\n * ```\n */\n static isEntity(obj: unknown): obj is object {\n if (obj == null) {\n return false;\n }\n\n // Check if obj is a constructor function (class)\n if (typeof obj === 'function') {\n return Reflect.hasMetadata(ENTITY_METADATA_KEY, obj);\n }\n\n // Check if obj is an object instance\n if (typeof obj !== 'object' || Array.isArray(obj)) {\n return false;\n }\n\n const constructor = Object.getPrototypeOf(obj).constructor;\n return Reflect.hasMetadata(ENTITY_METADATA_KEY, constructor);\n }\n\n /**\n * Gets the entity options for a given constructor\n *\n * @param entityOrClass - The entity class constructor or instance\n * @returns EntityOptions object (empty object if no options are defined)\n * @private\n */\n private static getEntityOptions(entityOrClass: unknown): EntityOptions {\n const constructor =\n typeof entityOrClass === 'function'\n ? entityOrClass\n : Object.getPrototypeOf(entityOrClass).constructor;\n\n const options: EntityOptions | undefined = Reflect.getMetadata(\n ENTITY_OPTIONS_METADATA_KEY,\n constructor,\n );\n return options ?? {};\n }\n\n /**\n * Gets the registered name for an entity class or instance\n *\n * @param entityOrClass - The entity class constructor or instance\n * @returns The entity name, or undefined if not found\n *\n * @example\n * ```typescript\n * @Entity({ name: 'CustomUser' })\n * class User {\n * name: string;\n * }\n *\n * console.log(EntityUtils.getEntityName(User)); // 'CustomUser'\n * console.log(EntityUtils.getEntityName(new User())); // 'CustomUser'\n * ```\n */\n static getEntityName(entityOrClass: unknown): string | undefined {\n if (!this.isEntity(entityOrClass)) {\n return undefined;\n }\n\n const options = this.getEntityOptions(entityOrClass);\n return options.name;\n }\n\n /**\n * Checks if a given entity is marked as a collection entity\n *\n * @param entityOrClass - The entity instance or class to check\n * @returns true if the entity is a collection entity, false otherwise\n *\n * @example\n * ```typescript\n * @CollectionEntity()\n * class Tags {\n * @ArrayProperty(() => String)\n * collection: string[];\n * }\n *\n * const tags = new Tags({ collection: ['a', 'b'] });\n * console.log(EntityUtils.isCollectionEntity(tags)); // true\n * console.log(EntityUtils.isCollectionEntity(Tags)); // true\n * ```\n */\n static isCollectionEntity(entityOrClass: unknown): boolean {\n if (!this.isEntity(entityOrClass)) {\n return false;\n }\n\n const options = this.getEntityOptions(entityOrClass);\n\n return options.collection === true;\n }\n\n /**\n * Checks if a given entity is marked as a stringifiable entity\n *\n * @param entityOrClass - The entity instance or class to check\n * @returns true if the entity is a stringifiable entity, false otherwise\n *\n * @example\n * ```typescript\n * @Stringifiable()\n * class UserId {\n * @StringProperty()\n * value: string;\n * }\n *\n * const userId = new UserId({ value: 'user-123' });\n * console.log(EntityUtils.isStringifiable(userId)); // true\n * console.log(EntityUtils.isStringifiable(UserId)); // true\n * ```\n */\n static isStringifiable(entityOrClass: unknown): boolean {\n if (!this.isEntity(entityOrClass)) {\n return false;\n }\n\n const options = this.getEntityOptions(entityOrClass);\n\n return options.stringifiable === true;\n }\n\n /**\n * Gets the \"wrapper\" property name for entities that act as transparent wrappers.\n * When set, this property name is excluded from error paths during validation.\n *\n * @param entityOrClass - The entity instance or class to check\n * @returns The wrapper property name, or undefined if not a wrapper entity\n * @private\n */\n private static getWrapperPropertyName(\n entityOrClass: unknown,\n ): string | undefined {\n if (!this.isEntity(entityOrClass)) {\n return undefined;\n }\n return this.getEntityOptions(entityOrClass).wrapperProperty;\n }\n\n static sameEntity(a: object, b: object): boolean {\n if (!this.isEntity(a) || !this.isEntity(b)) {\n return false;\n }\n\n return Object.getPrototypeOf(a) === Object.getPrototypeOf(b);\n }\n\n static getPropertyKeys(target: object): string[] {\n // Determine if we're dealing with a prototype or an instance\n let currentProto: any;\n\n // Check if target is a prototype by checking if it has a constructor property\n // and if target === target.constructor.prototype\n if (target.constructor && target === target.constructor.prototype) {\n // target is already a prototype\n currentProto = target;\n } else {\n // target is an instance, get its prototype\n currentProto = Object.getPrototypeOf(target);\n }\n\n const keys: string[] = [];\n const seen = new Set<string>();\n\n // Walk the prototype chain to collect all inherited properties\n while (currentProto && currentProto !== Object.prototype) {\n // Use getOwnMetadata to only get metadata directly on this prototype\n const protoKeys: string[] =\n Reflect.getOwnMetadata(PROPERTY_METADATA_KEY, currentProto) || [];\n\n for (const key of protoKeys) {\n if (!seen.has(key)) {\n seen.add(key);\n keys.push(key);\n }\n }\n\n currentProto = Object.getPrototypeOf(currentProto);\n }\n\n return keys;\n }\n\n static getPropertyOptions(\n target: object,\n propertyKey: string,\n ): PropertyOptions | undefined {\n // Determine if we're dealing with a prototype or an instance\n let currentProto: any;\n\n // Check if target is a prototype by checking if it has a constructor property\n // and if target === target.constructor.prototype\n if (target.constructor && target === target.constructor.prototype) {\n // target is already a prototype\n currentProto = target;\n } else {\n // target is an instance, get its prototype\n currentProto = Object.getPrototypeOf(target);\n }\n\n // Walk the prototype chain to find the property options\n while (currentProto && currentProto !== Object.prototype) {\n const protoOptions: Record<string, PropertyOptions> =\n Reflect.getOwnMetadata(PROPERTY_OPTIONS_METADATA_KEY, currentProto) ||\n {};\n\n if (protoOptions[propertyKey]) {\n return protoOptions[propertyKey];\n }\n\n currentProto = Object.getPrototypeOf(currentProto);\n }\n\n return undefined;\n }\n\n static equals(a: unknown, b: unknown): boolean {\n return isEqualWith(a, b, (val1, val2) => {\n if (this.isEntity(val1)) {\n if (!this.sameEntity(val1, val2)) {\n return false;\n }\n\n const diff = this.diff(val1, val2);\n\n return diff.length === 0;\n } else if (\n val1 != null &&\n val2 != null &&\n typeof val1 === 'object' &&\n !Array.isArray(val1) &&\n typeof val2 === 'object' &&\n !Array.isArray(val2) &&\n 'equals' in val1 &&\n typeof val1.equals === 'function'\n ) {\n return val1.equals(val2);\n }\n\n return undefined;\n });\n }\n\n static diff<T extends object>(\n oldEntity: T,\n newEntity: T,\n ): { property: string; oldValue: unknown; newValue: unknown }[] {\n if (!this.sameEntity(oldEntity, newEntity)) {\n throw new Error('Entities must be of the same type to compute diff');\n }\n\n const diffs: { property: string; oldValue: unknown; newValue: unknown }[] =\n [];\n\n const keys = this.getPropertyKeys(oldEntity);\n\n for (const key of keys) {\n const oldValue = (oldEntity as any)[key];\n const newValue = (newEntity as any)[key];\n\n // Check if there's a custom equals function for this property\n const propertyOptions = this.getPropertyOptions(oldEntity, key);\n\n let areEqual: boolean;\n if (oldValue == null && newValue == null) {\n areEqual = oldValue === newValue;\n } else if (oldValue == null || newValue == null) {\n areEqual = false;\n } else {\n areEqual = propertyOptions?.equals\n ? propertyOptions.equals(oldValue, newValue)\n : this.equals(oldValue, newValue);\n }\n\n if (!areEqual) {\n diffs.push({ property: key, oldValue, newValue });\n }\n }\n\n return diffs;\n }\n\n static changes<T extends object>(oldEntity: T, newEntity: T): Partial<T> {\n if (!this.sameEntity(oldEntity, newEntity)) {\n throw new Error('Entities must be of the same type to compute changes');\n }\n\n const diff = this.diff(oldEntity, newEntity);\n\n return diff.reduce((acc, { property, newValue }) => {\n (acc as any)[property] = newValue;\n return acc;\n }, {} as Partial<T>);\n }\n\n /**\n * Serializes an entity to a plain object, converting only properties decorated with @Property()\n *\n * @param entity - The entity instance to serialize\n * @returns A plain object containing only the serialized decorated properties, or an array for collection entities\n *\n * @remarks\n * Serialization rules:\n * - Only properties decorated with @Property() are included\n * - If a property has a custom toJSON() method, it will be used\n * - Nested entities are recursively serialized using EntityUtils.toJSON()\n * - Arrays are mapped with toJSON() applied to each element\n * - Date objects are serialized to ISO strings\n * - bigint values are serialized to strings\n * - undefined values are excluded from the output\n * - null values are included in the output\n * - Circular references are not supported (will cause stack overflow)\n * - Collection entities (@CollectionEntity) are unwrapped to just their array\n *\n * @example\n * ```typescript\n * @Entity()\n * class Address {\n * @Property() street: string;\n * @Property() city: string;\n * }\n *\n * @Entity()\n * class User {\n * @Property() name: string;\n * @Property() address: Address;\n * @Property() createdAt: Date;\n * undecorated: string; // Will not be serialized\n * }\n *\n * const user = new User();\n * user.name = 'John';\n * user.address = new Address();\n * user.address.street = '123 Main St';\n * user.address.city = 'Boston';\n * user.createdAt = new Date('2024-01-01');\n * user.undecorated = 'ignored';\n *\n * const json = EntityUtils.toJSON(user);\n * // {\n * // name: 'John',\n * // address: { street: '123 Main St', city: 'Boston' },\n * // createdAt: '2024-01-01T00:00:00.000Z'\n * // }\n *\n * @CollectionEntity()\n * class Tags {\n * @ArrayProperty(() => String)\n * collection: string[];\n * }\n *\n * const tags = new Tags({ collection: ['a', 'b'] });\n * const json = EntityUtils.toJSON(tags);\n * // ['a', 'b'] - unwrapped to array\n * ```\n */\n static toJSON<T extends object>(entity: T): unknown {\n if (this.isStringifiable(entity)) {\n const valuePropertyOptions = this.getPropertyOptions(entity, 'value');\n if (!valuePropertyOptions) {\n throw new Error(\n `Stringifiable entity 'value' property is missing metadata`,\n );\n }\n if (valuePropertyOptions.array) {\n throw new Error(\n `Stringifiable entity 'value' property must not be an array`,\n );\n }\n if (valuePropertyOptions.type?.() !== String) {\n throw new Error(\n `Stringifiable entity 'value' property must be of type String`,\n );\n }\n\n return this.serializeValue((entity as any).value, valuePropertyOptions);\n }\n\n if (this.isCollectionEntity(entity)) {\n const collectionPropertyOptions = this.getPropertyOptions(\n entity,\n 'collection',\n );\n if (!collectionPropertyOptions) {\n throw new Error(\n `Collection entity 'collection' property is missing metadata`,\n );\n }\n if (!collectionPropertyOptions.array) {\n throw new Error(\n `Collection entity 'collection' property must be an array`,\n );\n }\n\n return this.serializeValue(\n (entity as any).collection,\n collectionPropertyOptions,\n );\n }\n\n const result: Record<string, unknown> = {};\n const keys = this.getPropertyKeys(entity);\n\n for (const key of keys) {\n const value = (entity as any)[key];\n\n // Skip undefined values\n if (value === undefined) {\n continue;\n }\n\n const options = this.getPropertyOptions(entity, key);\n const serializeContext: PropertySerializeContext = {\n propertyName: key,\n entity: entity as Record<string, unknown>,\n };\n result[key] = this.serializeValue(value, options, serializeContext);\n }\n\n return result;\n }\n\n /**\n * Serializes a single value according to the toJSON rules\n * @private\n */\n private static serializeValue(\n value: unknown,\n options?: PropertyOptions,\n context?: PropertySerializeContext,\n ): unknown {\n if (value === null) {\n return null;\n }\n\n if (value === undefined) {\n return undefined;\n }\n\n const passthrough = options?.passthrough === true;\n if (passthrough) {\n return value;\n }\n\n if (Array.isArray(value)) {\n if (options?.serialize) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return value.map((item) => options.serialize!(item as any, context!));\n }\n return value.map((item) => this.serializeValue(item, options, context));\n }\n\n if (options?.serialize) {\n return options.serialize(value as any, context!);\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (typeof value === 'bigint') {\n return value.toString();\n }\n\n if (this.isEntity(value)) {\n const serialized = this.toJSON(value);\n\n // If this is a discriminated entity property, add the discriminator inline\n if (options?.discriminated === true) {\n const discriminatorProperty = options.discriminatorProperty;\n ok(discriminatorProperty, 'Discriminator property must be defined');\n\n const entityClass = Object.getPrototypeOf(value).constructor;\n const entityName = this.getEntityName(entityClass);\n\n if (!entityName) {\n throw new Error(\n `Cannot serialize discriminated entity: Entity class '${entityClass.name}' is not registered. Ensure it's decorated with @Entity().`,\n );\n }\n\n if (\n typeof serialized !== 'object' ||\n Array.isArray(serialized) ||\n serialized === null\n ) {\n throw new Error(\n `Cannot serialize discriminated entity: Expected serialized value to be an object.`,\n );\n }\n\n return {\n ...serialized,\n [discriminatorProperty]: entityName,\n } as Record<string, unknown>;\n }\n\n return serialized;\n }\n\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return value;\n }\n\n throw new Error(\n `Cannot serialize value of type '${typeof value}'. Use passthrough: true in @Property() to explicitly allow serialization of unknown types.`,\n );\n }\n\n /**\n * Internal parse implementation with extended options\n * @private\n */\n private static async _parseInternal<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n options: {\n strict?: boolean;\n skipDefaults?: boolean;\n skipMissing?: boolean;\n } = {},\n ): Promise<{\n data: Record<string, unknown>;\n hardProblems: Problem[];\n entityClass: new (data: any) => T;\n }> {\n const wrapperPropertyName = this.getWrapperPropertyName(entityClass);\n\n if (wrapperPropertyName) {\n plainObject = { [wrapperPropertyName]: plainObject };\n }\n if (plainObject == null) {\n throw createValidationError(\n `Expects an object but received ${typeof plainObject}`,\n );\n }\n if (Array.isArray(plainObject)) {\n throw createValidationError(`Expects an object but received array`);\n }\n if (typeof plainObject !== 'object') {\n throw createValidationError(\n `Expects an object but received ${typeof plainObject}`,\n );\n }\n\n // Check for polymorphic base class - resolve to concrete variant if found\n const discriminatorProperty =\n PolymorphicRegistry.getDiscriminatorProperty(entityClass);\n\n if (discriminatorProperty) {\n const discriminatorValue = (plainObject as Record<string, unknown>)[\n discriminatorProperty\n ];\n\n if (discriminatorValue === undefined) {\n throw createValidationError(\n `Missing polymorphic discriminator property '${discriminatorProperty}' ` +\n `for base class '${entityClass.name}'. ` +\n `The discriminator property is required to determine the correct variant class.`,\n );\n }\n\n const variantClass = PolymorphicRegistry.getVariant(\n entityClass,\n discriminatorValue,\n );\n\n if (!variantClass) {\n throw createValidationError(\n `Unknown polymorphic variant '${String(discriminatorValue)}' ` +\n `for base class '${entityClass.name}'. ` +\n `Discriminator property: '${discriminatorProperty}'. ` +\n `Ensure the variant class is decorated with @PolymorphicVariant.`,\n );\n }\n\n // Recursively parse as the concrete variant class\n return this._parseInternal(\n variantClass as new (data: any) => T,\n plainObject,\n options,\n );\n }\n\n const strict = options.strict ?? false;\n const skipDefaults = options.skipDefaults ?? false;\n const skipMissing = options.skipMissing ?? false;\n const keys = this.getPropertyKeys(entityClass.prototype);\n const data: Record<string, unknown> = {};\n const hardProblems: Problem[] = [];\n\n for (const key of keys) {\n const propertyOptions = this.getPropertyOptions(\n entityClass.prototype,\n key,\n );\n\n if (!propertyOptions) {\n hardProblems.push(\n new Problem({\n property: key,\n message: `Property has no metadata. This should not happen if @Property() was used correctly.`,\n }),\n );\n continue;\n }\n\n const value = (plainObject as Record<string, unknown>)[key];\n\n if (propertyOptions.passthrough === true) {\n data[key] = value;\n continue;\n }\n\n const isOptional = propertyOptions.optional === true;\n\n if (!(key in plainObject) || value == null) {\n if (skipMissing) {\n continue;\n }\n\n let valueToSet = value;\n\n if (!skipDefaults && propertyOptions.default !== undefined) {\n valueToSet =\n typeof propertyOptions.default === 'function'\n ? await propertyOptions.default()\n : propertyOptions.default;\n }\n\n if (!isOptional && valueToSet == null) {\n hardProblems.push(\n new Problem({\n property: key,\n message:\n 'Required property is missing, null or undefined from input',\n }),\n );\n }\n data[key] = valueToSet;\n continue;\n }\n\n try {\n const deserializeContext: PropertyDeserializeContext = {\n propertyName: key,\n rawObject: plainObject as Record<string, unknown>,\n };\n // Only pass strict to nested deserialization, not skipDefaults/skipMissing\n data[key] = await this.deserializeValue(\n value,\n propertyOptions,\n { strict },\n deserializeContext,\n );\n } catch (error) {\n if (error instanceof ValidationError) {\n const isWrapperProperty = wrapperPropertyName === key;\n if (isWrapperProperty) {\n hardProblems.push(...error.problems);\n } else {\n const problems = prependPropertyPath(key, error.problems);\n hardProblems.push(...problems);\n }\n } else if (error instanceof Error) {\n hardProblems.push(\n new Problem({\n property: wrapperPropertyName === key ? '' : key,\n message: error.message,\n }),\n );\n } else {\n throw error;\n }\n }\n }\n\n return { data, hardProblems, entityClass };\n }\n\n /**\n * Deserializes a plain object to an entity instance\n *\n * @param entityClass - The entity class constructor. Must accept a data object parameter.\n * @param plainObject - The plain object to deserialize\n * @param parseOptions - Parse options (strict mode)\n * @returns Promise resolving to a new instance of the entity with deserialized values\n *\n * @remarks\n * Deserialization rules:\n * - All @Property() decorators must include type metadata for parse() to work\n * - Properties without type metadata will throw an error\n * - Required properties (optional !== true) must be present and not null/undefined\n * - Optional properties (optional === true) can be undefined or null\n * - Arrays are supported with the array: true option\n * - Nested entities are recursively deserialized\n * - Type conversion is strict (no coercion)\n * - Entity constructors must accept a required data parameter\n *\n * Validation behavior:\n * - If strict: true - both HARD and SOFT problems throw ValidationError\n * - If strict: false (default) - HARD problems throw ValidationError, SOFT problems stored\n * - Property validators run first, then entity validators\n * - Validators can be synchronous or asynchronous\n * - Problems are accessible via EntityUtils.getProblems()\n * - Raw input data is accessible via EntityUtils.getRawInput()\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => Number }) age!: number;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const json = { name: 'John', age: 30 };\n * const user = await EntityUtils.parse(User, json);\n * const userStrict = await EntityUtils.parse(User, json, { strict: true });\n * ```\n */\n static async parse<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n parseOptions: ParseOptions = {},\n ): Promise<T> {\n const strict = parseOptions?.strict ?? false;\n\n const {\n data,\n hardProblems,\n entityClass: resolvedEntityClass,\n } = await this._parseInternal(entityClass, plainObject, { strict });\n\n if (hardProblems.length > 0) {\n throw new ValidationError(hardProblems);\n }\n\n await this.addInjectedDependencies(data, resolvedEntityClass.prototype);\n\n const instance = new resolvedEntityClass(data);\n\n rawInputStorage.set(instance, plainObject as Record<string, unknown>);\n\n const problems = await this.validate(instance);\n\n if (problems.length > 0 && strict) {\n throw new ValidationError(problems);\n }\n\n return instance;\n }\n\n /**\n * Safely deserializes a plain object to an entity instance without throwing errors\n *\n * @param entityClass - The entity class constructor. Must accept a data object parameter.\n * @param plainObject - The plain object to deserialize\n * @param parseOptions - Parse options (strict mode)\n * @returns Promise resolving to a result object with success flag, data, and problems\n *\n * @remarks\n * Similar to parse() but returns a result object instead of throwing errors:\n * - On success with strict: true - returns { success: true, data, problems: [] }\n * - On success with strict: false - returns { success: true, data, problems: [...] } (may include soft problems)\n * - On failure - returns { success: false, data: undefined, problems: [...] }\n *\n * All deserialization and validation rules from parse() apply.\n * See parse() documentation for detailed deserialization behavior.\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => Number }) age!: number;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const result = await EntityUtils.safeParse(User, { name: 'John', age: 30 });\n * if (result.success) {\n * console.log(result.data); // User instance\n * console.log(result.problems); // [] or soft problems if not strict\n * } else {\n * console.log(result.problems); // Hard problems\n * }\n * ```\n */\n static async safeParse<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n parseOptions?: ParseOptions,\n ): SafeOperationResult<T> {\n try {\n const data = await this.parse(entityClass, plainObject, parseOptions);\n const problems = this.getProblems(data);\n\n return {\n success: true,\n data,\n problems,\n };\n } catch (error) {\n if (error instanceof ValidationError) {\n return {\n success: false,\n data: undefined,\n problems: error.problems,\n };\n }\n throw error;\n }\n }\n\n /**\n * Partially deserializes a plain object, returning a plain object with only present properties\n *\n * @param entityClass - The entity class constructor\n * @param plainObject - The plain object to deserialize\n * @param options - Options with strict mode\n * @returns Promise resolving to a plain object with deserialized properties (Partial<T>)\n *\n * @remarks\n * Differences from parse():\n * - Returns a plain object, not an entity instance\n * - Ignores missing properties (does not include them in result)\n * - Does NOT apply default values to missing properties\n * - When strict: false (default), properties with HARD problems are excluded from result but problems are tracked\n * - When strict: true, any HARD problem throws ValidationError\n * - Nested entities/arrays are still fully deserialized and validated as normal\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => Number, default: 0 }) age!: number;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const partial = await EntityUtils.partialParse(User, { name: 'John' });\n * // partial = { name: 'John' } (age is not included, default not applied)\n *\n * const partialWithError = await EntityUtils.partialParse(User, { name: 'John', age: 'invalid' });\n * // partialWithError = { name: 'John' } (age excluded due to HARD problem)\n * // Access problems via second return value\n * ```\n */\n static async partialParse<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n options: { strict?: boolean } = {},\n ): Promise<Partial<T>> {\n const result = await this.safePartialParse(\n entityClass,\n plainObject,\n options,\n );\n\n if (!result.success) {\n throw new ValidationError(result.problems);\n }\n\n return result.data;\n }\n\n /**\n * Safely performs partial deserialization without throwing errors\n *\n * @param entityClass - The entity class constructor\n * @param plainObject - The plain object to deserialize\n * @param options - Options with strict mode\n * @returns Promise resolving to a result object with success flag, partial data, and problems\n *\n * @remarks\n * Similar to partialParse() but returns a result object instead of throwing errors:\n * - On success with strict: true - returns { success: true, data: Partial<T>, problems: [] }\n * - On success with strict: false - returns { success: true, data: Partial<T>, problems: [...] } (includes hard problems for excluded properties)\n * - On failure (strict mode only) - returns { success: false, data: undefined, problems: [...] }\n *\n * All partial deserialization rules from partialParse() apply.\n * See partialParse() documentation for detailed behavior.\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => Number }) age!: number;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const result = await EntityUtils.safePartialParse(User, { name: 'John', age: 'invalid' });\n * if (result.success) {\n * console.log(result.data); // { name: 'John' }\n * console.log(result.problems); // [Problem for age property]\n * } else {\n * console.log(result.problems); // Hard problems (only in strict mode)\n * }\n * ```\n */\n static async safePartialParse<T extends object>(\n entityClass: new (data: any) => T,\n plainObject: unknown,\n options?: { strict?: boolean },\n ): Promise<SafeOperationResult<Partial<T>>> {\n const strict = options?.strict ?? false;\n\n const { data, hardProblems } = await this._parseInternal(\n entityClass,\n plainObject,\n { strict, skipDefaults: true, skipMissing: true },\n );\n\n if (strict && hardProblems.length > 0) {\n return {\n success: false,\n data: undefined,\n problems: hardProblems,\n };\n }\n\n const propertyProblems = await this.validateProperties(\n data,\n entityClass.prototype,\n );\n const validationProblems = [...hardProblems, ...propertyProblems];\n\n if (strict && propertyProblems.length > 0) {\n return {\n success: false,\n data: undefined,\n problems: validationProblems,\n };\n }\n\n this.setProblems(data, validationProblems);\n\n return {\n success: true,\n data: data as Partial<T>,\n problems: validationProblems,\n };\n }\n\n /**\n * Updates an entity instance with new values, respecting preventUpdates flags on properties\n *\n * @param instance - The entity instance to update. Must be an Entity.\n * @param updates - Partial object with properties to update\n * @param options - Update options (strict mode)\n * @returns Promise resolving to a new instance with updated values\n *\n * @remarks\n * Update behavior:\n * - Creates a shallow copy of the instance\n * - For each @Property(), copies the value from updates if it exists\n * - Properties with preventUpdates: true will not be copied from updates\n * - Runs entity validators after applying updates\n * - Throws ValidationError if validation fails and strict: true\n * - Soft problems are stored on the instance if strict: false (default)\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n * @Property({ type: () => String, preventUpdates: true }) id!: string;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const user = new User({ id: '123', name: 'John' });\n * const updated = await EntityUtils.update(user, { id: '456', name: 'Jane' });\n * // updated.id === '123' (not updated due to preventUpdates: true)\n * // updated.name === 'Jane'\n * ```\n */\n static async update<T extends object>(\n instance: T,\n updates: Partial<T>,\n options?: { strict?: boolean },\n ): Promise<T> {\n if (!this.isEntity(instance)) {\n throw new Error('Cannot update non-entity instance');\n }\n\n const strict = options?.strict ?? false;\n const Constructor = Object.getPrototypeOf(instance).constructor;\n const keys = this.getPropertyKeys(instance);\n const data: Record<string, unknown> = {};\n\n // Copy existing properties\n for (const key of keys) {\n const value = (instance as any)[key];\n data[key] = value;\n }\n\n // Apply updates, respecting preventUpdates flag\n // Properties with an `undefined` value in the updates object are ignored;\n // use `null` to explicitly clear a property.\n for (const key of keys) {\n if (key in updates) {\n const updateValue = (updates as any)[key];\n if (updateValue === undefined) {\n continue;\n }\n const propertyOptions = this.getPropertyOptions(instance, key);\n if (propertyOptions && propertyOptions.preventUpdates === true) {\n // Skip updating this property\n continue;\n }\n data[key] = updateValue;\n }\n }\n\n const newInstance = new Constructor(data);\n\n const problems = await this.validate(newInstance);\n\n if (problems.length > 0 && strict) {\n throw new ValidationError(problems);\n }\n\n return newInstance;\n }\n\n /**\n * Safely updates an entity instance without throwing errors\n *\n * @param instance - The entity instance to update. Must be an Entity.\n * @param updates - Partial object with properties to update\n * @param options - Update options (strict mode)\n * @returns Promise resolving to a result object with success flag, data, and problems\n *\n * @remarks\n * Similar to update() but returns a result object instead of throwing errors:\n * - On success with strict: true - returns { success: true, data, problems: [] }\n * - On success with strict: false - returns { success: true, data, problems: [...] } (may include soft problems)\n * - On failure - returns { success: false, data: undefined, problems: [...] }\n *\n * All update and validation rules from update() apply.\n * See update() documentation for detailed update behavior.\n *\n * @example\n * ```typescript\n * @Entity()\n * class User {\n * @Property({ type: () => String }) name!: string;\n *\n * constructor(data: Partial<User>) {\n * Object.assign(this, data);\n * }\n * }\n *\n * const user = new User({ name: 'John' });\n * const result = await EntityUtils.safeUpdate(user, { name: 'Jane' });\n * if (result.success) {\n * console.log(result.data); // Updated User instance\n * console.log(result.problems); // [] or soft problems if not strict\n * } else {\n * console.log(result.problems); // Hard problems\n * }\n * ```\n */\n static async safeUpdate<T extends object>(\n instance: T,\n updates: Partial<T>,\n options?: { strict?: boolean },\n ): SafeOperationResult<T> {\n try {\n const updatedInstance = await this.update(instance, updates, options);\n const problems = this.getProblems(updatedInstance);\n\n return {\n success: true,\n data: updatedInstance,\n problems,\n };\n } catch (error) {\n if (error instanceof ValidationError) {\n return {\n success: false,\n data: undefined,\n problems: error.problems,\n };\n }\n throw error;\n }\n }\n\n /**\n * Deserializes a single value according to the type metadata\n * @private\n */\n private static async deserializeValue(\n value: unknown,\n options: PropertyOptions,\n parseOptions: ParseOptions,\n context?: PropertyDeserializeContext,\n ): Promise<unknown> {\n const isArray = options.array === true;\n const isSparse = options.sparse === true;\n const isDiscriminated = options.discriminated === true;\n\n if (isArray) {\n if (!Array.isArray(value)) {\n throw createValidationError(\n `Expects an array but received ${typeof value}`,\n );\n }\n\n const arrayProblems: Problem[] = [];\n const result: unknown[] = [];\n\n for (let index = 0; index < value.length; index++) {\n const item = value[index];\n if (item === null || item === undefined) {\n if (!isSparse) {\n arrayProblems.push(\n new Problem({\n property: `[${index}]`,\n message: 'Cannot be null or undefined.',\n }),\n );\n }\n result.push(item);\n } else {\n try {\n if (options.deserialize) {\n result.push(options.deserialize(item, context!));\n } else if (isDiscriminated) {\n result.push(\n await this.deserializeDiscriminatedValue(item, options),\n );\n } else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const typeConstructor = options.type!();\n result.push(\n await this.deserializeSingleValue(\n item,\n typeConstructor,\n parseOptions,\n ),\n );\n }\n } catch (error) {\n if (error instanceof ValidationError) {\n const problems = prependArrayIndex(index, error);\n arrayProblems.push(...problems);\n } else {\n throw error;\n }\n }\n }\n }\n\n if (arrayProblems.length > 0) {\n throw new ValidationError(arrayProblems);\n }\n\n return result;\n }\n\n if (options.deserialize) {\n return options.deserialize(value, context!);\n }\n\n if (isDiscriminated) {\n return await this.deserializeDiscriminatedValue(value, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const typeConstructor = options.type!();\n return await this.deserializeSingleValue(\n value,\n typeConstructor,\n parseOptions,\n );\n }\n\n /**\n * Deserializes a single non-array value\n * Reports validation errors with empty property (caller will prepend context)\n * @private\n */\n private static async deserializeSingleValue(\n value: unknown,\n typeConstructor: any,\n parseOptions: ParseOptions,\n ): Promise<unknown> {\n if (isPrimitiveConstructor(typeConstructor)) {\n return deserializePrimitive(value, typeConstructor);\n }\n\n if (this.isEntity(typeConstructor)) {\n return await this.parse(\n typeConstructor as new (data: any) => object,\n value as Record<string, unknown>,\n parseOptions,\n );\n }\n\n throw createValidationError(\n `Has unknown type constructor. Supported types are: String, Number, Boolean, Date, BigInt, and @Entity() classes. Use passthrough: true to explicitly allow unknown types.`,\n );\n }\n\n /**\n * Deserializes a discriminated entity value by reading the discriminator and looking up the entity class\n * @private\n */\n private static async deserializeDiscriminatedValue(\n value: unknown,\n options: PropertyOptions,\n ): Promise<unknown> {\n if (value == null) {\n throw createValidationError(\n `Cannot deserialize discriminated entity from null or undefined`,\n );\n }\n\n if (typeof value !== 'object' || Array.isArray(value)) {\n throw createValidationError(\n `Discriminated entity must be an object, received ${typeof value}`,\n );\n }\n\n const discriminatorProperty = options.discriminatorProperty;\n ok(discriminatorProperty, 'Discriminator property must be defined');\n\n const discriminatorValue = (value as Record<string, unknown>)[\n discriminatorProperty\n ];\n\n if (\n typeof discriminatorValue !== 'string' ||\n discriminatorValue.trim() === ''\n ) {\n throw createValidationError(\n `Missing or invalid discriminator property '${discriminatorProperty}'. Expected a non-empty string.`,\n );\n }\n\n const entityClass = EntityRegistry.get(discriminatorValue);\n\n if (!entityClass) {\n throw createValidationError(\n `Unknown entity type '${discriminatorValue}'. No entity registered with this name.`,\n );\n }\n\n return await this.parse(\n entityClass as new (data: any) => object,\n value as Record<string, unknown>,\n {},\n );\n }\n\n /**\n * Validates a property value by running validators and nested entity validation.\n * Prepends the property path to all returned problems.\n * @private\n */\n private static async validatePropertyValue(\n propertyPath: string,\n value: unknown,\n validators: PropertyOptions['validators'],\n ): Promise<Problem[]> {\n const problems: Problem[] = [];\n\n if (validators) {\n for (const validator of validators) {\n const validatorProblems = await validator({ value });\n if (validatorProblems.length > 0) {\n const prepended = prependPropertyPath(\n propertyPath,\n validatorProblems,\n );\n problems.push(...prepended);\n }\n }\n }\n\n if (EntityUtils.isEntity(value)) {\n const existingProblems = problemsStorage.get(value);\n const nestedProblems =\n existingProblems && existingProblems.length > 0\n ? existingProblems\n : await EntityUtils.validate(value);\n\n if (nestedProblems.length > 0) {\n const prepended = prependPropertyPath(propertyPath, nestedProblems);\n problems.push(...prepended);\n }\n }\n\n return problems;\n }\n\n /**\n * Checks if an array contains any entity elements\n * @private\n */\n private static hasEntityElements(value: unknown): boolean {\n if (!Array.isArray(value)) {\n return false;\n }\n return value.some((element) => this.isEntity(element));\n }\n\n /**\n * Runs property validators for a given property value\n * @private\n */\n private static async runPropertyValidators(\n key: string,\n value: unknown,\n options: PropertyOptions,\n ): Promise<Problem[]> {\n const problems: Problem[] = [];\n const isArray = options?.array === true;\n const isPassthrough = options?.passthrough === true;\n\n if (isPassthrough || !isArray) {\n const valueProblems = await this.validatePropertyValue(\n key,\n value,\n options.validators,\n );\n problems.push(...valueProblems);\n } else {\n ok(Array.isArray(value), 'Value must be an array for array property');\n\n const arrayValidators = options.arrayValidators || [];\n for (const validator of arrayValidators) {\n const validatorProblems = await validator({ value });\n if (validatorProblems.length > 0) {\n const prepended = prependPropertyPath(key, validatorProblems);\n problems.push(...prepended);\n }\n }\n\n const validators = options.validators || [];\n if (validators.length > 0 || this.hasEntityElements(value)) {\n for (let i = 0; i < value.length; i++) {\n const element = value[i];\n if (element !== null && element !== undefined) {\n const elementPath = `${key}[${i}]`;\n const elementProblems = await this.validatePropertyValue(\n elementPath,\n element,\n validators,\n );\n problems.push(...elementProblems);\n }\n }\n }\n }\n\n return problems;\n }\n\n /**\n * Validates all properties on an object (entity instance or plain object)\n * @private\n */\n private static async validateProperties(\n dataOrInstance: Record<string, unknown> | object,\n prototype: object,\n ): Promise<Problem[]> {\n const problems: Problem[] = [];\n const keys = Object.keys(dataOrInstance);\n const wrapperProperty = this.getWrapperPropertyName(dataOrInstance);\n\n for (const key of keys) {\n const options = this.getPropertyOptions(prototype, key);\n if (options) {\n const value = (dataOrInstance as any)[key];\n if (value != null) {\n const propertyPath = wrapperProperty === key ? '' : key;\n const validationProblems = await this.runPropertyValidators(\n propertyPath,\n value,\n options,\n );\n problems.push(...validationProblems);\n }\n }\n }\n\n return problems;\n }\n\n private static async addInjectedDependencies(\n data: Record<string, unknown>,\n prototype: object,\n ): Promise<void> {\n const injectedPropertyNames = getInjectedPropertyNames(prototype);\n if (injectedPropertyNames.length === 0) {\n return;\n }\n\n const injectedPropertyOptions = getInjectedPropertyOptions(prototype);\n\n for (const propertyName of injectedPropertyNames) {\n const token = injectedPropertyOptions[propertyName];\n if (token) {\n const dependency = await EntityDI.get(token);\n data[propertyName] = dependency;\n }\n }\n }\n\n /**\n * Validates an entity instance by running all property and entity validators\n *\n * @param instance - The entity instance to validate\n * @returns Promise resolving to array of Problems found during validation (empty if valid)\n *\n * @remarks\n * - Property validators run first, then entity validators\n * - Each validator can be synchronous or asynchronous\n * - Empty array means no problems found\n *\n * @example\n * ```typescript\n * const user = new User({ name: '', age: -5 });\n * const problems = await EntityUtils.validate(user);\n * console.log(problems); // [Problem, Problem, ...]\n * ```\n */\n static async validate<T extends object>(instance: T): Promise<Problem[]> {\n if (!this.isEntity(instance)) {\n throw new Error('Cannot validate non-entity instance');\n }\n\n const problems: Problem[] = [];\n\n const propertyProblems = await this.validateProperties(instance, instance);\n problems.push(...propertyProblems);\n\n const entityValidators = this.getEntityValidators(instance);\n for (const validatorMethod of entityValidators) {\n const validatorProblems = await (instance as any)[validatorMethod]();\n if (Array.isArray(validatorProblems)) {\n problems.push(...validatorProblems);\n }\n }\n\n EntityUtils.setProblems(instance, problems);\n\n return problems;\n }\n\n /**\n * Gets the validation problems for an entity instance\n *\n * @param instance - The entity instance\n * @returns Array of Problems (empty if no problems or instance not parsed)\n *\n * @remarks\n * - Only returns problems from the last parse() call\n * - Returns empty array if instance was not created via parse()\n * - Returns empty array if parse() was called with strict: true\n *\n * @example\n * ```typescript\n * const user = EntityUtils.parse(User, data);\n * const problems = EntityUtils.getProblems(user);\n * console.log(problems); // [Problem, ...]\n * ```\n */\n static getProblems<T extends object>(instance: T): Problem[] {\n return problemsStorage.get(instance) || [];\n }\n\n /**\n * Sets the validation problems for an entity instance\n *\n * @param instance - The entity instance\n * @param problems - Array of Problems to associate with the instance\n *\n * @remarks\n * - Overwrites any existing problems for the instance\n * - Pass an empty array to clear problems\n *\n * @example\n * ```typescript\n * const user = new User({ name: 'John' });\n * EntityUtils.setProblems(user, [new Problem({ property: 'name', message: 'Invalid name' })]);\n * ```\n */\n static setProblems<T extends object>(instance: T, problems: Problem[]): void {\n if (problems.length === 0) {\n problemsStorage.delete(instance);\n } else {\n problemsStorage.set(instance, problems);\n }\n }\n\n /**\n * Gets the raw input data that was used to create an entity instance\n *\n * @param instance - The entity instance\n * @returns The raw input object, or undefined if not available\n *\n * @remarks\n * - Only available for instances created via parse()\n * - Returns a reference to the original input data (not a copy)\n *\n * @example\n * ```typescript\n * const user = EntityUtils.parse(User, { name: 'John', age: 30 });\n * const rawInput = EntityUtils.getRawInput(user);\n * console.log(rawInput); // { name: 'John', age: 30 }\n * ```\n */\n static getRawInput<T extends object>(instance: T): unknown {\n return rawInputStorage.get(instance);\n }\n\n /**\n * Sets the raw input data for an entity instance\n *\n * @param instance - The entity instance\n * @param rawInput - The raw input object to associate with the instance\n *\n * @remarks\n * - Overwrites any existing raw input for the instance\n * - Pass undefined to clear the raw input\n *\n * @example\n * ```typescript\n * const user = new User({ name: 'John' });\n * EntityUtils.setRawInput(user, { name: 'John', age: 30 });\n * ```\n */\n static setRawInput<T extends object>(\n instance: T,\n rawInput: Record<string, unknown> | undefined,\n ): void {\n if (rawInput === undefined) {\n rawInputStorage.delete(instance);\n } else {\n rawInputStorage.set(instance, rawInput);\n }\n }\n\n /**\n * Gets all entity validator method names for an entity\n * @private\n */\n private static getEntityValidators(target: object): string[] {\n let currentProto: any;\n\n if (target.constructor && target === target.constructor.prototype) {\n currentProto = target;\n } else {\n currentProto = Object.getPrototypeOf(target);\n }\n\n const validators: string[] = [];\n const seen = new Set<string>();\n\n while (currentProto && currentProto !== Object.prototype) {\n const protoValidators: string[] =\n Reflect.getOwnMetadata(ENTITY_VALIDATOR_METADATA_KEY, currentProto) ||\n [];\n\n for (const validator of protoValidators) {\n if (!seen.has(validator)) {\n seen.add(validator);\n validators.push(validator);\n }\n }\n\n currentProto = Object.getPrototypeOf(currentProto);\n }\n\n return validators;\n }\n}\n"],"names":["ENTITY_METADATA_KEY","ENTITY_OPTIONS_METADATA_KEY","ENTITY_VALIDATOR_METADATA_KEY","PROPERTY_METADATA_KEY","PROPERTY_OPTIONS_METADATA_KEY","getInjectedPropertyNames","getInjectedPropertyOptions","EntityDI","isEqualWith","ValidationError","Problem","prependArrayIndex","prependPropertyPath","createValidationError","isPrimitiveConstructor","deserializePrimitive","ok","EntityRegistry","PolymorphicRegistry","problemsStorage","WeakMap","rawInputStorage","EntityUtils","isEntity","obj","Reflect","hasMetadata","Array","isArray","constructor","Object","getPrototypeOf","getEntityOptions","entityOrClass","options","getMetadata","getEntityName","undefined","name","isCollectionEntity","collection","isStringifiable","stringifiable","getWrapperPropertyName","wrapperProperty","sameEntity","a","b","getPropertyKeys","target","currentProto","prototype","keys","seen","Set","protoKeys","getOwnMetadata","key","has","add","push","getPropertyOptions","propertyKey","protoOptions","equals","val1","val2","diff","length","oldEntity","newEntity","Error","diffs","oldValue","newValue","propertyOptions","areEqual","property","changes","reduce","acc","toJSON","entity","valuePropertyOptions","array","type","String","serializeValue","value","collectionPropertyOptions","result","serializeContext","propertyName","context","passthrough","serialize","map","item","Date","toISOString","toString","serialized","discriminated","discriminatorProperty","entityClass","entityName","_parseInternal","plainObject","wrapperPropertyName","getDiscriminatorProperty","discriminatorValue","variantClass","getVariant","strict","skipDefaults","skipMissing","data","hardProblems","message","isOptional","optional","valueToSet","default","deserializeContext","rawObject","deserializeValue","error","isWrapperProperty","problems","parse","parseOptions","resolvedEntityClass","addInjectedDependencies","instance","set","validate","safeParse","getProblems","success","partialParse","safePartialParse","propertyProblems","validateProperties","validationProblems","setProblems","update","updates","Constructor","updateValue","preventUpdates","newInstance","safeUpdate","updatedInstance","isSparse","sparse","isDiscriminated","arrayProblems","index","deserialize","deserializeDiscriminatedValue","typeConstructor","deserializeSingleValue","trim","get","validatePropertyValue","propertyPath","validators","validator","validatorProblems","prepended","existingProblems","nestedProblems","hasEntityElements","some","element","runPropertyValidators","isPassthrough","valueProblems","arrayValidators","i","elementPath","elementProblems","dataOrInstance","injectedPropertyNames","injectedPropertyOptions","token","dependency","entityValidators","getEntityValidators","validatorMethod","delete","getRawInput","setRawInput","rawInput","protoValidators"],"mappings":"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"}
@@ -337,6 +337,18 @@ export declare class EntityWithCustomSerialization {
337
337
  position: CustomValue;
338
338
  });
339
339
  }
340
+ /**
341
+ * Entity to verify serialize/deserialize context is passed correctly
342
+ * Features: Context-aware serialization using propertyName and sibling values
343
+ */
344
+ export declare class EntityWithContextSerialization {
345
+ id: string;
346
+ label: string;
347
+ constructor(data: {
348
+ id: string;
349
+ label: string;
350
+ });
351
+ }
340
352
  /**
341
353
  * Custom class with equals method
342
354
  */
@@ -1 +1 @@
1
- {"version":3,"file":"test-entities.d.ts","sourceRoot":"","sources":["../../src/lib/test-entities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test-entities.d.ts","sourceRoot":"","sources":["../../src/lib/test-entities.ts"],"names":[],"mappings":"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"}
@@ -685,6 +685,31 @@ EntityWithCustomSerialization = _ts_decorate([
685
685
  Object
686
686
  ])
687
687
  ], EntityWithCustomSerialization);
688
+ export class EntityWithContextSerialization {
689
+ constructor(data){
690
+ this.id = data.id;
691
+ this.label = data.label;
692
+ }
693
+ }
694
+ _ts_decorate([
695
+ StringProperty(),
696
+ _ts_metadata("design:type", String)
697
+ ], EntityWithContextSerialization.prototype, "id", void 0);
698
+ _ts_decorate([
699
+ Property({
700
+ type: ()=>String,
701
+ serialize: (v, context)=>`${context.propertyName}:${v}:${context.entity['id']}`,
702
+ deserialize: (raw, context)=>`${raw}-from-${context.rawObject['id']}`
703
+ }),
704
+ _ts_metadata("design:type", String)
705
+ ], EntityWithContextSerialization.prototype, "label", void 0);
706
+ EntityWithContextSerialization = _ts_decorate([
707
+ Entity(),
708
+ _ts_metadata("design:type", Function),
709
+ _ts_metadata("design:paramtypes", [
710
+ Object
711
+ ])
712
+ ], EntityWithContextSerialization);
688
713
  /**
689
714
  * Custom class with equals method
690
715
  */ export class CustomPoint {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/test-entities.ts"],"sourcesContent":["import 'reflect-metadata';\nimport { z } from 'zod';\nimport {\n Entity,\n CollectionEntity,\n Stringifiable,\n EntityValidator,\n} from './entity.js';\nimport {\n Property,\n StringProperty,\n NumberProperty,\n IntProperty,\n BooleanProperty,\n DateProperty,\n BigIntProperty,\n EnumProperty,\n EntityProperty,\n ArrayProperty,\n PassthroughProperty,\n SerializableProperty,\n StringifiableProperty,\n} from './property.js';\nimport { InjectedProperty } from './injected-property.js';\nimport { ZodProperty } from './zod-property.js';\nimport { Problem } from './problem.js';\n\n// ============================================================================\n// SIMPLE ENTITIES WITH PRIMITIVES\n// ============================================================================\n\n/**\n * Basic entity with common primitive types\n * Features: String, Number, Boolean properties\n */\n@Entity()\nexport class TestUser {\n @StringProperty() name!: string;\n @NumberProperty() age!: number;\n @BooleanProperty() active!: boolean;\n\n constructor(data: { name: string; age: number; active: boolean }) {\n this.name = data.name;\n this.age = data.age;\n this.active = data.active;\n }\n}\n\n/**\n * Entity with different primitive combinations\n * Features: String, Number, Int, Date properties\n */\n@Entity()\nexport class TestProduct {\n @StringProperty() id!: string;\n @StringProperty() name!: string;\n @NumberProperty() price!: number;\n @IntProperty() quantity!: number;\n @DateProperty() createdAt!: Date;\n\n constructor(data: {\n id: string;\n name: string;\n price: number;\n quantity: number;\n createdAt: Date;\n }) {\n this.id = data.id;\n this.name = data.name;\n this.price = data.price;\n this.quantity = data.quantity;\n this.createdAt = data.createdAt;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH SPECIAL TYPES\n// ============================================================================\n\n/**\n * Entity with Date and BigInt types\n * Features: DateProperty, BigIntProperty\n */\n@Entity()\nexport class EntityWithSpecialTypes {\n @DateProperty() timestamp!: Date;\n @BigIntProperty() largeNumber!: bigint;\n @StringProperty() label!: string;\n\n constructor(data: { timestamp: Date; largeNumber: bigint; label: string }) {\n this.timestamp = data.timestamp;\n this.largeNumber = data.largeNumber;\n this.label = data.label;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH VALIDATION\n// ============================================================================\n\n/**\n * Entity with property-level validators\n * Features: String validators (minLength, maxLength, pattern)\n */\n@Entity()\nexport class ValidatedEntity {\n @StringProperty({\n minLength: 3,\n maxLength: 20,\n })\n username!: string;\n\n @StringProperty({\n pattern: /^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$/i,\n })\n email!: string;\n\n @NumberProperty({ min: 0, max: 150 })\n age!: number;\n\n constructor(data: { username: string; email: string; age: number }) {\n this.username = data.username;\n this.email = data.email;\n this.age = data.age;\n }\n}\n\n/**\n * Entity with cross-property validation\n * Features: @EntityValidator decorator\n */\n@Entity()\nexport class CrossValidatedEntity {\n @StringProperty() password!: string;\n @StringProperty() confirmPassword!: string;\n @DateProperty() startDate!: Date;\n @DateProperty() endDate!: Date;\n\n constructor(data: {\n password: string;\n confirmPassword: string;\n startDate: Date;\n endDate: Date;\n }) {\n this.password = data.password;\n this.confirmPassword = data.confirmPassword;\n this.startDate = data.startDate;\n this.endDate = data.endDate;\n }\n\n @EntityValidator()\n validatePasswords(): Problem[] {\n if (this.password !== this.confirmPassword) {\n return [\n new Problem({\n property: 'confirmPassword',\n message: 'Passwords do not match',\n }),\n ];\n }\n return [];\n }\n\n @EntityValidator()\n validateDates(): Problem[] {\n if (this.startDate >= this.endDate) {\n return [\n new Problem({\n property: 'endDate',\n message: 'End date must be after start date',\n }),\n ];\n }\n return [];\n }\n}\n\n// ============================================================================\n// ENTITIES WITH OPTIONAL/REQUIRED FIELDS\n// ============================================================================\n\n/**\n * Entity with mix of optional and required properties\n * Features: optional flag\n */\n@Entity()\nexport class OptionalFieldsEntity {\n @StringProperty() requiredField!: string;\n @StringProperty({ optional: true }) optionalField?: string;\n @NumberProperty({ optional: true }) optionalNumber?: number;\n @BooleanProperty() requiredBoolean!: boolean;\n\n constructor(data: {\n requiredField: string;\n optionalField?: string;\n optionalNumber?: number;\n requiredBoolean: boolean;\n }) {\n this.requiredField = data.requiredField;\n this.optionalField = data.optionalField;\n this.optionalNumber = data.optionalNumber;\n this.requiredBoolean = data.requiredBoolean;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH DEFAULT VALUES\n// ============================================================================\n\nlet factoryCallCount = 0;\n\n/**\n * Entity with various default value strategies\n * Features: Static defaults, factory defaults, async factory defaults\n */\n@Entity()\nexport class EntityWithDefaults {\n @StringProperty({ default: 'default-name' })\n name!: string;\n\n @NumberProperty({ default: () => factoryCallCount++ })\n counter!: number;\n\n @DateProperty({ default: () => new Date('2025-01-01') })\n timestamp!: Date;\n\n @StringProperty({ default: async () => 'async-value' })\n asyncField!: string;\n\n @BooleanProperty({ default: true })\n enabled!: boolean;\n\n constructor(data: {\n name?: string;\n counter?: number;\n timestamp?: Date;\n asyncField?: string;\n enabled?: boolean;\n }) {\n this.name = data.name!;\n this.counter = data.counter!;\n this.timestamp = data.timestamp!;\n this.asyncField = data.asyncField!;\n this.enabled = data.enabled!;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH ARRAYS\n// ============================================================================\n\n/**\n * Entity with various array configurations\n * Features: Regular arrays, sparse arrays, array validators\n */\n@Entity()\nexport class EntityWithArrays {\n @ArrayProperty(() => String)\n tags!: string[];\n\n @ArrayProperty(() => Number, {\n minLength: 1,\n maxLength: 5,\n })\n ratings!: number[];\n\n @ArrayProperty(() => String, { sparse: true })\n sparseArray!: (string | null | undefined)[];\n\n @ArrayProperty(() => TestUser)\n users!: TestUser[];\n\n constructor(data: {\n tags: string[];\n ratings: number[];\n sparseArray: (string | null | undefined)[];\n users: TestUser[];\n }) {\n this.tags = data.tags;\n this.ratings = data.ratings;\n this.sparseArray = data.sparseArray;\n this.users = data.users;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH ENUMS\n// ============================================================================\n\nexport enum UserRole {\n ADMIN = 'admin',\n USER = 'user',\n GUEST = 'guest',\n}\n\nexport enum ProductStatus {\n DRAFT = 'draft',\n PUBLISHED = 'published',\n ARCHIVED = 'archived',\n}\n\n/**\n * Entity with enum properties\n * Features: EnumProperty decorator\n */\n@Entity()\nexport class EntityWithEnum {\n @StringProperty() name!: string;\n @EnumProperty(UserRole) role!: UserRole;\n @EnumProperty(ProductStatus) status!: ProductStatus;\n\n constructor(data: { name: string; role: UserRole; status: ProductStatus }) {\n this.name = data.name;\n this.role = data.role;\n this.status = data.status;\n }\n}\n\n// ============================================================================\n// NESTED ENTITIES (2-3 LEVELS)\n// ============================================================================\n\n/**\n * Level 1: Simple address entity\n * Features: Basic nested entity\n */\n@Entity()\nexport class TestAddress {\n @StringProperty() street!: string;\n @StringProperty() city!: string;\n @StringProperty() country!: string;\n @IntProperty() zipCode!: number;\n\n constructor(data: {\n street: string;\n city: string;\n country: string;\n zipCode: number;\n }) {\n this.street = data.street;\n this.city = data.city;\n this.country = data.country;\n this.zipCode = data.zipCode;\n }\n}\n\n/**\n * Level 2: Company with nested address\n * Features: 1-level nesting\n */\n@Entity()\nexport class TestCompany {\n @StringProperty() name!: string;\n @EntityProperty(() => TestAddress) address!: TestAddress;\n @IntProperty() employeeCount!: number;\n\n constructor(data: {\n name: string;\n address: TestAddress;\n employeeCount: number;\n }) {\n this.name = data.name;\n this.address = data.address;\n this.employeeCount = data.employeeCount;\n }\n}\n\n/**\n * Level 3: Employee with nested company (which has nested address)\n * Features: 2-level nesting\n */\n@Entity()\nexport class TestEmployee {\n @StringProperty() name!: string;\n @StringProperty() email!: string;\n @EntityProperty(() => TestCompany) company!: TestCompany;\n @NumberProperty() salary!: number;\n @DateProperty() hireDate!: Date;\n\n constructor(data: {\n name: string;\n email: string;\n company: TestCompany;\n salary: number;\n hireDate: Date;\n }) {\n this.name = data.name;\n this.email = data.email;\n this.company = data.company;\n this.salary = data.salary;\n this.hireDate = data.hireDate;\n }\n}\n\n/**\n * Entity with optional nested entities\n * Features: Optional nested entities\n */\n@Entity()\nexport class EntityWithOptionalNested {\n @StringProperty() id!: string;\n @EntityProperty(() => TestAddress, { optional: true })\n billingAddress?: TestAddress;\n @EntityProperty(() => TestAddress, { optional: true })\n shippingAddress?: TestAddress;\n\n constructor(data: {\n id: string;\n billingAddress?: TestAddress;\n shippingAddress?: TestAddress;\n }) {\n this.id = data.id;\n this.billingAddress = data.billingAddress;\n this.shippingAddress = data.shippingAddress;\n }\n}\n\n// ============================================================================\n// COLLECTION ENTITIES\n// ============================================================================\n\n/**\n * Collection entity wrapping string array\n * Features: @CollectionEntity decorator, unwraps to array\n */\n@CollectionEntity()\nexport class TestTags {\n @ArrayProperty(() => String)\n readonly collection: string[];\n\n constructor(data: { collection: string[] }) {\n this.collection = data.collection;\n }\n}\n\n/**\n * Collection entity wrapping number array\n * Features: @CollectionEntity with numbers\n */\n@CollectionEntity()\nexport class TestIdList {\n @ArrayProperty(() => Number)\n readonly collection: number[];\n\n constructor(data: { collection: number[] }) {\n this.collection = data.collection;\n }\n}\n\n/**\n * Collection entity with entity items\n * Features: @CollectionEntity with nested entities\n */\n@CollectionEntity()\nexport class TestUserCollection {\n @ArrayProperty(() => TestUser)\n readonly collection: TestUser[];\n\n constructor(data: { collection: TestUser[] }) {\n this.collection = data.collection;\n }\n}\n\n// ============================================================================\n// STRINGIFIABLE ENTITIES\n// ============================================================================\n\n/**\n * Stringifiable entity for user IDs\n * Features: @Stringifiable decorator, unwraps to string\n */\n@Stringifiable()\nexport class TestUserId {\n @StringProperty() readonly value: string;\n\n constructor(data: { value: string }) {\n this.value = data.value;\n }\n}\n\n/**\n * Stringifiable entity for emails with validation\n * Features: @Stringifiable with validation\n */\n@Stringifiable()\nexport class TestEmail {\n @StringProperty({\n pattern: /^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$/i,\n })\n readonly value: string;\n\n constructor(data: { value: string }) {\n this.value = data.value;\n }\n}\n\n/**\n * Entity using stringifiable properties\n * Features: Properties that are stringifiable entities\n */\n@Entity()\nexport class EntityWithStringifiable {\n @EntityProperty(() => TestUserId) userId!: TestUserId;\n @EntityProperty(() => TestEmail) email!: TestEmail;\n @StringProperty() name!: string;\n\n constructor(data: { userId: TestUserId; email: TestEmail; name: string }) {\n this.userId = data.userId;\n this.email = data.email;\n this.name = data.name;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH DEPENDENCY INJECTION\n// ============================================================================\n\nexport interface ILogger {\n log(message: string): void;\n}\n\nexport const LOGGER_TOKEN = Symbol('Logger');\n\n/**\n * Entity with injected properties\n * Features: @InjectedProperty decorator\n */\n@Entity()\nexport class EntityWithDI {\n @StringProperty() name!: string;\n @InjectedProperty(LOGGER_TOKEN) logger!: ILogger;\n\n constructor(data: { name: string; logger?: ILogger }) {\n this.name = data.name;\n if (data.logger) {\n this.logger = data.logger;\n }\n }\n\n logName(): void {\n this.logger.log(`Name is: ${this.name}`);\n }\n}\n\n// ============================================================================\n// ENTITIES WITH PASSTHROUGH\n// ============================================================================\n\n/**\n * Entity with passthrough properties\n * Features: @PassthroughProperty for unknown types\n */\n@Entity()\nexport class EntityWithPassthrough {\n @StringProperty() id!: string;\n @PassthroughProperty() metadata!: Record<string, unknown>;\n @PassthroughProperty() config!: unknown;\n\n constructor(data: {\n id: string;\n metadata: Record<string, unknown>;\n config: unknown;\n }) {\n this.id = data.id;\n this.metadata = data.metadata;\n this.config = data.config;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH CUSTOM SERIALIZATION\n// ============================================================================\n\n/**\n * Custom serializable class\n */\nexport class CustomValue {\n constructor(\n public x: number,\n public y: number,\n ) {}\n\n toData() {\n return { x: this.x, y: this.y };\n }\n\n static fromData(data: { x: number; y: number }): CustomValue {\n return new CustomValue(data.x, data.y);\n }\n}\n\n/**\n * Entity with custom serialize/deserialize\n * Features: Custom serialization functions\n */\n@Entity()\nexport class EntityWithCustomSerialization {\n @StringProperty() name!: string;\n\n @Property({\n type: () => CustomValue,\n serialize: (v: CustomValue) => v.toData(),\n deserialize: (d: unknown) =>\n CustomValue.fromData(d as { x: number; y: number }),\n })\n position!: CustomValue;\n\n constructor(data: { name: string; position: CustomValue }) {\n this.name = data.name;\n this.position = data.position;\n }\n}\n\n/**\n * Custom class with equals method\n */\nexport class CustomPoint {\n constructor(\n public x: number,\n public y: number,\n ) {}\n\n equals(other: CustomPoint): boolean {\n return this.x === other.x && this.y === other.y;\n }\n\n toString(): string {\n return `${this.x},${this.y}`;\n }\n\n static fromString(str: string): CustomPoint {\n const [x, y] = str.split(',').map(Number);\n return new CustomPoint(x, y);\n }\n}\n\n/**\n * Entity with custom equals function\n * Features: Custom equality comparison\n */\n@Entity()\nexport class EntityWithCustomEquals {\n @StringProperty() id!: string;\n\n @Property({\n type: () => CustomPoint,\n serialize: (v: CustomPoint) => v.toString(),\n deserialize: (d: unknown) => CustomPoint.fromString(d as string),\n equals: (a: CustomPoint, b: CustomPoint) => a.equals(b),\n })\n location!: CustomPoint;\n\n constructor(data: { id: string; location: CustomPoint }) {\n this.id = data.id;\n this.location = data.location;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH SERIALIZABLE/PARSEABLE PROPERTIES\n// ============================================================================\n\n/**\n * Custom class implementing Serializable interface\n */\nexport class SerializableValue {\n constructor(public data: string) {}\n\n toJSON(): string {\n return this.data;\n }\n\n equals(other: SerializableValue): boolean {\n return this.data === other.data;\n }\n\n static parse(json: unknown): SerializableValue {\n return new SerializableValue(json as string);\n }\n}\n\n/**\n * Entity using SerializableProperty\n * Features: @SerializableProperty decorator\n */\n@Entity()\nexport class EntityWithSerializable {\n @StringProperty() name!: string;\n @SerializableProperty(() => SerializableValue)\n value!: SerializableValue;\n\n constructor(data: { name: string; value: SerializableValue }) {\n this.name = data.name;\n this.value = data.value;\n }\n}\n\n/**\n * Custom class implementing Parseable interface\n */\nexport class ParseableValue {\n constructor(public data: number) {}\n\n toString(): string {\n return String(this.data);\n }\n\n equals(other: ParseableValue): boolean {\n return this.data === other.data;\n }\n\n static parse(str: string): ParseableValue {\n return new ParseableValue(Number(str));\n }\n}\n\n/**\n * Entity using StringifiableProperty\n * Features: @StringifiableProperty decorator\n */\n@Entity()\nexport class EntityWithParseable {\n @StringProperty() label!: string;\n @StringifiableProperty(() => ParseableValue)\n value!: ParseableValue;\n\n constructor(data: { label: string; value: ParseableValue }) {\n this.label = data.label;\n this.value = data.value;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH ZOD VALIDATION\n// ============================================================================\n\nconst emailSchema = z.string().email();\nconst positiveIntSchema = z.number().int().positive();\n\n/**\n * Entity with Zod validation\n * Features: @ZodProperty decorator\n */\n@Entity()\nexport class EntityWithZod {\n @ZodProperty(z.string().min(3).max(20))\n username!: string;\n\n @ZodProperty(emailSchema)\n email!: string;\n\n @ZodProperty(positiveIntSchema)\n count!: number;\n\n constructor(data: { username: string; email: string; count: number }) {\n this.username = data.username;\n this.email = data.email;\n this.count = data.count;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH IMMUTABLE PROPERTIES\n// ============================================================================\n\n/**\n * Entity with immutable (preventUpdates) properties\n * Features: preventUpdates flag\n */\n@Entity()\nexport class EntityWithImmutable {\n @StringProperty({ preventUpdates: true })\n readonly id: string;\n\n @StringProperty() name!: string;\n\n @DateProperty({ preventUpdates: true })\n readonly createdAt: Date;\n\n @NumberProperty() value!: number;\n\n constructor(data: {\n id: string;\n name: string;\n createdAt: Date;\n value: number;\n }) {\n this.id = data.id;\n this.name = data.name;\n this.createdAt = data.createdAt;\n this.value = data.value;\n }\n}\n\n// ============================================================================\n// COMPLEX ENTITY (COMBINING MULTIPLE FEATURES)\n// ============================================================================\n\n/**\n * Complex entity combining multiple features\n * Features: All common features in one entity\n * - Primitives, enums, nested entities, arrays\n * - Optional fields, defaults, validation\n * - Custom serialization, stringifiable properties\n */\n@Entity()\nexport class ComplexEntity {\n @StringProperty({ preventUpdates: true })\n readonly id: string;\n\n @StringProperty({ minLength: 2, maxLength: 50 })\n name!: string;\n\n @EnumProperty(UserRole)\n role!: UserRole;\n\n @EntityProperty(() => TestUserId)\n userId!: TestUserId;\n\n @EntityProperty(() => TestAddress)\n address!: TestAddress;\n\n @ArrayProperty(() => String, { minLength: 0, maxLength: 10 })\n tags!: string[];\n\n @ArrayProperty(() => TestProduct)\n products!: TestProduct[];\n\n @NumberProperty({ optional: true, min: 0 })\n score?: number;\n\n @DateProperty({ default: () => new Date() })\n createdAt!: Date;\n\n @DateProperty({ optional: true })\n updatedAt?: Date;\n\n @BooleanProperty({ default: true })\n active!: boolean;\n\n @PassthroughProperty()\n metadata!: Record<string, unknown>;\n\n constructor(data: {\n id: string;\n name: string;\n role: UserRole;\n userId: TestUserId;\n address: TestAddress;\n tags: string[];\n products: TestProduct[];\n score?: number;\n createdAt?: Date;\n updatedAt?: Date;\n active?: boolean;\n metadata: Record<string, unknown>;\n }) {\n this.id = data.id;\n this.name = data.name;\n this.role = data.role;\n this.userId = data.userId;\n this.address = data.address;\n this.tags = data.tags;\n this.products = data.products;\n this.score = data.score;\n this.createdAt = data.createdAt!;\n this.updatedAt = data.updatedAt;\n this.active = data.active!;\n this.metadata = data.metadata;\n }\n\n @EntityValidator()\n validateProducts(): Problem[] {\n if (this.products.length === 0 && this.active) {\n return [\n new Problem({\n property: 'products',\n message: 'Active entity must have at least one product',\n }),\n ];\n }\n return [];\n }\n}\n\n// ============================================================================\n// HELPER TO RESET FACTORY COUNTER (FOR TESTING)\n// ============================================================================\n\nexport function resetFactoryCallCount(): void {\n factoryCallCount = 0;\n}\n\n// ============================================================================\n// ENTITIES FOR parseBigInt TESTING\n// ============================================================================\n\n/**\n * Entity with NumberProperty and IntProperty configured with parseBigInt: true\n * Features: coercion from bigint / integer string to number\n */\n@Entity()\nexport class EntityWithParseBigInt {\n @NumberProperty({ parseBigInt: true }) amount!: number;\n @IntProperty({ parseBigInt: true }) count!: number;\n\n constructor(data: { amount: number; count: number }) {\n this.amount = data.amount;\n this.count = data.count;\n }\n}\n"],"names":["z","Entity","CollectionEntity","Stringifiable","EntityValidator","Property","StringProperty","NumberProperty","IntProperty","BooleanProperty","DateProperty","BigIntProperty","EnumProperty","EntityProperty","ArrayProperty","PassthroughProperty","SerializableProperty","StringifiableProperty","InjectedProperty","ZodProperty","Problem","TestUser","data","name","age","active","TestProduct","id","price","quantity","createdAt","EntityWithSpecialTypes","timestamp","largeNumber","label","ValidatedEntity","username","email","minLength","maxLength","pattern","min","max","CrossValidatedEntity","password","confirmPassword","startDate","endDate","validatePasswords","property","message","validateDates","OptionalFieldsEntity","requiredField","optionalField","optionalNumber","requiredBoolean","optional","factoryCallCount","EntityWithDefaults","counter","asyncField","enabled","default","Date","EntityWithArrays","tags","ratings","sparseArray","users","String","Number","sparse","UserRole","ProductStatus","EntityWithEnum","role","status","TestAddress","street","city","country","zipCode","TestCompany","address","employeeCount","TestEmployee","company","salary","hireDate","EntityWithOptionalNested","billingAddress","shippingAddress","TestTags","collection","TestIdList","TestUserCollection","TestUserId","value","TestEmail","EntityWithStringifiable","userId","LOGGER_TOKEN","Symbol","EntityWithDI","logger","logName","log","EntityWithPassthrough","metadata","config","CustomValue","x","y","toData","fromData","EntityWithCustomSerialization","position","type","serialize","v","deserialize","d","CustomPoint","equals","other","toString","fromString","str","split","map","EntityWithCustomEquals","location","a","b","SerializableValue","toJSON","parse","json","EntityWithSerializable","ParseableValue","EntityWithParseable","emailSchema","string","positiveIntSchema","number","int","positive","EntityWithZod","count","EntityWithImmutable","preventUpdates","ComplexEntity","products","score","updatedAt","validateProducts","length","resetFactoryCallCount","EntityWithParseBigInt","amount","parseBigInt"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/lib/test-entities.ts"],"sourcesContent":["import 'reflect-metadata';\nimport { z } from 'zod';\nimport {\n Entity,\n CollectionEntity,\n Stringifiable,\n EntityValidator,\n} from './entity.js';\nimport {\n Property,\n StringProperty,\n NumberProperty,\n IntProperty,\n BooleanProperty,\n DateProperty,\n BigIntProperty,\n EnumProperty,\n EntityProperty,\n ArrayProperty,\n PassthroughProperty,\n SerializableProperty,\n StringifiableProperty,\n} from './property.js';\nimport { InjectedProperty } from './injected-property.js';\nimport { ZodProperty } from './zod-property.js';\nimport { Problem } from './problem.js';\n\n// ============================================================================\n// SIMPLE ENTITIES WITH PRIMITIVES\n// ============================================================================\n\n/**\n * Basic entity with common primitive types\n * Features: String, Number, Boolean properties\n */\n@Entity()\nexport class TestUser {\n @StringProperty() name!: string;\n @NumberProperty() age!: number;\n @BooleanProperty() active!: boolean;\n\n constructor(data: { name: string; age: number; active: boolean }) {\n this.name = data.name;\n this.age = data.age;\n this.active = data.active;\n }\n}\n\n/**\n * Entity with different primitive combinations\n * Features: String, Number, Int, Date properties\n */\n@Entity()\nexport class TestProduct {\n @StringProperty() id!: string;\n @StringProperty() name!: string;\n @NumberProperty() price!: number;\n @IntProperty() quantity!: number;\n @DateProperty() createdAt!: Date;\n\n constructor(data: {\n id: string;\n name: string;\n price: number;\n quantity: number;\n createdAt: Date;\n }) {\n this.id = data.id;\n this.name = data.name;\n this.price = data.price;\n this.quantity = data.quantity;\n this.createdAt = data.createdAt;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH SPECIAL TYPES\n// ============================================================================\n\n/**\n * Entity with Date and BigInt types\n * Features: DateProperty, BigIntProperty\n */\n@Entity()\nexport class EntityWithSpecialTypes {\n @DateProperty() timestamp!: Date;\n @BigIntProperty() largeNumber!: bigint;\n @StringProperty() label!: string;\n\n constructor(data: { timestamp: Date; largeNumber: bigint; label: string }) {\n this.timestamp = data.timestamp;\n this.largeNumber = data.largeNumber;\n this.label = data.label;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH VALIDATION\n// ============================================================================\n\n/**\n * Entity with property-level validators\n * Features: String validators (minLength, maxLength, pattern)\n */\n@Entity()\nexport class ValidatedEntity {\n @StringProperty({\n minLength: 3,\n maxLength: 20,\n })\n username!: string;\n\n @StringProperty({\n pattern: /^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$/i,\n })\n email!: string;\n\n @NumberProperty({ min: 0, max: 150 })\n age!: number;\n\n constructor(data: { username: string; email: string; age: number }) {\n this.username = data.username;\n this.email = data.email;\n this.age = data.age;\n }\n}\n\n/**\n * Entity with cross-property validation\n * Features: @EntityValidator decorator\n */\n@Entity()\nexport class CrossValidatedEntity {\n @StringProperty() password!: string;\n @StringProperty() confirmPassword!: string;\n @DateProperty() startDate!: Date;\n @DateProperty() endDate!: Date;\n\n constructor(data: {\n password: string;\n confirmPassword: string;\n startDate: Date;\n endDate: Date;\n }) {\n this.password = data.password;\n this.confirmPassword = data.confirmPassword;\n this.startDate = data.startDate;\n this.endDate = data.endDate;\n }\n\n @EntityValidator()\n validatePasswords(): Problem[] {\n if (this.password !== this.confirmPassword) {\n return [\n new Problem({\n property: 'confirmPassword',\n message: 'Passwords do not match',\n }),\n ];\n }\n return [];\n }\n\n @EntityValidator()\n validateDates(): Problem[] {\n if (this.startDate >= this.endDate) {\n return [\n new Problem({\n property: 'endDate',\n message: 'End date must be after start date',\n }),\n ];\n }\n return [];\n }\n}\n\n// ============================================================================\n// ENTITIES WITH OPTIONAL/REQUIRED FIELDS\n// ============================================================================\n\n/**\n * Entity with mix of optional and required properties\n * Features: optional flag\n */\n@Entity()\nexport class OptionalFieldsEntity {\n @StringProperty() requiredField!: string;\n @StringProperty({ optional: true }) optionalField?: string;\n @NumberProperty({ optional: true }) optionalNumber?: number;\n @BooleanProperty() requiredBoolean!: boolean;\n\n constructor(data: {\n requiredField: string;\n optionalField?: string;\n optionalNumber?: number;\n requiredBoolean: boolean;\n }) {\n this.requiredField = data.requiredField;\n this.optionalField = data.optionalField;\n this.optionalNumber = data.optionalNumber;\n this.requiredBoolean = data.requiredBoolean;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH DEFAULT VALUES\n// ============================================================================\n\nlet factoryCallCount = 0;\n\n/**\n * Entity with various default value strategies\n * Features: Static defaults, factory defaults, async factory defaults\n */\n@Entity()\nexport class EntityWithDefaults {\n @StringProperty({ default: 'default-name' })\n name!: string;\n\n @NumberProperty({ default: () => factoryCallCount++ })\n counter!: number;\n\n @DateProperty({ default: () => new Date('2025-01-01') })\n timestamp!: Date;\n\n @StringProperty({ default: async () => 'async-value' })\n asyncField!: string;\n\n @BooleanProperty({ default: true })\n enabled!: boolean;\n\n constructor(data: {\n name?: string;\n counter?: number;\n timestamp?: Date;\n asyncField?: string;\n enabled?: boolean;\n }) {\n this.name = data.name!;\n this.counter = data.counter!;\n this.timestamp = data.timestamp!;\n this.asyncField = data.asyncField!;\n this.enabled = data.enabled!;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH ARRAYS\n// ============================================================================\n\n/**\n * Entity with various array configurations\n * Features: Regular arrays, sparse arrays, array validators\n */\n@Entity()\nexport class EntityWithArrays {\n @ArrayProperty(() => String)\n tags!: string[];\n\n @ArrayProperty(() => Number, {\n minLength: 1,\n maxLength: 5,\n })\n ratings!: number[];\n\n @ArrayProperty(() => String, { sparse: true })\n sparseArray!: (string | null | undefined)[];\n\n @ArrayProperty(() => TestUser)\n users!: TestUser[];\n\n constructor(data: {\n tags: string[];\n ratings: number[];\n sparseArray: (string | null | undefined)[];\n users: TestUser[];\n }) {\n this.tags = data.tags;\n this.ratings = data.ratings;\n this.sparseArray = data.sparseArray;\n this.users = data.users;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH ENUMS\n// ============================================================================\n\nexport enum UserRole {\n ADMIN = 'admin',\n USER = 'user',\n GUEST = 'guest',\n}\n\nexport enum ProductStatus {\n DRAFT = 'draft',\n PUBLISHED = 'published',\n ARCHIVED = 'archived',\n}\n\n/**\n * Entity with enum properties\n * Features: EnumProperty decorator\n */\n@Entity()\nexport class EntityWithEnum {\n @StringProperty() name!: string;\n @EnumProperty(UserRole) role!: UserRole;\n @EnumProperty(ProductStatus) status!: ProductStatus;\n\n constructor(data: { name: string; role: UserRole; status: ProductStatus }) {\n this.name = data.name;\n this.role = data.role;\n this.status = data.status;\n }\n}\n\n// ============================================================================\n// NESTED ENTITIES (2-3 LEVELS)\n// ============================================================================\n\n/**\n * Level 1: Simple address entity\n * Features: Basic nested entity\n */\n@Entity()\nexport class TestAddress {\n @StringProperty() street!: string;\n @StringProperty() city!: string;\n @StringProperty() country!: string;\n @IntProperty() zipCode!: number;\n\n constructor(data: {\n street: string;\n city: string;\n country: string;\n zipCode: number;\n }) {\n this.street = data.street;\n this.city = data.city;\n this.country = data.country;\n this.zipCode = data.zipCode;\n }\n}\n\n/**\n * Level 2: Company with nested address\n * Features: 1-level nesting\n */\n@Entity()\nexport class TestCompany {\n @StringProperty() name!: string;\n @EntityProperty(() => TestAddress) address!: TestAddress;\n @IntProperty() employeeCount!: number;\n\n constructor(data: {\n name: string;\n address: TestAddress;\n employeeCount: number;\n }) {\n this.name = data.name;\n this.address = data.address;\n this.employeeCount = data.employeeCount;\n }\n}\n\n/**\n * Level 3: Employee with nested company (which has nested address)\n * Features: 2-level nesting\n */\n@Entity()\nexport class TestEmployee {\n @StringProperty() name!: string;\n @StringProperty() email!: string;\n @EntityProperty(() => TestCompany) company!: TestCompany;\n @NumberProperty() salary!: number;\n @DateProperty() hireDate!: Date;\n\n constructor(data: {\n name: string;\n email: string;\n company: TestCompany;\n salary: number;\n hireDate: Date;\n }) {\n this.name = data.name;\n this.email = data.email;\n this.company = data.company;\n this.salary = data.salary;\n this.hireDate = data.hireDate;\n }\n}\n\n/**\n * Entity with optional nested entities\n * Features: Optional nested entities\n */\n@Entity()\nexport class EntityWithOptionalNested {\n @StringProperty() id!: string;\n @EntityProperty(() => TestAddress, { optional: true })\n billingAddress?: TestAddress;\n @EntityProperty(() => TestAddress, { optional: true })\n shippingAddress?: TestAddress;\n\n constructor(data: {\n id: string;\n billingAddress?: TestAddress;\n shippingAddress?: TestAddress;\n }) {\n this.id = data.id;\n this.billingAddress = data.billingAddress;\n this.shippingAddress = data.shippingAddress;\n }\n}\n\n// ============================================================================\n// COLLECTION ENTITIES\n// ============================================================================\n\n/**\n * Collection entity wrapping string array\n * Features: @CollectionEntity decorator, unwraps to array\n */\n@CollectionEntity()\nexport class TestTags {\n @ArrayProperty(() => String)\n readonly collection: string[];\n\n constructor(data: { collection: string[] }) {\n this.collection = data.collection;\n }\n}\n\n/**\n * Collection entity wrapping number array\n * Features: @CollectionEntity with numbers\n */\n@CollectionEntity()\nexport class TestIdList {\n @ArrayProperty(() => Number)\n readonly collection: number[];\n\n constructor(data: { collection: number[] }) {\n this.collection = data.collection;\n }\n}\n\n/**\n * Collection entity with entity items\n * Features: @CollectionEntity with nested entities\n */\n@CollectionEntity()\nexport class TestUserCollection {\n @ArrayProperty(() => TestUser)\n readonly collection: TestUser[];\n\n constructor(data: { collection: TestUser[] }) {\n this.collection = data.collection;\n }\n}\n\n// ============================================================================\n// STRINGIFIABLE ENTITIES\n// ============================================================================\n\n/**\n * Stringifiable entity for user IDs\n * Features: @Stringifiable decorator, unwraps to string\n */\n@Stringifiable()\nexport class TestUserId {\n @StringProperty() readonly value: string;\n\n constructor(data: { value: string }) {\n this.value = data.value;\n }\n}\n\n/**\n * Stringifiable entity for emails with validation\n * Features: @Stringifiable with validation\n */\n@Stringifiable()\nexport class TestEmail {\n @StringProperty({\n pattern: /^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$/i,\n })\n readonly value: string;\n\n constructor(data: { value: string }) {\n this.value = data.value;\n }\n}\n\n/**\n * Entity using stringifiable properties\n * Features: Properties that are stringifiable entities\n */\n@Entity()\nexport class EntityWithStringifiable {\n @EntityProperty(() => TestUserId) userId!: TestUserId;\n @EntityProperty(() => TestEmail) email!: TestEmail;\n @StringProperty() name!: string;\n\n constructor(data: { userId: TestUserId; email: TestEmail; name: string }) {\n this.userId = data.userId;\n this.email = data.email;\n this.name = data.name;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH DEPENDENCY INJECTION\n// ============================================================================\n\nexport interface ILogger {\n log(message: string): void;\n}\n\nexport const LOGGER_TOKEN = Symbol('Logger');\n\n/**\n * Entity with injected properties\n * Features: @InjectedProperty decorator\n */\n@Entity()\nexport class EntityWithDI {\n @StringProperty() name!: string;\n @InjectedProperty(LOGGER_TOKEN) logger!: ILogger;\n\n constructor(data: { name: string; logger?: ILogger }) {\n this.name = data.name;\n if (data.logger) {\n this.logger = data.logger;\n }\n }\n\n logName(): void {\n this.logger.log(`Name is: ${this.name}`);\n }\n}\n\n// ============================================================================\n// ENTITIES WITH PASSTHROUGH\n// ============================================================================\n\n/**\n * Entity with passthrough properties\n * Features: @PassthroughProperty for unknown types\n */\n@Entity()\nexport class EntityWithPassthrough {\n @StringProperty() id!: string;\n @PassthroughProperty() metadata!: Record<string, unknown>;\n @PassthroughProperty() config!: unknown;\n\n constructor(data: {\n id: string;\n metadata: Record<string, unknown>;\n config: unknown;\n }) {\n this.id = data.id;\n this.metadata = data.metadata;\n this.config = data.config;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH CUSTOM SERIALIZATION\n// ============================================================================\n\n/**\n * Custom serializable class\n */\nexport class CustomValue {\n constructor(\n public x: number,\n public y: number,\n ) {}\n\n toData() {\n return { x: this.x, y: this.y };\n }\n\n static fromData(data: { x: number; y: number }): CustomValue {\n return new CustomValue(data.x, data.y);\n }\n}\n\n/**\n * Entity with custom serialize/deserialize\n * Features: Custom serialization functions\n */\n@Entity()\nexport class EntityWithCustomSerialization {\n @StringProperty() name!: string;\n\n @Property({\n type: () => CustomValue,\n serialize: (v: CustomValue) => v.toData(),\n deserialize: (d: unknown) =>\n CustomValue.fromData(d as { x: number; y: number }),\n })\n position!: CustomValue;\n\n constructor(data: { name: string; position: CustomValue }) {\n this.name = data.name;\n this.position = data.position;\n }\n}\n\n/**\n * Entity to verify serialize/deserialize context is passed correctly\n * Features: Context-aware serialization using propertyName and sibling values\n */\n@Entity()\nexport class EntityWithContextSerialization {\n @StringProperty() id!: string;\n\n @Property({\n type: () => String,\n serialize: (v: string, context) =>\n `${context.propertyName}:${v}:${context.entity['id']}`,\n deserialize: (raw: unknown, context) =>\n `${raw}-from-${context.rawObject['id']}`,\n })\n label!: string;\n\n constructor(data: { id: string; label: string }) {\n this.id = data.id;\n this.label = data.label;\n }\n}\n\n/**\n * Custom class with equals method\n */\nexport class CustomPoint {\n constructor(\n public x: number,\n public y: number,\n ) {}\n\n equals(other: CustomPoint): boolean {\n return this.x === other.x && this.y === other.y;\n }\n\n toString(): string {\n return `${this.x},${this.y}`;\n }\n\n static fromString(str: string): CustomPoint {\n const [x, y] = str.split(',').map(Number);\n return new CustomPoint(x, y);\n }\n}\n\n/**\n * Entity with custom equals function\n * Features: Custom equality comparison\n */\n@Entity()\nexport class EntityWithCustomEquals {\n @StringProperty() id!: string;\n\n @Property({\n type: () => CustomPoint,\n serialize: (v: CustomPoint) => v.toString(),\n deserialize: (d: unknown) => CustomPoint.fromString(d as string),\n equals: (a: CustomPoint, b: CustomPoint) => a.equals(b),\n })\n location!: CustomPoint;\n\n constructor(data: { id: string; location: CustomPoint }) {\n this.id = data.id;\n this.location = data.location;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH SERIALIZABLE/PARSEABLE PROPERTIES\n// ============================================================================\n\n/**\n * Custom class implementing Serializable interface\n */\nexport class SerializableValue {\n constructor(public data: string) {}\n\n toJSON(): string {\n return this.data;\n }\n\n equals(other: SerializableValue): boolean {\n return this.data === other.data;\n }\n\n static parse(json: unknown): SerializableValue {\n return new SerializableValue(json as string);\n }\n}\n\n/**\n * Entity using SerializableProperty\n * Features: @SerializableProperty decorator\n */\n@Entity()\nexport class EntityWithSerializable {\n @StringProperty() name!: string;\n @SerializableProperty(() => SerializableValue)\n value!: SerializableValue;\n\n constructor(data: { name: string; value: SerializableValue }) {\n this.name = data.name;\n this.value = data.value;\n }\n}\n\n/**\n * Custom class implementing Parseable interface\n */\nexport class ParseableValue {\n constructor(public data: number) {}\n\n toString(): string {\n return String(this.data);\n }\n\n equals(other: ParseableValue): boolean {\n return this.data === other.data;\n }\n\n static parse(str: string): ParseableValue {\n return new ParseableValue(Number(str));\n }\n}\n\n/**\n * Entity using StringifiableProperty\n * Features: @StringifiableProperty decorator\n */\n@Entity()\nexport class EntityWithParseable {\n @StringProperty() label!: string;\n @StringifiableProperty(() => ParseableValue)\n value!: ParseableValue;\n\n constructor(data: { label: string; value: ParseableValue }) {\n this.label = data.label;\n this.value = data.value;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH ZOD VALIDATION\n// ============================================================================\n\nconst emailSchema = z.string().email();\nconst positiveIntSchema = z.number().int().positive();\n\n/**\n * Entity with Zod validation\n * Features: @ZodProperty decorator\n */\n@Entity()\nexport class EntityWithZod {\n @ZodProperty(z.string().min(3).max(20))\n username!: string;\n\n @ZodProperty(emailSchema)\n email!: string;\n\n @ZodProperty(positiveIntSchema)\n count!: number;\n\n constructor(data: { username: string; email: string; count: number }) {\n this.username = data.username;\n this.email = data.email;\n this.count = data.count;\n }\n}\n\n// ============================================================================\n// ENTITIES WITH IMMUTABLE PROPERTIES\n// ============================================================================\n\n/**\n * Entity with immutable (preventUpdates) properties\n * Features: preventUpdates flag\n */\n@Entity()\nexport class EntityWithImmutable {\n @StringProperty({ preventUpdates: true })\n readonly id: string;\n\n @StringProperty() name!: string;\n\n @DateProperty({ preventUpdates: true })\n readonly createdAt: Date;\n\n @NumberProperty() value!: number;\n\n constructor(data: {\n id: string;\n name: string;\n createdAt: Date;\n value: number;\n }) {\n this.id = data.id;\n this.name = data.name;\n this.createdAt = data.createdAt;\n this.value = data.value;\n }\n}\n\n// ============================================================================\n// COMPLEX ENTITY (COMBINING MULTIPLE FEATURES)\n// ============================================================================\n\n/**\n * Complex entity combining multiple features\n * Features: All common features in one entity\n * - Primitives, enums, nested entities, arrays\n * - Optional fields, defaults, validation\n * - Custom serialization, stringifiable properties\n */\n@Entity()\nexport class ComplexEntity {\n @StringProperty({ preventUpdates: true })\n readonly id: string;\n\n @StringProperty({ minLength: 2, maxLength: 50 })\n name!: string;\n\n @EnumProperty(UserRole)\n role!: UserRole;\n\n @EntityProperty(() => TestUserId)\n userId!: TestUserId;\n\n @EntityProperty(() => TestAddress)\n address!: TestAddress;\n\n @ArrayProperty(() => String, { minLength: 0, maxLength: 10 })\n tags!: string[];\n\n @ArrayProperty(() => TestProduct)\n products!: TestProduct[];\n\n @NumberProperty({ optional: true, min: 0 })\n score?: number;\n\n @DateProperty({ default: () => new Date() })\n createdAt!: Date;\n\n @DateProperty({ optional: true })\n updatedAt?: Date;\n\n @BooleanProperty({ default: true })\n active!: boolean;\n\n @PassthroughProperty()\n metadata!: Record<string, unknown>;\n\n constructor(data: {\n id: string;\n name: string;\n role: UserRole;\n userId: TestUserId;\n address: TestAddress;\n tags: string[];\n products: TestProduct[];\n score?: number;\n createdAt?: Date;\n updatedAt?: Date;\n active?: boolean;\n metadata: Record<string, unknown>;\n }) {\n this.id = data.id;\n this.name = data.name;\n this.role = data.role;\n this.userId = data.userId;\n this.address = data.address;\n this.tags = data.tags;\n this.products = data.products;\n this.score = data.score;\n this.createdAt = data.createdAt!;\n this.updatedAt = data.updatedAt;\n this.active = data.active!;\n this.metadata = data.metadata;\n }\n\n @EntityValidator()\n validateProducts(): Problem[] {\n if (this.products.length === 0 && this.active) {\n return [\n new Problem({\n property: 'products',\n message: 'Active entity must have at least one product',\n }),\n ];\n }\n return [];\n }\n}\n\n// ============================================================================\n// HELPER TO RESET FACTORY COUNTER (FOR TESTING)\n// ============================================================================\n\nexport function resetFactoryCallCount(): void {\n factoryCallCount = 0;\n}\n\n// ============================================================================\n// ENTITIES FOR parseBigInt TESTING\n// ============================================================================\n\n/**\n * Entity with NumberProperty and IntProperty configured with parseBigInt: true\n * Features: coercion from bigint / integer string to number\n */\n@Entity()\nexport class EntityWithParseBigInt {\n @NumberProperty({ parseBigInt: true }) amount!: number;\n @IntProperty({ parseBigInt: true }) count!: number;\n\n constructor(data: { amount: number; count: number }) {\n this.amount = data.amount;\n this.count = data.count;\n }\n}\n"],"names":["z","Entity","CollectionEntity","Stringifiable","EntityValidator","Property","StringProperty","NumberProperty","IntProperty","BooleanProperty","DateProperty","BigIntProperty","EnumProperty","EntityProperty","ArrayProperty","PassthroughProperty","SerializableProperty","StringifiableProperty","InjectedProperty","ZodProperty","Problem","TestUser","data","name","age","active","TestProduct","id","price","quantity","createdAt","EntityWithSpecialTypes","timestamp","largeNumber","label","ValidatedEntity","username","email","minLength","maxLength","pattern","min","max","CrossValidatedEntity","password","confirmPassword","startDate","endDate","validatePasswords","property","message","validateDates","OptionalFieldsEntity","requiredField","optionalField","optionalNumber","requiredBoolean","optional","factoryCallCount","EntityWithDefaults","counter","asyncField","enabled","default","Date","EntityWithArrays","tags","ratings","sparseArray","users","String","Number","sparse","UserRole","ProductStatus","EntityWithEnum","role","status","TestAddress","street","city","country","zipCode","TestCompany","address","employeeCount","TestEmployee","company","salary","hireDate","EntityWithOptionalNested","billingAddress","shippingAddress","TestTags","collection","TestIdList","TestUserCollection","TestUserId","value","TestEmail","EntityWithStringifiable","userId","LOGGER_TOKEN","Symbol","EntityWithDI","logger","logName","log","EntityWithPassthrough","metadata","config","CustomValue","x","y","toData","fromData","EntityWithCustomSerialization","position","type","serialize","v","deserialize","d","EntityWithContextSerialization","context","propertyName","entity","raw","rawObject","CustomPoint","equals","other","toString","fromString","str","split","map","EntityWithCustomEquals","location","a","b","SerializableValue","toJSON","parse","json","EntityWithSerializable","ParseableValue","EntityWithParseable","emailSchema","string","positiveIntSchema","number","int","positive","EntityWithZod","count","EntityWithImmutable","preventUpdates","ComplexEntity","products","score","updatedAt","validateProducts","length","resetFactoryCallCount","EntityWithParseBigInt","amount","parseBigInt"],"mappings":"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"}
@@ -46,6 +46,24 @@ export type BuiltinCtors = StringConstructor | NumberConstructor | BooleanConstr
46
46
  export type PrimitiveConstructor = StringConstructor | NumberConstructor | BooleanConstructor | BigIntConstructor | DateConstructor;
47
47
  export type CtorLike<T> = AnyCtor<T> | BuiltinCtors;
48
48
  export type InstanceOfCtorLike<C> = C extends StringConstructor ? string : C extends NumberConstructor ? number : C extends BooleanConstructor ? boolean : C extends BigIntConstructor ? bigint : C extends SymbolConstructor ? symbol : C extends DateConstructor ? Date : C extends AnyCtor<infer T> ? T : never;
49
+ /**
50
+ * Context passed to a custom serialize callback.
51
+ */
52
+ export interface PropertySerializeContext {
53
+ /** The property key being serialized */
54
+ propertyName: string;
55
+ /** The full entity instance being serialized */
56
+ entity: Record<string, unknown>;
57
+ }
58
+ /**
59
+ * Context passed to a custom deserialize callback.
60
+ */
61
+ export interface PropertyDeserializeContext {
62
+ /** The property key being deserialized */
63
+ propertyName: string;
64
+ /** The original raw input object (JSON) */
65
+ rawObject: Record<string, unknown>;
66
+ }
49
67
  /**
50
68
  * Options for the Property decorator
51
69
  */
@@ -142,7 +160,7 @@ export interface PropertyOptions<T = any, C extends CtorLike<T> = AnyCtor<T> | B
142
160
  * })
143
161
  * myProperty!: MyClass;
144
162
  */
145
- serialize?: (value: InstanceOfCtorLike<C>) => unknown;
163
+ serialize?: (value: InstanceOfCtorLike<C>, context: PropertySerializeContext) => unknown;
146
164
  /**
147
165
  * Custom deserialization function to convert JSON data back to the property type.
148
166
  * Must be paired with serialize - both must be defined together or both omitted.
@@ -155,7 +173,7 @@ export interface PropertyOptions<T = any, C extends CtorLike<T> = AnyCtor<T> | B
155
173
  * })
156
174
  * myProperty!: MyClass;
157
175
  */
158
- deserialize?: (serialized: unknown) => InstanceOfCtorLike<C>;
176
+ deserialize?: (serialized: unknown, context: PropertyDeserializeContext) => InstanceOfCtorLike<C>;
159
177
  /**
160
178
  * Array of validator functions for this property.
161
179
  * Each validator receives the property value and validation context.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-wrapper-object-types */\nimport type { Problem } from './problem.js';\n\n/**\n * Metadata key used to store property information\n */\nexport const PROPERTY_METADATA_KEY = Symbol('property:metadata');\n\n/**\n * Metadata key used to store property options\n */\nexport const PROPERTY_OPTIONS_METADATA_KEY = Symbol(\n 'property:options:metadata',\n);\n\n/**\n * Metadata key used to store entity information\n */\nexport const ENTITY_METADATA_KEY = Symbol('entity:metadata');\n\n/**\n * Metadata key used to store entity options\n */\nexport const ENTITY_OPTIONS_METADATA_KEY = Symbol('entity:options:metadata');\n\n/**\n * Metadata key used to store entity validator methods\n */\nexport const ENTITY_VALIDATOR_METADATA_KEY = Symbol(\n 'entity:validator:metadata',\n);\n\n/**\n * Metadata key used to store polymorphic discriminator property information\n */\nexport const POLYMORPHIC_PROPERTY_METADATA_KEY = Symbol(\n 'polymorphic:property:metadata',\n);\n\n/**\n * Metadata key used to store polymorphic variant information\n */\nexport const POLYMORPHIC_VARIANT_METADATA_KEY = Symbol(\n 'polymorphic:variant:metadata',\n);\n\n/**\n * Metadata key used to store injected property information\n */\nexport const INJECTED_PROPERTY_METADATA_KEY = Symbol(\n 'injected-property:metadata',\n);\n\n/**\n * Metadata key used to store injected property options (tokens)\n */\nexport const INJECTED_PROPERTY_OPTIONS_METADATA_KEY = Symbol(\n 'injected-property:options:metadata',\n);\n\nexport type AnyCtor<T = any> = Function & { prototype: T };\n\nexport type BuiltinCtors =\n | StringConstructor\n | NumberConstructor\n | BooleanConstructor\n | BigIntConstructor\n | SymbolConstructor\n | DateConstructor;\n\n/**\n * Type constructors for primitive types that can be deserialized\n * (excludes Symbol which cannot be deserialized from JSON)\n */\nexport type PrimitiveConstructor =\n | StringConstructor\n | NumberConstructor\n | BooleanConstructor\n | BigIntConstructor\n | DateConstructor;\n\nexport type CtorLike<T> = AnyCtor<T> | BuiltinCtors;\n\nexport type InstanceOfCtorLike<C> = C extends StringConstructor\n ? string\n : C extends NumberConstructor\n ? number\n : C extends BooleanConstructor\n ? boolean\n : C extends BigIntConstructor\n ? bigint\n : C extends SymbolConstructor\n ? symbol\n : C extends DateConstructor\n ? Date\n : C extends AnyCtor<infer T>\n ? T\n : never;\n\n/**\n * Options for the Property decorator\n */\nexport interface PropertyOptions<\n T = any,\n C extends CtorLike<T> = AnyCtor<T> | BuiltinCtors,\n> {\n /**\n * Custom equality comparison function for this property\n * @param a - First value to compare\n * @param b - Second value to compare\n * @returns true if values are equal, false otherwise\n */\n equals?: (a: InstanceOfCtorLike<C>, b: InstanceOfCtorLike<C>) => boolean;\n\n /**\n * Type constructor for this property. Required for EntityUtils.parse() support.\n * Use a function that returns the type constructor to support forward references.\n * Not required for discriminated entity properties nor passthrough properties.\n * @example\n * @Property({ type: () => String })\n * name!: string;\n *\n * @Property({ type: () => Address })\n * address!: Address;\n */\n type?: () => C;\n\n /**\n * Whether this property is an array. Defaults to false.\n * When true, the deserializer will map over array elements.\n * @example\n * @Property({ type: () => String, array: true })\n * tags!: string[];\n */\n array?: boolean;\n\n /**\n * Whether this property is optional. Defaults to false.\n * When true, the property can be undefined or null.\n * When false, the property must be present and not null/undefined.\n * @example\n * @Property({ type: () => String, optional: true })\n * nickname?: string;\n */\n optional?: boolean;\n\n /**\n * Whether the array can contain null/undefined elements. Defaults to false.\n * Only applicable when array is true.\n * When false (default), null/undefined elements will cause an error.\n * When true, null/undefined elements are allowed in the array.\n * @example\n * @Property({ type: () => String, array: true, sparse: true })\n * tags!: (string | null)[];\n */\n sparse?: boolean;\n\n /**\n * Whether to bypass type validation and pass values through as-is.\n * Use this for generic types like Record<string, unknown> or any.\n * When true, no type checking or transformation is performed.\n * Also bypasses any custom serialize/deserialize callbacks.\n * @example\n * @Property({ passthrough: true })\n * metadata!: Record<string, unknown>;\n */\n passthrough?: boolean;\n\n /**\n * Whether to prevent this property from being updated via EntityUtils.update().\n * When true, this property cannot be modified through update operations.\n * Defaults to false, allowing the property to be updated.\n * @example\n * @Property({ type: () => String, preventUpdates: true })\n * id!: string; // This property cannot be updated\n */\n preventUpdates?: boolean;\n\n /**\n * Default value for the property when not provided during deserialization.\n * Can be a static value or a function that returns the default value.\n * The function can be async and return a Promise.\n * @example\n * @Property({ type: () => String, default: 'N/A' })\n * nickname?: string;\n *\n * @Property({ type: () => Date, default: () => new Date() })\n * createdAt!: Date;\n *\n * @Property({ type: () => String, default: async () => await fetchDefaultValue() })\n * value!: string;\n */\n default?:\n | InstanceOfCtorLike<C>\n | (() => InstanceOfCtorLike<C> | Promise<InstanceOfCtorLike<C>>);\n\n /**\n * Custom serialization function to convert the property value to JSON-compatible format.\n * Must be paired with deserialize - both must be defined together or both omitted.\n * Not used when passthrough is true.\n * @example\n * @Property({\n * type: () => MyClass,\n * serialize: (value) => ({ data: value.toData() }),\n * deserialize: (json) => MyClass.fromData(json.data)\n * })\n * myProperty!: MyClass;\n */\n serialize?: (value: InstanceOfCtorLike<C>) => unknown;\n\n /**\n * Custom deserialization function to convert JSON data back to the property type.\n * Must be paired with serialize - both must be defined together or both omitted.\n * Not used when passthrough is true.\n * @example\n * @Property({\n * type: () => MyClass,\n * serialize: (value) => ({ data: value.toData() }),\n * deserialize: (json) => MyClass.fromData(json.data)\n * })\n * myProperty!: MyClass;\n */\n deserialize?: (serialized: unknown) => InstanceOfCtorLike<C>;\n\n /**\n * Array of validator functions for this property.\n * Each validator receives the property value and validation context.\n * Empty array means validation passed.\n * If the property is an array (array: true), these validators will run against each item.\n * Use arrayValidators instead to validate the array as a whole.\n * If passthrough is true, validators will run against the raw value.\n * @example\n * @Property({\n * type: () => String,\n * validators: [\n * (value, { createProblem }) =>\n * value.length > 10 ? [createProblem('Too long')] : []\n * ]\n * })\n * name!: string;\n */\n validators?: PropertyValidator<InstanceOfCtorLike<C>>[];\n\n /**\n * Array of validator functions for this property when it is an array.\n * Each validator receives the array value and validation context.\n * Empty array means validation passed.\n * Only applicable when array is true.\n * Not applicable when passthrough is true.\n * @example\n * @Property({\n * type: () => Number,\n * array: true,\n * arrayValidators: [\n * (value, { createProblem }) =>\n * value.length === 0 ? [createProblem('Array cannot be empty')] : []\n * ]\n * })\n * scores!: number[];\n */\n arrayValidators?: PropertyValidator<InstanceOfCtorLike<C>[]>[];\n\n /**\n * Indicates this property uses discriminated entity types.\n * The discriminator property name (e.g., '__type') is used to determine the entity type at runtime.\n * When true, serialization will include the discriminator inline with the entity.\n * During deserialization, the discriminator value is used to lookup the entity class in EntityRegistry.\n * @example\n * @DiscriminatedEntityProperty({ discriminatorProperty: '__type' })\n * item!: BaseItem; // Could be ItemA or ItemB at runtime\n */\n discriminated?: boolean;\n\n /**\n * The property name to use as the discriminator for discriminated entity properties.\n * Defaults to '__type' if not specified.\n * Only applicable when discriminated is true.\n * @example\n * @DiscriminatedEntityProperty({ discriminatorProperty: 'entityType' })\n * item!: BaseItem;\n */\n discriminatorProperty?: string;\n\n /**\n * Indicates this property is a polymorphic discriminator.\n * The property value determines which subclass variant to instantiate during parsing.\n * Used for class hierarchies where the discriminator is part of the class definition.\n * @example\n * @PolymorphicProperty(SchemaPropertyType)\n * type!: SchemaPropertyType;\n */\n polymorphicDiscriminator?: boolean;\n\n /**\n * The enum or union type for the polymorphic discriminator.\n * Used for validation and schema generation (e.g., Zod enums).\n * @example\n * @PolymorphicProperty(SchemaPropertyType)\n * type!: SchemaPropertyType;\n */\n polymorphicEnumType?: any;\n}\n\n/**\n * A validator function for a property.\n * The validator receives the value and returns Problems with property paths relative to the value.\n * Can be synchronous or asynchronous.\n * The calling code will prepend the actual property key to all returned problems.\n *\n * @param data - Object containing the value to validate\n * @param data.value - The value to validate\n * @returns Array of Problems (empty if valid) or Promise resolving to Problems.\n * Problems should have empty property for the value itself,\n * or relative paths for nested properties (e.g., 'name', '[0]', 'address.street')\n *\n * @example\n * ```typescript\n * // Synchronous validator\n * (({ value }) =>\n * value.length < 3 ? [new Problem({ property: '', message: 'Too short' })] : [])\n *\n * // Asynchronous validator\n * async ({ value }) => {\n * const exists = await checkDatabase(value);\n * return exists ? [] : [new Problem({ property: '', message: 'Not found' })];\n * }\n * ```\n */\nexport type PropertyValidator<T> = (data: {\n value: T;\n}) => Problem[] | Promise<Problem[]>;\n\n/**\n * A validator function for an entity.\n * Can be synchronous or asynchronous.\n * @param instance - The entity instance to validate\n * @returns Array of Problems (empty if valid) or Promise resolving to Problems\n */\nexport type EntityValidatorFn<T = any> = (\n instance: T,\n) => Problem[] | Promise<Problem[]>;\n\nexport interface Type<T = any> extends Function {\n new (...args: any[]): T;\n}\n\nexport type EntityDIToken<T = any> =\n | string\n | symbol\n | Function\n | AnyCtor<T>\n | Type<T>;\n\nexport type EntityDIProvider<T = any> =\n | {\n provide: EntityDIToken<T>;\n useValue?: T;\n useFactory?: never;\n }\n | {\n provide: EntityDIToken<T>;\n useValue?: never;\n useFactory?: () => T | Promise<T>;\n };\n\nexport type EntityDIFallbackFn = (token: EntityDIToken) => Promise<any>;\n\n/**\n * Generic type for safe operation results that can succeed or fail\n * @template T - The data type on success\n */\nexport type SafeOperationResult<T> = Promise<\n | { success: true; data: T; problems: Problem[] }\n | { success: false; data: undefined; problems: Problem[] }\n>;\n\nexport type ParseOptions = { strict?: boolean };\n"],"names":["PROPERTY_METADATA_KEY","Symbol","PROPERTY_OPTIONS_METADATA_KEY","ENTITY_METADATA_KEY","ENTITY_OPTIONS_METADATA_KEY","ENTITY_VALIDATOR_METADATA_KEY","POLYMORPHIC_PROPERTY_METADATA_KEY","POLYMORPHIC_VARIANT_METADATA_KEY","INJECTED_PROPERTY_METADATA_KEY","INJECTED_PROPERTY_OPTIONS_METADATA_KEY"],"mappings":"AAAA,6DAA6D,GAC7D,qDAAqD,GACrD,6DAA6D,GAG7D;;CAEC,GACD,OAAO,MAAMA,wBAAwBC,OAAO,qBAAqB;AAEjE;;CAEC,GACD,OAAO,MAAMC,gCAAgCD,OAC3C,6BACA;AAEF;;CAEC,GACD,OAAO,MAAME,sBAAsBF,OAAO,mBAAmB;AAE7D;;CAEC,GACD,OAAO,MAAMG,8BAA8BH,OAAO,2BAA2B;AAE7E;;CAEC,GACD,OAAO,MAAMI,gCAAgCJ,OAC3C,6BACA;AAEF;;CAEC,GACD,OAAO,MAAMK,oCAAoCL,OAC/C,iCACA;AAEF;;CAEC,GACD,OAAO,MAAMM,mCAAmCN,OAC9C,gCACA;AAEF;;CAEC,GACD,OAAO,MAAMO,iCAAiCP,OAC5C,8BACA;AAEF;;CAEC,GACD,OAAO,MAAMQ,yCAAyCR,OACpD,sCACA"}
1
+ {"version":3,"sources":["../../src/lib/types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-wrapper-object-types */\nimport type { Problem } from './problem.js';\n\n/**\n * Metadata key used to store property information\n */\nexport const PROPERTY_METADATA_KEY = Symbol('property:metadata');\n\n/**\n * Metadata key used to store property options\n */\nexport const PROPERTY_OPTIONS_METADATA_KEY = Symbol(\n 'property:options:metadata',\n);\n\n/**\n * Metadata key used to store entity information\n */\nexport const ENTITY_METADATA_KEY = Symbol('entity:metadata');\n\n/**\n * Metadata key used to store entity options\n */\nexport const ENTITY_OPTIONS_METADATA_KEY = Symbol('entity:options:metadata');\n\n/**\n * Metadata key used to store entity validator methods\n */\nexport const ENTITY_VALIDATOR_METADATA_KEY = Symbol(\n 'entity:validator:metadata',\n);\n\n/**\n * Metadata key used to store polymorphic discriminator property information\n */\nexport const POLYMORPHIC_PROPERTY_METADATA_KEY = Symbol(\n 'polymorphic:property:metadata',\n);\n\n/**\n * Metadata key used to store polymorphic variant information\n */\nexport const POLYMORPHIC_VARIANT_METADATA_KEY = Symbol(\n 'polymorphic:variant:metadata',\n);\n\n/**\n * Metadata key used to store injected property information\n */\nexport const INJECTED_PROPERTY_METADATA_KEY = Symbol(\n 'injected-property:metadata',\n);\n\n/**\n * Metadata key used to store injected property options (tokens)\n */\nexport const INJECTED_PROPERTY_OPTIONS_METADATA_KEY = Symbol(\n 'injected-property:options:metadata',\n);\n\nexport type AnyCtor<T = any> = Function & { prototype: T };\n\nexport type BuiltinCtors =\n | StringConstructor\n | NumberConstructor\n | BooleanConstructor\n | BigIntConstructor\n | SymbolConstructor\n | DateConstructor;\n\n/**\n * Type constructors for primitive types that can be deserialized\n * (excludes Symbol which cannot be deserialized from JSON)\n */\nexport type PrimitiveConstructor =\n | StringConstructor\n | NumberConstructor\n | BooleanConstructor\n | BigIntConstructor\n | DateConstructor;\n\nexport type CtorLike<T> = AnyCtor<T> | BuiltinCtors;\n\nexport type InstanceOfCtorLike<C> = C extends StringConstructor\n ? string\n : C extends NumberConstructor\n ? number\n : C extends BooleanConstructor\n ? boolean\n : C extends BigIntConstructor\n ? bigint\n : C extends SymbolConstructor\n ? symbol\n : C extends DateConstructor\n ? Date\n : C extends AnyCtor<infer T>\n ? T\n : never;\n\n/**\n * Context passed to a custom serialize callback.\n */\nexport interface PropertySerializeContext {\n /** The property key being serialized */\n propertyName: string;\n /** The full entity instance being serialized */\n entity: Record<string, unknown>;\n}\n\n/**\n * Context passed to a custom deserialize callback.\n */\nexport interface PropertyDeserializeContext {\n /** The property key being deserialized */\n propertyName: string;\n /** The original raw input object (JSON) */\n rawObject: Record<string, unknown>;\n}\n\n/**\n * Options for the Property decorator\n */\nexport interface PropertyOptions<\n T = any,\n C extends CtorLike<T> = AnyCtor<T> | BuiltinCtors,\n> {\n /**\n * Custom equality comparison function for this property\n * @param a - First value to compare\n * @param b - Second value to compare\n * @returns true if values are equal, false otherwise\n */\n equals?: (a: InstanceOfCtorLike<C>, b: InstanceOfCtorLike<C>) => boolean;\n\n /**\n * Type constructor for this property. Required for EntityUtils.parse() support.\n * Use a function that returns the type constructor to support forward references.\n * Not required for discriminated entity properties nor passthrough properties.\n * @example\n * @Property({ type: () => String })\n * name!: string;\n *\n * @Property({ type: () => Address })\n * address!: Address;\n */\n type?: () => C;\n\n /**\n * Whether this property is an array. Defaults to false.\n * When true, the deserializer will map over array elements.\n * @example\n * @Property({ type: () => String, array: true })\n * tags!: string[];\n */\n array?: boolean;\n\n /**\n * Whether this property is optional. Defaults to false.\n * When true, the property can be undefined or null.\n * When false, the property must be present and not null/undefined.\n * @example\n * @Property({ type: () => String, optional: true })\n * nickname?: string;\n */\n optional?: boolean;\n\n /**\n * Whether the array can contain null/undefined elements. Defaults to false.\n * Only applicable when array is true.\n * When false (default), null/undefined elements will cause an error.\n * When true, null/undefined elements are allowed in the array.\n * @example\n * @Property({ type: () => String, array: true, sparse: true })\n * tags!: (string | null)[];\n */\n sparse?: boolean;\n\n /**\n * Whether to bypass type validation and pass values through as-is.\n * Use this for generic types like Record<string, unknown> or any.\n * When true, no type checking or transformation is performed.\n * Also bypasses any custom serialize/deserialize callbacks.\n * @example\n * @Property({ passthrough: true })\n * metadata!: Record<string, unknown>;\n */\n passthrough?: boolean;\n\n /**\n * Whether to prevent this property from being updated via EntityUtils.update().\n * When true, this property cannot be modified through update operations.\n * Defaults to false, allowing the property to be updated.\n * @example\n * @Property({ type: () => String, preventUpdates: true })\n * id!: string; // This property cannot be updated\n */\n preventUpdates?: boolean;\n\n /**\n * Default value for the property when not provided during deserialization.\n * Can be a static value or a function that returns the default value.\n * The function can be async and return a Promise.\n * @example\n * @Property({ type: () => String, default: 'N/A' })\n * nickname?: string;\n *\n * @Property({ type: () => Date, default: () => new Date() })\n * createdAt!: Date;\n *\n * @Property({ type: () => String, default: async () => await fetchDefaultValue() })\n * value!: string;\n */\n default?:\n | InstanceOfCtorLike<C>\n | (() => InstanceOfCtorLike<C> | Promise<InstanceOfCtorLike<C>>);\n\n /**\n * Custom serialization function to convert the property value to JSON-compatible format.\n * Must be paired with deserialize - both must be defined together or both omitted.\n * Not used when passthrough is true.\n * @example\n * @Property({\n * type: () => MyClass,\n * serialize: (value) => ({ data: value.toData() }),\n * deserialize: (json) => MyClass.fromData(json.data)\n * })\n * myProperty!: MyClass;\n */\n serialize?: (\n value: InstanceOfCtorLike<C>,\n context: PropertySerializeContext,\n ) => unknown;\n\n /**\n * Custom deserialization function to convert JSON data back to the property type.\n * Must be paired with serialize - both must be defined together or both omitted.\n * Not used when passthrough is true.\n * @example\n * @Property({\n * type: () => MyClass,\n * serialize: (value) => ({ data: value.toData() }),\n * deserialize: (json) => MyClass.fromData(json.data)\n * })\n * myProperty!: MyClass;\n */\n deserialize?: (\n serialized: unknown,\n context: PropertyDeserializeContext,\n ) => InstanceOfCtorLike<C>;\n\n /**\n * Array of validator functions for this property.\n * Each validator receives the property value and validation context.\n * Empty array means validation passed.\n * If the property is an array (array: true), these validators will run against each item.\n * Use arrayValidators instead to validate the array as a whole.\n * If passthrough is true, validators will run against the raw value.\n * @example\n * @Property({\n * type: () => String,\n * validators: [\n * (value, { createProblem }) =>\n * value.length > 10 ? [createProblem('Too long')] : []\n * ]\n * })\n * name!: string;\n */\n validators?: PropertyValidator<InstanceOfCtorLike<C>>[];\n\n /**\n * Array of validator functions for this property when it is an array.\n * Each validator receives the array value and validation context.\n * Empty array means validation passed.\n * Only applicable when array is true.\n * Not applicable when passthrough is true.\n * @example\n * @Property({\n * type: () => Number,\n * array: true,\n * arrayValidators: [\n * (value, { createProblem }) =>\n * value.length === 0 ? [createProblem('Array cannot be empty')] : []\n * ]\n * })\n * scores!: number[];\n */\n arrayValidators?: PropertyValidator<InstanceOfCtorLike<C>[]>[];\n\n /**\n * Indicates this property uses discriminated entity types.\n * The discriminator property name (e.g., '__type') is used to determine the entity type at runtime.\n * When true, serialization will include the discriminator inline with the entity.\n * During deserialization, the discriminator value is used to lookup the entity class in EntityRegistry.\n * @example\n * @DiscriminatedEntityProperty({ discriminatorProperty: '__type' })\n * item!: BaseItem; // Could be ItemA or ItemB at runtime\n */\n discriminated?: boolean;\n\n /**\n * The property name to use as the discriminator for discriminated entity properties.\n * Defaults to '__type' if not specified.\n * Only applicable when discriminated is true.\n * @example\n * @DiscriminatedEntityProperty({ discriminatorProperty: 'entityType' })\n * item!: BaseItem;\n */\n discriminatorProperty?: string;\n\n /**\n * Indicates this property is a polymorphic discriminator.\n * The property value determines which subclass variant to instantiate during parsing.\n * Used for class hierarchies where the discriminator is part of the class definition.\n * @example\n * @PolymorphicProperty(SchemaPropertyType)\n * type!: SchemaPropertyType;\n */\n polymorphicDiscriminator?: boolean;\n\n /**\n * The enum or union type for the polymorphic discriminator.\n * Used for validation and schema generation (e.g., Zod enums).\n * @example\n * @PolymorphicProperty(SchemaPropertyType)\n * type!: SchemaPropertyType;\n */\n polymorphicEnumType?: any;\n}\n\n/**\n * A validator function for a property.\n * The validator receives the value and returns Problems with property paths relative to the value.\n * Can be synchronous or asynchronous.\n * The calling code will prepend the actual property key to all returned problems.\n *\n * @param data - Object containing the value to validate\n * @param data.value - The value to validate\n * @returns Array of Problems (empty if valid) or Promise resolving to Problems.\n * Problems should have empty property for the value itself,\n * or relative paths for nested properties (e.g., 'name', '[0]', 'address.street')\n *\n * @example\n * ```typescript\n * // Synchronous validator\n * (({ value }) =>\n * value.length < 3 ? [new Problem({ property: '', message: 'Too short' })] : [])\n *\n * // Asynchronous validator\n * async ({ value }) => {\n * const exists = await checkDatabase(value);\n * return exists ? [] : [new Problem({ property: '', message: 'Not found' })];\n * }\n * ```\n */\nexport type PropertyValidator<T> = (data: {\n value: T;\n}) => Problem[] | Promise<Problem[]>;\n\n/**\n * A validator function for an entity.\n * Can be synchronous or asynchronous.\n * @param instance - The entity instance to validate\n * @returns Array of Problems (empty if valid) or Promise resolving to Problems\n */\nexport type EntityValidatorFn<T = any> = (\n instance: T,\n) => Problem[] | Promise<Problem[]>;\n\nexport interface Type<T = any> extends Function {\n new (...args: any[]): T;\n}\n\nexport type EntityDIToken<T = any> =\n | string\n | symbol\n | Function\n | AnyCtor<T>\n | Type<T>;\n\nexport type EntityDIProvider<T = any> =\n | {\n provide: EntityDIToken<T>;\n useValue?: T;\n useFactory?: never;\n }\n | {\n provide: EntityDIToken<T>;\n useValue?: never;\n useFactory?: () => T | Promise<T>;\n };\n\nexport type EntityDIFallbackFn = (token: EntityDIToken) => Promise<any>;\n\n/**\n * Generic type for safe operation results that can succeed or fail\n * @template T - The data type on success\n */\nexport type SafeOperationResult<T> = Promise<\n | { success: true; data: T; problems: Problem[] }\n | { success: false; data: undefined; problems: Problem[] }\n>;\n\nexport type ParseOptions = { strict?: boolean };\n"],"names":["PROPERTY_METADATA_KEY","Symbol","PROPERTY_OPTIONS_METADATA_KEY","ENTITY_METADATA_KEY","ENTITY_OPTIONS_METADATA_KEY","ENTITY_VALIDATOR_METADATA_KEY","POLYMORPHIC_PROPERTY_METADATA_KEY","POLYMORPHIC_VARIANT_METADATA_KEY","INJECTED_PROPERTY_METADATA_KEY","INJECTED_PROPERTY_OPTIONS_METADATA_KEY"],"mappings":"AAAA,6DAA6D,GAC7D,qDAAqD,GACrD,6DAA6D,GAG7D;;CAEC,GACD,OAAO,MAAMA,wBAAwBC,OAAO,qBAAqB;AAEjE;;CAEC,GACD,OAAO,MAAMC,gCAAgCD,OAC3C,6BACA;AAEF;;CAEC,GACD,OAAO,MAAME,sBAAsBF,OAAO,mBAAmB;AAE7D;;CAEC,GACD,OAAO,MAAMG,8BAA8BH,OAAO,2BAA2B;AAE7E;;CAEC,GACD,OAAO,MAAMI,gCAAgCJ,OAC3C,6BACA;AAEF;;CAEC,GACD,OAAO,MAAMK,oCAAoCL,OAC/C,iCACA;AAEF;;CAEC,GACD,OAAO,MAAMM,mCAAmCN,OAC9C,gCACA;AAEF;;CAEC,GACD,OAAO,MAAMO,iCAAiCP,OAC5C,8BACA;AAEF;;CAEC,GACD,OAAO,MAAMQ,yCAAyCR,OACpD,sCACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rtpaulino/entity",
3
- "version": "0.26.1",
3
+ "version": "0.28.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",