bun-query-builder 0.2.4 → 0.2.6

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)
@@ -12094,7 +12094,7 @@ function resolveDatabaseName(dbConfig = config5.database) {
12094
12094
  return String(raw).replace(/^['"]|['"]$/g, "");
12095
12095
  }
12096
12096
  function createConnectionString(dialect, dbConfig) {
12097
- if ((dialect === "postgres" || dialect === "mysql" || dialect === "singlestore") && process21.env.DB_CONNECTION === dialect) {
12097
+ if ((dialect === "postgres" || dialect === "mysql" || dialect === "singlestore" || dialect === "vitess") && process21.env.DB_CONNECTION === dialect) {
12098
12098
  const e = process21.env;
12099
12099
  const envDb = (e.DB_DATABASE || dbConfig.database || "").replace(/^['"]|['"]$/g, "");
12100
12100
  const envUser = e.DB_USERNAME || dbConfig.username;
@@ -12115,6 +12115,7 @@ function createConnectionString(dialect, dbConfig) {
12115
12115
  return `postgres://${username}:${password}@${host}${port ? `:${port}` : ""}/${database}${sslQ}`;
12116
12116
  case "mysql":
12117
12117
  case "singlestore":
12118
+ case "vitess":
12118
12119
  return `mysql://${username}:${password}@${host}${port ? `:${port}` : ""}/${database}${sslQ}`;
12119
12120
  case "sqlite":
12120
12121
  if (database === ":memory:") {
@@ -18078,10 +18079,26 @@ export default model
18078
18079
  var init_make_model = () => {};
18079
18080
 
18080
18081
  // src/drivers/index-name.ts
18082
+ function fingerprint(value) {
18083
+ let hash = 2166136261;
18084
+ for (let i = 0;i < value.length; i++) {
18085
+ hash ^= value.charCodeAt(i);
18086
+ hash = Math.imul(hash, 16777619) >>> 0;
18087
+ }
18088
+ return hash.toString(36).padStart(7, "0").slice(-7);
18089
+ }
18090
+ function boundIdentifier(name, limit = MAX_IDENTIFIER_LENGTH) {
18091
+ if (name.length <= limit)
18092
+ return name;
18093
+ const suffix = `_${fingerprint(name)}`;
18094
+ return name.slice(0, limit - suffix.length) + suffix;
18095
+ }
18081
18096
  function qualifiedIndexName(tableName, indexName) {
18082
18097
  const prefix = `${tableName}_`;
18083
- return indexName.startsWith(prefix) ? indexName : `${prefix}${indexName}`;
18098
+ const qualified = indexName.startsWith(prefix) ? indexName : `${prefix}${indexName}`;
18099
+ return boundIdentifier(qualified);
18084
18100
  }
18101
+ var MAX_IDENTIFIER_LENGTH = 63;
18085
18102
 
18086
18103
  // src/drivers/mysql.ts
18087
18104
  class MySQLDriver {
@@ -18509,6 +18526,35 @@ var init_singlestore = __esm(() => {
18509
18526
  };
18510
18527
  });
18511
18528
 
18529
+ // src/drivers/vitess.ts
18530
+ var VitessDriver;
18531
+ var init_vitess = __esm(() => {
18532
+ init_mysql();
18533
+ VitessDriver = class VitessDriver extends MySQLDriver {
18534
+ getAutoIncrementClause(_column) {
18535
+ return "";
18536
+ }
18537
+ renderColumn(column) {
18538
+ if (!column.references)
18539
+ return super.renderColumn(column);
18540
+ const { references: _references, ...withoutReference } = column;
18541
+ return super.renderColumn(withoutReference);
18542
+ }
18543
+ createTable(table) {
18544
+ return super.createTable(table);
18545
+ }
18546
+ addForeignKey() {
18547
+ return "";
18548
+ }
18549
+ createMigrationsTable() {
18550
+ return `CREATE TABLE IF NOT EXISTS migrations (
18551
+ migration VARCHAR(255) NOT NULL PRIMARY KEY,
18552
+ executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
18553
+ )`;
18554
+ }
18555
+ };
18556
+ });
18557
+
18512
18558
  // src/drivers/sqlite.ts
18513
18559
  function isNumericPlanType(type) {
18514
18560
  return type === "integer" || type === "bigint" || type === "float" || type === "double" || type === "decimal";
@@ -18720,6 +18766,8 @@ function getDialectDriver(dialect) {
18720
18766
  return new MySQLDriver;
18721
18767
  case "singlestore":
18722
18768
  return new SingleStoreDriver;
18769
+ case "vitess":
18770
+ return new VitessDriver;
18723
18771
  case "sqlite":
18724
18772
  return new SQLiteDriver;
18725
18773
  default:
@@ -18730,11 +18778,13 @@ var init_drivers = __esm(() => {
18730
18778
  init_mysql();
18731
18779
  init_postgres();
18732
18780
  init_singlestore();
18781
+ init_vitess();
18733
18782
  init_sqlite();
18734
18783
  init_mysql();
18735
18784
  init_postgres();
18736
18785
  init_singlestore();
18737
18786
  init_sqlite();
18787
+ init_vitess();
18738
18788
  });
18739
18789
 
18740
18790
  // src/workspace.ts
@@ -31464,7 +31514,7 @@ function getPrefix() {
31464
31514
  }
31465
31515
  var prefix = getPrefix();
31466
31516
  // package.json
31467
- var version2 = "0.2.4";
31517
+ var version2 = "0.2.6";
31468
31518
 
31469
31519
  // bin/cli.ts
31470
31520
  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
  /**
@@ -1 +1,28 @@
1
+ /**
2
+ * Shorten a name to what the database will actually store.
3
+ *
4
+ * Truncating and appending the fingerprint of the full name keeps the result
5
+ * readable at the front - where the table and column names are - and unique at
6
+ * the back.
7
+ */
8
+ export declare function boundIdentifier(name: string, limit?: unknown): string;
9
+ /**
10
+ * The name an index has in the database.
11
+ *
12
+ * Qualified with its table when it is not already, then bounded. Both halves
13
+ * have to happen here rather than at the call sites, because the diff compares
14
+ * what the model declares against what the database reports, and those only
15
+ * agree if the same function produced both.
16
+ */
1
17
  export declare function qualifiedIndexName(tableName: string, indexName: string): string;
18
+ /**
19
+ * Postgres truncates any identifier over 63 bytes, silently, with a notice
20
+ * nobody reads. MySQL refuses one over 64 outright.
21
+ *
22
+ * A truncated index name is worse than a rejected one. The database ends up
23
+ * holding a name the model never declared, so the next diff looks for the
24
+ * declared name, does not find it, and proposes creating it - forever. That is
25
+ * exactly what "drop and recreate this index, unchanged, on every single run"
26
+ * looks like from the outside.
27
+ */
28
+ export declare const MAX_IDENTIFIER_LENGTH: 63;
@@ -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,38 @@
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, and every divergence below follows from one fact: a keyspace is
10
+ * split across shards that share nothing.
11
+ *
12
+ * - **No foreign keys.** Enforcing one would need a cross-shard read on every
13
+ * write, so vtgate rejects them in a sharded keyspace. Both forms are
14
+ * suppressed: the `ALTER TABLE … ADD CONSTRAINT` statement (`addForeignKey`)
15
+ * and the inline `REFERENCES` clause the MySQL driver emits inside a column
16
+ * definition. Missing the inline form would be the subtler bug — the table
17
+ * plan carries the reference on the column, so a `CREATE TABLE` would fail
18
+ * on its own without any FK statement being generated.
19
+ * - **No AUTO_INCREMENT.** Each shard would independently hand out the same
20
+ * values and collide. This is not a parse error, which makes it worse than
21
+ * one: the DDL succeeds and the collisions appear later, under load, as
22
+ * duplicate-key failures on inserts that were previously fine. Primary keys
23
+ * must come from the application or from a sequence table in an unsharded
24
+ * keyspace, declared in the VSchema.
25
+ *
26
+ * **Sharding is not expressed in DDL.** Unlike SingleStore, where the shard key
27
+ * is a `CREATE TABLE` clause, Vitess keeps the topology in a separate VSchema
28
+ * document that maps each table's sharding column to a vindex. So `createTable`
29
+ * here is plain MySQL minus the two constructs above, and nothing in this
30
+ * driver needs to know how a table is sharded.
31
+ */
32
+ export declare class VitessDriver extends MySQLDriver {
33
+ protected getAutoIncrementClause(_column: ColumnPlan): string;
34
+ protected renderColumn(column: ColumnPlan): string;
35
+ createTable(table: TablePlan): string;
36
+ addForeignKey(): string;
37
+ createMigrationsTable(): string;
38
+ }
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)
@@ -12093,7 +12093,7 @@ function resolveDatabaseName(dbConfig = config5.database) {
12093
12093
  return String(raw).replace(/^['"]|['"]$/g, "");
12094
12094
  }
12095
12095
  function createConnectionString(dialect, dbConfig) {
12096
- if ((dialect === "postgres" || dialect === "mysql" || dialect === "singlestore") && process21.env.DB_CONNECTION === dialect) {
12096
+ if ((dialect === "postgres" || dialect === "mysql" || dialect === "singlestore" || dialect === "vitess") && process21.env.DB_CONNECTION === dialect) {
12097
12097
  const e = process21.env;
12098
12098
  const envDb = (e.DB_DATABASE || dbConfig.database || "").replace(/^['"]|['"]$/g, "");
12099
12099
  const envUser = e.DB_USERNAME || dbConfig.username;
@@ -12114,6 +12114,7 @@ function createConnectionString(dialect, dbConfig) {
12114
12114
  return `postgres://${username}:${password}@${host}${port ? `:${port}` : ""}/${database}${sslQ}`;
12115
12115
  case "mysql":
12116
12116
  case "singlestore":
12117
+ case "vitess":
12117
12118
  return `mysql://${username}:${password}@${host}${port ? `:${port}` : ""}/${database}${sslQ}`;
12118
12119
  case "sqlite":
12119
12120
  if (database === ":memory:") {
@@ -18077,10 +18078,26 @@ export default model
18077
18078
  var init_make_model = () => {};
18078
18079
 
18079
18080
  // src/drivers/index-name.ts
18081
+ function fingerprint(value) {
18082
+ let hash = 2166136261;
18083
+ for (let i = 0;i < value.length; i++) {
18084
+ hash ^= value.charCodeAt(i);
18085
+ hash = Math.imul(hash, 16777619) >>> 0;
18086
+ }
18087
+ return hash.toString(36).padStart(7, "0").slice(-7);
18088
+ }
18089
+ function boundIdentifier(name, limit = MAX_IDENTIFIER_LENGTH) {
18090
+ if (name.length <= limit)
18091
+ return name;
18092
+ const suffix = `_${fingerprint(name)}`;
18093
+ return name.slice(0, limit - suffix.length) + suffix;
18094
+ }
18080
18095
  function qualifiedIndexName(tableName, indexName) {
18081
18096
  const prefix = `${tableName}_`;
18082
- return indexName.startsWith(prefix) ? indexName : `${prefix}${indexName}`;
18097
+ const qualified = indexName.startsWith(prefix) ? indexName : `${prefix}${indexName}`;
18098
+ return boundIdentifier(qualified);
18083
18099
  }
18100
+ var MAX_IDENTIFIER_LENGTH = 63;
18084
18101
 
18085
18102
  // src/drivers/mysql.ts
18086
18103
  class MySQLDriver {
@@ -18508,6 +18525,35 @@ var init_singlestore = __esm(() => {
18508
18525
  };
18509
18526
  });
18510
18527
 
18528
+ // src/drivers/vitess.ts
18529
+ var VitessDriver;
18530
+ var init_vitess = __esm(() => {
18531
+ init_mysql();
18532
+ VitessDriver = class VitessDriver extends MySQLDriver {
18533
+ getAutoIncrementClause(_column) {
18534
+ return "";
18535
+ }
18536
+ renderColumn(column) {
18537
+ if (!column.references)
18538
+ return super.renderColumn(column);
18539
+ const { references: _references, ...withoutReference } = column;
18540
+ return super.renderColumn(withoutReference);
18541
+ }
18542
+ createTable(table) {
18543
+ return super.createTable(table);
18544
+ }
18545
+ addForeignKey() {
18546
+ return "";
18547
+ }
18548
+ createMigrationsTable() {
18549
+ return `CREATE TABLE IF NOT EXISTS migrations (
18550
+ migration VARCHAR(255) NOT NULL PRIMARY KEY,
18551
+ executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
18552
+ )`;
18553
+ }
18554
+ };
18555
+ });
18556
+
18511
18557
  // src/drivers/sqlite.ts
18512
18558
  function isNumericPlanType(type) {
18513
18559
  return type === "integer" || type === "bigint" || type === "float" || type === "double" || type === "decimal";
@@ -18719,6 +18765,8 @@ function getDialectDriver(dialect) {
18719
18765
  return new MySQLDriver;
18720
18766
  case "singlestore":
18721
18767
  return new SingleStoreDriver;
18768
+ case "vitess":
18769
+ return new VitessDriver;
18722
18770
  case "sqlite":
18723
18771
  return new SQLiteDriver;
18724
18772
  default:
@@ -18729,11 +18777,13 @@ var init_drivers = __esm(() => {
18729
18777
  init_mysql();
18730
18778
  init_postgres();
18731
18779
  init_singlestore();
18780
+ init_vitess();
18732
18781
  init_sqlite();
18733
18782
  init_mysql();
18734
18783
  init_postgres();
18735
18784
  init_singlestore();
18736
18785
  init_sqlite();
18786
+ init_vitess();
18737
18787
  });
18738
18788
 
18739
18789
  // src/workspace.ts
@@ -29564,6 +29614,7 @@ export {
29564
29614
  browserQuery,
29565
29615
  browserAuth,
29566
29616
  applySqliteBootstrapPragmas,
29617
+ VitessDriver,
29567
29618
  SingleTableRepository,
29568
29619
  SingleTableQueryBuilder,
29569
29620
  SingleTablePatterns,
package/dist/types.d.ts CHANGED
@@ -293,7 +293,11 @@ export declare interface UnsafeOptions {
293
293
  * but its DDL adds distributed-table concepts (`SHARD KEY`, `SORT KEY`,
294
294
  * `ROWSTORE`/columnstore) and drops foreign keys — handled by the dedicated
295
295
  * `SingleStoreDriver`.
296
+ * - 'vitess': Sharded MySQL behind vtgate. Shares MySQL's wire protocol and
297
+ * DML (see `isMysqlLike`), but a sharded keyspace rejects foreign keys and
298
+ * AUTO_INCREMENT, and its sharding topology lives in a separate VSchema
299
+ * document rather than in DDL — handled by the dedicated `VitessDriver`.
296
300
  * - 'sqlite': Lightweight engine; some features are limited or emulated
297
301
  * - 'browser': Browser-compatible mode that uses fetch() API calls instead of direct database connections
298
302
  */
299
- export type SupportedDialect = 'postgres' | 'mysql' | 'singlestore' | 'sqlite' | 'browser';
303
+ 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.4",
4
+ "version": "0.2.6",
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",