metal-orm 1.1.8 → 1.1.10

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.
Files changed (75) hide show
  1. package/README.md +769 -764
  2. package/dist/index.cjs +2352 -226
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +605 -40
  5. package/dist/index.d.ts +605 -40
  6. package/dist/index.js +2324 -226
  7. package/dist/index.js.map +1 -1
  8. package/package.json +22 -17
  9. package/src/bulk/bulk-context.ts +83 -0
  10. package/src/bulk/bulk-delete-executor.ts +89 -0
  11. package/src/bulk/bulk-executor.base.ts +73 -0
  12. package/src/bulk/bulk-insert-executor.ts +74 -0
  13. package/src/bulk/bulk-types.ts +70 -0
  14. package/src/bulk/bulk-update-executor.ts +192 -0
  15. package/src/bulk/bulk-upsert-executor.ts +95 -0
  16. package/src/bulk/bulk-utils.ts +91 -0
  17. package/src/bulk/index.ts +18 -0
  18. package/src/codegen/typescript.ts +30 -21
  19. package/src/core/ast/expression-builders.ts +107 -10
  20. package/src/core/ast/expression-nodes.ts +52 -22
  21. package/src/core/ast/expression-visitor.ts +23 -13
  22. package/src/core/dialect/abstract.ts +30 -17
  23. package/src/core/dialect/mysql/index.ts +20 -5
  24. package/src/core/execution/db-executor.ts +96 -64
  25. package/src/core/execution/executors/better-sqlite3-executor.ts +94 -0
  26. package/src/core/execution/executors/mssql-executor.ts +66 -34
  27. package/src/core/execution/executors/mysql-executor.ts +98 -66
  28. package/src/core/execution/executors/postgres-executor.ts +33 -11
  29. package/src/core/execution/executors/sqlite-executor.ts +86 -30
  30. package/src/decorators/bootstrap.ts +482 -398
  31. package/src/decorators/column-decorator.ts +87 -96
  32. package/src/decorators/decorator-metadata.ts +100 -24
  33. package/src/decorators/entity.ts +27 -24
  34. package/src/decorators/relations.ts +231 -149
  35. package/src/decorators/transformers/transformer-decorators.ts +26 -29
  36. package/src/decorators/validators/country-validators-decorators.ts +9 -15
  37. package/src/dto/apply-filter.ts +568 -551
  38. package/src/index.ts +16 -9
  39. package/src/orm/entity-hydration.ts +116 -72
  40. package/src/orm/entity-metadata.ts +347 -301
  41. package/src/orm/entity-relations.ts +264 -207
  42. package/src/orm/entity.ts +199 -199
  43. package/src/orm/execute.ts +13 -13
  44. package/src/orm/lazy-batch/morph-many.ts +70 -0
  45. package/src/orm/lazy-batch/morph-one.ts +69 -0
  46. package/src/orm/lazy-batch/morph-to.ts +59 -0
  47. package/src/orm/lazy-batch.ts +4 -1
  48. package/src/orm/orm-session.ts +170 -104
  49. package/src/orm/pooled-executor-factory.ts +99 -58
  50. package/src/orm/query-logger.ts +49 -40
  51. package/src/orm/relation-change-processor.ts +198 -96
  52. package/src/orm/relations/belongs-to.ts +143 -143
  53. package/src/orm/relations/has-many.ts +204 -204
  54. package/src/orm/relations/has-one.ts +174 -174
  55. package/src/orm/relations/many-to-many.ts +288 -288
  56. package/src/orm/relations/morph-many.ts +156 -0
  57. package/src/orm/relations/morph-one.ts +151 -0
  58. package/src/orm/relations/morph-to.ts +162 -0
  59. package/src/orm/save-graph.ts +116 -1
  60. package/src/query-builder/expression-table-mapper.ts +5 -0
  61. package/src/query-builder/hydration-manager.ts +345 -345
  62. package/src/query-builder/hydration-planner.ts +178 -148
  63. package/src/query-builder/relation-conditions.ts +171 -151
  64. package/src/query-builder/relation-cte-builder.ts +5 -1
  65. package/src/query-builder/relation-filter-utils.ts +9 -6
  66. package/src/query-builder/relation-include-strategies.ts +44 -2
  67. package/src/query-builder/relation-join-strategies.ts +8 -1
  68. package/src/query-builder/relation-service.ts +250 -241
  69. package/src/query-builder/select/cursor-pagination.ts +323 -0
  70. package/src/query-builder/select/select-operations.ts +110 -105
  71. package/src/query-builder/select.ts +42 -1
  72. package/src/query-builder/update-include.ts +4 -0
  73. package/src/schema/relation.ts +296 -188
  74. package/src/schema/types.ts +138 -123
  75. package/src/tree/tree-decorator.ts +127 -137
@@ -1,149 +1,231 @@
1
- import { CascadeMode, RelationKinds } from '../schema/relation.js';
2
- import {
3
- EntityOrTableTarget,
4
- EntityOrTableTargetResolver,
5
- RelationMetadata
6
- } from '../orm/entity-metadata.js';
7
- import { getOrCreateMetadataBag } from './decorator-metadata.js';
8
-
9
- interface BaseRelationOptions {
10
- target: EntityOrTableTargetResolver;
11
- cascade?: CascadeMode;
12
- localKey?: string;
13
- }
14
-
15
- /**
16
- * Options for HasMany relation.
17
- */
18
- export interface HasManyOptions extends BaseRelationOptions {
19
- foreignKey?: string;
20
- }
21
-
22
- /**
23
- * Options for HasOne relation.
24
- */
25
- export interface HasOneOptions extends BaseRelationOptions {
26
- foreignKey?: string;
27
- }
28
-
29
- /**
30
- * Options for BelongsTo relation.
31
- */
32
- export interface BelongsToOptions extends BaseRelationOptions {
33
- foreignKey?: string;
34
- }
35
-
36
- /**
37
- * Options for BelongsToMany relation.
38
- */
39
- export interface BelongsToManyOptions<
40
- TTarget extends EntityOrTableTarget = EntityOrTableTarget,
41
- TPivot extends EntityOrTableTarget = EntityOrTableTarget
42
- > {
43
- target: EntityOrTableTargetResolver<TTarget>;
44
- pivotTable: EntityOrTableTargetResolver<TPivot>;
45
- pivotForeignKeyToRoot?: string;
46
- pivotForeignKeyToTarget?: string;
47
- localKey?: string;
48
- targetKey?: string;
49
- pivotPrimaryKey?: string;
50
- defaultPivotColumns?: string[];
51
- cascade?: CascadeMode;
52
- }
53
-
54
- const normalizePropertyName = (name: string | symbol): string => {
55
- if (typeof name === 'symbol') {
56
- return name.description ?? name.toString();
57
- }
58
- return name;
59
- };
60
-
61
- const createFieldDecorator = (metadataFactory: (propertyName: string) => RelationMetadata) => {
62
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
63
- if (!context.name) {
64
- throw new Error('Relation decorator requires a property name');
65
- }
66
- if (context.private) {
67
- throw new Error('Relation decorator does not support private fields');
68
- }
69
- const propertyName = normalizePropertyName(context.name);
70
- const bag = getOrCreateMetadataBag(context);
71
- const relationMetadata = metadataFactory(propertyName);
72
-
73
- if (!bag.relations.some(entry => entry.propertyName === propertyName)) {
74
- bag.relations.push({ propertyName, relation: relationMetadata });
75
- }
76
- };
77
- };
78
-
79
- /**
80
- * Decorator to define a HasMany relation on an entity property.
81
- * @param options - The relation options.
82
- * @returns A property decorator that registers the relation metadata.
83
- */
84
- export function HasMany(options: HasManyOptions) {
85
- return createFieldDecorator(propertyName => ({
86
- kind: RelationKinds.HasMany,
87
- propertyKey: propertyName,
88
- target: options.target,
89
- foreignKey: options.foreignKey,
90
- localKey: options.localKey,
91
- cascade: options.cascade
92
- }));
93
- }
94
-
95
- /**
96
- * Decorator to define a HasOne relation on an entity property.
97
- * @param options - The relation options.
98
- * @returns A property decorator that registers the relation metadata.
99
- */
100
- export function HasOne(options: HasOneOptions) {
101
- return createFieldDecorator(propertyName => ({
102
- kind: RelationKinds.HasOne,
103
- propertyKey: propertyName,
104
- target: options.target,
105
- foreignKey: options.foreignKey,
106
- localKey: options.localKey,
107
- cascade: options.cascade
108
- }));
109
- }
110
-
111
- /**
112
- * Decorator to define a BelongsTo relation on an entity property.
113
- * @param options - The relation options.
114
- * @returns A property decorator that registers the relation metadata.
115
- */
116
- export function BelongsTo(options: BelongsToOptions) {
117
- return createFieldDecorator(propertyName => ({
118
- kind: RelationKinds.BelongsTo,
119
- propertyKey: propertyName,
120
- target: options.target,
121
- foreignKey: options.foreignKey ?? `${propertyName}_id`,
122
- localKey: options.localKey,
123
- cascade: options.cascade
124
- }));
125
- }
126
-
127
- /**
128
- * Decorator to define a BelongsToMany relation on an entity property.
129
- * @param options - The relation options.
130
- * @returns A property decorator that registers the relation metadata.
131
- */
132
- export function BelongsToMany<
133
- TTarget extends EntityOrTableTarget = EntityOrTableTarget,
134
- TPivot extends EntityOrTableTarget = EntityOrTableTarget
135
- >(options: BelongsToManyOptions<TTarget, TPivot>) {
136
- return createFieldDecorator(propertyName => ({
137
- kind: RelationKinds.BelongsToMany,
138
- propertyKey: propertyName,
139
- target: options.target,
140
- pivotTable: options.pivotTable,
141
- pivotForeignKeyToRoot: options.pivotForeignKeyToRoot,
142
- pivotForeignKeyToTarget: options.pivotForeignKeyToTarget,
143
- localKey: options.localKey,
144
- targetKey: options.targetKey,
145
- pivotPrimaryKey: options.pivotPrimaryKey,
146
- defaultPivotColumns: options.defaultPivotColumns,
147
- cascade: options.cascade
148
- }));
149
- }
1
+ import { CascadeMode, RelationKinds } from '../schema/relation.js';
2
+ import {
3
+ EntityOrTableTarget,
4
+ EntityOrTableTargetResolver,
5
+ RelationMetadata
6
+ } from '../orm/entity-metadata.js';
7
+ import { resolveFieldDecoratorInfo } from './decorator-metadata.js';
8
+
9
+ interface BaseRelationOptions {
10
+ target: EntityOrTableTargetResolver;
11
+ cascade?: CascadeMode;
12
+ localKey?: string;
13
+ }
14
+
15
+ /**
16
+ * Options for HasMany relation.
17
+ */
18
+ export interface HasManyOptions extends BaseRelationOptions {
19
+ foreignKey?: string;
20
+ }
21
+
22
+ /**
23
+ * Options for HasOne relation.
24
+ */
25
+ export interface HasOneOptions extends BaseRelationOptions {
26
+ foreignKey?: string;
27
+ }
28
+
29
+ /**
30
+ * Options for BelongsTo relation.
31
+ */
32
+ export interface BelongsToOptions extends BaseRelationOptions {
33
+ foreignKey?: string;
34
+ }
35
+
36
+ /**
37
+ * Options for BelongsToMany relation.
38
+ */
39
+ export interface BelongsToManyOptions<
40
+ TTarget extends EntityOrTableTarget = EntityOrTableTarget,
41
+ TPivot extends EntityOrTableTarget = EntityOrTableTarget
42
+ > {
43
+ target: EntityOrTableTargetResolver<TTarget>;
44
+ pivotTable: EntityOrTableTargetResolver<TPivot>;
45
+ pivotForeignKeyToRoot?: string;
46
+ pivotForeignKeyToTarget?: string;
47
+ localKey?: string;
48
+ targetKey?: string;
49
+ pivotPrimaryKey?: string;
50
+ defaultPivotColumns?: string[];
51
+ cascade?: CascadeMode;
52
+ }
53
+
54
+ const createFieldDecorator = (metadataFactory: (propertyName: string) => RelationMetadata) => {
55
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
56
+ const { propertyName, bag } = resolveFieldDecoratorInfo(
57
+ targetOrValue,
58
+ contextOrProperty,
59
+ 'Relation'
60
+ );
61
+ const relationMetadata = metadataFactory(propertyName);
62
+
63
+ if (!bag.relations.some(entry => entry.propertyName === propertyName)) {
64
+ bag.relations.push({ propertyName, relation: relationMetadata });
65
+ }
66
+ };
67
+ };
68
+
69
+ /**
70
+ * Decorator to define a HasMany relation on an entity property.
71
+ * @param options - The relation options.
72
+ * @returns A property decorator that registers the relation metadata.
73
+ */
74
+ export function HasMany(options: HasManyOptions) {
75
+ return createFieldDecorator(propertyName => ({
76
+ kind: RelationKinds.HasMany,
77
+ propertyKey: propertyName,
78
+ target: options.target,
79
+ foreignKey: options.foreignKey,
80
+ localKey: options.localKey,
81
+ cascade: options.cascade
82
+ }));
83
+ }
84
+
85
+ /**
86
+ * Decorator to define a HasOne relation on an entity property.
87
+ * @param options - The relation options.
88
+ * @returns A property decorator that registers the relation metadata.
89
+ */
90
+ export function HasOne(options: HasOneOptions) {
91
+ return createFieldDecorator(propertyName => ({
92
+ kind: RelationKinds.HasOne,
93
+ propertyKey: propertyName,
94
+ target: options.target,
95
+ foreignKey: options.foreignKey,
96
+ localKey: options.localKey,
97
+ cascade: options.cascade
98
+ }));
99
+ }
100
+
101
+ /**
102
+ * Decorator to define a BelongsTo relation on an entity property.
103
+ * @param options - The relation options.
104
+ * @returns A property decorator that registers the relation metadata.
105
+ */
106
+ export function BelongsTo(options: BelongsToOptions) {
107
+ return createFieldDecorator(propertyName => ({
108
+ kind: RelationKinds.BelongsTo,
109
+ propertyKey: propertyName,
110
+ target: options.target,
111
+ foreignKey: options.foreignKey ?? `${propertyName}_id`,
112
+ localKey: options.localKey,
113
+ cascade: options.cascade
114
+ }));
115
+ }
116
+
117
+ /**
118
+ * Decorator to define a BelongsToMany relation on an entity property.
119
+ * @param options - The relation options.
120
+ * @returns A property decorator that registers the relation metadata.
121
+ */
122
+ export function BelongsToMany<
123
+ TTarget extends EntityOrTableTarget = EntityOrTableTarget,
124
+ TPivot extends EntityOrTableTarget = EntityOrTableTarget
125
+ >(options: BelongsToManyOptions<TTarget, TPivot>) {
126
+ return createFieldDecorator(propertyName => ({
127
+ kind: RelationKinds.BelongsToMany,
128
+ propertyKey: propertyName,
129
+ target: options.target,
130
+ pivotTable: options.pivotTable,
131
+ pivotForeignKeyToRoot: options.pivotForeignKeyToRoot,
132
+ pivotForeignKeyToTarget: options.pivotForeignKeyToTarget,
133
+ localKey: options.localKey,
134
+ targetKey: options.targetKey,
135
+ pivotPrimaryKey: options.pivotPrimaryKey,
136
+ defaultPivotColumns: options.defaultPivotColumns,
137
+ cascade: options.cascade
138
+ }));
139
+ }
140
+
141
+ /**
142
+ * Options for MorphTo relation.
143
+ */
144
+ export interface MorphToOptions {
145
+ typeField: string;
146
+ idField: string;
147
+ targets: Record<string, EntityOrTableTargetResolver>;
148
+ targetKey?: string;
149
+ cascade?: CascadeMode;
150
+ }
151
+
152
+ /**
153
+ * Options for MorphOne relation.
154
+ */
155
+ export interface MorphOneOptions {
156
+ target: EntityOrTableTargetResolver;
157
+ morphName: string;
158
+ typeValue: string;
159
+ typeField?: string;
160
+ idField?: string;
161
+ localKey?: string;
162
+ cascade?: CascadeMode;
163
+ }
164
+
165
+ /**
166
+ * Options for MorphMany relation.
167
+ */
168
+ export interface MorphManyOptions {
169
+ target: EntityOrTableTargetResolver;
170
+ morphName: string;
171
+ typeValue: string;
172
+ typeField?: string;
173
+ idField?: string;
174
+ localKey?: string;
175
+ cascade?: CascadeMode;
176
+ }
177
+
178
+ /**
179
+ * Decorator to define a MorphTo relation on an entity property.
180
+ * @param options - The relation options.
181
+ * @returns A property decorator that registers the relation metadata.
182
+ */
183
+ export function MorphTo(options: MorphToOptions) {
184
+ return createFieldDecorator(propertyName => ({
185
+ kind: RelationKinds.MorphTo,
186
+ propertyKey: propertyName,
187
+ typeField: options.typeField,
188
+ idField: options.idField,
189
+ targets: options.targets,
190
+ targetKey: options.targetKey,
191
+ cascade: options.cascade
192
+ }));
193
+ }
194
+
195
+ /**
196
+ * Decorator to define a MorphOne relation on an entity property.
197
+ * @param options - The relation options.
198
+ * @returns A property decorator that registers the relation metadata.
199
+ */
200
+ export function MorphOne(options: MorphOneOptions) {
201
+ return createFieldDecorator(propertyName => ({
202
+ kind: RelationKinds.MorphOne,
203
+ propertyKey: propertyName,
204
+ target: options.target,
205
+ morphName: options.morphName,
206
+ typeValue: options.typeValue,
207
+ typeField: options.typeField,
208
+ idField: options.idField,
209
+ localKey: options.localKey,
210
+ cascade: options.cascade
211
+ }));
212
+ }
213
+
214
+ /**
215
+ * Decorator to define a MorphMany relation on an entity property.
216
+ * @param options - The relation options.
217
+ * @returns A property decorator that registers the relation metadata.
218
+ */
219
+ export function MorphMany(options: MorphManyOptions) {
220
+ return createFieldDecorator(propertyName => ({
221
+ kind: RelationKinds.MorphMany,
222
+ propertyKey: propertyName,
223
+ target: options.target,
224
+ morphName: options.morphName,
225
+ typeValue: options.typeValue,
226
+ typeField: options.typeField,
227
+ idField: options.idField,
228
+ localKey: options.localKey,
229
+ cascade: options.cascade
230
+ }));
231
+ }
@@ -1,4 +1,4 @@
1
- import { getOrCreateMetadataBag } from '../decorator-metadata.js';
1
+ import { resolveFieldDecoratorInfo } from '../decorator-metadata.js';
2
2
  import type { TransformerMetadata } from './transformer-metadata.js';
3
3
  import {
4
4
  TrimTransformer,
@@ -9,19 +9,16 @@ import {
9
9
  PatternValidator
10
10
  } from './built-in/string-transformers.js';
11
11
 
12
- const normalizePropertyName = (name: string | symbol): string => {
13
- if (typeof name === 'symbol') {
14
- return name.description ?? name.toString();
15
- }
16
- return name;
17
- };
18
-
19
12
  const registerTransformerMetadata = (
20
- context: ClassFieldDecoratorContext,
13
+ targetOrValue: unknown,
14
+ contextOrProperty: unknown,
21
15
  metadata: Partial<TransformerMetadata>
22
16
  ): void => {
23
- const propertyName = normalizePropertyName(context.name);
24
- const bag = getOrCreateMetadataBag(context);
17
+ const { propertyName, bag } = resolveFieldDecoratorInfo(
18
+ targetOrValue,
19
+ contextOrProperty,
20
+ 'Transformer'
21
+ );
25
22
 
26
23
  // Find existing transformer metadata for this property
27
24
  let existing = bag.transformers.find(t => t.propertyName === propertyName);
@@ -57,8 +54,8 @@ const registerTransformerMetadata = (
57
54
 
58
55
  // Trim decorator
59
56
  export function Trim(options?: { trimStart?: boolean; trimEnd?: boolean; trimAll?: boolean }) {
60
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
61
- registerTransformerMetadata(context, {
57
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
58
+ registerTransformerMetadata(targetOrValue, contextOrProperty, {
62
59
  sanitizers: [new TrimTransformer(options)]
63
60
  });
64
61
  };
@@ -66,8 +63,8 @@ export function Trim(options?: { trimStart?: boolean; trimEnd?: boolean; trimAll
66
63
 
67
64
  // Lower case decorator
68
65
  export function Lower() {
69
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
70
- registerTransformerMetadata(context, {
66
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
67
+ registerTransformerMetadata(targetOrValue, contextOrProperty, {
71
68
  sanitizers: [new CaseTransformer('lower')]
72
69
  });
73
70
  };
@@ -75,8 +72,8 @@ export function Lower() {
75
72
 
76
73
  // Upper case decorator
77
74
  export function Upper() {
78
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
79
- registerTransformerMetadata(context, {
75
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
76
+ registerTransformerMetadata(targetOrValue, contextOrProperty, {
80
77
  sanitizers: [new CaseTransformer('upper')]
81
78
  });
82
79
  };
@@ -84,8 +81,8 @@ export function Upper() {
84
81
 
85
82
  // Capitalize decorator
86
83
  export function Capitalize() {
87
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
88
- registerTransformerMetadata(context, {
84
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
85
+ registerTransformerMetadata(targetOrValue, contextOrProperty, {
89
86
  sanitizers: [new CaseTransformer('capitalize')]
90
87
  });
91
88
  };
@@ -93,8 +90,8 @@ export function Capitalize() {
93
90
 
94
91
  // Title case decorator
95
92
  export function Title() {
96
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
97
- registerTransformerMetadata(context, {
93
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
94
+ registerTransformerMetadata(targetOrValue, contextOrProperty, {
98
95
  sanitizers: [new CaseTransformer('title')]
99
96
  });
100
97
  };
@@ -102,8 +99,8 @@ export function Title() {
102
99
 
103
100
  // Alphanumeric decorator
104
101
  export function Alphanumeric(options?: { allowSpaces?: boolean; allowUnderscores?: boolean; allowHyphens?: boolean }) {
105
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
106
- registerTransformerMetadata(context, {
102
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
103
+ registerTransformerMetadata(targetOrValue, contextOrProperty, {
107
104
  validators: [new AlphanumericValidator(options)]
108
105
  });
109
106
  };
@@ -111,8 +108,8 @@ export function Alphanumeric(options?: { allowSpaces?: boolean; allowUnderscores
111
108
 
112
109
  // Email decorator
113
110
  export function Email(options?: { allowPlus?: boolean; requireTLD?: boolean }) {
114
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
115
- registerTransformerMetadata(context, {
111
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
112
+ registerTransformerMetadata(targetOrValue, contextOrProperty, {
116
113
  validators: [new EmailValidator(options)]
117
114
  });
118
115
  };
@@ -120,8 +117,8 @@ export function Email(options?: { allowPlus?: boolean; requireTLD?: boolean }) {
120
117
 
121
118
  // Length decorator
122
119
  export function Length(options: { min?: number; max?: number; exact?: number }) {
123
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
124
- registerTransformerMetadata(context, {
120
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
121
+ registerTransformerMetadata(targetOrValue, contextOrProperty, {
125
122
  validators: [new LengthValidator(options)]
126
123
  });
127
124
  };
@@ -129,8 +126,8 @@ export function Length(options: { min?: number; max?: number; exact?: number })
129
126
 
130
127
  // Pattern decorator
131
128
  export function Pattern(options: { pattern: RegExp; flags?: string; errorMessage?: string; replacement?: string }) {
132
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
133
- registerTransformerMetadata(context, {
129
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
130
+ registerTransformerMetadata(targetOrValue, contextOrProperty, {
134
131
  validators: [new PatternValidator(options)]
135
132
  });
136
133
  };
@@ -1,4 +1,4 @@
1
- import { getOrCreateMetadataBag } from '../decorator-metadata.js';
1
+ import { resolveFieldDecoratorInfo } from '../decorator-metadata.js';
2
2
  import { registerValidator } from './country-validator-registry.js';
3
3
  import { CPFValidator } from './built-in/br-cpf-validator.js';
4
4
  import { CNPJValidator } from './built-in/br-cnpj-validator.js';
@@ -9,11 +9,8 @@ registerValidator('BR', 'cpf', () => new CPFValidator());
9
9
  registerValidator('BR', 'cnpj', () => new CNPJValidator());
10
10
  registerValidator('BR', 'cep', () => new CEPValidator());
11
11
 
12
- const normalizePropertyName = (name: string | symbol): string => {
13
- if (typeof name === 'symbol') {
14
- return name.description ?? name.toString();
15
- }
16
- return name;
12
+ const resolveCountryDecoratorInfo = (targetOrValue: unknown, contextOrProperty: unknown) => {
13
+ return resolveFieldDecoratorInfo(targetOrValue, contextOrProperty, 'Country validator');
17
14
  };
18
15
 
19
16
  /**
@@ -22,9 +19,8 @@ const normalizePropertyName = (name: string | symbol): string => {
22
19
  * @returns Property decorator for CPF validation
23
20
  */
24
21
  export function CPF(options?: { strict?: boolean; errorMessage?: string }) {
25
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
26
- const propertyName = normalizePropertyName(context.name);
27
- const bag = getOrCreateMetadataBag(context);
22
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
23
+ const { propertyName, bag } = resolveCountryDecoratorInfo(targetOrValue, contextOrProperty);
28
24
 
29
25
  // Find or create transformer metadata for this property
30
26
  let existing = bag.transformers.find(t => t.propertyName === propertyName);
@@ -86,9 +82,8 @@ export function CPF(options?: { strict?: boolean; errorMessage?: string }) {
86
82
  * @returns Property decorator for CNPJ validation
87
83
  */
88
84
  export function CNPJ(options?: { strict?: boolean; errorMessage?: string }) {
89
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
90
- const propertyName = normalizePropertyName(context.name);
91
- const bag = getOrCreateMetadataBag(context);
85
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
86
+ const { propertyName, bag } = resolveCountryDecoratorInfo(targetOrValue, contextOrProperty);
92
87
 
93
88
  // Find or create transformer metadata for this property
94
89
  let existing = bag.transformers.find(t => t.propertyName === propertyName);
@@ -150,9 +145,8 @@ export function CNPJ(options?: { strict?: boolean; errorMessage?: string }) {
150
145
  * @returns Property decorator for CEP validation
151
146
  */
152
147
  export function CEP(options?: { strict?: boolean; errorMessage?: string }) {
153
- return function (_value: unknown, context: ClassFieldDecoratorContext) {
154
- const propertyName = normalizePropertyName(context.name);
155
- const bag = getOrCreateMetadataBag(context);
148
+ return function (targetOrValue: unknown, contextOrProperty: unknown) {
149
+ const { propertyName, bag } = resolveCountryDecoratorInfo(targetOrValue, contextOrProperty);
156
150
 
157
151
  // Find or create transformer metadata for this property
158
152
  let existing = bag.transformers.find(t => t.propertyName === propertyName);