@rtpaulino/entity 0.14.1 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -7,4 +7,5 @@ export * from './lib/validation-error.js';
7
7
  export * from './lib/problem.js';
8
8
  export * from './lib/validation-utils.js';
9
9
  export * from './lib/primitive-deserializers.js';
10
+ export * from './lib/validators.js';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -7,5 +7,6 @@ export * from './lib/validation-error.js';
7
7
  export * from './lib/problem.js';
8
8
  export * from './lib/validation-utils.js';
9
9
  export * from './lib/primitive-deserializers.js';
10
+ export * from './lib/validators.js';
10
11
 
11
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import 'reflect-metadata';\n\nexport * from './lib/entity.js';\nexport * from './lib/entity-utils.js';\nexport * from './lib/types.js';\nexport * from './lib/property.js';\nexport * from './lib/validation-error.js';\nexport * from './lib/problem.js';\nexport * from './lib/validation-utils.js';\nexport * from './lib/primitive-deserializers.js';\n"],"names":[],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,cAAc,kBAAkB;AAChC,cAAc,wBAAwB;AACtC,cAAc,iBAAiB;AAC/B,cAAc,oBAAoB;AAClC,cAAc,4BAA4B;AAC1C,cAAc,mBAAmB;AACjC,cAAc,4BAA4B;AAC1C,cAAc,mCAAmC"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import 'reflect-metadata';\n\nexport * from './lib/entity.js';\nexport * from './lib/entity-utils.js';\nexport * from './lib/types.js';\nexport * from './lib/property.js';\nexport * from './lib/validation-error.js';\nexport * from './lib/problem.js';\nexport * from './lib/validation-utils.js';\nexport * from './lib/primitive-deserializers.js';\nexport * from './lib/validators.js';\n"],"names":[],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,cAAc,kBAAkB;AAChC,cAAc,wBAAwB;AACtC,cAAc,iBAAiB;AAC/B,cAAc,oBAAoB;AAClC,cAAc,4BAA4B;AAC1C,cAAc,mBAAmB;AACjC,cAAc,4BAA4B;AAC1C,cAAc,mCAAmC;AACjD,cAAc,sBAAsB"}
@@ -30,6 +30,26 @@ export declare function Property<T, C extends CtorLike<T>>(options: PropertyOpti
30
30
  * }
31
31
  */
32
32
  export declare function StringProperty(options?: Omit<PropertyOptions<string, StringConstructor>, 'type'>): PropertyDecorator;
33
+ /**
34
+ * Helper decorator for enum properties (string enums)
35
+ * Validates that the string value matches one of the enum values
36
+ * @param enumType - The enum object (e.g., MyEnum)
37
+ * @param options - Additional property options
38
+ * @example
39
+ * enum Status {
40
+ * Active = 'active',
41
+ * Inactive = 'inactive'
42
+ * }
43
+ *
44
+ * class User {
45
+ * @EnumProperty(Status)
46
+ * status!: Status;
47
+ *
48
+ * @EnumProperty(Status, { optional: true })
49
+ * previousStatus?: Status;
50
+ * }
51
+ */
52
+ export declare function EnumProperty<T extends Record<string, string>>(enumType: T, options?: Omit<PropertyOptions<string, StringConstructor>, 'type'>): PropertyDecorator;
33
53
  /**
34
54
  * Helper decorator for number properties
35
55
  * @example
@@ -42,6 +62,19 @@ export declare function StringProperty(options?: Omit<PropertyOptions<string, St
42
62
  * }
43
63
  */
44
64
  export declare function NumberProperty(options?: Omit<PropertyOptions<number, NumberConstructor>, 'type'>): PropertyDecorator;
65
+ /**
66
+ * Helper decorator for integer properties
67
+ * Validates that the number is an integer (no decimal places)
68
+ * @example
69
+ * class User {
70
+ * @IntProperty()
71
+ * age!: number;
72
+ *
73
+ * @IntProperty({ optional: true })
74
+ * count?: number;
75
+ * }
76
+ */
77
+ export declare function IntProperty(options?: Omit<PropertyOptions<number, NumberConstructor>, 'type'>): PropertyDecorator;
45
78
  /**
46
79
  * Helper decorator for boolean properties
47
80
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"property.d.ts","sourceRoot":"","sources":["../../src/lib/property.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"property.d.ts","sourceRoot":"","sources":["../../src/lib/property.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,OAAO,EACP,KAAK,QAAQ,EAIb,eAAe,EAChB,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAC/C,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,iBAAiB,CA2EnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,GACjE,iBAAiB,CAEnB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3D,QAAQ,EAAE,CAAC,EACX,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,GACjE,iBAAiB,CAMnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,GACjE,iBAAiB,CAEnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,GACjE,iBAAiB,CAMnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,kBAAkB,CAAC,EAAE,MAAM,CAAC,GACnE,iBAAiB,CAEnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,GAC7D,iBAAiB,CAEnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,GACjE,iBAAiB,CAEnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,CAAC,EACD,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,GAAG;IAAE,KAAK,IAAI,EAAE,GAAG,GAAG,CAAC,CAAA;CAAE,EAE7C,IAAI,EAAE,MAAM,CAAC,EACb,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,GAC5C,iBAAiB,CAEnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EACpD,IAAI,EAAE,MAAM,CAAC,EACb,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GACtD,iBAAiB,CAEnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,IAAI,iBAAiB,CAGvD;AAED,eAAO,MAAM,qBAAqB,GAChC,CAAC,SAAS;IAAE,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;IAAC,QAAQ,IAAI,MAAM,CAAA;CAAE,EAC5D,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAA;CAAE,EAEnD,MAAM,MAAM,CAAC,EACb,OAAM,IAAI,CACR,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,WAAW,GAAG,aAAa,GAAG,aAAa,GAAG,MAAM,GAAG,QAAQ,CAC3D,KACL,iBAYC,CAAC;AAEL,eAAO,MAAM,oBAAoB,GAC/B,CAAC,SAAS;IAAE,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;IAAC,MAAM,IAAI,OAAO,CAAA;CAAE,EAC3D,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,CAAA;CAAE,EAEpD,MAAM,MAAM,CAAC,EACb,OAAM,IAAI,CACR,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,WAAW,GAAG,aAAa,GAAG,aAAa,GAAG,MAAM,GAAG,QAAQ,CAC3D,sBAWJ,CAAC"}
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-wrapper-object-types */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { isEqual } from 'lodash-es';
2
2
  import { PROPERTY_METADATA_KEY, PROPERTY_OPTIONS_METADATA_KEY } from './types.js';
3
+ import { enumValidator, intValidator } from './validators.js';
3
4
  /**
4
5
  * Property decorator that marks class properties with metadata.
5
6
  * This decorator can be used to identify and track properties within classes.
@@ -74,6 +75,37 @@ import { PROPERTY_METADATA_KEY, PROPERTY_OPTIONS_METADATA_KEY } from './types.js
74
75
  type: ()=>String
75
76
  });
76
77
  }
78
+ /**
79
+ * Helper decorator for enum properties (string enums)
80
+ * Validates that the string value matches one of the enum values
81
+ * @param enumType - The enum object (e.g., MyEnum)
82
+ * @param options - Additional property options
83
+ * @example
84
+ * enum Status {
85
+ * Active = 'active',
86
+ * Inactive = 'inactive'
87
+ * }
88
+ *
89
+ * class User {
90
+ * @EnumProperty(Status)
91
+ * status!: Status;
92
+ *
93
+ * @EnumProperty(Status, { optional: true })
94
+ * previousStatus?: Status;
95
+ * }
96
+ */ export function EnumProperty(enumType, options) {
97
+ const validators = options?.validators ? [
98
+ enumValidator(enumType),
99
+ ...options.validators
100
+ ] : [
101
+ enumValidator(enumType)
102
+ ];
103
+ return Property({
104
+ ...options,
105
+ type: ()=>String,
106
+ validators
107
+ });
108
+ }
77
109
  /**
78
110
  * Helper decorator for number properties
79
111
  * @example
@@ -90,6 +122,30 @@ import { PROPERTY_METADATA_KEY, PROPERTY_OPTIONS_METADATA_KEY } from './types.js
90
122
  type: ()=>Number
91
123
  });
92
124
  }
125
+ /**
126
+ * Helper decorator for integer properties
127
+ * Validates that the number is an integer (no decimal places)
128
+ * @example
129
+ * class User {
130
+ * @IntProperty()
131
+ * age!: number;
132
+ *
133
+ * @IntProperty({ optional: true })
134
+ * count?: number;
135
+ * }
136
+ */ export function IntProperty(options) {
137
+ const validators = options?.validators ? [
138
+ intValidator(),
139
+ ...options.validators
140
+ ] : [
141
+ intValidator()
142
+ ];
143
+ return Property({
144
+ ...options,
145
+ type: ()=>Number,
146
+ validators
147
+ });
148
+ }
93
149
  /**
94
150
  * Helper decorator for boolean properties
95
151
  * @example
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/property.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-wrapper-object-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { isEqual } from 'lodash-es';\nimport {\n AnyCtor,\n type CtorLike,\n type InstanceOfCtorLike,\n PROPERTY_METADATA_KEY,\n PROPERTY_OPTIONS_METADATA_KEY,\n PropertyOptions,\n} from './types.js';\n\n/**\n * Property decorator that marks class properties with metadata.\n * This decorator can be used to identify and track properties within classes.\n *\n * @param options - Configuration for the property (type is required)\n *\n * @example\n * class User {\n * @Property({ type: () => String })\n * name: string;\n *\n * @Property({ type: () => String, equals: (a, b) => a.toLowerCase() === b.toLowerCase() })\n * email: string;\n *\n * @Property({ type: () => Number })\n * age: number;\n * }\n */\nexport function Property<T, C extends CtorLike<T>>(\n options: PropertyOptions<T, C>,\n): PropertyDecorator {\n return (target: object, propertyKey: string | symbol): void => {\n if (typeof propertyKey !== 'string') {\n return;\n }\n\n const existingProperties: string[] =\n Reflect.getOwnMetadata(PROPERTY_METADATA_KEY, target) || [];\n\n if (!existingProperties.includes(propertyKey)) {\n existingProperties.push(propertyKey);\n }\n\n Reflect.defineMetadata(PROPERTY_METADATA_KEY, existingProperties, target);\n\n if (options.passthrough === true) {\n if (options.array === true) {\n throw new Error(\n `Property '${propertyKey}' has passthrough: true and array: true. Passthrough cannot be combined with array.`,\n );\n }\n if (options.optional === true) {\n throw new Error(\n `Property '${propertyKey}' has passthrough: true and optional: true. Passthrough cannot be combined with optional.`,\n );\n }\n if (options.sparse === true) {\n throw new Error(\n `Property '${propertyKey}' has passthrough: true and sparse: true. Passthrough cannot be combined with sparse.`,\n );\n }\n if (\n options.serialize !== undefined ||\n options.deserialize !== undefined\n ) {\n throw new Error(\n `Property '${propertyKey}' has passthrough: true and custom serialize/deserialize functions. Passthrough cannot be combined with serialize or deserialize.`,\n );\n }\n }\n\n if (options.sparse === true && options.array !== true) {\n throw new Error(\n `Property '${propertyKey}' has sparse: true but array is not true. The sparse option only applies to arrays.`,\n );\n }\n\n if (options.arrayValidators && options.array !== true) {\n throw new Error(\n `Property '${propertyKey}' has arrayValidators defined but array is not true. The arrayValidators option only applies to arrays.`,\n );\n }\n\n // Validate serialize/deserialize pairing\n const hasSerialize = options.serialize !== undefined;\n const hasDeserialize = options.deserialize !== undefined;\n if (hasSerialize !== hasDeserialize) {\n throw new Error(\n `Property '${propertyKey}' must define both serialize and deserialize functions, or neither. Found only ${hasSerialize ? 'serialize' : 'deserialize'}.`,\n );\n }\n\n const existingOptions: Record<\n string,\n PropertyOptions<any, any>\n > = Reflect.getOwnMetadata(PROPERTY_OPTIONS_METADATA_KEY, target) || {};\n\n existingOptions[propertyKey] = options;\n\n Reflect.defineMetadata(\n PROPERTY_OPTIONS_METADATA_KEY,\n existingOptions,\n target,\n );\n };\n}\n\n/**\n * Helper decorator for string properties\n * @example\n * class User {\n * @StringProperty()\n * name!: string;\n *\n * @StringProperty({ optional: true })\n * nickname?: string;\n * }\n */\nexport function StringProperty(\n options?: Omit<PropertyOptions<string, StringConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => String });\n}\n\n/**\n * Helper decorator for number properties\n * @example\n * class User {\n * @NumberProperty()\n * age!: number;\n *\n * @NumberProperty({ optional: true })\n * score?: number;\n * }\n */\nexport function NumberProperty(\n options?: Omit<PropertyOptions<number, NumberConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => Number });\n}\n\n/**\n * Helper decorator for boolean properties\n * @example\n * class User {\n * @BooleanProperty()\n * active!: boolean;\n *\n * @BooleanProperty({ optional: true })\n * verified?: boolean;\n * }\n */\nexport function BooleanProperty(\n options?: Omit<PropertyOptions<boolean, BooleanConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => Boolean });\n}\n\n/**\n * Helper decorator for Date properties\n * @example\n * class User {\n * @DateProperty()\n * createdAt!: Date;\n *\n * @DateProperty({ optional: true })\n * deletedAt?: Date;\n * }\n */\nexport function DateProperty(\n options?: Omit<PropertyOptions<Date, DateConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => Date });\n}\n\n/**\n * Helper decorator for BigInt properties\n * @example\n * class User {\n * @BigIntProperty()\n * id!: bigint;\n *\n * @BigIntProperty({ optional: true })\n * balance?: bigint;\n * }\n */\nexport function BigIntProperty(\n options?: Omit<PropertyOptions<bigint, BigIntConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => BigInt });\n}\n\n/**\n * Helper decorator for entity properties\n * @example\n * class User {\n * @EntityProperty(() => Address)\n * address!: Address;\n *\n * @EntityProperty(() => Profile, { optional: true })\n * profile?: Profile;\n * }\n */\nexport function EntityProperty<\n T,\n C extends AnyCtor<T> & { new (data: any): T },\n>(\n type: () => C,\n options?: Omit<PropertyOptions<T, C>, 'type'>,\n): PropertyDecorator {\n return Property<T, C>({ ...options, type });\n}\n\n/**\n * Helper decorator for array properties\n * @example\n * class User {\n * @ArrayProperty(() => String)\n * tags!: string[];\n *\n * @ArrayProperty(() => Phone)\n * phones!: Phone[];\n *\n * @ArrayProperty(() => Number, { optional: true })\n * scores?: number[];\n *\n * @ArrayProperty(() => String, { sparse: true })\n * sparseList!: (string | null)[];\n * }\n */\nexport function ArrayProperty<T, C extends CtorLike<T>>(\n type: () => C,\n options?: Omit<PropertyOptions<T, C>, 'type' | 'array'>,\n): PropertyDecorator {\n return Property({ ...options, type, array: true });\n}\n\n/**\n * Helper decorator for passthrough properties that bypass type validation.\n * Use this for generic types like Record<string, unknown>, any, or custom objects.\n * @example\n * class Config {\n * @PassthroughProperty()\n * metadata!: Record<string, unknown>;\n *\n * @PassthroughProperty()\n * customData!: any;\n * }\n */\nexport function PassthroughProperty(): PropertyDecorator {\n // Use a dummy type since type is mandatory but not used with passthrough\n return Property({ type: () => Object, passthrough: true });\n}\n\nexport const StringifiableProperty = <\n T extends { equals?(other: T): boolean; toString(): string },\n C extends CtorLike<T> & { parse(value: string): T },\n>(\n type: () => C,\n data: Omit<\n PropertyOptions<T, C>,\n 'serialize' | 'deserialize' | 'passthrough' | 'type' | 'equals'\n > = {},\n): PropertyDecorator =>\n Property<T, C>({\n ...data,\n type,\n equals: (a, b) => (a.equals ? a.equals(b) : a.toString() === b.toString()),\n serialize: (value) => value.toString(),\n deserialize: (value) => {\n if (typeof value === 'string') {\n return type().parse(value) as InstanceOfCtorLike<C>;\n }\n throw new Error(`Invalid value ${type().name}: ${String(value)}`);\n },\n });\n\nexport const SerializableProperty = <\n T extends { equals?(other: T): boolean; toJSON(): unknown },\n C extends CtorLike<T> & { parse(value: unknown): T },\n>(\n type: () => C,\n data: Omit<\n PropertyOptions<T, C>,\n 'serialize' | 'deserialize' | 'passthrough' | 'type' | 'equals'\n > = {},\n) =>\n Property({\n ...data,\n type,\n equals: (a: T, b: T) =>\n a.equals ? a.equals(b) : isEqual(a.toJSON(), b.toJSON()),\n serialize: (value: T) => value.toJSON(),\n deserialize: (value: unknown) => {\n return type().parse(value) as InstanceOfCtorLike<C>;\n },\n });\n"],"names":["isEqual","PROPERTY_METADATA_KEY","PROPERTY_OPTIONS_METADATA_KEY","Property","options","target","propertyKey","existingProperties","Reflect","getOwnMetadata","includes","push","defineMetadata","passthrough","array","Error","optional","sparse","serialize","undefined","deserialize","arrayValidators","hasSerialize","hasDeserialize","existingOptions","StringProperty","type","String","NumberProperty","Number","BooleanProperty","Boolean","DateProperty","Date","BigIntProperty","BigInt","EntityProperty","ArrayProperty","PassthroughProperty","Object","StringifiableProperty","data","equals","a","b","toString","value","parse","name","SerializableProperty","toJSON"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/lib/property.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-wrapper-object-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { isEqual } from 'lodash-es';\nimport {\n AnyCtor,\n type CtorLike,\n type InstanceOfCtorLike,\n PROPERTY_METADATA_KEY,\n PROPERTY_OPTIONS_METADATA_KEY,\n PropertyOptions,\n} from './types.js';\nimport { enumValidator, intValidator } from './validators.js';\n\n/**\n * Property decorator that marks class properties with metadata.\n * This decorator can be used to identify and track properties within classes.\n *\n * @param options - Configuration for the property (type is required)\n *\n * @example\n * class User {\n * @Property({ type: () => String })\n * name: string;\n *\n * @Property({ type: () => String, equals: (a, b) => a.toLowerCase() === b.toLowerCase() })\n * email: string;\n *\n * @Property({ type: () => Number })\n * age: number;\n * }\n */\nexport function Property<T, C extends CtorLike<T>>(\n options: PropertyOptions<T, C>,\n): PropertyDecorator {\n return (target: object, propertyKey: string | symbol): void => {\n if (typeof propertyKey !== 'string') {\n return;\n }\n\n const existingProperties: string[] =\n Reflect.getOwnMetadata(PROPERTY_METADATA_KEY, target) || [];\n\n if (!existingProperties.includes(propertyKey)) {\n existingProperties.push(propertyKey);\n }\n\n Reflect.defineMetadata(PROPERTY_METADATA_KEY, existingProperties, target);\n\n if (options.passthrough === true) {\n if (options.array === true) {\n throw new Error(\n `Property '${propertyKey}' has passthrough: true and array: true. Passthrough cannot be combined with array.`,\n );\n }\n if (options.optional === true) {\n throw new Error(\n `Property '${propertyKey}' has passthrough: true and optional: true. Passthrough cannot be combined with optional.`,\n );\n }\n if (options.sparse === true) {\n throw new Error(\n `Property '${propertyKey}' has passthrough: true and sparse: true. Passthrough cannot be combined with sparse.`,\n );\n }\n if (\n options.serialize !== undefined ||\n options.deserialize !== undefined\n ) {\n throw new Error(\n `Property '${propertyKey}' has passthrough: true and custom serialize/deserialize functions. Passthrough cannot be combined with serialize or deserialize.`,\n );\n }\n }\n\n if (options.sparse === true && options.array !== true) {\n throw new Error(\n `Property '${propertyKey}' has sparse: true but array is not true. The sparse option only applies to arrays.`,\n );\n }\n\n if (options.arrayValidators && options.array !== true) {\n throw new Error(\n `Property '${propertyKey}' has arrayValidators defined but array is not true. The arrayValidators option only applies to arrays.`,\n );\n }\n\n // Validate serialize/deserialize pairing\n const hasSerialize = options.serialize !== undefined;\n const hasDeserialize = options.deserialize !== undefined;\n if (hasSerialize !== hasDeserialize) {\n throw new Error(\n `Property '${propertyKey}' must define both serialize and deserialize functions, or neither. Found only ${hasSerialize ? 'serialize' : 'deserialize'}.`,\n );\n }\n\n const existingOptions: Record<\n string,\n PropertyOptions<any, any>\n > = Reflect.getOwnMetadata(PROPERTY_OPTIONS_METADATA_KEY, target) || {};\n\n existingOptions[propertyKey] = options;\n\n Reflect.defineMetadata(\n PROPERTY_OPTIONS_METADATA_KEY,\n existingOptions,\n target,\n );\n };\n}\n\n/**\n * Helper decorator for string properties\n * @example\n * class User {\n * @StringProperty()\n * name!: string;\n *\n * @StringProperty({ optional: true })\n * nickname?: string;\n * }\n */\nexport function StringProperty(\n options?: Omit<PropertyOptions<string, StringConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => String });\n}\n\n/**\n * Helper decorator for enum properties (string enums)\n * Validates that the string value matches one of the enum values\n * @param enumType - The enum object (e.g., MyEnum)\n * @param options - Additional property options\n * @example\n * enum Status {\n * Active = 'active',\n * Inactive = 'inactive'\n * }\n *\n * class User {\n * @EnumProperty(Status)\n * status!: Status;\n *\n * @EnumProperty(Status, { optional: true })\n * previousStatus?: Status;\n * }\n */\nexport function EnumProperty<T extends Record<string, string>>(\n enumType: T,\n options?: Omit<PropertyOptions<string, StringConstructor>, 'type'>,\n): PropertyDecorator {\n const validators = options?.validators\n ? [enumValidator(enumType), ...options.validators]\n : [enumValidator(enumType)];\n\n return Property({ ...options, type: () => String, validators });\n}\n\n/**\n * Helper decorator for number properties\n * @example\n * class User {\n * @NumberProperty()\n * age!: number;\n *\n * @NumberProperty({ optional: true })\n * score?: number;\n * }\n */\nexport function NumberProperty(\n options?: Omit<PropertyOptions<number, NumberConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => Number });\n}\n\n/**\n * Helper decorator for integer properties\n * Validates that the number is an integer (no decimal places)\n * @example\n * class User {\n * @IntProperty()\n * age!: number;\n *\n * @IntProperty({ optional: true })\n * count?: number;\n * }\n */\nexport function IntProperty(\n options?: Omit<PropertyOptions<number, NumberConstructor>, 'type'>,\n): PropertyDecorator {\n const validators = options?.validators\n ? [intValidator(), ...options.validators]\n : [intValidator()];\n\n return Property({ ...options, type: () => Number, validators });\n}\n\n/**\n * Helper decorator for boolean properties\n * @example\n * class User {\n * @BooleanProperty()\n * active!: boolean;\n *\n * @BooleanProperty({ optional: true })\n * verified?: boolean;\n * }\n */\nexport function BooleanProperty(\n options?: Omit<PropertyOptions<boolean, BooleanConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => Boolean });\n}\n\n/**\n * Helper decorator for Date properties\n * @example\n * class User {\n * @DateProperty()\n * createdAt!: Date;\n *\n * @DateProperty({ optional: true })\n * deletedAt?: Date;\n * }\n */\nexport function DateProperty(\n options?: Omit<PropertyOptions<Date, DateConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => Date });\n}\n\n/**\n * Helper decorator for BigInt properties\n * @example\n * class User {\n * @BigIntProperty()\n * id!: bigint;\n *\n * @BigIntProperty({ optional: true })\n * balance?: bigint;\n * }\n */\nexport function BigIntProperty(\n options?: Omit<PropertyOptions<bigint, BigIntConstructor>, 'type'>,\n): PropertyDecorator {\n return Property({ ...options, type: () => BigInt });\n}\n\n/**\n * Helper decorator for entity properties\n * @example\n * class User {\n * @EntityProperty(() => Address)\n * address!: Address;\n *\n * @EntityProperty(() => Profile, { optional: true })\n * profile?: Profile;\n * }\n */\nexport function EntityProperty<\n T,\n C extends AnyCtor<T> & { new (data: any): T },\n>(\n type: () => C,\n options?: Omit<PropertyOptions<T, C>, 'type'>,\n): PropertyDecorator {\n return Property<T, C>({ ...options, type });\n}\n\n/**\n * Helper decorator for array properties\n * @example\n * class User {\n * @ArrayProperty(() => String)\n * tags!: string[];\n *\n * @ArrayProperty(() => Phone)\n * phones!: Phone[];\n *\n * @ArrayProperty(() => Number, { optional: true })\n * scores?: number[];\n *\n * @ArrayProperty(() => String, { sparse: true })\n * sparseList!: (string | null)[];\n * }\n */\nexport function ArrayProperty<T, C extends CtorLike<T>>(\n type: () => C,\n options?: Omit<PropertyOptions<T, C>, 'type' | 'array'>,\n): PropertyDecorator {\n return Property({ ...options, type, array: true });\n}\n\n/**\n * Helper decorator for passthrough properties that bypass type validation.\n * Use this for generic types like Record<string, unknown>, any, or custom objects.\n * @example\n * class Config {\n * @PassthroughProperty()\n * metadata!: Record<string, unknown>;\n *\n * @PassthroughProperty()\n * customData!: any;\n * }\n */\nexport function PassthroughProperty(): PropertyDecorator {\n // Use a dummy type since type is mandatory but not used with passthrough\n return Property({ type: () => Object, passthrough: true });\n}\n\nexport const StringifiableProperty = <\n T extends { equals?(other: T): boolean; toString(): string },\n C extends CtorLike<T> & { parse(value: string): T },\n>(\n type: () => C,\n data: Omit<\n PropertyOptions<T, C>,\n 'serialize' | 'deserialize' | 'passthrough' | 'type' | 'equals'\n > = {},\n): PropertyDecorator =>\n Property<T, C>({\n ...data,\n type,\n equals: (a, b) => (a.equals ? a.equals(b) : a.toString() === b.toString()),\n serialize: (value) => value.toString(),\n deserialize: (value) => {\n if (typeof value === 'string') {\n return type().parse(value) as InstanceOfCtorLike<C>;\n }\n throw new Error(`Invalid value ${type().name}: ${String(value)}`);\n },\n });\n\nexport const SerializableProperty = <\n T extends { equals?(other: T): boolean; toJSON(): unknown },\n C extends CtorLike<T> & { parse(value: unknown): T },\n>(\n type: () => C,\n data: Omit<\n PropertyOptions<T, C>,\n 'serialize' | 'deserialize' | 'passthrough' | 'type' | 'equals'\n > = {},\n) =>\n Property({\n ...data,\n type,\n equals: (a: T, b: T) =>\n a.equals ? a.equals(b) : isEqual(a.toJSON(), b.toJSON()),\n serialize: (value: T) => value.toJSON(),\n deserialize: (value: unknown) => {\n return type().parse(value) as InstanceOfCtorLike<C>;\n },\n });\n"],"names":["isEqual","PROPERTY_METADATA_KEY","PROPERTY_OPTIONS_METADATA_KEY","enumValidator","intValidator","Property","options","target","propertyKey","existingProperties","Reflect","getOwnMetadata","includes","push","defineMetadata","passthrough","array","Error","optional","sparse","serialize","undefined","deserialize","arrayValidators","hasSerialize","hasDeserialize","existingOptions","StringProperty","type","String","EnumProperty","enumType","validators","NumberProperty","Number","IntProperty","BooleanProperty","Boolean","DateProperty","Date","BigIntProperty","BigInt","EntityProperty","ArrayProperty","PassthroughProperty","Object","StringifiableProperty","data","equals","a","b","toString","value","parse","name","SerializableProperty","toJSON"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { PropertyValidator } from './types.js';
2
+ /**
3
+ * Creates a validator that checks if a string value is one of the allowed enum values
4
+ * @param enumType - The enum object containing valid values
5
+ * @returns A validator function that validates enum values
6
+ * @example
7
+ * enum Status { Active = 'active', Inactive = 'inactive' }
8
+ * const validator = enumValidator(Status);
9
+ */
10
+ export declare function enumValidator<T extends Record<string, string>>(enumType: T): PropertyValidator<string>;
11
+ /**
12
+ * Creates a validator that checks if a number is an integer (no decimal places)
13
+ * @returns A validator function that validates integer values
14
+ * @example
15
+ * const validator = intValidator();
16
+ */
17
+ export declare function intValidator(): PropertyValidator<number>;
18
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/lib/validators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5D,QAAQ,EAAE,CAAC,GACV,iBAAiB,CAAC,MAAM,CAAC,CAa3B;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAYxD"}
@@ -0,0 +1,42 @@
1
+ import { Problem } from './problem.js';
2
+ /**
3
+ * Creates a validator that checks if a string value is one of the allowed enum values
4
+ * @param enumType - The enum object containing valid values
5
+ * @returns A validator function that validates enum values
6
+ * @example
7
+ * enum Status { Active = 'active', Inactive = 'inactive' }
8
+ * const validator = enumValidator(Status);
9
+ */ export function enumValidator(enumType) {
10
+ const validValues = Object.values(enumType);
11
+ return ({ value })=>{
12
+ if (!validValues.includes(value)) {
13
+ return [
14
+ new Problem({
15
+ property: '',
16
+ message: `Expected one of [${validValues.join(', ')}] but received "${value}"`
17
+ })
18
+ ];
19
+ }
20
+ return [];
21
+ };
22
+ }
23
+ /**
24
+ * Creates a validator that checks if a number is an integer (no decimal places)
25
+ * @returns A validator function that validates integer values
26
+ * @example
27
+ * const validator = intValidator();
28
+ */ export function intValidator() {
29
+ return ({ value })=>{
30
+ if (!Number.isInteger(value)) {
31
+ return [
32
+ new Problem({
33
+ property: '',
34
+ message: `Expected an integer but received ${value}`
35
+ })
36
+ ];
37
+ }
38
+ return [];
39
+ };
40
+ }
41
+
42
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/validators.ts"],"sourcesContent":["import { Problem } from './problem.js';\nimport type { PropertyValidator } from './types.js';\n\n/**\n * Creates a validator that checks if a string value is one of the allowed enum values\n * @param enumType - The enum object containing valid values\n * @returns A validator function that validates enum values\n * @example\n * enum Status { Active = 'active', Inactive = 'inactive' }\n * const validator = enumValidator(Status);\n */\nexport function enumValidator<T extends Record<string, string>>(\n enumType: T,\n): PropertyValidator<string> {\n const validValues = Object.values(enumType);\n return ({ value }: { value: string }) => {\n if (!validValues.includes(value)) {\n return [\n new Problem({\n property: '',\n message: `Expected one of [${validValues.join(', ')}] but received \"${value}\"`,\n }),\n ];\n }\n return [];\n };\n}\n\n/**\n * Creates a validator that checks if a number is an integer (no decimal places)\n * @returns A validator function that validates integer values\n * @example\n * const validator = intValidator();\n */\nexport function intValidator(): PropertyValidator<number> {\n return ({ value }: { value: number }) => {\n if (!Number.isInteger(value)) {\n return [\n new Problem({\n property: '',\n message: `Expected an integer but received ${value}`,\n }),\n ];\n }\n return [];\n };\n}\n"],"names":["Problem","enumValidator","enumType","validValues","Object","values","value","includes","property","message","join","intValidator","Number","isInteger"],"mappings":"AAAA,SAASA,OAAO,QAAQ,eAAe;AAGvC;;;;;;;CAOC,GACD,OAAO,SAASC,cACdC,QAAW;IAEX,MAAMC,cAAcC,OAAOC,MAAM,CAACH;IAClC,OAAO,CAAC,EAAEI,KAAK,EAAqB;QAClC,IAAI,CAACH,YAAYI,QAAQ,CAACD,QAAQ;YAChC,OAAO;gBACL,IAAIN,QAAQ;oBACVQ,UAAU;oBACVC,SAAS,CAAC,iBAAiB,EAAEN,YAAYO,IAAI,CAAC,MAAM,gBAAgB,EAAEJ,MAAM,CAAC,CAAC;gBAChF;aACD;QACH;QACA,OAAO,EAAE;IACX;AACF;AAEA;;;;;CAKC,GACD,OAAO,SAASK;IACd,OAAO,CAAC,EAAEL,KAAK,EAAqB;QAClC,IAAI,CAACM,OAAOC,SAAS,CAACP,QAAQ;YAC5B,OAAO;gBACL,IAAIN,QAAQ;oBACVQ,UAAU;oBACVC,SAAS,CAAC,iCAAiC,EAAEH,OAAO;gBACtD;aACD;QACH;QACA,OAAO,EAAE;IACX;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rtpaulino/entity",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",