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.
- package/dist/ForgeSQLORM.js +142 -103
- package/dist/ForgeSQLORM.js.map +1 -1
- package/dist/ForgeSQLORM.mjs +142 -103
- package/dist/ForgeSQLORM.mjs.map +1 -1
- package/dist/core/ForgeSQLORM.d.ts.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.d.ts +24 -25
- package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
- package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
- package/dist/utils/cacheContextUtils.d.ts +4 -2
- package/dist/utils/cacheContextUtils.d.ts.map +1 -1
- package/dist/utils/cacheUtils.d.ts.map +1 -1
- package/dist/utils/forgeDriver.d.ts.map +1 -1
- package/dist/utils/forgeDriverProxy.d.ts.map +1 -1
- package/dist/utils/sqlUtils.d.ts +1 -1
- package/dist/utils/sqlUtils.d.ts.map +1 -1
- package/dist/webtriggers/applyMigrationsWebTrigger.d.ts.map +1 -1
- package/dist/webtriggers/dropMigrationWebTrigger.d.ts.map +1 -1
- package/dist/webtriggers/dropTablesMigrationWebTrigger.d.ts.map +1 -1
- package/dist/webtriggers/fetchSchemaWebTrigger.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/core/ForgeSQLORM.ts +29 -23
- package/src/core/ForgeSQLQueryBuilder.ts +185 -128
- package/src/lib/drizzle/extensions/additionalActions.ts +125 -76
- package/src/lib/drizzle/extensions/types.d.ts +16 -11
- package/src/utils/cacheContextUtils.ts +16 -4
- package/src/utils/cacheUtils.ts +3 -1
- package/src/utils/forgeDriver.ts +16 -21
- package/src/utils/forgeDriverProxy.ts +10 -3
- package/src/utils/sqlUtils.ts +59 -35
- package/src/webtriggers/applyMigrationsWebTrigger.ts +18 -14
- package/src/webtriggers/dropMigrationWebTrigger.ts +8 -4
- package/src/webtriggers/dropTablesMigrationWebTrigger.ts +8 -4
- package/src/webtriggers/fetchSchemaWebTrigger.ts +7 -3
package/src/utils/sqlUtils.ts
CHANGED
|
@@ -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
|
|
61
|
-
const
|
|
62
|
-
if (
|
|
63
|
-
result =
|
|
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.
|
|
66
|
-
|
|
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(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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.
|
|
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:
|
|
46
|
-
|
|
47
|
-
|
|
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.
|
|
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:
|
|
46
|
-
|
|
47
|
-
|
|
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:
|
|
44
|
-
|
|
45
|
-
|
|
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
|
}
|