turbine-orm 0.22.0 → 0.23.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.
@@ -508,6 +508,10 @@ function serializeColumn(col) {
508
508
  `arrayType: '${escSQ(col.arrayType ?? col.pgArrayType)}'`,
509
509
  `pgArrayType: '${escSQ(col.pgArrayType)}'`,
510
510
  ];
511
+ // Emit isGenerated only when set (server-generated serial/identity), so the
512
+ // output stays byte-identical for the common client-default columns.
513
+ if (col.isGenerated)
514
+ parts.push(`isGenerated: true`);
511
515
  if (col.maxLength !== undefined)
512
516
  parts.push(`maxLength: ${col.maxLength}`);
513
517
  return `{ ${parts.join(', ')} }`;
@@ -35,6 +35,7 @@ const SQL_COLUMNS = `
35
35
  data_type,
36
36
  is_nullable,
37
37
  column_default,
38
+ is_identity,
38
39
  ordinal_position,
39
40
  character_maximum_length
40
41
  FROM information_schema.columns
@@ -170,6 +171,11 @@ async function introspectPostgresCatalog(options) {
170
171
  (0, schema_js_1.pgTypeToTs)(isArray ? dialectType : baseType, isNullable),
171
172
  nullable: isNullable,
172
173
  hasDefault: row.column_default !== null,
174
+ // Server-generated = a sequence default (serial/BIGSERIAL → nextval(…))
175
+ // or an IDENTITY column. Distinct from a client-side default expression
176
+ // (gen_random_uuid(), now()), which Turbine must still synthesize.
177
+ isGenerated: (typeof row.column_default === 'string' && row.column_default.includes('nextval(')) ||
178
+ row.is_identity === 'YES',
173
179
  isArray,
174
180
  arrayType,
175
181
  pgArrayType: arrayType,
package/dist/cjs/powdb.js CHANGED
@@ -248,18 +248,32 @@ function isDateColumn(col) {
248
248
  * Generate PowQL DDL (`type T { … }`) for every table in a schema. Used to
249
249
  * provision a PowDB database from a code-first `defineSchema`/`SchemaMetadata`
250
250
  * (PowDB has no migration runner yet). The primary key column is declared
251
- * `required unique`; non-nullable columns are `required`.
251
+ * `required unique`; non-nullable columns are `required`. A server-generated
252
+ * column ({@link ColumnMetadata.isGenerated}) that maps to PowQL `int` gets the
253
+ * `auto` modifier, so PowDB assigns a monotonic id on insert and Turbine stops
254
+ * synthesizing a client-side value for it.
252
255
  */
253
256
  function powqlSchemaDDL(schema) {
254
257
  const stmts = [];
255
258
  for (const meta of Object.values(schema.tables)) {
256
259
  const pkSet = new Set(meta.primaryKey);
260
+ // PowDB's `unique` is single-column only — there is no composite-unique
261
+ // constraint (`add unique` takes one `.column`). So the per-field `unique`
262
+ // modifier is emitted only for a single-column PK; a composite PK (e.g. a
263
+ // m2m junction's `(source_id, target_id)`) marks its columns `required` but
264
+ // cannot enforce the tuple's uniqueness at the engine level.
265
+ const pkIsSingle = meta.primaryKey.length === 1;
257
266
  const fields = meta.columns.map((col) => {
258
267
  const mods = [];
259
268
  if (!col.nullable || pkSet.has(col.name))
260
269
  mods.push('required');
261
- if (pkSet.has(col.name))
270
+ if (pkSet.has(col.name) && pkIsSingle)
262
271
  mods.push('unique');
272
+ // `auto` = server-generated monotonic int. PowDB requires it be `int` and
273
+ // rejects it alongside a `default`; non-int generated columns fall back to
274
+ // a plain typed column (Turbine assigns the value client-side instead).
275
+ if (col.isGenerated && powqlColumnType(col) === 'int')
276
+ mods.push('auto');
263
277
  return ` ${mods.join(' ')}${mods.length ? ' ' : ''}${col.name}: ${powqlColumnType(col)}`;
264
278
  });
265
279
  stmts.push(`type ${meta.name} {\n${fields.join(',\n')}\n}`);