@arcaelas/dynamite 1.0.13 → 1.0.14
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/README.md +1165 -152
- package/package.json +6 -9
- package/LICENSE.txt +0 -32
- package/README.txt +0 -206
- package/SECURITY.md +0 -41
- package/src/@types/index.d.ts +0 -96
- package/src/@types/index.js +0 -9
- package/src/core/client.d.ts +0 -69
- package/src/core/client.js +0 -164
- package/src/core/table.d.ts +0 -98
- package/src/core/table.js +0 -459
- 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/index.d.ts +0 -22
- package/src/index.js +0 -47
- 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 -209
- package/src/utils/memory-manager.d.ts +0 -42
- package/src/utils/memory-manager.js +0 -108
- 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/relations.d.ts +0 -17
- package/src/utils/relations.js +0 -166
- package/src/utils/security-validator.d.ts +0 -49
- package/src/utils/security-validator.js +0 -152
- package/src/utils/throttle-manager.d.ts +0 -78
- package/src/utils/throttle-manager.js +0 -196
- package/src/utils/transaction-manager.d.ts +0 -88
- package/src/utils/transaction-manager.js +0 -298
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file circular-detector.ts
|
|
3
|
-
* @description Detection and prevention of circular references in relations
|
|
4
|
-
* @author Miguel Alejandro
|
|
5
|
-
* @fecha 2025-08-31
|
|
6
|
-
*/
|
|
7
|
-
interface TraversalPath {
|
|
8
|
-
modelName: string;
|
|
9
|
-
relationKey: string;
|
|
10
|
-
depth: number;
|
|
11
|
-
}
|
|
12
|
-
interface CircularDetectionConfig {
|
|
13
|
-
maxDepth: number;
|
|
14
|
-
maxIncludeDepth: number;
|
|
15
|
-
trackingEnabled: boolean;
|
|
16
|
-
}
|
|
17
|
-
declare class CircularReferenceDetector {
|
|
18
|
-
private static readonly DEFAULT_CONFIG;
|
|
19
|
-
private config;
|
|
20
|
-
private activePaths;
|
|
21
|
-
private pathHistory;
|
|
22
|
-
constructor(config?: Partial<CircularDetectionConfig>);
|
|
23
|
-
/**
|
|
24
|
-
* Verificar si una ruta de inclusión es segura
|
|
25
|
-
*/
|
|
26
|
-
validateIncludePath(modelName: string, includeOptions: any, currentDepth?: number, visitedModels?: Set<string>): void;
|
|
27
|
-
/**
|
|
28
|
-
* Validar estructura de relaciones en tiempo de definición
|
|
29
|
-
*/
|
|
30
|
-
validateRelationStructure(models: Map<string, any>, maxAllowedCycles?: number): ValidationResult;
|
|
31
|
-
/**
|
|
32
|
-
* Construir grafo de relaciones
|
|
33
|
-
*/
|
|
34
|
-
private buildRelationGraph;
|
|
35
|
-
/**
|
|
36
|
-
* Detectar ciclos usando DFS
|
|
37
|
-
*/
|
|
38
|
-
private detectCycles;
|
|
39
|
-
/**
|
|
40
|
-
* Generar sugerencias para resolver ciclos
|
|
41
|
-
*/
|
|
42
|
-
private generateSuggestions;
|
|
43
|
-
/**
|
|
44
|
-
* Inferir nombre del modelo target (simplificado)
|
|
45
|
-
*/
|
|
46
|
-
private inferTargetModelName;
|
|
47
|
-
/**
|
|
48
|
-
* Crear contexto de rastreo para includes anidados
|
|
49
|
-
*/
|
|
50
|
-
createTrackingContext(): CircularTracker;
|
|
51
|
-
/**
|
|
52
|
-
* Obtener historial de paths para debugging
|
|
53
|
-
*/
|
|
54
|
-
getPathHistory(): TraversalPath[];
|
|
55
|
-
/**
|
|
56
|
-
* Limpiar historial
|
|
57
|
-
*/
|
|
58
|
-
clearHistory(): void;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Tracker específico para una operación de include
|
|
62
|
-
*/
|
|
63
|
-
declare class CircularTracker {
|
|
64
|
-
private visitedModels;
|
|
65
|
-
private currentPath;
|
|
66
|
-
private maxDepth;
|
|
67
|
-
constructor(maxDepth: number);
|
|
68
|
-
enter(modelName: string): void;
|
|
69
|
-
exit(modelName: string): void;
|
|
70
|
-
getCurrentPath(): string[];
|
|
71
|
-
}
|
|
72
|
-
interface ValidationResult {
|
|
73
|
-
isValid: boolean;
|
|
74
|
-
cycles: string[][];
|
|
75
|
-
suggestions: string[];
|
|
76
|
-
}
|
|
77
|
-
declare class CircularReferenceError extends Error {
|
|
78
|
-
constructor(message: string);
|
|
79
|
-
}
|
|
80
|
-
declare const circularDetector: CircularReferenceDetector;
|
|
81
|
-
export { CircularReferenceDetector, CircularTracker, CircularReferenceError, ValidationResult, circularDetector };
|
|
82
|
-
export default circularDetector;
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file circular-detector.ts
|
|
4
|
-
* @description Detection and prevention of circular references in relations
|
|
5
|
-
* @author Miguel Alejandro
|
|
6
|
-
* @fecha 2025-08-31
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.circularDetector = exports.CircularReferenceError = exports.CircularTracker = exports.CircularReferenceDetector = void 0;
|
|
10
|
-
class CircularReferenceDetector {
|
|
11
|
-
static { this.DEFAULT_CONFIG = {
|
|
12
|
-
maxDepth: 10,
|
|
13
|
-
maxIncludeDepth: 5,
|
|
14
|
-
trackingEnabled: true,
|
|
15
|
-
}; }
|
|
16
|
-
constructor(config) {
|
|
17
|
-
this.activePaths = new Set();
|
|
18
|
-
this.pathHistory = [];
|
|
19
|
-
this.config = { ...CircularReferenceDetector.DEFAULT_CONFIG, ...config };
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Verificar si una ruta de inclusión es segura
|
|
23
|
-
*/
|
|
24
|
-
validateIncludePath(modelName, includeOptions, currentDepth = 0, visitedModels = new Set()) {
|
|
25
|
-
// Verificar profundidad máxima
|
|
26
|
-
if (currentDepth > this.config.maxIncludeDepth) {
|
|
27
|
-
throw new CircularReferenceError(`Include depth exceeded limit of ${this.config.maxIncludeDepth} at model: ${modelName}`);
|
|
28
|
-
}
|
|
29
|
-
// Detectar referencia circular directa
|
|
30
|
-
if (visitedModels.has(modelName)) {
|
|
31
|
-
const path = Array.from(visitedModels).join(' -> ') + ` -> ${modelName}`;
|
|
32
|
-
throw new CircularReferenceError(`Circular reference detected in include path: ${path}`);
|
|
33
|
-
}
|
|
34
|
-
if (!includeOptions || typeof includeOptions !== 'object') {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const newVisited = new Set(visitedModels);
|
|
38
|
-
newVisited.add(modelName);
|
|
39
|
-
// Validar cada relación incluida
|
|
40
|
-
for (const [relationKey, relationOptions] of Object.entries(includeOptions)) {
|
|
41
|
-
if (this.config.trackingEnabled) {
|
|
42
|
-
this.pathHistory.push({
|
|
43
|
-
modelName,
|
|
44
|
-
relationKey,
|
|
45
|
-
depth: currentDepth,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
// Si la relación tiene sus propios includes, validar recursivamente
|
|
49
|
-
if (relationOptions && typeof relationOptions === 'object' && 'include' in relationOptions) {
|
|
50
|
-
// Aquí necesitaríamos obtener el modelo target de la relación
|
|
51
|
-
// Por simplicidad, usamos el relationKey como modelo (esto debería mejorar)
|
|
52
|
-
const targetModelName = this.inferTargetModelName(relationKey);
|
|
53
|
-
this.validateIncludePath(targetModelName, relationOptions.include, currentDepth + 1, newVisited);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Validar estructura de relaciones en tiempo de definición
|
|
59
|
-
*/
|
|
60
|
-
validateRelationStructure(models, maxAllowedCycles = 0) {
|
|
61
|
-
const graph = this.buildRelationGraph(models);
|
|
62
|
-
const cycles = this.detectCycles(graph);
|
|
63
|
-
return {
|
|
64
|
-
isValid: cycles.length <= maxAllowedCycles,
|
|
65
|
-
cycles,
|
|
66
|
-
suggestions: this.generateSuggestions(cycles),
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Construir grafo de relaciones
|
|
71
|
-
*/
|
|
72
|
-
buildRelationGraph(models) {
|
|
73
|
-
const graph = new Map();
|
|
74
|
-
for (const [modelName, model] of models.entries()) {
|
|
75
|
-
const relations = [];
|
|
76
|
-
// Esto necesitaría acceso a los metadatos del modelo
|
|
77
|
-
// Por ahora simulamos la extracción de relaciones
|
|
78
|
-
const meta = model.getMeta?.();
|
|
79
|
-
if (meta?.relations) {
|
|
80
|
-
for (const [relationKey, relation] of meta.relations.entries()) {
|
|
81
|
-
const targetModel = relation.targetModel?.()?.name || relationKey;
|
|
82
|
-
relations.push(targetModel);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
graph.set(modelName, relations);
|
|
86
|
-
}
|
|
87
|
-
return graph;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Detectar ciclos usando DFS
|
|
91
|
-
*/
|
|
92
|
-
detectCycles(graph) {
|
|
93
|
-
const cycles = [];
|
|
94
|
-
const visited = new Set();
|
|
95
|
-
const recursionStack = new Set();
|
|
96
|
-
const dfs = (node, path) => {
|
|
97
|
-
if (recursionStack.has(node)) {
|
|
98
|
-
// Ciclo detectado
|
|
99
|
-
const cycleStart = path.indexOf(node);
|
|
100
|
-
const cycle = path.slice(cycleStart).concat(node);
|
|
101
|
-
cycles.push(cycle);
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
if (visited.has(node)) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
visited.add(node);
|
|
108
|
-
recursionStack.add(node);
|
|
109
|
-
path.push(node);
|
|
110
|
-
const neighbors = graph.get(node) || [];
|
|
111
|
-
for (const neighbor of neighbors) {
|
|
112
|
-
dfs(neighbor, [...path]);
|
|
113
|
-
}
|
|
114
|
-
recursionStack.delete(node);
|
|
115
|
-
};
|
|
116
|
-
for (const node of graph.keys()) {
|
|
117
|
-
if (!visited.has(node)) {
|
|
118
|
-
dfs(node, []);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return cycles;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Generar sugerencias para resolver ciclos
|
|
125
|
-
*/
|
|
126
|
-
generateSuggestions(cycles) {
|
|
127
|
-
const suggestions = [];
|
|
128
|
-
for (const cycle of cycles) {
|
|
129
|
-
if (cycle.length === 2) {
|
|
130
|
-
suggestions.push(`Circular reference between ${cycle[0]} and ${cycle[1]}. Consider using lazy loading or removing one direction.`);
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
suggestions.push(`Complex circular reference detected: ${cycle.join(' -> ')}. Consider breaking the cycle at the weakest relationship.`);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (cycles.length > 0) {
|
|
137
|
-
suggestions.push('General: Use @NonAttribute for computed relationships or implement lazy loading to break cycles.');
|
|
138
|
-
}
|
|
139
|
-
return suggestions;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Inferir nombre del modelo target (simplificado)
|
|
143
|
-
*/
|
|
144
|
-
inferTargetModelName(relationKey) {
|
|
145
|
-
// Conversión simple: posts -> Post, user -> User
|
|
146
|
-
return relationKey.charAt(0).toUpperCase() + relationKey.slice(1).replace(/s$/, '');
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Crear contexto de rastreo para includes anidados
|
|
150
|
-
*/
|
|
151
|
-
createTrackingContext() {
|
|
152
|
-
return new CircularTracker(this.config.maxIncludeDepth);
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Obtener historial de paths para debugging
|
|
156
|
-
*/
|
|
157
|
-
getPathHistory() {
|
|
158
|
-
return [...this.pathHistory];
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Limpiar historial
|
|
162
|
-
*/
|
|
163
|
-
clearHistory() {
|
|
164
|
-
this.pathHistory = [];
|
|
165
|
-
this.activePaths.clear();
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
exports.CircularReferenceDetector = CircularReferenceDetector;
|
|
169
|
-
/**
|
|
170
|
-
* Tracker específico para una operación de include
|
|
171
|
-
*/
|
|
172
|
-
class CircularTracker {
|
|
173
|
-
constructor(maxDepth) {
|
|
174
|
-
this.visitedModels = new Set();
|
|
175
|
-
this.currentPath = [];
|
|
176
|
-
this.maxDepth = maxDepth;
|
|
177
|
-
}
|
|
178
|
-
enter(modelName) {
|
|
179
|
-
if (this.currentPath.length >= this.maxDepth) {
|
|
180
|
-
throw new CircularReferenceError(`Maximum include depth ${this.maxDepth} exceeded at: ${modelName}`);
|
|
181
|
-
}
|
|
182
|
-
if (this.visitedModels.has(modelName)) {
|
|
183
|
-
const cyclePath = this.currentPath.join(' -> ') + ` -> ${modelName}`;
|
|
184
|
-
throw new CircularReferenceError(`Circular reference detected: ${cyclePath}`);
|
|
185
|
-
}
|
|
186
|
-
this.visitedModels.add(modelName);
|
|
187
|
-
this.currentPath.push(modelName);
|
|
188
|
-
}
|
|
189
|
-
exit(modelName) {
|
|
190
|
-
this.currentPath.pop();
|
|
191
|
-
this.visitedModels.delete(modelName);
|
|
192
|
-
}
|
|
193
|
-
getCurrentPath() {
|
|
194
|
-
return [...this.currentPath];
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
exports.CircularTracker = CircularTracker;
|
|
198
|
-
class CircularReferenceError extends Error {
|
|
199
|
-
constructor(message) {
|
|
200
|
-
super(message);
|
|
201
|
-
this.name = 'CircularReferenceError';
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
exports.CircularReferenceError = CircularReferenceError;
|
|
205
|
-
// Instancia singleton
|
|
206
|
-
const circularDetector = new CircularReferenceDetector();
|
|
207
|
-
exports.circularDetector = circularDetector;
|
|
208
|
-
exports.default = circularDetector;
|
|
209
|
-
//# sourceMappingURL=circular-detector.js.map
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file memory-manager.ts
|
|
3
|
-
* @description Memory management and leak prevention
|
|
4
|
-
* @author Miguel Alejandro
|
|
5
|
-
* @fecha 2025-08-31
|
|
6
|
-
*/
|
|
7
|
-
declare class MemoryManager {
|
|
8
|
-
private static instance;
|
|
9
|
-
private cleanupTasks;
|
|
10
|
-
private maxCacheSize;
|
|
11
|
-
private maxCacheAge;
|
|
12
|
-
static getInstance(): MemoryManager;
|
|
13
|
-
/**
|
|
14
|
-
* Registrar una tarea de limpieza
|
|
15
|
-
*/
|
|
16
|
-
registerCleanup(id: string, cleanup: () => void, intervalMs?: number): void;
|
|
17
|
-
/**
|
|
18
|
-
* Desregistrar y limpiar tarea
|
|
19
|
-
*/
|
|
20
|
-
unregisterCleanup(id: string): void;
|
|
21
|
-
/**
|
|
22
|
-
* Limpiar cache con límites de tamaño y edad
|
|
23
|
-
*/
|
|
24
|
-
cleanCache<T>(cache: Map<string, {
|
|
25
|
-
data: T;
|
|
26
|
-
expires: number;
|
|
27
|
-
created: number;
|
|
28
|
-
}>, maxSize?: number): void;
|
|
29
|
-
/**
|
|
30
|
-
* Monitorear uso de memoria
|
|
31
|
-
*/
|
|
32
|
-
getMemoryUsage(): NodeJS.MemoryUsage;
|
|
33
|
-
/**
|
|
34
|
-
* Forzar garbage collection si está disponible
|
|
35
|
-
*/
|
|
36
|
-
forceGC(): void;
|
|
37
|
-
/**
|
|
38
|
-
* Cleanup completo al shutdown
|
|
39
|
-
*/
|
|
40
|
-
shutdown(): void;
|
|
41
|
-
}
|
|
42
|
-
export default MemoryManager;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file memory-manager.ts
|
|
4
|
-
* @description Memory management and leak prevention
|
|
5
|
-
* @author Miguel Alejandro
|
|
6
|
-
* @fecha 2025-08-31
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
class MemoryManager {
|
|
10
|
-
constructor() {
|
|
11
|
-
this.cleanupTasks = new Map();
|
|
12
|
-
this.maxCacheSize = 1000;
|
|
13
|
-
this.maxCacheAge = 300000; // 5 minutos
|
|
14
|
-
}
|
|
15
|
-
static getInstance() {
|
|
16
|
-
if (!MemoryManager.instance) {
|
|
17
|
-
MemoryManager.instance = new MemoryManager();
|
|
18
|
-
}
|
|
19
|
-
return MemoryManager.instance;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Registrar una tarea de limpieza
|
|
23
|
-
*/
|
|
24
|
-
registerCleanup(id, cleanup, intervalMs) {
|
|
25
|
-
// Limpiar tarea previa si existe
|
|
26
|
-
this.unregisterCleanup(id);
|
|
27
|
-
const task = { id, cleanup };
|
|
28
|
-
if (intervalMs) {
|
|
29
|
-
task.interval = setInterval(() => {
|
|
30
|
-
try {
|
|
31
|
-
cleanup();
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
console.warn(`Cleanup task ${id} failed:`, error);
|
|
35
|
-
}
|
|
36
|
-
}, intervalMs);
|
|
37
|
-
}
|
|
38
|
-
this.cleanupTasks.set(id, task);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Desregistrar y limpiar tarea
|
|
42
|
-
*/
|
|
43
|
-
unregisterCleanup(id) {
|
|
44
|
-
const task = this.cleanupTasks.get(id);
|
|
45
|
-
if (task) {
|
|
46
|
-
if (task.interval) {
|
|
47
|
-
clearInterval(task.interval);
|
|
48
|
-
}
|
|
49
|
-
task.cleanup();
|
|
50
|
-
this.cleanupTasks.delete(id);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Limpiar cache con límites de tamaño y edad
|
|
55
|
-
*/
|
|
56
|
-
cleanCache(cache, maxSize = this.maxCacheSize) {
|
|
57
|
-
const now = Date.now();
|
|
58
|
-
// Remover entradas expiradas
|
|
59
|
-
for (const [key, entry] of cache.entries()) {
|
|
60
|
-
if (entry.expires <= now || (now - entry.created) > this.maxCacheAge) {
|
|
61
|
-
cache.delete(key);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// Si aún excede el tamaño, remover las más antiguas
|
|
65
|
-
if (cache.size > maxSize) {
|
|
66
|
-
const entries = Array.from(cache.entries())
|
|
67
|
-
.sort((a, b) => a[1].created - b[1].created);
|
|
68
|
-
const toRemove = entries.slice(0, cache.size - maxSize);
|
|
69
|
-
toRemove.forEach(([key]) => cache.delete(key));
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Monitorear uso de memoria
|
|
74
|
-
*/
|
|
75
|
-
getMemoryUsage() {
|
|
76
|
-
return process.memoryUsage();
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Forzar garbage collection si está disponible
|
|
80
|
-
*/
|
|
81
|
-
forceGC() {
|
|
82
|
-
if (global.gc) {
|
|
83
|
-
global.gc();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Cleanup completo al shutdown
|
|
88
|
-
*/
|
|
89
|
-
shutdown() {
|
|
90
|
-
console.log('MemoryManager: Iniciando cleanup completo...');
|
|
91
|
-
for (const [id, task] of this.cleanupTasks.entries()) {
|
|
92
|
-
try {
|
|
93
|
-
this.unregisterCleanup(id);
|
|
94
|
-
}
|
|
95
|
-
catch (error) {
|
|
96
|
-
console.warn(`Error cleaning up task ${id}:`, error);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
this.cleanupTasks.clear();
|
|
100
|
-
this.forceGC();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
// Cleanup automático en shutdown
|
|
104
|
-
process.on('SIGTERM', () => MemoryManager.getInstance().shutdown());
|
|
105
|
-
process.on('SIGINT', () => MemoryManager.getInstance().shutdown());
|
|
106
|
-
process.on('uncaughtException', () => MemoryManager.getInstance().shutdown());
|
|
107
|
-
exports.default = MemoryManager;
|
|
108
|
-
//# sourceMappingURL=memory-manager.js.map
|
package/src/utils/naming.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file naming.ts
|
|
3
|
-
* @descripcion Utilidades de conversión de nombres
|
|
4
|
-
* @autor Miguel Alejandro
|
|
5
|
-
* @fecha 2025-01-27
|
|
6
|
-
*/
|
|
7
|
-
/** Convierte nombre de clase a formato snake_case plural para tablas */
|
|
8
|
-
export declare function toSnakePlural(input: string): string;
|
package/src/utils/naming.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file naming.ts
|
|
4
|
-
* @descripcion Utilidades de conversión de nombres
|
|
5
|
-
* @autor Miguel Alejandro
|
|
6
|
-
* @fecha 2025-01-27
|
|
7
|
-
*/
|
|
8
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.toSnakePlural = toSnakePlural;
|
|
13
|
-
const pluralize_1 = __importDefault(require("pluralize"));
|
|
14
|
-
/** Convierte nombre de clase a formato snake_case plural para tablas */
|
|
15
|
-
function toSnakePlural(input) {
|
|
16
|
-
return (0, pluralize_1.default)(input.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase());
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=naming.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file projection.ts
|
|
3
|
-
* @description Selective field loading and projection optimization
|
|
4
|
-
* @autor Miguel Alejandro
|
|
5
|
-
* @fecha 2025-01-27
|
|
6
|
-
*/
|
|
7
|
-
/** Build DynamoDB ProjectionExpression */
|
|
8
|
-
export declare const buildProjection: (attributes?: string[], meta?: any) => string | undefined;
|
|
9
|
-
/** Optimize attributes loading for relations */
|
|
10
|
-
export declare const optimizeRelationAttributes: (include: any, baseAttributes?: string[]) => string[];
|
|
11
|
-
/** Smart attribute selection for common patterns */
|
|
12
|
-
export declare const getSmartAttributes: (Model: any, scenario: "list" | "detail" | "minimal") => string[];
|
package/src/utils/projection.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file projection.ts
|
|
4
|
-
* @description Selective field loading and projection optimization
|
|
5
|
-
* @autor Miguel Alejandro
|
|
6
|
-
* @fecha 2025-01-27
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.getSmartAttributes = exports.optimizeRelationAttributes = exports.buildProjection = void 0;
|
|
10
|
-
const wrapper_1 = require("../core/wrapper");
|
|
11
|
-
/** Build DynamoDB ProjectionExpression */
|
|
12
|
-
const buildProjection = (attributes, meta) => {
|
|
13
|
-
if (!attributes?.length || !meta)
|
|
14
|
-
return undefined;
|
|
15
|
-
// Validate attributes exist in model
|
|
16
|
-
const validAttributes = attributes.filter((attr) => meta.columns.has(attr) || meta.relations.has(attr));
|
|
17
|
-
return validAttributes.length ? validAttributes.join(", ") : undefined;
|
|
18
|
-
};
|
|
19
|
-
exports.buildProjection = buildProjection;
|
|
20
|
-
/** Optimize attributes loading for relations */
|
|
21
|
-
const optimizeRelationAttributes = (include, baseAttributes) => {
|
|
22
|
-
const attributes = new Set(baseAttributes || []);
|
|
23
|
-
// Add foreign keys needed for relations
|
|
24
|
-
Object.entries(include || {}).forEach(([relationKey, options]) => {
|
|
25
|
-
attributes.add(relationKey);
|
|
26
|
-
// Add foreign key fields
|
|
27
|
-
if (options?.foreignKey)
|
|
28
|
-
attributes.add(options.foreignKey);
|
|
29
|
-
if (options?.localKey)
|
|
30
|
-
attributes.add(options.localKey);
|
|
31
|
-
});
|
|
32
|
-
return Array.from(attributes);
|
|
33
|
-
};
|
|
34
|
-
exports.optimizeRelationAttributes = optimizeRelationAttributes;
|
|
35
|
-
/** Smart attribute selection for common patterns */
|
|
36
|
-
const getSmartAttributes = (Model, scenario) => {
|
|
37
|
-
const meta = (0, wrapper_1.mustMeta)(Model);
|
|
38
|
-
const columns = Array.from(meta.columns.keys());
|
|
39
|
-
switch (scenario) {
|
|
40
|
-
case "minimal":
|
|
41
|
-
return columns.filter((col) => meta.columns.get(col)?.primaryKey ||
|
|
42
|
-
["id", "name", "title", "email"].includes(col));
|
|
43
|
-
case "list":
|
|
44
|
-
return columns.filter((col) => !["description", "content", "body", "metadata"].includes(col));
|
|
45
|
-
case "detail":
|
|
46
|
-
default:
|
|
47
|
-
return columns;
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
exports.getSmartAttributes = getSmartAttributes;
|
|
51
|
-
//# sourceMappingURL=projection.js.map
|
package/src/utils/relations.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file relations.ts
|
|
3
|
-
* @descripcion Sistema de relaciones optimizado
|
|
4
|
-
* @autor Miguel Alejandro
|
|
5
|
-
* @fecha 2025-01-28
|
|
6
|
-
*/
|
|
7
|
-
/** Decorador @hasMany para relaciones 1:N */
|
|
8
|
-
export declare const hasMany: (targetModel: () => any, foreignKey: string, localKey?: string) => (target: any, propertyKey: string) => void;
|
|
9
|
-
/** Decorador @belongsTo para relaciones N:1 */
|
|
10
|
-
export declare const belongsTo: (targetModel: () => any, localKey: string, foreignKey?: string) => (target: any, propertyKey: string) => void;
|
|
11
|
-
/** Procesamiento optimizado de includes con batch loading transparente */
|
|
12
|
-
export declare const processIncludes: (Model: any, items: any[], include: Record<string, any>, depth?: number) => Promise<any[]>;
|
|
13
|
-
/** Separar opciones de query e include */
|
|
14
|
-
export declare const separateQueryOptions: (options: Record<string, any>) => {
|
|
15
|
-
queryOptions: Record<string, any>;
|
|
16
|
-
includeOptions: Record<string, any> | undefined;
|
|
17
|
-
};
|