forge-sql-orm 2.1.2 → 2.1.3

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.
@@ -36,11 +36,16 @@ const parseDateTime = (value, format) => {
36
36
  if (dt.isValid) {
37
37
  result = dt.toJSDate();
38
38
  } else {
39
- const isoDt = luxon.DateTime.fromISO(value);
40
- if (isoDt.isValid) {
41
- result = isoDt.toJSDate();
39
+ const sqlDt = luxon.DateTime.fromSQL(value);
40
+ if (sqlDt.isValid) {
41
+ result = sqlDt.toJSDate();
42
42
  } else {
43
- result = new Date(value);
43
+ const isoDt = luxon.DateTime.fromRFC2822(value);
44
+ if (isoDt.isValid) {
45
+ result = isoDt.toJSDate();
46
+ } else {
47
+ result = new Date(value);
48
+ }
44
49
  }
45
50
  }
46
51
  }
@@ -49,7 +54,7 @@ const parseDateTime = (value, format) => {
49
54
  }
50
55
  return result;
51
56
  };
52
- function formatDateTime(value, format) {
57
+ function formatDateTime(value, format, isTimeStamp) {
53
58
  let dt = null;
54
59
  if (value instanceof Date) {
55
60
  dt = luxon.DateTime.fromJSDate(value);
@@ -77,6 +82,20 @@ function formatDateTime(value, format) {
77
82
  if (!dt?.isValid) {
78
83
  throw new Error("Invalid Date");
79
84
  }
85
+ const minDate = luxon.DateTime.fromSeconds(1);
86
+ const maxDate = luxon.DateTime.fromMillis(2147483647 * 1e3);
87
+ if (isTimeStamp) {
88
+ if (dt < minDate) {
89
+ throw new Error(
90
+ "Atlassian Forge does not support zero or negative timestamps. Allowed range: from '1970-01-01 00:00:01.000000' to '2038-01-19 03:14:07.999999'."
91
+ );
92
+ }
93
+ if (dt > maxDate) {
94
+ throw new Error(
95
+ "Atlassian Forge does not support timestamps beyond 2038-01-19 03:14:07.999999. Please use a smaller date within the supported range."
96
+ );
97
+ }
98
+ }
80
99
  return dt.toFormat(format);
81
100
  }
82
101
  function getPrimaryKeys(table2) {
@@ -480,7 +499,9 @@ async function clearExpiredCache(options) {
480
499
  );
481
500
  } finally {
482
501
  const duration = luxon.DateTime.now().toSeconds() - startTime.toSeconds();
483
- console.info(`Cleared ${totalRecords} expired cache records in ${duration} seconds`);
502
+ if (options?.logRawSqlQuery) {
503
+ console.debug(`Cleared ${totalRecords} expired cache records in ${duration} seconds`);
504
+ }
484
505
  }
485
506
  }
486
507
  async function getFromCache(query, options) {
@@ -567,7 +588,7 @@ async function saveQueryLocalCacheQuery(query, rows, options) {
567
588
  };
568
589
  if (options.logRawSqlQuery) {
569
590
  const q = sql2.toSQL();
570
- console.log(
591
+ console.debug(
571
592
  `[forge-sql-orm][local-cache][SAVE] Stored result in cache. sql="${q.sql}", params=${JSON.stringify(q.params)}`
572
593
  );
573
594
  }
@@ -584,7 +605,7 @@ async function getQueryLocalCacheQuery(query, options) {
584
605
  if (context.cache[key] && context.cache[key].sql === sql2.toSQL().sql.toLowerCase()) {
585
606
  if (options.logRawSqlQuery) {
586
607
  const q = sql2.toSQL();
587
- console.log(
608
+ console.debug(
588
609
  `[forge-sql-orm][local-cache][HIT] Returned cached result. sql="${q.sql}", params=${JSON.stringify(q.params)}`
589
610
  );
590
611
  }
@@ -1014,28 +1035,23 @@ class ForgeSQLSelectOperations {
1014
1035
  }
1015
1036
  }
1016
1037
  const forgeDriver = async (query, params, method) => {
1017
- try {
1018
- if (method == "execute") {
1019
- const sqlStatement = sql$1.sql.prepare(query);
1020
- if (params) {
1021
- sqlStatement.bindParams(...params);
1022
- }
1023
- const updateQueryResponseResults = await sqlStatement.execute();
1024
- let result = updateQueryResponseResults.rows;
1025
- return { ...result, rows: [result] };
1026
- } else {
1027
- const sqlStatement = await sql$1.sql.prepare(query);
1028
- if (params) {
1029
- await sqlStatement.bindParams(...params);
1030
- }
1031
- const result = await sqlStatement.execute();
1032
- let rows;
1033
- rows = result.rows.map((r) => Object.values(r));
1034
- return { rows };
1038
+ if (method == "execute") {
1039
+ const sqlStatement = sql$1.sql.prepare(query);
1040
+ if (params) {
1041
+ sqlStatement.bindParams(...params);
1035
1042
  }
1036
- } catch (error) {
1037
- console.error("SQL Error:", JSON.stringify(error));
1038
- throw error;
1043
+ const updateQueryResponseResults = await sqlStatement.execute();
1044
+ let result = updateQueryResponseResults.rows;
1045
+ return { ...result, rows: [result] };
1046
+ } else {
1047
+ const sqlStatement = await sql$1.sql.prepare(query);
1048
+ if (params) {
1049
+ await sqlStatement.bindParams(...params);
1050
+ }
1051
+ const result = await sqlStatement.execute();
1052
+ let rows;
1053
+ rows = result.rows.map((r) => Object.values(r));
1054
+ return { rows };
1039
1055
  }
1040
1056
  };
1041
1057
  function injectSqlHints(query, hints) {
@@ -1072,9 +1088,16 @@ function createForgeDriverProxy(options, logRawSqlQuery) {
1072
1088
  return async (query, params, method) => {
1073
1089
  const modifiedQuery = injectSqlHints(query, options);
1074
1090
  if (options && logRawSqlQuery && modifiedQuery !== query) {
1075
- console.warn("modified query: " + modifiedQuery);
1091
+ console.debug("injected Hints: " + modifiedQuery);
1092
+ }
1093
+ try {
1094
+ return await forgeDriver(modifiedQuery, params, method);
1095
+ } catch (error) {
1096
+ if (logRawSqlQuery) {
1097
+ console.debug("SQL Error:", JSON.stringify(error));
1098
+ }
1099
+ throw error;
1076
1100
  }
1077
- return forgeDriver(modifiedQuery, params, method);
1078
1101
  };
1079
1102
  }
1080
1103
  const NON_CACHE_CLEARING_ERROR_CODES = ["VALIDATION_ERROR", "CONSTRAINT_ERROR"];
@@ -1109,8 +1132,8 @@ async function handleSuccessfulExecution(rows, onfulfilled, table2, options, isC
1109
1132
  if (shouldClearCacheOnError(error)) {
1110
1133
  await evictLocalCacheQuery(table2, options);
1111
1134
  if (isCached) {
1112
- await clearCache(table2, options).catch(() => {
1113
- console.warn("Ignore cache clear errors");
1135
+ await clearCache(table2, options).catch((e) => {
1136
+ console.warn("Ignore cache clear errors", e);
1114
1137
  });
1115
1138
  } else {
1116
1139
  await saveTableIfInsideCacheContext(table2);
@@ -2572,10 +2595,10 @@ const forgeDateTimeString = mysqlCore.customType({
2572
2595
  return "datetime";
2573
2596
  },
2574
2597
  toDriver(value) {
2575
- return formatDateTime(value, "yyyy-LL-dd' 'HH:mm:ss.SSS");
2598
+ return formatDateTime(value, "yyyy-MM-dd' 'HH:mm:ss.SSS", false);
2576
2599
  },
2577
2600
  fromDriver(value) {
2578
- const format = "yyyy-LL-dd'T'HH:mm:ss.SSS";
2601
+ const format = "yyyy-MM-dd' 'HH:mm:ss.SSS";
2579
2602
  return parseDateTime(value, format);
2580
2603
  }
2581
2604
  });
@@ -2584,10 +2607,10 @@ const forgeTimestampString = mysqlCore.customType({
2584
2607
  return "timestamp";
2585
2608
  },
2586
2609
  toDriver(value) {
2587
- return formatDateTime(value, "yyyy-LL-dd' 'HH:mm:ss.SSS");
2610
+ return formatDateTime(value, "yyyy-MM-dd' 'HH:mm:ss.SSS", true);
2588
2611
  },
2589
2612
  fromDriver(value) {
2590
- const format = "yyyy-LL-dd'T'HH:mm:ss.SSS";
2613
+ const format = "yyyy-MM-dd' 'HH:mm:ss.SSS";
2591
2614
  return parseDateTime(value, format);
2592
2615
  }
2593
2616
  });
@@ -2596,10 +2619,10 @@ const forgeDateString = mysqlCore.customType({
2596
2619
  return "date";
2597
2620
  },
2598
2621
  toDriver(value) {
2599
- return formatDateTime(value, "yyyy-LL-dd");
2622
+ return formatDateTime(value, "yyyy-MM-dd", false);
2600
2623
  },
2601
2624
  fromDriver(value) {
2602
- const format = "yyyy-LL-dd";
2625
+ const format = "yyyy-MM-dd";
2603
2626
  return parseDateTime(value, format);
2604
2627
  }
2605
2628
  });
@@ -2608,7 +2631,7 @@ const forgeTimeString = mysqlCore.customType({
2608
2631
  return "time";
2609
2632
  },
2610
2633
  toDriver(value) {
2611
- return formatDateTime(value, "HH:mm:ss.SSS");
2634
+ return formatDateTime(value, "HH:mm:ss.SSS", false);
2612
2635
  },
2613
2636
  fromDriver(value) {
2614
2637
  return parseDateTime(value, "HH:mm:ss.SSS");
@@ -2629,7 +2652,7 @@ async function dropSchemaMigrations() {
2629
2652
  const tables = await getTables();
2630
2653
  const dropStatements = generateDropTableStatements(tables, { sequence: true, table: true });
2631
2654
  for (const statement of dropStatements) {
2632
- console.warn(statement);
2655
+ console.debug(`execute DDL: ${statement}`);
2633
2656
  await sql$1.sql.executeDDL(statement);
2634
2657
  }
2635
2658
  return getHttpResponse(
@@ -2637,8 +2660,8 @@ async function dropSchemaMigrations() {
2637
2660
  "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone."
2638
2661
  );
2639
2662
  } catch (error) {
2640
- console.error(error);
2641
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
2663
+ const errorMessage = error?.debug?.sqlMessage ?? error?.debug?.message ?? error.message ?? "Unknown error occurred";
2664
+ console.error(errorMessage);
2642
2665
  return getHttpResponse(500, errorMessage);
2643
2666
  }
2644
2667
  }
@@ -2654,7 +2677,13 @@ const applySchemaMigrations = async (migration) => {
2654
2677
  const successfulMigrations = await migrations2.run();
2655
2678
  console.info("Migrations applied:", successfulMigrations);
2656
2679
  const migrationList = await sql$1.migrationRunner.list();
2657
- const migrationHistory = Array.isArray(migrationList) && migrationList.length > 0 ? migrationList.sort((a, b) => a.migratedAt.getTime() - b.migratedAt.getTime()).map((y) => `${y.id}, ${y.name}, ${y.migratedAt.toUTCString()}`).join("\n") : "No migrations found";
2680
+ let migrationHistory = "No migrations found";
2681
+ if (Array.isArray(migrationList) && migrationList.length > 0) {
2682
+ const sortedMigrations = migrationList.toSorted(
2683
+ (a, b) => a.migratedAt.getTime() - b.migratedAt.getTime()
2684
+ );
2685
+ migrationHistory = sortedMigrations.map((y) => `${y.id}, ${y.name}, ${y.migratedAt.toUTCString()}`).join("\n");
2686
+ }
2658
2687
  console.info("Migrations history:\nid, name, migrated_at\n", migrationHistory);
2659
2688
  return {
2660
2689
  headers: { "Content-Type": ["application/json"] },
@@ -2663,12 +2692,8 @@ const applySchemaMigrations = async (migration) => {
2663
2692
  body: "Migrations successfully executed"
2664
2693
  };
2665
2694
  } catch (error) {
2666
- try {
2667
- console.error("Error during migration:", JSON.stringify(error));
2668
- } catch (e) {
2669
- console.trace("Error stringify:", e);
2670
- console.error("Error during migration:", error);
2671
- }
2695
+ const errorMessage = error?.debug?.sqlMessage ?? error?.debug?.message ?? error.message ?? "Unknown error occurred";
2696
+ console.error("Error during migration:", errorMessage);
2672
2697
  return {
2673
2698
  headers: { "Content-Type": ["application/json"] },
2674
2699
  statusCode: 500,
@@ -2684,8 +2709,8 @@ async function fetchSchemaWebTrigger() {
2684
2709
  const sqlStatements = wrapWithForeignKeyChecks(createTableStatements);
2685
2710
  return getHttpResponse(200, sqlStatements.join(";\n"));
2686
2711
  } catch (error) {
2687
- console.error(JSON.stringify(error));
2688
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
2712
+ const errorMessage = error?.debug?.sqlMessage ?? error?.debug?.message ?? error.message ?? "Unknown error occurred";
2713
+ console.error(errorMessage);
2689
2714
  return getHttpResponse(500, errorMessage);
2690
2715
  }
2691
2716
  }
@@ -2712,7 +2737,7 @@ async function dropTableSchemaMigrations() {
2712
2737
  const tables = await getTables();
2713
2738
  const dropStatements = generateDropTableStatements(tables, { sequence: false, table: true });
2714
2739
  for (const statement of dropStatements) {
2715
- console.warn(statement);
2740
+ console.debug(`execute DDL: ${statement}`);
2716
2741
  await sql$1.sql.executeDDL(statement);
2717
2742
  }
2718
2743
  return getHttpResponse(
@@ -2720,8 +2745,8 @@ async function dropTableSchemaMigrations() {
2720
2745
  "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone."
2721
2746
  );
2722
2747
  } catch (error) {
2723
- console.error(error);
2724
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
2748
+ const errorMessage = error?.debug?.sqlMessage ?? error?.debug?.message ?? error.message ?? "Unknown error occurred";
2749
+ console.error(errorMessage);
2725
2750
  return getHttpResponse(500, errorMessage);
2726
2751
  }
2727
2752
  }