metal-orm 1.0.92 → 1.0.94
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.cjs +728 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +225 -1
- package/dist/index.d.ts +225 -1
- package/dist/index.js +712 -23
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
- package/src/decorators/bootstrap.ts +11 -1
- package/src/decorators/decorator-metadata.ts +3 -1
- package/src/decorators/index.ts +27 -0
- package/src/decorators/transformers/built-in/string-transformers.ts +231 -0
- package/src/decorators/transformers/transformer-decorators.ts +137 -0
- package/src/decorators/transformers/transformer-executor.ts +172 -0
- package/src/decorators/transformers/transformer-metadata.ts +73 -0
- package/src/decorators/validators/built-in/br-cep-validator.ts +55 -0
- package/src/decorators/validators/built-in/br-cnpj-validator.ts +105 -0
- package/src/decorators/validators/built-in/br-cpf-validator.ts +103 -0
- package/src/decorators/validators/country-validator-registry.ts +64 -0
- package/src/decorators/validators/country-validators-decorators.ts +209 -0
- package/src/decorators/validators/country-validators.ts +105 -0
- package/src/decorators/validators/validator-metadata.ts +59 -0
- package/src/dto/openapi/utilities.ts +5 -0
- package/src/orm/entity-metadata.ts +64 -45
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base interface for country-specific identifier validators
|
|
3
|
+
*/
|
|
4
|
+
export interface CountryValidator<T = string> {
|
|
5
|
+
/** ISO 3166-1 alpha-2 country code (e.g., 'BR', 'US') */
|
|
6
|
+
readonly countryCode: string;
|
|
7
|
+
|
|
8
|
+
/** Identifier type (e.g., 'cpf', 'cnpj', 'ssn', 'zip') */
|
|
9
|
+
readonly identifierType: string;
|
|
10
|
+
|
|
11
|
+
/** Unique validator name (e.g., 'br-cpf', 'us-ssn') */
|
|
12
|
+
readonly name: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Validates an identifier value
|
|
16
|
+
* @param value - The identifier value to validate
|
|
17
|
+
* @param options - Validation options
|
|
18
|
+
* @returns Validation result with success status and optional error message
|
|
19
|
+
*/
|
|
20
|
+
validate(value: T, options?: ValidationOptions): ValidationResult;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Normalizes an identifier value (removes formatting, standardizes)
|
|
24
|
+
* @param value - The identifier value to normalize
|
|
25
|
+
* @returns Normalized value (digits only, uppercase, etc.)
|
|
26
|
+
*/
|
|
27
|
+
normalize(value: T): string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Formats an identifier value according to country standards
|
|
31
|
+
* @param value - The identifier value to format (can be normalized or formatted)
|
|
32
|
+
* @returns Formatted value (e.g., '123.456.789-01' for CPF)
|
|
33
|
+
*/
|
|
34
|
+
format(value: T): string;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Attempts to auto-correct an invalid value
|
|
38
|
+
* @param value - The invalid value to correct
|
|
39
|
+
* @returns Auto-correction result or undefined if not possible
|
|
40
|
+
*/
|
|
41
|
+
autoCorrect?(value: T): AutoCorrectionResult<T>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Validation options for country identifiers
|
|
46
|
+
*/
|
|
47
|
+
export interface ValidationOptions {
|
|
48
|
+
/** Whether to allow formatted input (e.g., '123.456.789-01') */
|
|
49
|
+
allowFormatted?: boolean;
|
|
50
|
+
|
|
51
|
+
/** Whether to allow normalized input (e.g., '12345678901') */
|
|
52
|
+
allowNormalized?: boolean;
|
|
53
|
+
|
|
54
|
+
/** Whether to perform strict validation (e.g., check for known invalid numbers) */
|
|
55
|
+
strict?: boolean;
|
|
56
|
+
|
|
57
|
+
/** Custom error message */
|
|
58
|
+
errorMessage?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Validation result
|
|
63
|
+
*/
|
|
64
|
+
export interface ValidationResult {
|
|
65
|
+
/** Whether validation passed */
|
|
66
|
+
isValid: boolean;
|
|
67
|
+
|
|
68
|
+
/** Error message if validation failed */
|
|
69
|
+
error?: string;
|
|
70
|
+
|
|
71
|
+
/** Normalized value (if validation passed) */
|
|
72
|
+
normalizedValue?: string;
|
|
73
|
+
|
|
74
|
+
/** Formatted value (if validation passed) */
|
|
75
|
+
formattedValue?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Auto-correction result
|
|
80
|
+
*/
|
|
81
|
+
export interface AutoCorrectionResult<T = string> {
|
|
82
|
+
/** Whether auto-correction was successful */
|
|
83
|
+
success: boolean;
|
|
84
|
+
|
|
85
|
+
/** Corrected value */
|
|
86
|
+
correctedValue?: T;
|
|
87
|
+
|
|
88
|
+
/** Description of what was corrected */
|
|
89
|
+
message?: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Country Validator Factory
|
|
93
|
+
export type CountryValidatorFactory<T = string> = (options?: ValidatorFactoryOptions) => CountryValidator<T>;
|
|
94
|
+
|
|
95
|
+
// Options for creating a validator instance
|
|
96
|
+
export interface ValidatorFactoryOptions {
|
|
97
|
+
/** Custom validation rules */
|
|
98
|
+
customRules?: Record<string, unknown>;
|
|
99
|
+
|
|
100
|
+
/** Whether to enable strict mode by default */
|
|
101
|
+
strict?: boolean;
|
|
102
|
+
|
|
103
|
+
/** Custom error messages */
|
|
104
|
+
errorMessages?: Record<string, string>;
|
|
105
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation options for country identifiers
|
|
3
|
+
*/
|
|
4
|
+
export interface ValidationOptions {
|
|
5
|
+
/** Whether to allow formatted input (e.g., '123.456.789-01') */
|
|
6
|
+
allowFormatted?: boolean;
|
|
7
|
+
|
|
8
|
+
/** Whether to allow normalized input (e.g., '12345678901') */
|
|
9
|
+
allowNormalized?: boolean;
|
|
10
|
+
|
|
11
|
+
/** Whether to perform strict validation (e.g., check for known invalid numbers) */
|
|
12
|
+
strict?: boolean;
|
|
13
|
+
|
|
14
|
+
/** Custom error message */
|
|
15
|
+
errorMessage?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Validation result
|
|
20
|
+
*/
|
|
21
|
+
export interface ValidationResult {
|
|
22
|
+
/** Whether validation passed */
|
|
23
|
+
isValid: boolean;
|
|
24
|
+
|
|
25
|
+
/** Error message if validation failed */
|
|
26
|
+
error?: string;
|
|
27
|
+
|
|
28
|
+
/** Normalized value (if validation passed) */
|
|
29
|
+
normalizedValue?: string;
|
|
30
|
+
|
|
31
|
+
/** Formatted value (if validation passed) */
|
|
32
|
+
formattedValue?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Auto-correction result
|
|
37
|
+
*/
|
|
38
|
+
export interface AutoCorrectionResult<T = string> {
|
|
39
|
+
/** Whether auto-correction was successful */
|
|
40
|
+
success: boolean;
|
|
41
|
+
|
|
42
|
+
/** Corrected value */
|
|
43
|
+
correctedValue?: T;
|
|
44
|
+
|
|
45
|
+
/** Description of what was corrected */
|
|
46
|
+
message?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Options for creating a validator instance
|
|
50
|
+
export interface ValidatorFactoryOptions {
|
|
51
|
+
/** Custom validation rules */
|
|
52
|
+
customRules?: Record<string, unknown>;
|
|
53
|
+
|
|
54
|
+
/** Whether to enable strict mode by default */
|
|
55
|
+
strict?: boolean;
|
|
56
|
+
|
|
57
|
+
/** Custom error messages */
|
|
58
|
+
errorMessages?: Record<string, string>;
|
|
59
|
+
}
|
|
@@ -26,6 +26,7 @@ export function applyNullability(
|
|
|
26
26
|
dialect: OpenApiDialect
|
|
27
27
|
): OpenApiSchema {
|
|
28
28
|
if (!isNullable) {
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
29
30
|
const { nullable: _, ...clean } = schema;
|
|
30
31
|
return clean;
|
|
31
32
|
}
|
|
@@ -37,17 +38,21 @@ export function applyNullability(
|
|
|
37
38
|
const type = schema.type;
|
|
38
39
|
if (Array.isArray(type)) {
|
|
39
40
|
if (!type.includes('null')) {
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
40
42
|
const { nullable: _, ...clean } = schema;
|
|
41
43
|
return { ...clean, type: [...type, 'null'] as OpenApiType[] };
|
|
42
44
|
}
|
|
43
45
|
} else if (type) {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
44
47
|
const { nullable: _, ...clean } = schema;
|
|
45
48
|
return { ...clean, type: [type, 'null'] as OpenApiType[] };
|
|
46
49
|
} else {
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
47
51
|
const { nullable: _, ...clean } = schema;
|
|
48
52
|
return { ...clean, type: ['null'] as OpenApiType[] };
|
|
49
53
|
}
|
|
50
54
|
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
56
|
const { nullable: _, ...clean } = schema;
|
|
52
57
|
return clean;
|
|
53
58
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ColumnDef } from '../schema/column-types.js';
|
|
2
2
|
import { defineTable, TableDef, TableHooks } from '../schema/table.js';
|
|
3
3
|
import { CascadeMode, RelationKinds } from '../schema/relation.js';
|
|
4
|
+
import type { TransformerMetadata } from '../decorators/transformers/transformer-metadata.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Constructor type for entities.
|
|
@@ -21,11 +22,11 @@ export type EntityOrTableTarget = EntityConstructor | TableDef;
|
|
|
21
22
|
export type EntityOrTableTargetResolver<T extends EntityOrTableTarget = EntityOrTableTarget> =
|
|
22
23
|
T | (() => T);
|
|
23
24
|
|
|
24
|
-
/**
|
|
25
|
-
* Simplified column definition structure used during metadata registration.
|
|
26
|
-
* @template T - Concrete column definition type being extended
|
|
27
|
-
*/
|
|
28
|
-
export type ColumnDefLike<T extends ColumnDef = ColumnDef> = Omit<T, 'table'>;
|
|
25
|
+
/**
|
|
26
|
+
* Simplified column definition structure used during metadata registration.
|
|
27
|
+
* @template T - Concrete column definition type being extended
|
|
28
|
+
*/
|
|
29
|
+
export type ColumnDefLike<T extends ColumnDef = ColumnDef> = Omit<T, 'table'>;
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* Transforms simplified column metadata into full ColumnDef objects during table building.
|
|
@@ -53,26 +54,26 @@ interface BaseRelationMetadata {
|
|
|
53
54
|
/**
|
|
54
55
|
* Metadata for has many relations.
|
|
55
56
|
*/
|
|
56
|
-
export interface HasManyRelationMetadata extends BaseRelationMetadata {
|
|
57
|
-
/** The relation kind */
|
|
58
|
-
kind: typeof RelationKinds.HasMany;
|
|
59
|
-
/** The foreign key */
|
|
60
|
-
foreignKey?: string;
|
|
61
|
-
/** Optional local key */
|
|
62
|
-
localKey?: string;
|
|
63
|
-
}
|
|
57
|
+
export interface HasManyRelationMetadata extends BaseRelationMetadata {
|
|
58
|
+
/** The relation kind */
|
|
59
|
+
kind: typeof RelationKinds.HasMany;
|
|
60
|
+
/** The foreign key */
|
|
61
|
+
foreignKey?: string;
|
|
62
|
+
/** Optional local key */
|
|
63
|
+
localKey?: string;
|
|
64
|
+
}
|
|
64
65
|
|
|
65
66
|
/**
|
|
66
67
|
* Metadata for has one relations.
|
|
67
68
|
*/
|
|
68
|
-
export interface HasOneRelationMetadata extends BaseRelationMetadata {
|
|
69
|
-
/** The relation kind */
|
|
70
|
-
kind: typeof RelationKinds.HasOne;
|
|
71
|
-
/** The foreign key */
|
|
72
|
-
foreignKey?: string;
|
|
73
|
-
/** Optional local key */
|
|
74
|
-
localKey?: string;
|
|
75
|
-
}
|
|
69
|
+
export interface HasOneRelationMetadata extends BaseRelationMetadata {
|
|
70
|
+
/** The relation kind */
|
|
71
|
+
kind: typeof RelationKinds.HasOne;
|
|
72
|
+
/** The foreign key */
|
|
73
|
+
foreignKey?: string;
|
|
74
|
+
/** Optional local key */
|
|
75
|
+
localKey?: string;
|
|
76
|
+
}
|
|
76
77
|
|
|
77
78
|
/**
|
|
78
79
|
* Metadata for belongs to relations.
|
|
@@ -89,20 +90,20 @@ export interface BelongsToRelationMetadata extends BaseRelationMetadata {
|
|
|
89
90
|
/**
|
|
90
91
|
* Metadata for belongs to many relations.
|
|
91
92
|
*/
|
|
92
|
-
export interface BelongsToManyRelationMetadata extends BaseRelationMetadata {
|
|
93
|
-
/** The relation kind */
|
|
94
|
-
kind: typeof RelationKinds.BelongsToMany;
|
|
95
|
-
/** The pivot table */
|
|
96
|
-
pivotTable: EntityOrTableTargetResolver;
|
|
97
|
-
/** The pivot foreign key to root */
|
|
98
|
-
pivotForeignKeyToRoot?: string;
|
|
99
|
-
/** The pivot foreign key to target */
|
|
100
|
-
pivotForeignKeyToTarget?: string;
|
|
101
|
-
/** Optional local key */
|
|
102
|
-
localKey?: string;
|
|
103
|
-
/** Optional target key */
|
|
104
|
-
targetKey?: string;
|
|
105
|
-
/** Optional pivot primary key */
|
|
93
|
+
export interface BelongsToManyRelationMetadata extends BaseRelationMetadata {
|
|
94
|
+
/** The relation kind */
|
|
95
|
+
kind: typeof RelationKinds.BelongsToMany;
|
|
96
|
+
/** The pivot table */
|
|
97
|
+
pivotTable: EntityOrTableTargetResolver;
|
|
98
|
+
/** The pivot foreign key to root */
|
|
99
|
+
pivotForeignKeyToRoot?: string;
|
|
100
|
+
/** The pivot foreign key to target */
|
|
101
|
+
pivotForeignKeyToTarget?: string;
|
|
102
|
+
/** Optional local key */
|
|
103
|
+
localKey?: string;
|
|
104
|
+
/** Optional target key */
|
|
105
|
+
targetKey?: string;
|
|
106
|
+
/** Optional pivot primary key */
|
|
106
107
|
pivotPrimaryKey?: string;
|
|
107
108
|
/** Optional default pivot columns */
|
|
108
109
|
defaultPivotColumns?: string[];
|
|
@@ -130,6 +131,8 @@ export interface EntityMetadata<TColumns extends Record<string, ColumnDefLike> =
|
|
|
130
131
|
columns: TColumns;
|
|
131
132
|
/** The relations */
|
|
132
133
|
relations: Record<string, RelationMetadata>;
|
|
134
|
+
/** The transformers */
|
|
135
|
+
transformers: Record<string, TransformerMetadata>;
|
|
133
136
|
/** Optional hooks */
|
|
134
137
|
hooks?: TableHooks;
|
|
135
138
|
/** Optional table definition */
|
|
@@ -158,7 +161,8 @@ export const ensureEntityMetadata = (target: EntityConstructor): EntityMetadata
|
|
|
158
161
|
target,
|
|
159
162
|
tableName: target.name || 'unknown',
|
|
160
163
|
columns: {},
|
|
161
|
-
relations: {}
|
|
164
|
+
relations: {},
|
|
165
|
+
transformers: {}
|
|
162
166
|
};
|
|
163
167
|
metadataMap.set(target, meta);
|
|
164
168
|
}
|
|
@@ -219,6 +223,21 @@ export const addRelationMetadata = (
|
|
|
219
223
|
meta.relations[propertyKey] = relation;
|
|
220
224
|
};
|
|
221
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Adds transformer metadata to an entity.
|
|
228
|
+
* @param target - The entity constructor
|
|
229
|
+
* @param propertyKey - The property key
|
|
230
|
+
* @param transformer - The transformer metadata
|
|
231
|
+
*/
|
|
232
|
+
export const addTransformerMetadata = (
|
|
233
|
+
target: EntityConstructor,
|
|
234
|
+
propertyKey: string,
|
|
235
|
+
transformer: TransformerMetadata
|
|
236
|
+
): void => {
|
|
237
|
+
const meta = ensureEntityMetadata(target);
|
|
238
|
+
meta.transformers[propertyKey] = transformer;
|
|
239
|
+
};
|
|
240
|
+
|
|
222
241
|
/**
|
|
223
242
|
* Sets the table name and hooks for an entity.
|
|
224
243
|
* @param target - The entity constructor
|
|
@@ -250,15 +269,15 @@ export const buildTableDef = <TColumns extends Record<string, ColumnDefLike>>(me
|
|
|
250
269
|
return meta.table;
|
|
251
270
|
}
|
|
252
271
|
|
|
253
|
-
// Build columns using a simpler approach that avoids type assertion
|
|
254
|
-
const columns: Record<string, ColumnDef> = {};
|
|
255
|
-
for (const [key, def] of Object.entries(meta.columns)) {
|
|
256
|
-
columns[key] = {
|
|
257
|
-
...def,
|
|
258
|
-
name: def.name ?? key,
|
|
259
|
-
table: meta.tableName
|
|
260
|
-
} as ColumnDef;
|
|
261
|
-
}
|
|
272
|
+
// Build columns using a simpler approach that avoids type assertion
|
|
273
|
+
const columns: Record<string, ColumnDef> = {};
|
|
274
|
+
for (const [key, def] of Object.entries(meta.columns)) {
|
|
275
|
+
columns[key] = {
|
|
276
|
+
...def,
|
|
277
|
+
name: def.name ?? key,
|
|
278
|
+
table: meta.tableName
|
|
279
|
+
} as ColumnDef;
|
|
280
|
+
}
|
|
262
281
|
|
|
263
282
|
const table = defineTable(meta.tableName, columns as MaterializeColumns<TColumns>, {}, meta.hooks);
|
|
264
283
|
meta.table = table;
|