jerkjs 2.3.1 → 2.4.0

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.
@@ -1,455 +0,0 @@
1
- /**
2
- * Sistema de Hooks y Filters para QueryBuilder en el framework JERK
3
- * Implementación del componente query/queryBuilderHooks.js
4
- * Proporciona integración completa con el sistema de hooks y filters de JERK
5
- */
6
-
7
- // Función para inicializar los hooks del QueryBuilder
8
- function initializeQueryBuilderHooks(hooks) {
9
- if (!hooks) {
10
- console.error('No se proporcionó un sistema de hooks para el QueryBuilder');
11
- return;
12
- }
13
-
14
- // Hook para antes de crear una instancia del QueryBuilder
15
- hooks.addAction('query_builder_before_create', (config) => {
16
- console.log('[HOOK] QueryBuilder antes de crear instancia', config);
17
- });
18
-
19
- // Hook para después de crear una instancia del QueryBuilder
20
- hooks.addAction('query_builder_after_create', (queryBuilder, config) => {
21
- console.log('[HOOK] QueryBuilder instancia creada', { tableName: queryBuilder.tableName });
22
- });
23
-
24
- // Filter para modificar la configuración antes de crear el QueryBuilder
25
- hooks.addFilter('query_builder_config', (config) => {
26
- // Añadir valores por defecto si no están presentes
27
- return {
28
- logQueries: false,
29
- cacheResults: false,
30
- ...config
31
- };
32
- });
33
-
34
- // Hook para antes de ejecutar una consulta SELECT
35
- hooks.addAction('query_builder_before_select', (sql, params, queryBuilder) => {
36
- console.log('[HOOK] QueryBuilder antes de SELECT', { sql, params });
37
- });
38
-
39
- // Hook para después de ejecutar una consulta SELECT
40
- hooks.addAction('query_builder_after_select', (results, sql, params, queryBuilder) => {
41
- console.log('[HOOK] QueryBuilder después de SELECT', { rowCount: results.length });
42
- });
43
-
44
- // Hook para antes de ejecutar una inserción
45
- hooks.addAction('query_builder_before_insert', (sql, data, queryBuilder) => {
46
- console.log('[HOOK] QueryBuilder antes de INSERT', { sql, dataKeys: Object.keys(data) });
47
- });
48
-
49
- // Hook para después de ejecutar una inserción
50
- hooks.addAction('query_builder_after_insert', (result, sql, data, queryBuilder) => {
51
- console.log('[HOOK] QueryBuilder después de INSERT', { insertId: result.insertId });
52
- });
53
-
54
- // Hook para antes de ejecutar una actualización
55
- hooks.addAction('query_builder_before_update', (sql, data, queryBuilder) => {
56
- console.log('[HOOK] QueryBuilder antes de UPDATE', { sql, dataKeys: Object.keys(data) });
57
- });
58
-
59
- // Hook para después de ejecutar una actualización
60
- hooks.addAction('query_builder_after_update', (result, sql, data, queryBuilder) => {
61
- console.log('[HOOK] QueryBuilder después de UPDATE', { affectedRows: result });
62
- });
63
-
64
- // Hook para antes de ejecutar una eliminación
65
- hooks.addAction('query_builder_before_delete', (sql, params, queryBuilder) => {
66
- console.log('[HOOK] QueryBuilder antes de DELETE', { sql, params });
67
- });
68
-
69
- // Hook para después de ejecutar una eliminación
70
- hooks.addAction('query_builder_after_delete', (result, sql, params, queryBuilder) => {
71
- console.log('[HOOK] QueryBuilder después de DELETE', { affectedRows: result });
72
- });
73
-
74
- // Filter para modificar la consulta antes de ejecutarla
75
- hooks.addFilter('query_builder_modify_query', (queryData, operation) => {
76
- const { sql, params } = queryData;
77
-
78
- // Ejemplo: añadir comentario con la operación realizada
79
- const modifiedSql = `${sql} /* JERK QueryBuilder: ${operation} */`;
80
-
81
- return { sql: modifiedSql, params };
82
- });
83
-
84
- // Filter para transformar resultados antes de devolverlos
85
- hooks.addFilter('query_builder_transform_results', (results, operation, queryBuilder) => {
86
- // Añadir metadatos a los resultados si es una operación de selección
87
- if (operation === 'select' && Array.isArray(results)) {
88
- return {
89
- data: results,
90
- metadata: {
91
- count: results.length,
92
- operation: operation,
93
- timestamp: new Date().toISOString()
94
- }
95
- };
96
- }
97
-
98
- return results;
99
- });
100
-
101
- // Hook para cuando ocurre un error en una consulta
102
- hooks.addAction('query_builder_error', (error, sql, params, queryBuilder, operation) => {
103
- console.error('[HOOK] QueryBuilder error en operación', {
104
- operation,
105
- error: error.message,
106
- sql,
107
- params
108
- });
109
- });
110
-
111
- // Hook para auditoría de consultas
112
- hooks.addAction('query_builder_audit', (operation, sql, params, queryBuilder, executionTime) => {
113
- console.log('[AUDIT] QueryBuilder operación auditada', {
114
- operation,
115
- executionTime: `${executionTime}ms`,
116
- sqlPreview: sql.substring(0, 100) + (sql.length > 100 ? '...' : '')
117
- });
118
- });
119
-
120
- // Filter para aplicar reglas de seguridad a las consultas
121
- hooks.addFilter('query_builder_security_check', (queryData, operation, queryBuilder) => {
122
- const { sql, params } = queryData;
123
-
124
- // Verificar si la consulta contiene patrones potencialmente peligrosos
125
- const dangerousPatterns = ['DROP ', 'TRUNCATE ', 'ALTER ', '--', '/*'];
126
-
127
- for (const pattern of dangerousPatterns) {
128
- if (sql.toUpperCase().includes(pattern)) {
129
- throw new Error(`Consulta bloqueada por seguridad: contiene '${pattern}'`);
130
- }
131
- }
132
-
133
- return queryData;
134
- });
135
-
136
- // Filter para aplicar límites de rendimiento
137
- hooks.addFilter('query_builder_performance_limit', (queryData, operation, queryBuilder) => {
138
- // Este filter podría ser usado para aplicar límites de rendimiento
139
- // basados en la complejidad de la consulta
140
- return queryData;
141
- });
142
- }
143
-
144
- // Función para extender el QueryBuilder con funcionalidad de hooks
145
- function extendQueryBuilderWithHooks(QueryBuilder, hooks) {
146
- if (!QueryBuilder || !hooks) {
147
- throw new Error('Se requieren QueryBuilder y hooks para extender funcionalidad');
148
- }
149
-
150
- // Guardar métodos originales
151
- const originalGet = QueryBuilder.prototype.get;
152
- const originalFirst = QueryBuilder.prototype.first;
153
- const originalInsert = QueryBuilder.prototype.insert;
154
- const originalUpdate = QueryBuilder.prototype.update;
155
- const originalDelete = QueryBuilder.prototype.delete;
156
-
157
- // Extender el método get con hooks
158
- QueryBuilder.prototype.get = async function() {
159
- const startTime = Date.now();
160
-
161
- // Disparar hook antes de la consulta
162
- hooks.doAction('query_builder_before_select', this.toSQL().sql, this.toSQL().params, this);
163
-
164
- try {
165
- // Modificar la consulta si es necesario usando filters
166
- const originalSQLData = this.toSQL();
167
- const modifiedSQLData = hooks.applyFilters(
168
- 'query_builder_modify_query',
169
- originalSQLData,
170
- 'select'
171
- );
172
-
173
- // Ejecutar la consulta original
174
- const results = await originalGet.call(this);
175
-
176
- // Transformar resultados si es necesario
177
- const transformedResults = hooks.applyFilters(
178
- 'query_builder_transform_results',
179
- results,
180
- 'select',
181
- this
182
- );
183
-
184
- // Calcular tiempo de ejecución
185
- const executionTime = Date.now() - startTime;
186
-
187
- // Disparar hook después de la consulta
188
- hooks.doAction(
189
- 'query_builder_after_select',
190
- results,
191
- modifiedSQLData.sql,
192
- modifiedSQLData.params,
193
- this
194
- );
195
-
196
- // Disparar hook de auditoría
197
- hooks.doAction(
198
- 'query_builder_audit',
199
- 'select',
200
- modifiedSQLData.sql,
201
- modifiedSQLData.params,
202
- this,
203
- executionTime
204
- );
205
-
206
- return transformedResults;
207
- } catch (error) {
208
- // Disparar hook de error
209
- hooks.doAction(
210
- 'query_builder_error',
211
- error,
212
- this.toSQL().sql,
213
- this.toSQL().params,
214
- this,
215
- 'select'
216
- );
217
-
218
- throw error;
219
- }
220
- };
221
-
222
- // Extender el método first con hooks
223
- QueryBuilder.prototype.first = async function() {
224
- const startTime = Date.now();
225
-
226
- // Disparar hook antes de la consulta
227
- hooks.doAction('query_builder_before_select', this.toSQL().sql, this.toSQL().params, this);
228
-
229
- try {
230
- // Modificar la consulta si es necesario usando filters
231
- const originalSQLData = this.toSQL();
232
- const modifiedSQLData = hooks.applyFilters(
233
- 'query_builder_modify_query',
234
- originalSQLData,
235
- 'select_first'
236
- );
237
-
238
- // Ejecutar la consulta original
239
- const result = await originalFirst.call(this);
240
-
241
- // Transformar resultados si es necesario
242
- const transformedResult = hooks.applyFilters(
243
- 'query_builder_transform_results',
244
- result,
245
- 'select_first',
246
- this
247
- );
248
-
249
- // Calcular tiempo de ejecución
250
- const executionTime = Date.now() - startTime;
251
-
252
- // Disparar hook después de la consulta
253
- hooks.doAction(
254
- 'query_builder_after_select',
255
- [result],
256
- modifiedSQLData.sql,
257
- modifiedSQLData.params,
258
- this
259
- );
260
-
261
- // Disparar hook de auditoría
262
- hooks.doAction(
263
- 'query_builder_audit',
264
- 'select_first',
265
- modifiedSQLData.sql,
266
- modifiedSQLData.params,
267
- this,
268
- executionTime
269
- );
270
-
271
- return transformedResult;
272
- } catch (error) {
273
- // Disparar hook de error
274
- hooks.doAction(
275
- 'query_builder_error',
276
- error,
277
- this.toSQL().sql,
278
- this.toSQL().params,
279
- this,
280
- 'select_first'
281
- );
282
-
283
- throw error;
284
- }
285
- };
286
-
287
- // Extender el método insert con hooks
288
- QueryBuilder.prototype.insert = async function(data) {
289
- const startTime = Date.now();
290
-
291
- // Aplicar chequeo de seguridad
292
- const queryData = {
293
- sql: `INSERT INTO \`${this.tableName}\``,
294
- params: Object.values(data)
295
- };
296
-
297
- const secureQueryData = hooks.applyFilters(
298
- 'query_builder_security_check',
299
- queryData,
300
- 'insert',
301
- this
302
- );
303
-
304
- // Disparar hook antes de la inserción
305
- hooks.doAction('query_builder_before_insert', secureQueryData.sql, data, this);
306
-
307
- try {
308
- // Ejecutar la inserción original
309
- const result = await originalInsert.call(this, data);
310
-
311
- // Calcular tiempo de ejecución
312
- const executionTime = Date.now() - startTime;
313
-
314
- // Disparar hook después de la inserción
315
- hooks.doAction('query_builder_after_insert', result, secureQueryData.sql, data, this);
316
-
317
- // Disparar hook de auditoría
318
- hooks.doAction(
319
- 'query_builder_audit',
320
- 'insert',
321
- secureQueryData.sql,
322
- secureQueryData.params,
323
- this,
324
- executionTime
325
- );
326
-
327
- return result;
328
- } catch (error) {
329
- // Disparar hook de error
330
- hooks.doAction(
331
- 'query_builder_error',
332
- error,
333
- secureQueryData.sql,
334
- secureQueryData.params,
335
- this,
336
- 'insert'
337
- );
338
-
339
- throw error;
340
- }
341
- };
342
-
343
- // Extender el método update con hooks
344
- QueryBuilder.prototype.update = async function(data) {
345
- const startTime = Date.now();
346
-
347
- // Aplicar chequeo de seguridad
348
- const queryData = {
349
- sql: `UPDATE \`${this.tableName}\``,
350
- params: [...Object.values(data), ...this.parameters]
351
- };
352
-
353
- const secureQueryData = hooks.applyFilters(
354
- 'query_builder_security_check',
355
- queryData,
356
- 'update',
357
- this
358
- );
359
-
360
- // Disparar hook antes de la actualización
361
- hooks.doAction('query_builder_before_update', secureQueryData.sql, data, this);
362
-
363
- try {
364
- // Ejecutar la actualización original
365
- const result = await originalUpdate.call(this, data);
366
-
367
- // Calcular tiempo de ejecución
368
- const executionTime = Date.now() - startTime;
369
-
370
- // Disparar hook después de la actualización
371
- hooks.doAction('query_builder_after_update', result, secureQueryData.sql, data, this);
372
-
373
- // Disparar hook de auditoría
374
- hooks.doAction(
375
- 'query_builder_audit',
376
- 'update',
377
- secureQueryData.sql,
378
- secureQueryData.params,
379
- this,
380
- executionTime
381
- );
382
-
383
- return result;
384
- } catch (error) {
385
- // Disparar hook de error
386
- hooks.doAction(
387
- 'query_builder_error',
388
- error,
389
- secureQueryData.sql,
390
- secureQueryData.params,
391
- this,
392
- 'update'
393
- );
394
-
395
- throw error;
396
- }
397
- };
398
-
399
- // Extender el método delete con hooks
400
- QueryBuilder.prototype.delete = async function() {
401
- const startTime = Date.now();
402
-
403
- // Aplicar chequeo de seguridad
404
- const originalSQLData = this.toSQL();
405
- const secureQueryData = hooks.applyFilters(
406
- 'query_builder_security_check',
407
- originalSQLData,
408
- 'delete',
409
- this
410
- );
411
-
412
- // Disparar hook antes de la eliminación
413
- hooks.doAction('query_builder_before_delete', secureQueryData.sql, secureQueryData.params, this);
414
-
415
- try {
416
- // Ejecutar la eliminación original
417
- const result = await originalDelete.call(this);
418
-
419
- // Calcular tiempo de ejecución
420
- const executionTime = Date.now() - startTime;
421
-
422
- // Disparar hook después de la eliminación
423
- hooks.doAction('query_builder_after_delete', result, secureQueryData.sql, secureQueryData.params, this);
424
-
425
- // Disparar hook de auditoría
426
- hooks.doAction(
427
- 'query_builder_audit',
428
- 'delete',
429
- secureQueryData.sql,
430
- secureQueryData.params,
431
- this,
432
- executionTime
433
- );
434
-
435
- return result;
436
- } catch (error) {
437
- // Disparar hook de error
438
- hooks.doAction(
439
- 'query_builder_error',
440
- error,
441
- secureQueryData.sql,
442
- secureQueryData.params,
443
- this,
444
- 'delete'
445
- );
446
-
447
- throw error;
448
- }
449
- };
450
- }
451
-
452
- module.exports = {
453
- initializeQueryBuilderHooks,
454
- extendQueryBuilderWithHooks
455
- };