forge-sql-orm 2.1.1 → 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.
Files changed (33) hide show
  1. package/dist/ForgeSQLORM.js +142 -103
  2. package/dist/ForgeSQLORM.js.map +1 -1
  3. package/dist/ForgeSQLORM.mjs +142 -103
  4. package/dist/ForgeSQLORM.mjs.map +1 -1
  5. package/dist/core/ForgeSQLORM.d.ts.map +1 -1
  6. package/dist/core/ForgeSQLQueryBuilder.d.ts +24 -25
  7. package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
  8. package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
  9. package/dist/utils/cacheContextUtils.d.ts +4 -2
  10. package/dist/utils/cacheContextUtils.d.ts.map +1 -1
  11. package/dist/utils/cacheUtils.d.ts.map +1 -1
  12. package/dist/utils/forgeDriver.d.ts.map +1 -1
  13. package/dist/utils/forgeDriverProxy.d.ts.map +1 -1
  14. package/dist/utils/sqlUtils.d.ts +1 -1
  15. package/dist/utils/sqlUtils.d.ts.map +1 -1
  16. package/dist/webtriggers/applyMigrationsWebTrigger.d.ts.map +1 -1
  17. package/dist/webtriggers/dropMigrationWebTrigger.d.ts.map +1 -1
  18. package/dist/webtriggers/dropTablesMigrationWebTrigger.d.ts.map +1 -1
  19. package/dist/webtriggers/fetchSchemaWebTrigger.d.ts.map +1 -1
  20. package/package.json +5 -5
  21. package/src/core/ForgeSQLORM.ts +29 -23
  22. package/src/core/ForgeSQLQueryBuilder.ts +185 -128
  23. package/src/lib/drizzle/extensions/additionalActions.ts +125 -76
  24. package/src/lib/drizzle/extensions/types.d.ts +16 -11
  25. package/src/utils/cacheContextUtils.ts +16 -4
  26. package/src/utils/cacheUtils.ts +3 -1
  27. package/src/utils/forgeDriver.ts +16 -21
  28. package/src/utils/forgeDriverProxy.ts +10 -3
  29. package/src/utils/sqlUtils.ts +59 -35
  30. package/src/webtriggers/applyMigrationsWebTrigger.ts +18 -14
  31. package/src/webtriggers/dropMigrationWebTrigger.ts +8 -4
  32. package/src/webtriggers/dropTablesMigrationWebTrigger.ts +8 -4
  33. package/src/webtriggers/fetchSchemaWebTrigger.ts +7 -3
@@ -57,13 +57,19 @@ export const parseDateTime = (value: string | Date, format: string): Date => {
57
57
  if (dt.isValid) {
58
58
  result = dt.toJSDate();
59
59
  } else {
60
- // 2. Try to parse as ISO string
61
- const isoDt = DateTime.fromISO(value);
62
- if (isoDt.isValid) {
63
- result = isoDt.toJSDate();
60
+ // 2. Try to parse as SQL string
61
+ const sqlDt = DateTime.fromSQL(value);
62
+ if (sqlDt.isValid) {
63
+ result = sqlDt.toJSDate();
64
64
  } else {
65
- // 3. Fallback: use native Date constructor
66
- result = new Date(value);
65
+ // 3. Try to parse as RFC2822 string
66
+ const isoDt = DateTime.fromRFC2822(value);
67
+ if (isoDt.isValid) {
68
+ result = isoDt.toJSDate();
69
+ } else {
70
+ // 4. Fallback: use native Date constructor
71
+ result = new Date(value);
72
+ }
67
73
  }
68
74
  }
69
75
  }
@@ -81,39 +87,57 @@ export const parseDateTime = (value: string | Date, format: string): Date => {
81
87
  * @returns Formatted date string.
82
88
  * @throws Error if value cannot be parsed as a valid date.
83
89
  */
84
- export function formatDateTime(value: Date | string | number, format: string): string {
85
- let dt: DateTime|null = null;
86
-
87
- if (value instanceof Date) {
88
- dt = DateTime.fromJSDate(value);
89
- } else if (typeof value === "string") {
90
- // Перебор парсеров
91
- for (const parser of [
92
- DateTime.fromISO,
93
- DateTime.fromRFC2822,
94
- DateTime.fromSQL,
95
- DateTime.fromHTTP,
96
- ]) {
97
- dt = parser(value);
98
- if (dt.isValid) break;
99
- }
100
- if (!dt?.isValid) {
101
- const parsed = Number(value);
102
- if (!isNaN(parsed)) {
103
- dt = DateTime.fromMillis(parsed);
104
- }
105
- }
106
- } else if (typeof value === "number") {
107
- dt = DateTime.fromMillis(value);
108
- } else {
109
- throw new Error("Unsupported type");
110
- }
90
+ export function formatDateTime(
91
+ value: Date | string | number,
92
+ format: string,
93
+ isTimeStamp: boolean,
94
+ ): string {
95
+ let dt: DateTime | null = null;
111
96
 
97
+ if (value instanceof Date) {
98
+ dt = DateTime.fromJSDate(value);
99
+ } else if (typeof value === "string") {
100
+ for (const parser of [
101
+ DateTime.fromISO,
102
+ DateTime.fromRFC2822,
103
+ DateTime.fromSQL,
104
+ DateTime.fromHTTP,
105
+ ]) {
106
+ dt = parser(value);
107
+ if (dt.isValid) break;
108
+ }
112
109
  if (!dt?.isValid) {
113
- throw new Error("Invalid Date");
110
+ const parsed = Number(value);
111
+ if (!isNaN(parsed)) {
112
+ dt = DateTime.fromMillis(parsed);
113
+ }
114
114
  }
115
+ } else if (typeof value === "number") {
116
+ dt = DateTime.fromMillis(value);
117
+ } else {
118
+ throw new Error("Unsupported type");
119
+ }
120
+
121
+ if (!dt?.isValid) {
122
+ throw new Error("Invalid Date");
123
+ }
124
+ const minDate = DateTime.fromSeconds(1);
125
+ const maxDate = DateTime.fromMillis(2147483647 * 1000); // 2038-01-19 03:14:07.999 UTC
126
+
127
+ if (isTimeStamp) {
128
+ if (dt < minDate) {
129
+ throw new Error(
130
+ "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'.",
131
+ );
132
+ }
133
+ if (dt > maxDate) {
134
+ throw new Error(
135
+ "Atlassian Forge does not support timestamps beyond 2038-01-19 03:14:07.999999. Please use a smaller date within the supported range.",
136
+ );
137
+ }
138
+ }
115
139
 
116
- return dt.toFormat(format);
140
+ return dt.toFormat(format);
117
141
  }
118
142
 
119
143
  /**
@@ -40,13 +40,17 @@ export const applySchemaMigrations = async (
40
40
  console.info("Migrations applied:", successfulMigrations);
41
41
 
42
42
  const migrationList = await migrationRunner.list();
43
- const migrationHistory =
44
- Array.isArray(migrationList) && migrationList.length > 0
45
- ? migrationList
46
- .sort((a, b) => a.migratedAt.getTime() - b.migratedAt.getTime())
47
- .map((y) => `${y.id}, ${y.name}, ${y.migratedAt.toUTCString()}`)
48
- .join("\n")
49
- : "No migrations found";
43
+ let migrationHistory = "No migrations found";
44
+
45
+ if (Array.isArray(migrationList) && migrationList.length > 0) {
46
+ const sortedMigrations = migrationList.toSorted(
47
+ (a, b) => a.migratedAt.getTime() - b.migratedAt.getTime(),
48
+ );
49
+
50
+ migrationHistory = sortedMigrations
51
+ .map((y) => `${y.id}, ${y.name}, ${y.migratedAt.toUTCString()}`)
52
+ .join("\n");
53
+ }
50
54
 
51
55
  console.info("Migrations history:\nid, name, migrated_at\n", migrationHistory);
52
56
 
@@ -56,13 +60,13 @@ export const applySchemaMigrations = async (
56
60
  statusText: "OK",
57
61
  body: "Migrations successfully executed",
58
62
  };
59
- } catch (error) {
60
- try {
61
- console.error("Error during migration:", JSON.stringify(error));
62
- } catch (e) {
63
- console.trace("Error stringify:", e);
64
- console.error("Error during migration:", error);
65
- }
63
+ } catch (error: any) {
64
+ const errorMessage =
65
+ error?.debug?.sqlMessage ??
66
+ error?.debug?.message ??
67
+ error.message ??
68
+ "Unknown error occurred";
69
+ console.error("Error during migration:", errorMessage);
66
70
  return {
67
71
  headers: { "Content-Type": ["application/json"] },
68
72
  statusCode: 500,
@@ -34,7 +34,7 @@ export async function dropSchemaMigrations(): Promise<TriggerResponse<string>> {
34
34
 
35
35
  // Execute each statement
36
36
  for (const statement of dropStatements) {
37
- console.warn(statement);
37
+ console.debug(`execute DDL: ${statement}`);
38
38
  await sql.executeDDL(statement);
39
39
  }
40
40
 
@@ -42,9 +42,13 @@ export async function dropSchemaMigrations(): Promise<TriggerResponse<string>> {
42
42
  200,
43
43
  "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.",
44
44
  );
45
- } catch (error: unknown) {
46
- console.error(error);
47
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
45
+ } catch (error: any) {
46
+ const errorMessage =
47
+ error?.debug?.sqlMessage ??
48
+ error?.debug?.message ??
49
+ error.message ??
50
+ "Unknown error occurred";
51
+ console.error(errorMessage);
48
52
  return getHttpResponse<string>(500, errorMessage);
49
53
  }
50
54
  }
@@ -34,7 +34,7 @@ export async function dropTableSchemaMigrations(): Promise<TriggerResponse<strin
34
34
 
35
35
  // Execute each statement
36
36
  for (const statement of dropStatements) {
37
- console.warn(statement);
37
+ console.debug(`execute DDL: ${statement}`);
38
38
  await sql.executeDDL(statement);
39
39
  }
40
40
 
@@ -42,9 +42,13 @@ export async function dropTableSchemaMigrations(): Promise<TriggerResponse<strin
42
42
  200,
43
43
  "⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.",
44
44
  );
45
- } catch (error: unknown) {
46
- console.error(error);
47
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
45
+ } catch (error: any) {
46
+ const errorMessage =
47
+ error?.debug?.sqlMessage ??
48
+ error?.debug?.message ??
49
+ error.message ??
50
+ "Unknown error occurred";
51
+ console.error(errorMessage);
48
52
  return getHttpResponse<string>(500, errorMessage);
49
53
  }
50
54
  }
@@ -40,9 +40,13 @@ export async function fetchSchemaWebTrigger(): Promise<TriggerResponse<string>>
40
40
  const sqlStatements = wrapWithForeignKeyChecks(createTableStatements);
41
41
 
42
42
  return getHttpResponse<string>(200, sqlStatements.join(";\n"));
43
- } catch (error: unknown) {
44
- console.error(JSON.stringify(error));
45
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
43
+ } catch (error: any) {
44
+ const errorMessage =
45
+ error?.debug?.sqlMessage ??
46
+ error?.debug?.message ??
47
+ error.message ??
48
+ "Unknown error occurred";
49
+ console.error(errorMessage);
46
50
  return getHttpResponse<string>(500, errorMessage);
47
51
  }
48
52
  }