forge-sql-orm 2.0.7 → 2.0.8

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 CHANGED
@@ -23,14 +23,53 @@ import { drizzle } from "drizzle-orm/mysql-core";
23
23
  import { forgeDriver } from "forge-sql-orm";
24
24
  const db = drizzle(forgeDriver);
25
25
  ```
26
- Best for: Simple CRUD operations without optimistic locking
26
+ Best for: Simple CRUD operations without optimistic locking. Note that you need to manually set `mapSelectFieldsWithAlias` for select fields to prevent field name collisions in Atlassian Forge SQL.
27
27
 
28
28
  ### 2. Full Forge-SQL-ORM Usage
29
29
  ```typescript
30
30
  import ForgeSQL from "forge-sql-orm";
31
31
  const forgeSQL = new ForgeSQL();
32
32
  ```
33
- Best for: Advanced features like optimistic locking and automatic versioning
33
+ Best for: Advanced features like optimistic locking, automatic versioning, and automatic field name collision prevention in complex queries.
34
+
35
+ ## Field Name Collision Prevention in Complex Queries
36
+
37
+ When working with complex queries involving multiple tables (joins, inner joins, etc.), Atlassian Forge SQL has a specific behavior where fields with the same name from different tables get collapsed into a single field with a null value. This is not a Drizzle ORM issue but rather a characteristic of Atlassian Forge SQL's behavior.
38
+
39
+ Forge-SQL-ORM provides two ways to handle this:
40
+
41
+ ### Using Forge-SQL-ORM
42
+ ```typescript
43
+ import ForgeSQL from "forge-sql-orm";
44
+
45
+ const forgeSQL = new ForgeSQL();
46
+
47
+ // Automatic field name collision prevention
48
+ await forgeSQL
49
+ .select({user: users, order: orders})
50
+ .from(orders)
51
+ .innerJoin(users, eq(orders.userId, users.id));
52
+ ```
53
+
54
+ ### Using Direct Drizzle
55
+ ```typescript
56
+ import { drizzle } from "drizzle-orm/mysql-core";
57
+ import { forgeDriver, mapSelectFieldsWithAlias } from "forge-sql-orm";
58
+
59
+ const db = drizzle(forgeDriver);
60
+
61
+ // Manual field name collision prevention
62
+ await db
63
+ .select(mapSelectFieldsWithAlias({user: users, order: orders}))
64
+ .from(orders)
65
+ .innerJoin(users, eq(orders.userId, users.id));
66
+ ```
67
+
68
+ ### Important Notes
69
+ - This is a specific behavior of Atlassian Forge SQL, not Drizzle ORM
70
+ - For complex queries involving multiple tables, it's recommended to always specify select fields and avoid using `select()` without field selection
71
+ - The solution automatically creates unique aliases for each field by prefixing them with the table name
72
+ - This ensures that fields with the same name from different tables remain distinct in the query results
34
73
 
35
74
  ## Installation
36
75
 
@@ -40,7 +79,7 @@ Forge-SQL-ORM is designed to work with @forge/sql and requires some additional s
40
79
 
41
80
  ```sh
42
81
  npm install forge-sql-orm @forge/sql drizzle-orm momment -S
43
- npm install mysql2 @types/mysql2 drizzle-kit -D
82
+ npm install mysql2 drizzle-kit inquirer@8.0.0 -D
44
83
  ```
45
84
 
46
85
  This will:
@@ -293,13 +332,13 @@ const users = await db.select().from(users);
293
332
  // Using forgeSQL.getDrizzleQueryBuilder()
294
333
  const user = await forgeSQL
295
334
  .getDrizzleQueryBuilder()
296
- .select("*").from(Users)
335
+ .select().from(Users)
297
336
  .where(eq(Users.id, 1));
298
337
 
299
338
  // OR using direct drizzle with custom driver
300
339
  const db = drizzle(forgeDriver);
301
340
  const user = await db
302
- .select("*").from(Users)
341
+ .select().from(Users)
303
342
  .where(eq(Users.id, 1));
304
343
  // Returns: { id: 1, name: "John Doe" }
305
344
 
@@ -309,7 +348,7 @@ const user = await forgeSQL
309
348
  .executeQueryOnlyOne(
310
349
  forgeSQL
311
350
  .getDrizzleQueryBuilder()
312
- .select("*").from(Users)
351
+ .select().from(Users)
313
352
  .where(eq(Users.id, 1))
314
353
  );
315
354
  // Returns: { id: 1, name: "John Doe" }
@@ -322,67 +361,69 @@ const usersAlias = alias(Users, "u");
322
361
  const result = await forgeSQL
323
362
  .getDrizzleQueryBuilder()
324
363
  .select({
325
- userId: rawSql`${usersAlias.id} as \`userId\``,
326
- userName: rawSql`${usersAlias.name} as \`userName\``
364
+ userId: sql<string>`${usersAlias.id} as \`userId\``,
365
+ userName: sql<string>`${usersAlias.name} as \`userName\``
327
366
  }).from(usersAlias);
328
367
 
329
368
  // OR with direct drizzle
330
369
  const db = drizzle(forgeDriver);
331
370
  const result = await db
332
371
  .select({
333
- userId: rawSql`${usersAlias.id} as \`userId\``,
334
- userName: rawSql`${usersAlias.name} as \`userName\``
372
+ userId: sql<string>`${usersAlias.id} as \`userId\``,
373
+ userName: sql<string>`${usersAlias.name} as \`userName\``
335
374
  }).from(usersAlias);
336
375
  // Returns: { userId: 1, userName: "John Doe" }
376
+ ```
377
+
378
+ ### Complex Queries
379
+ ```js
337
380
 
338
- // Using joins
381
+ // Using joins with automatic field name collision prevention
339
382
  // With forgeSQL
340
383
  const orderWithUser = await forgeSQL
341
- .getDrizzleQueryBuilder()
342
- .select({
343
- orderId: rawSql`${Orders.id} as \`orderId\``,
344
- product: Orders.product,
345
- userName: rawSql`${Users.name} as \`userName\``
346
- }).from(Orders)
347
- .innerJoin(Users, eq(Orders.userId, Users.id))
348
- .where(eq(Orders.id, 1));
384
+ .select({user: users, order: orders})
385
+ .from(orders)
386
+ .innerJoin(users, eq(orders.userId, users.id));
349
387
 
350
388
  // OR with direct drizzle
351
389
  const db = drizzle(forgeDriver);
352
390
  const orderWithUser = await db
353
- .select({
354
- orderId: rawSql`${Orders.id} as \`orderId\``,
355
- product: Orders.product,
356
- userName: rawSql`${Users.name} as \`userName\``
357
- }).from(Orders)
358
- .innerJoin(Users, eq(Orders.userId, Users.id))
359
- .where(eq(Orders.id, 1));
360
- // Returns: { orderId: 1, product: "Product 1", userName: "John Doe" }
361
- ```
362
-
363
- ### Complex Queries with Aggregations
391
+ .select(mapSelectFieldsWithAlias({user: users, order: orders}))
392
+ .from(orders)
393
+ .innerJoin(users, eq(orders.userId, users.id));
394
+ // Returns: {
395
+ // user_id: 1,
396
+ // user_name: "John Doe",
397
+ // order_id: 1,
398
+ // order_product: "Product 1"
399
+ // }
400
+
401
+ // Using distinct select with automatic field name collision prevention
402
+ const uniqueOrdersWithUsers = await forgeSQL
403
+ .selectDistinct({user: users, order: orders})
404
+ .from(orders)
405
+ .innerJoin(users, eq(orders.userId, users.id));
364
406
 
365
- ```js
366
407
  // Finding duplicates
367
408
  // With forgeSQL
368
409
  const duplicates = await forgeSQL
369
410
  .getDrizzleQueryBuilder()
370
411
  .select({
371
412
  name: Users.name,
372
- count: rawSql`COUNT(*) as \`count\``
413
+ count: sql<number>`COUNT(*) as \`count\``
373
414
  }).from(Users)
374
415
  .groupBy(Users.name)
375
- .having(rawSql`COUNT(*) > 1`);
416
+ .having(sql`COUNT(*) > 1`);
376
417
 
377
418
  // OR with direct drizzle
378
419
  const db = drizzle(forgeDriver);
379
420
  const duplicates = await db
380
421
  .select({
381
422
  name: Users.name,
382
- count: rawSql`COUNT(*) as \`count\``
423
+ count: sql<number>`COUNT(*) as \`count\``
383
424
  }).from(Users)
384
425
  .groupBy(Users.name)
385
- .having(rawSql`COUNT(*) > 1`);
426
+ .having(sql`COUNT(*) > 1`);
386
427
  // Returns: { name: "John Doe", count: 2 }
387
428
 
388
429
  // Using executeQueryOnlyOne for unique results
@@ -392,8 +433,8 @@ const userStats = await forgeSQL
392
433
  forgeSQL
393
434
  .getDrizzleQueryBuilder()
394
435
  .select({
395
- totalUsers: rawSql`COUNT(*) as \`totalUsers\``,
396
- uniqueNames: rawSql`COUNT(DISTINCT name) as \`uniqueNames\``
436
+ totalUsers: sql`COUNT(*) as \`totalUsers\``,
437
+ uniqueNames: sql`COUNT(DISTINCT name) as \`uniqueNames\``
397
438
  }).from(Users)
398
439
  );
399
440
  // Returns: { totalUsers: 100, uniqueNames: 80 }
@@ -2,7 +2,9 @@
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const drizzleOrm = require("drizzle-orm");
4
4
  const moment = require("moment");
5
- const sql = require("@forge/sql");
5
+ const table = require("drizzle-orm/table");
6
+ const sql = require("drizzle-orm/sql/sql");
7
+ const sql$1 = require("@forge/sql");
6
8
  const mysql2 = require("drizzle-orm/mysql2");
7
9
  const mysqlCore = require("drizzle-orm/mysql-core");
8
10
  const moment$1 = require("moment/moment.js");
@@ -17,8 +19,8 @@ function extractAlias(query) {
17
19
  const match = query.match(/\bas\s+(['"`]?)([\w*]+)\1$/i);
18
20
  return match ? match[2] : query;
19
21
  }
20
- function getPrimaryKeys(table) {
21
- const { columns, primaryKeys } = getTableMetadata(table);
22
+ function getPrimaryKeys(table2) {
23
+ const { columns, primaryKeys } = getTableMetadata(table2);
22
24
  const columnPrimaryKeys = Object.entries(columns).filter(([, column]) => column.primary);
23
25
  if (columnPrimaryKeys.length > 0) {
24
26
  return columnPrimaryKeys;
@@ -36,10 +38,10 @@ function getPrimaryKeys(table) {
36
38
  }
37
39
  return [];
38
40
  }
39
- function processForeignKeys(table, foreignKeysSymbol, extraSymbol) {
41
+ function processForeignKeys(table2, foreignKeysSymbol, extraSymbol) {
40
42
  const foreignKeys = [];
41
43
  if (foreignKeysSymbol) {
42
- const fkArray = table[foreignKeysSymbol];
44
+ const fkArray = table2[foreignKeysSymbol];
43
45
  if (fkArray) {
44
46
  fkArray.forEach((fk) => {
45
47
  if (fk.reference) {
@@ -50,9 +52,9 @@ function processForeignKeys(table, foreignKeysSymbol, extraSymbol) {
50
52
  }
51
53
  }
52
54
  if (extraSymbol) {
53
- const extraConfigBuilder = table[extraSymbol];
55
+ const extraConfigBuilder = table2[extraSymbol];
54
56
  if (extraConfigBuilder && typeof extraConfigBuilder === "function") {
55
- const configBuilderData = extraConfigBuilder(table);
57
+ const configBuilderData = extraConfigBuilder(table2);
56
58
  if (configBuilderData) {
57
59
  const configBuilders = Array.isArray(configBuilderData) ? configBuilderData : Object.values(configBuilderData).map(
58
60
  (item) => item.value || item
@@ -69,8 +71,8 @@ function processForeignKeys(table, foreignKeysSymbol, extraSymbol) {
69
71
  }
70
72
  return foreignKeys;
71
73
  }
72
- function getTableMetadata(table) {
73
- const symbols = Object.getOwnPropertySymbols(table);
74
+ function getTableMetadata(table2) {
75
+ const symbols = Object.getOwnPropertySymbols(table2);
74
76
  const nameSymbol = symbols.find((s) => s.toString().includes("Name"));
75
77
  const columnsSymbol = symbols.find((s) => s.toString().includes("Columns"));
76
78
  const foreignKeysSymbol = symbols.find((s) => s.toString().includes("ForeignKeys)"));
@@ -83,11 +85,11 @@ function getTableMetadata(table) {
83
85
  uniqueConstraints: [],
84
86
  extras: []
85
87
  };
86
- builders.foreignKeys = processForeignKeys(table, foreignKeysSymbol, extraSymbol);
88
+ builders.foreignKeys = processForeignKeys(table2, foreignKeysSymbol, extraSymbol);
87
89
  if (extraSymbol) {
88
- const extraConfigBuilder = table[extraSymbol];
90
+ const extraConfigBuilder = table2[extraSymbol];
89
91
  if (extraConfigBuilder && typeof extraConfigBuilder === "function") {
90
- const configBuilderData = extraConfigBuilder(table);
92
+ const configBuilderData = extraConfigBuilder(table2);
91
93
  if (configBuilderData) {
92
94
  const configBuilders = Array.isArray(configBuilderData) ? configBuilderData : Object.values(configBuilderData).map(
93
95
  (item) => item.value || item
@@ -113,15 +115,15 @@ function getTableMetadata(table) {
113
115
  }
114
116
  }
115
117
  return {
116
- tableName: nameSymbol ? table[nameSymbol] : "",
117
- columns: columnsSymbol ? table[columnsSymbol] : {},
118
+ tableName: nameSymbol ? table2[nameSymbol] : "",
119
+ columns: columnsSymbol ? table2[columnsSymbol] : {},
118
120
  ...builders
119
121
  };
120
122
  }
121
123
  function generateDropTableStatements(tables) {
122
124
  const dropStatements = [];
123
- tables.forEach((table) => {
124
- const tableMetadata = getTableMetadata(table);
125
+ tables.forEach((table2) => {
126
+ const tableMetadata = getTableMetadata(table2);
125
127
  if (tableMetadata.tableName) {
126
128
  dropStatements.push(`DROP TABLE IF EXISTS \`${tableMetadata.tableName}\`;`);
127
129
  }
@@ -129,6 +131,47 @@ function generateDropTableStatements(tables) {
129
131
  dropStatements.push(`DELETE FROM __migrations;`);
130
132
  return dropStatements;
131
133
  }
134
+ function mapSelectTableToAlias(table2) {
135
+ const { columns, tableName } = getTableMetadata(table2);
136
+ const selectionsTableFields = {};
137
+ Object.keys(columns).forEach((name) => {
138
+ const column = columns[name];
139
+ const fieldAlias = drizzleOrm.sql.raw(`${tableName}_${column.name}`);
140
+ selectionsTableFields[name] = drizzleOrm.sql`${column} as \`${fieldAlias}\``;
141
+ });
142
+ return selectionsTableFields;
143
+ }
144
+ function isDrizzleColumn(column) {
145
+ return column && typeof column === "object" && "table" in column;
146
+ }
147
+ function mapSelectAllFieldsToAlias(selections, name, fields) {
148
+ if (drizzleOrm.isTable(fields)) {
149
+ selections[name] = mapSelectTableToAlias(fields);
150
+ } else if (isDrizzleColumn(fields)) {
151
+ const column = fields;
152
+ let aliasName = drizzleOrm.sql.raw(`${table.getTableName(column.table)}_${column.name}`);
153
+ selections[name] = drizzleOrm.sql`${column} as \`${aliasName}\``;
154
+ } else if (sql.isSQLWrapper(fields)) {
155
+ selections[name] = fields;
156
+ } else {
157
+ const innerSelections = {};
158
+ Object.entries(fields).forEach(([iname, ifields]) => {
159
+ mapSelectAllFieldsToAlias(innerSelections, iname, ifields);
160
+ });
161
+ selections[name] = innerSelections;
162
+ }
163
+ return selections;
164
+ }
165
+ function mapSelectFieldsWithAlias(fields) {
166
+ if (!fields) {
167
+ throw new Error("fields is empty");
168
+ }
169
+ const selections = {};
170
+ Object.entries(fields).forEach(([name, fields2]) => {
171
+ mapSelectAllFieldsToAlias(selections, name, fields2);
172
+ });
173
+ return selections;
174
+ }
132
175
  class ForgeSQLCrudOperations {
133
176
  forgeOperations;
134
177
  options;
@@ -450,13 +493,12 @@ class ForgeSQLSelectOperations {
450
493
  */
451
494
  async executeRawSQL(query, params) {
452
495
  if (this.options.logRawSqlQuery) {
453
- console.debug("Executing raw SQL: " + query);
496
+ console.debug(
497
+ `Executing with SQL ${query}` + params ? `, with params: ${JSON.stringify(params)}` : ""
498
+ );
454
499
  }
455
- const sqlStatement = sql.sql.prepare(query);
500
+ const sqlStatement = sql$1.sql.prepare(query);
456
501
  if (params) {
457
- if (this.options.logRawSqlQuery && this.options.logRawSqlQueryParams) {
458
- console.debug("Executing with SQL Params: " + JSON.stringify(params));
459
- }
460
502
  sqlStatement.bindParams(...params);
461
503
  }
462
504
  const result = await sqlStatement.execute();
@@ -469,10 +511,15 @@ class ForgeSQLSelectOperations {
469
511
  * @returns {Promise<UpdateQueryResponse>} The update response containing affected rows
470
512
  */
471
513
  async executeRawUpdateSQL(query, params) {
472
- const sqlStatement = sql.sql.prepare(query);
514
+ const sqlStatement = sql$1.sql.prepare(query);
473
515
  if (params) {
474
516
  sqlStatement.bindParams(...params);
475
517
  }
518
+ if (this.options.logRawSqlQuery) {
519
+ console.debug(
520
+ `Executing Update with SQL ${query}` + params ? `, with params: ${JSON.stringify(params)}` : ""
521
+ );
522
+ }
476
523
  const updateQueryResponseResults = await sqlStatement.execute();
477
524
  return updateQueryResponseResults.rows;
478
525
  }
@@ -480,20 +527,16 @@ class ForgeSQLSelectOperations {
480
527
  const forgeDriver = {
481
528
  query: async (query, params) => {
482
529
  try {
483
- const sqlStatement = await sql.sql.prepare(query.sql);
530
+ const sqlStatement = await sql$1.sql.prepare(query.sql);
484
531
  if (params) {
485
532
  await sqlStatement.bindParams(...params);
486
533
  }
487
534
  const result = await sqlStatement.execute();
488
535
  let rows;
489
536
  if (Array.isArray(result.rows)) {
490
- rows = [
491
- result.rows.map((r) => Object.values(r))
492
- ];
537
+ rows = [result.rows.map((r) => Object.values(r))];
493
538
  } else {
494
- rows = [
495
- result.rows
496
- ];
539
+ rows = [result.rows];
497
540
  }
498
541
  return rows;
499
542
  } catch (error) {
@@ -520,7 +563,7 @@ class ForgeSQLORMImpl {
520
563
  if (newOptions.logRawSqlQuery) {
521
564
  console.debug("Initializing ForgeSQLORM...");
522
565
  }
523
- this.drizzle = mysql2.drizzle(forgeDriver);
566
+ this.drizzle = mysql2.drizzle(forgeDriver, { logger: newOptions.logRawSqlQuery });
524
567
  this.crudOperations = new ForgeSQLCrudOperations(this, newOptions);
525
568
  this.fetchOperations = new ForgeSQLSelectOperations(newOptions);
526
569
  } catch (error) {
@@ -565,12 +608,94 @@ class ForgeSQLORMImpl {
565
608
  getDrizzleQueryBuilder() {
566
609
  return this.drizzle;
567
610
  }
611
+ /**
612
+ * Creates a select query with unique field aliases to prevent field name collisions in joins.
613
+ * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.
614
+ *
615
+ * @template TSelection - The type of the selected fields
616
+ * @param {TSelection} fields - Object containing the fields to select, with table schemas as values
617
+ * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A select query builder with unique field aliases
618
+ * @throws {Error} If fields parameter is empty
619
+ * @example
620
+ * ```typescript
621
+ * await forgeSQL
622
+ * .select({user: users, order: orders})
623
+ * .from(orders)
624
+ * .innerJoin(users, eq(orders.userId, users.id));
625
+ * ```
626
+ */
627
+ select(fields) {
628
+ if (!fields) {
629
+ throw new Error("fields is empty");
630
+ }
631
+ return this.drizzle.select(mapSelectFieldsWithAlias(fields));
632
+ }
633
+ /**
634
+ * Creates a distinct select query with unique field aliases to prevent field name collisions in joins.
635
+ * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.
636
+ *
637
+ * @template TSelection - The type of the selected fields
638
+ * @param {TSelection} fields - Object containing the fields to select, with table schemas as values
639
+ * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A distinct select query builder with unique field aliases
640
+ * @throws {Error} If fields parameter is empty
641
+ * @example
642
+ * ```typescript
643
+ * await forgeSQL
644
+ * .selectDistinct({user: users, order: orders})
645
+ * .from(orders)
646
+ * .innerJoin(users, eq(orders.userId, users.id));
647
+ * ```
648
+ */
649
+ selectDistinct(fields) {
650
+ if (!fields) {
651
+ throw new Error("fields is empty");
652
+ }
653
+ return this.drizzle.selectDistinct(mapSelectFieldsWithAlias(fields));
654
+ }
568
655
  }
569
656
  class ForgeSQLORM {
570
657
  ormInstance;
571
658
  constructor(options) {
572
659
  this.ormInstance = ForgeSQLORMImpl.getInstance(options);
573
660
  }
661
+ /**
662
+ * Creates a select query with unique field aliases to prevent field name collisions in joins.
663
+ * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.
664
+ *
665
+ * @template TSelection - The type of the selected fields
666
+ * @param {TSelection} fields - Object containing the fields to select, with table schemas as values
667
+ * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A select query builder with unique field aliases
668
+ * @throws {Error} If fields parameter is empty
669
+ * @example
670
+ * ```typescript
671
+ * await forgeSQL
672
+ * .select({user: users, order: orders})
673
+ * .from(orders)
674
+ * .innerJoin(users, eq(orders.userId, users.id));
675
+ * ```
676
+ */
677
+ select(fields) {
678
+ return this.ormInstance.getDrizzleQueryBuilder().select(mapSelectFieldsWithAlias(fields));
679
+ }
680
+ /**
681
+ * Creates a distinct select query with unique field aliases to prevent field name collisions in joins.
682
+ * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.
683
+ *
684
+ * @template TSelection - The type of the selected fields
685
+ * @param {TSelection} fields - Object containing the fields to select, with table schemas as values
686
+ * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A distinct select query builder with unique field aliases
687
+ * @throws {Error} If fields parameter is empty
688
+ * @example
689
+ * ```typescript
690
+ * await forgeSQL
691
+ * .selectDistinct({user: users, order: orders})
692
+ * .from(orders)
693
+ * .innerJoin(users, eq(orders.userId, users.id));
694
+ * ```
695
+ */
696
+ selectDistinct(fields) {
697
+ return this.ormInstance.getDrizzleQueryBuilder().selectDistinct(mapSelectFieldsWithAlias(fields));
698
+ }
574
699
  /**
575
700
  * Proxies the `crud` method from `ForgeSQLORMImpl`.
576
701
  * @returns CRUD operations.
@@ -650,13 +775,12 @@ async function dropSchemaMigrations(tables) {
650
775
  const dropStatements = generateDropTableStatements(tables);
651
776
  for (const statement of dropStatements) {
652
777
  console.warn(statement);
653
- await sql.sql.executeDDL(statement);
778
+ await sql$1.sql.executeDDL(statement);
654
779
  }
655
- const droppedTables = tables.map((table) => {
656
- const metadata = getTableMetadata(table);
657
- return metadata.tableName;
658
- }).filter(Boolean);
659
- return getHttpResponse(200, "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.");
780
+ return getHttpResponse(
781
+ 200,
782
+ "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone."
783
+ );
660
784
  } catch (error) {
661
785
  const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
662
786
  return getHttpResponse(500, errorMessage);
@@ -664,12 +788,12 @@ async function dropSchemaMigrations(tables) {
664
788
  }
665
789
  const applySchemaMigrations = async (migration) => {
666
790
  console.log("Provisioning the database");
667
- await sql.sql._provision();
791
+ await sql$1.sql._provision();
668
792
  console.info("Running schema migrations");
669
- const migrations = await migration(sql.migrationRunner);
793
+ const migrations = await migration(sql$1.migrationRunner);
670
794
  const successfulMigrations = await migrations.run();
671
795
  console.info("Migrations applied:", successfulMigrations);
672
- const migrationHistory = (await sql.migrationRunner.list()).map((y) => `${y.id}, ${y.name}, ${y.migratedAt.toUTCString()}`).join("\n");
796
+ const migrationHistory = (await sql$1.migrationRunner.list()).map((y) => `${y.id}, ${y.name}, ${y.migratedAt.toUTCString()}`).join("\n");
673
797
  console.info("Migrations history:\nid, name, migrated_at\n", migrationHistory);
674
798
  return {
675
799
  headers: { "Content-Type": ["application/json"] },
@@ -707,5 +831,8 @@ exports.generateDropTableStatements = generateDropTableStatements;
707
831
  exports.getHttpResponse = getHttpResponse;
708
832
  exports.getPrimaryKeys = getPrimaryKeys;
709
833
  exports.getTableMetadata = getTableMetadata;
834
+ exports.mapSelectAllFieldsToAlias = mapSelectAllFieldsToAlias;
835
+ exports.mapSelectFieldsWithAlias = mapSelectFieldsWithAlias;
836
+ exports.mapSelectTableToAlias = mapSelectTableToAlias;
710
837
  exports.parseDateTime = parseDateTime;
711
838
  //# sourceMappingURL=ForgeSQLORM.js.map