turbine-orm 0.50.0 → 0.51.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.
Files changed (186) hide show
  1. package/README.md +66 -66
  2. package/dist/adapters/cockroachdb.d.ts +5 -5
  3. package/dist/adapters/cockroachdb.js +10 -10
  4. package/dist/adapters/index.d.ts +5 -5
  5. package/dist/adapters/index.js +7 -7
  6. package/dist/adapters/yugabytedb.d.ts +7 -7
  7. package/dist/adapters/yugabytedb.js +10 -10
  8. package/dist/cjs/adapters/cockroachdb.d.ts +5 -5
  9. package/dist/cjs/adapters/cockroachdb.js +10 -10
  10. package/dist/cjs/adapters/index.d.ts +5 -5
  11. package/dist/cjs/adapters/index.js +7 -7
  12. package/dist/cjs/adapters/yugabytedb.d.ts +7 -7
  13. package/dist/cjs/adapters/yugabytedb.js +10 -10
  14. package/dist/cjs/cli/config.d.ts +13 -2
  15. package/dist/cjs/cli/config.js +3 -2
  16. package/dist/cjs/cli/destructive.d.ts +1 -1
  17. package/dist/cjs/cli/destructive.js +1 -1
  18. package/dist/cjs/cli/index.d.ts +10 -10
  19. package/dist/cjs/cli/index.js +49 -45
  20. package/dist/cjs/cli/loader.d.ts +7 -7
  21. package/dist/cjs/cli/loader.js +9 -9
  22. package/dist/cjs/cli/mcp.js +4 -4
  23. package/dist/cjs/cli/migrate.d.ts +5 -5
  24. package/dist/cjs/cli/migrate.js +11 -11
  25. package/dist/cjs/cli/studio-ui.generated.js +1 -1
  26. package/dist/cjs/cli/ui.d.ts +2 -2
  27. package/dist/cjs/cli/ui.js +2 -2
  28. package/dist/cjs/client.d.ts +49 -38
  29. package/dist/cjs/client.js +57 -56
  30. package/dist/cjs/dialect.d.ts +62 -18
  31. package/dist/cjs/dialect.js +40 -2
  32. package/dist/cjs/errors.d.ts +5 -5
  33. package/dist/cjs/errors.js +11 -11
  34. package/dist/cjs/generate.d.ts +6 -6
  35. package/dist/cjs/generate.js +31 -29
  36. package/dist/cjs/index-advisor.d.ts +5 -5
  37. package/dist/cjs/index-advisor.js +0 -0
  38. package/dist/cjs/index.d.ts +1 -1
  39. package/dist/cjs/index.js +7 -7
  40. package/dist/cjs/introspect.d.ts +35 -9
  41. package/dist/cjs/introspect.js +83 -32
  42. package/dist/cjs/mssql.d.ts +11 -11
  43. package/dist/cjs/mssql.js +64 -29
  44. package/dist/cjs/mysql.d.ts +8 -8
  45. package/dist/cjs/mysql.js +61 -23
  46. package/dist/cjs/nested-write.d.ts +21 -2
  47. package/dist/cjs/nested-write.js +51 -14
  48. package/dist/cjs/optional-peer-import.cjs +7 -7
  49. package/dist/cjs/optional-peer-import.d.cts +7 -7
  50. package/dist/cjs/pipeline-submittable.d.ts +2 -2
  51. package/dist/cjs/pipeline-submittable.js +6 -6
  52. package/dist/cjs/pipeline.d.ts +1 -1
  53. package/dist/cjs/pipeline.js +4 -4
  54. package/dist/cjs/powdb-introspect.d.ts +1 -1
  55. package/dist/cjs/powdb-introspect.js +1 -1
  56. package/dist/cjs/powdb.d.ts +28 -28
  57. package/dist/cjs/powdb.js +66 -66
  58. package/dist/cjs/powql.d.ts +27 -27
  59. package/dist/cjs/powql.js +73 -52
  60. package/dist/cjs/query/aggregates.d.ts +1 -1
  61. package/dist/cjs/query/aggregates.js +5 -5
  62. package/dist/cjs/query/batched-loader.d.ts +11 -11
  63. package/dist/cjs/query/batched-loader.js +24 -24
  64. package/dist/cjs/query/builder.d.ts +39 -21
  65. package/dist/cjs/query/builder.js +99 -57
  66. package/dist/cjs/query/compound-unique.d.ts +1 -1
  67. package/dist/cjs/query/compound-unique.js +0 -0
  68. package/dist/cjs/query/deferred.d.ts +12 -6
  69. package/dist/cjs/query/deferred.js +1 -1
  70. package/dist/cjs/query/filters.d.ts +31 -11
  71. package/dist/cjs/query/filters.js +67 -14
  72. package/dist/cjs/query/index.d.ts +1 -1
  73. package/dist/cjs/query/index.js +1 -1
  74. package/dist/cjs/query/relations.d.ts +9 -9
  75. package/dist/cjs/query/relations.js +164 -57
  76. package/dist/cjs/query/types.d.ts +86 -35
  77. package/dist/cjs/query/types.js +1 -1
  78. package/dist/cjs/query/utils.d.ts +27 -10
  79. package/dist/cjs/query/utils.js +86 -14
  80. package/dist/cjs/query/where.d.ts +47 -28
  81. package/dist/cjs/query/where.js +130 -31
  82. package/dist/cjs/query/writes.d.ts +24 -5
  83. package/dist/cjs/query/writes.js +102 -13
  84. package/dist/cjs/realtime.d.ts +7 -7
  85. package/dist/cjs/realtime.js +9 -9
  86. package/dist/cjs/schema-builder.d.ts +18 -7
  87. package/dist/cjs/schema-builder.js +17 -10
  88. package/dist/cjs/schema-metadata.d.ts +3 -3
  89. package/dist/cjs/schema-metadata.js +9 -9
  90. package/dist/cjs/schema-sql.d.ts +9 -9
  91. package/dist/cjs/schema-sql.js +20 -20
  92. package/dist/cjs/schema.d.ts +19 -9
  93. package/dist/cjs/schema.js +6 -6
  94. package/dist/cjs/serverless.d.ts +15 -15
  95. package/dist/cjs/serverless.js +16 -16
  96. package/dist/cjs/sqlite.d.ts +8 -8
  97. package/dist/cjs/sqlite.js +53 -22
  98. package/dist/cjs/typed-sql.d.ts +4 -4
  99. package/dist/cjs/typed-sql.js +5 -5
  100. package/dist/cli/config.d.ts +13 -2
  101. package/dist/cli/config.js +3 -2
  102. package/dist/cli/destructive.d.ts +1 -1
  103. package/dist/cli/destructive.js +1 -1
  104. package/dist/cli/index.d.ts +10 -10
  105. package/dist/cli/index.js +49 -45
  106. package/dist/cli/loader.d.ts +7 -7
  107. package/dist/cli/loader.js +9 -9
  108. package/dist/cli/mcp.js +4 -4
  109. package/dist/cli/migrate.d.ts +5 -5
  110. package/dist/cli/migrate.js +11 -11
  111. package/dist/cli/studio-ui.generated.js +1 -1
  112. package/dist/cli/ui.d.ts +2 -2
  113. package/dist/cli/ui.js +2 -2
  114. package/dist/client.d.ts +49 -38
  115. package/dist/client.js +57 -56
  116. package/dist/dialect.d.ts +62 -18
  117. package/dist/dialect.js +40 -2
  118. package/dist/errors.d.ts +5 -5
  119. package/dist/errors.js +11 -11
  120. package/dist/generate.d.ts +6 -6
  121. package/dist/generate.js +31 -29
  122. package/dist/index-advisor.d.ts +5 -5
  123. package/dist/index-advisor.js +0 -0
  124. package/dist/index.d.ts +1 -1
  125. package/dist/index.js +7 -7
  126. package/dist/introspect.d.ts +35 -9
  127. package/dist/introspect.js +82 -32
  128. package/dist/mssql.d.ts +11 -11
  129. package/dist/mssql.js +64 -29
  130. package/dist/mysql.d.ts +8 -8
  131. package/dist/mysql.js +61 -23
  132. package/dist/nested-write.d.ts +21 -2
  133. package/dist/nested-write.js +51 -14
  134. package/dist/optional-peer-import.cjs +7 -7
  135. package/dist/optional-peer-import.d.cts +7 -7
  136. package/dist/pipeline-submittable.d.ts +2 -2
  137. package/dist/pipeline-submittable.js +6 -6
  138. package/dist/pipeline.d.ts +1 -1
  139. package/dist/pipeline.js +4 -4
  140. package/dist/powdb-introspect.d.ts +1 -1
  141. package/dist/powdb-introspect.js +1 -1
  142. package/dist/powdb.d.ts +28 -28
  143. package/dist/powdb.js +66 -66
  144. package/dist/powql.d.ts +27 -27
  145. package/dist/powql.js +73 -52
  146. package/dist/query/aggregates.d.ts +1 -1
  147. package/dist/query/aggregates.js +5 -5
  148. package/dist/query/batched-loader.d.ts +11 -11
  149. package/dist/query/batched-loader.js +24 -24
  150. package/dist/query/builder.d.ts +39 -21
  151. package/dist/query/builder.js +100 -58
  152. package/dist/query/compound-unique.d.ts +1 -1
  153. package/dist/query/compound-unique.js +0 -0
  154. package/dist/query/deferred.d.ts +12 -6
  155. package/dist/query/deferred.js +1 -1
  156. package/dist/query/filters.d.ts +31 -11
  157. package/dist/query/filters.js +66 -13
  158. package/dist/query/index.d.ts +1 -1
  159. package/dist/query/index.js +1 -1
  160. package/dist/query/relations.d.ts +9 -9
  161. package/dist/query/relations.js +165 -58
  162. package/dist/query/types.d.ts +86 -35
  163. package/dist/query/types.js +1 -1
  164. package/dist/query/utils.d.ts +27 -10
  165. package/dist/query/utils.js +84 -14
  166. package/dist/query/where.d.ts +47 -28
  167. package/dist/query/where.js +129 -32
  168. package/dist/query/writes.d.ts +24 -5
  169. package/dist/query/writes.js +101 -13
  170. package/dist/realtime.d.ts +7 -7
  171. package/dist/realtime.js +9 -9
  172. package/dist/schema-builder.d.ts +18 -7
  173. package/dist/schema-builder.js +17 -10
  174. package/dist/schema-metadata.d.ts +3 -3
  175. package/dist/schema-metadata.js +9 -9
  176. package/dist/schema-sql.d.ts +9 -9
  177. package/dist/schema-sql.js +20 -20
  178. package/dist/schema.d.ts +19 -9
  179. package/dist/schema.js +6 -6
  180. package/dist/serverless.d.ts +15 -15
  181. package/dist/serverless.js +16 -16
  182. package/dist/sqlite.d.ts +8 -8
  183. package/dist/sqlite.js +53 -22
  184. package/dist/typed-sql.d.ts +4 -4
  185. package/dist/typed-sql.js +5 -5
  186. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * turbine-orm YugabyteDB adapter
2
+ * turbine-orm, YugabyteDB adapter
3
3
  *
4
4
  * YugabyteDB is a distributed SQL database that speaks the PostgreSQL wire
5
5
  * protocol. It supports most PostgreSQL features including json_agg,
@@ -7,28 +7,28 @@
7
7
  *
8
8
  * Key differences from PostgreSQL that this adapter addresses:
9
9
  *
10
- * 1. **Advisory locks are per-node** `pg_try_advisory_lock()` is supported
10
+ * 1. **Advisory locks are per-node**, `pg_try_advisory_lock()` is supported
11
11
  * but only scoped to the tserver node handling the connection. In a
12
12
  * multi-node cluster, two concurrent `turbine migrate` runs routed to
13
13
  * different nodes would both acquire the "same" advisory lock. This adapter
14
14
  * provides a table-based distributed lock using `SELECT FOR UPDATE NOWAIT`
15
15
  * which is cluster-wide via YugabyteDB's distributed transactions.
16
16
  *
17
- * 2. **Sequences may have gaps** YugabyteDB uses distributed sequences.
17
+ * 2. **Sequences may have gaps**, YugabyteDB uses distributed sequences.
18
18
  * SERIAL/BIGSERIAL columns work correctly but may produce non-contiguous
19
19
  * IDs under concurrent inserts. This is purely cosmetic and does not affect
20
20
  * Turbine's behavior.
21
21
  *
22
- * 3. **pg_catalog** Mostly complete. `pg_indexes`, `pg_type`, `pg_enum`,
22
+ * 3. **pg_catalog**, Mostly complete. `pg_indexes`, `pg_type`, `pg_enum`,
23
23
  * `information_schema.columns` all work. Row estimate via `pg_class.reltuples`
24
24
  * may be stale or zero on recently created tables (YugabyteDB's stats
25
25
  * collection is asynchronous). This adapter provides an override that
26
26
  * falls back to `yb_table_properties` when available.
27
27
  *
28
28
  * Features that work identically to PostgreSQL (no adapter override needed):
29
- * - `json_agg` / `json_build_object` fully supported
30
- * - Correlated subqueries fully supported
31
- * - `COALESCE`, `LIMIT`, `OFFSET`, `ORDER BY` fully supported
29
+ * - `json_agg` / `json_build_object`, fully supported
30
+ * - Correlated subqueries, fully supported
31
+ * - `COALESCE`, `LIMIT`, `OFFSET`, `ORDER BY`, fully supported
32
32
  * - `information_schema` for table/column/constraint introspection
33
33
  * - Extended query protocol (parameterized queries, pipeline batching)
34
34
  * - Transactions with `SAVEPOINT` (nested transactions)
@@ -1,5 +1,5 @@
1
1
  /**
2
- * turbine-orm YugabyteDB adapter
2
+ * turbine-orm, YugabyteDB adapter
3
3
  *
4
4
  * YugabyteDB is a distributed SQL database that speaks the PostgreSQL wire
5
5
  * protocol. It supports most PostgreSQL features including json_agg,
@@ -7,28 +7,28 @@
7
7
  *
8
8
  * Key differences from PostgreSQL that this adapter addresses:
9
9
  *
10
- * 1. **Advisory locks are per-node** `pg_try_advisory_lock()` is supported
10
+ * 1. **Advisory locks are per-node**, `pg_try_advisory_lock()` is supported
11
11
  * but only scoped to the tserver node handling the connection. In a
12
12
  * multi-node cluster, two concurrent `turbine migrate` runs routed to
13
13
  * different nodes would both acquire the "same" advisory lock. This adapter
14
14
  * provides a table-based distributed lock using `SELECT FOR UPDATE NOWAIT`
15
15
  * which is cluster-wide via YugabyteDB's distributed transactions.
16
16
  *
17
- * 2. **Sequences may have gaps** YugabyteDB uses distributed sequences.
17
+ * 2. **Sequences may have gaps**, YugabyteDB uses distributed sequences.
18
18
  * SERIAL/BIGSERIAL columns work correctly but may produce non-contiguous
19
19
  * IDs under concurrent inserts. This is purely cosmetic and does not affect
20
20
  * Turbine's behavior.
21
21
  *
22
- * 3. **pg_catalog** Mostly complete. `pg_indexes`, `pg_type`, `pg_enum`,
22
+ * 3. **pg_catalog**, Mostly complete. `pg_indexes`, `pg_type`, `pg_enum`,
23
23
  * `information_schema.columns` all work. Row estimate via `pg_class.reltuples`
24
24
  * may be stale or zero on recently created tables (YugabyteDB's stats
25
25
  * collection is asynchronous). This adapter provides an override that
26
26
  * falls back to `yb_table_properties` when available.
27
27
  *
28
28
  * Features that work identically to PostgreSQL (no adapter override needed):
29
- * - `json_agg` / `json_build_object` fully supported
30
- * - Correlated subqueries fully supported
31
- * - `COALESCE`, `LIMIT`, `OFFSET`, `ORDER BY` fully supported
29
+ * - `json_agg` / `json_build_object`, fully supported
30
+ * - Correlated subqueries, fully supported
31
+ * - `COALESCE`, `LIMIT`, `OFFSET`, `ORDER BY`, fully supported
32
32
  * - `information_schema` for table/column/constraint introspection
33
33
  * - Extended query protocol (parameterized queries, pipeline batching)
34
34
  * - Transactions with `SAVEPOINT` (nested transactions)
@@ -105,7 +105,7 @@ export const yugabytedb = {
105
105
  await client.query(`SELECT lock_id FROM "${LOCK_TABLE}" WHERE lock_id = $1 FOR UPDATE NOWAIT`, [lockId]);
106
106
  // Update acquisition metadata for observability
107
107
  await client.query(`UPDATE "${LOCK_TABLE}" SET acquired_at = now(), acquired_by = current_user WHERE lock_id = $1`, [lockId]);
108
- // Leave the transaction open lock is held until releaseLock()
108
+ // Leave the transaction open, lock is held until releaseLock()
109
109
  return true;
110
110
  }
111
111
  catch (err) {
@@ -120,7 +120,7 @@ export const yugabytedb = {
120
120
  }
121
121
  return false;
122
122
  }
123
- // Any other error rollback and re-throw
123
+ // Any other error, rollback and re-throw
124
124
  try {
125
125
  await client.query('ROLLBACK');
126
126
  }
@@ -136,7 +136,7 @@ export const yugabytedb = {
136
136
  await client.query('COMMIT');
137
137
  }
138
138
  catch {
139
- // If commit fails, try rollback either way the lock is released
139
+ // If commit fails, try rollback, either way the lock is released
140
140
  try {
141
141
  await client.query('ROLLBACK');
142
142
  }
@@ -1,20 +1,20 @@
1
1
  /**
2
- * turbine-orm CockroachDB adapter
2
+ * turbine-orm, CockroachDB adapter
3
3
  *
4
4
  * CockroachDB speaks the PostgreSQL wire protocol but has key differences:
5
5
  *
6
- * 1. **No advisory locks** `pg_try_advisory_lock()` is not supported.
6
+ * 1. **No advisory locks**, `pg_try_advisory_lock()` is not supported.
7
7
  * This adapter uses a `_turbine_lock` table with `SELECT FOR UPDATE NOWAIT`
8
8
  * as a concurrency mechanism for migrations.
9
9
  *
10
- * 2. **No `SET LOCAL statement_timeout`** CockroachDB uses
10
+ * 2. **No `SET LOCAL statement_timeout`**, CockroachDB uses
11
11
  * `SET transaction_timeout` (v23.1+) for per-transaction time limits.
12
12
  *
13
- * 3. **`pg_indexes` view** CockroachDB supports `pg_indexes` since v22.1
13
+ * 3. **`pg_indexes` view**, CockroachDB supports `pg_indexes` since v22.1
14
14
  * but the `indexdef` column may not match Postgres exactly. We use
15
15
  * `SHOW INDEXES` as a more reliable alternative.
16
16
  *
17
- * 4. **`pg_class.reltuples`** Not reliable in CockroachDB. We use
17
+ * 4. **`pg_class.reltuples`**, Not reliable in CockroachDB. We use
18
18
  * `crdb_internal.table_row_statistics` for row estimates.
19
19
  *
20
20
  * Known limitations with Turbine on CockroachDB:
@@ -1,21 +1,21 @@
1
1
  "use strict";
2
2
  /**
3
- * turbine-orm CockroachDB adapter
3
+ * turbine-orm, CockroachDB adapter
4
4
  *
5
5
  * CockroachDB speaks the PostgreSQL wire protocol but has key differences:
6
6
  *
7
- * 1. **No advisory locks** `pg_try_advisory_lock()` is not supported.
7
+ * 1. **No advisory locks**, `pg_try_advisory_lock()` is not supported.
8
8
  * This adapter uses a `_turbine_lock` table with `SELECT FOR UPDATE NOWAIT`
9
9
  * as a concurrency mechanism for migrations.
10
10
  *
11
- * 2. **No `SET LOCAL statement_timeout`** CockroachDB uses
11
+ * 2. **No `SET LOCAL statement_timeout`**, CockroachDB uses
12
12
  * `SET transaction_timeout` (v23.1+) for per-transaction time limits.
13
13
  *
14
- * 3. **`pg_indexes` view** CockroachDB supports `pg_indexes` since v22.1
14
+ * 3. **`pg_indexes` view**, CockroachDB supports `pg_indexes` since v22.1
15
15
  * but the `indexdef` column may not match Postgres exactly. We use
16
16
  * `SHOW INDEXES` as a more reliable alternative.
17
17
  *
18
- * 4. **`pg_class.reltuples`** Not reliable in CockroachDB. We use
18
+ * 4. **`pg_class.reltuples`**, Not reliable in CockroachDB. We use
19
19
  * `crdb_internal.table_row_statistics` for row estimates.
20
20
  *
21
21
  * Known limitations with Turbine on CockroachDB:
@@ -72,7 +72,7 @@ const SQL_INDEXES_CRDB = `
72
72
  `;
73
73
  /**
74
74
  * Row estimates using crdb_internal. Falls back gracefully if the view
75
- * doesn't exist (permissions issue) returns 0 rows in that case.
75
+ * doesn't exist (permissions issue), returns 0 rows in that case.
76
76
  */
77
77
  const SQL_ROW_ESTIMATES_CRDB = `
78
78
  SELECT
@@ -85,7 +85,7 @@ const SQL_ROW_ESTIMATES_CRDB = `
85
85
  AND t.database_name = current_database()
86
86
  `;
87
87
  /**
88
- * Enum introspection CockroachDB supports pg_type/pg_enum since v20.2.
88
+ * Enum introspection, CockroachDB supports pg_type/pg_enum since v20.2.
89
89
  * The standard query works, but we include it explicitly so the override
90
90
  * mechanism is complete.
91
91
  */
@@ -110,13 +110,13 @@ exports.cockroachdb = {
110
110
  await client.query(CREATE_LOCK_TABLE_SQL);
111
111
  // Insert the lock row if it doesn't exist (idempotent)
112
112
  await client.query(`INSERT INTO "${LOCK_TABLE}" (lock_id) VALUES ($1) ON CONFLICT (lock_id) DO NOTHING`, [lockId]);
113
- // Try to acquire the row lock with NOWAIT fails immediately if held
113
+ // Try to acquire the row lock with NOWAIT, fails immediately if held
114
114
  try {
115
115
  await client.query('BEGIN');
116
116
  await client.query(`SELECT lock_id FROM "${LOCK_TABLE}" WHERE lock_id = $1 FOR UPDATE NOWAIT`, [lockId]);
117
117
  // Update the acquired metadata
118
118
  await client.query(`UPDATE "${LOCK_TABLE}" SET acquired_at = now(), acquired_by = current_user WHERE lock_id = $1`, [lockId]);
119
- // Note: we leave the transaction OPEN the lock is held until
119
+ // Note: we leave the transaction OPEN, the lock is held until
120
120
  // releaseLock() commits or rolls back.
121
121
  return true;
122
122
  }
@@ -132,7 +132,7 @@ exports.cockroachdb = {
132
132
  }
133
133
  return false;
134
134
  }
135
- // Any other error rollback and re-throw
135
+ // Any other error, rollback and re-throw
136
136
  try {
137
137
  await client.query('ROLLBACK');
138
138
  }
@@ -1,9 +1,9 @@
1
1
  /**
2
- * turbine-orm Database adapter interface
2
+ * turbine-orm, Database adapter interface
3
3
  *
4
4
  * Adapters allow Turbine to work with PostgreSQL-compatible databases that
5
5
  * have subtle differences (e.g. CockroachDB, YugabyteDB). The default
6
- * behavior remains standard PostgreSQL adapters only override specific
6
+ * behavior remains standard PostgreSQL, adapters only override specific
7
7
  * operations where compatibility gaps exist.
8
8
  *
9
9
  * @example
@@ -57,9 +57,9 @@ export interface DatabaseAdapter {
57
57
  * Generate the SQL to set a statement timeout within a transaction.
58
58
  * PostgreSQL uses `SELECT set_config('statement_timeout', $1, true)`.
59
59
  * CockroachDB uses `SELECT set_config('transaction_timeout', $1, true)` (v23.1+).
60
- * (`SET LOCAL ... = $1` is a syntax error SET takes no bind params.)
60
+ * (`SET LOCAL ... = $1` is a syntax error, SET takes no bind params.)
61
61
  *
62
- * @param seconds timeout in seconds
62
+ * @param seconds, timeout in seconds
63
63
  * @returns an object with the parameterized SQL and its bound values
64
64
  */
65
65
  statementTimeout?(seconds: number): {
@@ -79,7 +79,7 @@ export interface DatabaseAdapter {
79
79
  export declare const postgresql: DatabaseAdapter;
80
80
  /**
81
81
  * Google AlloyDB adapter. AlloyDB is PostgreSQL with Google's columnar storage
82
- * engine. It is wire-protocol and catalog-compatible no adapter overrides
82
+ * engine. It is wire-protocol and catalog-compatible, no adapter overrides
83
83
  * are needed. All Turbine features (json_agg, advisory locks, introspection,
84
84
  * migrations) work identically to standard PostgreSQL.
85
85
  *
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  /**
3
- * turbine-orm Database adapter interface
3
+ * turbine-orm, Database adapter interface
4
4
  *
5
5
  * Adapters allow Turbine to work with PostgreSQL-compatible databases that
6
6
  * have subtle differences (e.g. CockroachDB, YugabyteDB). The default
7
- * behavior remains standard PostgreSQL adapters only override specific
7
+ * behavior remains standard PostgreSQL, adapters only override specific
8
8
  * operations where compatibility gaps exist.
9
9
  *
10
10
  * @example
@@ -18,7 +18,7 @@
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.yugabytedb = exports.cockroachdb = exports.timescale = exports.alloydb = exports.postgresql = void 0;
20
20
  // ---------------------------------------------------------------------------
21
- // Default PostgreSQL adapter (no-op standard behavior)
21
+ // Default PostgreSQL adapter (no-op, standard behavior)
22
22
  // ---------------------------------------------------------------------------
23
23
  /**
24
24
  * The default PostgreSQL adapter. Uses pg_try_advisory_lock, standard
@@ -34,18 +34,18 @@ exports.postgresql = {
34
34
  await client.query(`SELECT pg_advisory_unlock($1)`, [lockId]);
35
35
  },
36
36
  statementTimeout(seconds) {
37
- // `SET LOCAL ... = $1` is a Postgres syntax error SET does not accept
37
+ // `SET LOCAL ... = $1` is a Postgres syntax error, SET does not accept
38
38
  // bind parameters. `set_config(name, value, is_local=true)` is the
39
39
  // parameterizable, transaction-local equivalent.
40
40
  return { sql: `SELECT set_config('statement_timeout', $1, true)`, params: [`${seconds}s`] };
41
41
  },
42
42
  };
43
43
  // ---------------------------------------------------------------------------
44
- // AlloyDB fully PostgreSQL-compatible, no adapter logic needed
44
+ // AlloyDB, fully PostgreSQL-compatible, no adapter logic needed
45
45
  // ---------------------------------------------------------------------------
46
46
  /**
47
47
  * Google AlloyDB adapter. AlloyDB is PostgreSQL with Google's columnar storage
48
- * engine. It is wire-protocol and catalog-compatible no adapter overrides
48
+ * engine. It is wire-protocol and catalog-compatible, no adapter overrides
49
49
  * are needed. All Turbine features (json_agg, advisory locks, introspection,
50
50
  * migrations) work identically to standard PostgreSQL.
51
51
  *
@@ -61,7 +61,7 @@ exports.alloydb = {
61
61
  name: 'alloydb',
62
62
  };
63
63
  // ---------------------------------------------------------------------------
64
- // TimescaleDB PostgreSQL extension, fully compatible
64
+ // TimescaleDB, PostgreSQL extension, fully compatible
65
65
  // ---------------------------------------------------------------------------
66
66
  /**
67
67
  * TimescaleDB adapter. Timescale is a PostgreSQL extension that adds
@@ -1,5 +1,5 @@
1
1
  /**
2
- * turbine-orm YugabyteDB adapter
2
+ * turbine-orm, YugabyteDB adapter
3
3
  *
4
4
  * YugabyteDB is a distributed SQL database that speaks the PostgreSQL wire
5
5
  * protocol. It supports most PostgreSQL features including json_agg,
@@ -7,28 +7,28 @@
7
7
  *
8
8
  * Key differences from PostgreSQL that this adapter addresses:
9
9
  *
10
- * 1. **Advisory locks are per-node** `pg_try_advisory_lock()` is supported
10
+ * 1. **Advisory locks are per-node**, `pg_try_advisory_lock()` is supported
11
11
  * but only scoped to the tserver node handling the connection. In a
12
12
  * multi-node cluster, two concurrent `turbine migrate` runs routed to
13
13
  * different nodes would both acquire the "same" advisory lock. This adapter
14
14
  * provides a table-based distributed lock using `SELECT FOR UPDATE NOWAIT`
15
15
  * which is cluster-wide via YugabyteDB's distributed transactions.
16
16
  *
17
- * 2. **Sequences may have gaps** YugabyteDB uses distributed sequences.
17
+ * 2. **Sequences may have gaps**, YugabyteDB uses distributed sequences.
18
18
  * SERIAL/BIGSERIAL columns work correctly but may produce non-contiguous
19
19
  * IDs under concurrent inserts. This is purely cosmetic and does not affect
20
20
  * Turbine's behavior.
21
21
  *
22
- * 3. **pg_catalog** Mostly complete. `pg_indexes`, `pg_type`, `pg_enum`,
22
+ * 3. **pg_catalog**, Mostly complete. `pg_indexes`, `pg_type`, `pg_enum`,
23
23
  * `information_schema.columns` all work. Row estimate via `pg_class.reltuples`
24
24
  * may be stale or zero on recently created tables (YugabyteDB's stats
25
25
  * collection is asynchronous). This adapter provides an override that
26
26
  * falls back to `yb_table_properties` when available.
27
27
  *
28
28
  * Features that work identically to PostgreSQL (no adapter override needed):
29
- * - `json_agg` / `json_build_object` fully supported
30
- * - Correlated subqueries fully supported
31
- * - `COALESCE`, `LIMIT`, `OFFSET`, `ORDER BY` fully supported
29
+ * - `json_agg` / `json_build_object`, fully supported
30
+ * - Correlated subqueries, fully supported
31
+ * - `COALESCE`, `LIMIT`, `OFFSET`, `ORDER BY`, fully supported
32
32
  * - `information_schema` for table/column/constraint introspection
33
33
  * - Extended query protocol (parameterized queries, pipeline batching)
34
34
  * - Transactions with `SAVEPOINT` (nested transactions)
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * turbine-orm YugabyteDB adapter
3
+ * turbine-orm, YugabyteDB adapter
4
4
  *
5
5
  * YugabyteDB is a distributed SQL database that speaks the PostgreSQL wire
6
6
  * protocol. It supports most PostgreSQL features including json_agg,
@@ -8,28 +8,28 @@
8
8
  *
9
9
  * Key differences from PostgreSQL that this adapter addresses:
10
10
  *
11
- * 1. **Advisory locks are per-node** `pg_try_advisory_lock()` is supported
11
+ * 1. **Advisory locks are per-node**, `pg_try_advisory_lock()` is supported
12
12
  * but only scoped to the tserver node handling the connection. In a
13
13
  * multi-node cluster, two concurrent `turbine migrate` runs routed to
14
14
  * different nodes would both acquire the "same" advisory lock. This adapter
15
15
  * provides a table-based distributed lock using `SELECT FOR UPDATE NOWAIT`
16
16
  * which is cluster-wide via YugabyteDB's distributed transactions.
17
17
  *
18
- * 2. **Sequences may have gaps** YugabyteDB uses distributed sequences.
18
+ * 2. **Sequences may have gaps**, YugabyteDB uses distributed sequences.
19
19
  * SERIAL/BIGSERIAL columns work correctly but may produce non-contiguous
20
20
  * IDs under concurrent inserts. This is purely cosmetic and does not affect
21
21
  * Turbine's behavior.
22
22
  *
23
- * 3. **pg_catalog** Mostly complete. `pg_indexes`, `pg_type`, `pg_enum`,
23
+ * 3. **pg_catalog**, Mostly complete. `pg_indexes`, `pg_type`, `pg_enum`,
24
24
  * `information_schema.columns` all work. Row estimate via `pg_class.reltuples`
25
25
  * may be stale or zero on recently created tables (YugabyteDB's stats
26
26
  * collection is asynchronous). This adapter provides an override that
27
27
  * falls back to `yb_table_properties` when available.
28
28
  *
29
29
  * Features that work identically to PostgreSQL (no adapter override needed):
30
- * - `json_agg` / `json_build_object` fully supported
31
- * - Correlated subqueries fully supported
32
- * - `COALESCE`, `LIMIT`, `OFFSET`, `ORDER BY` fully supported
30
+ * - `json_agg` / `json_build_object`, fully supported
31
+ * - Correlated subqueries, fully supported
32
+ * - `COALESCE`, `LIMIT`, `OFFSET`, `ORDER BY`, fully supported
33
33
  * - `information_schema` for table/column/constraint introspection
34
34
  * - Extended query protocol (parameterized queries, pipeline batching)
35
35
  * - Transactions with `SAVEPOINT` (nested transactions)
@@ -108,7 +108,7 @@ exports.yugabytedb = {
108
108
  await client.query(`SELECT lock_id FROM "${LOCK_TABLE}" WHERE lock_id = $1 FOR UPDATE NOWAIT`, [lockId]);
109
109
  // Update acquisition metadata for observability
110
110
  await client.query(`UPDATE "${LOCK_TABLE}" SET acquired_at = now(), acquired_by = current_user WHERE lock_id = $1`, [lockId]);
111
- // Leave the transaction open lock is held until releaseLock()
111
+ // Leave the transaction open, lock is held until releaseLock()
112
112
  return true;
113
113
  }
114
114
  catch (err) {
@@ -123,7 +123,7 @@ exports.yugabytedb = {
123
123
  }
124
124
  return false;
125
125
  }
126
- // Any other error rollback and re-throw
126
+ // Any other error, rollback and re-throw
127
127
  try {
128
128
  await client.query('ROLLBACK');
129
129
  }
@@ -139,7 +139,7 @@ exports.yugabytedb = {
139
139
  await client.query('COMMIT');
140
140
  }
141
141
  catch {
142
- // If commit fails, try rollback either way the lock is released
142
+ // If commit fails, try rollback, either way the lock is released
143
143
  try {
144
144
  await client.query('ROLLBACK');
145
145
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * turbine-orm CLI Configuration file support
2
+ * turbine-orm CLI, Configuration file support
3
3
  *
4
4
  * Loads turbine.config.ts (or .js/.mjs) via dynamic import.
5
5
  * Falls back to CLI args and environment variables.
@@ -15,6 +15,15 @@ export interface TurbineCliConfig {
15
15
  include?: string[];
16
16
  /** Tables to exclude */
17
17
  exclude?: string[];
18
+ /**
19
+ * Rename derived relations, as `{ table: { derivedName: desiredName } }`.
20
+ *
21
+ * Relation names are composed by introspection (a database does not name its
22
+ * relationships), so two foreign keys to the same table produce names nobody
23
+ * would predict, and a port from another ORM that named them differently has
24
+ * to hand-edit every call site. A typo here is an error, not a silent no-op.
25
+ */
26
+ relationNames?: Record<string, Record<string, string>>;
18
27
  /**
19
28
  * Extension for the generated `index.ts` sibling imports (F3):
20
29
  * `'js'` (`./types.js`), `'none'` (`./types`), or `'auto'` (default:
@@ -69,7 +78,7 @@ export type TurbineConfig = TurbineCliConfig;
69
78
  * path rather than a Postgres schema name? `schema` is the Postgres namespace
70
79
  * to introspect (default `public`); the schema-builder file goes in `schemaFile`.
71
80
  * A value containing a path separator or a JS/TS extension is almost certainly a
72
- * mis-set `schemaFile` introspecting `WHERE table_schema = './turbine/schema.ts'`
81
+ * mis-set `schemaFile`, introspecting `WHERE table_schema = './turbine/schema.ts'`
73
82
  * silently matches zero tables. Used by `turbine generate` to fail loudly.
74
83
  */
75
84
  export declare function looksLikeSchemaFilePath(schema: string): boolean;
@@ -156,6 +165,8 @@ export interface ResolvedConfig {
156
165
  keepColumnNames: boolean;
157
166
  /** Resolved opt-out of the unique-FK → hasOne introspection flip (F2). */
158
167
  legacyToManyUniques: boolean;
168
+ /** Resolved derived-relation rename map, or undefined when none is declared. */
169
+ relationNames?: Record<string, Record<string, string>>;
159
170
  }
160
171
  export interface CliOverrides {
161
172
  url?: string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * turbine-orm CLI Configuration file support
3
+ * turbine-orm CLI, Configuration file support
4
4
  *
5
5
  * Loads turbine.config.ts (or .js/.mjs) via dynamic import.
6
6
  * Falls back to CLI args and environment variables.
@@ -57,7 +57,7 @@ const node_url_1 = require("node:url");
57
57
  * path rather than a Postgres schema name? `schema` is the Postgres namespace
58
58
  * to introspect (default `public`); the schema-builder file goes in `schemaFile`.
59
59
  * A value containing a path separator or a JS/TS extension is almost certainly a
60
- * mis-set `schemaFile` introspecting `WHERE table_schema = './turbine/schema.ts'`
60
+ * mis-set `schemaFile`, introspecting `WHERE table_schema = './turbine/schema.ts'`
61
61
  * silently matches zero tables. Used by `turbine generate` to fail loudly.
62
62
  */
63
63
  function looksLikeSchemaFilePath(schema) {
@@ -203,6 +203,7 @@ function resolveConfig(fileConfig, overrides) {
203
203
  out: overrides.out ?? fileConfig.out ?? './generated/turbine',
204
204
  schema: overrides.schema ?? fileConfig.schema ?? 'public',
205
205
  include: overrides.include ?? fileConfig.include ?? [],
206
+ relationNames: fileConfig.relationNames,
206
207
  exclude: overrides.exclude ?? fileConfig.exclude ?? [],
207
208
  migrationsDir: fileConfig.migrationsDir ?? './turbine/migrations',
208
209
  // `seedFile` is canonical (what the docs and `turbine init` use); `seed` is a
@@ -23,7 +23,7 @@
23
23
  */
24
24
  export type DestructiveKind = 'drop-table' | 'drop-schema' | 'drop-database' | 'drop-owned' | 'drop-matview' | 'drop-column' | 'truncate' | 'delete' | 'update-without-where' | 'alter-column-type' | 'merge-delete';
25
25
  export interface DestructiveStatement {
26
- /** The offending SQL statement (trimmed, possibly long display truncated) */
26
+ /** The offending SQL statement (trimmed, possibly long, display truncated) */
27
27
  statement: string;
28
28
  kind: DestructiveKind;
29
29
  /** Best-effort extracted object name (table, schema, or table.column) */
@@ -133,7 +133,7 @@ function isEscapeStringPrefix(sql, quoteAt) {
133
133
  /** Unquote a "quoted" identifier for display. */
134
134
  const ident = (raw) => (raw ?? '?').replace(/^"|"$/g, '');
135
135
  const IDENT = String.raw `("[^"]+"|[a-zA-Z_][\w$]*)(\.("[^"]+"|[a-zA-Z_][\w$]*))?`;
136
- /** Ordered rules first match per statement wins. */
136
+ /** Ordered rules, first match per statement wins. */
137
137
  const RULES = [
138
138
  {
139
139
  kind: 'drop-table',
@@ -3,21 +3,21 @@
3
3
  * turbine-orm CLI
4
4
  *
5
5
  * Commands:
6
- * turbine init Initialize a Turbine project
7
- * turbine generate | pull Introspect database and generate TypeScript types
6
+ * turbine init , Initialize a Turbine project
7
+ * turbine generate | pull , Introspect database and generate TypeScript types
8
8
  * turbine migrate-from-prisma - Parse a schema.prisma and emit a Prisma->Turbine name map + report
9
9
  * turbine push - Apply schema-builder definitions to database (destructive ops gated)
10
10
  * turbine migrate create <name> - Create a new SQL migration file (--auto | --from-diff | --recipe <name>)
11
- * turbine migrate up Apply pending migrations
12
- * turbine migrate deploy Apply pending migrations without prompts
13
- * turbine migrate down Rollback last migration
14
- * turbine migrate status Show migration status
15
- * turbine seed Run seed file
16
- * turbine status Show schema summary
11
+ * turbine migrate up , Apply pending migrations
12
+ * turbine migrate deploy , Apply pending migrations without prompts
13
+ * turbine migrate down , Rollback last migration
14
+ * turbine migrate status , Show migration status
15
+ * turbine seed , Run seed file
16
+ * turbine status , Show schema summary
17
17
  * turbine doctor - Cost-aware missing-FK-index triage (--fix, --json, --no-concurrently, --unused, --audit)
18
18
  * turbine studio : Launch local read-only web UI (--demo for a seeded sample DB)
19
- * turbine mcp Start read-only MCP server over JSON-RPC stdio
20
- * turbine observe Launch metrics dashboard (requires TURBINE_OBSERVE_URL)
19
+ * turbine mcp , Start read-only MCP server over JSON-RPC stdio
20
+ * turbine observe , Launch metrics dashboard (requires TURBINE_OBSERVE_URL)
21
21
  *
22
22
  * Usage:
23
23
  * DATABASE_URL=postgres://... npx turbine generate