@fragno-dev/db 0.1.1 → 0.1.2

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 (108) hide show
  1. package/.turbo/turbo-build.log +61 -53
  2. package/CHANGELOG.md +12 -0
  3. package/dist/adapters/adapters.d.ts +11 -1
  4. package/dist/adapters/adapters.d.ts.map +1 -1
  5. package/dist/adapters/drizzle/drizzle-adapter.d.ts +9 -2
  6. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.js +21 -39
  8. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-query.d.ts.map +1 -1
  10. package/dist/adapters/drizzle/drizzle-query.js +3 -2
  11. package/dist/adapters/drizzle/drizzle-query.js.map +1 -1
  12. package/dist/adapters/drizzle/drizzle-uow-compiler.js +8 -6
  13. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +1 -1
  14. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +1 -1
  15. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +1 -1
  16. package/dist/adapters/drizzle/generate.js +107 -34
  17. package/dist/adapters/drizzle/generate.js.map +1 -1
  18. package/dist/adapters/drizzle/shared.js +14 -1
  19. package/dist/adapters/drizzle/shared.js.map +1 -1
  20. package/dist/adapters/kysely/kysely-adapter.d.ts +2 -1
  21. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  22. package/dist/adapters/kysely/kysely-adapter.js +25 -30
  23. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  24. package/dist/adapters/kysely/kysely-query-builder.js +48 -44
  25. package/dist/adapters/kysely/kysely-query-builder.js.map +1 -1
  26. package/dist/adapters/kysely/kysely-query-compiler.js +2 -2
  27. package/dist/adapters/kysely/kysely-query-compiler.js.map +1 -1
  28. package/dist/adapters/kysely/kysely-query.js +3 -2
  29. package/dist/adapters/kysely/kysely-query.js.map +1 -1
  30. package/dist/adapters/kysely/kysely-shared.js +18 -0
  31. package/dist/adapters/kysely/kysely-shared.js.map +1 -0
  32. package/dist/adapters/kysely/kysely-uow-compiler.js +4 -3
  33. package/dist/adapters/kysely/kysely-uow-compiler.js.map +1 -1
  34. package/dist/adapters/kysely/migration/execute.js +15 -12
  35. package/dist/adapters/kysely/migration/execute.js.map +1 -1
  36. package/dist/migration-engine/auto-from-schema.js +2 -8
  37. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  38. package/dist/migration-engine/create.d.ts +1 -5
  39. package/dist/migration-engine/create.js +1 -1
  40. package/dist/migration-engine/create.js.map +1 -1
  41. package/dist/migration-engine/generation-engine.d.ts +51 -0
  42. package/dist/migration-engine/generation-engine.d.ts.map +1 -0
  43. package/dist/migration-engine/generation-engine.js +165 -0
  44. package/dist/migration-engine/generation-engine.js.map +1 -0
  45. package/dist/migration-engine/shared.d.ts +5 -2
  46. package/dist/migration-engine/shared.d.ts.map +1 -1
  47. package/dist/migration-engine/shared.js.map +1 -1
  48. package/dist/mod.d.ts +0 -8
  49. package/dist/mod.d.ts.map +1 -1
  50. package/dist/mod.js +0 -32
  51. package/dist/mod.js.map +1 -1
  52. package/dist/query/condition-builder.js.map +1 -1
  53. package/dist/query/result-transform.js +2 -1
  54. package/dist/query/result-transform.js.map +1 -1
  55. package/dist/schema/create.d.ts +74 -16
  56. package/dist/schema/create.d.ts.map +1 -1
  57. package/dist/schema/create.js +76 -11
  58. package/dist/schema/create.js.map +1 -1
  59. package/dist/schema/serialize.js.map +1 -1
  60. package/dist/shared/settings-schema.js +36 -0
  61. package/dist/shared/settings-schema.js.map +1 -0
  62. package/dist/util/import-generator.js.map +1 -1
  63. package/dist/util/parse.js.map +1 -1
  64. package/package.json +8 -2
  65. package/src/adapters/adapters.ts +10 -3
  66. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +11 -7
  67. package/src/adapters/drizzle/drizzle-adapter.test.ts +77 -29
  68. package/src/adapters/drizzle/drizzle-adapter.ts +31 -78
  69. package/src/adapters/drizzle/drizzle-query.ts +4 -7
  70. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +9 -3
  71. package/src/adapters/drizzle/drizzle-uow-compiler.ts +12 -6
  72. package/src/adapters/drizzle/drizzle-uow-decoder.ts +1 -1
  73. package/src/adapters/drizzle/drizzle-uow-executor.ts +1 -1
  74. package/src/adapters/drizzle/generate.test.ts +573 -150
  75. package/src/adapters/drizzle/generate.ts +187 -36
  76. package/src/adapters/drizzle/migrate-drizzle.test.ts +30 -6
  77. package/src/adapters/drizzle/shared.ts +31 -1
  78. package/src/adapters/drizzle/test-utils.ts +3 -1
  79. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +25 -27
  80. package/src/adapters/kysely/kysely-adapter.ts +35 -58
  81. package/src/adapters/kysely/kysely-query-builder.ts +75 -44
  82. package/src/adapters/kysely/kysely-query-compiler.ts +3 -1
  83. package/src/adapters/kysely/kysely-query.ts +8 -2
  84. package/src/adapters/kysely/kysely-shared.ts +23 -0
  85. package/src/adapters/kysely/kysely-uow-compiler.ts +5 -2
  86. package/src/adapters/kysely/migration/execute-mysql.test.ts +2 -2
  87. package/src/adapters/kysely/migration/execute-postgres.test.ts +19 -19
  88. package/src/adapters/kysely/migration/execute.ts +48 -17
  89. package/src/adapters/kysely/migration/kysely-migrator.test.ts +19 -37
  90. package/src/fragment.test.ts +1 -0
  91. package/src/migration-engine/auto-from-schema.ts +14 -18
  92. package/src/migration-engine/create.ts +1 -6
  93. package/src/migration-engine/generation-engine.test.ts +597 -0
  94. package/src/migration-engine/generation-engine.ts +356 -0
  95. package/src/migration-engine/shared.ts +1 -4
  96. package/src/mod.ts +0 -66
  97. package/src/query/condition-builder.ts +24 -8
  98. package/src/query/result-transform.ts +7 -1
  99. package/src/schema/create.test.ts +4 -1
  100. package/src/schema/create.ts +132 -24
  101. package/src/schema/serialize.ts +21 -7
  102. package/src/shared/settings-schema.ts +61 -0
  103. package/src/util/deep-equal.ts +21 -7
  104. package/src/util/import-generator.ts +3 -1
  105. package/src/util/parse.ts +3 -1
  106. package/tsdown.config.ts +1 -0
  107. package/.turbo/turbo-test.log +0 -37
  108. package/.turbo/turbo-types$colon$check.log +0 -1
@@ -151,15 +151,35 @@ export interface Table<
151
151
  getVersionColumn: () => AnyColumn;
152
152
  }
153
153
 
154
- type DefaultFunctionMap = {
155
- date: "now";
156
- timestamp: "now";
157
- string: "auto";
158
- } & Record<`varchar(${number})`, "auto">;
154
+ type DBSpecial = { tag: "special"; value: "now" };
155
+ type RuntimeSpecial = { tag: "special"; value: "cuid" | "now" };
159
156
 
160
- type DefaultFunction<TType extends keyof TypeMap> =
161
- | (TType extends keyof DefaultFunctionMap ? DefaultFunctionMap[TType] : never)
162
- | (() => TypeMap[TType]);
157
+ /**
158
+ * Builder for database-level default values.
159
+ */
160
+ export interface DefaultBuilder {
161
+ /** Database-generated timestamp (DEFAULT NOW()) */
162
+ now(): DBSpecial;
163
+ }
164
+
165
+ /**
166
+ * Builder for runtime-generated default values.
167
+ */
168
+ export interface RuntimeDefaultBuilder {
169
+ /** Generate CUID identifier */
170
+ cuid(): RuntimeSpecial;
171
+ /** Generate current timestamp */
172
+ now(): RuntimeSpecial;
173
+ }
174
+
175
+ const defaultBuilder: DefaultBuilder = {
176
+ now: () => ({ tag: "special", value: "now" }),
177
+ };
178
+
179
+ const runtimeDefaultBuilder: RuntimeDefaultBuilder = {
180
+ cuid: () => ({ tag: "special", value: "cuid" }),
181
+ now: () => ({ tag: "special", value: "now" }),
182
+ };
163
183
 
164
184
  type IdColumnType = `varchar(${number})`;
165
185
 
@@ -188,9 +208,8 @@ export class Column<TType extends keyof TypeMap, TIn = unknown, TOut = unknown>
188
208
 
189
209
  default?:
190
210
  | { value: TypeMap[TType] }
191
- | {
192
- runtime: DefaultFunction<TType>;
193
- };
211
+ | { dbSpecial: "now" }
212
+ | { runtime: "cuid" | "now" | (() => TypeMap[TType]) };
194
213
 
195
214
  tableName: string = "";
196
215
 
@@ -214,25 +233,99 @@ export class Column<TType extends keyof TypeMap, TIn = unknown, TOut = unknown>
214
233
  }
215
234
 
216
235
  /**
217
- * Generate default value on runtime
236
+ * Generate default value at runtime in application code (not in the database).
237
+ *
238
+ * Use this when you need values generated in your application code, either because:
239
+ * - Your database doesn't support the operation (e.g., generating CUIDs)
240
+ * - You want consistent behavior across all databases
241
+ * - You need custom generation logic
242
+ *
243
+ * @param value - Either a literal value or builder callback:
244
+ * - Literal: Any static value of the column type
245
+ * - `(b) => b.cuid()` - Generate a CUID identifier
246
+ * - `(b) => b.now()` - Generate current timestamp
247
+ * - `(b) => ...` - Custom function that returns the default value
248
+ *
249
+ * @example
250
+ * ```ts
251
+ * column("string").defaultTo$((b) => b.cuid()) // Generate CUID at runtime
252
+ * column("timestamp").defaultTo$((b) => b.now()) // Generate timestamp at runtime
253
+ * column("integer").defaultTo$(42) // Static literal
254
+ * column("integer").defaultTo$((b) => Math.floor(Math.random() * 100)) // Custom function
255
+ * ```
218
256
  */
219
- defaultTo$(fn: DefaultFunction<TType>): Column<TType, TIn | null, TOut> {
220
- this.default = { runtime: fn };
257
+ defaultTo$(
258
+ value: TypeMap[TType] | ((builder: RuntimeDefaultBuilder) => RuntimeSpecial | TypeMap[TType]),
259
+ ): Column<TType, TIn | null, TOut> {
260
+ if (typeof value === "function") {
261
+ const fn = value as (builder: RuntimeDefaultBuilder) => RuntimeSpecial | TypeMap[TType];
262
+ const result = fn(runtimeDefaultBuilder);
263
+ if (
264
+ typeof result === "object" &&
265
+ result !== null &&
266
+ "tag" in result &&
267
+ result.tag === "special"
268
+ ) {
269
+ this.default = { runtime: result.value };
270
+ } else {
271
+ // Custom function - we need to wrap the callback to call it again later
272
+ this.default = { runtime: () => fn(runtimeDefaultBuilder) as TypeMap[TType] };
273
+ }
274
+ } else {
275
+ // Direct literal value - wrap it in a function for runtime generation
276
+ this.default = { runtime: () => value };
277
+ }
221
278
  return this;
222
279
  }
223
280
 
224
281
  /**
225
- * Set a database-level default value
282
+ * Set a database-level default value (generated by the database, not application code).
283
+ *
284
+ * The database will generate the default value when inserting rows. If the database
285
+ * doesn't support the operation, Fragno will fall back to generating the value in
286
+ * application code.
287
+ *
288
+ * @param value - Either a literal value or builder callback:
289
+ * - Literal: Any static value of the column type
290
+ * - `(b) => b.now()` - Database-generated timestamp
226
291
  *
227
- * For schemaless database, it's still generated on runtime
292
+ * @example
293
+ * ```ts
294
+ * // Static defaults
295
+ * column("string").defaultTo("active")
296
+ * column("integer").defaultTo(0)
297
+ * column("boolean").defaultTo(true)
298
+ *
299
+ * // Database-generated timestamp (with fallback)
300
+ * column("timestamp").defaultTo((b) => b.now())
301
+ * ```
228
302
  */
229
- defaultTo(value: TypeMap[TType]): Column<TType, TIn | null, TOut> {
230
- this.default = { value };
303
+ defaultTo(
304
+ value: TypeMap[TType] | ((builder: DefaultBuilder) => DBSpecial | TypeMap[TType]),
305
+ ): Column<TType, TIn | null, TOut> {
306
+ if (typeof value === "function") {
307
+ const fn = value as (builder: DefaultBuilder) => DBSpecial | TypeMap[TType];
308
+ const result = fn(defaultBuilder);
309
+ if (
310
+ typeof result === "object" &&
311
+ result !== null &&
312
+ "tag" in result &&
313
+ result.tag === "special"
314
+ ) {
315
+ this.default = { dbSpecial: result.value };
316
+ } else {
317
+ this.default = { value: result as TypeMap[TType] };
318
+ }
319
+ } else {
320
+ this.default = { value };
321
+ }
231
322
  return this;
232
323
  }
233
324
 
234
325
  /**
235
- * Generate default value for the column on runtime.
326
+ * Generate default value for the column at runtime.
327
+ * Used for both runtime defaults (defaultTo$) and fallback generation for
328
+ * database defaults (defaultTo) when the database doesn't support them.
236
329
  */
237
330
  generateDefaultValue(): TypeMap[TType] | undefined {
238
331
  if (!this.default) {
@@ -242,13 +335,24 @@ export class Column<TType extends keyof TypeMap, TIn = unknown, TOut = unknown>
242
335
  if ("value" in this.default) {
243
336
  return this.default.value;
244
337
  }
245
- if (this.default.runtime === "auto") {
338
+
339
+ if ("dbSpecial" in this.default) {
340
+ // Fallback generation for database-level special functions
341
+ if (this.default.dbSpecial === "now") {
342
+ return new Date(Date.now()) as TypeMap[TType];
343
+ }
344
+ return;
345
+ }
346
+
347
+ // Runtime defaults (defaultTo$)
348
+ if (this.default.runtime === "cuid") {
246
349
  return createId() as TypeMap[TType];
247
350
  }
248
351
  if (this.default.runtime === "now") {
249
352
  return new Date(Date.now()) as TypeMap[TType];
250
353
  }
251
354
 
355
+ // Custom function
252
356
  return this.default.runtime();
253
357
  }
254
358
 
@@ -276,11 +380,15 @@ export class IdColumn<
276
380
  > extends Column<TType, TIn, TOut> {
277
381
  id = true;
278
382
 
279
- override defaultTo$(fn: DefaultFunction<TType>) {
280
- return super.defaultTo$(fn) as IdColumn<TType, TIn | null, TOut>;
383
+ override defaultTo$(
384
+ value: TypeMap[TType] | ((builder: RuntimeDefaultBuilder) => RuntimeSpecial | TypeMap[TType]),
385
+ ) {
386
+ return super.defaultTo$(value) as IdColumn<TType, TIn | null, TOut>;
281
387
  }
282
388
 
283
- override defaultTo(value: TypeMap[TType]) {
389
+ override defaultTo(
390
+ value: TypeMap[TType] | ((builder: DefaultBuilder) => DBSpecial | TypeMap[TType]),
391
+ ) {
284
392
  return super.defaultTo(value) as IdColumn<TType, TIn | null, TOut>;
285
393
  }
286
394
  }
@@ -342,7 +450,7 @@ export function referenceColumn(): Column<
342
450
  export function idColumn(): IdColumn<"varchar(30)", string | FragnoId | null, FragnoId> {
343
451
  const col = new IdColumn<"varchar(30)", string | FragnoId | null, FragnoId>("varchar(30)");
344
452
  col.role = "external-id";
345
- col.defaultTo$("auto");
453
+ col.defaultTo$((b) => b.cuid());
346
454
  return col;
347
455
  }
348
456
 
@@ -205,7 +205,9 @@ export function schemaToDBType(
205
205
  return "real";
206
206
  default:
207
207
  // sqlite doesn't support varchar
208
- if (type.startsWith("varchar")) return "text";
208
+ if (type.startsWith("varchar")) {
209
+ return "text";
210
+ }
209
211
  }
210
212
  }
211
213
 
@@ -225,7 +227,9 @@ export function schemaToDBType(
225
227
  case "json":
226
228
  return "varchar(max)";
227
229
  default:
228
- if (type.startsWith("varchar")) return type as `varchar(${number})`;
230
+ if (type.startsWith("varchar")) {
231
+ return type as `varchar(${number})`;
232
+ }
229
233
  return type;
230
234
  }
231
235
  }
@@ -241,7 +245,9 @@ export function schemaToDBType(
241
245
  case "binary":
242
246
  return "bytea";
243
247
  default:
244
- if (type.startsWith("varchar")) return type as `varchar(${number})`;
248
+ if (type.startsWith("varchar")) {
249
+ return type as `varchar(${number})`;
250
+ }
245
251
  return type;
246
252
  }
247
253
  }
@@ -255,7 +261,9 @@ export function schemaToDBType(
255
261
  case "binary":
256
262
  return "longblob";
257
263
  default:
258
- if (type.startsWith("varchar")) return type as `varchar(${number})`;
264
+ if (type.startsWith("varchar")) {
265
+ return type as `varchar(${number})`;
266
+ }
259
267
  return type;
260
268
  }
261
269
  }
@@ -269,7 +277,9 @@ const supportJson: SQLProvider[] = ["postgresql", "cockroachdb", "mysql"];
269
277
  * Parse from driver value
270
278
  */
271
279
  export function deserialize(value: unknown, col: AnyColumn, provider: SQLProvider) {
272
- if (value === null) return null;
280
+ if (value === null) {
281
+ return null;
282
+ }
273
283
 
274
284
  if (!supportJson.includes(provider) && col.type === "json" && typeof value === "string") {
275
285
  return JSON.parse(value);
@@ -283,7 +293,9 @@ export function deserialize(value: unknown, col: AnyColumn, provider: SQLProvide
283
293
  return new Date(value);
284
294
  }
285
295
 
286
- if (col.type === "bool" && typeof value === "number") return value === 1;
296
+ if (col.type === "bool" && typeof value === "number") {
297
+ return value === 1;
298
+ }
287
299
 
288
300
  if (col.type === "bigint" && value instanceof Buffer) {
289
301
  return value.readBigInt64BE(0);
@@ -342,7 +354,9 @@ export function serialize(value: unknown, col: AnyColumn, provider: SQLProvider)
342
354
  return value.getTime();
343
355
  }
344
356
 
345
- if (provider === "sqlite" && typeof value === "boolean") return value ? 1 : 0;
357
+ if (provider === "sqlite" && typeof value === "boolean") {
358
+ return value ? 1 : 0;
359
+ }
346
360
 
347
361
  if (provider === "sqlite" && typeof value === "bigint") {
348
362
  const buf = Buffer.alloc(8);
@@ -0,0 +1,61 @@
1
+ import type { AbstractQuery } from "../query/query";
2
+ import { schema, idColumn, column, type FragnoId } from "../schema/create";
3
+
4
+ export const SETTINGS_TABLE_NAME = "fragno_db_settings" as const;
5
+ export const SETTINGS_NAMESPACE = "fragno-db-settings" as const;
6
+
7
+ export const settingsSchema = schema((s) => {
8
+ return s.addTable(SETTINGS_TABLE_NAME, (t) => {
9
+ return t
10
+ .addColumn("id", idColumn())
11
+ .addColumn("key", column("string"))
12
+ .addColumn("value", column("string"))
13
+ .createIndex("unique_key", ["key"], { unique: true });
14
+ });
15
+ });
16
+
17
+ export function createSettingsManager(
18
+ // oxlint-disable-next-line no-explicit-any
19
+ queryEngine: AbstractQuery<typeof settingsSchema, any>,
20
+ namespace: string,
21
+ ) {
22
+ return {
23
+ async get(key: string): Promise<{ id: FragnoId; key: string; value: string } | undefined> {
24
+ const uow = queryEngine
25
+ .createUnitOfWork()
26
+ .find(SETTINGS_TABLE_NAME, (b) =>
27
+ b.whereIndex("unique_key", (eb) => eb("key", "=", `${namespace}.${key}`)),
28
+ );
29
+ const [[result]] = await uow.executeRetrieve();
30
+ return result; // Safe: result can be undefined if key doesn't exist
31
+ },
32
+
33
+ async set(key: string, value: string) {
34
+ const uow = queryEngine
35
+ .createUnitOfWork("createSettingsManager#set")
36
+ .find(SETTINGS_TABLE_NAME, (b) =>
37
+ b.whereIndex("unique_key", (eb) => eb("key", "=", `${namespace}.${key}`)),
38
+ );
39
+ const [[existing]] = await uow.executeRetrieve();
40
+
41
+ if (existing) {
42
+ uow.update(SETTINGS_TABLE_NAME, existing.id, (b) => b.set({ value }).check());
43
+ } else {
44
+ uow.create(SETTINGS_TABLE_NAME, {
45
+ key: `${namespace}.${key}`,
46
+ value,
47
+ });
48
+ }
49
+
50
+ const { success } = await uow.executeMutations();
51
+
52
+ if (!success) {
53
+ throw new Error("Failed to set schema version");
54
+ }
55
+ },
56
+
57
+ async delete(id: FragnoId) {
58
+ await queryEngine.delete(SETTINGS_TABLE_NAME, id);
59
+ },
60
+ };
61
+ }
@@ -1,13 +1,21 @@
1
1
  // Minimal deep equal utility for primitives, arrays, and plain objects
2
2
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3
3
  export function deepEqual(a: any, b: any): boolean {
4
- if (a === b) return true;
5
- if (typeof a !== typeof b) return false;
4
+ if (a === b) {
5
+ return true;
6
+ }
7
+ if (typeof a !== typeof b) {
8
+ return false;
9
+ }
6
10
 
7
11
  if (Array.isArray(a) && Array.isArray(b)) {
8
- if (a.length !== b.length) return false;
12
+ if (a.length !== b.length) {
13
+ return false;
14
+ }
9
15
  for (let i = 0; i < a.length; i++) {
10
- if (!deepEqual(a[i], b[i])) return false;
16
+ if (!deepEqual(a[i], b[i])) {
17
+ return false;
18
+ }
11
19
  }
12
20
  return true;
13
21
  }
@@ -15,11 +23,17 @@ export function deepEqual(a: any, b: any): boolean {
15
23
  if (typeof a === "object" && typeof b === "object") {
16
24
  const aKeys = Object.keys(a);
17
25
  const bKeys = Object.keys(b);
18
- if (aKeys.length !== bKeys.length) return false;
26
+ if (aKeys.length !== bKeys.length) {
27
+ return false;
28
+ }
19
29
  for (const key of aKeys) {
20
- if (!(key in b)) return false;
30
+ if (!(key in b)) {
31
+ return false;
32
+ }
21
33
 
22
- if (!Object.hasOwn(b, key) || !deepEqual(a[key], b[key])) return false;
34
+ if (!Object.hasOwn(b, key) || !deepEqual(a[key], b[key])) {
35
+ return false;
36
+ }
23
37
  }
24
38
 
25
39
  return true;
@@ -17,7 +17,9 @@ export function importGenerator() {
17
17
  format(): string {
18
18
  const v: string[] = [];
19
19
  for (const [specifier, names] of map) {
20
- if (names.length === 0) continue;
20
+ if (names.length === 0) {
21
+ continue;
22
+ }
21
23
 
22
24
  v.push(`import { ${names.join(", ")} } from "${specifier}"`);
23
25
  }
package/src/util/parse.ts CHANGED
@@ -2,7 +2,9 @@ const RegexVarchar = /^varchar\((\d+)\)$/;
2
2
 
3
3
  export function parseVarchar(template: string): number {
4
4
  const match = RegexVarchar.exec(template);
5
- if (!match) throw new Error("Failed to match varchar(n)");
5
+ if (!match) {
6
+ throw new Error("Failed to match varchar(n)");
7
+ }
6
8
  return Number(match[1]);
7
9
  }
8
10
 
package/tsdown.config.ts CHANGED
@@ -11,6 +11,7 @@ export default defineConfig({
11
11
  "./src/query/unit-of-work.ts",
12
12
  "./src/query/cursor.ts",
13
13
  "./src/fragment.ts",
14
+ "./src/migration-engine/generation-engine.ts",
14
15
  ],
15
16
  dts: true,
16
17
  unbundle: true,
@@ -1,37 +0,0 @@
1
- $ vitest run
2
-
3
-  RUN  v3.2.4 /home/runner/work/fragno/fragno/packages/fragno-db
4
- Coverage enabled with istanbul
5
-
6
- ✓ src/adapters/kysely/migration/execute-postgres.test.ts (50 tests) 779ms
7
- ✓ src/adapters/kysely/kysely-query-builder.test.ts (83 tests) 575ms
8
- ✓ src/adapters/kysely/kysely-uow-joins.test.ts (26 tests) 422ms
9
- ✓ src/adapters/kysely/kysely-uow-compiler.test.ts (42 tests) 467ms
10
- ✓ src/schema/create.test.ts (28 tests) 208ms
11
- ✓ src/adapters/kysely/migration/execute-mysql.test.ts (36 tests) 331ms
12
- ✓ src/query/unit-of-work.test.ts (30 tests) 262ms
13
- ✓ src/adapters/drizzle/generate.test.ts (13 tests) 154ms
14
- ✓ src/query/result-transform.test.ts (47 tests) 173ms
15
- ✓ src/schema/serialize.test.ts (86 tests) 206ms
16
- ✓ src/adapters/drizzle/drizzle-uow-compiler.test.ts (45 tests) 24852ms
17
- ✓ src/adapters/kysely/kysely-adapter-pglite.test.ts (7 tests) 10686ms
18
- ✓ KyselyAdapter PGLite > should run migrations and basic queries  623ms
19
- ✓ KyselyAdapter PGLite > should support many-to-many queries through junction table  343ms
20
- ✓ src/query/query-type.test.ts (29 tests) 29ms
21
- ✓ src/query/condition-builder.test.ts (20 tests) 34ms
22
- ✓ src/migration-engine/create.test.ts (20 tests) 56ms
23
- ✓ src/migration-engine/auto-from-schema.test.ts (13 tests) 76ms
24
- ✓ src/adapters/drizzle/drizzle-adapter-pglite.test.ts (5 tests) 8905ms
25
- ✓ src/adapters/drizzle/migrate-drizzle.test.ts (1 test) 491ms
26
- ✓ src/fragment.test.ts (11 tests) 57ms
27
- ✓ src/query/cursor.test.ts (18 tests) 41ms
28
- ✓ src/query/unit-of-work-types.test.ts (5 tests) 37ms
29
- ✓ src/adapters/kysely/migration/kysely-migrator.test.ts (9 tests) 142ms
30
- ✓ src/adapters/drizzle/drizzle-adapter.test.ts (4 tests) 53ms
31
- ✓ src/adapters/drizzle/join-column-utils.test.ts (8 tests) 23ms
32
-
33
-  Test Files  24 passed (24)
34
-  Tests  636 passed (636)
35
-  Start at  12:33:42
36
-  Duration  47.25s (transform 20.15s, setup 0ms, collect 51.86s, tests 49.06s, environment 119ms, prepare 11.76s)
37
-
@@ -1 +0,0 @@
1
- $ tsc --noEmit