bun-query-builder 0.1.26 → 0.1.27

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/src/index.js CHANGED
@@ -11762,6 +11762,7 @@ var init_config = __esm(() => {
11762
11762
  // src/db.ts
11763
11763
  var {SQL } = globalThis.Bun;
11764
11764
  import { Database } from "bun:sqlite";
11765
+ import process19 from "process";
11765
11766
 
11766
11767
  class SQLiteWrapper {
11767
11768
  db;
@@ -11975,6 +11976,16 @@ function createSQLiteSQL(filename) {
11975
11976
  return sqlFunction;
11976
11977
  }
11977
11978
  function createConnectionString(dialect, dbConfig) {
11979
+ if ((dialect === "postgres" || dialect === "mysql") && process19.env.DB_CONNECTION === dialect) {
11980
+ const e = process19.env;
11981
+ const envDb = (e.DB_DATABASE || dbConfig.database || "").replace(/^['"]|['"]$/g, "");
11982
+ const envUser = e.DB_USERNAME || dbConfig.username;
11983
+ const envPass = e.DB_PASSWORD ?? dbConfig.password ?? "";
11984
+ const envHost = e.DB_HOST || dbConfig.host || "localhost";
11985
+ const envPort = e.DB_PORT || dbConfig.port;
11986
+ const scheme = dialect === "postgres" ? "postgres" : "mysql";
11987
+ return `${scheme}://${envUser}:${envPass}@${envHost}${envPort ? `:${envPort}` : ""}/${envDb}`;
11988
+ }
11978
11989
  if (dbConfig.url) {
11979
11990
  return dbConfig.url;
11980
11991
  }
@@ -12392,13 +12403,29 @@ class QueryCache {
12392
12403
  this.cache.delete(key);
12393
12404
  return null;
12394
12405
  }
12406
+ this.cache.delete(key);
12407
+ this.cache.set(key, entry);
12395
12408
  return entry.data;
12396
12409
  }
12397
12410
  set(key, data, ttlMs) {
12411
+ if (this.cache.has(key))
12412
+ this.cache.delete(key);
12398
12413
  if (this.cache.size >= this.maxSize) {
12399
- const firstKey = this.cache.keys().next().value;
12400
- if (firstKey)
12401
- this.cache.delete(firstKey);
12414
+ const now = Date.now();
12415
+ let evicted = false;
12416
+ for (const [k, v] of this.cache) {
12417
+ if (now > v.expiresAt) {
12418
+ this.cache.delete(k);
12419
+ evicted = true;
12420
+ if (this.cache.size < this.maxSize)
12421
+ break;
12422
+ }
12423
+ }
12424
+ if (!evicted) {
12425
+ const lruKey = this.cache.keys().next().value;
12426
+ if (lruKey !== undefined)
12427
+ this.cache.delete(lruKey);
12428
+ }
12402
12429
  }
12403
12430
  this.cache.set(key, {
12404
12431
  data,
@@ -12469,6 +12496,9 @@ function reorderSelectClauses(sql) {
12469
12496
  continue;
12470
12497
  if (i === 0 || !/\s/.test(sql[i - 1]))
12471
12498
  continue;
12499
+ const lead = sql.charCodeAt(i) & ~32;
12500
+ if (lead !== 71 && lead !== 79 && lead !== 72 && lead !== 76 && lead !== 87)
12501
+ continue;
12472
12502
  const rest = sql.slice(i);
12473
12503
  for (const { key, tokens } of KEYWORDS) {
12474
12504
  const m = rest.match(tokens);
@@ -13245,28 +13275,6 @@ function createQueryBuilder(state) {
13245
13275
  if (!rels) {
13246
13276
  return fromTable;
13247
13277
  }
13248
- const _buildConditionalJoin = (baseJoinCondition, targetTable2) => {
13249
- let joinCondition = baseJoinCondition;
13250
- if (config5.softDeletes?.enabled && config5.softDeletes?.defaultFilter) {
13251
- const softDeleteColumn = config5.softDeletes.column || "deleted_at";
13252
- joinCondition = `${joinCondition} AND ${targetTable2}.${softDeleteColumn} IS NULL`;
13253
- }
13254
- if (!condition)
13255
- return joinCondition;
13256
- const conditionBuilder = {
13257
- where: (col, op, val) => {
13258
- const valStr = typeof val === "string" ? `'${val}'` : String(val);
13259
- return `${targetTable2}.${col} ${op} ${valStr}`;
13260
- }
13261
- };
13262
- try {
13263
- const additionalCondition = condition(conditionBuilder);
13264
- if (additionalCondition && typeof additionalCondition === "string") {
13265
- return `${joinCondition} AND ${additionalCondition}`;
13266
- }
13267
- } catch {}
13268
- return joinCondition;
13269
- };
13270
13278
  const addSoftDeleteCheck = (table2) => {
13271
13279
  if (config5.softDeletes?.enabled && config5.softDeletes?.defaultFilter) {
13272
13280
  const softDeleteColumn = config5.softDeletes.column || "deleted_at";
@@ -13745,6 +13753,8 @@ function createQueryBuilder(state) {
13745
13753
  where(expr, op, value) {
13746
13754
  const getWhereKeyword = () => SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
13747
13755
  if (typeof expr === "string" && op !== undefined) {
13756
+ validateIdentifier(String(expr), "where(column)");
13757
+ assertSafeWhereOperator(op, "where(operator)");
13748
13758
  const operator = String(op).toLowerCase();
13749
13759
  if (operator === "in" || operator === "not in") {
13750
13760
  const values = Array.isArray(value) ? value : [value];
@@ -13766,7 +13776,8 @@ function createQueryBuilder(state) {
13766
13776
  if (Array.isArray(expr)) {
13767
13777
  const [col, op2, val] = expr;
13768
13778
  const colName = String(col);
13769
- const operator = String(op2);
13779
+ validateIdentifier(colName, "where(column)");
13780
+ const operator = assertSafeWhereOperator(op2, "where(operator)");
13770
13781
  if (operator === "in" || operator === "not in") {
13771
13782
  const values = Array.isArray(val) ? val : [val];
13772
13783
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
@@ -13788,6 +13799,7 @@ function createQueryBuilder(state) {
13788
13799
  const keys = Object.keys(whereObject);
13789
13800
  const conditions = [];
13790
13801
  for (const key of keys) {
13802
+ validateIdentifier(key, "where(column)");
13791
13803
  const value2 = whereObject[key];
13792
13804
  if (Array.isArray(value2)) {
13793
13805
  const placeholders = getPlaceholders(value2.length, whereParams.length + 1);
@@ -13816,18 +13828,21 @@ function createQueryBuilder(state) {
13816
13828
  return this;
13817
13829
  },
13818
13830
  whereNull(column) {
13831
+ validateIdentifier(String(column), "whereNull(column)");
13819
13832
  const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
13820
13833
  text = `${text} ${keyword} ${String(column)} IS NULL`;
13821
13834
  built = null;
13822
13835
  return this;
13823
13836
  },
13824
13837
  whereNotNull(column) {
13838
+ validateIdentifier(String(column), "whereNotNull(column)");
13825
13839
  const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
13826
13840
  text = `${text} ${keyword} ${String(column)} IS NOT NULL`;
13827
13841
  built = null;
13828
13842
  return this;
13829
13843
  },
13830
13844
  whereBetween(column, start, end) {
13845
+ validateIdentifier(String(column), "whereBetween(column)");
13831
13846
  const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
13832
13847
  const i = whereParams.length + 1;
13833
13848
  text = `${text} ${keyword} ${String(column)} BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`;
@@ -13842,6 +13857,7 @@ function createQueryBuilder(state) {
13842
13857
  return this;
13843
13858
  },
13844
13859
  whereJsonContains(column, json) {
13860
+ validateIdentifier(String(column), "whereJsonContains(column)");
13845
13861
  const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
13846
13862
  const dialect = config5.dialect;
13847
13863
  const idx = whereParams.length + 1;
@@ -14011,6 +14027,7 @@ function createQueryBuilder(state) {
14011
14027
  return this;
14012
14028
  },
14013
14029
  whereNotBetween(column, start, end) {
14030
+ validateIdentifier(String(column), "whereNotBetween(column)");
14014
14031
  const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14015
14032
  const i = whereParams.length + 1;
14016
14033
  text += ` ${keyword} ${column} NOT BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`;
@@ -14053,6 +14070,7 @@ function createQueryBuilder(state) {
14053
14070
  return this;
14054
14071
  },
14055
14072
  whereIn(column, values) {
14073
+ validateIdentifier(String(column), "whereIn(column)");
14056
14074
  const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14057
14075
  if (Array.isArray(values)) {
14058
14076
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
@@ -14065,6 +14083,7 @@ function createQueryBuilder(state) {
14065
14083
  return this;
14066
14084
  },
14067
14085
  orWhereIn(column, values) {
14086
+ validateIdentifier(String(column), "orWhereIn(column)");
14068
14087
  if (Array.isArray(values)) {
14069
14088
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14070
14089
  text += ` OR ${column} IN (${placeholders})`;
@@ -14076,6 +14095,7 @@ function createQueryBuilder(state) {
14076
14095
  return this;
14077
14096
  },
14078
14097
  whereNotIn(column, values) {
14098
+ validateIdentifier(String(column), "whereNotIn(column)");
14079
14099
  const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
14080
14100
  if (Array.isArray(values)) {
14081
14101
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
@@ -14088,6 +14108,7 @@ function createQueryBuilder(state) {
14088
14108
  return this;
14089
14109
  },
14090
14110
  orWhereNotIn(column, values) {
14111
+ validateIdentifier(String(column), "orWhereNotIn(column)");
14091
14112
  if (Array.isArray(values)) {
14092
14113
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
14093
14114
  text += ` OR ${column} NOT IN (${placeholders})`;
@@ -14113,6 +14134,8 @@ function createQueryBuilder(state) {
14113
14134
  },
14114
14135
  andWhere(expr, op, value) {
14115
14136
  if (typeof expr === "string" && op !== undefined) {
14137
+ validateIdentifier(String(expr), "andWhere(column)");
14138
+ assertSafeWhereOperator(op, "andWhere(operator)");
14116
14139
  const paramIndex = whereParams.length + 1;
14117
14140
  whereConditions.push(`${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
14118
14141
  whereParams.push(value);
@@ -14123,7 +14146,8 @@ function createQueryBuilder(state) {
14123
14146
  if (Array.isArray(expr)) {
14124
14147
  const [col, op2, val] = expr;
14125
14148
  const colName = String(col);
14126
- const operator = String(op2);
14149
+ validateIdentifier(colName, "andWhere(column)");
14150
+ const operator = assertSafeWhereOperator(op2, "andWhere(operator)");
14127
14151
  if (operator === "in" || operator === "not in") {
14128
14152
  const values = Array.isArray(val) ? val : [val];
14129
14153
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
@@ -14173,6 +14197,8 @@ function createQueryBuilder(state) {
14173
14197
  },
14174
14198
  orWhere(expr, op, value) {
14175
14199
  if (typeof expr === "string" && op !== undefined) {
14200
+ validateIdentifier(String(expr), "orWhere(column)");
14201
+ assertSafeWhereOperator(op, "orWhere(operator)");
14176
14202
  const paramIndex = whereParams.length + 1;
14177
14203
  whereConditions.push(`OR ${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
14178
14204
  whereParams.push(value);
@@ -14183,7 +14209,8 @@ function createQueryBuilder(state) {
14183
14209
  if (Array.isArray(expr)) {
14184
14210
  const [col, op2, val] = expr;
14185
14211
  const colName = String(col);
14186
- const operator = String(op2);
14212
+ validateIdentifier(colName, "orWhere(column)");
14213
+ const operator = assertSafeWhereOperator(op2, "orWhere(operator)");
14187
14214
  if (operator === "in" || operator === "not in") {
14188
14215
  const values = Array.isArray(val) ? val : [val];
14189
14216
  const placeholders = getPlaceholders(values.length, whereParams.length + 1);
@@ -14281,6 +14308,10 @@ function createQueryBuilder(state) {
14281
14308
  return this;
14282
14309
  },
14283
14310
  join(table2, onLeft, operator, onRight) {
14311
+ validateIdentifier(table2, "join(table)");
14312
+ validateQualifiedIdentifier(onLeft, "join(onLeft)");
14313
+ validateQualifiedIdentifier(onRight, "join(onRight)");
14314
+ assertSafeWhereOperator(operator, "join(operator)");
14284
14315
  insertJoin(`JOIN ${table2} ON ${onLeft} ${operator} ${onRight}`);
14285
14316
  joinedTables.add(table2);
14286
14317
  return this;
@@ -14295,31 +14326,49 @@ function createQueryBuilder(state) {
14295
14326
  return this;
14296
14327
  },
14297
14328
  innerJoin(table2, onLeft, operator, onRight) {
14329
+ validateIdentifier(table2, "innerJoin(table)");
14330
+ validateQualifiedIdentifier(onLeft, "innerJoin(onLeft)");
14331
+ validateQualifiedIdentifier(onRight, "innerJoin(onRight)");
14332
+ assertSafeWhereOperator(operator, "innerJoin(operator)");
14298
14333
  insertJoin(`INNER JOIN ${table2} ON ${onLeft} ${operator} ${onRight}`);
14299
14334
  joinedTables.add(table2);
14300
14335
  return this;
14301
14336
  },
14302
14337
  leftJoin(table2, onLeft, operator, onRight) {
14338
+ validateIdentifier(table2, "leftJoin(table)");
14339
+ validateQualifiedIdentifier(onLeft, "leftJoin(onLeft)");
14340
+ validateQualifiedIdentifier(onRight, "leftJoin(onRight)");
14341
+ assertSafeWhereOperator(operator, "leftJoin(operator)");
14303
14342
  insertJoin(`LEFT JOIN ${table2} ON ${onLeft} ${operator} ${onRight}`);
14304
14343
  joinedTables.add(table2);
14305
14344
  return this;
14306
14345
  },
14307
14346
  leftJoinSub(sub, alias, onLeft, operator, onRight) {
14347
+ validateIdentifier(alias, "leftJoinSub(alias)");
14348
+ validateQualifiedIdentifier(onLeft, "leftJoinSub(onLeft)");
14349
+ validateQualifiedIdentifier(onRight, "leftJoinSub(onRight)");
14350
+ assertSafeWhereOperator(operator, "leftJoinSub(operator)");
14308
14351
  insertJoin(`LEFT JOIN (${String(sub.toSQL())}) AS ${alias} ON ${onLeft} ${operator} ${onRight}`);
14309
14352
  joinedTables.add(alias);
14310
14353
  return this;
14311
14354
  },
14312
14355
  rightJoin(table2, onLeft, operator, onRight) {
14356
+ validateIdentifier(table2, "rightJoin(table)");
14357
+ validateQualifiedIdentifier(onLeft, "rightJoin(onLeft)");
14358
+ validateQualifiedIdentifier(onRight, "rightJoin(onRight)");
14359
+ assertSafeWhereOperator(operator, "rightJoin(operator)");
14313
14360
  insertJoin(`RIGHT JOIN ${table2} ON ${onLeft} ${operator} ${onRight}`);
14314
14361
  joinedTables.add(table2);
14315
14362
  return this;
14316
14363
  },
14317
14364
  crossJoin(table2) {
14365
+ validateIdentifier(table2, "crossJoin(table)");
14318
14366
  insertJoin(`CROSS JOIN ${table2}`);
14319
14367
  joinedTables.add(table2);
14320
14368
  return this;
14321
14369
  },
14322
14370
  crossJoinSub(sub, alias) {
14371
+ validateIdentifier(alias, "crossJoinSub(alias)");
14323
14372
  insertJoin(`CROSS JOIN (${String(sub.toSQL())}) AS ${alias}`);
14324
14373
  joinedTables.add(alias);
14325
14374
  return this;
@@ -16251,7 +16300,7 @@ var init_cache = __esm(() => {
16251
16300
  });
16252
16301
 
16253
16302
  // src/actions/console.ts
16254
- import process19 from "process";
16303
+ import process21 from "process";
16255
16304
  import { createInterface } from "readline";
16256
16305
  async function startConsole() {
16257
16306
  console.log("-- Query Builder Interactive Console");
@@ -16260,8 +16309,8 @@ async function startConsole() {
16260
16309
  console.log();
16261
16310
  const qb = createQueryBuilder();
16262
16311
  const rl = createInterface({
16263
- input: process19.stdin,
16264
- output: process19.stdout,
16312
+ input: process21.stdin,
16313
+ output: process21.stdout,
16265
16314
  prompt: "qb> "
16266
16315
  });
16267
16316
  let multilineBuffer = "";
@@ -16312,7 +16361,7 @@ Tips:
16312
16361
  if (cmd === ".exit" || cmd === ".quit") {
16313
16362
  console.log("Goodbye!");
16314
16363
  rl.close();
16315
- process19.exit(0);
16364
+ process21.exit(0);
16316
16365
  } else if (cmd === ".help") {
16317
16366
  console.log(helpText);
16318
16367
  } else if (cmd === ".clear") {
@@ -16383,7 +16432,7 @@ Tips:
16383
16432
  rl.on("close", () => {
16384
16433
  console.log(`
16385
16434
  Goodbye!`);
16386
- process19.exit(0);
16435
+ process21.exit(0);
16387
16436
  });
16388
16437
  rl.prompt();
16389
16438
  }
@@ -16761,9 +16810,9 @@ var init_db_info = __esm(() => {
16761
16810
  });
16762
16811
 
16763
16812
  // src/actions/db-optimize.ts
16764
- import process21 from "process";
16813
+ import process22 from "process";
16765
16814
  async function dbOptimize(options = {}) {
16766
- const dialect = options.dialect || process21.env.DB_DIALECT || "postgres";
16815
+ const dialect = options.dialect || process22.env.DB_DIALECT || "postgres";
16767
16816
  const aggressive = options.aggressive || false;
16768
16817
  if (options.verbose) {
16769
16818
  console.log(`Optimizing ${dialect} database${aggressive ? " (aggressive mode)" : ""}...`);
@@ -16803,7 +16852,7 @@ async function dbOptimize(options = {}) {
16803
16852
  await bunSql`ANALYZE TABLE ${bunSql(table)}`;
16804
16853
  }
16805
16854
  } else {
16806
- const dbName = process21.env.DB_NAME || "test";
16855
+ const dbName = process22.env.DB_NAME || "test";
16807
16856
  const tables = await bunSql`
16808
16857
  SELECT table_name
16809
16858
  FROM information_schema.tables
@@ -16855,9 +16904,9 @@ var init_db_optimize = __esm(() => {
16855
16904
  });
16856
16905
 
16857
16906
  // src/actions/db-wipe.ts
16858
- import process22 from "process";
16907
+ import process23 from "process";
16859
16908
  async function dbWipe(options = {}) {
16860
- const dialect = options.dialect || process22.env.DB_DIALECT || "postgres";
16909
+ const dialect = options.dialect || process23.env.DB_DIALECT || "postgres";
16861
16910
  if (options.verbose) {
16862
16911
  console.log(`Wiping all tables from ${dialect} database...`);
16863
16912
  }
@@ -16871,7 +16920,7 @@ async function dbWipe(options = {}) {
16871
16920
  `;
16872
16921
  tables = result.map((row) => row.tablename);
16873
16922
  } else if (dialect === "mysql") {
16874
- const dbName = process22.env.DB_NAME || "test";
16923
+ const dbName = process23.env.DB_NAME || "test";
16875
16924
  const result = await bunSql`
16876
16925
  SELECT table_name
16877
16926
  FROM information_schema.tables
@@ -17287,7 +17336,7 @@ var init_introspect_db = __esm(() => {
17287
17336
  // src/actions/make-model.ts
17288
17337
  import { existsSync as existsSync14, mkdirSync as mkdirSync5, writeFileSync as writeFileSync10 } from "fs";
17289
17338
  import { dirname as dirname5, join as join7 } from "path";
17290
- import process23 from "process";
17339
+ import process24 from "process";
17291
17340
  function findWorkspaceRoot(startPath) {
17292
17341
  let currentPath = startPath;
17293
17342
  while (currentPath !== dirname5(currentPath)) {
@@ -17296,10 +17345,10 @@ function findWorkspaceRoot(startPath) {
17296
17345
  }
17297
17346
  currentPath = dirname5(currentPath);
17298
17347
  }
17299
- return process23.cwd();
17348
+ return process24.cwd();
17300
17349
  }
17301
17350
  async function makeModel(name, options = {}) {
17302
- const workspaceRoot = findWorkspaceRoot(process23.cwd());
17351
+ const workspaceRoot = findWorkspaceRoot(process24.cwd());
17303
17352
  const modelsDir = options.dir || join7(workspaceRoot, "app/Models");
17304
17353
  if (!existsSync14(modelsDir)) {
17305
17354
  mkdirSync5(modelsDir, { recursive: true });
@@ -17856,7 +17905,7 @@ __export(exports_migrate, {
17856
17905
  import { existsSync as existsSync16, mkdirSync as mkdirSync7, mkdtempSync, readdirSync as readdirSync6, readFileSync as readFileSync3, rmSync, unlinkSync, writeFileSync as writeFileSync11 } from "fs";
17857
17906
  import { tmpdir } from "os";
17858
17907
  import { join as join9 } from "path";
17859
- import process24 from "process";
17908
+ import process25 from "process";
17860
17909
  function info(message) {
17861
17910
  if (config5.verbose)
17862
17911
  console.log(message);
@@ -17903,7 +17952,7 @@ function savePlanSnapshot(workspaceRoot, dialect, plan) {
17903
17952
  info(`-- Model snapshot saved to ${snapshotPath}`);
17904
17953
  }
17905
17954
  function getWorkspaceRoot() {
17906
- return process24.cwd();
17955
+ return process25.cwd();
17907
17956
  }
17908
17957
  function ensureSqlDirectory(workspaceRoot) {
17909
17958
  const sqlDir = getSqlDirectory(workspaceRoot);
@@ -17915,7 +17964,7 @@ function ensureSqlDirectory(workspaceRoot) {
17915
17964
  }
17916
17965
  async function generateMigration(dir, opts = {}) {
17917
17966
  if (!dir) {
17918
- dir = join9(process24.cwd(), "app/Models");
17967
+ dir = join9(process25.cwd(), "app/Models");
17919
17968
  }
17920
17969
  const dialect = opts.dialect || config5.dialect || "postgres";
17921
17970
  const workspaceRoot = getWorkspaceRoot();
@@ -17970,7 +18019,7 @@ async function generateMigration(dir, opts = {}) {
17970
18019
  }
17971
18020
  async function executeMigration(dir) {
17972
18021
  if (!dir) {
17973
- dir = join9(process24.cwd(), "app/Models");
18022
+ dir = join9(process25.cwd(), "app/Models");
17974
18023
  }
17975
18024
  const workspaceRoot = getWorkspaceRoot();
17976
18025
  const sqlDir = ensureSqlDirectory(workspaceRoot);
@@ -18035,7 +18084,7 @@ async function executeMigration(dir) {
18035
18084
  }
18036
18085
  async function resetDatabase(dir, opts = {}) {
18037
18086
  if (!dir) {
18038
- dir = join9(process24.cwd(), "app/Models");
18087
+ dir = join9(process25.cwd(), "app/Models");
18039
18088
  }
18040
18089
  const dialect = opts.dialect || "postgres";
18041
18090
  const driver = getDialectDriver(dialect);
@@ -18128,7 +18177,7 @@ async function resetDatabase(dir, opts = {}) {
18128
18177
  }
18129
18178
  async function deleteMigrationFiles(dir, workspaceRoot, opts = {}) {
18130
18179
  if (!dir) {
18131
- dir = join9(process24.cwd(), "app/Models");
18180
+ dir = join9(process25.cwd(), "app/Models");
18132
18181
  }
18133
18182
  if (!workspaceRoot) {
18134
18183
  workspaceRoot = getWorkspaceRoot();
@@ -18228,7 +18277,7 @@ var init_migrate_generate = __esm(() => {
18228
18277
  // src/actions/migrate-rollback.ts
18229
18278
  import { existsSync as existsSync17, readFileSync as readFileSync4, unlinkSync as unlinkSync2 } from "fs";
18230
18279
  import { dirname as dirname7, join as join10 } from "path";
18231
- import process25 from "process";
18280
+ import process26 from "process";
18232
18281
  function splitSqlStatements2(sql) {
18233
18282
  const out = [];
18234
18283
  let buf = "";
@@ -18279,11 +18328,11 @@ function findWorkspaceRoot2(startPath) {
18279
18328
  }
18280
18329
  currentPath = dirname7(currentPath);
18281
18330
  }
18282
- return process25.cwd();
18331
+ return process26.cwd();
18283
18332
  }
18284
18333
  function getSqlDirectory2(workspaceRoot) {
18285
18334
  if (!workspaceRoot) {
18286
- workspaceRoot = findWorkspaceRoot2(process25.cwd());
18335
+ workspaceRoot = findWorkspaceRoot2(process26.cwd());
18287
18336
  }
18288
18337
  return join10(workspaceRoot, "database", "migrations");
18289
18338
  }
@@ -18366,7 +18415,7 @@ var init_migrate_rollback = __esm(() => {
18366
18415
  // src/actions/migrate-status.ts
18367
18416
  import { existsSync as existsSync18, readdirSync as readdirSync8 } from "fs";
18368
18417
  import { dirname as dirname8, join as join11 } from "path";
18369
- import process26 from "process";
18418
+ import process27 from "process";
18370
18419
  function findWorkspaceRoot3(startPath) {
18371
18420
  let currentPath = startPath;
18372
18421
  while (currentPath !== dirname8(currentPath)) {
@@ -18375,11 +18424,11 @@ function findWorkspaceRoot3(startPath) {
18375
18424
  }
18376
18425
  currentPath = dirname8(currentPath);
18377
18426
  }
18378
- return process26.cwd();
18427
+ return process27.cwd();
18379
18428
  }
18380
18429
  function getSqlDirectory3(workspaceRoot) {
18381
18430
  if (!workspaceRoot) {
18382
- workspaceRoot = findWorkspaceRoot3(process26.cwd());
18431
+ workspaceRoot = findWorkspaceRoot3(process27.cwd());
18383
18432
  }
18384
18433
  return join11(workspaceRoot, "database", "migrations");
18385
18434
  }
@@ -18473,9 +18522,9 @@ var init_migrate_status = __esm(() => {
18473
18522
  // src/actions/model-show.ts
18474
18523
  import { readdirSync as readdirSync9 } from "fs";
18475
18524
  import { extname as extname2, join as join12 } from "path";
18476
- import process27 from "process";
18525
+ import process28 from "process";
18477
18526
  async function modelShow(modelName, options = {}) {
18478
- const dir = options.dir || join12(process27.cwd(), "app/Models");
18527
+ const dir = options.dir || join12(process28.cwd(), "app/Models");
18479
18528
  try {
18480
18529
  const files = readdirSync9(dir);
18481
18530
  const modelFile = files.find((f) => {
@@ -18689,9 +18738,9 @@ var init_query_explain_all = __esm(() => {
18689
18738
  // src/actions/relation-diagram.ts
18690
18739
  import { writeFileSync as writeFileSync12 } from "fs";
18691
18740
  import { join as join14 } from "path";
18692
- import process28 from "process";
18741
+ import process29 from "process";
18693
18742
  async function relationDiagram(options = {}) {
18694
- const dir = options.dir || join14(process28.cwd(), "app/Models");
18743
+ const dir = options.dir || join14(process29.cwd(), "app/Models");
18695
18744
  const format = options.format || "mermaid";
18696
18745
  try {
18697
18746
  const models = await loadModels({ modelsDir: dir });
@@ -18813,7 +18862,7 @@ var init_relation_diagram = __esm(() => {
18813
18862
  // src/actions/seed.ts
18814
18863
  import { existsSync as existsSync19, mkdirSync as mkdirSync8, readdirSync as readdirSync11, writeFileSync as writeFileSync13 } from "fs";
18815
18864
  import { dirname as dirname9, join as join15 } from "path";
18816
- import process29 from "process";
18865
+ import process30 from "process";
18817
18866
  function findWorkspaceRoot4(startPath) {
18818
18867
  let currentPath = startPath;
18819
18868
  while (currentPath !== dirname9(currentPath)) {
@@ -18822,7 +18871,7 @@ function findWorkspaceRoot4(startPath) {
18822
18871
  }
18823
18872
  currentPath = dirname9(currentPath);
18824
18873
  }
18825
- return process29.cwd();
18874
+ return process30.cwd();
18826
18875
  }
18827
18876
  async function loadSeeders(seedersDir) {
18828
18877
  if (!existsSync19(seedersDir)) {
@@ -18854,7 +18903,7 @@ async function loadSeeders(seedersDir) {
18854
18903
  return seeders;
18855
18904
  }
18856
18905
  async function runSeeders(config6 = {}) {
18857
- const workspaceRoot = findWorkspaceRoot4(process29.cwd());
18906
+ const workspaceRoot = findWorkspaceRoot4(process30.cwd());
18858
18907
  const seedersDir = config6.seedersDir || join15(workspaceRoot, "database/seeders");
18859
18908
  const verbose = config6.verbose ?? true;
18860
18909
  if (verbose) {
@@ -18889,7 +18938,7 @@ async function runSeeders(config6 = {}) {
18889
18938
  }
18890
18939
  }
18891
18940
  async function runSeeder(className, options = {}) {
18892
- const workspaceRoot = findWorkspaceRoot4(process29.cwd());
18941
+ const workspaceRoot = findWorkspaceRoot4(process30.cwd());
18893
18942
  const seedersDir = join15(workspaceRoot, "database/seeders");
18894
18943
  const verbose = options.verbose ?? true;
18895
18944
  if (verbose) {
@@ -18913,7 +18962,7 @@ async function runSeeder(className, options = {}) {
18913
18962
  }
18914
18963
  }
18915
18964
  async function makeSeeder(name) {
18916
- const workspaceRoot = findWorkspaceRoot4(process29.cwd());
18965
+ const workspaceRoot = findWorkspaceRoot4(process30.cwd());
18917
18966
  const seedersDir = join15(workspaceRoot, "database/seeders");
18918
18967
  if (!existsSync19(seedersDir)) {
18919
18968
  mkdirSync8(seedersDir, { recursive: true });
@@ -18977,7 +19026,7 @@ export default class ${className} extends Seeder {
18977
19026
  console.log(`-- \u2713 Created seeder: ${filePath}`);
18978
19027
  }
18979
19028
  async function freshDatabase(options = {}) {
18980
- const workspaceRoot = findWorkspaceRoot4(process29.cwd());
19029
+ const workspaceRoot = findWorkspaceRoot4(process30.cwd());
18981
19030
  const modelsDir = options.modelsDir || join15(workspaceRoot, "app/Models");
18982
19031
  const seedersDir = options.seedersDir || join15(workspaceRoot, "database/seeders");
18983
19032
  const verbose = options.verbose ?? true;
@@ -19039,7 +19088,7 @@ var init_unsafe = __esm(() => {
19039
19088
  // src/actions/validate.ts
19040
19089
  import { existsSync as existsSync20 } from "fs";
19041
19090
  import { dirname as dirname10, join as join16 } from "path";
19042
- import process30 from "process";
19091
+ import process31 from "process";
19043
19092
  function findWorkspaceRoot5(startPath) {
19044
19093
  let currentPath = startPath;
19045
19094
  while (currentPath !== dirname10(currentPath)) {
@@ -19048,11 +19097,11 @@ function findWorkspaceRoot5(startPath) {
19048
19097
  }
19049
19098
  currentPath = dirname10(currentPath);
19050
19099
  }
19051
- return process30.cwd();
19100
+ return process31.cwd();
19052
19101
  }
19053
19102
  async function validateSchema(dir) {
19054
19103
  if (!dir) {
19055
- dir = join16(findWorkspaceRoot5(process30.cwd()), "app/Models");
19104
+ dir = join16(findWorkspaceRoot5(process31.cwd()), "app/Models");
19056
19105
  }
19057
19106
  const dialect = config5.dialect || "postgres";
19058
19107
  console.log("-- Validating Schema");
@@ -24885,6 +24934,8 @@ class ModelQueryBuilder {
24885
24934
  let rel = relationCache.get(cacheKey);
24886
24935
  if (rel === undefined) {
24887
24936
  rel = resolveRelation(this._definition, relationName);
24937
+ if (relationCache.size >= RELATION_CACHE_MAX)
24938
+ relationCache.clear();
24888
24939
  relationCache.set(cacheKey, rel);
24889
24940
  }
24890
24941
  if (!rel)
@@ -24921,8 +24972,13 @@ class ModelQueryBuilder {
24921
24972
  }
24922
24973
  }
24923
24974
  if (rel.type === "belongsTo") {
24924
- const fkValues = instances.map((i2) => i2._attributes[rel.foreignKey]).filter((v2) => v2 != null);
24925
- const uniqueFkValues = [...new Set(fkValues)];
24975
+ const fkSet = new Set;
24976
+ for (const i2 of instances) {
24977
+ const v2 = i2._attributes[rel.foreignKey];
24978
+ if (v2 != null)
24979
+ fkSet.add(v2);
24980
+ }
24981
+ const uniqueFkValues = [...fkSet];
24926
24982
  if (uniqueFkValues.length === 0)
24927
24983
  continue;
24928
24984
  const placeholders = uniqueFkValues.map(() => "?").join(", ");
@@ -24952,7 +25008,13 @@ class ModelQueryBuilder {
24952
25008
  instance.setRelation(relationName, []);
24953
25009
  continue;
24954
25010
  }
24955
- const relatedIds = [...new Set(pivotRows.map((p2) => p2[rel.pivotFkRelated]))].filter((v2) => v2 != null);
25011
+ const relatedIdSet = new Set;
25012
+ for (const p2 of pivotRows) {
25013
+ const v2 = p2[rel.pivotFkRelated];
25014
+ if (v2 != null)
25015
+ relatedIdSet.add(v2);
25016
+ }
25017
+ const relatedIds = [...relatedIdSet];
24956
25018
  const relatedModelDef = getModelFromRegistry(rel.relatedModelName);
24957
25019
  const relDef = relatedModelDef?.getDefinition?.() || relatedModelDef?.definition || this._definition;
24958
25020
  const relatedPk = relDef?.primaryKey || "id";
@@ -25402,7 +25464,7 @@ async function seedModel(definition, count, faker) {
25402
25464
  await exec.run(`INSERT INTO ${definition.table} (${columns.join(", ")}) VALUES (${columns.map(() => "?").join(", ")})`, Object.values(data));
25403
25465
  }
25404
25466
  }
25405
- var SAFE_SQL_IDENTIFIER, _getModel = null, globalDb = null, _executor = null, _executorForDb = null, _executorDialect = null, _executorDatabase = null, SOFT_DELETE_COLUMN = "deleted_at", BTM_RELATED_ALIAS = "__btm_rel__", snakeCaseCache, tableNameCache, relationCache;
25467
+ var SAFE_SQL_IDENTIFIER, _getModel = null, globalDb = null, _executor = null, _executorForDb = null, _executorDialect = null, _executorDatabase = null, SOFT_DELETE_COLUMN = "deleted_at", BTM_RELATED_ALIAS = "__btm_rel__", snakeCaseCache, tableNameCache, relationCache, RELATION_CACHE_MAX = 1000;
25406
25468
  var init_orm = __esm(() => {
25407
25469
  init_config();
25408
25470
  init_db();
@@ -26858,9 +26920,9 @@ function buildDatabaseSchema(models) {
26858
26920
  // src/loader.ts
26859
26921
  import { readdirSync as readdirSync12, statSync as statSync5 } from "fs";
26860
26922
  import { basename, extname as extname4 } from "path";
26861
- import process31 from "process";
26923
+ import process33 from "process";
26862
26924
  async function loadModels(options) {
26863
- const cwd = options.cwd ?? process31.cwd();
26925
+ const cwd = options.cwd ?? process33.cwd();
26864
26926
  const dir = options.modelsDir.startsWith("/") ? options.modelsDir : `${cwd}/${options.modelsDir}`;
26865
26927
  const result = {};
26866
26928
  const entries = readdirSync12(dir);
@@ -26990,7 +27052,7 @@ var init_meta = () => {};
26990
27052
  // src/migrations.ts
26991
27053
  import { existsSync as existsSync21, mkdirSync as mkdirSync9, writeFileSync as writeFileSync14 } from "fs";
26992
27054
  import { dirname as dirname11, join as join17 } from "path";
26993
- import process33 from "process";
27055
+ import process35 from "process";
26994
27056
  function info2(message) {
26995
27057
  if (config5.verbose)
26996
27058
  console.log(message);
@@ -27006,10 +27068,10 @@ function findWorkspaceRoot6(startPath) {
27006
27068
  }
27007
27069
  currentPath = dirname11(currentPath);
27008
27070
  }
27009
- return process33.cwd();
27071
+ return process35.cwd();
27010
27072
  }
27011
27073
  function ensureSqlDirectory2() {
27012
- const workspaceRoot = findWorkspaceRoot6(process33.cwd());
27074
+ const workspaceRoot = findWorkspaceRoot6(process35.cwd());
27013
27075
  const sqlDir = join17(workspaceRoot, "database", "migrations");
27014
27076
  if (!existsSync21(sqlDir)) {
27015
27077
  mkdirSync9(sqlDir, { recursive: true });