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.
@@ -17,11 +17,16 @@ const parseDateTime = (value, format) => {
17
17
  if (dt.isValid) {
18
18
  result = dt.toJSDate();
19
19
  } else {
20
- const isoDt = DateTime.fromISO(value);
21
- if (isoDt.isValid) {
22
- result = isoDt.toJSDate();
20
+ const sqlDt = DateTime.fromSQL(value);
21
+ if (sqlDt.isValid) {
22
+ result = sqlDt.toJSDate();
23
23
  } else {
24
- result = new Date(value);
24
+ const isoDt = DateTime.fromRFC2822(value);
25
+ if (isoDt.isValid) {
26
+ result = isoDt.toJSDate();
27
+ } else {
28
+ result = new Date(value);
29
+ }
25
30
  }
26
31
  }
27
32
  }
@@ -30,7 +35,7 @@ const parseDateTime = (value, format) => {
30
35
  }
31
36
  return result;
32
37
  };
33
- function formatDateTime(value, format) {
38
+ function formatDateTime(value, format, isTimeStamp) {
34
39
  let dt = null;
35
40
  if (value instanceof Date) {
36
41
  dt = DateTime.fromJSDate(value);
@@ -58,6 +63,20 @@ function formatDateTime(value, format) {
58
63
  if (!dt?.isValid) {
59
64
  throw new Error("Invalid Date");
60
65
  }
66
+ const minDate = DateTime.fromSeconds(1);
67
+ const maxDate = DateTime.fromMillis(2147483647 * 1e3);
68
+ if (isTimeStamp) {
69
+ if (dt < minDate) {
70
+ throw new Error(
71
+ "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'."
72
+ );
73
+ }
74
+ if (dt > maxDate) {
75
+ throw new Error(
76
+ "Atlassian Forge does not support timestamps beyond 2038-01-19 03:14:07.999999. Please use a smaller date within the supported range."
77
+ );
78
+ }
79
+ }
61
80
  return dt.toFormat(format);
62
81
  }
63
82
  function getPrimaryKeys(table) {
@@ -461,7 +480,9 @@ async function clearExpiredCache(options) {
461
480
  );
462
481
  } finally {
463
482
  const duration = DateTime.now().toSeconds() - startTime.toSeconds();
464
- console.info(`Cleared ${totalRecords} expired cache records in ${duration} seconds`);
483
+ if (options?.logRawSqlQuery) {
484
+ console.debug(`Cleared ${totalRecords} expired cache records in ${duration} seconds`);
485
+ }
465
486
  }
466
487
  }
467
488
  async function getFromCache(query, options) {
@@ -548,7 +569,7 @@ async function saveQueryLocalCacheQuery(query, rows, options) {
548
569
  };
549
570
  if (options.logRawSqlQuery) {
550
571
  const q = sql2.toSQL();
551
- console.log(
572
+ console.debug(
552
573
  `[forge-sql-orm][local-cache][SAVE] Stored result in cache. sql="${q.sql}", params=${JSON.stringify(q.params)}`
553
574
  );
554
575
  }
@@ -565,7 +586,7 @@ async function getQueryLocalCacheQuery(query, options) {
565
586
  if (context.cache[key] && context.cache[key].sql === sql2.toSQL().sql.toLowerCase()) {
566
587
  if (options.logRawSqlQuery) {
567
588
  const q = sql2.toSQL();
568
- console.log(
589
+ console.debug(
569
590
  `[forge-sql-orm][local-cache][HIT] Returned cached result. sql="${q.sql}", params=${JSON.stringify(q.params)}`
570
591
  );
571
592
  }
@@ -995,28 +1016,23 @@ class ForgeSQLSelectOperations {
995
1016
  }
996
1017
  }
997
1018
  const forgeDriver = async (query, params, method) => {
998
- try {
999
- if (method == "execute") {
1000
- const sqlStatement = sql$1.prepare(query);
1001
- if (params) {
1002
- sqlStatement.bindParams(...params);
1003
- }
1004
- const updateQueryResponseResults = await sqlStatement.execute();
1005
- let result = updateQueryResponseResults.rows;
1006
- return { ...result, rows: [result] };
1007
- } else {
1008
- const sqlStatement = await sql$1.prepare(query);
1009
- if (params) {
1010
- await sqlStatement.bindParams(...params);
1011
- }
1012
- const result = await sqlStatement.execute();
1013
- let rows;
1014
- rows = result.rows.map((r) => Object.values(r));
1015
- return { rows };
1019
+ if (method == "execute") {
1020
+ const sqlStatement = sql$1.prepare(query);
1021
+ if (params) {
1022
+ sqlStatement.bindParams(...params);
1016
1023
  }
1017
- } catch (error) {
1018
- console.error("SQL Error:", JSON.stringify(error));
1019
- throw error;
1024
+ const updateQueryResponseResults = await sqlStatement.execute();
1025
+ let result = updateQueryResponseResults.rows;
1026
+ return { ...result, rows: [result] };
1027
+ } else {
1028
+ const sqlStatement = await sql$1.prepare(query);
1029
+ if (params) {
1030
+ await sqlStatement.bindParams(...params);
1031
+ }
1032
+ const result = await sqlStatement.execute();
1033
+ let rows;
1034
+ rows = result.rows.map((r) => Object.values(r));
1035
+ return { rows };
1020
1036
  }
1021
1037
  };
1022
1038
  function injectSqlHints(query, hints) {
@@ -1053,9 +1069,16 @@ function createForgeDriverProxy(options, logRawSqlQuery) {
1053
1069
  return async (query, params, method) => {
1054
1070
  const modifiedQuery = injectSqlHints(query, options);
1055
1071
  if (options && logRawSqlQuery && modifiedQuery !== query) {
1056
- console.warn("modified query: " + modifiedQuery);
1072
+ console.debug("injected Hints: " + modifiedQuery);
1073
+ }
1074
+ try {
1075
+ return await forgeDriver(modifiedQuery, params, method);
1076
+ } catch (error) {
1077
+ if (logRawSqlQuery) {
1078
+ console.debug("SQL Error:", JSON.stringify(error));
1079
+ }
1080
+ throw error;
1057
1081
  }
1058
- return forgeDriver(modifiedQuery, params, method);
1059
1082
  };
1060
1083
  }
1061
1084
  const NON_CACHE_CLEARING_ERROR_CODES = ["VALIDATION_ERROR", "CONSTRAINT_ERROR"];
@@ -1090,8 +1113,8 @@ async function handleSuccessfulExecution(rows, onfulfilled, table, options, isCa
1090
1113
  if (shouldClearCacheOnError(error)) {
1091
1114
  await evictLocalCacheQuery(table, options);
1092
1115
  if (isCached) {
1093
- await clearCache(table, options).catch(() => {
1094
- console.warn("Ignore cache clear errors");
1116
+ await clearCache(table, options).catch((e) => {
1117
+ console.warn("Ignore cache clear errors", e);
1095
1118
  });
1096
1119
  } else {
1097
1120
  await saveTableIfInsideCacheContext(table);
@@ -2553,10 +2576,10 @@ const forgeDateTimeString = customType({
2553
2576
  return "datetime";
2554
2577
  },
2555
2578
  toDriver(value) {
2556
- return formatDateTime(value, "yyyy-LL-dd' 'HH:mm:ss.SSS");
2579
+ return formatDateTime(value, "yyyy-MM-dd' 'HH:mm:ss.SSS", false);
2557
2580
  },
2558
2581
  fromDriver(value) {
2559
- const format = "yyyy-LL-dd'T'HH:mm:ss.SSS";
2582
+ const format = "yyyy-MM-dd' 'HH:mm:ss.SSS";
2560
2583
  return parseDateTime(value, format);
2561
2584
  }
2562
2585
  });
@@ -2565,10 +2588,10 @@ const forgeTimestampString = customType({
2565
2588
  return "timestamp";
2566
2589
  },
2567
2590
  toDriver(value) {
2568
- return formatDateTime(value, "yyyy-LL-dd' 'HH:mm:ss.SSS");
2591
+ return formatDateTime(value, "yyyy-MM-dd' 'HH:mm:ss.SSS", true);
2569
2592
  },
2570
2593
  fromDriver(value) {
2571
- const format = "yyyy-LL-dd'T'HH:mm:ss.SSS";
2594
+ const format = "yyyy-MM-dd' 'HH:mm:ss.SSS";
2572
2595
  return parseDateTime(value, format);
2573
2596
  }
2574
2597
  });
@@ -2577,10 +2600,10 @@ const forgeDateString = customType({
2577
2600
  return "date";
2578
2601
  },
2579
2602
  toDriver(value) {
2580
- return formatDateTime(value, "yyyy-LL-dd");
2603
+ return formatDateTime(value, "yyyy-MM-dd", false);
2581
2604
  },
2582
2605
  fromDriver(value) {
2583
- const format = "yyyy-LL-dd";
2606
+ const format = "yyyy-MM-dd";
2584
2607
  return parseDateTime(value, format);
2585
2608
  }
2586
2609
  });
@@ -2589,7 +2612,7 @@ const forgeTimeString = customType({
2589
2612
  return "time";
2590
2613
  },
2591
2614
  toDriver(value) {
2592
- return formatDateTime(value, "HH:mm:ss.SSS");
2615
+ return formatDateTime(value, "HH:mm:ss.SSS", false);
2593
2616
  },
2594
2617
  fromDriver(value) {
2595
2618
  return parseDateTime(value, "HH:mm:ss.SSS");
@@ -2610,7 +2633,7 @@ async function dropSchemaMigrations() {
2610
2633
  const tables = await getTables();
2611
2634
  const dropStatements = generateDropTableStatements(tables, { sequence: true, table: true });
2612
2635
  for (const statement of dropStatements) {
2613
- console.warn(statement);
2636
+ console.debug(`execute DDL: ${statement}`);
2614
2637
  await sql$1.executeDDL(statement);
2615
2638
  }
2616
2639
  return getHttpResponse(
@@ -2618,8 +2641,8 @@ async function dropSchemaMigrations() {
2618
2641
  "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone."
2619
2642
  );
2620
2643
  } catch (error) {
2621
- console.error(error);
2622
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
2644
+ const errorMessage = error?.debug?.sqlMessage ?? error?.debug?.message ?? error.message ?? "Unknown error occurred";
2645
+ console.error(errorMessage);
2623
2646
  return getHttpResponse(500, errorMessage);
2624
2647
  }
2625
2648
  }
@@ -2635,7 +2658,13 @@ const applySchemaMigrations = async (migration) => {
2635
2658
  const successfulMigrations = await migrations2.run();
2636
2659
  console.info("Migrations applied:", successfulMigrations);
2637
2660
  const migrationList = await migrationRunner.list();
2638
- 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";
2661
+ let migrationHistory = "No migrations found";
2662
+ if (Array.isArray(migrationList) && migrationList.length > 0) {
2663
+ const sortedMigrations = migrationList.toSorted(
2664
+ (a, b) => a.migratedAt.getTime() - b.migratedAt.getTime()
2665
+ );
2666
+ migrationHistory = sortedMigrations.map((y) => `${y.id}, ${y.name}, ${y.migratedAt.toUTCString()}`).join("\n");
2667
+ }
2639
2668
  console.info("Migrations history:\nid, name, migrated_at\n", migrationHistory);
2640
2669
  return {
2641
2670
  headers: { "Content-Type": ["application/json"] },
@@ -2644,12 +2673,8 @@ const applySchemaMigrations = async (migration) => {
2644
2673
  body: "Migrations successfully executed"
2645
2674
  };
2646
2675
  } catch (error) {
2647
- try {
2648
- console.error("Error during migration:", JSON.stringify(error));
2649
- } catch (e) {
2650
- console.trace("Error stringify:", e);
2651
- console.error("Error during migration:", error);
2652
- }
2676
+ const errorMessage = error?.debug?.sqlMessage ?? error?.debug?.message ?? error.message ?? "Unknown error occurred";
2677
+ console.error("Error during migration:", errorMessage);
2653
2678
  return {
2654
2679
  headers: { "Content-Type": ["application/json"] },
2655
2680
  statusCode: 500,
@@ -2665,8 +2690,8 @@ async function fetchSchemaWebTrigger() {
2665
2690
  const sqlStatements = wrapWithForeignKeyChecks(createTableStatements);
2666
2691
  return getHttpResponse(200, sqlStatements.join(";\n"));
2667
2692
  } catch (error) {
2668
- console.error(JSON.stringify(error));
2669
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
2693
+ const errorMessage = error?.debug?.sqlMessage ?? error?.debug?.message ?? error.message ?? "Unknown error occurred";
2694
+ console.error(errorMessage);
2670
2695
  return getHttpResponse(500, errorMessage);
2671
2696
  }
2672
2697
  }
@@ -2693,7 +2718,7 @@ async function dropTableSchemaMigrations() {
2693
2718
  const tables = await getTables();
2694
2719
  const dropStatements = generateDropTableStatements(tables, { sequence: false, table: true });
2695
2720
  for (const statement of dropStatements) {
2696
- console.warn(statement);
2721
+ console.debug(`execute DDL: ${statement}`);
2697
2722
  await sql$1.executeDDL(statement);
2698
2723
  }
2699
2724
  return getHttpResponse(
@@ -2701,8 +2726,8 @@ async function dropTableSchemaMigrations() {
2701
2726
  "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone."
2702
2727
  );
2703
2728
  } catch (error) {
2704
- console.error(error);
2705
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
2729
+ const errorMessage = error?.debug?.sqlMessage ?? error?.debug?.message ?? error.message ?? "Unknown error occurred";
2730
+ console.error(errorMessage);
2706
2731
  return getHttpResponse(500, errorMessage);
2707
2732
  }
2708
2733
  }