bun-query-builder 0.2.5 → 0.2.7

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/bin/cli.js CHANGED
@@ -11643,7 +11643,7 @@ var init_dist = __esm(() => {
11643
11643
  // src/config.ts
11644
11644
  import process19 from "process";
11645
11645
  function isMysqlLike(dialect = config5.dialect) {
11646
- return dialect === "mysql" || dialect === "singlestore";
11646
+ return dialect === "mysql" || dialect === "singlestore" || dialect === "vitess";
11647
11647
  }
11648
11648
  function resolveDialect(explicit) {
11649
11649
  if (explicit)
@@ -11701,6 +11701,9 @@ function applyConfig(userConfig) {
11701
11701
  if (userConfig.softDeletes) {
11702
11702
  config5.softDeletes = { ...config5.softDeletes, ...userConfig.softDeletes };
11703
11703
  }
11704
+ if (userConfig.vitess) {
11705
+ config5.vitess = { ...config5.vitess, ...userConfig.vitess };
11706
+ }
11704
11707
  }
11705
11708
  function setConfig(userConfig) {
11706
11709
  if (userConfig.dialect && _lastConfiguredDialect && userConfig.dialect !== _lastConfiguredDialect) {
@@ -11730,6 +11733,9 @@ var init_config = __esm(() => {
11730
11733
  host: "localhost",
11731
11734
  port: 5432
11732
11735
  },
11736
+ vitess: {
11737
+ sharded: true
11738
+ },
11733
11739
  timestamps: {
11734
11740
  createdAt: "created_at",
11735
11741
  updatedAt: "updated_at",
@@ -12094,7 +12100,7 @@ function resolveDatabaseName(dbConfig = config5.database) {
12094
12100
  return String(raw).replace(/^['"]|['"]$/g, "");
12095
12101
  }
12096
12102
  function createConnectionString(dialect, dbConfig) {
12097
- if ((dialect === "postgres" || dialect === "mysql" || dialect === "singlestore") && process21.env.DB_CONNECTION === dialect) {
12103
+ if ((dialect === "postgres" || dialect === "mysql" || dialect === "singlestore" || dialect === "vitess") && process21.env.DB_CONNECTION === dialect) {
12098
12104
  const e = process21.env;
12099
12105
  const envDb = (e.DB_DATABASE || dbConfig.database || "").replace(/^['"]|['"]$/g, "");
12100
12106
  const envUser = e.DB_USERNAME || dbConfig.username;
@@ -12115,6 +12121,7 @@ function createConnectionString(dialect, dbConfig) {
12115
12121
  return `postgres://${username}:${password}@${host}${port ? `:${port}` : ""}/${database}${sslQ}`;
12116
12122
  case "mysql":
12117
12123
  case "singlestore":
12124
+ case "vitess":
12118
12125
  return `mysql://${username}:${password}@${host}${port ? `:${port}` : ""}/${database}${sslQ}`;
12119
12126
  case "sqlite":
12120
12127
  if (database === ":memory:") {
@@ -17969,7 +17976,7 @@ function parseMysqlEnum(columnType) {
17969
17976
  return;
17970
17977
  return m[1].split(",").map((s) => s.trim().replace(/^'(.*)'$/s, "$1").replace(/''/g, "'")).filter((s) => s.length > 0);
17971
17978
  }
17972
- function groupPhysicalIndexes(table, rows) {
17979
+ function groupPhysicalIndexes(_table, rows) {
17973
17980
  const byName = new Map;
17974
17981
  for (const r of rows) {
17975
17982
  if (r.isPrimary)
@@ -18525,6 +18532,42 @@ var init_singlestore = __esm(() => {
18525
18532
  };
18526
18533
  });
18527
18534
 
18535
+ // src/drivers/vitess.ts
18536
+ var VitessDriver;
18537
+ var init_vitess = __esm(() => {
18538
+ init_mysql();
18539
+ VitessDriver = class VitessDriver extends MySQLDriver {
18540
+ sharded;
18541
+ constructor(sharded = true) {
18542
+ super();
18543
+ this.sharded = sharded;
18544
+ }
18545
+ getAutoIncrementClause(column) {
18546
+ return this.sharded ? "" : super.getAutoIncrementClause(column);
18547
+ }
18548
+ renderColumn(column) {
18549
+ if (!this.sharded || !column.references)
18550
+ return super.renderColumn(column);
18551
+ const { references: _references, ...withoutReference } = column;
18552
+ return super.renderColumn(withoutReference);
18553
+ }
18554
+ createTable(table) {
18555
+ return super.createTable(table);
18556
+ }
18557
+ addForeignKey(...args) {
18558
+ return this.sharded ? "" : super.addForeignKey(...args);
18559
+ }
18560
+ createMigrationsTable() {
18561
+ if (!this.sharded)
18562
+ return super.createMigrationsTable();
18563
+ return `CREATE TABLE IF NOT EXISTS migrations (
18564
+ migration VARCHAR(255) NOT NULL PRIMARY KEY,
18565
+ executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
18566
+ )`;
18567
+ }
18568
+ };
18569
+ });
18570
+
18528
18571
  // src/drivers/sqlite.ts
18529
18572
  function isNumericPlanType(type) {
18530
18573
  return type === "integer" || type === "bigint" || type === "float" || type === "double" || type === "decimal";
@@ -18736,6 +18779,8 @@ function getDialectDriver(dialect) {
18736
18779
  return new MySQLDriver;
18737
18780
  case "singlestore":
18738
18781
  return new SingleStoreDriver;
18782
+ case "vitess":
18783
+ return new VitessDriver(config5.vitess?.sharded ?? true);
18739
18784
  case "sqlite":
18740
18785
  return new SQLiteDriver;
18741
18786
  default:
@@ -18743,14 +18788,17 @@ function getDialectDriver(dialect) {
18743
18788
  }
18744
18789
  }
18745
18790
  var init_drivers = __esm(() => {
18791
+ init_config();
18746
18792
  init_mysql();
18747
18793
  init_postgres();
18748
18794
  init_singlestore();
18795
+ init_vitess();
18749
18796
  init_sqlite();
18750
18797
  init_mysql();
18751
18798
  init_postgres();
18752
18799
  init_singlestore();
18753
18800
  init_sqlite();
18801
+ init_vitess();
18754
18802
  });
18755
18803
 
18756
18804
  // src/workspace.ts
@@ -29238,7 +29286,7 @@ function generateDiffOperations(previous, next, opts = {}) {
29238
29286
  if (preserveUnknownColumns && removedCols.length > 0) {
29239
29287
  const preserved = removedCols.map((name) => prevCols[name]);
29240
29288
  const preservedNames = new Set(removedCols);
29241
- const keptIndexes = prev.indexes.filter((idx) => idx.columns.some((c2) => preservedNames.has(c2)) && !currIdx[indexKey(idx)]);
29289
+ const keptIndexes = prev.indexes.filter((idx) => idx.columns.some((c2) => preservedNames.has(c2)) && !currIdx[indexKey(idx, prev.table)]);
29242
29290
  info2(`-- Keeping ${preserved.length} column(s) on "${curr.table}" no model declares: ${removedCols.join(", ")} \u2014 reconciled from the database, where an undeclared column is out of scope rather than removed`);
29243
29291
  curr = { ...curr, columns: [...curr.columns, ...preserved], indexes: [...curr.indexes, ...keptIndexes] };
29244
29292
  currCols = mapColumnsByName(curr.columns);
@@ -31480,7 +31528,7 @@ function getPrefix() {
31480
31528
  }
31481
31529
  var prefix = getPrefix();
31482
31530
  // package.json
31483
- var version2 = "0.2.5";
31531
+ var version2 = "0.2.7";
31484
31532
 
31485
31533
  // bin/cli.ts
31486
31534
  init_actions();
package/dist/config.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import type { QueryBuilderConfig, SupportedDialect } from './types';
2
2
  /**
3
- * Whether a dialect belongs to the MySQL wire-protocol family (MySQL itself or
4
- * SingleStore). These share `?` placeholders, backtick identifier quoting,
5
- * `ON DUPLICATE KEY UPDATE` upserts, `LAST_INSERT_ID()` id recovery, and the
6
- * `YYYY-MM-DD HH:MM:SS` datetime literal shape. Runtime DML branches should key
7
- * off this helper rather than `dialect === 'mysql'` so SingleStore inherits the
8
- * same behavior; only DDL (see `SingleStoreDriver`) diverges.
3
+ * Whether a dialect belongs to the MySQL wire-protocol family (MySQL itself,
4
+ * SingleStore, or Vitess). These share `?` placeholders, backtick identifier
5
+ * quoting, `ON DUPLICATE KEY UPDATE` upserts, `LAST_INSERT_ID()` id recovery,
6
+ * and the `YYYY-MM-DD HH:MM:SS` datetime literal shape. Runtime DML branches
7
+ * should key off this helper rather than `dialect === 'mysql'` so the
8
+ * distributed dialects inherit the same behavior; only DDL (see
9
+ * `SingleStoreDriver` / `VitessDriver`) diverges.
9
10
  */
10
11
  export declare function isMysqlLike(dialect?: SupportedDialect): boolean;
11
12
  /**
@@ -2,6 +2,7 @@ import { MySQLDriver } from './mysql';
2
2
  import { PostgresDriver } from './postgres';
3
3
  import { SingleStoreDriver } from './singlestore';
4
4
  import { SQLiteDriver } from './sqlite';
5
+ import { VitessDriver } from './vitess';
5
6
  import type { DialectDriver } from './postgres';
6
7
  import type { SupportedDialect } from '../types';
7
8
  export type { DialectDriver } from './postgres';
@@ -32,6 +33,7 @@ export { MySQLDriver } from './mysql';
32
33
  export { PostgresDriver } from './postgres';
33
34
  export { SingleStoreDriver } from './singlestore';
34
35
  export { SQLiteDriver } from './sqlite';
36
+ export { VitessDriver } from './vitess';
35
37
  // DynamoDB driver (NoSQL)
36
38
  export {
37
39
  createDynamoDBDriver,
@@ -0,0 +1,41 @@
1
+ import { MySQLDriver } from './mysql';
2
+ import type { ColumnPlan, TablePlan } from '../migrations';
3
+ /**
4
+ * Vitess DDL driver.
5
+ *
6
+ * Vitess shards MySQL behind vtgate, which speaks the MySQL wire protocol, so
7
+ * runtime DML (placeholders, backtick quoting, `ON DUPLICATE KEY UPDATE`,
8
+ * `LAST_INSERT_ID`) is identical — see `isMysqlLike` in `config.ts`. Only DDL
9
+ * diverges only when the keyspace is sharded. An unsharded keyspace retains
10
+ * normal MySQL AUTO_INCREMENT and foreign-key support, so this driver takes
11
+ * the topology explicitly instead of conflating "behind vtgate" with
12
+ * "distributed across shards".
13
+ *
14
+ * - **No foreign keys.** Enforcing one would need a cross-shard read on every
15
+ * write, so vtgate rejects them in a sharded keyspace. Both forms are
16
+ * suppressed: the `ALTER TABLE … ADD CONSTRAINT` statement (`addForeignKey`)
17
+ * and the inline `REFERENCES` clause the MySQL driver emits inside a column
18
+ * definition. Missing the inline form would be the subtler bug — the table
19
+ * plan carries the reference on the column, so a `CREATE TABLE` would fail
20
+ * on its own without any FK statement being generated.
21
+ * - **No AUTO_INCREMENT.** Each shard would independently hand out the same
22
+ * values and collide. This is not a parse error, which makes it worse than
23
+ * one: the DDL succeeds and the collisions appear later, under load, as
24
+ * duplicate-key failures on inserts that were previously fine. Primary keys
25
+ * must come from the application or from a sequence table in an unsharded
26
+ * keyspace, declared in the VSchema.
27
+ *
28
+ * **Sharding is not expressed in DDL.** Unlike SingleStore, where the shard key
29
+ * is a `CREATE TABLE` clause, Vitess keeps the topology in a separate VSchema
30
+ * document that maps each table's sharding column to a vindex. So `createTable`
31
+ * here is plain MySQL minus the two constructs above, and nothing in this
32
+ * driver needs to know how a table is sharded.
33
+ */
34
+ export declare class VitessDriver extends MySQLDriver {
35
+ constructor(sharded?: boolean);
36
+ protected getAutoIncrementClause(column: ColumnPlan): string;
37
+ protected renderColumn(column: ColumnPlan): string;
38
+ createTable(table: TablePlan): string;
39
+ addForeignKey(...args: Parameters<MySQLDriver['addForeignKey']>): string;
40
+ createMigrationsTable(): string;
41
+ }
package/dist/src/index.js CHANGED
@@ -11642,7 +11642,7 @@ var init_dist = __esm(() => {
11642
11642
  // src/config.ts
11643
11643
  import process19 from "process";
11644
11644
  function isMysqlLike(dialect = config5.dialect) {
11645
- return dialect === "mysql" || dialect === "singlestore";
11645
+ return dialect === "mysql" || dialect === "singlestore" || dialect === "vitess";
11646
11646
  }
11647
11647
  function resolveDialect(explicit) {
11648
11648
  if (explicit)
@@ -11700,6 +11700,9 @@ function applyConfig(userConfig) {
11700
11700
  if (userConfig.softDeletes) {
11701
11701
  config5.softDeletes = { ...config5.softDeletes, ...userConfig.softDeletes };
11702
11702
  }
11703
+ if (userConfig.vitess) {
11704
+ config5.vitess = { ...config5.vitess, ...userConfig.vitess };
11705
+ }
11703
11706
  }
11704
11707
  function setConfig(userConfig) {
11705
11708
  if (userConfig.dialect && _lastConfiguredDialect && userConfig.dialect !== _lastConfiguredDialect) {
@@ -11729,6 +11732,9 @@ var init_config = __esm(() => {
11729
11732
  host: "localhost",
11730
11733
  port: 5432
11731
11734
  },
11735
+ vitess: {
11736
+ sharded: true
11737
+ },
11732
11738
  timestamps: {
11733
11739
  createdAt: "created_at",
11734
11740
  updatedAt: "updated_at",
@@ -12093,7 +12099,7 @@ function resolveDatabaseName(dbConfig = config5.database) {
12093
12099
  return String(raw).replace(/^['"]|['"]$/g, "");
12094
12100
  }
12095
12101
  function createConnectionString(dialect, dbConfig) {
12096
- if ((dialect === "postgres" || dialect === "mysql" || dialect === "singlestore") && process21.env.DB_CONNECTION === dialect) {
12102
+ if ((dialect === "postgres" || dialect === "mysql" || dialect === "singlestore" || dialect === "vitess") && process21.env.DB_CONNECTION === dialect) {
12097
12103
  const e = process21.env;
12098
12104
  const envDb = (e.DB_DATABASE || dbConfig.database || "").replace(/^['"]|['"]$/g, "");
12099
12105
  const envUser = e.DB_USERNAME || dbConfig.username;
@@ -12114,6 +12120,7 @@ function createConnectionString(dialect, dbConfig) {
12114
12120
  return `postgres://${username}:${password}@${host}${port ? `:${port}` : ""}/${database}${sslQ}`;
12115
12121
  case "mysql":
12116
12122
  case "singlestore":
12123
+ case "vitess":
12117
12124
  return `mysql://${username}:${password}@${host}${port ? `:${port}` : ""}/${database}${sslQ}`;
12118
12125
  case "sqlite":
12119
12126
  if (database === ":memory:") {
@@ -17968,7 +17975,7 @@ function parseMysqlEnum(columnType) {
17968
17975
  return;
17969
17976
  return m[1].split(",").map((s) => s.trim().replace(/^'(.*)'$/s, "$1").replace(/''/g, "'")).filter((s) => s.length > 0);
17970
17977
  }
17971
- function groupPhysicalIndexes(table, rows) {
17978
+ function groupPhysicalIndexes(_table, rows) {
17972
17979
  const byName = new Map;
17973
17980
  for (const r of rows) {
17974
17981
  if (r.isPrimary)
@@ -18524,6 +18531,42 @@ var init_singlestore = __esm(() => {
18524
18531
  };
18525
18532
  });
18526
18533
 
18534
+ // src/drivers/vitess.ts
18535
+ var VitessDriver;
18536
+ var init_vitess = __esm(() => {
18537
+ init_mysql();
18538
+ VitessDriver = class VitessDriver extends MySQLDriver {
18539
+ sharded;
18540
+ constructor(sharded = true) {
18541
+ super();
18542
+ this.sharded = sharded;
18543
+ }
18544
+ getAutoIncrementClause(column) {
18545
+ return this.sharded ? "" : super.getAutoIncrementClause(column);
18546
+ }
18547
+ renderColumn(column) {
18548
+ if (!this.sharded || !column.references)
18549
+ return super.renderColumn(column);
18550
+ const { references: _references, ...withoutReference } = column;
18551
+ return super.renderColumn(withoutReference);
18552
+ }
18553
+ createTable(table) {
18554
+ return super.createTable(table);
18555
+ }
18556
+ addForeignKey(...args) {
18557
+ return this.sharded ? "" : super.addForeignKey(...args);
18558
+ }
18559
+ createMigrationsTable() {
18560
+ if (!this.sharded)
18561
+ return super.createMigrationsTable();
18562
+ return `CREATE TABLE IF NOT EXISTS migrations (
18563
+ migration VARCHAR(255) NOT NULL PRIMARY KEY,
18564
+ executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
18565
+ )`;
18566
+ }
18567
+ };
18568
+ });
18569
+
18527
18570
  // src/drivers/sqlite.ts
18528
18571
  function isNumericPlanType(type) {
18529
18572
  return type === "integer" || type === "bigint" || type === "float" || type === "double" || type === "decimal";
@@ -18735,6 +18778,8 @@ function getDialectDriver(dialect) {
18735
18778
  return new MySQLDriver;
18736
18779
  case "singlestore":
18737
18780
  return new SingleStoreDriver;
18781
+ case "vitess":
18782
+ return new VitessDriver(config5.vitess?.sharded ?? true);
18738
18783
  case "sqlite":
18739
18784
  return new SQLiteDriver;
18740
18785
  default:
@@ -18742,14 +18787,17 @@ function getDialectDriver(dialect) {
18742
18787
  }
18743
18788
  }
18744
18789
  var init_drivers = __esm(() => {
18790
+ init_config();
18745
18791
  init_mysql();
18746
18792
  init_postgres();
18747
18793
  init_singlestore();
18794
+ init_vitess();
18748
18795
  init_sqlite();
18749
18796
  init_mysql();
18750
18797
  init_postgres();
18751
18798
  init_singlestore();
18752
18799
  init_sqlite();
18800
+ init_vitess();
18753
18801
  });
18754
18802
 
18755
18803
  // src/workspace.ts
@@ -29237,7 +29285,7 @@ function generateDiffOperations(previous, next, opts = {}) {
29237
29285
  if (preserveUnknownColumns && removedCols.length > 0) {
29238
29286
  const preserved = removedCols.map((name) => prevCols[name]);
29239
29287
  const preservedNames = new Set(removedCols);
29240
- const keptIndexes = prev.indexes.filter((idx) => idx.columns.some((c2) => preservedNames.has(c2)) && !currIdx[indexKey(idx)]);
29288
+ const keptIndexes = prev.indexes.filter((idx) => idx.columns.some((c2) => preservedNames.has(c2)) && !currIdx[indexKey(idx, prev.table)]);
29241
29289
  info2(`-- Keeping ${preserved.length} column(s) on "${curr.table}" no model declares: ${removedCols.join(", ")} \u2014 reconciled from the database, where an undeclared column is out of scope rather than removed`);
29242
29290
  curr = { ...curr, columns: [...curr.columns, ...preserved], indexes: [...curr.indexes, ...keptIndexes] };
29243
29291
  currCols = mapColumnsByName(curr.columns);
@@ -29580,6 +29628,7 @@ export {
29580
29628
  browserQuery,
29581
29629
  browserAuth,
29582
29630
  applySqliteBootstrapPragmas,
29631
+ VitessDriver,
29583
29632
  SingleTableRepository,
29584
29633
  SingleTableQueryBuilder,
29585
29634
  SingleTablePatterns,
package/dist/types.d.ts CHANGED
@@ -192,6 +192,10 @@ export declare interface DatabaseConfig {
192
192
  ssl?: boolean
193
193
  pool?: PoolConfig
194
194
  }
195
+ /** Vitess topology controls that affect generated DDL. */
196
+ export declare interface VitessConfig {
197
+ sharded: boolean
198
+ }
195
199
  /**
196
200
  * # `BrowserConfig`
197
201
  *
@@ -236,6 +240,7 @@ export declare interface QueryBuilderConfig {
236
240
  transactionDefaults: TransactionDefaultsConfig
237
241
  sql: SqlConfig
238
242
  sqlite?: SqliteConfig
243
+ vitess?: VitessConfig
239
244
  features: FeatureToggles
240
245
  debug?: {
241
246
  captureText: boolean
@@ -293,7 +298,11 @@ export declare interface UnsafeOptions {
293
298
  * but its DDL adds distributed-table concepts (`SHARD KEY`, `SORT KEY`,
294
299
  * `ROWSTORE`/columnstore) and drops foreign keys — handled by the dedicated
295
300
  * `SingleStoreDriver`.
301
+ * - 'vitess': MySQL behind vtgate. Shares MySQL's wire protocol and DML (see
302
+ * `isMysqlLike`). Unsharded keyspaces retain normal MySQL DDL, while a
303
+ * sharded keyspace rejects foreign keys and AUTO_INCREMENT; select that
304
+ * stricter profile with `vitess.sharded`.
296
305
  * - 'sqlite': Lightweight engine; some features are limited or emulated
297
306
  * - 'browser': Browser-compatible mode that uses fetch() API calls instead of direct database connections
298
307
  */
299
- export type SupportedDialect = 'postgres' | 'mysql' | 'singlestore' | 'sqlite' | 'browser';
308
+ export type SupportedDialect = 'postgres' | 'mysql' | 'singlestore' | 'vitess' | 'sqlite' | 'browser';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bun-query-builder",
3
3
  "type": "module",
4
- "version": "0.2.5",
4
+ "version": "0.2.7",
5
5
  "description": "A simple yet performant query builder for TypeScript. Built with Bun.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",