@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 +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/property.d.ts +33 -0
- package/dist/lib/property.d.ts.map +1 -1
- package/dist/lib/property.js +56 -0
- package/dist/lib/property.js.map +1 -1
- package/dist/lib/validators.d.ts +18 -0
- package/dist/lib/validators.d.ts.map +1 -0
- package/dist/lib/validators.js +42 -0
- package/dist/lib/validators.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,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
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"}
|
package/dist/lib/property.d.ts
CHANGED
|
@@ -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":"AAGA,OAAO,EACL,OAAO,EACP,KAAK,QAAQ,EAIb,eAAe,EAChB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"property.d.ts","sourceRoot":"","sources":["../../src/lib/property.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/property.js
CHANGED
|
@@ -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
|
package/dist/lib/property.js.map
CHANGED
|
@@ -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"}
|