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 Schema SQL Generator
2
+ * turbine-orm, Schema SQL Generator
3
3
  *
4
4
  * Converts a SchemaDef (from defineSchema) into executable DDL statements.
5
5
  * Also provides diff and push commands for syncing schema to a live database.
@@ -15,7 +15,7 @@ export interface SchemaSqlOptions {
15
15
  /**
16
16
  * How to handle the pgvector extension when the schema contains a `vector`
17
17
  * column. `'auto'` (default) prepends `CREATE EXTENSION IF NOT EXISTS vector;`
18
- * appropriate for `push`. `'manual'` emits a leading comment only, so the
18
+ * - appropriate for `push`. `'manual'` emits a leading comment only, so the
19
19
  * generated `.sql` migration doesn't silently require superuser privileges.
20
20
  */
21
21
  extensions?: 'auto' | 'manual';
@@ -72,11 +72,11 @@ export interface AlterDef {
72
72
  columns: AlterColumnDef[];
73
73
  }
74
74
  export interface DiffResult {
75
- /** Tables that exist in schema but not in DB need CREATE TABLE */
75
+ /** Tables that exist in schema but not in DB, need CREATE TABLE */
76
76
  create: TableDef[];
77
- /** Tables that exist in both but differ need ALTER TABLE */
77
+ /** Tables that exist in both but differ, need ALTER TABLE */
78
78
  alter: AlterDef[];
79
- /** Table names that exist in DB but not in schema would need DROP TABLE */
79
+ /** Table names that exist in DB but not in schema, would need DROP TABLE */
80
80
  drop: string[];
81
81
  /** SQL statements to execute the diff (UP direction) */
82
82
  statements: string[];
@@ -85,7 +85,7 @@ export interface DiffResult {
85
85
  /**
86
86
  * Human-readable warnings for changes the diff detected but refuses to apply
87
87
  * automatically because they are destructive or otherwise unsafe (enum value
88
- * removal/reorder, etc.). Never executed surfaced for the operator.
88
+ * removal/reorder, etc.). Never executed, surfaced for the operator.
89
89
  */
90
90
  warnings?: string[];
91
91
  }
@@ -106,7 +106,7 @@ export interface DbForeignKey {
106
106
  export declare function buildAddForeignKeyStatement(table: string, constraintName: string, column: string, targetTable: string, targetColumn: string, onDelete: ReferentialAction, onUpdate: ReferentialAction, dialect?: Dialect): string;
107
107
  /**
108
108
  * Decide whether a FK's referential actions changed. When they differ, returns
109
- * the DROP + ADD CONSTRAINT statements (and their reverse) Postgres has no
109
+ * the DROP + ADD CONSTRAINT statements (and their reverse), Postgres has no
110
110
  * `ALTER CONSTRAINT` for referential actions, so drop-and-recreate is the only
111
111
  * path. Returns null when the actions already match.
112
112
  */
@@ -117,7 +117,7 @@ export declare function diffReferentialAction(table: string, db: DbForeignKey, s
117
117
  /**
118
118
  * Compute append-only enum value changes. Returns `ALTER TYPE ... ADD VALUE`
119
119
  * statements for labels present in the schema but not the DB (in order), plus a
120
- * destructive warning for any DB label the schema dropped or any reorder
120
+ * destructive warning for any DB label the schema dropped or any reorder -
121
121
  * Postgres cannot remove or reorder enum values without recreating the type.
122
122
  */
123
123
  export declare function diffEnumValues(enumName: string, schemaLabels: readonly string[], dbLabels: readonly string[], dialect?: Dialect): {
@@ -147,7 +147,7 @@ export interface CheckSpec {
147
147
  * Diff a table's CHECK constraints (matched by name). Adds constraints missing
148
148
  * from the DB, drops DB constraints absent from the schema, and drop+adds when a
149
149
  * same-named constraint's expression changed. Expression comparison is a naive
150
- * whitespace-insensitive match semantically-equal-but-different-spelled
150
+ * whitespace-insensitive match, semantically-equal-but-different-spelled
151
151
  * expressions may re-emit (documented; harmless drop+add).
152
152
  */
153
153
  export declare function diffCheckConstraints(table: string, schemaChecks: readonly CheckSpec[], dbChecks: readonly CheckSpec[], dialect?: Dialect): {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * turbine-orm Schema SQL Generator
2
+ * turbine-orm, Schema SQL Generator
3
3
  *
4
4
  * Converts a SchemaDef (from defineSchema) into executable DDL statements.
5
5
  * Also provides diff and push commands for syncing schema to a live database.
@@ -33,7 +33,7 @@ function quoteEnumLabel(label) {
33
33
  /**
34
34
  * Whether a resolved column type is an auto-increment pseudo-type (SERIAL /
35
35
  * BIGSERIAL). These carry an implicit sequence default and NOT NULL, and their
36
- * underlying integer width (int4 vs int8) is never auto-migrated by diff a
36
+ * underlying integer width (int4 vs int8) is never auto-migrated by diff, a
37
37
  * width change on a live PK is destructive and must be done by hand.
38
38
  */
39
39
  function isSerialType(type) {
@@ -56,7 +56,7 @@ function generateCreateEnumType(enumName, labels, dialect) {
56
56
  }
57
57
  /**
58
58
  * Resolve the DDL type token for a column: an enum type name, a `vector(n)`
59
- * literal, or the dialect's scalar type with a trailing `[]` for arrays.
59
+ * literal, or the dialect's scalar type, with a trailing `[]` for arrays.
60
60
  *
61
61
  * `vectorDimensions` is the one number interpolated into the type token, so it
62
62
  * is validated here as a positive integer within pgvector's limit rather than
@@ -81,7 +81,7 @@ function resolveDdlType(config, dialect, columnName) {
81
81
  return config.isArray ? `${base}[]` : base;
82
82
  }
83
83
  // ---------------------------------------------------------------------------
84
- // SQL Generation SchemaDef → CREATE TABLE statements
84
+ // SQL Generation, SchemaDef → CREATE TABLE statements
85
85
  // ---------------------------------------------------------------------------
86
86
  /**
87
87
  * Convert a SchemaDef into an ordered array of SQL DDL statements.
@@ -96,7 +96,7 @@ export function schemaToSQL(schema, options) {
96
96
  // Topologically sort tables by their foreign key references
97
97
  const sorted = topologicalSort(schema);
98
98
  const resolveRef = makeRefResolver(schema);
99
- // pgvector extension line only when a vector column exists. Postgres-only:
99
+ // pgvector extension line, only when a vector column exists. Postgres-only:
100
100
  // a dialect that can't do pgvector must not silently emit broken DDL.
101
101
  if (schemaHasVectorColumn(schema)) {
102
102
  if (!dialect.supportsVector) {
@@ -180,7 +180,7 @@ function topologicalSort(schema) {
180
180
  if (resolved.has(name))
181
181
  return;
182
182
  if (visiting.has(name)) {
183
- // Circular reference just add it
183
+ // Circular reference, just add it
184
184
  return;
185
185
  }
186
186
  visiting.add(name);
@@ -250,7 +250,7 @@ function generateCreateTable(table, resolveRef, dialect = postgresDialect) {
250
250
  */
251
251
  function generateColumnDef(fieldName, config, resolveRef, dialect = postgresDialect) {
252
252
  const snakeName = camelToSnake(fieldName);
253
- // NOT NULL serial types are implicitly NOT NULL, but explicit is fine.
253
+ // NOT NULL, serial types are implicitly NOT NULL, but explicit is fine.
254
254
  // A column is NOT NULL if:
255
255
  // 1. Explicitly marked .notNull(), OR
256
256
  // 2. Is a serial (BIGSERIAL implies NOT NULL), OR
@@ -264,7 +264,7 @@ function generateColumnDef(fieldName, config, resolveRef, dialect = postgresDial
264
264
  if (config.defaultValue != null) {
265
265
  defaultValue = normalizeDefault(config.defaultValue);
266
266
  }
267
- // REFERENCES resolve the raw table name through the optional resolver so
267
+ // REFERENCES, resolve the raw table name through the optional resolver so
268
268
  // both camelCase accessor names and snake_case DDL names work.
269
269
  let references;
270
270
  if (config.referencesTarget) {
@@ -493,7 +493,7 @@ export function buildAddForeignKeyStatement(table, constraintName, column, targe
493
493
  }
494
494
  /**
495
495
  * Decide whether a FK's referential actions changed. When they differ, returns
496
- * the DROP + ADD CONSTRAINT statements (and their reverse) Postgres has no
496
+ * the DROP + ADD CONSTRAINT statements (and their reverse), Postgres has no
497
497
  * `ALTER CONSTRAINT` for referential actions, so drop-and-recreate is the only
498
498
  * path. Returns null when the actions already match.
499
499
  */
@@ -509,7 +509,7 @@ export function diffReferentialAction(table, db, schemaOnDelete, schemaOnUpdate,
509
509
  /**
510
510
  * Compute append-only enum value changes. Returns `ALTER TYPE ... ADD VALUE`
511
511
  * statements for labels present in the schema but not the DB (in order), plus a
512
- * destructive warning for any DB label the schema dropped or any reorder
512
+ * destructive warning for any DB label the schema dropped or any reorder -
513
513
  * Postgres cannot remove or reorder enum values without recreating the type.
514
514
  */
515
515
  export function diffEnumValues(enumName, schemaLabels, dbLabels, dialect = postgresDialect) {
@@ -525,7 +525,7 @@ export function diffEnumValues(enumName, schemaLabels, dbLabels, dialect = postg
525
525
  const removed = dbLabels.filter((l) => !schemaSet.has(l));
526
526
  if (removed.length > 0) {
527
527
  warnings.push(`Enum "${enumName}": labels [${removed.join(', ')}] exist in the database but not the schema. ` +
528
- `Postgres cannot remove enum values in place recreate the type manually if intended.`);
528
+ `Postgres cannot remove enum values in place, recreate the type manually if intended.`);
529
529
  }
530
530
  return { statements, warnings };
531
531
  }
@@ -533,7 +533,7 @@ export function diffEnumValues(enumName, schemaLabels, dbLabels, dialect = postg
533
533
  * Diff a table's CHECK constraints (matched by name). Adds constraints missing
534
534
  * from the DB, drops DB constraints absent from the schema, and drop+adds when a
535
535
  * same-named constraint's expression changed. Expression comparison is a naive
536
- * whitespace-insensitive match semantically-equal-but-different-spelled
536
+ * whitespace-insensitive match, semantically-equal-but-different-spelled
537
537
  * expressions may re-emit (documented; harmless drop+add).
538
538
  */
539
539
  export function diffCheckConstraints(table, schemaChecks, dbChecks, dialect = postgresDialect) {
@@ -715,7 +715,7 @@ export async function schemaDiff(schema, connectionString) {
715
715
  result.statements.push(...fkIndexes);
716
716
  // User-declared indexes on a brand-new table (reversed by the DROP TABLE).
717
717
  result.statements.push(...generateDeclaredIndexes(tableDef, dialect));
718
- // Reverse: DROP TABLE (with indexes they drop automatically)
718
+ // Reverse: DROP TABLE (with indexes, they drop automatically)
719
719
  result.reverseStatements.unshift(`DROP TABLE IF EXISTS ${dialect.quoteIdentifier(ddlName)} CASCADE;`);
720
720
  }
721
721
  }
@@ -739,7 +739,7 @@ export async function schemaDiff(schema, connectionString) {
739
739
  const snakeName = camelToSnake(fieldName);
740
740
  const dbCol = dbCols[snakeName];
741
741
  if (!dbCol) {
742
- // Column exists in schema but not in DB ADD COLUMN
742
+ // Column exists in schema but not in DB, ADD COLUMN
743
743
  const colDef = generateColumnDef(fieldName, config, resolveRef, dialect);
744
744
  const sql = `ALTER TABLE ${dialect.quoteIdentifier(tableName)} ADD COLUMN ${colDef};`;
745
745
  const reverseSql = `ALTER TABLE ${dialect.quoteIdentifier(tableName)} DROP COLUMN ${dialect.quoteIdentifier(snakeName)};`;
@@ -752,10 +752,10 @@ export async function schemaDiff(schema, connectionString) {
752
752
  // underlying int4/int8 width must never be auto-altered on a live table
753
753
  // (a downcast on a PK loses data / breaks the sequence). This also
754
754
  // preserves back-compat for DBs whose `serial` columns were created as
755
- // BIGSERIAL (int8) before 0.24.0 `push` won't try to shrink them.
755
+ // BIGSERIAL (int8) before 0.24.0, `push` won't try to shrink them.
756
756
  const expectedUdt = schemaTypeToUdt(config);
757
757
  if (expectedUdt && !isSerialType(config.type) && dbCol.udtName !== expectedUdt) {
758
- // resolveDdlType handles enum names, vector(n), arrays, and VARCHAR(n)
758
+ // resolveDdlType handles enum names, vector(n), arrays, and VARCHAR(n) -
759
759
  // config.type alone would emit the internal ENUM/VECTOR sentinels here.
760
760
  const sqlType = resolveDdlType(config, dialect, snakeName);
761
761
  const oldSqlType = udtToSqlType(dbCol.udtName, dbCol.maxLength);
@@ -815,7 +815,7 @@ export async function schemaDiff(schema, connectionString) {
815
815
  result.reverseStatements.unshift(reverseSql);
816
816
  }
817
817
  }
818
- // Check UNIQUE constraint mismatch (skip PKs they're implicitly unique)
818
+ // Check UNIQUE constraint mismatch (skip PKs, they're implicitly unique)
819
819
  if (!config.isPrimaryKey) {
820
820
  const hasDbUnique = snakeName in tableUniques;
821
821
  const wantsUnique = config.isUnique === true;
@@ -868,7 +868,7 @@ export async function schemaDiff(schema, connectionString) {
868
868
  const snakeName = camelToSnake(fieldName);
869
869
  const dbFk = tableFks[snakeName];
870
870
  if (!dbFk)
871
- continue; // FK not present in DB yet (or composite) skip
871
+ continue; // FK not present in DB yet (or composite), skip
872
872
  const change = diffReferentialAction(tableName, dbFk, config.onDelete ?? 'no action', config.onUpdate ?? 'no action', dialect);
873
873
  if (change) {
874
874
  result.statements.push(...change.statements);
@@ -882,7 +882,7 @@ export async function schemaDiff(schema, connectionString) {
882
882
  // inline checks carry auto-generated names the code-first schema never
883
883
  // sees), and we do NOT drop+add on expression mismatch: pg_get_constraintdef
884
884
  // canonicalizes expressions (casts, ANY(ARRAY[...]) rewrites), so authored
885
- // text almost never string-matches the stored form comparing would emit a
885
+ // text almost never string-matches the stored form, comparing would emit a
886
886
  // spurious full-table-revalidating drop+add on every diff. An apparent
887
887
  // mismatch surfaces as a warning instead; rename the constraint to
888
888
  // intentionally replace its expression. Unnamed schema checks are skipped
@@ -1060,7 +1060,7 @@ function defaultsMatch(schemaDefault, dbDefault) {
1060
1060
  return a === b;
1061
1061
  }
1062
1062
  // ---------------------------------------------------------------------------
1063
- // Schema Push execute the diff against a live database
1063
+ // Schema Push, execute the diff against a live database
1064
1064
  // ---------------------------------------------------------------------------
1065
1065
  /**
1066
1066
  * Scan a set of diff statements for data-destroying operations, using the same
package/dist/schema.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * turbine-orm Schema metadata types
2
+ * turbine-orm, Schema metadata types
3
3
  *
4
4
  * These types represent the introspected database schema at runtime.
5
5
  * They're used by the query builder, code generator, and CLI.
@@ -70,7 +70,7 @@ export interface ColumnMetadata {
70
70
  /**
71
71
  * Schema the column's Postgres type lives in, recorded by introspection
72
72
  * ONLY when it differs from the introspected schema (and isn't a
73
- * `pg_catalog` builtin) e.g. an enum or domain owned by another schema.
73
+ * `pg_catalog` builtin), e.g. an enum or domain owned by another schema.
74
74
  * Consumers use it as a cross-schema guard: a same-named enum in another
75
75
  * schema must not receive this schema's `::"enum"` cast (search_path would
76
76
  * resolve it to the wrong type). Absent for same-schema types, builtins,
@@ -84,7 +84,7 @@ export interface ColumnMetadata {
84
84
  /** Whether the column has a DEFAULT, is serial, or is generated */
85
85
  hasDefault: boolean;
86
86
  /**
87
- * Whether the **database server** generates this column's value on insert
87
+ * Whether the **database server** generates this column's value on insert -
88
88
  * a `serial`/`BIGSERIAL` sequence, an `IDENTITY` column, or PowDB's `auto`
89
89
  * modifier. This is a strict subset of {@link hasDefault} (a server-generated
90
90
  * column always reports `hasDefault: true`), but unlike a client-side default
@@ -96,8 +96,8 @@ export interface ColumnMetadata {
96
96
  /**
97
97
  * True when this is a Postgres **`GENERATED ALWAYS AS (expr) STORED`** column
98
98
  * (`information_schema.columns.is_generated = 'ALWAYS'`). Distinct from
99
- * {@link isGenerated} which flags a server-*assigned* identity/serial value
100
- * that a client MAY still override a STORED generated column's value is
99
+ * {@link isGenerated}, which flags a server-*assigned* identity/serial value
100
+ * that a client MAY still override, a STORED generated column's value is
101
101
  * *computed from other columns* and can NEVER be supplied on insert/update
102
102
  * (Postgres rejects it). Codegen therefore omits it from `*Create`/`*Update`
103
103
  * input types, and the write builders reject any `data` containing it with a
@@ -120,6 +120,16 @@ export interface ColumnMetadata {
120
120
  * Introspection never auto-tags PII (it is a code-first declaration).
121
121
  */
122
122
  pii?: boolean;
123
+ /**
124
+ * True when this column should be set to the current time on every `update`
125
+ * that does not name it explicitly (Prisma's `@updatedAt`).
126
+ *
127
+ * A code-first declaration only (`defineSchema` `updatedAt: true` /
128
+ * `.updatedAt()`): introspection NEVER infers it from a column's name,
129
+ * because an application that already manages its own `updated_at` would
130
+ * silently have its writes changed. Untagged schemas emit byte-identical SQL.
131
+ */
132
+ updatedAt?: boolean;
123
133
  /** Whether this is an array column */
124
134
  isArray: boolean;
125
135
  /** Dialect-specific array/bulk-insert type token when needed. */
@@ -159,10 +169,10 @@ export interface RelationDef {
159
169
  * For `manyToMany` relations only: the junction (join) table that links the
160
170
  * source and target tables. The subquery JOINs the target through this table.
161
171
  *
162
- * - `table` junction table name (snake_case).
163
- * - `sourceKey` junction column(s) referencing the SOURCE table's
172
+ * - `table` , junction table name (snake_case).
173
+ * - `sourceKey`, junction column(s) referencing the SOURCE table's
164
174
  * {@link referenceKey} (typically the source PK).
165
- * - `targetKey` junction column(s) referencing the TARGET table's PK.
175
+ * - `targetKey`, junction column(s) referencing the TARGET table's PK.
166
176
  *
167
177
  * Array forms support composite keys (paired positionally with the
168
178
  * referenced columns). Omitted for non-m2m relations.
@@ -246,7 +256,7 @@ export declare function timeOfDayKind(dbType: string | undefined): 'time' | 'tim
246
256
  * driver's local-offset serialization is CORRECT for it (Postgres converts the
247
257
  * offset away). The two types here store the literal wall-clock fields they
248
258
  * are given, so binding a JS `Date` through the driver stores the process's
249
- * LOCAL calendar fields in `America/Los_Angeles`, `2026-07-25T00:00:00Z`
259
+ * LOCAL calendar fields, in `America/Los_Angeles`, `2026-07-25T00:00:00Z`
250
260
  * lands as `2026-07-24 17:00:00`. The read path already interprets an
251
261
  * offset-less value as UTC (see `parseDbDate`), so the write path has to bind
252
262
  * the UTC components for the round trip to be stable.
package/dist/schema.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * turbine-orm Schema metadata types
2
+ * turbine-orm, Schema metadata types
3
3
  *
4
4
  * These types represent the introspected database schema at runtime.
5
5
  * They're used by the query builder, code generator, and CLI.
@@ -25,7 +25,7 @@ const PG_TO_TS = {
25
25
  float4: 'number',
26
26
  float8: 'number',
27
27
  oid: 'number',
28
- // Precision-sensitive keep as string to avoid JS float issues
28
+ // Precision-sensitive, keep as string to avoid JS float issues
29
29
  numeric: 'string',
30
30
  money: 'string',
31
31
  // Boolean
@@ -66,9 +66,9 @@ const PG_TO_TS = {
66
66
  // TSVector
67
67
  tsvector: 'string',
68
68
  tsquery: 'string',
69
- // pgvector embeddings. Mapped to `number[]` for DX (the natural shape an app
69
+ // pgvector, embeddings. Mapped to `number[]` for DX (the natural shape an app
70
70
  // passes when inserting / comparing embeddings). NOTE: like `numeric` above,
71
- // there is a runtime caveat pg has no built-in parser for the `vector` type,
71
+ // there is a runtime caveat, pg has no built-in parser for the `vector` type,
72
72
  // so over the wire a fetched vector arrives as a string literal like
73
73
  // '[1,2,3]' unless the app registers its own parser (e.g. via pgvector's
74
74
  // `registerType`). Turbine never auto-registers one (no side-effecting type
@@ -86,7 +86,7 @@ const DATE_TYPES = new Set(['timestamptz', 'timestamp', 'date']);
86
86
  * `text`: the `text[]` fallback below then produces text-typed UNNEST output
87
87
  * and Postgres refuses the insert with `42804 column "x" is of type <t> but
88
88
  * expression is of type text`. `varchar` / `char` / `bpchar` deliberately keep
89
- * the `text[]` cast `text` assignment-casts to all three, and pinning them
89
+ * the `text[]` cast, `text` assignment-casts to all three, and pinning them
90
90
  * would change already-emitted SQL for no behavioral gain.
91
91
  */
92
92
  const PG_TO_ARRAY = {
@@ -210,7 +210,7 @@ export function timeOfDayKind(dbType) {
210
210
  * driver's local-offset serialization is CORRECT for it (Postgres converts the
211
211
  * offset away). The two types here store the literal wall-clock fields they
212
212
  * are given, so binding a JS `Date` through the driver stores the process's
213
- * LOCAL calendar fields in `America/Los_Angeles`, `2026-07-25T00:00:00Z`
213
+ * LOCAL calendar fields, in `America/Los_Angeles`, `2026-07-25T00:00:00Z`
214
214
  * lands as `2026-07-24 17:00:00`. The read path already interprets an
215
215
  * offset-less value as UTC (see `parseDbDate`), so the write path has to bind
216
216
  * the UTC components for the round trip to be stable.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * turbine-orm/serverless edge / serverless driver integration
2
+ * turbine-orm/serverless, edge / serverless driver integration
3
3
  *
4
4
  * Turbine runs on any Postgres driver that speaks the node-postgres API.
5
5
  * This module exposes a thin factory (`turbineHttp`) that binds an external
@@ -12,12 +12,12 @@
12
12
  * Any driver whose `Pool` satisfies `PgCompatPool` will work. The ones
13
13
  * below are verified:
14
14
  *
15
- * - **Neon** (`@neondatabase/serverless`) HTTP and WebSocket transports
16
- * - **Vercel Postgres** (`@vercel/postgres`) wraps Neon
17
- * - **Cloudflare Hyperdrive** exposes a pg-compatible driver
18
- * - **Supabase** use the regular `pg` package; Supabase is Postgres-native
15
+ * - **Neon** (`@neondatabase/serverless`), HTTP and WebSocket transports
16
+ * - **Vercel Postgres** (`@vercel/postgres`), wraps Neon
17
+ * - **Cloudflare Hyperdrive**, exposes a pg-compatible driver
18
+ * - **Supabase**, use the regular `pg` package; Supabase is Postgres-native
19
19
  *
20
- * Turbine does NOT bundle any of these install whichever you need and
20
+ * Turbine does NOT bundle any of these, install whichever you need and
21
21
  * pass its pool directly.
22
22
  *
23
23
  * ## Limitations over HTTP
@@ -27,9 +27,9 @@
27
27
  * If you call these on an HTTP pool the underlying driver will error.
28
28
  * - **LISTEN/NOTIFY** is not available over HTTP.
29
29
  * - **Transactions** are supported but each transaction holds an HTTP
30
- * connection for its duration keep them short.
30
+ * connection for its duration, keep them short.
31
31
  *
32
- * ## Example Neon on Vercel Edge
32
+ * ## Example, Neon on Vercel Edge
33
33
  *
34
34
  * ```ts
35
35
  * // app/api/users/route.ts
@@ -48,7 +48,7 @@
48
48
  * }
49
49
  * ```
50
50
  *
51
- * ## Example Supabase (direct Postgres, no HTTP proxy needed)
51
+ * ## Example, Supabase (direct Postgres, no HTTP proxy needed)
52
52
  *
53
53
  * ```ts
54
54
  * import { TurbineClient } from 'turbine-orm';
@@ -60,7 +60,7 @@
60
60
  * }, SCHEMA);
61
61
  * ```
62
62
  *
63
- * ## Example Cloudflare Workers
63
+ * ## Example, Cloudflare Workers
64
64
  *
65
65
  * ```ts
66
66
  * // Use the Neon HTTP driver which works in Workers runtime
@@ -92,14 +92,14 @@ export interface TurbineHttpOptions extends Pick<TurbineConfig, 'logging' | 'def
92
92
  *
93
93
  * Use this for serverless/edge environments where Turbine should NOT
94
94
  * manage its own `pg.Pool`. The caller retains ownership of the pool's
95
- * lifecycle `db.disconnect()` is a no-op.
95
+ * lifecycle, `db.disconnect()` is a no-op.
96
96
  *
97
97
  * ## Typed table accessors
98
98
  *
99
99
  * By default `turbineHttp` returns the base {@link TurbineClient}, so you
100
100
  * reach tables through `db.table('users')`. To get the *generated*, fully
101
- * typed accessors (`db.users.findMany()`) identical to what the TCP-path
102
- * `turbine()` factory gives you pass your generated client type as the
101
+ * typed accessors (`db.users.findMany()`), identical to what the TCP-path
102
+ * `turbine()` factory gives you, pass your generated client type as the
103
103
  * `TClient` type argument. The runtime object is the same; the generated
104
104
  * subclass only adds `declare readonly` accessor typings, and the base
105
105
  * constructor already creates those accessors at runtime for every table in
@@ -116,7 +116,7 @@ export interface TurbineHttpOptions extends Pick<TurbineConfig, 'logging' | 'def
116
116
  * @param options - Optional logging / defaultLimit / warnOnUnlimited
117
117
  * @returns A TurbineClient instance (typed as `TClient`)
118
118
  *
119
- * @example Untyped (back-compat) reach tables via `db.table(...)`
119
+ * @example Untyped (back-compat), reach tables via `db.table(...)`
120
120
  * ```ts
121
121
  * import { Pool } from '@neondatabase/serverless';
122
122
  * import { turbineHttp } from 'turbine-orm/serverless';
@@ -127,7 +127,7 @@ export interface TurbineHttpOptions extends Pick<TurbineConfig, 'logging' | 'def
127
127
  * const users = await db.table('users').findMany({ limit: 10 });
128
128
  * ```
129
129
  *
130
- * @example Typed generated accessors, identical to the TCP client
130
+ * @example Typed, generated accessors, identical to the TCP client
131
131
  * ```ts
132
132
  * import { Pool } from '@neondatabase/serverless';
133
133
  * import { turbineHttp } from 'turbine-orm/serverless';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * turbine-orm/serverless edge / serverless driver integration
2
+ * turbine-orm/serverless, edge / serverless driver integration
3
3
  *
4
4
  * Turbine runs on any Postgres driver that speaks the node-postgres API.
5
5
  * This module exposes a thin factory (`turbineHttp`) that binds an external
@@ -12,12 +12,12 @@
12
12
  * Any driver whose `Pool` satisfies `PgCompatPool` will work. The ones
13
13
  * below are verified:
14
14
  *
15
- * - **Neon** (`@neondatabase/serverless`) HTTP and WebSocket transports
16
- * - **Vercel Postgres** (`@vercel/postgres`) wraps Neon
17
- * - **Cloudflare Hyperdrive** exposes a pg-compatible driver
18
- * - **Supabase** use the regular `pg` package; Supabase is Postgres-native
15
+ * - **Neon** (`@neondatabase/serverless`), HTTP and WebSocket transports
16
+ * - **Vercel Postgres** (`@vercel/postgres`), wraps Neon
17
+ * - **Cloudflare Hyperdrive**, exposes a pg-compatible driver
18
+ * - **Supabase**, use the regular `pg` package; Supabase is Postgres-native
19
19
  *
20
- * Turbine does NOT bundle any of these install whichever you need and
20
+ * Turbine does NOT bundle any of these, install whichever you need and
21
21
  * pass its pool directly.
22
22
  *
23
23
  * ## Limitations over HTTP
@@ -27,9 +27,9 @@
27
27
  * If you call these on an HTTP pool the underlying driver will error.
28
28
  * - **LISTEN/NOTIFY** is not available over HTTP.
29
29
  * - **Transactions** are supported but each transaction holds an HTTP
30
- * connection for its duration keep them short.
30
+ * connection for its duration, keep them short.
31
31
  *
32
- * ## Example Neon on Vercel Edge
32
+ * ## Example, Neon on Vercel Edge
33
33
  *
34
34
  * ```ts
35
35
  * // app/api/users/route.ts
@@ -48,7 +48,7 @@
48
48
  * }
49
49
  * ```
50
50
  *
51
- * ## Example Supabase (direct Postgres, no HTTP proxy needed)
51
+ * ## Example, Supabase (direct Postgres, no HTTP proxy needed)
52
52
  *
53
53
  * ```ts
54
54
  * import { TurbineClient } from 'turbine-orm';
@@ -60,7 +60,7 @@
60
60
  * }, SCHEMA);
61
61
  * ```
62
62
  *
63
- * ## Example Cloudflare Workers
63
+ * ## Example, Cloudflare Workers
64
64
  *
65
65
  * ```ts
66
66
  * // Use the Neon HTTP driver which works in Workers runtime
@@ -84,14 +84,14 @@ import { TurbineClient } from './client.js';
84
84
  *
85
85
  * Use this for serverless/edge environments where Turbine should NOT
86
86
  * manage its own `pg.Pool`. The caller retains ownership of the pool's
87
- * lifecycle `db.disconnect()` is a no-op.
87
+ * lifecycle, `db.disconnect()` is a no-op.
88
88
  *
89
89
  * ## Typed table accessors
90
90
  *
91
91
  * By default `turbineHttp` returns the base {@link TurbineClient}, so you
92
92
  * reach tables through `db.table('users')`. To get the *generated*, fully
93
- * typed accessors (`db.users.findMany()`) identical to what the TCP-path
94
- * `turbine()` factory gives you pass your generated client type as the
93
+ * typed accessors (`db.users.findMany()`), identical to what the TCP-path
94
+ * `turbine()` factory gives you, pass your generated client type as the
95
95
  * `TClient` type argument. The runtime object is the same; the generated
96
96
  * subclass only adds `declare readonly` accessor typings, and the base
97
97
  * constructor already creates those accessors at runtime for every table in
@@ -108,7 +108,7 @@ import { TurbineClient } from './client.js';
108
108
  * @param options - Optional logging / defaultLimit / warnOnUnlimited
109
109
  * @returns A TurbineClient instance (typed as `TClient`)
110
110
  *
111
- * @example Untyped (back-compat) reach tables via `db.table(...)`
111
+ * @example Untyped (back-compat), reach tables via `db.table(...)`
112
112
  * ```ts
113
113
  * import { Pool } from '@neondatabase/serverless';
114
114
  * import { turbineHttp } from 'turbine-orm/serverless';
@@ -119,7 +119,7 @@ import { TurbineClient } from './client.js';
119
119
  * const users = await db.table('users').findMany({ limit: 10 });
120
120
  * ```
121
121
  *
122
- * @example Typed generated accessors, identical to the TCP client
122
+ * @example Typed, generated accessors, identical to the TCP client
123
123
  * ```ts
124
124
  * import { Pool } from '@neondatabase/serverless';
125
125
  * import { turbineHttp } from 'turbine-orm/serverless';
@@ -135,6 +135,6 @@ export function turbineHttp(pool, schema, options = {}) {
135
135
  // The generated subclass only layers `declare readonly` accessor typings
136
136
  // over the base client; the base constructor materializes those same
137
137
  // accessors at runtime (Object.defineProperty per schema table). So the
138
- // returned instance genuinely has TClient's shape the assertion is safe.
138
+ // returned instance genuinely has TClient's shape, the assertion is safe.
139
139
  return new TurbineClient({ pool, ...options }, schema);
140
140
  }
package/dist/sqlite.d.ts CHANGED
@@ -1,16 +1,16 @@
1
1
  /**
2
- * turbine-orm/sqlite zero-dependency SQLite engine
2
+ * turbine-orm/sqlite, zero-dependency SQLite engine
3
3
  *
4
4
  * Binds Turbine to SQLite via Node's built-in `node:sqlite` driver
5
5
  * (`DatabaseSync`), so SQLite is a **zero new dependency** engine: the root
6
6
  * package's runtime dependency stays exactly `pg`. This is the in-process
7
- * test / edge / "try it in 10 seconds" engine `:memory:` databases run
7
+ * test / edge / "try it in 10 seconds" engine, `:memory:` databases run
8
8
  * entirely in-process with no service container.
9
9
  *
10
10
  * ## Driver
11
11
  *
12
12
  * - **Primary:** `node:sqlite` `DatabaseSync` (Node ≥ 22.5, experimental). Emits
13
- * an `ExperimentalWarning` harmless. No native build, no extra dependency.
13
+ * an `ExperimentalWarning`, harmless. No native build, no extra dependency.
14
14
  * - **Fallback:** `better-sqlite3` for Node < 22.5. Not bundled and not required;
15
15
  * wrap a `better-sqlite3` handle in the same `PgCompatPool` shape if needed.
16
16
  *
@@ -24,7 +24,7 @@
24
24
  * WAL` is enabled for file databases to allow concurrent readers.
25
25
  * - **Unsupported (throw `UnsupportedFeatureError`):** pgvector distance ops,
26
26
  * LISTEN/NOTIFY (`$listen` / `$notify`), RLS `sessionContext`. Advisory-lock
27
- * migration locking is unavailable SQLite is single-writer, so migrations
27
+ * migration locking is unavailable, SQLite is single-writer, so migrations
28
28
  * serialize naturally.
29
29
  * - **Type affinity caveats:** SQLite has no native `BOOLEAN` (0/1 integers) or
30
30
  * `DATE` (TEXT/INTEGER). Booleans bind as 1/0; `Date` values bind as ISO-8601
@@ -34,7 +34,7 @@
34
34
  * - **Case-insensitive matching** uses `COLLATE NOCASE`, which is **ASCII-only**
35
35
  * (no Unicode case folding).
36
36
  *
37
- * ## Example `:memory:` database
37
+ * ## Example, `:memory:` database
38
38
  *
39
39
  * ```ts
40
40
  * import { turbineSqlite } from 'turbine-orm/sqlite';
@@ -58,12 +58,12 @@ type QueryArg = string | {
58
58
  /**
59
59
  * A `PgCompatPool` backed by a single `node:sqlite` `DatabaseSync` connection.
60
60
  * SQLite is single-connection by nature (a `:memory:` database is per-handle),
61
- * so `connect()` hands back a client over the **same** handle transactions
61
+ * so `connect()` hands back a client over the **same** handle, transactions
62
62
  * (`BEGIN`/`COMMIT`/`ROLLBACK`, `SAVEPOINT` nesting) just run on it. Queries are
63
63
  * serialized; this is the documented single-writer model.
64
64
  */
65
65
  export declare class SqlitePool implements PgCompatPool {
66
- /** The underlying `node:sqlite` handle exposed as an escape hatch (seed/DDL). */
66
+ /** The underlying `node:sqlite` handle, exposed as an escape hatch (seed/DDL). */
67
67
  readonly db: DatabaseSync;
68
68
  private closed;
69
69
  constructor(db: DatabaseSync);
@@ -116,7 +116,7 @@ export interface TurbineSqliteOptions extends Pick<TurbineConfig, 'logging' | 'd
116
116
  * Ignored for `':memory:'`. Default: `true`.
117
117
  */
118
118
  wal?: boolean;
119
- /** `PRAGMA busy_timeout` in ms how long a writer waits on `SQLITE_BUSY`. Default: 5000. */
119
+ /** `PRAGMA busy_timeout` in ms, how long a writer waits on `SQLITE_BUSY`. Default: 5000. */
120
120
  busyTimeoutMs?: number;
121
121
  /** Enable `PRAGMA foreign_keys` enforcement. Default: `true`. */
122
122
  foreignKeys?: boolean;