forge-sql-orm 2.0.17 → 2.0.18

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ForgeSQLORM.d.ts","sourceRoot":"","sources":["../../src/core/ForgeSQLORM.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAW,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAEpG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAmI5D;;;GAGG;AACH,cAAM,WAAY,YAAW,iBAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;gBAEpC,OAAO,CAAC,EAAE,kBAAkB;IAIxC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,UAAU,SAAS,cAAc,EACtC,MAAM,EAAE,UAAU,GACjB,kBAAkB,CAAC,UAAU,EAAE,2BAA2B,CAAC;IAI9D;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,UAAU,SAAS,cAAc,EAC9C,MAAM,EAAE,UAAU,GACjB,kBAAkB,CAAC,UAAU,EAAE,2BAA2B,CAAC;IAI9D;;;OAGG;IACH,IAAI,IAAI,YAAY;IAIpB;;;OAGG;IACH,KAAK,IAAI,iBAAiB;IAI1B;;;;;;;;OAQG;IACH,sBAAsB;CAGvB;AAED,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ForgeSQLORM.d.ts","sourceRoot":"","sources":["../../src/core/ForgeSQLORM.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAW,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAEpG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAoI5D;;;GAGG;AACH,cAAM,WAAY,YAAW,iBAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;gBAEpC,OAAO,CAAC,EAAE,kBAAkB;IAIxC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,UAAU,SAAS,cAAc,EACtC,MAAM,EAAE,UAAU,GACjB,kBAAkB,CAAC,UAAU,EAAE,2BAA2B,CAAC;IAI9D;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,UAAU,SAAS,cAAc,EAC9C,MAAM,EAAE,UAAU,GACjB,kBAAkB,CAAC,UAAU,EAAE,2BAA2B,CAAC;IAI9D;;;OAGG;IACH,IAAI,IAAI,YAAY;IAIpB;;;OAGG;IACH,KAAK,IAAI,iBAAiB;IAI1B;;;;;;;;OAQG;IACH,sBAAsB;CAGvB;AAED,eAAe,WAAW,CAAC"}
@@ -4,6 +4,7 @@ import { AnyMySqlSelectQueryBuilder, AnyMySqlTable, MySqlSelectBuilder } from "d
4
4
  import { MySqlSelectDynamic, type SelectedFields } from "drizzle-orm/mysql-core/query-builders/select.types";
5
5
  import { InferInsertModel, SQL } from "drizzle-orm";
6
6
  import { MySqlRemoteDatabase, MySqlRemotePreparedQueryHKT } from "drizzle-orm/mysql-proxy/index";
7
+ import { SqlHints } from "../utils/sqlHints";
7
8
  /**
8
9
  * Interface representing the main ForgeSQL operations.
9
10
  * Provides access to CRUD operations and schema-level SQL operations.
@@ -74,12 +75,12 @@ export interface CRUDForgeSQL {
74
75
  * Inserts multiple records into the database.
75
76
  * @template T - The type of the table schema
76
77
  * @param {T} schema - The entity schema
77
- * @param {Partial<InferInsertModel<T>>[]} models - The list of entities to insert
78
+ * @param {<InferInsertModel<T>[]} models - The list of entities to insert
78
79
  * @param {boolean} [updateIfExists] - Whether to update the row if it already exists (default: false)
79
80
  * @returns {Promise<number>} The number of inserted rows
80
81
  * @throws {Error} If the insert operation fails
81
82
  */
82
- insert<T extends AnyMySqlTable>(schema: T, models: Partial<InferInsertModel<T>>[], updateIfExists?: boolean): Promise<number>;
83
+ insert<T extends AnyMySqlTable>(schema: T, models: InferInsertModel<T>[], updateIfExists?: boolean): Promise<number>;
83
84
  /**
84
85
  * Deletes a record by its ID.
85
86
  * @template T - The type of the table schema
@@ -175,21 +176,15 @@ export interface TableMetadata {
175
176
  */
176
177
  export type AdditionalMetadata = Record<string, TableMetadata>;
177
178
  /**
178
- * Options for configuring ForgeSQL ORM behavior.
179
+ * Interface for ForgeSQL ORM options
179
180
  */
180
181
  export interface ForgeSqlOrmOptions {
181
- /**
182
- * Enables logging of raw SQL queries in the Atlassian Forge Developer Console.
183
- * Useful for debugging and monitoring SQL operations.
184
- * @default false
185
- */
182
+ /** Whether to log raw SQL queries */
186
183
  logRawSqlQuery?: boolean;
187
- /**
188
- * Disables optimistic locking for all operations.
189
- * When enabled, version checks are skipped during updates.
190
- * @default false
191
- */
184
+ /** Whether to disable optimistic locking */
192
185
  disableOptimisticLocking?: boolean;
186
+ /** SQL hints to be applied to queries */
187
+ hints?: SqlHints;
193
188
  /**
194
189
  * Additional metadata for table configuration.
195
190
  * Allows specifying table-specific settings and behaviors.
@@ -1 +1 @@
1
- {"version":3,"file":"ForgeSQLQueryBuilder.d.ts","sourceRoot":"","sources":["../../src/core/ForgeSQLQueryBuilder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ForgeSQLQueryBuilder.d.ts","sourceRoot":"","sources":["../../src/core/ForgeSQLQueryBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { SqlHints } from "./sqlHints";
2
+ /**
3
+ * Creates a proxy for the forgeDriver that injects SQL hints
4
+ * @returns A proxied version of the forgeDriver
5
+ */
6
+ export declare function createForgeDriverProxy(options?: SqlHints, logRawSqlQuery?: boolean): (query: string, params: any[], method: "all" | "execute") => Promise<{
7
+ rows: any[];
8
+ insertId?: number;
9
+ affectedRows?: number;
10
+ }>;
11
+ //# sourceMappingURL=forgeDriverProxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forgeDriverProxy.d.ts","sourceRoot":"","sources":["../../src/utils/forgeDriverProxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,cAAc,CAAC,EAAE,OAAO,IAE/E,OAAO,MAAM,EACb,QAAQ,GAAG,EAAE,EACb,QAAQ,KAAK,GAAG,SAAS,KACxB,OAAO,CAAC;IACT,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC,CAUH"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Interface for SQL hints configuration
3
+ */
4
+ export interface SqlHints {
5
+ /** SQL hints for SELECT queries */
6
+ select?: string[];
7
+ /** SQL hints for INSERT queries */
8
+ insert?: string[];
9
+ /** SQL hints for UPDATE queries */
10
+ update?: string[];
11
+ /** SQL hints for DELETE queries */
12
+ delete?: string[];
13
+ }
14
+ /**
15
+ * Detects the type of SQL query and injects appropriate hints
16
+ * @param query - The SQL query to analyze
17
+ * @param hints - The hints configuration
18
+ * @returns The modified query with injected hints
19
+ */
20
+ export declare function injectSqlHints(query: string, hints?: SqlHints): string;
21
+ //# sourceMappingURL=sqlHints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlHints.d.ts","sourceRoot":"","sources":["../../src/utils/sqlHints.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,CA0CtE"}
@@ -34,12 +34,6 @@ export interface MetadataInfo {
34
34
  * @returns Date object
35
35
  */
36
36
  export declare const parseDateTime: (value: string, format: string) => Date;
37
- /**
38
- * Extracts the alias from a SQL query
39
- * @param query - The SQL query to extract the alias from
40
- * @returns The extracted alias or the original query if no alias found
41
- */
42
- export declare function extractAlias(query: string): string;
43
37
  /**
44
38
  * Gets primary keys from the schema.
45
39
  * @template T - The type of the table schema
@@ -1 +1 @@
1
- {"version":3,"file":"sqlUtils.d.ts","sourceRoot":"","sources":["../../src/utils/sqlUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAA0C,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,aAAa,EAAqB,MAAM,8BAA8B,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AAIzF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,8BAA8B;IAC9B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,yCAAyC;IACzC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,oCAAoC;IACpC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,oCAAoC;IACpC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,0CAA0C;IAC1C,iBAAiB,EAAE,uBAAuB,EAAE,CAAC;IAC7C,kCAAkC;IAClC,MAAM,EAAE,GAAG,EAAE,CAAC;CACf;AAUD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,IAM7D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAkCvF;AA0DD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,CAoEnE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,CAc7E;AAED,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAmBhD,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,GAAG,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAC,MAAM,EACf,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,cAAc,GACvB,GAAG,CAmBL;AACD,wBAAgB,wBAAwB,CAAC,UAAU,SAAS,cAAc,EACxE,MAAM,EAAE,UAAU,GACjB;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,CAUtD;AAsED,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,UAAU,EACpD,IAAI,EAAE,CAAC,EAAE,EACT,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAClC,CAAC,EAAE,CAUL"}
1
+ {"version":3,"file":"sqlUtils.d.ts","sourceRoot":"","sources":["../../src/utils/sqlUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAA0C,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,aAAa,EAAqB,MAAM,8BAA8B,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AAIzF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,8BAA8B;IAC9B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,yCAAyC;IACzC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,oCAAoC;IACpC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,oCAAoC;IACpC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,0CAA0C;IAC1C,iBAAiB,EAAE,uBAAuB,EAAE,CAAC;IAC7C,kCAAkC;IAClC,MAAM,EAAE,GAAG,EAAE,CAAC;CACf;AAUD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,IAiB7D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAkCvF;AA0DD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,CAoEnE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,CAc7E;AAED,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAuBhD,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,GAAG,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,cAAc,GACvB,GAAG,CAmBL;AACD,wBAAgB,wBAAwB,CAAC,UAAU,SAAS,cAAc,EACxE,MAAM,EAAE,UAAU,GACjB;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,CAUtD;AAsED,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,UAAU,EACpD,IAAI,EAAE,CAAC,EAAE,EACT,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAClC,CAAC,EAAE,CAUL"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-sql-orm",
3
- "version": "2.0.17",
3
+ "version": "2.0.18",
4
4
  "description": "Drizzle ORM integration for Forge-SQL in Atlassian Forge applications.",
5
5
  "main": "dist/ForgeSQLORM.js",
6
6
  "module": "dist/ForgeSQLORM.mjs",
@@ -37,7 +37,7 @@ export class ForgeSQLCrudOperations implements CRUDForgeSQL {
37
37
  */
38
38
  async insert<T extends AnyMySqlTable>(
39
39
  schema: T,
40
- models: Partial<InferInsertModel<T>>[],
40
+ models: InferInsertModel<T>[],
41
41
  updateIfExists: boolean = false,
42
42
  ): Promise<number> {
43
43
  if (!models?.length) return 0;
@@ -257,12 +257,12 @@ export class ForgeSQLCrudOperations implements CRUDForgeSQL {
257
257
  }
258
258
  const versionMetadata = this.options.additionalMetadata?.[tableName]?.versionField;
259
259
  if (!versionMetadata) return undefined;
260
- let fieldName = versionMetadata.fieldName;
260
+ let fieldName = versionMetadata.fieldName;
261
261
 
262
262
  let versionField = columns[versionMetadata.fieldName];
263
- if (!versionField){
264
- const find = Object.entries(columns).find(([_,c])=>c.name === versionMetadata.fieldName);
265
- if (find){
263
+ if (!versionField) {
264
+ const find = Object.entries(columns).find(([, c]) => c.name === versionMetadata.fieldName);
265
+ if (find) {
266
266
  fieldName = find[0];
267
267
  versionField = find[1];
268
268
  }
@@ -349,15 +349,22 @@ let fieldName = versionMetadata.fieldName;
349
349
  columns: Record<string, AnyColumn>,
350
350
  ): InferInsertModel<T> {
351
351
  if (!versionMetadata || !columns) return model as InferInsertModel<T>;
352
+ let fieldName = versionMetadata.fieldName;
353
+ let versionField = columns[versionMetadata.fieldName];
354
+ if (!versionField) {
355
+ const find = Object.entries(columns).find(([, c]) => c.name === versionMetadata.fieldName);
356
+ if (find) {
357
+ fieldName = find[0];
358
+ versionField = find[1];
359
+ }
360
+ }
352
361
 
353
- const versionField = columns[versionMetadata.fieldName];
354
362
  if (!versionField) return model as InferInsertModel<T>;
355
363
 
356
364
  const modelWithVersion = { ...model };
357
365
  const fieldType = versionField.getSQLType();
358
366
  const versionValue = fieldType === "datetime" || fieldType === "timestamp" ? new Date() : 1;
359
- modelWithVersion[versionMetadata.fieldName as keyof typeof modelWithVersion] =
360
- versionValue as any;
367
+ modelWithVersion[fieldName as keyof typeof modelWithVersion] = versionValue as any;
361
368
 
362
369
  return modelWithVersion as InferInsertModel<T>;
363
370
  }
@@ -7,7 +7,7 @@ import {
7
7
  } from "./ForgeSQLQueryBuilder";
8
8
  import { ForgeSQLSelectOperations } from "./ForgeSQLSelectOperations";
9
9
  import { drizzle, MySqlRemoteDatabase, MySqlRemotePreparedQueryHKT } from "drizzle-orm/mysql-proxy";
10
- import { forgeDriver } from "../utils/forgeDriver";
10
+ import { createForgeDriverProxy } from "../utils/forgeDriverProxy";
11
11
  import type { SelectedFields } from "drizzle-orm/mysql-core/query-builders/select.types";
12
12
  import { MySqlSelectBuilder } from "drizzle-orm/mysql-core";
13
13
  import { patchDbWithSelectAliased } from "../lib/drizzle/extensions/selectAliased";
@@ -37,8 +37,9 @@ class ForgeSQLORMImpl implements ForgeSqlOperation {
37
37
  console.debug("Initializing ForgeSQLORM...");
38
38
  }
39
39
  // Initialize Drizzle instance with our custom driver
40
+ const proxiedDriver = createForgeDriverProxy(newOptions.hints, newOptions.logRawSqlQuery);
40
41
  this.drizzle = patchDbWithSelectAliased(
41
- drizzle(forgeDriver, { logger: newOptions.logRawSqlQuery }),
42
+ drizzle(proxiedDriver, { logger: newOptions.logRawSqlQuery }),
42
43
  );
43
44
  this.crudOperations = new ForgeSQLCrudOperations(this, newOptions);
44
45
  this.fetchOperations = new ForgeSQLSelectOperations(newOptions);
@@ -14,6 +14,7 @@ import { InferInsertModel, SQL } from "drizzle-orm";
14
14
  import moment from "moment/moment";
15
15
  import { parseDateTime } from "../utils/sqlUtils";
16
16
  import { MySqlRemoteDatabase, MySqlRemotePreparedQueryHKT } from "drizzle-orm/mysql-proxy/index";
17
+ import { SqlHints } from "../utils/sqlHints";
17
18
 
18
19
  // ============= Core Types =============
19
20
 
@@ -98,14 +99,14 @@ export interface CRUDForgeSQL {
98
99
  * Inserts multiple records into the database.
99
100
  * @template T - The type of the table schema
100
101
  * @param {T} schema - The entity schema
101
- * @param {Partial<InferInsertModel<T>>[]} models - The list of entities to insert
102
+ * @param {<InferInsertModel<T>[]} models - The list of entities to insert
102
103
  * @param {boolean} [updateIfExists] - Whether to update the row if it already exists (default: false)
103
104
  * @returns {Promise<number>} The number of inserted rows
104
105
  * @throws {Error} If the insert operation fails
105
106
  */
106
107
  insert<T extends AnyMySqlTable>(
107
108
  schema: T,
108
- models: Partial<InferInsertModel<T>>[],
109
+ models: InferInsertModel<T>[],
109
110
  updateIfExists?: boolean,
110
111
  ): Promise<number>;
111
112
 
@@ -228,22 +229,15 @@ export interface TableMetadata {
228
229
  export type AdditionalMetadata = Record<string, TableMetadata>;
229
230
 
230
231
  /**
231
- * Options for configuring ForgeSQL ORM behavior.
232
+ * Interface for ForgeSQL ORM options
232
233
  */
233
234
  export interface ForgeSqlOrmOptions {
234
- /**
235
- * Enables logging of raw SQL queries in the Atlassian Forge Developer Console.
236
- * Useful for debugging and monitoring SQL operations.
237
- * @default false
238
- */
235
+ /** Whether to log raw SQL queries */
239
236
  logRawSqlQuery?: boolean;
240
-
241
- /**
242
- * Disables optimistic locking for all operations.
243
- * When enabled, version checks are skipped during updates.
244
- * @default false
245
- */
237
+ /** Whether to disable optimistic locking */
246
238
  disableOptimisticLocking?: boolean;
239
+ /** SQL hints to be applied to queries */
240
+ hints?: SqlHints;
247
241
 
248
242
  /**
249
243
  * Additional metadata for table configuration.
@@ -301,7 +295,7 @@ export const forgeTimestampString = customType<{
301
295
  return "timestamp";
302
296
  },
303
297
  toDriver(value: Date) {
304
- return moment(value as Date).format("YYYY-MM-DDTHH:mm:ss.SSS");
298
+ return moment(new Date(value)).format("YYYY-MM-DDTHH:mm:ss.SSS");
305
299
  },
306
300
  fromDriver(value: unknown) {
307
301
  const format = "YYYY-MM-DDTHH:mm:ss.SSS";
@@ -0,0 +1,27 @@
1
+ import { forgeDriver } from "./forgeDriver";
2
+ import { injectSqlHints, SqlHints } from "./sqlHints";
3
+
4
+ /**
5
+ * Creates a proxy for the forgeDriver that injects SQL hints
6
+ * @returns A proxied version of the forgeDriver
7
+ */
8
+ export function createForgeDriverProxy(options?: SqlHints, logRawSqlQuery?: boolean) {
9
+ return async (
10
+ query: string,
11
+ params: any[],
12
+ method: "all" | "execute",
13
+ ): Promise<{
14
+ rows: any[];
15
+ insertId?: number;
16
+ affectedRows?: number;
17
+ }> => {
18
+ // Inject SQL hints into the query
19
+ const modifiedQuery = injectSqlHints(query, options);
20
+
21
+ if (options && logRawSqlQuery) {
22
+ console.warn("modified query: " + modifiedQuery);
23
+ }
24
+ // Call the original forgeDriver with the modified query
25
+ return forgeDriver(modifiedQuery, params, method);
26
+ };
27
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Interface for SQL hints configuration
3
+ */
4
+ export interface SqlHints {
5
+ /** SQL hints for SELECT queries */
6
+ select?: string[];
7
+ /** SQL hints for INSERT queries */
8
+ insert?: string[];
9
+ /** SQL hints for UPDATE queries */
10
+ update?: string[];
11
+ /** SQL hints for DELETE queries */
12
+ delete?: string[];
13
+ }
14
+
15
+ /**
16
+ * Detects the type of SQL query and injects appropriate hints
17
+ * @param query - The SQL query to analyze
18
+ * @param hints - The hints configuration
19
+ * @returns The modified query with injected hints
20
+ */
21
+ export function injectSqlHints(query: string, hints?: SqlHints): string {
22
+ if (!hints) {
23
+ return query;
24
+ }
25
+
26
+ // Normalize the query for easier matching
27
+ const normalizedQuery = query.trim().toUpperCase();
28
+
29
+ // Get the appropriate hints based on query type
30
+ let queryHints: string[] | undefined;
31
+
32
+ if (normalizedQuery.startsWith("SELECT")) {
33
+ queryHints = hints.select;
34
+ } else if (normalizedQuery.startsWith("INSERT")) {
35
+ queryHints = hints.insert;
36
+ } else if (normalizedQuery.startsWith("UPDATE")) {
37
+ queryHints = hints.update;
38
+ } else if (normalizedQuery.startsWith("DELETE")) {
39
+ queryHints = hints.delete;
40
+ }
41
+
42
+ // If no hints for this query type, return original query
43
+ if (!queryHints || queryHints.length === 0) {
44
+ return query;
45
+ }
46
+
47
+ // Join all hints with spaces
48
+ const hintsString = queryHints.join(" ");
49
+
50
+ // Inject hints into the query
51
+ if (normalizedQuery.startsWith("SELECT")) {
52
+ return `SELECT /*+ ${hintsString} */ ${query.substring(6)}`;
53
+ } else if (normalizedQuery.startsWith("INSERT")) {
54
+ return `INSERT /*+ ${hintsString} */ ${query.substring(6)}`;
55
+ } else if (normalizedQuery.startsWith("UPDATE")) {
56
+ return `UPDATE /*+ ${hintsString} */ ${query.substring(6)}`;
57
+ } else if (normalizedQuery.startsWith("DELETE")) {
58
+ return `DELETE /*+ ${hintsString} */ ${query.substring(6)}`;
59
+ }
60
+
61
+ // If no match found, return original query
62
+ return query;
63
+ }
@@ -47,23 +47,24 @@ interface ConfigBuilderData {
47
47
  * @returns Date object
48
48
  */
49
49
  export const parseDateTime = (value: string, format: string): Date => {
50
+ let result: Date;
50
51
  const m = moment(value, format, true);
51
52
  if (!m.isValid()) {
52
- return moment(value).toDate();
53
+ const momentDate = moment(value);
54
+ if (momentDate.isValid()) {
55
+ result = momentDate.toDate();
56
+ } else {
57
+ result = new Date(value);
58
+ }
59
+ } else {
60
+ result = m.toDate();
61
+ }
62
+ if (isNaN(result.getTime())) {
63
+ result = new Date(value);
53
64
  }
54
- return m.toDate();
65
+ return result;
55
66
  };
56
67
 
57
- /**
58
- * Extracts the alias from a SQL query
59
- * @param query - The SQL query to extract the alias from
60
- * @returns The extracted alias or the original query if no alias found
61
- */
62
- export function extractAlias(query: string): string {
63
- const match = query.match(/\bas\s+(['"`]?)([\w*]+)\1$/i);
64
- return match ? match[2] : query;
65
- }
66
-
67
68
  /**
68
69
  * Gets primary keys from the schema.
69
70
  * @template T - The type of the table schema
@@ -260,7 +261,11 @@ export function generateDropTableStatements(tables: AnyMySqlTable[]): string[] {
260
261
 
261
262
  type AliasColumnMap = Record<string, AnyColumn>;
262
263
 
263
- function mapSelectTableToAlias(table: MySqlTable,uniqPrefix:string, aliasMap: AliasColumnMap): any {
264
+ function mapSelectTableToAlias(
265
+ table: MySqlTable,
266
+ uniqPrefix: string,
267
+ aliasMap: AliasColumnMap,
268
+ ): any {
264
269
  const { columns, tableName } = getTableMetadata(table);
265
270
  const selectionsTableFields: Record<string, unknown> = {};
266
271
  Object.keys(columns).forEach((name) => {
@@ -280,7 +285,7 @@ function isDrizzleColumn(column: any): boolean {
280
285
  export function mapSelectAllFieldsToAlias(
281
286
  selections: any,
282
287
  name: string,
283
- uniqName:string,
288
+ uniqName: string,
284
289
  fields: any,
285
290
  aliasMap: AliasColumnMap,
286
291
  ): any {
@@ -312,7 +317,7 @@ export function mapSelectFieldsWithAlias<TSelection extends SelectedFields>(
312
317
  const aliasMap: AliasColumnMap = {};
313
318
  const selections: any = {};
314
319
  Object.entries(fields).forEach(([name, fields]) => {
315
- mapSelectAllFieldsToAlias(selections, name,name, fields, aliasMap);
320
+ mapSelectAllFieldsToAlias(selections, name, name, fields, aliasMap);
316
321
  });
317
322
  return { selections, aliasMap };
318
323
  }
@@ -402,7 +407,12 @@ export function applyFromDriverTransform<T, TSelection>(
402
407
  }
403
408
 
404
409
  function processNullBranches(obj: Record<string, unknown>): Record<string, unknown> | null {
405
- if (obj === null || typeof obj !== 'object' || obj===undefined) {
410
+ if (obj === null || typeof obj !== "object" || obj === undefined) {
411
+ return obj;
412
+ }
413
+
414
+ // Skip built-in objects like Date, Array, etc.
415
+ if (obj.constructor && obj.constructor.name !== "Object") {
406
416
  return obj;
407
417
  }
408
418
 
@@ -410,12 +420,12 @@ function processNullBranches(obj: Record<string, unknown>): Record<string, unkno
410
420
  let allNull = true;
411
421
 
412
422
  for (const [key, value] of Object.entries(obj)) {
413
- if (value === null || value===undefined) {
423
+ if (value === null || value === undefined) {
414
424
  result[key] = null;
415
425
  continue;
416
426
  }
417
427
 
418
- if (typeof value === 'object' && (value !== null || value !== undefined) ) {
428
+ if (typeof value === "object" && value !== null && value !== undefined) {
419
429
  const processed = processNullBranches(value as Record<string, unknown>);
420
430
  result[key] = processed;
421
431
  if (processed !== null) {