@bungres/kit 0.4.0 → 0.6.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.
@@ -1 +1 @@
1
- {"version":3,"file":"drop.d.ts","sourceRoot":"","sources":["../../src/commands/drop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AASnD,wBAAsB,OAAO,CAC3B,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7B,OAAO,CAAC,IAAI,CAAC,CA8Ef"}
1
+ {"version":3,"file":"drop.d.ts","sourceRoot":"","sources":["../../src/commands/drop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AASnD,wBAAsB,OAAO,CAC3B,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7B,OAAO,CAAC,IAAI,CAAC,CA8Ff"}
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAgBnD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,cAAc,EACtB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAgGf"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAgBnD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,cAAc,EACtB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CA+Ff"}
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAiBnD,wBAAsB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAiEtE"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAOnD,wBAAsB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAoFtE"}
@@ -1 +1 @@
1
- {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAUnD,wBAAsB,OAAO,CAC3B,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7B,OAAO,CAAC,IAAI,CAAC,CAoFf"}
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAUnD,wBAAsB,OAAO,CAC3B,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7B,OAAO,CAAC,IAAI,CAAC,CAqFf"}
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AASnD,wBAAsB,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDrE"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAOnD,wBAAsB,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDrE"}
@@ -1 +1 @@
1
- {"version":3,"file":"studio.d.ts","sourceRoot":"","sources":["../../src/commands/studio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQnD,wBAAsB,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAoHrE"}
1
+ {"version":3,"file":"studio.d.ts","sourceRoot":"","sources":["../../src/commands/studio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQnD,wBAAsB,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAyIrE"}
package/dist/config.d.ts CHANGED
@@ -11,7 +11,7 @@ export interface BungresKitConfig {
11
11
  seed?: string;
12
12
  /**
13
13
  * Output directory for generated migration .sql files.
14
- * Equivalent to drizzle's `out`. Default: "./migrations"
14
+ * Default: "./migrations"
15
15
  */
16
16
  out?: string;
17
17
  /**
@@ -26,6 +26,38 @@ export interface BungresKitConfig {
26
26
  * Default: "public"
27
27
  */
28
28
  dbSchema?: string;
29
+ /**
30
+ * Migrations tracking options.
31
+ */
32
+ migrations?: {
33
+ /**
34
+ * Name of the table used to track applied migrations.
35
+ * Default: "__bungres_migrations"
36
+ */
37
+ table?: string;
38
+ /**
39
+ * Postgres schema where the migrations tracking table lives.
40
+ * Default: "bungres"
41
+ */
42
+ schema?: string;
43
+ };
44
+ /**
45
+ * When true, split generated SQL at `-->statement-breakpoint` comments
46
+ * and execute each statement individually inside a transaction.
47
+ * Default: true
48
+ */
49
+ breakpoints?: boolean;
50
+ /**
51
+ * When true, commands like `push` and `drop` will prompt for confirmation
52
+ * before making destructive changes.
53
+ * Default: false
54
+ */
55
+ strict?: boolean;
56
+ /**
57
+ * Output directory for `bungres pull` generated TypeScript.
58
+ * Default: "./src/db/generated"
59
+ */
60
+ outDir?: string;
29
61
  /** Print every SQL statement executed. Default: false */
30
62
  verbose?: boolean;
31
63
  }
@@ -35,8 +67,10 @@ export interface ResolvedConfig {
35
67
  out: string;
36
68
  dbUrl: string;
37
69
  dbSchema: string;
38
- /** @deprecated use out — kept internally for compat */
39
- migrationsDir: string;
70
+ migrationsTable: string;
71
+ migrationsSchema: string;
72
+ breakpoints: boolean;
73
+ strict: boolean;
40
74
  outDir: string;
41
75
  verbose: boolean;
42
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE1B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,aAAa,CAAC,EAAE;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IAEF;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AASD,wBAAsB,UAAU,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CAuC7E"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE1B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,aAAa,CAAC,EAAE;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IAEF;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,EAAE;QACX;;;WAGG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf;;;WAGG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AASD,wBAAsB,UAAU,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CA0C7E"}
@@ -1 +1 @@
1
- {"version":3,"file":"ensure-db.d.ts","sourceRoot":"","sources":["../src/ensure-db.ts"],"names":[],"mappings":"AAAA,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BjE"}
1
+ {"version":3,"file":"ensure-db.d.ts","sourceRoot":"","sources":["../src/ensure-db.ts"],"names":[],"mappings":"AAAA,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCjE"}
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,8 +30,11 @@ async function loadConfig(cwd = process.cwd()) {
30
30
  out,
31
31
  dbUrl,
32
32
  dbSchema: userConfig.dbSchema ?? "public",
33
- migrationsDir: out,
34
- outDir: "./src/db/generated",
33
+ migrationsTable: userConfig.migrations?.table ?? "__bungres_migrations",
34
+ migrationsSchema: userConfig.migrations?.schema ?? "bungres",
35
+ breakpoints: userConfig.breakpoints ?? true,
36
+ strict: userConfig.strict ?? false,
37
+ outDir: userConfig.outDir ?? "./src/db/generated",
35
38
  verbose: userConfig.verbose ?? false
36
39
  };
37
40
  }
@@ -104,9 +107,10 @@ function createTableFactory(casing) {
104
107
  return Object.assign(tableObj, columnConfigs);
105
108
  };
106
109
  }
107
- var table = createTableFactory("none");
110
+ var table = createTableFactory("snake");
108
111
  var snakeCase = { table: createTableFactory("snake") };
109
112
  var camelCase = { table: createTableFactory("camel") };
113
+ var noCasing = { table: createTableFactory("none") };
110
114
  // ../bungres-orm/src/schema/columns.ts
111
115
  function buildColumn(dataType, nameOrOpts, opts) {
112
116
  let name = "";
@@ -201,14 +205,14 @@ function sqlJoin(chunks, separator = ", ") {
201
205
  function rawSql(query) {
202
206
  return { sql: query, params: [] };
203
207
  }
204
- // ../bungres-orm/src/core/conditions.ts
205
- var colName = (c) => {
208
+ function colName(c) {
206
209
  if (typeof c === "string")
207
210
  return `"${c}"`;
208
211
  if (isSQLChunk(c))
209
212
  return c.sql;
210
213
  return c.tableName ? `${c.tableName}."${c.name}"` : `"${c.name}"`;
211
- };
214
+ }
215
+ // ../bungres-orm/src/core/conditions.ts
212
216
  function isColumnConfig(val) {
213
217
  return val !== null && typeof val === "object" && "name" in val && "dataType" in val;
214
218
  }
@@ -265,6 +269,14 @@ var inArray = (column, values) => {
265
269
  const placeholders = params.map((_, i) => `$${i + 1}`).join(", ");
266
270
  return { sql: `${colName(column)} = ANY(ARRAY[${placeholders}])`, params };
267
271
  };
272
+ var notInArray = (column, values) => {
273
+ if (values.length === 0)
274
+ return rawSql("TRUE");
275
+ const params = values;
276
+ const placeholders = params.map((_, i) => `$${i + 1}`).join(", ");
277
+ return { sql: `${colName(column)} != ALL(ARRAY[${placeholders}])`, params };
278
+ };
279
+ var between = (column, min, max) => sql`${rawSql(colName(column))} BETWEEN ${min} AND ${max}`;
268
280
  var and = (...conditions) => sqlJoin(conditions, " AND ");
269
281
  var or = (...conditions) => {
270
282
  const joined = sqlJoin(conditions, " OR ");
@@ -315,6 +327,10 @@ function parseWhereObject(tableConfig, whereObj) {
315
327
  conditions.push(lte(columnArg, opVal.lte));
316
328
  if (opVal.in !== undefined)
317
329
  conditions.push(inArray(columnArg, opVal.in));
330
+ if (opVal.notIn !== undefined)
331
+ conditions.push(notInArray(columnArg, opVal.notIn));
332
+ if (opVal.between !== undefined)
333
+ conditions.push(between(columnArg, opVal.between[0], opVal.between[1]));
318
334
  if (opVal.like !== undefined)
319
335
  conditions.push(like(columnArg, opVal.like));
320
336
  if (opVal.ilike !== undefined)
@@ -395,6 +411,9 @@ class DeleteBuilder {
395
411
  if (this._returning) {
396
412
  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(", "));
397
413
  }
414
+ if (this._comment) {
415
+ query += ` /* ${this._comment.replace(/\*\//g, "")} */`;
416
+ }
398
417
  return { sql: query, params };
399
418
  }
400
419
  }
@@ -505,7 +524,7 @@ class InsertBuilder {
505
524
  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(", "));
506
525
  }
507
526
  if (this._comment) {
508
- query += ` /* ${this._comment} */`;
527
+ query += ` /* ${this._comment.replace(/\*\//g, "")} */`;
509
528
  }
510
529
  return { sql: query, params };
511
530
  }
@@ -702,7 +721,7 @@ class SelectBuilder {
702
721
  query += ` OFFSET $${params.length}`;
703
722
  }
704
723
  if (this._comment) {
705
- query += ` /* ${this._comment} */`;
724
+ query += ` /* ${this._comment.replace(/\*\//g, "")} */`;
706
725
  }
707
726
  return { sql: query, params };
708
727
  }
@@ -802,10 +821,22 @@ class UpdateBuilder {
802
821
  if (this._returning) {
803
822
  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(", "));
804
823
  }
824
+ if (this._comment) {
825
+ query += ` /* ${this._comment.replace(/\*\//g, "")} */`;
826
+ }
805
827
  return { sql: query, params };
806
828
  }
807
829
  }
808
830
  // ../bungres-orm/src/builders/relational.ts
831
+ function getPkColumn(tableConfig) {
832
+ if (tableConfig.primaryKeys?.length > 0)
833
+ return tableConfig.primaryKeys[0];
834
+ for (const [, col2] of Object.entries(tableConfig.columns)) {
835
+ if (col2.primaryKey)
836
+ return col2.name;
837
+ }
838
+ return "id";
839
+ }
809
840
  var _relationsCache = new WeakMap;
810
841
 
811
842
  class RelationalQueryBuilder {
@@ -956,14 +987,17 @@ class RelationalQueryBuilder {
956
987
  if (relations.ones[relKey]) {
957
988
  const rel = relations.ones[relKey];
958
989
  const subAlias = `${alias}_${relKey}`;
959
- const joinCond = `"${subAlias}"."${this._schema[rel.targetTable][TableConfigSymbol].columns.id?.name ?? "id"}" = "${alias}"."${rel.sourceColumn}"`;
990
+ const targetConfig = this._schema[rel.targetTable][TableConfigSymbol];
991
+ const targetPk = getPkColumn(targetConfig);
992
+ const joinCond = `"${subAlias}"."${targetPk}" = "${alias}"."${rel.sourceColumn}"`;
960
993
  const subQuery = this._buildSelectJson(rel.targetTable, rArgs, subAlias, params, alias, joinCond);
961
994
  const subSql = `SELECT ${subQuery.sql} ${subQuery.from}`;
962
995
  jsonFields.push(`'${relKey}', (${subSql})`);
963
996
  } else if (relations.manys[relKey]) {
964
997
  const rel = relations.manys[relKey];
965
998
  const subAlias = `${alias}_${relKey}`;
966
- const joinCond = `"${subAlias}"."${rel.targetColumn}" = "${alias}"."${tableConfig.columns.id?.name ?? "id"}"`;
999
+ const thisPk = getPkColumn(tableConfig);
1000
+ const joinCond = `"${subAlias}"."${rel.targetColumn}" = "${alias}"."${thisPk}"`;
967
1001
  const subQuery = this._buildSelectJson(rel.targetTable, rArgs, subAlias, params, alias, joinCond);
968
1002
  const aggAlias = `${subAlias}_agg`;
969
1003
  const aggSql = `
@@ -982,9 +1016,9 @@ class RelationalQueryBuilder {
982
1016
  const junctionTableConfig = this._schema[rel.junctionTable][TableConfigSymbol];
983
1017
  const fromExtra = `
984
1018
  INNER JOIN ${junctionTableConfig.qualifiedName} AS "${junctionAlias}"
985
- ON "${junctionAlias}"."${rel.joinTargetColumn}" = "${subAlias}"."${targetTableConfig.columns.id?.name ?? "id"}"
1019
+ ON "${junctionAlias}"."${rel.joinTargetColumn}" = "${subAlias}"."${getPkColumn(targetTableConfig)}"
986
1020
  `;
987
- const whereExtra = `"${junctionAlias}"."${rel.joinSourceColumn}" = "${alias}"."${tableConfig.columns.id?.name ?? "id"}"`;
1021
+ const whereExtra = `"${junctionAlias}"."${rel.joinSourceColumn}" = "${alias}"."${getPkColumn(tableConfig)}"`;
988
1022
  const subQuery = this._buildSelectJson(rel.targetTable, rArgs, subAlias, params, alias, whereExtra, fromExtra);
989
1023
  const aggSql = `
990
1024
  SELECT COALESCE(json_agg(_sub.obj), '[]'::json)
@@ -1196,7 +1230,7 @@ class BungresTransaction {
1196
1230
  return Array.from(result);
1197
1231
  }
1198
1232
  }
1199
- function createDB(config) {
1233
+ function bungres(config) {
1200
1234
  const db = new BungresDB(config);
1201
1235
  if (typeof config === "object" && config.schema) {
1202
1236
  const schema = config.schema;
@@ -1497,6 +1531,14 @@ function diffColumn(prev, next) {
1497
1531
  const col2 = `"${next.name}"`;
1498
1532
  if (prev.dataType !== next.dataType) {
1499
1533
  changes.push(`ALTER COLUMN ${col2} TYPE ${next.dataType.toUpperCase()} USING ${col2}::${next.dataType}`);
1534
+ } else {
1535
+ const prevLen = prev.length;
1536
+ const nextLen = next.length;
1537
+ if (prevLen !== nextLen && (next.dataType === "varchar" || next.dataType === "char")) {
1538
+ const typeName = next.dataType === "varchar" ? "VARCHAR" : "CHAR";
1539
+ const typeStr = nextLen ? `${typeName}(${nextLen})` : typeName;
1540
+ changes.push(`ALTER COLUMN ${col2} TYPE ${typeStr}`);
1541
+ }
1500
1542
  }
1501
1543
  if (!prev.notNull && next.notNull) {
1502
1544
  changes.push(`ALTER COLUMN ${col2} SET NOT NULL`);
@@ -1541,13 +1583,15 @@ async function runPush(config, opts = {}) {
1541
1583
  }
1542
1584
  const sql2 = new Bun.SQL(config.dbUrl);
1543
1585
  try {
1586
+ await sql2.unsafe(`CREATE SCHEMA IF NOT EXISTS "${config.migrationsSchema}";`);
1587
+ const qualifiedPush = `"${config.migrationsSchema}"."__bungres_push"`;
1544
1588
  await sql2.unsafe(`
1545
- CREATE TABLE IF NOT EXISTS public.__bungres_push (
1589
+ CREATE TABLE IF NOT EXISTS ${qualifiedPush} (
1546
1590
  id SERIAL PRIMARY KEY,
1547
1591
  snapshot JSONB NOT NULL
1548
1592
  );
1549
1593
  `);
1550
- const rows = await sql2.unsafe(`SELECT snapshot FROM public.__bungres_push ORDER BY id DESC LIMIT 1;`);
1594
+ const rows = await sql2.unsafe(`SELECT snapshot FROM ${qualifiedPush} ORDER BY id DESC LIMIT 1;`);
1551
1595
  let prevSnapshot = {};
1552
1596
  if (rows.length > 0) {
1553
1597
  prevSnapshot = typeof rows[0].snapshot === "string" ? JSON.parse(rows[0].snapshot) : rows[0].snapshot;
@@ -1582,14 +1626,13 @@ Are you sure you want to push these changes? Type YES to continue: `);
1582
1626
  }
1583
1627
  console.log(`
1584
1628
  Pushing changes...`);
1585
- await sql2.unsafe(`CREATE EXTENSION IF NOT EXISTS "pgcrypto";`);
1586
1629
  for (const stmt of diff.statements) {
1587
1630
  if (config.verbose) {
1588
1631
  console.log(`-- ${stmt}`);
1589
1632
  }
1590
1633
  await sql2.unsafe(stmt);
1591
1634
  }
1592
- await sql2.unsafe(`INSERT INTO public.__bungres_push (snapshot) VALUES ($1);`, [JSON.stringify(currentSnapshot)]);
1635
+ await sql2.unsafe(`INSERT INTO ${qualifiedPush} (snapshot) VALUES ($1);`, [JSON.stringify(currentSnapshot)]);
1593
1636
  console.log(`
1594
1637
  Push complete.`);
1595
1638
  } finally {
@@ -1605,9 +1648,9 @@ async function readLine() {
1605
1648
  import { join as join3, resolve as resolve3 } from "path";
1606
1649
 
1607
1650
  // src/utils/colors.ts
1608
- function colorize(text2, color) {
1651
+ function colorize(text, color) {
1609
1652
  const code = Bun.color(color, "ansi");
1610
- return code ? `${code}${text2}\x1B[0m` : text2;
1653
+ return code ? `${code}${text}\x1B[0m` : text;
1611
1654
  }
1612
1655
 
1613
1656
  // src/commands/generate.ts
@@ -1619,7 +1662,7 @@ async function runGenerate(config, name) {
1619
1662
  console.warn(colorize("No table definitions found. Check your schema glob pattern.", "yellow"));
1620
1663
  return;
1621
1664
  }
1622
- const migrationsDir = resolve3(config.migrationsDir);
1665
+ const migrationsDir = resolve3(config.out);
1623
1666
  await Bun.$`mkdir -p ${migrationsDir}`.quiet();
1624
1667
  const currentSnapshot = Object.fromEntries(schemas.map((s) => [s.config.name, s.config]));
1625
1668
  const snapshotPath = join3(migrationsDir, SNAPSHOT_FILE);
@@ -1642,8 +1685,6 @@ async function runGenerate(config, name) {
1642
1685
  if (isFirstMigration) {
1643
1686
  const sorted = topoSort(schemas);
1644
1687
  statements = [
1645
- `CREATE EXTENSION IF NOT EXISTS "pgcrypto";`,
1646
- ``,
1647
1688
  ...sorted.flatMap((entry) => [
1648
1689
  `-- ${entry.exportName}`,
1649
1690
  generateCreateTable(entry.config, true),
@@ -1712,19 +1753,22 @@ function topoSort(schemas) {
1712
1753
  }
1713
1754
  // src/commands/migrate.ts
1714
1755
  import { join as join4, resolve as resolve4 } from "path";
1715
- var MIGRATIONS_TABLE = "__bungres_migrations";
1716
- var CREATE_MIGRATIONS_TABLE = `
1717
- CREATE TABLE IF NOT EXISTS "${MIGRATIONS_TABLE}" (
1756
+ async function runMigrate(config) {
1757
+ const migrationsDir = resolve4(config.out);
1758
+ const sql2 = new Bun.SQL(config.dbUrl);
1759
+ const table2 = config.migrationsTable;
1760
+ const schema = config.migrationsSchema;
1761
+ const qualifiedTable = `"${schema}"."${table2}"`;
1762
+ const createSchema = `CREATE SCHEMA IF NOT EXISTS "${schema}";`;
1763
+ const createMigrationsTable = `
1764
+ CREATE TABLE IF NOT EXISTS ${qualifiedTable} (
1718
1765
  id SERIAL PRIMARY KEY,
1719
1766
  name TEXT NOT NULL UNIQUE,
1720
1767
  applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
1721
- );
1722
- `.trim();
1723
- async function runMigrate(config) {
1724
- const migrationsDir = resolve4(config.migrationsDir);
1725
- const sql2 = new Bun.SQL(config.dbUrl);
1768
+ );`.trim();
1726
1769
  try {
1727
- await sql2.unsafe(CREATE_MIGRATIONS_TABLE);
1770
+ await sql2.unsafe(createSchema);
1771
+ await sql2.unsafe(createMigrationsTable);
1728
1772
  const glob = new Bun.Glob("*.sql");
1729
1773
  const files = [];
1730
1774
  for await (const file of glob.scan({ cwd: migrationsDir, absolute: false })) {
@@ -1736,7 +1780,7 @@ async function runMigrate(config) {
1736
1780
  console.log(colorize("Run `bungres generate` first.", "yellow"));
1737
1781
  return;
1738
1782
  }
1739
- const applied = await sql2.unsafe(`SELECT name FROM "${MIGRATIONS_TABLE}"`);
1783
+ const applied = await sql2.unsafe(`SELECT name FROM ${qualifiedTable}`);
1740
1784
  const appliedSet = new Set(applied.map((r) => r.name));
1741
1785
  const pending = files.filter((f) => !appliedSet.has(f));
1742
1786
  if (pending.length === 0) {
@@ -1754,11 +1798,11 @@ ${content}
1754
1798
  `);
1755
1799
  }
1756
1800
  await sql2.transaction(async (txSql) => {
1757
- const statements = content.split(";").map((s) => s.trim()).filter(Boolean);
1801
+ 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);
1758
1802
  for (const stmt of statements) {
1759
1803
  await txSql.unsafe(stmt + ";");
1760
1804
  }
1761
- await txSql.unsafe(`INSERT INTO "${MIGRATIONS_TABLE}" (name) VALUES ($1)`, [file]);
1805
+ await txSql.unsafe(`INSERT INTO ${qualifiedTable} (name) VALUES ($1)`, [file]);
1762
1806
  });
1763
1807
  console.log(colorize(` \u2713 ${file}`, "green"));
1764
1808
  }
@@ -1866,7 +1910,7 @@ function generateSchemaTS(tableMap, dbSchema) {
1866
1910
  `// Generated at: ${new Date().toISOString()}`,
1867
1911
  ``,
1868
1912
  `import {`,
1869
- ` snakeCase,`,
1913
+ ` table,`,
1870
1914
  ` text, varchar, char, integer, bigint, smallint,`,
1871
1915
  ` serial, bigserial, boolean, real, doublePrecision,`,
1872
1916
  ` numeric, decimal, json, jsonb,`,
@@ -1878,7 +1922,7 @@ function generateSchemaTS(tableMap, dbSchema) {
1878
1922
  ];
1879
1923
  for (const [, table2] of tableMap) {
1880
1924
  const varName = toCamelCase(table2.tableName);
1881
- lines.push(`export const ${varName} = snakeCase.table("${table2.tableName}", {`);
1925
+ lines.push(`export const ${varName} = table("${table2.tableName}", {`);
1882
1926
  for (const col2 of table2.columns) {
1883
1927
  const colExpr = buildColumnExpression(col2);
1884
1928
  lines.push(` ${toCamelCase(col2.name)}: ${colExpr},`);
@@ -2025,15 +2069,17 @@ function toCamelCase(str) {
2025
2069
  }
2026
2070
  // src/commands/status.ts
2027
2071
  import { resolve as resolve6 } from "path";
2028
- var MIGRATIONS_TABLE2 = "__bungres_migrations";
2029
2072
  async function runStatus(config) {
2030
- const migrationsDir = resolve6(config.migrationsDir);
2073
+ const migrationsDir = resolve6(config.out);
2031
2074
  const sql2 = new Bun.SQL(config.dbUrl);
2075
+ const table2 = config.migrationsTable;
2076
+ const schema = config.migrationsSchema;
2077
+ const qualifiedTable = `"${schema}"."${table2}"`;
2032
2078
  try {
2033
2079
  const tableCheck = await sql2.unsafe(`SELECT EXISTS (
2034
2080
  SELECT 1 FROM information_schema.tables
2035
- WHERE table_name = $1
2036
- ) AS exists`, [MIGRATIONS_TABLE2]);
2081
+ WHERE table_schema = $1 AND table_name = $2
2082
+ ) AS exists`, [schema, table2]);
2037
2083
  const trackingExists = tableCheck[0]?.exists ?? false;
2038
2084
  const glob = new Bun.Glob("*.sql");
2039
2085
  const files = [];
@@ -2047,7 +2093,7 @@ async function runStatus(config) {
2047
2093
  }
2048
2094
  let appliedSet = new Set;
2049
2095
  if (trackingExists) {
2050
- const applied = await sql2.unsafe(`SELECT name FROM "${MIGRATIONS_TABLE2}" ORDER BY applied_at`);
2096
+ const applied = await sql2.unsafe(`SELECT name FROM ${qualifiedTable} ORDER BY applied_at`);
2051
2097
  appliedSet = new Set(applied.map((r) => r.name));
2052
2098
  }
2053
2099
  console.log(colorize(`
@@ -2077,14 +2123,19 @@ async function runDrop(config, opts = {}) {
2077
2123
  }
2078
2124
  const sql2 = new Bun.SQL(config.dbUrl);
2079
2125
  try {
2080
- const existingTablesResult = await sql2`
2081
- SELECT table_name
2082
- FROM information_schema.tables
2083
- WHERE table_schema = 'public' OR table_schema = current_schema()
2084
- `;
2085
- const existingTableNames = new Set(existingTablesResult.map((row) => row.table_name));
2086
- const migrationTableExists = existingTableNames.has("__bungres_migrations");
2087
- const pushTableExists = existingTableNames.has("__bungres_push");
2126
+ const userSchema = config.dbSchema;
2127
+ const existingUserTablesResult = await sql2.unsafe(`SELECT table_name FROM information_schema.tables WHERE table_schema = $1`, [userSchema]);
2128
+ const existingTableNames = new Set(existingUserTablesResult.map((r) => r.table_name));
2129
+ const migTableCheck = await sql2.unsafe(`SELECT EXISTS (
2130
+ SELECT 1 FROM information_schema.tables
2131
+ WHERE table_schema = $1 AND table_name = $2
2132
+ ) AS exists`, [config.migrationsSchema, config.migrationsTable]);
2133
+ const migrationTableExists = migTableCheck[0]?.exists ?? false;
2134
+ const pushTableCheck = await sql2.unsafe(`SELECT EXISTS (
2135
+ SELECT 1 FROM information_schema.tables
2136
+ WHERE table_schema = $1 AND table_name = $2
2137
+ ) AS exists`, [config.migrationsSchema, "__bungres_push"]);
2138
+ const pushTableExists = pushTableCheck[0]?.exists ?? false;
2088
2139
  const tablesToDrop = schemas.filter((s) => existingTableNames.has(s.config.name));
2089
2140
  if (tablesToDrop.length === 0 && !migrationTableExists && !pushTableExists) {
2090
2141
  console.log("No tables to drop (they either don't exist or were already dropped).");
@@ -2092,10 +2143,10 @@ async function runDrop(config, opts = {}) {
2092
2143
  }
2093
2144
  const tableNamesToPrint = tablesToDrop.map((s) => (s.config.schema ? s.config.schema + "." : "") + s.config.name);
2094
2145
  if (migrationTableExists) {
2095
- tableNamesToPrint.push("__bungres_migrations");
2146
+ tableNamesToPrint.push(`${config.migrationsSchema}.${config.migrationsTable}`);
2096
2147
  }
2097
2148
  if (pushTableExists) {
2098
- tableNamesToPrint.push("__bungres_push");
2149
+ tableNamesToPrint.push(`${config.migrationsSchema}.__bungres_push`);
2099
2150
  }
2100
2151
  if (!opts.force) {
2101
2152
  console.warn(colorize(`
@@ -2119,12 +2170,13 @@ Are you sure? Type YES to continue: `, "cyan"));
2119
2170
  console.log(colorize(` \u2713 dropped ${entry.config.name}`, "green"));
2120
2171
  }
2121
2172
  if (migrationTableExists) {
2122
- await sql2.unsafe("DROP TABLE IF EXISTS public.__bungres_migrations CASCADE");
2123
- console.log(colorize(` \u2713 dropped __bungres_migrations`, "green"));
2173
+ const qualifiedMigTable = `"${config.migrationsSchema}"."${config.migrationsTable}"`;
2174
+ await sql2.unsafe(`DROP TABLE IF EXISTS ${qualifiedMigTable} CASCADE`);
2175
+ console.log(colorize(` \u2713 dropped ${config.migrationsSchema}.${config.migrationsTable}`, "green"));
2124
2176
  }
2125
2177
  if (pushTableExists) {
2126
- await sql2.unsafe("DROP TABLE IF EXISTS public.__bungres_push CASCADE");
2127
- console.log(colorize(` \u2713 dropped __bungres_push`, "green"));
2178
+ await sql2.unsafe(`DROP TABLE IF EXISTS "${config.migrationsSchema}"."__bungres_push" CASCADE`);
2179
+ console.log(colorize(` \u2713 dropped ${config.migrationsSchema}.__bungres_push`, "green"));
2128
2180
  }
2129
2181
  console.log(colorize(`
2130
2182
  Drop complete.`, "green"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bungres/kit",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "CLI toolkit for @bungres/orm — migrate, push, generate, pull",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -29,7 +29,7 @@
29
29
  "repository": {
30
30
  "type": "git",
31
31
  "url": "https://github.com/bungres/bungres.git",
32
- "directory": "packages/@bungres/kit"
32
+ "directory": "packages/bungres-kit"
33
33
  },
34
34
  "bugs": {
35
35
  "url": "https://github.com/bungres/bungres/issues"