@bdkinc/knex-ibmi 0.5.9 → 0.5.11

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/index.mjs CHANGED
@@ -473,7 +473,8 @@ var IBMiQueryCompiler = class extends QueryCompiler {
473
473
  updateSql: baseUpdateSql,
474
474
  selectColumns,
475
475
  whereClause: where,
476
- tableName: this.tableName
476
+ tableName: this.tableName,
477
+ setBindingCount: updates.map((fragment) => (fragment.match(/\?/g) || []).length).reduce((sum, count) => sum + count, 0)
477
478
  }
478
479
  };
479
480
  }
@@ -538,6 +539,9 @@ import { Readable } from "stream";
538
539
  import fs from "fs";
539
540
  import path from "path";
540
541
  import { pathToFileURL } from "url";
542
+ function buildTsRuntimeHelpMessage(fileName) {
543
+ return `TypeScript migration '${fileName}' requires a TypeScript runtime loader. Run with a TS-capable runtime (for example: \`node --import tsx\`) or precompile migrations to JavaScript.`;
544
+ }
541
545
  var IBMiMigrationRunner = class {
542
546
  constructor(knex2, config) {
543
547
  __publicField(this, "knex");
@@ -547,9 +551,13 @@ var IBMiMigrationRunner = class {
547
551
  directory: "./migrations",
548
552
  tableName: "KNEX_MIGRATIONS",
549
553
  schemaName: void 0,
550
- extension: "js",
551
554
  ...config
552
555
  };
556
+ if (typeof config?.extension === "string") {
557
+ console.warn(
558
+ "\u26A0\uFE0F IBMiMigrationRunner config 'extension' is ignored for discovery. The runner always discovers .js/.ts/.mjs/.cjs migration files."
559
+ );
560
+ }
553
561
  }
554
562
  getFullTableName() {
555
563
  return this.config.schemaName ? `${this.config.schemaName}.${this.config.tableName}` : this.config.tableName;
@@ -596,7 +604,18 @@ var IBMiMigrationRunner = class {
596
604
  try {
597
605
  const migrationPath = this.getMigrationPath(migrationFile);
598
606
  const fileUrl = pathToFileURL(migrationPath).href;
599
- const migration = await import(`${fileUrl}?t=${Date.now()}`);
607
+ let migration;
608
+ try {
609
+ const moduleNs = await import(`${fileUrl}?t=${Date.now()}`);
610
+ migration = moduleNs.default ?? moduleNs;
611
+ } catch (importError) {
612
+ const isTsMigration = migrationFile.toLowerCase().endsWith(".ts");
613
+ const message = String(importError?.message || importError || "");
614
+ if (isTsMigration && (message.includes("Unknown file extension") || message.includes("Cannot use import statement") || message.includes("Unexpected token"))) {
615
+ throw new Error(buildTsRuntimeHelpMessage(migrationFile));
616
+ }
617
+ throw importError;
618
+ }
600
619
  if (!migration.up || typeof migration.up !== "function") {
601
620
  throw new Error(`Migration ${migrationFile} has no 'up' function`);
602
621
  }
@@ -644,7 +663,18 @@ var IBMiMigrationRunner = class {
644
663
  try {
645
664
  const migrationPath = this.getMigrationPath(migrationFile);
646
665
  const fileUrl = pathToFileURL(migrationPath).href;
647
- const migration = await import(`${fileUrl}?t=${Date.now()}`);
666
+ let migration;
667
+ try {
668
+ const moduleNs = await import(`${fileUrl}?t=${Date.now()}`);
669
+ migration = moduleNs.default ?? moduleNs;
670
+ } catch (importError) {
671
+ const isTsMigration = migrationFile.toLowerCase().endsWith(".ts");
672
+ const message = String(importError?.message || importError || "");
673
+ if (isTsMigration && (message.includes("Unknown file extension") || message.includes("Cannot use import statement") || message.includes("Unexpected token"))) {
674
+ throw new Error(buildTsRuntimeHelpMessage(migrationFile));
675
+ }
676
+ throw importError;
677
+ }
648
678
  if (migration.down && typeof migration.down === "function") {
649
679
  console.log(` \u26A1 Executing rollback...`);
650
680
  await migration.down(this.knex);
@@ -715,17 +745,12 @@ var IBMiMigrationRunner = class {
715
745
  }
716
746
  }
717
747
  getMigrationFiles() {
718
- const { directory, extension } = this.config;
748
+ const { directory } = this.config;
719
749
  if (!fs.existsSync(directory)) {
720
750
  throw new Error(`Migration directory does not exist: ${directory}`);
721
751
  }
722
752
  const validExtensions = ["js", "ts", "mjs", "cjs"];
723
- return fs.readdirSync(directory).filter((file) => {
724
- if (extension && extension !== "js") {
725
- return file.endsWith(`.${extension}`);
726
- }
727
- return validExtensions.some((ext) => file.endsWith(`.${ext}`));
728
- }).sort();
753
+ return fs.readdirSync(directory).filter((file) => validExtensions.some((ext) => file.endsWith(`.${ext}`))).sort();
729
754
  }
730
755
  getMigrationPath(filename) {
731
756
  return path.resolve(this.config.directory, filename);
@@ -969,7 +994,13 @@ var DB2Client = class extends knex.Client {
969
994
  */
970
995
  async executeUpdateReturning(connection, obj) {
971
996
  const { _ibmiUpdateReturning } = obj;
972
- const { updateSql, selectColumns, whereClause, tableName } = _ibmiUpdateReturning;
997
+ const {
998
+ updateSql,
999
+ selectColumns,
1000
+ whereClause,
1001
+ tableName,
1002
+ setBindingCount
1003
+ } = _ibmiUpdateReturning;
973
1004
  this.printDebug(
974
1005
  "Executing UPDATE with returning using transaction approach"
975
1006
  );
@@ -981,10 +1012,8 @@ var DB2Client = class extends knex.Client {
981
1012
  };
982
1013
  await this.executeStatementQuery(connection, updateObj);
983
1014
  const selectSql = whereClause ? `select ${selectColumns} from ${tableName} ${whereClause}` : `select ${selectColumns} from ${tableName}`;
984
- const updateSqlParts = updateSql.split(" where ");
985
- const setClausePart = updateSqlParts[0];
986
- const setBindingCount = (setClausePart.match(/\?/g) || []).length;
987
- const whereBindings = obj.bindings ? obj.bindings.slice(setBindingCount) : [];
1015
+ const inferredSetBindingCount = typeof setBindingCount === "number" ? setBindingCount : (updateSql.split(" where ")[0].match(/\?/g) || []).length;
1016
+ const whereBindings = obj.bindings ? obj.bindings.slice(inferredSetBindingCount) : [];
988
1017
  const selectObj = {
989
1018
  sql: selectSql,
990
1019
  bindings: whereBindings,
@@ -1390,11 +1419,25 @@ var DB2Client = class extends knex.Client {
1390
1419
  validateResponse(obj) {
1391
1420
  if (!obj.response) {
1392
1421
  this.printDebug("response undefined " + this.safeStringify(obj));
1393
- return null;
1422
+ return this.processSqlMethod({
1423
+ ...obj,
1424
+ response: { rows: [], rowCount: 0 }
1425
+ });
1394
1426
  }
1395
1427
  if (!obj.response.rows) {
1396
- this.printError("rows undefined " + this.safeStringify(obj));
1397
- return null;
1428
+ const usesRowCountOnly = !obj.select && (obj.sqlMethod === "del" /* DELETE */ || obj.sqlMethod === "delete" /* DELETE_ALT */ || obj.sqlMethod === "update" /* UPDATE */ || obj.sqlMethod === "counter" /* COUNTER */);
1429
+ if (usesRowCountOnly) {
1430
+ return null;
1431
+ }
1432
+ this.printWarn("rows undefined " + this.safeStringify(obj));
1433
+ return this.processSqlMethod({
1434
+ ...obj,
1435
+ response: {
1436
+ ...obj.response,
1437
+ rows: [],
1438
+ rowCount: obj.response.rowCount ?? 0
1439
+ }
1440
+ });
1398
1441
  }
1399
1442
  return null;
1400
1443
  }
@@ -1439,8 +1482,7 @@ var DB2Client = class extends knex.Client {
1439
1482
  return queryObject;
1440
1483
  } catch (retryError) {
1441
1484
  this.printError(`Retry failed: ${retryError.message}`);
1442
- queryObject.response = { rows: [], rowCount: 0 };
1443
- return queryObject;
1485
+ throw this.wrapError(retryError, `${method}_retry`, queryObject);
1444
1486
  }
1445
1487
  }
1446
1488
  /**
@@ -1485,7 +1527,8 @@ var DB2Client = class extends knex.Client {
1485
1527
  return errorMessage.includes("sql") || errorMessage.includes("syntax") || errorMessage.includes("table") || errorMessage.includes("column");
1486
1528
  }
1487
1529
  processSqlMethod(obj) {
1488
- const { rows, rowCount } = obj.response;
1530
+ const rows = obj.response?.rows ?? [];
1531
+ const rowCount = obj.response?.rowCount;
1489
1532
  switch (obj.sqlMethod) {
1490
1533
  case "select" /* SELECT */:
1491
1534
  return rows;