forge-sql-orm 2.1.4 → 2.1.6

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 (52) hide show
  1. package/README.md +195 -27
  2. package/dist/ForgeSQLORM.js +632 -192
  3. package/dist/ForgeSQLORM.js.map +1 -1
  4. package/dist/ForgeSQLORM.mjs +632 -192
  5. package/dist/ForgeSQLORM.mjs.map +1 -1
  6. package/dist/core/ForgeSQLCrudOperations.d.ts.map +1 -1
  7. package/dist/core/ForgeSQLORM.d.ts +114 -3
  8. package/dist/core/ForgeSQLORM.d.ts.map +1 -1
  9. package/dist/core/ForgeSQLQueryBuilder.d.ts +125 -7
  10. package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
  11. package/dist/core/ForgeSQLSelectOperations.d.ts.map +1 -1
  12. package/dist/core/SystemTables.d.ts +3654 -0
  13. package/dist/core/SystemTables.d.ts.map +1 -1
  14. package/dist/lib/drizzle/extensions/additionalActions.d.ts +2 -2
  15. package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
  16. package/dist/utils/cacheContextUtils.d.ts.map +1 -1
  17. package/dist/utils/cacheUtils.d.ts.map +1 -1
  18. package/dist/utils/forgeDriver.d.ts +71 -3
  19. package/dist/utils/forgeDriver.d.ts.map +1 -1
  20. package/dist/utils/forgeDriverProxy.d.ts.map +1 -1
  21. package/dist/utils/metadataContextUtils.d.ts +11 -0
  22. package/dist/utils/metadataContextUtils.d.ts.map +1 -0
  23. package/dist/utils/requestTypeContextUtils.d.ts +8 -0
  24. package/dist/utils/requestTypeContextUtils.d.ts.map +1 -0
  25. package/dist/utils/sqlUtils.d.ts.map +1 -1
  26. package/dist/webtriggers/applyMigrationsWebTrigger.d.ts.map +1 -1
  27. package/dist/webtriggers/clearCacheSchedulerTrigger.d.ts.map +1 -1
  28. package/dist/webtriggers/dropMigrationWebTrigger.d.ts.map +1 -1
  29. package/dist/webtriggers/dropTablesMigrationWebTrigger.d.ts.map +1 -1
  30. package/dist/webtriggers/fetchSchemaWebTrigger.d.ts.map +1 -1
  31. package/dist/webtriggers/topSlowestStatementLastHourTrigger.d.ts +85 -43
  32. package/dist/webtriggers/topSlowestStatementLastHourTrigger.d.ts.map +1 -1
  33. package/package.json +9 -9
  34. package/src/core/ForgeSQLCrudOperations.ts +3 -0
  35. package/src/core/ForgeSQLORM.ts +287 -9
  36. package/src/core/ForgeSQLQueryBuilder.ts +138 -8
  37. package/src/core/ForgeSQLSelectOperations.ts +2 -0
  38. package/src/core/SystemTables.ts +16 -0
  39. package/src/lib/drizzle/extensions/additionalActions.ts +10 -12
  40. package/src/utils/cacheContextUtils.ts +4 -2
  41. package/src/utils/cacheUtils.ts +20 -8
  42. package/src/utils/forgeDriver.ts +223 -23
  43. package/src/utils/forgeDriverProxy.ts +2 -0
  44. package/src/utils/metadataContextUtils.ts +22 -0
  45. package/src/utils/requestTypeContextUtils.ts +11 -0
  46. package/src/utils/sqlUtils.ts +1 -0
  47. package/src/webtriggers/applyMigrationsWebTrigger.ts +9 -6
  48. package/src/webtriggers/clearCacheSchedulerTrigger.ts +1 -0
  49. package/src/webtriggers/dropMigrationWebTrigger.ts +2 -0
  50. package/src/webtriggers/dropTablesMigrationWebTrigger.ts +2 -0
  51. package/src/webtriggers/fetchSchemaWebTrigger.ts +1 -0
  52. package/src/webtriggers/topSlowestStatementLastHourTrigger.ts +515 -257
@@ -102,8 +102,9 @@ export async function saveQueryLocalCacheQuery<
102
102
  sql: sql.toSQL().sql.toLowerCase(),
103
103
  data: rows,
104
104
  };
105
- if (options.logRawSqlQuery) {
105
+ if (options.logCache) {
106
106
  const q = sql.toSQL();
107
+ // eslint-disable-next-line no-console
107
108
  console.debug(
108
109
  `[forge-sql-orm][local-cache][SAVE] Stored result in cache. sql="${q.sql}", params=${JSON.stringify(q.params)}`,
109
110
  );
@@ -140,8 +141,9 @@ export async function getQueryLocalCacheQuery<
140
141
  const sql = query as { toSQL: () => Query };
141
142
  const key = hashKey(sql.toSQL());
142
143
  if (context.cache[key] && context.cache[key].sql === sql.toSQL().sql.toLowerCase()) {
143
- if (options.logRawSqlQuery) {
144
+ if (options.logCache) {
144
145
  const q = sql.toSQL();
146
+ // eslint-disable-next-line no-console
145
147
  console.debug(
146
148
  `[forge-sql-orm][local-cache][HIT] Returned cached result. sql="${q.sql}", params=${JSON.stringify(q.params)}`,
147
149
  );
@@ -123,7 +123,8 @@ async function clearCursorCache(
123
123
 
124
124
  const listResult = await entityQueryBuilder.limit(100).getMany();
125
125
 
126
- if (options.logRawSqlQuery) {
126
+ if (options.logCache) {
127
+ // eslint-disable-next-line no-console
127
128
  console.warn(`clear cache Records: ${JSON.stringify(listResult.results.map((r) => r.key))}`);
128
129
  }
129
130
 
@@ -170,7 +171,8 @@ async function clearExpirationCursorCache(
170
171
 
171
172
  const listResult = await entityQueryBuilder.limit(100).getMany();
172
173
 
173
- if (options.logRawSqlQuery) {
174
+ if (options.logCache) {
175
+ // eslint-disable-next-line no-console
174
176
  console.warn(`clear expired Records: ${JSON.stringify(listResult.results.map((r) => r.key))}`);
175
177
  }
176
178
 
@@ -201,10 +203,12 @@ async function executeWithRetry<T>(operation: () => Promise<T>, operationName: s
201
203
  try {
202
204
  return await operation();
203
205
  } catch (err: any) {
206
+ // eslint-disable-next-line no-console
204
207
  console.warn(`Error during ${operationName}: ${err.message}, retry ${attempt}`, err);
205
208
  attempt++;
206
209
 
207
210
  if (attempt >= CACHE_CONSTANTS.MAX_RETRY_ATTEMPTS) {
211
+ // eslint-disable-next-line no-console
208
212
  console.error(`Error during ${operationName}: ${err.message}`, err);
209
213
  throw err;
210
214
  }
@@ -260,8 +264,9 @@ export async function clearTablesCache(
260
264
  "clearing cache",
261
265
  );
262
266
  } finally {
263
- if (options.logRawSqlQuery) {
267
+ if (options.logCache) {
264
268
  const duration = DateTime.now().toSeconds() - startTime.toSeconds();
269
+ // eslint-disable-next-line no-console
265
270
  console.info(`Cleared ${totalRecords} cache records in ${duration} seconds`);
266
271
  }
267
272
  }
@@ -287,7 +292,8 @@ export async function clearExpiredCache(options: ForgeSqlOrmOptions): Promise<vo
287
292
  );
288
293
  } finally {
289
294
  const duration = DateTime.now().toSeconds() - startTime.toSeconds();
290
- if (options?.logRawSqlQuery) {
295
+ if (options?.logCache) {
296
+ // eslint-disable-next-line no-console
291
297
  console.debug(`Cleared ${totalRecords} expired cache records in ${duration} seconds`);
292
298
  }
293
299
  }
@@ -318,7 +324,8 @@ export async function getFromCache<T>(
318
324
 
319
325
  // Skip cache if table is in cache context (will be cleared)
320
326
  if (await isTableContainsTableInCacheContext(sqlQuery.sql, options)) {
321
- if (options.logRawSqlQuery) {
327
+ if (options.logCache) {
328
+ // eslint-disable-next-line no-console
322
329
  console.warn(`Context contains value to clear. Skip getting from cache`);
323
330
  }
324
331
  return undefined;
@@ -332,13 +339,15 @@ export async function getFromCache<T>(
332
339
  (cacheResult[expirationName] as number) >= getCurrentTime() &&
333
340
  sqlQuery.sql.toLowerCase() === cacheResult[entityQueryName]
334
341
  ) {
335
- if (options.logRawSqlQuery) {
342
+ if (options.logCache) {
343
+ // eslint-disable-next-line no-console
336
344
  console.warn(`Get value from cache, cacheKey: ${key}`);
337
345
  }
338
346
  const results = cacheResult[dataName];
339
347
  return JSON.parse(results as string);
340
348
  }
341
349
  } catch (error: any) {
350
+ // eslint-disable-next-line no-console
342
351
  console.error(`Error getting from cache: ${error.message}`, error);
343
352
  }
344
353
 
@@ -375,7 +384,8 @@ export async function setCacheResult(
375
384
 
376
385
  // Skip cache if table is in cache context (will be cleared)
377
386
  if (await isTableContainsTableInCacheContext(sqlQuery.sql, options)) {
378
- if (options.logRawSqlQuery) {
387
+ if (options.logCache) {
388
+ // eslint-disable-next-line no-console
379
389
  console.warn(`Context contains value to clear. Skip setting from cache`);
380
390
  }
381
391
  return;
@@ -396,10 +406,12 @@ export async function setCacheResult(
396
406
  )
397
407
  .execute();
398
408
 
399
- if (options.logRawSqlQuery) {
409
+ if (options.logCache) {
410
+ // eslint-disable-next-line no-console
400
411
  console.warn(`Store value to cache, cacheKey: ${key}`);
401
412
  }
402
413
  } catch (error: any) {
414
+ // eslint-disable-next-line no-console
403
415
  console.error(`Error setting cache: ${error.message}`, error);
404
416
  }
405
417
  }
@@ -1,34 +1,234 @@
1
1
  import { sql, UpdateQueryResponse } from "@forge/sql";
2
+ import { saveMetaDataToContext } from "./metadataContextUtils";
3
+ import { getOperationType } from "./requestTypeContextUtils";
2
4
 
3
- interface ForgeSQLResult {
5
+ /**
6
+ * Metadata structure for Forge SQL query results.
7
+ * Contains execution timing, response size, and field information.
8
+ */
9
+ export type ForgeSQLMetadata = {
10
+ dbExecutionTime: number;
11
+ responseSize: number;
12
+ fields: {
13
+ catalog: string;
14
+ name: string;
15
+ schema: string;
16
+ characterSet: number;
17
+ decimals: number;
18
+ table: string;
19
+ orgTable: string;
20
+ orgName: string;
21
+ flags: number;
22
+ columnType: number;
23
+ columnLength: number;
24
+ }[];
25
+ };
26
+
27
+ /**
28
+ * Result structure for Forge SQL queries.
29
+ * Contains rows data and execution metadata.
30
+ */
31
+ export interface ForgeSQLResult {
4
32
  rows: Record<string, unknown>[] | Record<string, unknown>;
33
+ metadata: ForgeSQLMetadata;
5
34
  }
6
35
 
7
- export const forgeDriver = async (
8
- query: string,
9
- params: any[],
10
- method: "all" | "execute",
11
- ): Promise<{
12
- rows: any[];
36
+ /**
37
+ * Driver result structure for Drizzle ORM compatibility.
38
+ */
39
+ export interface ForgeDriverResult {
40
+ rows: unknown[];
13
41
  insertId?: number;
14
42
  affectedRows?: number;
15
- }> => {
16
- if (method == "execute") {
17
- const sqlStatement = sql.prepare<UpdateQueryResponse>(query);
18
- if (params) {
19
- sqlStatement.bindParams(...params);
43
+ }
44
+
45
+ /**
46
+ * Query execution method types.
47
+ */
48
+ export type QueryMethod = "all" | "execute";
49
+
50
+ /**
51
+ * Type guard to check if an object is an UpdateQueryResponse.
52
+ *
53
+ * @param obj - The object to check
54
+ * @returns True if the object is an UpdateQueryResponse
55
+ */
56
+ export function isUpdateQueryResponse(obj: unknown): obj is UpdateQueryResponse {
57
+ return (
58
+ obj !== null &&
59
+ typeof obj === "object" &&
60
+ typeof (obj as any).affectedRows === "number" &&
61
+ typeof (obj as any).insertId === "number"
62
+ );
63
+ }
64
+
65
+ /**
66
+ * Executes a promise with a timeout.
67
+ *
68
+ * @param promise - The promise to execute
69
+ * @param timeoutMs - Timeout in milliseconds (default: 10000ms)
70
+ * @returns Promise that resolves with the result or rejects on timeout
71
+ * @throws {Error} When the operation times out
72
+ */
73
+ async function withTimeout<T>(promise: Promise<T>, timeoutMs: number = 10000): Promise<T> {
74
+ let timeoutId: ReturnType<typeof setTimeout> | undefined;
75
+
76
+ const timeoutPromise = new Promise<never>((_, reject) => {
77
+ timeoutId = setTimeout(() => {
78
+ reject(
79
+ new Error(
80
+ `Atlassian @forge/sql did not return a response within ${timeoutMs}ms (${timeoutMs / 1000} seconds), so the request is blocked. Possible causes: slow query, network issues, or exceeding Forge SQL limits.`,
81
+ ),
82
+ );
83
+ }, timeoutMs);
84
+ });
85
+
86
+ try {
87
+ return await Promise.race([promise, timeoutPromise]);
88
+ } finally {
89
+ if (timeoutId) {
90
+ clearTimeout(timeoutId);
20
91
  }
21
- const updateQueryResponseResults = await sqlStatement.execute();
22
- let result = updateQueryResponseResults.rows as any;
23
- return { ...result, rows: [result] };
24
- } else {
25
- const sqlStatement = await sql.prepare<unknown>(query);
26
- if (params) {
27
- await sqlStatement.bindParams(...params);
92
+ }
93
+ }
94
+
95
+ function inlineParams(sql: string, params: unknown[]): string {
96
+ let i = 0;
97
+ return sql.replace(/\?/g, () => {
98
+ const val = params[i++];
99
+ if (val === null) return "NULL";
100
+ if (typeof val === "number") return val.toString();
101
+ return `'${String(val).replace(/'/g, "''")}'`;
102
+ });
103
+ }
104
+
105
+ /**
106
+ * Processes DDL query results and saves metadata.
107
+ *
108
+ * @param result - The DDL query result
109
+ * @returns Processed result for Drizzle ORM
110
+ */
111
+ async function processDDLResult(method: QueryMethod, result: any): Promise<ForgeDriverResult> {
112
+ if (result.metadata) {
113
+ await saveMetaDataToContext(result.metadata as ForgeSQLMetadata);
114
+ }
115
+
116
+ if (!result.rows) {
117
+ return { rows: [] };
118
+ }
119
+
120
+ if (isUpdateQueryResponse(result.rows)) {
121
+ const oneRow = result.rows as any;
122
+ return { ...oneRow, rows: [oneRow] };
123
+ }
124
+
125
+ if (Array.isArray(result.rows)) {
126
+ if (method === "execute") {
127
+ return { rows: result.rows };
128
+ } else {
129
+ const rows = (result.rows as any[]).map((r) => Object.values(r as Record<string, unknown>));
130
+ return { rows };
28
131
  }
29
- const result = (await sqlStatement.execute()) as ForgeSQLResult;
30
- let rows;
31
- rows = (result.rows as any[]).map((r) => Object.values(r as Record<string, unknown>));
32
- return { rows: rows };
33
132
  }
133
+
134
+ return { rows: [] };
135
+ }
136
+
137
+ /**
138
+ * Processes execute method results (UPDATE, INSERT, DELETE).
139
+ *
140
+ * @param query - The SQL query
141
+ * @param params - Query parameters
142
+ * @returns Processed result for Drizzle ORM
143
+ */
144
+ async function processExecuteMethod(query: string, params: unknown[]): Promise<ForgeDriverResult> {
145
+ const sqlStatement = sql.prepare<UpdateQueryResponse>(query);
146
+
147
+ if (params) {
148
+ sqlStatement.bindParams(...params);
149
+ }
150
+
151
+ const result = await withTimeout(sqlStatement.execute());
152
+ await saveMetaDataToContext(result.metadata as ForgeSQLMetadata);
153
+ if (!result.rows) {
154
+ return { rows: [] };
155
+ }
156
+
157
+ if (isUpdateQueryResponse(result.rows)) {
158
+ const oneRow = result.rows as any;
159
+ return { ...oneRow, rows: [oneRow] };
160
+ }
161
+
162
+ return { rows: result.rows };
163
+ }
164
+
165
+ /**
166
+ * Processes all method results (SELECT queries).
167
+ *
168
+ * @param query - The SQL query
169
+ * @param params - Query parameters
170
+ * @returns Processed result for Drizzle ORM
171
+ */
172
+ async function processAllMethod(query: string, params: unknown[]): Promise<ForgeDriverResult> {
173
+ const sqlStatement = await sql.prepare<unknown>(query);
174
+
175
+ if (params) {
176
+ await sqlStatement.bindParams(...params);
177
+ }
178
+
179
+ const result = (await withTimeout(sqlStatement.execute())) as ForgeSQLResult;
180
+ await saveMetaDataToContext(result.metadata);
181
+
182
+ if (!result.rows) {
183
+ return { rows: [] };
184
+ }
185
+
186
+ const rows = (result.rows as any[]).map((r) => Object.values(r as Record<string, unknown>));
187
+
188
+ return { rows };
189
+ }
190
+
191
+ /**
192
+ * Main Forge SQL driver function for Drizzle ORM integration.
193
+ * Handles DDL operations, execute operations (UPDATE/INSERT/DELETE), and select operations.
194
+ *
195
+ * @param query - The SQL query to execute
196
+ * @param params - Query parameters
197
+ * @param method - Execution method ("all" for SELECT, "execute" for UPDATE/INSERT/DELETE)
198
+ * @returns Promise with query results compatible with Drizzle ORM
199
+ *
200
+ * @throws {Error} When DDL operations are called with parameters
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * // DDL operation
205
+ * await forgeDriver("CREATE TABLE users (id INT)", [], "all");
206
+ *
207
+ * // SELECT operation
208
+ * await forgeDriver("SELECT * FROM users WHERE id = ?", [1], "all");
209
+ *
210
+ * // UPDATE operation
211
+ * await forgeDriver("UPDATE users SET name = ? WHERE id = ?", ["John", 1], "execute");
212
+ * ```
213
+ */
214
+ export const forgeDriver = async (
215
+ query: string,
216
+ params: unknown[],
217
+ method: QueryMethod,
218
+ ): Promise<ForgeDriverResult> => {
219
+ const operationType = await getOperationType();
220
+
221
+ // Handle DDL operations
222
+ if (operationType === "DDL") {
223
+ const result = await withTimeout(sql.executeDDL(inlineParams(query, params)));
224
+ return await processDDLResult(method, result);
225
+ }
226
+
227
+ // Handle execute method (UPDATE, INSERT, DELETE)
228
+ if (method === "execute") {
229
+ return await processExecuteMethod(query, params ?? []);
230
+ }
231
+
232
+ // Handle all method (SELECT)
233
+ return await processAllMethod(query, params ?? []);
34
234
  };
@@ -19,6 +19,7 @@ export function createForgeDriverProxy(options?: SqlHints, logRawSqlQuery?: bool
19
19
  const modifiedQuery = injectSqlHints(query, options);
20
20
 
21
21
  if (options && logRawSqlQuery && modifiedQuery !== query) {
22
+ // eslint-disable-next-line no-console
22
23
  console.debug("injected Hints: " + modifiedQuery);
23
24
  }
24
25
  try {
@@ -26,6 +27,7 @@ export function createForgeDriverProxy(options?: SqlHints, logRawSqlQuery?: bool
26
27
  return await forgeDriver(modifiedQuery, params, method);
27
28
  } catch (error) {
28
29
  if (logRawSqlQuery) {
30
+ // eslint-disable-next-line no-console
29
31
  console.debug("SQL Error:", JSON.stringify(error));
30
32
  }
31
33
  throw error;
@@ -0,0 +1,22 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { ForgeSQLMetadata } from "./forgeDriver";
3
+
4
+ export type MetadataQueryContext = {
5
+ totalDbExecutionTime: number;
6
+ totalResponseSize: number;
7
+ lastMetadata?: ForgeSQLMetadata;
8
+ };
9
+ export const metadataQueryContext = new AsyncLocalStorage<MetadataQueryContext>();
10
+
11
+ export async function saveMetaDataToContext(metadata: ForgeSQLMetadata): Promise<void> {
12
+ const context = metadataQueryContext.getStore();
13
+ if (context && metadata) {
14
+ context.totalResponseSize += metadata.responseSize;
15
+ context.totalDbExecutionTime += metadata.dbExecutionTime;
16
+ context.lastMetadata = metadata;
17
+ }
18
+ }
19
+
20
+ export async function getLastestMetadata(): Promise<MetadataQueryContext | undefined> {
21
+ return metadataQueryContext.getStore();
22
+ }
@@ -0,0 +1,11 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ export type OperationType = "DML" | "DDL";
3
+
4
+ export type OperationTypeQueryContext = {
5
+ operationType: OperationType;
6
+ };
7
+ export const operationTypeQueryContext = new AsyncLocalStorage<OperationTypeQueryContext>();
8
+
9
+ export async function getOperationType(): Promise<OperationType> {
10
+ return operationTypeQueryContext.getStore()?.operationType ?? "DML";
11
+ }
@@ -329,6 +329,7 @@ export function generateDropTableStatements(
329
329
  const dropStatements: string[] = [];
330
330
  const validOptions = options ?? { sequence: true, table: true };
331
331
  if (!validOptions.sequence && !validOptions.table) {
332
+ // eslint-disable-next-line no-console
332
333
  console.warn('No drop operations requested: both "table" and "sequence" options are false');
333
334
  return [];
334
335
  }
@@ -31,13 +31,15 @@ export const applySchemaMigrations = async (
31
31
  if (typeof migration !== "function") {
32
32
  throw new Error("migration is not a function");
33
33
  }
34
-
35
- console.log("Provisioning the database");
34
+ // eslint-disable-next-line no-console
35
+ console.debug("Provisioning the database");
36
36
  await sql._provision();
37
- console.info("Running schema migrations");
37
+ // eslint-disable-next-line no-console
38
+ console.debug("Running schema migrations");
38
39
  const migrations = await migration(migrationRunner);
39
40
  const successfulMigrations = await migrations.run();
40
- console.info("Migrations applied:", successfulMigrations);
41
+ // eslint-disable-next-line no-console
42
+ console.debug("Migrations applied:", successfulMigrations);
41
43
 
42
44
  const migrationList = await migrationRunner.list();
43
45
  let migrationHistory = "No migrations found";
@@ -51,8 +53,8 @@ export const applySchemaMigrations = async (
51
53
  .map((y) => `${y.id}, ${y.name}, ${y.migratedAt.toUTCString()}`)
52
54
  .join("\n");
53
55
  }
54
-
55
- console.info("Migrations history:\nid, name, migrated_at\n", migrationHistory);
56
+ // eslint-disable-next-line no-console
57
+ console.debug("Migrations history:\nid, name, migrated_at\n", migrationHistory);
56
58
 
57
59
  return {
58
60
  headers: { "Content-Type": ["application/json"] },
@@ -68,6 +70,7 @@ export const applySchemaMigrations = async (
68
70
  error?.debug?.context?.message ??
69
71
  error.message ??
70
72
  "Unknown error occurred";
73
+ // eslint-disable-next-line no-console
71
74
  console.error("Error during migration:", errorMessage);
72
75
  return {
73
76
  headers: { "Content-Type": ["application/json"] },
@@ -64,6 +64,7 @@ export const clearCacheSchedulerTrigger = async (options?: ForgeSqlOrmOptions) =
64
64
  }),
65
65
  };
66
66
  } catch (error) {
67
+ // eslint-disable-next-line no-console
67
68
  console.error("Error during cache cleanup: ", JSON.stringify(error));
68
69
  return {
69
70
  headers: { "Content-Type": ["application/json"] },
@@ -34,6 +34,7 @@ export async function dropSchemaMigrations(): Promise<TriggerResponse<string>> {
34
34
 
35
35
  // Execute each statement
36
36
  for (const statement of dropStatements) {
37
+ // eslint-disable-next-line no-console
37
38
  console.debug(`execute DDL: ${statement}`);
38
39
  await sql.executeDDL(statement);
39
40
  }
@@ -48,6 +49,7 @@ export async function dropSchemaMigrations(): Promise<TriggerResponse<string>> {
48
49
  error?.debug?.message ??
49
50
  error.message ??
50
51
  "Unknown error occurred";
52
+ // eslint-disable-next-line no-console
51
53
  console.error(errorMessage);
52
54
  return getHttpResponse<string>(500, errorMessage);
53
55
  }
@@ -34,6 +34,7 @@ export async function dropTableSchemaMigrations(): Promise<TriggerResponse<strin
34
34
 
35
35
  // Execute each statement
36
36
  for (const statement of dropStatements) {
37
+ // eslint-disable-next-line no-console
37
38
  console.debug(`execute DDL: ${statement}`);
38
39
  await sql.executeDDL(statement);
39
40
  }
@@ -48,6 +49,7 @@ export async function dropTableSchemaMigrations(): Promise<TriggerResponse<strin
48
49
  error?.debug?.message ??
49
50
  error.message ??
50
51
  "Unknown error occurred";
52
+ // eslint-disable-next-line no-console
51
53
  console.error(errorMessage);
52
54
  return getHttpResponse<string>(500, errorMessage);
53
55
  }
@@ -46,6 +46,7 @@ export async function fetchSchemaWebTrigger(): Promise<TriggerResponse<string>>
46
46
  error?.debug?.message ??
47
47
  error.message ??
48
48
  "Unknown error occurred";
49
+ // eslint-disable-next-line no-console
49
50
  console.error(errorMessage);
50
51
  return getHttpResponse<string>(500, errorMessage);
51
52
  }