@arcaelas/dynamite 1.0.17 → 1.0.18
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/package.json +40 -2
- package/src/@types/index.d.ts +27 -21
- package/src/core/client.d.ts +36 -0
- package/src/core/client.js +80 -27
- package/src/core/decorator.d.ts +44 -0
- package/src/core/decorator.js +133 -0
- package/src/core/method.d.ts +73 -0
- package/src/core/method.js +140 -0
- package/src/core/table.d.ts +44 -86
- package/src/core/table.js +510 -310
- package/src/decorators/indexes.d.ts +38 -0
- package/src/decorators/indexes.js +67 -0
- package/src/decorators/relations.d.ts +55 -0
- package/src/decorators/relations.js +84 -0
- package/src/decorators/timestamps.d.ts +54 -0
- package/src/decorators/timestamps.js +67 -0
- package/src/decorators/transforms.d.ts +86 -0
- package/src/decorators/transforms.js +154 -0
- package/src/index.d.ts +9 -16
- package/src/index.js +35 -32
- package/src/index.test.d.ts +13 -0
- package/src/index.test.js +1992 -0
- package/src/utils/relations.d.ts +34 -12
- package/src/utils/relations.js +109 -133
- package/src/core/wrapper.d.ts +0 -17
- package/src/core/wrapper.js +0 -46
- package/src/decorators/belongs_to.d.ts +0 -1
- package/src/decorators/belongs_to.js +0 -24
- package/src/decorators/created_at.d.ts +0 -1
- package/src/decorators/created_at.js +0 -11
- package/src/decorators/default.d.ts +0 -1
- package/src/decorators/default.js +0 -47
- package/src/decorators/has_many.d.ts +0 -1
- package/src/decorators/has_many.js +0 -24
- package/src/decorators/index.d.ts +0 -11
- package/src/decorators/index.js +0 -36
- package/src/decorators/index_sort.d.ts +0 -12
- package/src/decorators/index_sort.js +0 -43
- package/src/decorators/mutate.d.ts +0 -2
- package/src/decorators/mutate.js +0 -51
- package/src/decorators/name.d.ts +0 -1
- package/src/decorators/name.js +0 -28
- package/src/decorators/not_null.d.ts +0 -1
- package/src/decorators/not_null.js +0 -13
- package/src/decorators/primary_key.d.ts +0 -6
- package/src/decorators/primary_key.js +0 -30
- package/src/decorators/updated_at.d.ts +0 -12
- package/src/decorators/updated_at.js +0 -26
- package/src/decorators/validate.d.ts +0 -1
- package/src/decorators/validate.js +0 -53
- package/src/utils/batch-relations.d.ts +0 -14
- package/src/utils/batch-relations.js +0 -131
- package/src/utils/circular-detector.d.ts +0 -82
- package/src/utils/circular-detector.js +0 -212
- package/src/utils/memory-manager.d.ts +0 -42
- package/src/utils/memory-manager.js +0 -107
- package/src/utils/naming.d.ts +0 -8
- package/src/utils/naming.js +0 -18
- package/src/utils/projection.d.ts +0 -12
- package/src/utils/projection.js +0 -51
- package/src/utils/security-validator.d.ts +0 -49
- package/src/utils/security-validator.js +0 -163
- package/src/utils/throttle-manager.d.ts +0 -78
- package/src/utils/throttle-manager.js +0 -201
- package/src/utils/transaction-manager.d.ts +0 -88
- package/src/utils/transaction-manager.js +0 -300
package/src/utils/relations.d.ts
CHANGED
|
@@ -1,17 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file relations.ts
|
|
3
|
-
* @
|
|
3
|
+
* @description Sistema de carga de relaciones con batch loading
|
|
4
4
|
* @autor Miguel Alejandro
|
|
5
5
|
* @fecha 2025-01-28
|
|
6
6
|
*/
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
/**
|
|
8
|
+
* @description Opciones para include de relaciones
|
|
9
|
+
*/
|
|
10
|
+
interface IncludeOptions {
|
|
11
|
+
where?: Record<string, any>;
|
|
12
|
+
limit?: number;
|
|
13
|
+
offset?: number;
|
|
14
|
+
order?: 'asc' | 'desc';
|
|
15
|
+
include?: Record<string, IncludeOptions | boolean>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @description Procesa includes recursivamente para cargar relaciones
|
|
19
|
+
* @param items Array de instancias a poblar
|
|
20
|
+
* @param include Objeto con relaciones a incluir
|
|
21
|
+
* @param TableClass Clase de la tabla actual
|
|
22
|
+
* @param depth Profundidad actual (máximo 10)
|
|
23
|
+
* @returns Items con relaciones pobladas
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* // Uso interno en Table.where()
|
|
27
|
+
* await processIncludes(users, {
|
|
28
|
+
* posts: {
|
|
29
|
+
* where: { published: true },
|
|
30
|
+
* limit: 5,
|
|
31
|
+
* include: {
|
|
32
|
+
* comments: true
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
* }, User);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare const processIncludes: (items: any[], include: Record<string, IncludeOptions | boolean>, TableClass: any, depth?: number) => Promise<any[]>;
|
|
39
|
+
export {};
|
package/src/utils/relations.js
CHANGED
|
@@ -1,165 +1,141 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* @file relations.ts
|
|
4
|
-
* @
|
|
4
|
+
* @description Sistema de carga de relaciones con batch loading
|
|
5
5
|
* @autor Miguel Alejandro
|
|
6
6
|
* @fecha 2025-01-28
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
type: "hasMany",
|
|
19
|
-
targetModel,
|
|
20
|
-
foreignKey,
|
|
21
|
-
localKey,
|
|
22
|
-
});
|
|
23
|
-
Object.defineProperty(target, propertyKey, {
|
|
24
|
-
get() {
|
|
25
|
-
const cached = this[`_${propertyKey}`];
|
|
26
|
-
return cached !== undefined
|
|
27
|
-
? cached
|
|
28
|
-
: (console.warn(`Relación ${propertyKey} no cargada. Use includes en la consulta.`),
|
|
29
|
-
[]);
|
|
30
|
-
},
|
|
31
|
-
configurable: true,
|
|
32
|
-
enumerable: false,
|
|
33
|
-
});
|
|
34
|
-
};
|
|
35
|
-
exports.hasMany = hasMany;
|
|
36
|
-
/** Decorador @belongsTo para relaciones N:1 */
|
|
37
|
-
const belongsTo = (targetModel, localKey, foreignKey = "id") => (target, propertyKey) => {
|
|
38
|
-
(0, wrapper_1.ensureConfig)(target.constructor, (0, naming_1.toSnakePlural)(target.constructor.name)).relations.set(propertyKey, {
|
|
39
|
-
type: "belongsTo",
|
|
40
|
-
targetModel,
|
|
41
|
-
localKey,
|
|
42
|
-
foreignKey,
|
|
43
|
-
});
|
|
44
|
-
Object.defineProperty(target, propertyKey, {
|
|
45
|
-
get() {
|
|
46
|
-
const cached = this[`_${propertyKey}`];
|
|
47
|
-
return cached !== undefined
|
|
48
|
-
? cached
|
|
49
|
-
: (console.warn(`Relación ${propertyKey} no cargada. Use includes en la consulta.`),
|
|
50
|
-
null);
|
|
51
|
-
},
|
|
52
|
-
configurable: true,
|
|
53
|
-
enumerable: false,
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
exports.belongsTo = belongsTo;
|
|
57
|
-
// =============================================================================
|
|
58
|
-
// FUNCTIONS
|
|
59
|
-
// =============================================================================
|
|
60
|
-
/** Batch loading para relaciones hasMany */
|
|
61
|
-
const batchLoadHasMany = async (Model, items, relation, options = {}) => {
|
|
62
|
-
const { targetModel, foreignKey, localKey = "id" } = relation;
|
|
63
|
-
const parent_keys = items.map((item) => item[localKey]).filter(Boolean);
|
|
64
|
-
if (!parent_keys.length)
|
|
9
|
+
exports.processIncludes = void 0;
|
|
10
|
+
const decorator_1 = require("../core/decorator");
|
|
11
|
+
/**
|
|
12
|
+
* @description Batch load para HasMany/HasOne
|
|
13
|
+
* Obtiene items relacionados donde foreignKey IN parent_ids
|
|
14
|
+
*/
|
|
15
|
+
const batchLoadHasMany = async (items, relation, options = {}) => {
|
|
16
|
+
const parent_ids = items.map(i => i[relation.localKey]).filter(Boolean);
|
|
17
|
+
if (!parent_ids.length)
|
|
65
18
|
return new Map();
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
//
|
|
19
|
+
// Obtener clase del modelo relacionado
|
|
20
|
+
const RelatedModel = relation.model();
|
|
21
|
+
// Query básico
|
|
22
|
+
let related = await RelatedModel.where(relation.foreignKey, 'in', parent_ids);
|
|
23
|
+
// Aplicar filtros adicionales
|
|
69
24
|
if (options.where) {
|
|
70
|
-
|
|
71
|
-
for (const [key, value] of additionalFilters) {
|
|
72
|
-
const currentResults = await query;
|
|
73
|
-
query = Promise.resolve(currentResults.filter((item) => item[key] === value));
|
|
74
|
-
}
|
|
25
|
+
related = related.filter((item) => Object.entries(options.where).every(([k, v]) => item[k] === v));
|
|
75
26
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
filteredItems.sort((a, b) => b.id.localeCompare(a.id));
|
|
27
|
+
// Ordenar
|
|
28
|
+
if (options.order) {
|
|
29
|
+
related.sort((a, b) => {
|
|
30
|
+
const aId = String(a.id ?? '');
|
|
31
|
+
const bId = String(b.id ?? '');
|
|
32
|
+
return options.order === 'asc' ? aId.localeCompare(bId) : bId.localeCompare(aId);
|
|
33
|
+
});
|
|
84
34
|
}
|
|
85
|
-
|
|
86
|
-
|
|
35
|
+
// Agrupar por foreignKey
|
|
36
|
+
const grouped = new Map();
|
|
37
|
+
for (const item of related) {
|
|
38
|
+
const key = String(item[relation.foreignKey]);
|
|
39
|
+
if (!grouped.has(key))
|
|
40
|
+
grouped.set(key, []);
|
|
41
|
+
grouped.get(key).push(item);
|
|
87
42
|
}
|
|
43
|
+
// Aplicar limit por grupo
|
|
88
44
|
if (options.limit) {
|
|
89
|
-
|
|
45
|
+
for (const [key, groupItems] of grouped) {
|
|
46
|
+
grouped.set(key, groupItems.slice(options.offset ?? 0, (options.offset ?? 0) + options.limit));
|
|
47
|
+
}
|
|
90
48
|
}
|
|
91
|
-
const grouped = new Map();
|
|
92
|
-
filteredItems.forEach((item) => {
|
|
93
|
-
const key = item[foreignKey];
|
|
94
|
-
grouped.has(key) ? grouped.get(key).push(item) : grouped.set(key, [item]);
|
|
95
|
-
});
|
|
96
49
|
return grouped;
|
|
97
50
|
};
|
|
98
|
-
/**
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (!keys.length)
|
|
51
|
+
/**
|
|
52
|
+
* @description Batch load para BelongsTo
|
|
53
|
+
* Obtiene items donde id IN local_keys
|
|
54
|
+
*/
|
|
55
|
+
const batchLoadBelongsTo = async (items, relation, _options = {}) => {
|
|
56
|
+
const local_keys = items.map(i => i[relation.localKey]).filter(Boolean);
|
|
57
|
+
if (!local_keys.length)
|
|
106
58
|
return new Map();
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
processedItems.forEach((item) => results.set(item[foreignKey], item));
|
|
115
|
-
return results;
|
|
59
|
+
const RelatedModel = relation.model();
|
|
60
|
+
const related = await RelatedModel.where(relation.foreignKey, 'in', local_keys);
|
|
61
|
+
const result = new Map();
|
|
62
|
+
for (const item of related) {
|
|
63
|
+
result.set(String(item[relation.foreignKey]), item);
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
116
66
|
};
|
|
117
|
-
/**
|
|
118
|
-
|
|
67
|
+
/**
|
|
68
|
+
* @description Procesa includes recursivamente para cargar relaciones
|
|
69
|
+
* @param items Array de instancias a poblar
|
|
70
|
+
* @param include Objeto con relaciones a incluir
|
|
71
|
+
* @param TableClass Clase de la tabla actual
|
|
72
|
+
* @param depth Profundidad actual (máximo 10)
|
|
73
|
+
* @returns Items con relaciones pobladas
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* // Uso interno en Table.where()
|
|
77
|
+
* await processIncludes(users, {
|
|
78
|
+
* posts: {
|
|
79
|
+
* where: { published: true },
|
|
80
|
+
* limit: 5,
|
|
81
|
+
* include: {
|
|
82
|
+
* comments: true
|
|
83
|
+
* }
|
|
84
|
+
* }
|
|
85
|
+
* }, User);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
const processIncludes = async (items, include, TableClass, depth = 0) => {
|
|
119
89
|
if (!include || depth > 10 || !items.length)
|
|
120
90
|
return items;
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
91
|
+
const schema = TableClass[decorator_1.SCHEMA];
|
|
92
|
+
if (!schema)
|
|
93
|
+
return items;
|
|
94
|
+
const promises = Object.entries(include).map(async ([relation_key, options]) => {
|
|
95
|
+
const column = schema.columns[relation_key];
|
|
96
|
+
if (!column?.store?.relation)
|
|
125
97
|
return;
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
98
|
+
const relation = column.store.relation;
|
|
99
|
+
const opts = typeof options === 'boolean' ? {} : options;
|
|
100
|
+
// Batch load según tipo
|
|
101
|
+
let data;
|
|
102
|
+
if (relation.type === 'HasMany') {
|
|
103
|
+
data = await batchLoadHasMany(items, relation, opts);
|
|
104
|
+
}
|
|
105
|
+
else if (relation.type === 'HasOne') {
|
|
106
|
+
const hasMany = await batchLoadHasMany(items, relation, { ...opts, limit: 1 });
|
|
107
|
+
data = new Map();
|
|
108
|
+
for (const [k, v] of hasMany) {
|
|
109
|
+
data.set(k, v[0] ?? null);
|
|
138
110
|
}
|
|
139
|
-
|
|
140
|
-
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// BelongsTo
|
|
114
|
+
data = await batchLoadBelongsTo(items, relation, opts);
|
|
115
|
+
}
|
|
116
|
+
// Asignar datos relacionados a cada item
|
|
117
|
+
for (const item of items) {
|
|
118
|
+
const key = String(item[relation.localKey]);
|
|
119
|
+
const value = relation.type === 'HasMany'
|
|
120
|
+
? data.get(key) ?? []
|
|
121
|
+
: data.get(key) ?? null;
|
|
141
122
|
Object.defineProperty(item, relation_key, {
|
|
142
|
-
value
|
|
123
|
+
value,
|
|
143
124
|
writable: true,
|
|
144
125
|
enumerable: true,
|
|
145
|
-
configurable: true
|
|
126
|
+
configurable: true
|
|
146
127
|
});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
128
|
+
}
|
|
129
|
+
// Recursión para includes anidados
|
|
130
|
+
if (opts.include && data.size) {
|
|
131
|
+
const all_related = Array.from(data.values()).flat().filter(Boolean);
|
|
132
|
+
if (all_related.length) {
|
|
133
|
+
await (0, exports.processIncludes)(all_related, opts.include, relation.model(), depth + 1);
|
|
134
|
+
}
|
|
153
135
|
}
|
|
154
136
|
});
|
|
155
|
-
await Promise.all(
|
|
137
|
+
await Promise.all(promises);
|
|
156
138
|
return items;
|
|
157
139
|
};
|
|
158
140
|
exports.processIncludes = processIncludes;
|
|
159
|
-
/** Separar opciones de query e include */
|
|
160
|
-
const separateQueryOptions = (options) => {
|
|
161
|
-
const { include, ...queryOptions } = options;
|
|
162
|
-
return { queryOptions, includeOptions: include };
|
|
163
|
-
};
|
|
164
|
-
exports.separateQueryOptions = separateQueryOptions;
|
|
165
141
|
//# sourceMappingURL=relations.js.map
|
package/src/core/wrapper.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file wrapper.ts
|
|
3
|
-
* @descripcion Sistema de tipos y wrapper optimizado
|
|
4
|
-
* @autor Miguel Alejandro
|
|
5
|
-
* @fecha 2025-01-28
|
|
6
|
-
*/
|
|
7
|
-
import type { Column, WrapperEntry } from "../@types/index";
|
|
8
|
-
export type { BelongsTo, Column, CreationOptional, FilterableAttributes, HasMany, IncludeOptions, IncludeRelationOptions, InferAttributes, Mutate, NonAttribute, QueryOperator, QueryResult, Validate, WhereOptions, WhereOptionsWithoutWhere, WhereQueryOptions, WrapperEntry, } from "../@types/index";
|
|
9
|
-
export declare const STORE: unique symbol;
|
|
10
|
-
declare const wrapper: Map<Function, WrapperEntry>;
|
|
11
|
-
/** Obtener o crear entrada wrapper para constructor */
|
|
12
|
-
export declare const ensureConfig: (ctor: Function, table_name: string) => WrapperEntry;
|
|
13
|
-
/** Obtener o crear configuración de columna para propiedad */
|
|
14
|
-
export declare const ensureColumn: (entry: WrapperEntry, prop: string | symbol, column_name: string) => Column;
|
|
15
|
-
/** Obtener metadatos requeridos (throws si no existen) */
|
|
16
|
-
export declare const mustMeta: (ctor: Function) => WrapperEntry;
|
|
17
|
-
export default wrapper;
|
package/src/core/wrapper.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file wrapper.ts
|
|
4
|
-
* @descripcion Sistema de tipos y wrapper optimizado
|
|
5
|
-
* @autor Miguel Alejandro
|
|
6
|
-
* @fecha 2025-01-28
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.mustMeta = exports.ensureColumn = exports.ensureConfig = exports.STORE = void 0;
|
|
10
|
-
exports.STORE = Symbol("dynamite:values");
|
|
11
|
-
const wrapper = new Map();
|
|
12
|
-
/** Obtener o crear entrada wrapper para constructor */
|
|
13
|
-
const ensureConfig = (ctor, table_name) => {
|
|
14
|
-
const existing = wrapper.get(ctor);
|
|
15
|
-
if (existing)
|
|
16
|
-
return existing;
|
|
17
|
-
const entry = {
|
|
18
|
-
name: table_name,
|
|
19
|
-
columns: new Map(),
|
|
20
|
-
relations: new Map(),
|
|
21
|
-
};
|
|
22
|
-
wrapper.set(ctor, entry);
|
|
23
|
-
return entry;
|
|
24
|
-
};
|
|
25
|
-
exports.ensureConfig = ensureConfig;
|
|
26
|
-
/** Obtener o crear configuración de columna para propiedad */
|
|
27
|
-
const ensureColumn = (entry, prop, column_name) => {
|
|
28
|
-
const existing = entry.columns.get(prop);
|
|
29
|
-
if (existing)
|
|
30
|
-
return existing;
|
|
31
|
-
const column = { name: column_name, mutate: [], validate: [] };
|
|
32
|
-
entry.columns.set(prop, column);
|
|
33
|
-
return column;
|
|
34
|
-
};
|
|
35
|
-
exports.ensureColumn = ensureColumn;
|
|
36
|
-
/** Obtener metadatos requeridos (throws si no existen) */
|
|
37
|
-
const mustMeta = (ctor) => {
|
|
38
|
-
const meta = wrapper.get(ctor);
|
|
39
|
-
if (!meta) {
|
|
40
|
-
throw new Error(`Metadatos no encontrados para ${ctor.name}. ¿Usaste decoradores @Index, @PrimaryKey, etc.?`);
|
|
41
|
-
}
|
|
42
|
-
return meta;
|
|
43
|
-
};
|
|
44
|
-
exports.mustMeta = mustMeta;
|
|
45
|
-
exports.default = wrapper;
|
|
46
|
-
//# sourceMappingURL=wrapper.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function BelongsTo(targetModel: () => any, localKey: string, foreignKey?: string): PropertyDecorator;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = BelongsTo;
|
|
4
|
-
const wrapper_1 = require("../core/wrapper");
|
|
5
|
-
function BelongsTo(targetModel, localKey, foreignKey) {
|
|
6
|
-
return (target, prop) => {
|
|
7
|
-
const entry = (0, wrapper_1.ensureConfig)(target.constructor, target.constructor.name);
|
|
8
|
-
entry.relations.set(prop, {
|
|
9
|
-
type: "belongsTo",
|
|
10
|
-
targetModel,
|
|
11
|
-
foreignKey: foreignKey || "id",
|
|
12
|
-
localKey,
|
|
13
|
-
});
|
|
14
|
-
// Crear getter dinámico para la relación
|
|
15
|
-
Object.defineProperty(target, prop, {
|
|
16
|
-
get() {
|
|
17
|
-
return this[`_${prop.toString()}`] || null;
|
|
18
|
-
},
|
|
19
|
-
enumerable: true,
|
|
20
|
-
configurable: true,
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
//# sourceMappingURL=belongs_to.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function CreatedAt(): PropertyDecorator;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.default = CreatedAt;
|
|
7
|
-
const default_1 = __importDefault(require("./default"));
|
|
8
|
-
function CreatedAt() {
|
|
9
|
-
return (0, default_1.default)(() => new Date().toISOString());
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=created_at.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function Default(factory: any): PropertyDecorator;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = Default;
|
|
4
|
-
const wrapper_1 = require("../core/wrapper");
|
|
5
|
-
const naming_1 = require("../utils/naming");
|
|
6
|
-
function Default(factory) {
|
|
7
|
-
return (target, prop) => {
|
|
8
|
-
const ctor = target.constructor;
|
|
9
|
-
const entry = (0, wrapper_1.ensureConfig)(ctor, (0, naming_1.toSnakePlural)(ctor.name));
|
|
10
|
-
const column = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
|
|
11
|
-
if (column.default)
|
|
12
|
-
throw new Error(`@Default duplicado en '${String(prop)}'`);
|
|
13
|
-
column.default = typeof factory === "function" ? factory : () => factory;
|
|
14
|
-
!Object.getOwnPropertyDescriptor(ctor.prototype, prop)?.set &&
|
|
15
|
-
defineVirtual(ctor.prototype, column, prop);
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function defineVirtual(proto, col, prop) {
|
|
19
|
-
Object.defineProperty(proto, prop, {
|
|
20
|
-
get() {
|
|
21
|
-
return (this[wrapper_1.STORE] ?? {})[prop];
|
|
22
|
-
},
|
|
23
|
-
set(val) {
|
|
24
|
-
const buf = (this[wrapper_1.STORE] ??= {});
|
|
25
|
-
val =
|
|
26
|
-
val === undefined && col.default !== undefined
|
|
27
|
-
? typeof col.default === "function"
|
|
28
|
-
? col.default()
|
|
29
|
-
: col.default
|
|
30
|
-
: val;
|
|
31
|
-
if (col.mutate)
|
|
32
|
-
for (const m of col.mutate)
|
|
33
|
-
val = m(val);
|
|
34
|
-
if (col.validate) {
|
|
35
|
-
for (const v of col.validate) {
|
|
36
|
-
const r = v(val);
|
|
37
|
-
if (r !== true)
|
|
38
|
-
throw new Error(typeof r === "string" ? r : "Validación fallida");
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
buf[prop] = val;
|
|
42
|
-
},
|
|
43
|
-
enumerable: true,
|
|
44
|
-
configurable: true,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=default.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function HasMany(targetModel: () => any, foreignKey: string, localKey?: string): PropertyDecorator;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = HasMany;
|
|
4
|
-
const wrapper_1 = require("../core/wrapper");
|
|
5
|
-
function HasMany(targetModel, foreignKey, localKey) {
|
|
6
|
-
return (target, prop) => {
|
|
7
|
-
const entry = (0, wrapper_1.ensureConfig)(target.constructor, target.constructor.name);
|
|
8
|
-
entry.relations.set(prop, {
|
|
9
|
-
type: "hasMany",
|
|
10
|
-
targetModel,
|
|
11
|
-
foreignKey,
|
|
12
|
-
localKey: localKey || "id",
|
|
13
|
-
});
|
|
14
|
-
// Crear getter dinámico para la relación
|
|
15
|
-
Object.defineProperty(target, prop, {
|
|
16
|
-
get() {
|
|
17
|
-
return this[`_${prop.toString()}`] || [];
|
|
18
|
-
},
|
|
19
|
-
enumerable: true,
|
|
20
|
-
configurable: true,
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
//# sourceMappingURL=has_many.js.map
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file index.ts
|
|
3
|
-
* @descripcion Decorador @Index para Partition Key
|
|
4
|
-
* @autor Miguel Alejandro
|
|
5
|
-
* @fecha 2025-01-27
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Decorador para marcar propiedad como Partition Key.
|
|
9
|
-
* Configura la propiedad como índice principal para consultas.
|
|
10
|
-
*/
|
|
11
|
-
export default function Index(): PropertyDecorator;
|
package/src/decorators/index.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file index.ts
|
|
4
|
-
* @descripcion Decorador @Index para Partition Key
|
|
5
|
-
* @autor Miguel Alejandro
|
|
6
|
-
* @fecha 2025-01-27
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.default = Index;
|
|
10
|
-
const wrapper_1 = require("../core/wrapper");
|
|
11
|
-
const naming_1 = require("../utils/naming");
|
|
12
|
-
/**
|
|
13
|
-
* Decorador para marcar propiedad como Partition Key.
|
|
14
|
-
* Configura la propiedad como índice principal para consultas.
|
|
15
|
-
*/
|
|
16
|
-
function Index() {
|
|
17
|
-
return (target, prop) => {
|
|
18
|
-
const ctor = target.constructor;
|
|
19
|
-
const tableName = (0, naming_1.toSnakePlural)(ctor.name);
|
|
20
|
-
const entry = (0, wrapper_1.ensureConfig)(ctor, tableName);
|
|
21
|
-
// Verificar si ya existe un índice primario
|
|
22
|
-
const existingIndex = [...entry.columns.values()].find((col) => col.index === true);
|
|
23
|
-
if (existingIndex && existingIndex.name !== String(prop)) {
|
|
24
|
-
throw new Error(`La tabla ${tableName} ya tiene definida una PartitionKey (${existingIndex.name}). ` +
|
|
25
|
-
`No se puede definir otra PartitionKey en '${String(prop)}'`);
|
|
26
|
-
}
|
|
27
|
-
// Obtener o crear la columna y marcar como índice
|
|
28
|
-
const column = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
|
|
29
|
-
column.index = true;
|
|
30
|
-
// Asegurar que la columna no sea nula por defecto
|
|
31
|
-
if (column.nullable === undefined) {
|
|
32
|
-
column.nullable = false;
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file index_sort.ts
|
|
3
|
-
* @descripcion Decorador @IndexSort para Sort Key
|
|
4
|
-
* @autor Miguel Alejandro
|
|
5
|
-
* @fecha 2025-01-27
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Decorador para marcar propiedad como Sort Key.
|
|
9
|
-
* Configura la propiedad como clave de ordenación para consultas.
|
|
10
|
-
* Requiere que exista una PartitionKey (@Index) definida previamente.
|
|
11
|
-
*/
|
|
12
|
-
export default function IndexSort(): PropertyDecorator;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file index_sort.ts
|
|
4
|
-
* @descripcion Decorador @IndexSort para Sort Key
|
|
5
|
-
* @autor Miguel Alejandro
|
|
6
|
-
* @fecha 2025-01-27
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.default = IndexSort;
|
|
10
|
-
const wrapper_1 = require("../core/wrapper");
|
|
11
|
-
const naming_1 = require("../utils/naming");
|
|
12
|
-
/**
|
|
13
|
-
* Decorador para marcar propiedad como Sort Key.
|
|
14
|
-
* Configura la propiedad como clave de ordenación para consultas.
|
|
15
|
-
* Requiere que exista una PartitionKey (@Index) definida previamente.
|
|
16
|
-
*/
|
|
17
|
-
function IndexSort() {
|
|
18
|
-
return (target, prop) => {
|
|
19
|
-
const ctor = target.constructor;
|
|
20
|
-
const tableName = (0, naming_1.toSnakePlural)(ctor.name);
|
|
21
|
-
const entry = (0, wrapper_1.ensureConfig)(ctor, tableName);
|
|
22
|
-
// Verificar que exista una PartitionKey definida
|
|
23
|
-
const hasPartitionKey = [...entry.columns.values()].some((col) => col.index === true);
|
|
24
|
-
if (!hasPartitionKey) {
|
|
25
|
-
throw new Error(`No se puede definir una SortKey en '${String(prop)}' sin una PartitionKey. ` +
|
|
26
|
-
`Asegúrate de marcar una propiedad con @Index primero.`);
|
|
27
|
-
}
|
|
28
|
-
// Verificar si ya existe una SortKey
|
|
29
|
-
const existingSortKey = [...entry.columns.values()].find((col) => col.indexSort === true);
|
|
30
|
-
if (existingSortKey && existingSortKey.name !== String(prop)) {
|
|
31
|
-
throw new Error(`La tabla ${tableName} ya tiene una SortKey definida (${existingSortKey.name}). ` +
|
|
32
|
-
`No se puede definir otra SortKey en '${String(prop)}'`);
|
|
33
|
-
}
|
|
34
|
-
// Obtener o crear la columna y marcar como índice de ordenación
|
|
35
|
-
const column = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
|
|
36
|
-
column.indexSort = true;
|
|
37
|
-
// Asegurar que la columna no sea nula por defecto
|
|
38
|
-
if (column.nullable === undefined) {
|
|
39
|
-
column.nullable = false;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=index_sort.js.map
|