@bungres/kit 0.3.0 → 0.5.0

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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  // src/config.ts
3
- import { resolve, join } from "path";
3
+ import { join, resolve } from "path";
4
4
  var CONFIG_FILES = [
5
5
  "bungres.config.ts",
6
6
  "bungres.config.js",
@@ -17,7 +17,7 @@ async function loadConfig(cwd = process.cwd()) {
17
17
  break;
18
18
  }
19
19
  }
20
- const dbUrl = userConfig.dbCredentials?.url ?? process.env["DATABASE_URL"] ?? process.env["POSTGRES_URL"] ?? "";
20
+ const dbUrl = userConfig.dbCredentials?.url ?? Bun.env.DATABASE_URL ?? Bun.env.POSTGRES_URL ?? "";
21
21
  if (!dbUrl) {
22
22
  console.error(`bungres: No database URL found.
23
23
  Add dbCredentials.url to bungres.config.ts or set DATABASE_URL.`);
@@ -30,7 +30,10 @@ async function loadConfig(cwd = process.cwd()) {
30
30
  out,
31
31
  dbUrl,
32
32
  dbSchema: userConfig.dbSchema ?? "public",
33
- migrationsDir: out,
33
+ migrationsTable: userConfig.migrations?.table ?? "__bungres_migrations",
34
+ migrationsSchema: userConfig.migrations?.schema ?? "bungres",
35
+ breakpoints: userConfig.breakpoints ?? true,
36
+ strict: userConfig.strict ?? false,
34
37
  outDir: "./src/db/generated",
35
38
  verbose: userConfig.verbose ?? false
36
39
  };
@@ -38,7 +41,7 @@ async function loadConfig(cwd = process.cwd()) {
38
41
  // src/schema-loader.ts
39
42
  import { resolve as resolve2, join as join2 } from "path";
40
43
 
41
- // ../../node_modules/.bun/@bungres+orm@0.2.0/node_modules/@bungres/orm/src/table.ts
44
+ // ../bungres-orm/src/schema/table.ts
42
45
  var TableConfigSymbol = Symbol.for("BungresTableConfig");
43
46
  function getTableConfig(table) {
44
47
  return table[TableConfigSymbol];
@@ -48,8 +51,13 @@ function camelToSnakeCase(str) {
48
51
  }
49
52
  function createTableFactory(casing) {
50
53
  return function(name, columns, extra) {
54
+ let schema;
55
+ if (extra && typeof extra !== "function") {
56
+ schema = extra.schema;
57
+ }
58
+ const qualifiedName = schema ? `"${schema}"."${name}"` : `"${name}"`;
51
59
  const columnConfigs = Object.fromEntries(Object.entries(columns).map(([key, config]) => {
52
- const c = { ...config };
60
+ const c = { ...config, tableName: qualifiedName };
53
61
  if (!c.name) {
54
62
  if (casing === "snake") {
55
63
  c.name = camelToSnakeCase(key);
@@ -59,26 +67,50 @@ function createTableFactory(casing) {
59
67
  }
60
68
  return [key, c];
61
69
  }));
62
- const schema = extra?.schema;
63
- const qualifiedName = schema ? `"${schema}"."${name}"` : `"${name}"`;
70
+ const indexes = [];
71
+ const checks = [];
72
+ const primaryKeys = [];
73
+ const foreignKeys = [];
74
+ if (extra) {
75
+ if (typeof extra === "function") {
76
+ const builders = extra(columnConfigs);
77
+ for (const builder of builders) {
78
+ const config = builder.build();
79
+ if (config.type === "index")
80
+ indexes.push(config);
81
+ else if (config.type === "check")
82
+ checks.push(config.condition);
83
+ else if (config.type === "primaryKey")
84
+ primaryKeys.push(...config.columns);
85
+ else if (config.type === "foreignKey")
86
+ foreignKeys.push(config);
87
+ }
88
+ } else {
89
+ if (extra.indexes)
90
+ indexes.push(...extra.indexes);
91
+ if (extra.checks)
92
+ checks.push(...extra.checks);
93
+ }
94
+ }
64
95
  const tableObj = {
65
96
  [TableConfigSymbol]: {
66
97
  name,
67
98
  schema,
68
99
  columns: columnConfigs,
69
- indexes: extra?.indexes ?? [],
70
- checks: extra?.checks ?? [],
71
- primaryKeys: extra?.primaryKeys ?? [],
100
+ indexes,
101
+ checks,
102
+ primaryKeys,
103
+ foreignKeys,
72
104
  qualifiedName
73
105
  }
74
106
  };
75
107
  return Object.assign(tableObj, columnConfigs);
76
108
  };
77
109
  }
78
- var table = createTableFactory("none");
110
+ var table = createTableFactory("snake");
79
111
  var snakeCase = { table: createTableFactory("snake") };
80
112
  var camelCase = { table: createTableFactory("camel") };
81
- // ../../node_modules/.bun/@bungres+orm@0.2.0/node_modules/@bungres/orm/src/column.ts
113
+ // ../bungres-orm/src/schema/columns.ts
82
114
  function buildColumn(dataType, nameOrOpts, opts) {
83
115
  let name = "";
84
116
  let options = opts;
@@ -132,7 +164,33 @@ var interval = col("interval");
132
164
  var inet = col("inet");
133
165
  var cidr = col("cidr");
134
166
  var macaddr = col("macaddr");
135
- // ../../node_modules/.bun/@bungres+orm@0.2.0/node_modules/@bungres/orm/src/sql.ts
167
+ var textArray = col("text[]");
168
+ var integerArray = col("integer[]");
169
+ var varcharArray = col("varchar[]");
170
+ var uuidArray = col("uuid[]");
171
+ // ../bungres-orm/src/core/sql.ts
172
+ function sql(strings, ...values) {
173
+ let query = "";
174
+ const params = [];
175
+ for (let i = 0;i < strings.length; i++) {
176
+ query += strings[i];
177
+ if (i < values.length) {
178
+ const val = values[i];
179
+ if (isSQLChunk(val)) {
180
+ const offset = params.length;
181
+ query += val.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
182
+ params.push(...val.params);
183
+ } else {
184
+ params.push(val);
185
+ query += `$${params.length}`;
186
+ }
187
+ }
188
+ }
189
+ return { sql: query, params };
190
+ }
191
+ function isSQLChunk(value) {
192
+ return typeof value === "object" && value !== null && "sql" in value && "params" in value && typeof value.sql === "string" && Array.isArray(value.params);
193
+ }
136
194
  function sqlJoin(chunks, separator = ", ") {
137
195
  const params = [];
138
196
  const parts = [];
@@ -143,12 +201,326 @@ function sqlJoin(chunks, separator = ", ") {
143
201
  }
144
202
  return { sql: parts.join(separator), params };
145
203
  }
146
- // ../../node_modules/.bun/@bungres+orm@0.2.0/node_modules/@bungres/orm/src/query.ts
204
+ function rawSql(query) {
205
+ return { sql: query, params: [] };
206
+ }
207
+ // ../bungres-orm/src/core/conditions.ts
208
+ var colName = (c) => {
209
+ if (typeof c === "string")
210
+ return `"${c}"`;
211
+ if (isSQLChunk(c))
212
+ return c.sql;
213
+ return c.tableName ? `${c.tableName}."${c.name}"` : `"${c.name}"`;
214
+ };
215
+ function isColumnConfig(val) {
216
+ return val !== null && typeof val === "object" && "name" in val && "dataType" in val;
217
+ }
218
+ var eq = (column, value) => {
219
+ if (isColumnConfig(value))
220
+ return sql`${rawSql(colName(column))} = ${rawSql(colName(value))}`;
221
+ if (isSQLChunk(value))
222
+ return sql`${rawSql(colName(column))} = ${value}`;
223
+ return sql`${rawSql(colName(column))} = ${value}`;
224
+ };
225
+ var ne = (column, value) => {
226
+ if (isColumnConfig(value))
227
+ return sql`${rawSql(colName(column))} != ${rawSql(colName(value))}`;
228
+ if (isSQLChunk(value))
229
+ return sql`${rawSql(colName(column))} != ${value}`;
230
+ return sql`${rawSql(colName(column))} != ${value}`;
231
+ };
232
+ var gt = (column, value) => {
233
+ if (isColumnConfig(value))
234
+ return sql`${rawSql(colName(column))} > ${rawSql(colName(value))}`;
235
+ if (isSQLChunk(value))
236
+ return sql`${rawSql(colName(column))} > ${value}`;
237
+ return sql`${rawSql(colName(column))} > ${value}`;
238
+ };
239
+ var gte = (column, value) => {
240
+ if (isColumnConfig(value))
241
+ return sql`${rawSql(colName(column))} >= ${rawSql(colName(value))}`;
242
+ if (isSQLChunk(value))
243
+ return sql`${rawSql(colName(column))} >= ${value}`;
244
+ return sql`${rawSql(colName(column))} >= ${value}`;
245
+ };
246
+ var lt = (column, value) => {
247
+ if (isColumnConfig(value))
248
+ return sql`${rawSql(colName(column))} < ${rawSql(colName(value))}`;
249
+ if (isSQLChunk(value))
250
+ return sql`${rawSql(colName(column))} < ${value}`;
251
+ return sql`${rawSql(colName(column))} < ${value}`;
252
+ };
253
+ var lte = (column, value) => {
254
+ if (isColumnConfig(value))
255
+ return sql`${rawSql(colName(column))} <= ${rawSql(colName(value))}`;
256
+ if (isSQLChunk(value))
257
+ return sql`${rawSql(colName(column))} <= ${value}`;
258
+ return sql`${rawSql(colName(column))} <= ${value}`;
259
+ };
260
+ var like = (column, pattern) => sql`${rawSql(colName(column))} LIKE ${pattern}`;
261
+ var ilike = (column, pattern) => sql`${rawSql(colName(column))} ILIKE ${pattern}`;
262
+ var isNull = (column) => rawSql(`${colName(column)} IS NULL`);
263
+ var isNotNull = (column) => rawSql(`${colName(column)} IS NOT NULL`);
264
+ var inArray = (column, values) => {
265
+ if (values.length === 0)
266
+ return rawSql("FALSE");
267
+ const params = values;
268
+ const placeholders = params.map((_, i) => `$${i + 1}`).join(", ");
269
+ return { sql: `${colName(column)} = ANY(ARRAY[${placeholders}])`, params };
270
+ };
271
+ var and = (...conditions) => sqlJoin(conditions, " AND ");
272
+ var or = (...conditions) => {
273
+ const joined = sqlJoin(conditions, " OR ");
274
+ return { sql: `(${joined.sql})`, params: joined.params };
275
+ };
276
+ var not = (condition) => ({
277
+ sql: `NOT (${condition.sql})`,
278
+ params: condition.params
279
+ });
280
+ var asc = (column) => sql`${rawSql(colName(column))} ASC`;
281
+ var desc = (column) => sql`${rawSql(colName(column))} DESC`;
282
+ function parseWhereObject(tableConfig, whereObj) {
283
+ const conditions = [];
284
+ for (const [key, val] of Object.entries(whereObj)) {
285
+ if (val === undefined)
286
+ continue;
287
+ if (key === "OR") {
288
+ const orConditions = val.map((o) => parseWhereObject(tableConfig, o));
289
+ if (orConditions.length > 0)
290
+ conditions.push(or(...orConditions));
291
+ continue;
292
+ }
293
+ if (key === "AND") {
294
+ const andConditions = val.map((o) => parseWhereObject(tableConfig, o));
295
+ if (andConditions.length > 0)
296
+ conditions.push(and(...andConditions));
297
+ continue;
298
+ }
299
+ if (key === "NOT") {
300
+ conditions.push(not(parseWhereObject(tableConfig, val)));
301
+ continue;
302
+ }
303
+ const colConfig = tableConfig.columns[key];
304
+ const columnArg = colConfig ?? key;
305
+ if (val !== null && typeof val === "object" && !Array.isArray(val) && !(val instanceof Date) && !(val instanceof Uint8Array)) {
306
+ const opVal = val;
307
+ if (opVal.eq !== undefined)
308
+ conditions.push(eq(columnArg, opVal.eq));
309
+ if (opVal.ne !== undefined)
310
+ conditions.push(ne(columnArg, opVal.ne));
311
+ if (opVal.gt !== undefined)
312
+ conditions.push(gt(columnArg, opVal.gt));
313
+ if (opVal.gte !== undefined)
314
+ conditions.push(gte(columnArg, opVal.gte));
315
+ if (opVal.lt !== undefined)
316
+ conditions.push(lt(columnArg, opVal.lt));
317
+ if (opVal.lte !== undefined)
318
+ conditions.push(lte(columnArg, opVal.lte));
319
+ if (opVal.in !== undefined)
320
+ conditions.push(inArray(columnArg, opVal.in));
321
+ if (opVal.like !== undefined)
322
+ conditions.push(like(columnArg, opVal.like));
323
+ if (opVal.ilike !== undefined)
324
+ conditions.push(ilike(columnArg, opVal.ilike));
325
+ if (opVal.isNull)
326
+ conditions.push(isNull(columnArg));
327
+ if (opVal.isNotNull)
328
+ conditions.push(isNotNull(columnArg));
329
+ } else {
330
+ if (val === null) {
331
+ conditions.push(isNull(columnArg));
332
+ } else {
333
+ conditions.push(eq(columnArg, val));
334
+ }
335
+ }
336
+ }
337
+ if (conditions.length === 0) {
338
+ return rawSql("TRUE");
339
+ }
340
+ return and(...conditions);
341
+ }
342
+ function parseOrderByObject(tableConfig, orderByObj) {
343
+ const parts = [];
344
+ for (const [key, dir] of Object.entries(orderByObj)) {
345
+ if (dir === undefined)
346
+ continue;
347
+ const colConfig = tableConfig.columns[key];
348
+ const columnArg = colConfig ?? key;
349
+ if (dir === "asc")
350
+ parts.push(asc(columnArg));
351
+ else if (dir === "desc")
352
+ parts.push(desc(columnArg));
353
+ }
354
+ return parts;
355
+ }
356
+
357
+ // ../bungres-orm/src/builders/delete.ts
358
+ class DeleteBuilder {
359
+ _table;
360
+ _executor;
361
+ _where = [];
362
+ _returning;
363
+ _comment;
364
+ constructor(table2, executor) {
365
+ this._table = table2;
366
+ this._executor = executor;
367
+ }
368
+ then(onfulfilled, onrejected) {
369
+ return this._executor.execute(this).then(onfulfilled, onrejected);
370
+ }
371
+ async single() {
372
+ return this._executor.executeSingle(this);
373
+ }
374
+ where(condition) {
375
+ if (condition && typeof condition === "object" && !("sql" in condition)) {
376
+ this._where.push(parseWhereObject(getTableConfig(this._table), condition));
377
+ } else {
378
+ this._where.push(condition);
379
+ }
380
+ return this;
381
+ }
382
+ returning(...columns) {
383
+ this._returning = columns.length > 0 ? columns : ["*"];
384
+ return this;
385
+ }
386
+ comment(tag) {
387
+ this._comment = tag;
388
+ return this;
389
+ }
390
+ toSQL() {
391
+ let query = `DELETE FROM ${getTableConfig(this._table).qualifiedName}`;
392
+ const params = [];
393
+ if (this._where.length > 0) {
394
+ const combined = sqlJoin(this._where, " AND ");
395
+ query += " WHERE " + combined.sql;
396
+ params.push(...combined.params);
397
+ }
398
+ if (this._returning) {
399
+ query += " RETURNING " + (this._returning[0] === "*" ? Object.keys(getTableConfig(this._table).columns).map((c) => `"${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ") : this._returning.map((c) => `"${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`).join(", "));
400
+ }
401
+ return { sql: query, params };
402
+ }
403
+ }
404
+ // ../bungres-orm/src/builders/insert.ts
405
+ class InsertBuilder {
406
+ _table;
407
+ _executor;
408
+ _values = [];
409
+ _onConflict;
410
+ _returning;
411
+ _comment;
412
+ constructor(table2, executor) {
413
+ this._table = table2;
414
+ this._executor = executor;
415
+ }
416
+ then(onfulfilled, onrejected) {
417
+ return this._executor.execute(this).then(onfulfilled, onrejected);
418
+ }
419
+ async single() {
420
+ return this._executor.executeSingle(this);
421
+ }
422
+ values(data) {
423
+ if (Array.isArray(data)) {
424
+ this._values.push(...data);
425
+ } else {
426
+ this._values.push(data);
427
+ }
428
+ return this;
429
+ }
430
+ onConflictDoNothing() {
431
+ this._onConflict = "do nothing";
432
+ return this;
433
+ }
434
+ onConflict(clause) {
435
+ this._onConflict = clause;
436
+ return this;
437
+ }
438
+ returning(...columns) {
439
+ this._returning = columns.length > 0 ? columns : ["*"];
440
+ return this;
441
+ }
442
+ comment(tag) {
443
+ this._comment = tag;
444
+ return this;
445
+ }
446
+ toSQL() {
447
+ if (this._values.length === 0) {
448
+ throw new Error("InsertBuilder: no values provided");
449
+ }
450
+ const tConfig = getTableConfig(this._table);
451
+ const keySet = new Set;
452
+ for (const v of this._values) {
453
+ for (const k of Object.keys(v)) {
454
+ keySet.add(k);
455
+ }
456
+ }
457
+ const keys = Array.from(keySet);
458
+ if (keys.length === 0) {
459
+ return { sql: `INSERT INTO ${tConfig.qualifiedName} DEFAULT VALUES`, params: [] };
460
+ }
461
+ const columnsStr = keys.map((k) => `"${tConfig.columns[k]?.name ?? k}"`).join(", ");
462
+ const params = [];
463
+ const valuesStrs = this._values.map((v) => {
464
+ const vals = keys.map((k) => {
465
+ const val = v[k];
466
+ if (val && typeof val === "object" && "sql" in val && "params" in val) {
467
+ const chunk = val;
468
+ const offset = params.length;
469
+ params.push(...chunk.params);
470
+ return chunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
471
+ }
472
+ if (val && typeof val === "object" && !(val instanceof Date)) {
473
+ const colType = tConfig.columns[k]?.dataType;
474
+ if (colType === "json" || colType === "jsonb") {
475
+ params.push(val);
476
+ } else if (Array.isArray(val)) {
477
+ const pgArray = "{" + val.map((item) => {
478
+ if (item === null || item === undefined)
479
+ return "NULL";
480
+ if (typeof item === "string")
481
+ return '"' + item.replace(/"/g, "\\\"") + '"';
482
+ return typeof item === "object" ? '"' + JSON.stringify(item).replace(/"/g, "\\\"") + '"' : String(item);
483
+ }).join(",") + "}";
484
+ params.push(pgArray);
485
+ } else {
486
+ params.push(JSON.stringify(val));
487
+ }
488
+ return `$${params.length}`;
489
+ }
490
+ if (val === undefined)
491
+ return "DEFAULT";
492
+ params.push(val);
493
+ return `$${params.length}`;
494
+ });
495
+ return `(${vals.join(", ")})`;
496
+ });
497
+ let query = `INSERT INTO ${tConfig.qualifiedName} (${columnsStr}) VALUES ${valuesStrs.join(", ")}`;
498
+ if (this._onConflict) {
499
+ if (this._onConflict === "do nothing") {
500
+ query += " ON CONFLICT DO NOTHING";
501
+ } else {
502
+ const offset = params.length;
503
+ query += " " + this._onConflict.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
504
+ params.push(...this._onConflict.params);
505
+ }
506
+ }
507
+ if (this._returning) {
508
+ query += " RETURNING " + (this._returning[0] === "*" ? Object.keys(tConfig.columns).map((c) => `"${tConfig.columns[c].name}" AS "${c}"`).join(", ") : this._returning.map((c) => `"${tConfig.columns[c]?.name ?? c}" AS "${c}"`).join(", "));
509
+ }
510
+ if (this._comment) {
511
+ query += ` /* ${this._comment} */`;
512
+ }
513
+ return { sql: query, params };
514
+ }
515
+ }
516
+ // ../bungres-orm/src/builders/select.ts
147
517
  class SelectBuilder {
148
518
  _table;
149
519
  _executor;
150
520
  _where = [];
151
521
  _orderBy = [];
522
+ _groupBy = [];
523
+ _having = [];
152
524
  _limit;
153
525
  _offset;
154
526
  _select;
@@ -175,11 +547,27 @@ class SelectBuilder {
175
547
  return this;
176
548
  }
177
549
  where(condition) {
178
- this._where.push(condition);
550
+ if (condition && typeof condition === "object" && !("sql" in condition)) {
551
+ this._where.push(parseWhereObject(getTableConfig(this._table), condition));
552
+ } else {
553
+ this._where.push(condition);
554
+ }
179
555
  return this;
180
556
  }
181
557
  orderBy(column, dir = "asc") {
182
- this._orderBy.push({ column: typeof column === "string" ? column : column.name, dir });
558
+ this._orderBy.push({ column, dir });
559
+ return this;
560
+ }
561
+ groupBy(...columns) {
562
+ this._groupBy.push(...columns);
563
+ return this;
564
+ }
565
+ having(condition) {
566
+ if (condition && typeof condition === "object" && !("sql" in condition)) {
567
+ this._having.push(parseWhereObject(getTableConfig(this._table), condition));
568
+ } else {
569
+ this._having.push(condition);
570
+ }
183
571
  return this;
184
572
  }
185
573
  limit(n) {
@@ -194,35 +582,118 @@ class SelectBuilder {
194
582
  this._joins.push(rawClause);
195
583
  return this;
196
584
  }
585
+ innerJoin(table2, condition) {
586
+ this._joins.push(sql`INNER JOIN ${rawSql(getTableConfig(table2).qualifiedName)} ON ${condition}`);
587
+ return this;
588
+ }
589
+ leftJoin(table2, condition) {
590
+ this._joins.push(sql`LEFT JOIN ${rawSql(getTableConfig(table2).qualifiedName)} ON ${condition}`);
591
+ return this;
592
+ }
593
+ rightJoin(table2, condition) {
594
+ this._joins.push(sql`RIGHT JOIN ${rawSql(getTableConfig(table2).qualifiedName)} ON ${condition}`);
595
+ return this;
596
+ }
597
+ fullJoin(table2, condition) {
598
+ this._joins.push(sql`FULL JOIN ${rawSql(getTableConfig(table2).qualifiedName)} ON ${condition}`);
599
+ return this;
600
+ }
601
+ _buildSelection(selection, params) {
602
+ const parts = [];
603
+ for (const [alias, col2] of Object.entries(selection)) {
604
+ if (typeof col2 === "object" && col2 !== null) {
605
+ if ("sql" in col2 && "params" in col2) {
606
+ const chunk = col2;
607
+ const offset = params.length;
608
+ params.push(...chunk.params);
609
+ parts.push(`'${alias}', ${chunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`)}`);
610
+ } else if ("name" in col2 && "dataType" in col2) {
611
+ const c = col2;
612
+ parts.push(`'${alias}', ${c.tableName ? c.tableName + "." : ""}"${c.name}"`);
613
+ } else {
614
+ parts.push(`'${alias}', json_build_object(${this._buildSelection(col2, params)})`);
615
+ }
616
+ }
617
+ }
618
+ return parts.join(", ");
619
+ }
197
620
  toSQL() {
198
621
  let cols = "";
622
+ const params = [];
199
623
  if (this._selection) {
200
- cols = Object.entries(this._selection).map(([alias, col2]) => `"${col2.name}" AS "${alias}"`).join(", ");
624
+ cols = Object.entries(this._selection).map(([alias, col2]) => {
625
+ if (typeof col2 === "object" && col2 !== null && "sql" in col2 && "params" in col2) {
626
+ const chunk = col2;
627
+ const offset = params.length;
628
+ params.push(...chunk.params);
629
+ return `${chunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`)} AS "${alias}"`;
630
+ } else if (typeof col2 === "object" && col2 !== null && "name" in col2 && "dataType" in col2) {
631
+ const c = col2;
632
+ return `${c.tableName ? c.tableName + "." : ""}"${c.name}" AS "${alias}"`;
633
+ } else {
634
+ return `json_build_object(${this._buildSelection(col2, params)}) AS "${alias}"`;
635
+ }
636
+ }).join(", ");
201
637
  } else if (this._select && this._select.length > 0) {
638
+ const qName = getTableConfig(this._table).qualifiedName;
202
639
  cols = this._select.map((c) => {
203
640
  if (typeof c === "string") {
204
- return `"${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`;
641
+ return `${qName}."${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`;
205
642
  }
206
- return `"${c.name}" AS "${c.alias || c.name}"`;
643
+ return `${c.tableName ? c.tableName + "." : ""}"${c.name}" AS "${c.alias || c.name}"`;
207
644
  }).join(", ");
208
645
  } else {
209
- cols = Object.keys(getTableConfig(this._table).columns).map((c) => `"${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ");
646
+ const qName = getTableConfig(this._table).qualifiedName;
647
+ cols = Object.keys(getTableConfig(this._table).columns).map((c) => `${qName}."${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ");
210
648
  }
211
649
  let query = `SELECT ${cols} FROM ${getTableConfig(this._table).qualifiedName}`;
212
650
  if (this._joins.length > 0) {
213
- query += " " + this._joins.join(" ");
651
+ const joinChunks = this._joins.map((j) => typeof j === "string" ? rawSql(j) : j);
652
+ const combinedJoins = sqlJoin(joinChunks, " ");
653
+ const offset = params.length;
654
+ query += " " + combinedJoins.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
655
+ params.push(...combinedJoins.params);
214
656
  }
215
- const params = [];
216
657
  if (this._where.length > 0) {
217
658
  const combined = sqlJoin(this._where, " AND ");
218
- const offset = 0;
659
+ const offset = params.length;
219
660
  query += " WHERE " + combined.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
220
661
  params.push(...combined.params);
221
662
  }
663
+ if (this._groupBy.length > 0) {
664
+ const qName = getTableConfig(this._table).qualifiedName;
665
+ query += " GROUP BY " + this._groupBy.map((c) => {
666
+ if (typeof c === "string") {
667
+ const dbCol = getTableConfig(this._table).columns[c]?.name ?? c;
668
+ return `${qName}."${dbCol}"`;
669
+ } else if ("sql" in c && "params" in c) {
670
+ const offset = params.length;
671
+ params.push(...c.params);
672
+ return c.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
673
+ } else {
674
+ return `${c.tableName ? c.tableName + "." : ""}"${c.name}"`;
675
+ }
676
+ }).join(", ");
677
+ }
678
+ if (this._having.length > 0) {
679
+ const combined = sqlJoin(this._having, " AND ");
680
+ const offset = params.length;
681
+ query += " HAVING " + combined.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
682
+ params.push(...combined.params);
683
+ }
222
684
  if (this._orderBy.length > 0) {
685
+ const qName = getTableConfig(this._table).qualifiedName;
223
686
  query += " ORDER BY " + this._orderBy.map((o) => {
224
- const dbCol = getTableConfig(this._table).columns[o.column]?.name ?? o.column;
225
- return `"${dbCol}" ${o.dir.toUpperCase()}`;
687
+ if (typeof o.column === "string") {
688
+ const dbCol = getTableConfig(this._table).columns[o.column]?.name ?? o.column;
689
+ return `${qName}."${dbCol}" ${o.dir.toUpperCase()}`;
690
+ } else if ("sql" in o.column && "params" in o.column) {
691
+ const offset = params.length;
692
+ params.push(...o.column.params);
693
+ return `${o.column.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`)} ${o.dir.toUpperCase()}`;
694
+ } else {
695
+ return `${o.column.tableName ? o.column.tableName + "." : ""}"${o.column.name}" ${o.dir.toUpperCase()}`;
696
+ }
226
697
  }).join(", ");
227
698
  }
228
699
  if (this._limit !== undefined) {
@@ -251,76 +722,7 @@ class SelectBuilderIntermediate {
251
722
  return new SelectBuilder(table2, this._executor, this._selection);
252
723
  }
253
724
  }
254
-
255
- class InsertBuilder {
256
- _table;
257
- _executor;
258
- _values = [];
259
- _onConflict;
260
- _returning;
261
- _comment;
262
- constructor(table2, executor) {
263
- this._table = table2;
264
- this._executor = executor;
265
- }
266
- then(onfulfilled, onrejected) {
267
- return this._executor.execute(this).then(onfulfilled, onrejected);
268
- }
269
- async single() {
270
- return this._executor.executeSingle(this);
271
- }
272
- values(data) {
273
- const rows = Array.isArray(data) ? data : [data];
274
- this._values.push(...rows);
275
- return this;
276
- }
277
- onConflictDoNothing() {
278
- this._onConflict = "do nothing";
279
- return this;
280
- }
281
- onConflictDoUpdate(clause) {
282
- this._onConflict = clause;
283
- return this;
284
- }
285
- returning(...columns) {
286
- this._returning = columns.length > 0 ? columns : ["*"];
287
- return this;
288
- }
289
- comment(tag) {
290
- this._comment = tag;
291
- return this;
292
- }
293
- toSQL() {
294
- if (this._values.length === 0) {
295
- throw new Error("InsertBuilder: no values provided");
296
- }
297
- const keys = Array.from(new Set(this._values.flatMap((v) => Object.keys(v))));
298
- const params = [];
299
- const rowPlaceholders = [];
300
- for (const row of this._values) {
301
- const placeholders = [];
302
- for (const key of keys) {
303
- params.push(row[key] ?? null);
304
- placeholders.push(`$${params.length}`);
305
- }
306
- rowPlaceholders.push(`(${placeholders.join(", ")})`);
307
- }
308
- const colList = keys.map((k) => `"${getTableConfig(this._table).columns[k]?.name ?? k}"`).join(", ");
309
- let query = `INSERT INTO ${getTableConfig(this._table).qualifiedName} (${colList}) VALUES ${rowPlaceholders.join(", ")}`;
310
- if (this._onConflict === "do nothing") {
311
- query += " ON CONFLICT DO NOTHING";
312
- } else if (this._onConflict && typeof this._onConflict === "object") {
313
- const offset = params.length;
314
- query += " ON CONFLICT " + this._onConflict.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
315
- params.push(...this._onConflict.params);
316
- }
317
- if (this._returning) {
318
- query += " RETURNING " + (this._returning[0] === "*" ? Object.keys(getTableConfig(this._table).columns).map((c) => `"${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ") : this._returning.map((c) => `"${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`).join(", "));
319
- }
320
- return { sql: query, params };
321
- }
322
- }
323
-
725
+ // ../bungres-orm/src/builders/update.ts
324
726
  class UpdateBuilder {
325
727
  _table;
326
728
  _executor;
@@ -343,7 +745,11 @@ class UpdateBuilder {
343
745
  return this;
344
746
  }
345
747
  where(condition) {
346
- this._where.push(condition);
748
+ if (condition && typeof condition === "object" && !("sql" in condition)) {
749
+ this._where.push(parseWhereObject(getTableConfig(this._table), condition));
750
+ } else {
751
+ this._where.push(condition);
752
+ }
347
753
  return this;
348
754
  }
349
755
  returning(...columns) {
@@ -361,8 +767,32 @@ class UpdateBuilder {
361
767
  }
362
768
  const params = [];
363
769
  const setClauses = entries.map(([key, value]) => {
364
- params.push(value);
365
770
  const dbCol = getTableConfig(this._table).columns[key]?.name ?? key;
771
+ if (value && typeof value === "object" && "sql" in value && "params" in value) {
772
+ const chunk = value;
773
+ const offset = params.length;
774
+ params.push(...chunk.params);
775
+ return `"${dbCol}" = ${chunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`)}`;
776
+ }
777
+ if (value && typeof value === "object" && !(value instanceof Date)) {
778
+ const colType = getTableConfig(this._table).columns[key]?.dataType;
779
+ if (colType === "json" || colType === "jsonb") {
780
+ params.push(value);
781
+ } else if (Array.isArray(value)) {
782
+ const pgArray = "{" + value.map((item) => {
783
+ if (item === null || item === undefined)
784
+ return "NULL";
785
+ if (typeof item === "string")
786
+ return '"' + item.replace(/"/g, "\\\"") + '"';
787
+ return typeof item === "object" ? '"' + JSON.stringify(item).replace(/"/g, "\\\"") + '"' : String(item);
788
+ }).join(",") + "}";
789
+ params.push(pgArray);
790
+ } else {
791
+ params.push(JSON.stringify(value));
792
+ }
793
+ return `"${dbCol}" = $${params.length}`;
794
+ }
795
+ params.push(value);
366
796
  return `"${dbCol}" = $${params.length}`;
367
797
  });
368
798
  let query = `UPDATE ${getTableConfig(this._table).qualifiedName} SET ${setClauses.join(", ")}`;
@@ -378,50 +808,7 @@ class UpdateBuilder {
378
808
  return { sql: query, params };
379
809
  }
380
810
  }
381
-
382
- class DeleteBuilder {
383
- _table;
384
- _executor;
385
- _where = [];
386
- _returning;
387
- _comment;
388
- constructor(table2, executor) {
389
- this._table = table2;
390
- this._executor = executor;
391
- }
392
- then(onfulfilled, onrejected) {
393
- return this._executor.execute(this).then(onfulfilled, onrejected);
394
- }
395
- async single() {
396
- return this._executor.executeSingle(this);
397
- }
398
- where(condition) {
399
- this._where.push(condition);
400
- return this;
401
- }
402
- returning(...columns) {
403
- this._returning = columns.length > 0 ? columns : ["*"];
404
- return this;
405
- }
406
- comment(tag) {
407
- this._comment = tag;
408
- return this;
409
- }
410
- toSQL() {
411
- let query = `DELETE FROM ${getTableConfig(this._table).qualifiedName}`;
412
- const params = [];
413
- if (this._where.length > 0) {
414
- const combined = sqlJoin(this._where, " AND ");
415
- query += " WHERE " + combined.sql;
416
- params.push(...combined.params);
417
- }
418
- if (this._returning) {
419
- query += " RETURNING " + (this._returning[0] === "*" ? Object.keys(getTableConfig(this._table).columns).map((c) => `"${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ") : this._returning.map((c) => `"${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`).join(", "));
420
- }
421
- return { sql: query, params };
422
- }
423
- }
424
- // ../../node_modules/.bun/@bungres+orm@0.2.0/node_modules/@bungres/orm/src/relational.ts
811
+ // ../bungres-orm/src/builders/relational.ts
425
812
  var _relationsCache = new WeakMap;
426
813
 
427
814
  class RelationalQueryBuilder {
@@ -505,7 +892,7 @@ class RelationalQueryBuilder {
505
892
  const ones = {};
506
893
  const manys = {};
507
894
  const manyToManys = {};
508
- for (const [colName, col2] of Object.entries(tConfig.columns)) {
895
+ for (const [colName2, col2] of Object.entries(tConfig.columns)) {
509
896
  if (col2.references) {
510
897
  const ref = col2.references;
511
898
  const relName = ref.relationName || ref.table;
@@ -514,7 +901,7 @@ class RelationalQueryBuilder {
514
901
  }
515
902
  for (const [otherName, otherTable] of Object.entries(this._schema)) {
516
903
  const otherConfig = otherTable[TableConfigSymbol];
517
- for (const [colName, col2] of Object.entries(otherConfig.columns)) {
904
+ for (const [colName2, col2] of Object.entries(otherConfig.columns)) {
518
905
  if (col2.references && col2.references.table === tableName) {
519
906
  const ref = col2.references;
520
907
  const backRelName = ref.backRelationName || otherName;
@@ -553,10 +940,15 @@ class RelationalQueryBuilder {
553
940
  const jsonFields = [];
554
941
  const lateralJoins = [];
555
942
  const columnsConfig = args.columns;
943
+ const hasTrue = columnsConfig ? Object.values(columnsConfig).some((v) => v === true) : false;
556
944
  for (const [colKey, colConfig] of Object.entries(tableConfig.columns)) {
557
945
  if (columnsConfig) {
558
- if (columnsConfig[colKey] !== true) {
559
- continue;
946
+ if (hasTrue) {
947
+ if (columnsConfig[colKey] !== true)
948
+ continue;
949
+ } else {
950
+ if (columnsConfig[colKey] === false)
951
+ continue;
560
952
  }
561
953
  }
562
954
  jsonFields.push(`'${colKey}', "${alias}"."${colConfig.name}"`);
@@ -615,10 +1007,16 @@ class RelationalQueryBuilder {
615
1007
  if (joinCondition) {
616
1008
  fromSql += ` WHERE ${joinCondition}`;
617
1009
  }
618
- if (args.where && args.where.sql) {
1010
+ if (args.where) {
619
1011
  const offset = params.length;
620
- fromSql += (joinCondition ? " AND " : " WHERE ") + args.where.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
621
- params.push(...args.where.params);
1012
+ let whereChunk = args.where;
1013
+ if (args.where && !args.where.sql) {
1014
+ whereChunk = parseWhereObject(tableConfig, args.where);
1015
+ }
1016
+ if (whereChunk && whereChunk.sql) {
1017
+ fromSql += (joinCondition ? " AND " : " WHERE ") + whereChunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
1018
+ params.push(...whereChunk.params);
1019
+ }
622
1020
  }
623
1021
  if (args.orderBy) {
624
1022
  if (typeof args.orderBy === "string") {
@@ -627,6 +1025,15 @@ class RelationalQueryBuilder {
627
1025
  const offset = params.length;
628
1026
  fromSql += ` ORDER BY ` + args.orderBy.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
629
1027
  params.push(...args.orderBy.params);
1028
+ } else {
1029
+ const chunks = parseOrderByObject(tableConfig, args.orderBy);
1030
+ if (chunks.length > 0) {
1031
+ fromSql += ` ORDER BY ` + chunks.map((c) => {
1032
+ const offset = params.length;
1033
+ params.push(...c.params);
1034
+ return c.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
1035
+ }).join(", ");
1036
+ }
630
1037
  }
631
1038
  }
632
1039
  if (args.limit !== undefined) {
@@ -648,7 +1055,7 @@ class RelationalQueryBuilder {
648
1055
  }
649
1056
  }
650
1057
 
651
- // ../../node_modules/.bun/@bungres+orm@0.2.0/node_modules/@bungres/orm/src/db.ts
1058
+ // ../bungres-orm/src/core/db.ts
652
1059
  function parseDBName(url) {
653
1060
  try {
654
1061
  return new URL(url).pathname.slice(1);
@@ -792,7 +1199,7 @@ class BungresTransaction {
792
1199
  return Array.from(result);
793
1200
  }
794
1201
  }
795
- function createDB(config) {
1202
+ function bungres(config) {
796
1203
  const db = new BungresDB(config);
797
1204
  if (typeof config === "object" && config.schema) {
798
1205
  const schema = config.schema;
@@ -814,7 +1221,7 @@ function createDB(config) {
814
1221
  }
815
1222
  return db;
816
1223
  }
817
- // ../../node_modules/.bun/@bungres+orm@0.2.0/node_modules/@bungres/orm/src/ddl.ts
1224
+ // ../bungres-orm/src/ddl.ts
818
1225
  function generateCreateTable(config, ifNotExists = true) {
819
1226
  const tableName = config.schema ? `"${config.schema}"."${config.name}"` : `"${config.name}"`;
820
1227
  const exists = ifNotExists ? " IF NOT EXISTS" : "";
@@ -1047,11 +1454,11 @@ function diffSchemas(prev, next) {
1047
1454
  const idxName = idx.name ?? `idx_${tableName}_${idx.columns.join("_")}`;
1048
1455
  if (!prevIdxNames.has(idxName)) {
1049
1456
  const tbl = nextConfig.schema ? `"${nextConfig.schema}"."${tableName}"` : `"${tableName}"`;
1050
- const unique = idx.unique ? "UNIQUE " : "";
1457
+ const unique2 = idx.unique ? "UNIQUE " : "";
1051
1458
  const using = idx.using ? ` USING ${idx.using.toUpperCase()}` : "";
1052
1459
  const cols = idx.columns.map((c) => `"${c}"`).join(", ");
1053
1460
  const where = idx.where ? ` WHERE ${idx.where}` : "";
1054
- statements.push(`CREATE ${unique}INDEX IF NOT EXISTS "${idxName}" ON ${tbl}${using} (${cols})${where};`);
1461
+ statements.push(`CREATE ${unique2}INDEX IF NOT EXISTS "${idxName}" ON ${tbl}${using} (${cols})${where};`);
1055
1462
  summary.push(`CREATE INDEX ${idxName} ON ${tableName}`);
1056
1463
  }
1057
1464
  }
@@ -1215,7 +1622,7 @@ async function runGenerate(config, name) {
1215
1622
  console.warn(colorize("No table definitions found. Check your schema glob pattern.", "yellow"));
1216
1623
  return;
1217
1624
  }
1218
- const migrationsDir = resolve3(config.migrationsDir);
1625
+ const migrationsDir = resolve3(config.out);
1219
1626
  await Bun.$`mkdir -p ${migrationsDir}`.quiet();
1220
1627
  const currentSnapshot = Object.fromEntries(schemas.map((s) => [s.config.name, s.config]));
1221
1628
  const snapshotPath = join3(migrationsDir, SNAPSHOT_FILE);
@@ -1308,19 +1715,22 @@ function topoSort(schemas) {
1308
1715
  }
1309
1716
  // src/commands/migrate.ts
1310
1717
  import { join as join4, resolve as resolve4 } from "path";
1311
- var MIGRATIONS_TABLE = "__bungres_migrations";
1312
- var CREATE_MIGRATIONS_TABLE = `
1313
- CREATE TABLE IF NOT EXISTS "${MIGRATIONS_TABLE}" (
1718
+ async function runMigrate(config) {
1719
+ const migrationsDir = resolve4(config.out);
1720
+ const sql2 = new Bun.SQL(config.dbUrl);
1721
+ const table2 = config.migrationsTable;
1722
+ const schema = config.migrationsSchema;
1723
+ const qualifiedTable = `"${schema}"."${table2}"`;
1724
+ const createSchema = `CREATE SCHEMA IF NOT EXISTS "${schema}";`;
1725
+ const createMigrationsTable = `
1726
+ CREATE TABLE IF NOT EXISTS ${qualifiedTable} (
1314
1727
  id SERIAL PRIMARY KEY,
1315
1728
  name TEXT NOT NULL UNIQUE,
1316
1729
  applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
1317
- );
1318
- `.trim();
1319
- async function runMigrate(config) {
1320
- const migrationsDir = resolve4(config.migrationsDir);
1321
- const sql2 = new Bun.SQL(config.dbUrl);
1730
+ );`.trim();
1322
1731
  try {
1323
- await sql2.unsafe(CREATE_MIGRATIONS_TABLE);
1732
+ await sql2.unsafe(createSchema);
1733
+ await sql2.unsafe(createMigrationsTable);
1324
1734
  const glob = new Bun.Glob("*.sql");
1325
1735
  const files = [];
1326
1736
  for await (const file of glob.scan({ cwd: migrationsDir, absolute: false })) {
@@ -1332,7 +1742,7 @@ async function runMigrate(config) {
1332
1742
  console.log(colorize("Run `bungres generate` first.", "yellow"));
1333
1743
  return;
1334
1744
  }
1335
- const applied = await sql2.unsafe(`SELECT name FROM "${MIGRATIONS_TABLE}"`);
1745
+ const applied = await sql2.unsafe(`SELECT name FROM ${qualifiedTable}`);
1336
1746
  const appliedSet = new Set(applied.map((r) => r.name));
1337
1747
  const pending = files.filter((f) => !appliedSet.has(f));
1338
1748
  if (pending.length === 0) {
@@ -1350,11 +1760,11 @@ ${content}
1350
1760
  `);
1351
1761
  }
1352
1762
  await sql2.transaction(async (txSql) => {
1353
- const statements = content.split(";").map((s) => s.trim()).filter(Boolean);
1763
+ const statements = config.breakpoints ? content.split(/-->statement-breakpoint/g).flatMap((chunk) => chunk.split(";").map((s) => s.trim()).filter(Boolean)) : content.split(";").map((s) => s.trim()).filter(Boolean);
1354
1764
  for (const stmt of statements) {
1355
1765
  await txSql.unsafe(stmt + ";");
1356
1766
  }
1357
- await txSql.unsafe(`INSERT INTO "${MIGRATIONS_TABLE}" (name) VALUES ($1)`, [file]);
1767
+ await txSql.unsafe(`INSERT INTO ${qualifiedTable} (name) VALUES ($1)`, [file]);
1358
1768
  });
1359
1769
  console.log(colorize(` \u2713 ${file}`, "green"));
1360
1770
  }
@@ -1367,7 +1777,7 @@ Done.`, "green"));
1367
1777
  // src/commands/pull.ts
1368
1778
  import { resolve as resolve5, join as join5 } from "path";
1369
1779
  async function introspectDb(sql2, dbSchema) {
1370
- const columns = await sql2.unsafe(`SELECT
1780
+ const columns2 = await sql2.unsafe(`SELECT
1371
1781
  c.table_name,
1372
1782
  c.column_name,
1373
1783
  c.data_type,
@@ -1401,7 +1811,7 @@ async function introspectDb(sql2, dbSchema) {
1401
1811
  const indexes = await sql2.unsafe(`SELECT tablename, indexname, indexdef
1402
1812
  FROM pg_indexes
1403
1813
  WHERE schemaname = $1`, [dbSchema]);
1404
- return groupByTable(columns, constraints, indexes);
1814
+ return groupByTable(columns2, constraints, indexes);
1405
1815
  }
1406
1816
  async function runPull(config) {
1407
1817
  console.log("@bungres/kit pull: introspecting database...");
@@ -1424,9 +1834,9 @@ async function runPull(config) {
1424
1834
  await sql2.end();
1425
1835
  }
1426
1836
  }
1427
- function groupByTable(columns, constraints, indexes) {
1837
+ function groupByTable(columns2, constraints, indexes) {
1428
1838
  const map = new Map;
1429
- for (const col2 of columns) {
1839
+ for (const col2 of columns2) {
1430
1840
  if (!map.has(col2.table_name)) {
1431
1841
  map.set(col2.table_name, {
1432
1842
  tableName: col2.table_name,
@@ -1462,7 +1872,7 @@ function generateSchemaTS(tableMap, dbSchema) {
1462
1872
  `// Generated at: ${new Date().toISOString()}`,
1463
1873
  ``,
1464
1874
  `import {`,
1465
- ` snakeCase,`,
1875
+ ` table,`,
1466
1876
  ` text, varchar, char, integer, bigint, smallint,`,
1467
1877
  ` serial, bigserial, boolean, real, doublePrecision,`,
1468
1878
  ` numeric, decimal, json, jsonb,`,
@@ -1474,7 +1884,7 @@ function generateSchemaTS(tableMap, dbSchema) {
1474
1884
  ];
1475
1885
  for (const [, table2] of tableMap) {
1476
1886
  const varName = toCamelCase(table2.tableName);
1477
- lines.push(`export const ${varName} = snakeCase.table("${table2.tableName}", {`);
1887
+ lines.push(`export const ${varName} = table("${table2.tableName}", {`);
1478
1888
  for (const col2 of table2.columns) {
1479
1889
  const colExpr = buildColumnExpression(col2);
1480
1890
  lines.push(` ${toCamelCase(col2.name)}: ${colExpr},`);
@@ -1621,15 +2031,17 @@ function toCamelCase(str) {
1621
2031
  }
1622
2032
  // src/commands/status.ts
1623
2033
  import { resolve as resolve6 } from "path";
1624
- var MIGRATIONS_TABLE2 = "__bungres_migrations";
1625
2034
  async function runStatus(config) {
1626
- const migrationsDir = resolve6(config.migrationsDir);
2035
+ const migrationsDir = resolve6(config.out);
1627
2036
  const sql2 = new Bun.SQL(config.dbUrl);
2037
+ const table2 = config.migrationsTable;
2038
+ const schema = config.migrationsSchema;
2039
+ const qualifiedTable = `"${schema}"."${table2}"`;
1628
2040
  try {
1629
2041
  const tableCheck = await sql2.unsafe(`SELECT EXISTS (
1630
2042
  SELECT 1 FROM information_schema.tables
1631
- WHERE table_name = $1
1632
- ) AS exists`, [MIGRATIONS_TABLE2]);
2043
+ WHERE table_schema = $1 AND table_name = $2
2044
+ ) AS exists`, [schema, table2]);
1633
2045
  const trackingExists = tableCheck[0]?.exists ?? false;
1634
2046
  const glob = new Bun.Glob("*.sql");
1635
2047
  const files = [];
@@ -1643,7 +2055,7 @@ async function runStatus(config) {
1643
2055
  }
1644
2056
  let appliedSet = new Set;
1645
2057
  if (trackingExists) {
1646
- const applied = await sql2.unsafe(`SELECT name FROM "${MIGRATIONS_TABLE2}" ORDER BY applied_at`);
2058
+ const applied = await sql2.unsafe(`SELECT name FROM ${qualifiedTable} ORDER BY applied_at`);
1647
2059
  appliedSet = new Set(applied.map((r) => r.name));
1648
2060
  }
1649
2061
  console.log(colorize(`
@@ -1673,14 +2085,19 @@ async function runDrop(config, opts = {}) {
1673
2085
  }
1674
2086
  const sql2 = new Bun.SQL(config.dbUrl);
1675
2087
  try {
1676
- const existingTablesResult = await sql2`
1677
- SELECT table_name
1678
- FROM information_schema.tables
1679
- WHERE table_schema = 'public' OR table_schema = current_schema()
1680
- `;
1681
- const existingTableNames = new Set(existingTablesResult.map((row) => row.table_name));
1682
- const migrationTableExists = existingTableNames.has("__bungres_migrations");
1683
- const pushTableExists = existingTableNames.has("__bungres_push");
2088
+ const userSchema = config.dbSchema;
2089
+ const existingUserTablesResult = await sql2.unsafe(`SELECT table_name FROM information_schema.tables WHERE table_schema = $1`, [userSchema]);
2090
+ const existingTableNames = new Set(existingUserTablesResult.map((r) => r.table_name));
2091
+ const migTableCheck = await sql2.unsafe(`SELECT EXISTS (
2092
+ SELECT 1 FROM information_schema.tables
2093
+ WHERE table_schema = $1 AND table_name = $2
2094
+ ) AS exists`, [config.migrationsSchema, config.migrationsTable]);
2095
+ const migrationTableExists = migTableCheck[0]?.exists ?? false;
2096
+ const pushTableCheck = await sql2.unsafe(`SELECT EXISTS (
2097
+ SELECT 1 FROM information_schema.tables
2098
+ WHERE table_schema = $1 AND table_name = $2
2099
+ ) AS exists`, [config.migrationsSchema, "__bungres_push"]);
2100
+ const pushTableExists = pushTableCheck[0]?.exists ?? false;
1684
2101
  const tablesToDrop = schemas.filter((s) => existingTableNames.has(s.config.name));
1685
2102
  if (tablesToDrop.length === 0 && !migrationTableExists && !pushTableExists) {
1686
2103
  console.log("No tables to drop (they either don't exist or were already dropped).");
@@ -1688,10 +2105,10 @@ async function runDrop(config, opts = {}) {
1688
2105
  }
1689
2106
  const tableNamesToPrint = tablesToDrop.map((s) => (s.config.schema ? s.config.schema + "." : "") + s.config.name);
1690
2107
  if (migrationTableExists) {
1691
- tableNamesToPrint.push("__bungres_migrations");
2108
+ tableNamesToPrint.push(`${config.migrationsSchema}.${config.migrationsTable}`);
1692
2109
  }
1693
2110
  if (pushTableExists) {
1694
- tableNamesToPrint.push("__bungres_push");
2111
+ tableNamesToPrint.push(`${config.migrationsSchema}.__bungres_push`);
1695
2112
  }
1696
2113
  if (!opts.force) {
1697
2114
  console.warn(colorize(`
@@ -1715,12 +2132,13 @@ Are you sure? Type YES to continue: `, "cyan"));
1715
2132
  console.log(colorize(` \u2713 dropped ${entry.config.name}`, "green"));
1716
2133
  }
1717
2134
  if (migrationTableExists) {
1718
- await sql2.unsafe("DROP TABLE IF EXISTS public.__bungres_migrations CASCADE");
1719
- console.log(colorize(` \u2713 dropped __bungres_migrations`, "green"));
2135
+ const qualifiedMigTable = `"${config.migrationsSchema}"."${config.migrationsTable}"`;
2136
+ await sql2.unsafe(`DROP TABLE IF EXISTS ${qualifiedMigTable} CASCADE`);
2137
+ console.log(colorize(` \u2713 dropped ${config.migrationsSchema}.${config.migrationsTable}`, "green"));
1720
2138
  }
1721
2139
  if (pushTableExists) {
1722
- await sql2.unsafe("DROP TABLE IF EXISTS public.__bungres_push CASCADE");
1723
- console.log(colorize(` \u2713 dropped __bungres_push`, "green"));
2140
+ await sql2.unsafe(`DROP TABLE IF EXISTS "${config.migrationsSchema}"."__bungres_push" CASCADE`);
2141
+ console.log(colorize(` \u2713 dropped ${config.migrationsSchema}.__bungres_push`, "green"));
1724
2142
  }
1725
2143
  console.log(colorize(`
1726
2144
  Drop complete.`, "green"));