@fragno-dev/db 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,20 +1,20 @@
1
1
 
2
- > @fragno-dev/db@0.1.5 build /home/runner/work/fragno/fragno/packages/fragno-db
2
+ > @fragno-dev/db@0.1.6 build /home/runner/work/fragno/fragno/packages/fragno-db
3
3
  > tsdown
4
4
 
5
5
  ℹ tsdown v0.15.10 powered by rolldown v1.0.0-beta.44
6
6
  ℹ Using tsdown config: /home/runner/work/fragno/fragno/packages/fragno-db/tsdown.config.ts
7
- ℹ entry: src/fragment.ts, src/id.ts, src/mod.ts, src/adapters/adapters.ts, src/migration-engine/generation-engine.ts, src/query/cursor.ts, src/query/query.ts, src/query/unit-of-work.ts, src/schema/create.ts, src/adapters/drizzle/drizzle-adapter.ts, src/adapters/kysely/kysely-adapter.ts
7
+ ℹ entry: src/fragment.ts, src/id.ts, src/mod.ts, src/migration-engine/generation-engine.ts, src/adapters/adapters.ts, src/query/cursor.ts, src/query/query.ts, src/query/unit-of-work.ts, src/schema/create.ts, src/adapters/drizzle/drizzle-adapter.ts, src/adapters/kysely/kysely-adapter.ts
8
8
  ℹ tsconfig: tsconfig.json
9
9
  ℹ Build start
10
10
  ℹ dist/schema/create.js 19.85 kB │ gzip: 5.20 kB
11
11
  ℹ dist/query/unit-of-work.js 16.08 kB │ gzip: 3.74 kB
12
12
  ℹ dist/migration-engine/generation-engine.js  7.87 kB │ gzip: 2.17 kB
13
- ℹ dist/adapters/kysely/kysely-adapter.js  4.25 kB │ gzip: 1.46 kB
13
+ ℹ dist/adapters/kysely/kysely-adapter.js  4.35 kB │ gzip: 1.50 kB
14
14
  ℹ dist/query/cursor.js  2.99 kB │ gzip: 1.13 kB
15
15
  ℹ dist/mod.js  2.72 kB │ gzip: 0.90 kB
16
16
  ℹ dist/fragment.js  2.49 kB │ gzip: 0.71 kB
17
- ℹ dist/adapters/drizzle/drizzle-adapter.js  1.67 kB │ gzip: 0.73 kB
17
+ ℹ dist/adapters/drizzle/drizzle-adapter.js  1.81 kB │ gzip: 0.78 kB
18
18
  ℹ dist/id.js  0.07 kB │ gzip: 0.07 kB
19
19
  ℹ dist/adapters/adapters.js  0.01 kB │ gzip: 0.03 kB
20
20
  ℹ dist/query/query.js  0.01 kB │ gzip: 0.03 kB
@@ -31,9 +31,9 @@
31
31
  ℹ dist/migration-engine/generation-engine.js.map 15.63 kB │ gzip: 4.22 kB
32
32
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/db.js.map 14.29 kB │ gzip: 3.59 kB
33
33
  ℹ dist/adapters/drizzle/drizzle-uow-compiler.js 13.95 kB │ gzip: 3.57 kB
34
- ℹ dist/adapters/kysely/kysely-uow-compiler.js.map 13.52 kB │ gzip: 3.84 kB
34
+ ℹ dist/adapters/kysely/kysely-uow-compiler.js.map 13.64 kB │ gzip: 3.89 kB
35
35
  ℹ dist/adapters/drizzle/generate.js 13.44 kB │ gzip: 3.46 kB
36
- ℹ dist/adapters/kysely/kysely-query.js.map 12.85 kB │ gzip: 3.47 kB
36
+ ℹ dist/adapters/kysely/kysely-query.js.map 12.98 kB │ gzip: 3.54 kB
37
37
  ℹ dist/adapters/kysely/kysely-query-builder.js 12.83 kB │ gzip: 3.58 kB
38
38
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/relations.js.map 12.16 kB │ gzip: 3.29 kB
39
39
  ℹ dist/schema/serialize.js.map 12.12 kB │ gzip: 2.75 kB
@@ -48,8 +48,8 @@
48
48
  ℹ dist/query/unit-of-work.d.ts.map  9.79 kB │ gzip: 3.77 kB
49
49
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/insert.js.map  9.78 kB │ gzip: 2.96 kB
50
50
  ℹ dist/adapters/kysely/migration/execute-base.js.map  9.77 kB │ gzip: 3.27 kB
51
+ ℹ dist/adapters/kysely/kysely-adapter.js.map  9.69 kB │ gzip: 3.17 kB
51
52
  ℹ dist/adapters/kysely/migration/execute-mysql.js.map  9.30 kB │ gzip: 2.37 kB
52
- ℹ dist/adapters/kysely/kysely-adapter.js.map  9.29 kB │ gzip: 3.05 kB
53
53
  ℹ dist/query/condition-builder.js.map  9.18 kB │ gzip: 2.42 kB
54
54
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/pg-core/columns/common.js.map  8.97 kB │ gzip: 2.98 kB
55
55
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/db.js  8.91 kB │ gzip: 2.40 kB
@@ -64,10 +64,10 @@
64
64
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/query.js.map  6.71 kB │ gzip: 1.70 kB
65
65
  ℹ dist/query/query.d.ts.map  6.51 kB │ gzip: 2.43 kB
66
66
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/insert.js  6.33 kB │ gzip: 2.02 kB
67
+ ℹ dist/adapters/kysely/kysely-query-compiler.js.map  6.32 kB │ gzip: 1.57 kB
67
68
  ℹ dist/adapters/drizzle/drizzle-uow-executor.js  6.22 kB │ gzip: 1.93 kB
68
- ℹ dist/adapters/kysely/kysely-query-compiler.js.map  6.21 kB │ gzip: 1.51 kB
69
- ℹ dist/adapters/kysely/kysely-query.js  6.00 kB │ gzip: 1.69 kB
70
- ℹ dist/adapters/kysely/kysely-uow-compiler.js  5.93 kB │ gzip: 1.81 kB
69
+ ℹ dist/adapters/kysely/kysely-query.js  6.05 kB │ gzip: 1.72 kB
70
+ ℹ dist/adapters/kysely/kysely-uow-compiler.js  5.96 kB │ gzip: 1.82 kB
71
71
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/pg-core/columns/common.js  5.80 kB │ gzip: 2.04 kB
72
72
  ℹ dist/query/result-transform.js  5.52 kB │ gzip: 1.87 kB
73
73
  ℹ dist/adapters/kysely/migration/execute-mssql.js  5.51 kB │ gzip: 1.52 kB
@@ -84,6 +84,7 @@
84
84
  ℹ dist/migration-engine/auto-from-schema.js  4.33 kB │ gzip: 1.21 kB
85
85
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/column-builder.js.map  4.32 kB │ gzip: 1.47 kB
86
86
  ℹ dist/adapters/kysely/migration/execute-base.js  4.31 kB │ gzip: 1.69 kB
87
+ ℹ dist/adapters/drizzle/drizzle-adapter.js.map  4.00 kB │ gzip: 1.59 kB
87
88
  ℹ dist/migration-engine/shared.js.map  3.89 kB │ gzip: 1.25 kB
88
89
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/pg-core/utils/array.js.map  3.85 kB │ gzip: 1.25 kB
89
90
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/query.js  3.81 kB │ gzip: 1.03 kB
@@ -93,7 +94,6 @@
93
94
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/selection-proxy.js.map  3.71 kB │ gzip: 1.36 kB
94
95
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/query-builder.js.map  3.69 kB │ gzip: 1.31 kB
95
96
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/delete.js  3.58 kB │ gzip: 1.32 kB
96
- ℹ dist/adapters/drizzle/drizzle-adapter.js.map  3.57 kB │ gzip: 1.43 kB
97
97
  ℹ dist/adapters/kysely/kysely-uow-executor.js  3.54 kB │ gzip: 1.25 kB
98
98
  ℹ dist/query/orm/orm.js.map  3.49 kB │ gzip: 1.38 kB
99
99
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sql/expressions/conditions.js  3.47 kB │ gzip: 0.94 kB
@@ -111,9 +111,9 @@
111
111
  ℹ dist/migration-engine/create.js  2.52 kB │ gzip: 0.80 kB
112
112
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/table.js.map  2.44 kB │ gzip: 0.97 kB
113
113
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/count.js.map  2.36 kB │ gzip: 1.00 kB
114
+ ℹ dist/adapters/kysely/kysely-query-compiler.js  2.35 kB │ gzip: 0.63 kB
114
115
  ℹ dist/adapters/kysely/migration/execute.js.map  2.34 kB │ gzip: 0.88 kB
115
116
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/column.js.map  2.33 kB │ gzip: 0.85 kB
116
- ℹ dist/adapters/kysely/kysely-query-compiler.js  2.32 kB │ gzip: 0.61 kB
117
117
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/unique-constraint.js.map  2.31 kB │ gzip: 0.89 kB
118
118
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/query-builder.js  2.16 kB │ gzip: 0.78 kB
119
119
  ℹ dist/adapters/drizzle/shared.js.map  2.16 kB │ gzip: 1.01 kB
@@ -127,10 +127,10 @@
127
127
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/pg-core/foreign-keys.js  1.82 kB │ gzip: 0.70 kB
128
128
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/casing.js  1.80 kB │ gzip: 0.80 kB
129
129
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/columns/common.js  1.78 kB │ gzip: 0.73 kB
130
+ ℹ dist/adapters/kysely/migration/execute-factory.js.map  1.76 kB │ gzip: 0.70 kB
130
131
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/pg-core/columns/enum.js  1.74 kB │ gzip: 0.59 kB
131
132
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/foreign-keys.js  1.74 kB │ gzip: 0.68 kB
132
133
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/entity.js.map  1.62 kB │ gzip: 0.83 kB
133
- ℹ dist/adapters/kysely/migration/execute-factory.js.map  1.60 kB │ gzip: 0.62 kB
134
134
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/pg-core/unique-constraint.js  1.58 kB │ gzip: 0.61 kB
135
135
  ℹ dist/shared/settings-schema.js  1.57 kB │ gzip: 0.65 kB
136
136
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/raw.js.map  1.56 kB │ gzip: 0.78 kB
@@ -147,8 +147,8 @@
147
147
  ℹ dist/adapters/drizzle/join-column-utils.js  1.14 kB │ gzip: 0.55 kB
148
148
  ℹ dist/adapters/kysely/kysely-shared.js.map  1.07 kB │ gzip: 0.53 kB
149
149
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/subquery.js.map  1.07 kB │ gzip: 0.60 kB
150
+ ℹ dist/adapters/kysely/migration/execute-factory.js  1.04 kB │ gzip: 0.42 kB
150
151
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/query-builders/raw.js  1.01 kB │ gzip: 0.54 kB
151
- ℹ dist/adapters/kysely/migration/execute-factory.js  0.97 kB │ gzip: 0.39 kB
152
152
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/entity.js  0.95 kB │ gzip: 0.54 kB
153
153
  ℹ dist/mod.d.ts.map  0.92 kB │ gzip: 0.49 kB
154
154
  ℹ dist/adapters/drizzle/shared.js  0.87 kB │ gzip: 0.48 kB
@@ -163,8 +163,8 @@
163
163
  ℹ dist/util/import-generator.js  0.65 kB │ gzip: 0.36 kB
164
164
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sql/expressions/select.js.map  0.64 kB │ gzip: 0.39 kB
165
165
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/subquery.js  0.64 kB │ gzip: 0.39 kB
166
+ ℹ dist/adapters/kysely/kysely-adapter.d.ts.map  0.63 kB │ gzip: 0.34 kB
166
167
  ℹ dist/node_modules/.pnpm/drizzle-orm@0.44.7_@electric-sql_pglite@0.3.11_@types_better-sqlite3@7.6.13_better-sqlite3@12.4.1_kysely@0.28.8/node_modules/drizzle-orm/sqlite-core/view-base.js.map  0.62 kB │ gzip: 0.39 kB
167
- ℹ dist/adapters/kysely/kysely-adapter.d.ts.map  0.60 kB │ gzip: 0.32 kB
168
168
  ℹ dist/adapters/adapters.d.ts.map  0.60 kB │ gzip: 0.30 kB
169
169
  ℹ dist/adapters/kysely/kysely-shared.js  0.54 kB │ gzip: 0.31 kB
170
170
  ℹ dist/migration-engine/shared.d.ts.map  0.51 kB │ gzip: 0.30 kB
@@ -196,9 +196,9 @@
196
196
  ℹ dist/fragment.d.ts  2.39 kB │ gzip: 0.75 kB
197
197
  ℹ dist/mod.d.ts  2.23 kB │ gzip: 0.73 kB
198
198
  ℹ dist/migration-engine/generation-engine.d.ts  1.99 kB │ gzip: 0.72 kB
199
+ ℹ dist/adapters/drizzle/drizzle-adapter.d.ts  1.11 kB │ gzip: 0.49 kB
199
200
  ℹ dist/adapters/adapters.d.ts  1.10 kB │ gzip: 0.51 kB
200
- ℹ dist/adapters/drizzle/drizzle-adapter.d.ts  1.09 kB │ gzip: 0.49 kB
201
- ℹ dist/adapters/kysely/kysely-adapter.d.ts  0.94 kB │ gzip: 0.44 kB
201
+ ℹ dist/adapters/kysely/kysely-adapter.d.ts  0.96 kB │ gzip: 0.45 kB
202
202
  ℹ dist/id.d.ts  0.07 kB │ gzip: 0.07 kB
203
203
  ℹ dist/migration-engine/shared.d.ts  2.76 kB │ gzip: 0.99 kB
204
204
  ℹ dist/query/condition-builder.d.ts  2.00 kB │ gzip: 0.68 kB
@@ -209,5 +209,5 @@
209
209
  ℹ dist/shared/providers.d.ts  0.26 kB │ gzip: 0.19 kB
210
210
  ℹ dist/util/types.d.ts  0.26 kB │ gzip: 0.21 kB
211
211
  ℹ dist/adapters/drizzle/drizzle-uow-compiler.d.ts  0.22 kB │ gzip: 0.17 kB
212
- ℹ 202 files, total: 1078.36 kB
213
- ✔ Build complete in 9629ms
212
+ ℹ 202 files, total: 1080.20 kB
213
+ ✔ Build complete in 2548ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @fragno-dev/db
2
2
 
3
+ ## 0.1.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 70bdcb2: feat: allow lazy initialization of `db` in adapters
8
+
3
9
  ## 0.1.5
4
10
 
5
11
  ### Patch Changes
@@ -6,7 +6,7 @@ import { DrizzleUOWConfig } from "./drizzle-query.js";
6
6
 
7
7
  //#region src/adapters/drizzle/drizzle-adapter.d.ts
8
8
  interface DrizzleConfig {
9
- db: unknown;
9
+ db: unknown | (() => unknown);
10
10
  provider: "sqlite" | "mysql" | "postgresql";
11
11
  }
12
12
  declare class DrizzleAdapter implements DatabaseAdapter<DrizzleUOWConfig> {
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle-adapter.d.ts","names":[],"sources":["../../../src/adapters/drizzle/drizzle-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;UAUiB,aAAA;;EAAA,QAAA,EAAA,QAAa,GAAA,OAAA,GAAA,YAAA;AAK9B;AAAuD,cAA1C,cAAA,YAA0B,eAAgB,CAAA,gBAAA,CAAA,CAAA;EAGjC,CAAA,OAAA;EAQS,WAAA,CAAA,MAAA,EART,aAQS;EAkBc,IAAA,QAAA,CAAA,CAAA,EAAA,QAAA,GAAA,OAAA,GAAA,YAAA;EAST,mBAAA,CAAA,CAAA,EA3BL,OA2BK,CAAA,OAAA,CAAA;EACxB,gBAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAViC,OAUjC,CAAA,MAAA,GAAA,SAAA,CAAA;EAEO,iBAAA,CAAA,gBAHiB,SAGjB,CAAA,CAAA,MAAA,EAFP,OAEO,EAAA,SAAA,EAAA,MAAA,CAAA,EAAd,aAAc,CAAA,OAAA,EAAS,gBAAT,CAAA;EAAS,qBAAA,CAAA,SAAA,EAAA;IAAvB,MAAA,EAOoB,SAPpB;IAOoB,SAAA,EAAA,MAAA;EAEpB,CAAA,EAAA,EAAA,OAlDiD,CAkDjD,EAAA;IAlDkC,IAAA,CAAA,EAAA,MAAA;EAAe,CAAA,CAAA,EAkDjD,eAlDiD"}
1
+ {"version":3,"file":"drizzle-adapter.d.ts","names":[],"sources":["../../../src/adapters/drizzle/drizzle-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;UAUiB,aAAA;;EAAA,QAAA,EAAA,QAAa,GAAA,OAAA,GAAA,YAAA;AAK9B;AAAuD,cAA1C,cAAA,YAA0B,eAAgB,CAAA,gBAAA,CAAA,CAAA;EAGjC,CAAA,OAAA;EAaS,WAAA,CAAA,MAAA,EAbT,aAaS;EAkBc,IAAA,QAAA,CAAA,CAAA,EAAA,QAAA,GAAA,OAAA,GAAA,YAAA;EAST,mBAAA,CAAA,CAAA,EA3BL,OA2BK,CAAA,OAAA,CAAA;EACxB,gBAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAViC,OAUjC,CAAA,MAAA,GAAA,SAAA,CAAA;EAEO,iBAAA,CAAA,gBAHiB,SAGjB,CAAA,CAAA,MAAA,EAFP,OAEO,EAAA,SAAA,EAAA,MAAA,CAAA,EAAd,aAAc,CAAA,OAAA,EAAS,gBAAT,CAAA;EAAS,qBAAA,CAAA,SAAA,EAAA;IAAvB,MAAA,EAYoB,SAZpB;IAYoB,SAAA,EAAA,MAAA;EAEpB,CAAA,EAAA,EAAA,OA5DiD,CA4DjD,EAAA;IA5DkC,IAAA,CAAA,EAAA,MAAA;EAAe,CAAA,CAAA,EA4DjD,eA5DiD"}
@@ -14,9 +14,13 @@ var DrizzleAdapter = class {
14
14
  get provider() {
15
15
  return this.#drizzleConfig.provider;
16
16
  }
17
+ #getDb() {
18
+ const db = this.#drizzleConfig.db;
19
+ return typeof db === "function" ? db() : db;
20
+ }
17
21
  async isConnectionHealthy() {
18
22
  try {
19
- const result = await this.#drizzleConfig.db.execute(sql`SELECT 1 as healthy`);
23
+ const result = await this.#getDb().execute(sql`SELECT 1 as healthy`);
20
24
  if (Array.isArray(result)) return result.length > 0 && result[0]["healthy"] === 1;
21
25
  else return result.rows[0]["healthy"] === 1;
22
26
  } catch {
@@ -28,7 +32,10 @@ var DrizzleAdapter = class {
28
32
  }
29
33
  createQueryEngine(schema, namespace) {
30
34
  const mapper = namespace ? createTableNameMapper(namespace) : void 0;
31
- return fromDrizzle(schema, this.#drizzleConfig, mapper);
35
+ return fromDrizzle(schema, {
36
+ db: this.#getDb(),
37
+ provider: this.#drizzleConfig.provider
38
+ }, mapper);
32
39
  }
33
40
  createSchemaGenerator(fragments, options) {
34
41
  return { generateSchema: (genOptions) => {
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle-adapter.js","names":["#drizzleConfig"],"sources":["../../../src/adapters/drizzle/drizzle-adapter.ts"],"sourcesContent":["import type { DatabaseAdapter } from \"../adapters\";\nimport { type AnySchema } from \"../../schema/create\";\nimport type { AbstractQuery } from \"../../query/query\";\nimport type { SchemaGenerator } from \"../../schema-generator/schema-generator\";\nimport { generateSchema } from \"./generate\";\nimport { fromDrizzle, type DrizzleUOWConfig } from \"./drizzle-query\";\nimport { createTableNameMapper, type DBType, type DrizzleResult } from \"./shared\";\nimport { createSettingsManager, settingsSchema } from \"../../shared/settings-schema\";\nimport { sql } from \"drizzle-orm\";\n\nexport interface DrizzleConfig {\n db: unknown;\n provider: \"sqlite\" | \"mysql\" | \"postgresql\";\n}\n\nexport class DrizzleAdapter implements DatabaseAdapter<DrizzleUOWConfig> {\n #drizzleConfig: DrizzleConfig;\n\n constructor(config: DrizzleConfig) {\n this.#drizzleConfig = config;\n }\n\n get provider(): \"sqlite\" | \"mysql\" | \"postgresql\" {\n return this.#drizzleConfig.provider;\n }\n\n async isConnectionHealthy(): Promise<boolean> {\n try {\n const result = await (this.#drizzleConfig.db as DBType).execute(sql`SELECT 1 as healthy`);\n\n // Handle different result formats across providers\n // PostgreSQL/MySQL: { rows: [...] }\n // SQLite: array directly or { rows: [...] }\n if (Array.isArray(result)) {\n return result.length > 0 && result[0][\"healthy\"] === 1;\n } else {\n const drizzleResult = result as DrizzleResult;\n return drizzleResult.rows[0][\"healthy\"] === 1;\n }\n } catch {\n return false;\n }\n }\n\n async getSchemaVersion(namespace: string): Promise<string | undefined> {\n const queryEngine = this.createQueryEngine(settingsSchema, namespace);\n const manager = createSettingsManager(queryEngine, namespace);\n\n // Try to read the version key directly\n const result = await manager.get(\"version\");\n return result?.value;\n }\n\n createQueryEngine<TSchema extends AnySchema>(\n schema: TSchema,\n namespace: string,\n ): AbstractQuery<TSchema, DrizzleUOWConfig> {\n // Only create mapper if namespace is non-empty\n const mapper = namespace ? createTableNameMapper(namespace) : undefined;\n return fromDrizzle(schema, this.#drizzleConfig, mapper);\n }\n\n createSchemaGenerator(\n fragments: { schema: AnySchema; namespace: string }[],\n options?: { path?: string },\n ): SchemaGenerator {\n return {\n generateSchema: (genOptions) => {\n const path = genOptions?.path ?? options?.path ?? \"fragno-schema.ts\";\n\n return {\n schema: generateSchema(fragments, this.#drizzleConfig.provider),\n path,\n };\n },\n };\n }\n}\n"],"mappings":";;;;;;;;AAeA,IAAa,iBAAb,MAAyE;CACvE;CAEA,YAAY,QAAuB;AACjC,QAAKA,gBAAiB;;CAGxB,IAAI,WAA8C;AAChD,SAAO,MAAKA,cAAe;;CAG7B,MAAM,sBAAwC;AAC5C,MAAI;GACF,MAAM,SAAS,MAAO,MAAKA,cAAe,GAAc,QAAQ,GAAG,sBAAsB;AAKzF,OAAI,MAAM,QAAQ,OAAO,CACvB,QAAO,OAAO,SAAS,KAAK,OAAO,GAAG,eAAe;OAGrD,QADsB,OACD,KAAK,GAAG,eAAe;UAExC;AACN,UAAO;;;CAIX,MAAM,iBAAiB,WAAgD;AAMrE,UADe,MAHC,sBADI,KAAK,kBAAkB,gBAAgB,UAAU,EAClB,UAAU,CAGhC,IAAI,UAAU,GAC5B;;CAGjB,kBACE,QACA,WAC0C;EAE1C,MAAM,SAAS,YAAY,sBAAsB,UAAU,GAAG;AAC9D,SAAO,YAAY,QAAQ,MAAKA,eAAgB,OAAO;;CAGzD,sBACE,WACA,SACiB;AACjB,SAAO,EACL,iBAAiB,eAAe;GAC9B,MAAM,OAAO,YAAY,QAAQ,SAAS,QAAQ;AAElD,UAAO;IACL,QAAQ,eAAe,WAAW,MAAKA,cAAe,SAAS;IAC/D;IACD;KAEJ"}
1
+ {"version":3,"file":"drizzle-adapter.js","names":["#drizzleConfig","#getDb"],"sources":["../../../src/adapters/drizzle/drizzle-adapter.ts"],"sourcesContent":["import type { DatabaseAdapter } from \"../adapters\";\nimport { type AnySchema } from \"../../schema/create\";\nimport type { AbstractQuery } from \"../../query/query\";\nimport type { SchemaGenerator } from \"../../schema-generator/schema-generator\";\nimport { generateSchema } from \"./generate\";\nimport { fromDrizzle, type DrizzleUOWConfig } from \"./drizzle-query\";\nimport { createTableNameMapper, type DBType, type DrizzleResult } from \"./shared\";\nimport { createSettingsManager, settingsSchema } from \"../../shared/settings-schema\";\nimport { sql } from \"drizzle-orm\";\n\nexport interface DrizzleConfig {\n db: unknown | (() => unknown);\n provider: \"sqlite\" | \"mysql\" | \"postgresql\";\n}\n\nexport class DrizzleAdapter implements DatabaseAdapter<DrizzleUOWConfig> {\n #drizzleConfig: DrizzleConfig;\n\n constructor(config: DrizzleConfig) {\n this.#drizzleConfig = config;\n }\n\n get provider(): \"sqlite\" | \"mysql\" | \"postgresql\" {\n return this.#drizzleConfig.provider;\n }\n\n #getDb(): DBType {\n const db = this.#drizzleConfig.db;\n return (typeof db === \"function\" ? db() : db) as DBType;\n }\n\n async isConnectionHealthy(): Promise<boolean> {\n try {\n const result = await this.#getDb().execute(sql`SELECT 1 as healthy`);\n\n // Handle different result formats across providers\n // PostgreSQL/MySQL: { rows: [...] }\n // SQLite: array directly or { rows: [...] }\n if (Array.isArray(result)) {\n return result.length > 0 && result[0][\"healthy\"] === 1;\n } else {\n const drizzleResult = result as DrizzleResult;\n return drizzleResult.rows[0][\"healthy\"] === 1;\n }\n } catch {\n return false;\n }\n }\n\n async getSchemaVersion(namespace: string): Promise<string | undefined> {\n const queryEngine = this.createQueryEngine(settingsSchema, namespace);\n const manager = createSettingsManager(queryEngine, namespace);\n\n // Try to read the version key directly\n const result = await manager.get(\"version\");\n return result?.value;\n }\n\n createQueryEngine<TSchema extends AnySchema>(\n schema: TSchema,\n namespace: string,\n ): AbstractQuery<TSchema, DrizzleUOWConfig> {\n // Only create mapper if namespace is non-empty\n const mapper = namespace ? createTableNameMapper(namespace) : undefined;\n // Resolve the db instance if it's a function\n const resolvedConfig: DrizzleConfig = {\n db: this.#getDb(),\n provider: this.#drizzleConfig.provider,\n };\n return fromDrizzle(schema, resolvedConfig, mapper);\n }\n\n createSchemaGenerator(\n fragments: { schema: AnySchema; namespace: string }[],\n options?: { path?: string },\n ): SchemaGenerator {\n return {\n generateSchema: (genOptions) => {\n const path = genOptions?.path ?? options?.path ?? \"fragno-schema.ts\";\n\n return {\n schema: generateSchema(fragments, this.#drizzleConfig.provider),\n path,\n };\n },\n };\n }\n}\n"],"mappings":";;;;;;;;AAeA,IAAa,iBAAb,MAAyE;CACvE;CAEA,YAAY,QAAuB;AACjC,QAAKA,gBAAiB;;CAGxB,IAAI,WAA8C;AAChD,SAAO,MAAKA,cAAe;;CAG7B,SAAiB;EACf,MAAM,KAAK,MAAKA,cAAe;AAC/B,SAAQ,OAAO,OAAO,aAAa,IAAI,GAAG;;CAG5C,MAAM,sBAAwC;AAC5C,MAAI;GACF,MAAM,SAAS,MAAM,MAAKC,OAAQ,CAAC,QAAQ,GAAG,sBAAsB;AAKpE,OAAI,MAAM,QAAQ,OAAO,CACvB,QAAO,OAAO,SAAS,KAAK,OAAO,GAAG,eAAe;OAGrD,QADsB,OACD,KAAK,GAAG,eAAe;UAExC;AACN,UAAO;;;CAIX,MAAM,iBAAiB,WAAgD;AAMrE,UADe,MAHC,sBADI,KAAK,kBAAkB,gBAAgB,UAAU,EAClB,UAAU,CAGhC,IAAI,UAAU,GAC5B;;CAGjB,kBACE,QACA,WAC0C;EAE1C,MAAM,SAAS,YAAY,sBAAsB,UAAU,GAAG;AAM9D,SAAO,YAAY,QAJmB;GACpC,IAAI,MAAKA,OAAQ;GACjB,UAAU,MAAKD,cAAe;GAC/B,EAC0C,OAAO;;CAGpD,sBACE,WACA,SACiB;AACjB,SAAO,EACL,iBAAiB,eAAe;GAC9B,MAAM,OAAO,YAAY,QAAQ,SAAS,QAAQ;AAElD,UAAO;IACL,QAAQ,eAAe,WAAW,MAAKA,cAAe,SAAS;IAC/D;IACD;KAEJ"}
@@ -8,7 +8,7 @@ import { Kysely } from "kysely";
8
8
  //#region src/adapters/kysely/kysely-adapter.d.ts
9
9
  type KyselyAny = Kysely<any>;
10
10
  interface KyselyConfig {
11
- db: KyselyAny;
11
+ db: KyselyAny | (() => KyselyAny);
12
12
  provider: SQLProvider;
13
13
  }
14
14
  declare class KyselyAdapter implements DatabaseAdapter {
@@ -1 +1 @@
1
- {"version":3,"file":"kysely-adapter.d.ts","names":[],"sources":["../../../src/adapters/kysely/kysely-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAcK,SAAA,GAAY;UAEA,YAAA;EAFZ,EAAA,EAGC,SAHQ;EAEG,QAAA,EAEL,WAFiB;AAK7B;AAGsB,cAHT,aAAA,YAAyB,eAGhB,CAAA;EAIQ,CAAA,OAAA;EAAmB,WAAA,CAAA,MAAA,EAJ3B,YAI2B;EAAqC,iBAAA,CAAA,UAAxD,SAAwD,CAAA,CAAA,MAAA,EAArC,CAAqC,EAAA,SAAA,EAAA,MAAA,CAAA,EAAd,aAAc,CAAA,CAAA,CAAA;EAAd,mBAAA,CAAA,CAAA,EAMzC,OANyC,CAAA,OAAA,CAAA;EAMzC,qBAAA,CAAA,MAAA,EAWC,SAXD,EAAA,SAAA,EAAA,MAAA,CAAA,EAWgC,QAXhC;EAWC,gBAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAkGI,OAlGJ,CAAA,MAAA,GAAA,SAAA,CAAA"}
1
+ {"version":3,"file":"kysely-adapter.d.ts","names":[],"sources":["../../../src/adapters/kysely/kysely-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAcK,SAAA,GAAY;UAEA,YAAA;EAFZ,EAAA,EAGC,SAHQ,GAAA,CAAA,GAAA,GAGW,SAHF,CAAA;EAEN,QAAA,EAEL,WAFiB;;AACJ,cAIZ,aAAA,YAAyB,eAJb,CAAA;EACb,CAAA,OAAA;EAAW,WAAA,CAAA,MAAA,EAMD,YANC;EAGV,iBAAc,CAAA,UAYG,SAZH,CAAA,CAAA,MAAA,EAYsB,CAZtB,EAAA,SAAA,EAAA,MAAA,CAAA,EAY6C,aAZ7C,CAY2D,CAZ3D,CAAA;EAGL,mBAAA,CAAA,CAAA,EAoBS,OApBT,CAAA,OAAA,CAAA;EASQ,qBAAA,CAAA,MAAA,EAqBE,SArBF,EAAA,SAAA,EAAA,MAAA,CAAA,EAqBiC,QArBjC;EAAmB,gBAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAwHb,OAxHa,CAAA,MAAA,GAAA,SAAA,CAAA"}
@@ -12,19 +12,27 @@ var KyselyAdapter = class {
12
12
  constructor(config) {
13
13
  this.#kyselyConfig = config;
14
14
  }
15
+ #getDb() {
16
+ const db = this.#kyselyConfig.db;
17
+ return typeof db === "function" ? db() : db;
18
+ }
15
19
  createQueryEngine(schema, namespace) {
16
20
  const mapper = namespace ? createTableNameMapper(namespace) : void 0;
17
- return fromKysely(schema, this.#kyselyConfig, mapper);
21
+ return fromKysely(schema, {
22
+ db: this.#getDb(),
23
+ provider: this.#kyselyConfig.provider
24
+ }, mapper);
18
25
  }
19
26
  async isConnectionHealthy() {
20
27
  try {
21
- return (await this.#kyselyConfig.db.executeQuery(sql`SELECT 1 as healthy`.compile(this.#kyselyConfig.db))).rows[0]["healthy"] === 1;
28
+ const db = this.#getDb();
29
+ return (await db.executeQuery(sql`SELECT 1 as healthy`.compile(db))).rows[0]["healthy"] === 1;
22
30
  } catch {
23
31
  return false;
24
32
  }
25
33
  }
26
34
  createMigrationEngine(schema, namespace) {
27
- const manager = createSettingsManager(this.#kyselyConfig.db, namespace);
35
+ const manager = createSettingsManager(this.#getDb(), namespace);
28
36
  const mapper = namespace ? createTableNameMapper(namespace) : void 0;
29
37
  const preprocessMigrationOperations = (operations) => {
30
38
  let preprocessed = preprocessOperations(operations, this.#kyselyConfig);
@@ -61,8 +69,9 @@ var KyselyAdapter = class {
61
69
  return createMigrator({
62
70
  schema,
63
71
  executor: async (operations) => {
64
- if (this.#kyselyConfig.provider === "sqlite") await sql.raw("PRAGMA defer_foreign_keys = ON").execute(this.#kyselyConfig.db);
65
- await this.#kyselyConfig.db.transaction().execute(async (tx) => {
72
+ const db = this.#getDb();
73
+ if (this.#kyselyConfig.provider === "sqlite") await sql.raw("PRAGMA defer_foreign_keys = ON").execute(db);
74
+ await db.transaction().execute(async (tx) => {
66
75
  const nodes = toExecutableNodes(preprocessMigrationOperations(operations), tx);
67
76
  for (const node of nodes) try {
68
77
  await node.execute();
@@ -75,7 +84,7 @@ var KyselyAdapter = class {
75
84
  sql: { toSql: (operations) => {
76
85
  const parts = [];
77
86
  if (this.#kyselyConfig.provider === "sqlite") parts.push("PRAGMA defer_foreign_keys = ON;");
78
- const compiled = toExecutableNodes(preprocessMigrationOperations(operations), this.#kyselyConfig.db).map((node) => `${node.compile().sql};`);
87
+ const compiled = toExecutableNodes(preprocessMigrationOperations(operations), this.#getDb()).map((node) => `${node.compile().sql};`);
79
88
  parts.push(...compiled);
80
89
  return parts.join("\n\n");
81
90
  } },
@@ -94,7 +103,7 @@ var KyselyAdapter = class {
94
103
  });
95
104
  }
96
105
  getSchemaVersion(namespace) {
97
- return createSettingsManager(this.#kyselyConfig.db, namespace).get(`schema_version`);
106
+ return createSettingsManager(this.#getDb(), namespace).get(`schema_version`);
98
107
  }
99
108
  };
100
109
  function createSettingsManager(db, namespace) {
@@ -1 +1 @@
1
- {"version":3,"file":"kysely-adapter.js","names":["#kyselyConfig","db","dbConfig: KyselyConfig","parts: string[]"],"sources":["../../../src/adapters/kysely/kysely-adapter.ts"],"sourcesContent":["import { sql, type Kysely } from \"kysely\";\nimport type { SQLProvider } from \"../../shared/providers\";\nimport type { DatabaseAdapter } from \"../adapters\";\nimport { createMigrator, type Migrator } from \"../../migration-engine/create\";\nimport type { AnySchema } from \"../../schema/create\";\nimport type { CustomOperation, MigrationOperation } from \"../../migration-engine/shared\";\nimport { execute, preprocessOperations } from \"./migration/execute\";\nimport type { AbstractQuery } from \"../../query/query\";\nimport { fromKysely } from \"./kysely-query\";\nimport { createTableNameMapper } from \"./kysely-shared\";\nimport { createHash } from \"node:crypto\";\nimport { SETTINGS_TABLE_NAME } from \"../../shared/settings-schema\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype KyselyAny = Kysely<any>;\n\nexport interface KyselyConfig {\n db: KyselyAny;\n provider: SQLProvider;\n}\n\nexport class KyselyAdapter implements DatabaseAdapter {\n #kyselyConfig: KyselyConfig;\n\n constructor(config: KyselyConfig) {\n this.#kyselyConfig = config;\n }\n\n createQueryEngine<T extends AnySchema>(schema: T, namespace: string): AbstractQuery<T> {\n // Only create mapper if namespace is non-empty\n const mapper = namespace ? createTableNameMapper(namespace) : undefined;\n return fromKysely(schema, this.#kyselyConfig, mapper);\n }\n\n async isConnectionHealthy(): Promise<boolean> {\n try {\n const result = await this.#kyselyConfig.db.executeQuery(\n sql`SELECT 1 as healthy`.compile(this.#kyselyConfig.db),\n );\n return (result.rows[0] as Record<string, unknown>)[\"healthy\"] === 1;\n } catch {\n return false;\n }\n }\n\n createMigrationEngine(schema: AnySchema, namespace: string): Migrator {\n const manager = createSettingsManager(this.#kyselyConfig.db, namespace);\n const mapper = namespace ? createTableNameMapper(namespace) : undefined;\n\n const preprocessMigrationOperations = (operations: MigrationOperation[]) => {\n let preprocessed = preprocessOperations(operations, this.#kyselyConfig);\n\n if (this.#kyselyConfig.provider === \"mysql\") {\n preprocessed.unshift({ type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 0\" });\n preprocessed.push({ type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 1\" });\n }\n\n return preprocessed;\n };\n\n // Convert operations to executable nodes bound to specific db instance\n const toExecutableNodes = (operations: MigrationOperation[], db: KyselyAny) => {\n const onCustomNode = (node: CustomOperation, db: KyselyAny) => {\n const statement = sql.raw(node[\"sql\"] as string);\n\n return {\n compile() {\n return statement.compile(db);\n },\n execute() {\n return statement.execute(db);\n },\n };\n };\n\n const dbConfig: KyselyConfig = { db, provider: this.#kyselyConfig.provider };\n return operations.flatMap((op) =>\n execute(op, dbConfig, (node) => onCustomNode(node, db), mapper),\n );\n };\n\n const migrator = createMigrator({\n schema,\n executor: async (operations) => {\n // For SQLite, execute PRAGMA defer_foreign_keys BEFORE transaction\n if (this.#kyselyConfig.provider === \"sqlite\") {\n await sql.raw(\"PRAGMA defer_foreign_keys = ON\").execute(this.#kyselyConfig.db);\n }\n\n await this.#kyselyConfig.db.transaction().execute(async (tx) => {\n const preprocessed = preprocessMigrationOperations(operations);\n const nodes = toExecutableNodes(preprocessed, tx);\n for (const node of nodes) {\n try {\n await node.execute();\n } catch (e) {\n console.error(\"failed at\", node.compile(), e);\n throw e;\n }\n }\n });\n },\n sql: {\n toSql: (operations) => {\n const parts: string[] = [];\n\n // Add SQLite PRAGMA at the beginning\n if (this.#kyselyConfig.provider === \"sqlite\") {\n parts.push(\"PRAGMA defer_foreign_keys = ON;\");\n }\n\n const preprocessed = preprocessMigrationOperations(operations);\n const nodes = toExecutableNodes(preprocessed, this.#kyselyConfig.db);\n const compiled = nodes.map((node) => `${node.compile().sql};`);\n\n parts.push(...compiled);\n\n return parts.join(\"\\n\\n\");\n },\n },\n\n settings: {\n getVersion: async () => {\n const v = await manager.get(`schema_version`);\n return v ? parseInt(v) : 0;\n },\n updateSettingsInMigration: async (fromVersion, toVersion) => {\n return [\n {\n type: \"custom\",\n sql:\n fromVersion === 0\n ? manager.insert(`schema_version`, toVersion.toString())\n : manager.update(`schema_version`, toVersion.toString()),\n },\n ];\n },\n },\n });\n\n return migrator;\n }\n\n getSchemaVersion(namespace: string) {\n const manager = createSettingsManager(this.#kyselyConfig.db, namespace);\n\n return manager.get(`schema_version`);\n }\n}\n\nfunction createSettingsManager(db: KyselyAny, namespace: string) {\n // Settings table is never namespaced, but keys include namespace prefix\n const tableName = SETTINGS_TABLE_NAME;\n\n return {\n async get(key: string): Promise<string | undefined> {\n try {\n const result = await db\n .selectFrom(tableName)\n .where(\"key\", \"=\", sql.lit(`${namespace}.${key}`))\n .select([\"value\"])\n .executeTakeFirstOrThrow();\n return result.value as string;\n } catch {\n return;\n }\n },\n\n insert(key: string, value: string) {\n return db\n .insertInto(tableName)\n .values({\n id: sql.lit(\n createHash(\"md5\").update(`${namespace}.${key}`).digest(\"base64url\").replace(/=/g, \"\"),\n ),\n key: sql.lit(`${namespace}.${key}`),\n value: sql.lit(value),\n })\n .compile().sql;\n },\n\n update(key: string, value: string) {\n return db\n .updateTable(tableName)\n .set({\n value: sql.lit(value),\n })\n .where(\"key\", \"=\", sql.lit(`${namespace}.${key}`))\n .compile().sql;\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"kysely-adapter.js","names":["#kyselyConfig","#getDb","db","dbConfig: KyselyConfig","parts: string[]"],"sources":["../../../src/adapters/kysely/kysely-adapter.ts"],"sourcesContent":["import { sql, type Kysely } from \"kysely\";\nimport type { SQLProvider } from \"../../shared/providers\";\nimport type { DatabaseAdapter } from \"../adapters\";\nimport { createMigrator, type Migrator } from \"../../migration-engine/create\";\nimport type { AnySchema } from \"../../schema/create\";\nimport type { CustomOperation, MigrationOperation } from \"../../migration-engine/shared\";\nimport { execute, preprocessOperations } from \"./migration/execute\";\nimport type { AbstractQuery } from \"../../query/query\";\nimport { fromKysely } from \"./kysely-query\";\nimport { createTableNameMapper } from \"./kysely-shared\";\nimport { createHash } from \"node:crypto\";\nimport { SETTINGS_TABLE_NAME } from \"../../shared/settings-schema\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype KyselyAny = Kysely<any>;\n\nexport interface KyselyConfig {\n db: KyselyAny | (() => KyselyAny);\n provider: SQLProvider;\n}\n\nexport class KyselyAdapter implements DatabaseAdapter {\n #kyselyConfig: KyselyConfig;\n\n constructor(config: KyselyConfig) {\n this.#kyselyConfig = config;\n }\n\n #getDb(): KyselyAny {\n const db = this.#kyselyConfig.db;\n return typeof db === \"function\" ? db() : db;\n }\n\n createQueryEngine<T extends AnySchema>(schema: T, namespace: string): AbstractQuery<T> {\n // Only create mapper if namespace is non-empty\n const mapper = namespace ? createTableNameMapper(namespace) : undefined;\n // Resolve the db instance if it's a function\n const resolvedConfig: KyselyConfig = {\n db: this.#getDb(),\n provider: this.#kyselyConfig.provider,\n };\n return fromKysely(schema, resolvedConfig, mapper);\n }\n\n async isConnectionHealthy(): Promise<boolean> {\n try {\n const db = this.#getDb();\n const result = await db.executeQuery(sql`SELECT 1 as healthy`.compile(db));\n return (result.rows[0] as Record<string, unknown>)[\"healthy\"] === 1;\n } catch {\n return false;\n }\n }\n\n createMigrationEngine(schema: AnySchema, namespace: string): Migrator {\n const manager = createSettingsManager(this.#getDb(), namespace);\n const mapper = namespace ? createTableNameMapper(namespace) : undefined;\n\n const preprocessMigrationOperations = (operations: MigrationOperation[]) => {\n let preprocessed = preprocessOperations(operations, this.#kyselyConfig);\n\n if (this.#kyselyConfig.provider === \"mysql\") {\n preprocessed.unshift({ type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 0\" });\n preprocessed.push({ type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 1\" });\n }\n\n return preprocessed;\n };\n\n // Convert operations to executable nodes bound to specific db instance\n const toExecutableNodes = (operations: MigrationOperation[], db: KyselyAny) => {\n const onCustomNode = (node: CustomOperation, db: KyselyAny) => {\n const statement = sql.raw(node[\"sql\"] as string);\n\n return {\n compile() {\n return statement.compile(db);\n },\n execute() {\n return statement.execute(db);\n },\n };\n };\n\n const dbConfig: KyselyConfig = { db, provider: this.#kyselyConfig.provider };\n return operations.flatMap((op) =>\n execute(op, dbConfig, (node) => onCustomNode(node, db), mapper),\n );\n };\n\n const migrator = createMigrator({\n schema,\n executor: async (operations) => {\n const db = this.#getDb();\n // For SQLite, execute PRAGMA defer_foreign_keys BEFORE transaction\n if (this.#kyselyConfig.provider === \"sqlite\") {\n await sql.raw(\"PRAGMA defer_foreign_keys = ON\").execute(db);\n }\n\n await db.transaction().execute(async (tx) => {\n const preprocessed = preprocessMigrationOperations(operations);\n const nodes = toExecutableNodes(preprocessed, tx);\n for (const node of nodes) {\n try {\n await node.execute();\n } catch (e) {\n console.error(\"failed at\", node.compile(), e);\n throw e;\n }\n }\n });\n },\n sql: {\n toSql: (operations) => {\n const parts: string[] = [];\n\n // Add SQLite PRAGMA at the beginning\n if (this.#kyselyConfig.provider === \"sqlite\") {\n parts.push(\"PRAGMA defer_foreign_keys = ON;\");\n }\n\n const preprocessed = preprocessMigrationOperations(operations);\n const nodes = toExecutableNodes(preprocessed, this.#getDb());\n const compiled = nodes.map((node) => `${node.compile().sql};`);\n\n parts.push(...compiled);\n\n return parts.join(\"\\n\\n\");\n },\n },\n\n settings: {\n getVersion: async () => {\n const v = await manager.get(`schema_version`);\n return v ? parseInt(v) : 0;\n },\n updateSettingsInMigration: async (fromVersion, toVersion) => {\n return [\n {\n type: \"custom\",\n sql:\n fromVersion === 0\n ? manager.insert(`schema_version`, toVersion.toString())\n : manager.update(`schema_version`, toVersion.toString()),\n },\n ];\n },\n },\n });\n\n return migrator;\n }\n\n getSchemaVersion(namespace: string) {\n const manager = createSettingsManager(this.#getDb(), namespace);\n\n return manager.get(`schema_version`);\n }\n}\n\nfunction createSettingsManager(db: KyselyAny, namespace: string) {\n // Settings table is never namespaced, but keys include namespace prefix\n const tableName = SETTINGS_TABLE_NAME;\n\n return {\n async get(key: string): Promise<string | undefined> {\n try {\n const result = await db\n .selectFrom(tableName)\n .where(\"key\", \"=\", sql.lit(`${namespace}.${key}`))\n .select([\"value\"])\n .executeTakeFirstOrThrow();\n return result.value as string;\n } catch {\n return;\n }\n },\n\n insert(key: string, value: string) {\n return db\n .insertInto(tableName)\n .values({\n id: sql.lit(\n createHash(\"md5\").update(`${namespace}.${key}`).digest(\"base64url\").replace(/=/g, \"\"),\n ),\n key: sql.lit(`${namespace}.${key}`),\n value: sql.lit(value),\n })\n .compile().sql;\n },\n\n update(key: string, value: string) {\n return db\n .updateTable(tableName)\n .set({\n value: sql.lit(value),\n })\n .where(\"key\", \"=\", sql.lit(`${namespace}.${key}`))\n .compile().sql;\n },\n };\n}\n"],"mappings":"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"}
@@ -4,8 +4,8 @@ import { createKyselyQueryBuilder } from "./kysely-query-builder.js";
4
4
 
5
5
  //#region src/adapters/kysely/kysely-query-compiler.ts
6
6
  function createKyselyQueryCompiler(schema, config, mapper) {
7
- const { db: kysely, provider } = config;
8
- const queryBuilder = createKyselyQueryBuilder(kysely, provider, mapper);
7
+ const { db, provider } = config;
8
+ const queryBuilder = createKyselyQueryBuilder(typeof db === "function" ? db() : db, provider, mapper);
9
9
  function toTable(name) {
10
10
  const table = schema.tables[name];
11
11
  if (!table) throw new Error(`Invalid table name ${name}.`);
@@ -1 +1 @@
1
- {"version":3,"file":"kysely-query-compiler.js","names":[],"sources":["../../../src/adapters/kysely/kysely-query-compiler.ts"],"sourcesContent":["import type { CompiledQuery } from \"kysely\";\nimport type { AnySchema, AnyTable } from \"../../schema/create\";\nimport { buildCondition } from \"../../query/condition-builder\";\nimport { buildFindOptions } from \"../../query/orm/orm\";\nimport type { KyselyConfig } from \"./kysely-adapter\";\nimport { createKyselyQueryBuilder } from \"./kysely-query-builder\";\nimport type { ConditionBuilder, Condition } from \"../../query/condition-builder\";\nimport type { TableNameMapper } from \"./kysely-shared\";\n\n/**\n * Internal query compiler interface for Kysely\n * Used by the UOW compiler to generate compiled queries\n */\nexport interface KyselyQueryCompiler {\n count: (\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: { where?: (eb: ConditionBuilder<any>) => any },\n ) => CompiledQuery | null;\n findFirst: (name: string, options: any) => CompiledQuery | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n findMany: (name: string, options?: any) => CompiledQuery | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n create: (name: string, values: any) => CompiledQuery; // eslint-disable-line @typescript-eslint/no-explicit-any\n createMany: (name: string, values: any[]) => CompiledQuery; // eslint-disable-line @typescript-eslint/no-explicit-any\n updateMany: (name: string, options: { set: any; where?: any }) => CompiledQuery | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n deleteMany: (name: string, options: { where?: any }) => CompiledQuery | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n\nexport function createKyselyQueryCompiler<T extends AnySchema>(\n schema: T,\n config: KyselyConfig,\n mapper?: TableNameMapper,\n): KyselyQueryCompiler {\n const { db: kysely, provider } = config;\n const queryBuilder = createKyselyQueryBuilder(kysely, provider, mapper);\n\n function toTable(name: unknown): AnyTable {\n const table = schema.tables[name as string];\n if (!table) {\n throw new Error(`Invalid table name ${name}.`);\n }\n return table;\n }\n\n return {\n count(name, { where } = {}) {\n const table = toTable(name);\n let conditions = where ? buildCondition(table.columns, where) : undefined;\n if (conditions === true) {\n conditions = undefined;\n }\n if (conditions === false) {\n return null;\n }\n\n return queryBuilder.count(table, { where: conditions });\n },\n\n findFirst(name, options) {\n const table = toTable(name);\n // Safe cast: FindFirstOptions is structurally compatible with FindManyOptions\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const compiledOptions = buildFindOptions(table, options as any);\n if (compiledOptions === false) {\n return null;\n }\n\n return queryBuilder.findMany(table, {\n ...compiledOptions,\n limit: 1,\n });\n },\n\n findMany(name, options = {}) {\n const table = toTable(name);\n // Safe cast: FindManyOptions from compiler matches FindManyOptions from buildFindOptions\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const compiledOptions = buildFindOptions(table, options as any);\n if (compiledOptions === false) {\n return null;\n }\n\n return queryBuilder.findMany(table, compiledOptions);\n },\n\n create(name, values) {\n const table = toTable(name);\n return queryBuilder.create(table, values);\n },\n\n createMany(name, values) {\n const table = toTable(name);\n return queryBuilder.createMany(table, values);\n },\n\n updateMany(name, { set, where }) {\n const table = toTable(name);\n let conditions = where ? buildCondition(table.columns, where) : undefined;\n if (conditions === true) {\n conditions = undefined;\n }\n if (conditions === false) {\n return null;\n }\n\n // Safe: conditions is Condition | undefined after filtering out true/false\n return queryBuilder.updateMany(table, {\n set,\n where: conditions as Condition | undefined,\n });\n },\n\n deleteMany(name, { where }) {\n const table = toTable(name);\n let conditions = where ? buildCondition(table.columns, where) : undefined;\n if (conditions === true) {\n conditions = undefined;\n }\n if (conditions === false) {\n return null;\n }\n\n // Safe: conditions is Condition | undefined after filtering out true/false\n return queryBuilder.deleteMany(table, { where: conditions as Condition | undefined });\n },\n };\n}\n"],"mappings":";;;;;AA2BA,SAAgB,0BACd,QACA,QACA,QACqB;CACrB,MAAM,EAAE,IAAI,QAAQ,aAAa;CACjC,MAAM,eAAe,yBAAyB,QAAQ,UAAU,OAAO;CAEvE,SAAS,QAAQ,MAAyB;EACxC,MAAM,QAAQ,OAAO,OAAO;AAC5B,MAAI,CAAC,MACH,OAAM,IAAI,MAAM,sBAAsB,KAAK,GAAG;AAEhD,SAAO;;AAGT,QAAO;EACL,MAAM,MAAM,EAAE,UAAU,EAAE,EAAE;GAC1B,MAAM,QAAQ,QAAQ,KAAK;GAC3B,IAAI,aAAa,QAAQ,eAAe,MAAM,SAAS,MAAM,GAAG;AAChE,OAAI,eAAe,KACjB,cAAa;AAEf,OAAI,eAAe,MACjB,QAAO;AAGT,UAAO,aAAa,MAAM,OAAO,EAAE,OAAO,YAAY,CAAC;;EAGzD,UAAU,MAAM,SAAS;GACvB,MAAM,QAAQ,QAAQ,KAAK;GAG3B,MAAM,kBAAkB,iBAAiB,OAAO,QAAe;AAC/D,OAAI,oBAAoB,MACtB,QAAO;AAGT,UAAO,aAAa,SAAS,OAAO;IAClC,GAAG;IACH,OAAO;IACR,CAAC;;EAGJ,SAAS,MAAM,UAAU,EAAE,EAAE;GAC3B,MAAM,QAAQ,QAAQ,KAAK;GAG3B,MAAM,kBAAkB,iBAAiB,OAAO,QAAe;AAC/D,OAAI,oBAAoB,MACtB,QAAO;AAGT,UAAO,aAAa,SAAS,OAAO,gBAAgB;;EAGtD,OAAO,MAAM,QAAQ;GACnB,MAAM,QAAQ,QAAQ,KAAK;AAC3B,UAAO,aAAa,OAAO,OAAO,OAAO;;EAG3C,WAAW,MAAM,QAAQ;GACvB,MAAM,QAAQ,QAAQ,KAAK;AAC3B,UAAO,aAAa,WAAW,OAAO,OAAO;;EAG/C,WAAW,MAAM,EAAE,KAAK,SAAS;GAC/B,MAAM,QAAQ,QAAQ,KAAK;GAC3B,IAAI,aAAa,QAAQ,eAAe,MAAM,SAAS,MAAM,GAAG;AAChE,OAAI,eAAe,KACjB,cAAa;AAEf,OAAI,eAAe,MACjB,QAAO;AAIT,UAAO,aAAa,WAAW,OAAO;IACpC;IACA,OAAO;IACR,CAAC;;EAGJ,WAAW,MAAM,EAAE,SAAS;GAC1B,MAAM,QAAQ,QAAQ,KAAK;GAC3B,IAAI,aAAa,QAAQ,eAAe,MAAM,SAAS,MAAM,GAAG;AAChE,OAAI,eAAe,KACjB,cAAa;AAEf,OAAI,eAAe,MACjB,QAAO;AAIT,UAAO,aAAa,WAAW,OAAO,EAAE,OAAO,YAAqC,CAAC;;EAExF"}
1
+ {"version":3,"file":"kysely-query-compiler.js","names":[],"sources":["../../../src/adapters/kysely/kysely-query-compiler.ts"],"sourcesContent":["import type { CompiledQuery } from \"kysely\";\nimport type { AnySchema, AnyTable } from \"../../schema/create\";\nimport { buildCondition } from \"../../query/condition-builder\";\nimport { buildFindOptions } from \"../../query/orm/orm\";\nimport type { KyselyConfig } from \"./kysely-adapter\";\nimport { createKyselyQueryBuilder } from \"./kysely-query-builder\";\nimport type { ConditionBuilder, Condition } from \"../../query/condition-builder\";\nimport type { TableNameMapper } from \"./kysely-shared\";\n\n/**\n * Internal query compiler interface for Kysely\n * Used by the UOW compiler to generate compiled queries\n */\nexport interface KyselyQueryCompiler {\n count: (\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: { where?: (eb: ConditionBuilder<any>) => any },\n ) => CompiledQuery | null;\n findFirst: (name: string, options: any) => CompiledQuery | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n findMany: (name: string, options?: any) => CompiledQuery | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n create: (name: string, values: any) => CompiledQuery; // eslint-disable-line @typescript-eslint/no-explicit-any\n createMany: (name: string, values: any[]) => CompiledQuery; // eslint-disable-line @typescript-eslint/no-explicit-any\n updateMany: (name: string, options: { set: any; where?: any }) => CompiledQuery | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n deleteMany: (name: string, options: { where?: any }) => CompiledQuery | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n\nexport function createKyselyQueryCompiler<T extends AnySchema>(\n schema: T,\n config: KyselyConfig,\n mapper?: TableNameMapper,\n): KyselyQueryCompiler {\n const { db, provider } = config;\n // Resolve the db instance if it's a function\n const kysely = typeof db === \"function\" ? db() : db;\n const queryBuilder = createKyselyQueryBuilder(kysely, provider, mapper);\n\n function toTable(name: unknown): AnyTable {\n const table = schema.tables[name as string];\n if (!table) {\n throw new Error(`Invalid table name ${name}.`);\n }\n return table;\n }\n\n return {\n count(name, { where } = {}) {\n const table = toTable(name);\n let conditions = where ? buildCondition(table.columns, where) : undefined;\n if (conditions === true) {\n conditions = undefined;\n }\n if (conditions === false) {\n return null;\n }\n\n return queryBuilder.count(table, { where: conditions });\n },\n\n findFirst(name, options) {\n const table = toTable(name);\n // Safe cast: FindFirstOptions is structurally compatible with FindManyOptions\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const compiledOptions = buildFindOptions(table, options as any);\n if (compiledOptions === false) {\n return null;\n }\n\n return queryBuilder.findMany(table, {\n ...compiledOptions,\n limit: 1,\n });\n },\n\n findMany(name, options = {}) {\n const table = toTable(name);\n // Safe cast: FindManyOptions from compiler matches FindManyOptions from buildFindOptions\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const compiledOptions = buildFindOptions(table, options as any);\n if (compiledOptions === false) {\n return null;\n }\n\n return queryBuilder.findMany(table, compiledOptions);\n },\n\n create(name, values) {\n const table = toTable(name);\n return queryBuilder.create(table, values);\n },\n\n createMany(name, values) {\n const table = toTable(name);\n return queryBuilder.createMany(table, values);\n },\n\n updateMany(name, { set, where }) {\n const table = toTable(name);\n let conditions = where ? buildCondition(table.columns, where) : undefined;\n if (conditions === true) {\n conditions = undefined;\n }\n if (conditions === false) {\n return null;\n }\n\n // Safe: conditions is Condition | undefined after filtering out true/false\n return queryBuilder.updateMany(table, {\n set,\n where: conditions as Condition | undefined,\n });\n },\n\n deleteMany(name, { where }) {\n const table = toTable(name);\n let conditions = where ? buildCondition(table.columns, where) : undefined;\n if (conditions === true) {\n conditions = undefined;\n }\n if (conditions === false) {\n return null;\n }\n\n // Safe: conditions is Condition | undefined after filtering out true/false\n return queryBuilder.deleteMany(table, { where: conditions as Condition | undefined });\n },\n };\n}\n"],"mappings":";;;;;AA2BA,SAAgB,0BACd,QACA,QACA,QACqB;CACrB,MAAM,EAAE,IAAI,aAAa;CAGzB,MAAM,eAAe,yBADN,OAAO,OAAO,aAAa,IAAI,GAAG,IACK,UAAU,OAAO;CAEvE,SAAS,QAAQ,MAAyB;EACxC,MAAM,QAAQ,OAAO,OAAO;AAC5B,MAAI,CAAC,MACH,OAAM,IAAI,MAAM,sBAAsB,KAAK,GAAG;AAEhD,SAAO;;AAGT,QAAO;EACL,MAAM,MAAM,EAAE,UAAU,EAAE,EAAE;GAC1B,MAAM,QAAQ,QAAQ,KAAK;GAC3B,IAAI,aAAa,QAAQ,eAAe,MAAM,SAAS,MAAM,GAAG;AAChE,OAAI,eAAe,KACjB,cAAa;AAEf,OAAI,eAAe,MACjB,QAAO;AAGT,UAAO,aAAa,MAAM,OAAO,EAAE,OAAO,YAAY,CAAC;;EAGzD,UAAU,MAAM,SAAS;GACvB,MAAM,QAAQ,QAAQ,KAAK;GAG3B,MAAM,kBAAkB,iBAAiB,OAAO,QAAe;AAC/D,OAAI,oBAAoB,MACtB,QAAO;AAGT,UAAO,aAAa,SAAS,OAAO;IAClC,GAAG;IACH,OAAO;IACR,CAAC;;EAGJ,SAAS,MAAM,UAAU,EAAE,EAAE;GAC3B,MAAM,QAAQ,QAAQ,KAAK;GAG3B,MAAM,kBAAkB,iBAAiB,OAAO,QAAe;AAC/D,OAAI,oBAAoB,MACtB,QAAO;AAGT,UAAO,aAAa,SAAS,OAAO,gBAAgB;;EAGtD,OAAO,MAAM,QAAQ;GACnB,MAAM,QAAQ,QAAQ,KAAK;AAC3B,UAAO,aAAa,OAAO,OAAO,OAAO;;EAG3C,WAAW,MAAM,QAAQ;GACvB,MAAM,QAAQ,QAAQ,KAAK;AAC3B,UAAO,aAAa,WAAW,OAAO,OAAO;;EAG/C,WAAW,MAAM,EAAE,KAAK,SAAS;GAC/B,MAAM,QAAQ,QAAQ,KAAK;GAC3B,IAAI,aAAa,QAAQ,eAAe,MAAM,SAAS,MAAM,GAAG;AAChE,OAAI,eAAe,KACjB,cAAa;AAEf,OAAI,eAAe,MACjB,QAAO;AAIT,UAAO,aAAa,WAAW,OAAO;IACpC;IACA,OAAO;IACR,CAAC;;EAGJ,WAAW,MAAM,EAAE,SAAS;GAC1B,MAAM,QAAQ,QAAQ,KAAK;GAC3B,IAAI,aAAa,QAAQ,eAAe,MAAM,SAAS,MAAM,GAAG;AAChE,OAAI,eAAe,KACjB,cAAa;AAEf,OAAI,eAAe,MACjB,QAAO;AAIT,UAAO,aAAa,WAAW,OAAO,EAAE,OAAO,YAAqC,CAAC;;EAExF"}
@@ -30,7 +30,8 @@ import { executeKyselyMutationPhase, executeKyselyRetrievalPhase } from "./kysel
30
30
  * ```
31
31
  */
32
32
  function fromKysely(schema, config, mapper) {
33
- const { db: kysely, provider } = config;
33
+ const { db, provider } = config;
34
+ const kysely = typeof db === "function" ? db() : db;
34
35
  const uowCompiler = createKyselyUOWCompiler(schema, config, mapper);
35
36
  function createUOW(name) {
36
37
  const executor = {
@@ -1 +1 @@
1
- {"version":3,"file":"kysely-query.js","names":["executor: UOWExecutor<CompiledQuery, unknown>","decoder: UOWDecoder<T>","whereConfig: { indexName?: string; condition?: unknown }","setValues: unknown"],"sources":["../../../src/adapters/kysely/kysely-query.ts"],"sourcesContent":["import type { AbstractQuery } from \"../../query/query\";\nimport type { AnySchema } from \"../../schema/create\";\nimport type { KyselyConfig } from \"./kysely-adapter\";\nimport type { CompiledMutation, UOWDecoder, UOWExecutor } from \"../../query/unit-of-work\";\nimport { decodeResult } from \"../../query/result-transform\";\nimport { createKyselyUOWCompiler } from \"./kysely-uow-compiler\";\nimport { executeKyselyRetrievalPhase, executeKyselyMutationPhase } from \"./kysely-uow-executor\";\nimport { UnitOfWork } from \"../../query/unit-of-work\";\nimport type { CompiledQuery } from \"kysely\";\nimport type { TableNameMapper } from \"./kysely-shared\";\n\n/**\n * Creates a Kysely-based query engine for the given schema.\n *\n * This is the main entry point for creating a database query interface using Kysely.\n * It uses a compiler-based architecture where queries are compiled to SQL and then executed,\n * enabling features like SQL snapshot testing.\n *\n * @param schema - The database schema definition\n * @param config - Kysely configuration containing the database instance and provider\n * @param mapper - Optional table name mapper for namespace prefixing\n * @returns An AbstractQuery instance for performing database operations\n *\n * @example\n * ```ts\n * const queryEngine = fromKysely(mySchema, {\n * db: kysely,\n * provider: 'postgresql'\n * });\n *\n * const users = await queryEngine.findMany('users', {\n * where: (b) => b('age', '>', 18),\n * orderBy: [['name', 'asc']]\n * });\n * ```\n */\nexport function fromKysely<T extends AnySchema>(\n schema: T,\n config: KyselyConfig,\n mapper?: TableNameMapper,\n): AbstractQuery<T> {\n const { db: kysely, provider } = config;\n const uowCompiler = createKyselyUOWCompiler(schema, config, mapper);\n\n function createUOW(name?: string): UnitOfWork<T, []> {\n const executor: UOWExecutor<CompiledQuery, unknown> = {\n executeRetrievalPhase: (retrievalBatch: CompiledQuery[]) =>\n executeKyselyRetrievalPhase(kysely, retrievalBatch),\n executeMutationPhase: (mutationBatch: CompiledMutation<CompiledQuery>[]) =>\n executeKyselyMutationPhase(kysely, mutationBatch),\n };\n\n // Create a decoder function to transform raw results into application format\n const decoder: UOWDecoder<T> = (rawResults, ops) => {\n if (rawResults.length !== ops.length) {\n throw new Error(\"rawResults and ops must have the same length\");\n }\n\n return rawResults.map((rows, index) => {\n const op = ops[index];\n if (!op) {\n throw new Error(\"op must be defined\");\n }\n\n // Handle count operations differently - return the count number directly\n if (op.type === \"count\") {\n const rowArray = rows as Record<string, unknown>[];\n const firstRow = rowArray[0];\n if (!firstRow) {\n return 0;\n }\n const count = Number(firstRow[\"count\"]);\n if (Number.isNaN(count)) {\n throw new Error(`Unexpected result for count, received: ${count}`);\n }\n return count;\n }\n\n // Each result is an array of rows - decode each row\n const rowArray = rows as Record<string, unknown>[];\n return rowArray.map((row) => decodeResult(row, op.table, provider));\n });\n };\n\n return new UnitOfWork(schema, uowCompiler, executor, decoder, name);\n }\n\n return {\n async find(tableName, builderFn) {\n const uow = createUOW();\n uow.find(tableName, builderFn);\n // executeRetrieve returns an array of results (one per find operation)\n // Since we only have one find, unwrap the first result\n const [result]: unknown[][] = await uow.executeRetrieve();\n return result ?? [];\n },\n\n async findFirst(tableName, builderFn) {\n const uow = createUOW();\n if (builderFn) {\n uow.find(tableName, (b) => builderFn(b as never).pageSize(1));\n } else {\n uow.find(tableName, (b) => b.whereIndex(\"primary\").pageSize(1));\n }\n // executeRetrieve runs an array of `find` operation results, which each return an array of rows\n const [result]: unknown[][] = await uow.executeRetrieve();\n return result?.[0] ?? null;\n },\n\n async create(tableName, values) {\n const uow = createUOW();\n uow.create(tableName, values);\n const { success } = await uow.executeMutations();\n if (!success) {\n // This should not happen because we don't `.check()` this call.\n // TODO: Verify what happens when there are unique constraints\n throw new Error(\"Failed to create record\");\n }\n\n const [createdId] = uow.getCreatedIds();\n if (!createdId) {\n throw new Error(\"Failed to get created ID\");\n }\n return createdId;\n },\n\n async createMany(tableName, valuesArray) {\n const uow = createUOW();\n for (const values of valuesArray) {\n uow.create(tableName, values);\n }\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to create records\");\n }\n\n return uow.getCreatedIds();\n },\n\n async update(tableName, id, builderFn) {\n const uow = createUOW();\n uow.update(tableName, id, builderFn as never);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to update record (version conflict or record not found)\");\n }\n },\n\n async updateMany(tableName, builderFn) {\n // Create a special builder that captures both where and set operations\n let whereConfig: { indexName?: string; condition?: unknown } = {};\n let setValues: unknown;\n\n const specialBuilder = {\n whereIndex(indexName: string, condition?: unknown) {\n whereConfig = { indexName, condition };\n return this;\n },\n set(values: unknown) {\n setValues = values;\n return this;\n },\n };\n\n builderFn(specialBuilder);\n\n if (!whereConfig.indexName) {\n throw new Error(\"whereIndex() must be called in updateMany\");\n }\n if (!setValues) {\n throw new Error(\"set() must be called in updateMany\");\n }\n\n // First, find all matching records\n const findUow = createUOW();\n findUow.find(tableName, (b) => {\n if (whereConfig.condition) {\n return b.whereIndex(whereConfig.indexName as never, whereConfig.condition as never);\n }\n return b.whereIndex(whereConfig.indexName as never);\n });\n const findResults: unknown[][] = await findUow.executeRetrieve();\n const records = findResults[0];\n\n if (!records || records.length === 0) {\n return;\n }\n\n // Now update all found records\n const updateUow = createUOW();\n for (const record of records as never as Array<{ id: unknown }>) {\n updateUow.update(tableName as string, record.id as string, (b) =>\n b.set(setValues as never),\n );\n }\n const { success } = await updateUow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to update records (version conflict)\");\n }\n },\n\n async delete(tableName, id, builderFn) {\n const uow = createUOW();\n uow.delete(tableName, id, builderFn as never);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to delete record (version conflict or record not found)\");\n }\n },\n\n async deleteMany(tableName, builderFn) {\n // Create a special builder that captures where configuration\n let whereConfig: { indexName?: string; condition?: unknown } = {};\n\n const specialBuilder = {\n whereIndex(indexName: string, condition?: unknown) {\n whereConfig = { indexName, condition };\n return this;\n },\n };\n\n // Safe: Call builderFn to capture the configuration\n builderFn(specialBuilder as never);\n\n if (!whereConfig.indexName) {\n throw new Error(\"whereIndex() must be called in deleteMany\");\n }\n\n // First, find all matching records\n const findUow = createUOW();\n findUow.find(tableName as string, (b) => {\n if (whereConfig.condition) {\n return b.whereIndex(whereConfig.indexName as never, whereConfig.condition as never);\n }\n return b.whereIndex(whereConfig.indexName as never);\n });\n const findResults2 = await findUow.executeRetrieve();\n const records = (findResults2 as unknown as [unknown])[0];\n\n // @ts-expect-error - Type narrowing doesn't work through unknown cast\n if (!records || records.length === 0) {\n return;\n }\n\n // Now delete all found records\n const deleteUow = createUOW();\n for (const record of records as never as Array<{ id: unknown }>) {\n deleteUow.delete(tableName as string, record.id as string);\n }\n const { success } = await deleteUow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to delete records (version conflict)\");\n }\n },\n\n createUnitOfWork(name) {\n return createUOW(name);\n },\n } as AbstractQuery<T>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"kysely-query.js","names":["executor: UOWExecutor<CompiledQuery, unknown>","decoder: UOWDecoder<T>","whereConfig: { indexName?: string; condition?: unknown }","setValues: unknown"],"sources":["../../../src/adapters/kysely/kysely-query.ts"],"sourcesContent":["import type { AbstractQuery } from \"../../query/query\";\nimport type { AnySchema } from \"../../schema/create\";\nimport type { KyselyConfig } from \"./kysely-adapter\";\nimport type { CompiledMutation, UOWDecoder, UOWExecutor } from \"../../query/unit-of-work\";\nimport { decodeResult } from \"../../query/result-transform\";\nimport { createKyselyUOWCompiler } from \"./kysely-uow-compiler\";\nimport { executeKyselyRetrievalPhase, executeKyselyMutationPhase } from \"./kysely-uow-executor\";\nimport { UnitOfWork } from \"../../query/unit-of-work\";\nimport type { CompiledQuery } from \"kysely\";\nimport type { TableNameMapper } from \"./kysely-shared\";\n\n/**\n * Creates a Kysely-based query engine for the given schema.\n *\n * This is the main entry point for creating a database query interface using Kysely.\n * It uses a compiler-based architecture where queries are compiled to SQL and then executed,\n * enabling features like SQL snapshot testing.\n *\n * @param schema - The database schema definition\n * @param config - Kysely configuration containing the database instance and provider\n * @param mapper - Optional table name mapper for namespace prefixing\n * @returns An AbstractQuery instance for performing database operations\n *\n * @example\n * ```ts\n * const queryEngine = fromKysely(mySchema, {\n * db: kysely,\n * provider: 'postgresql'\n * });\n *\n * const users = await queryEngine.findMany('users', {\n * where: (b) => b('age', '>', 18),\n * orderBy: [['name', 'asc']]\n * });\n * ```\n */\nexport function fromKysely<T extends AnySchema>(\n schema: T,\n config: KyselyConfig,\n mapper?: TableNameMapper,\n): AbstractQuery<T> {\n const { db, provider } = config;\n // Resolve the db instance if it's a function\n const kysely = typeof db === \"function\" ? db() : db;\n const uowCompiler = createKyselyUOWCompiler(schema, config, mapper);\n\n function createUOW(name?: string): UnitOfWork<T, []> {\n const executor: UOWExecutor<CompiledQuery, unknown> = {\n executeRetrievalPhase: (retrievalBatch: CompiledQuery[]) =>\n executeKyselyRetrievalPhase(kysely, retrievalBatch),\n executeMutationPhase: (mutationBatch: CompiledMutation<CompiledQuery>[]) =>\n executeKyselyMutationPhase(kysely, mutationBatch),\n };\n\n // Create a decoder function to transform raw results into application format\n const decoder: UOWDecoder<T> = (rawResults, ops) => {\n if (rawResults.length !== ops.length) {\n throw new Error(\"rawResults and ops must have the same length\");\n }\n\n return rawResults.map((rows, index) => {\n const op = ops[index];\n if (!op) {\n throw new Error(\"op must be defined\");\n }\n\n // Handle count operations differently - return the count number directly\n if (op.type === \"count\") {\n const rowArray = rows as Record<string, unknown>[];\n const firstRow = rowArray[0];\n if (!firstRow) {\n return 0;\n }\n const count = Number(firstRow[\"count\"]);\n if (Number.isNaN(count)) {\n throw new Error(`Unexpected result for count, received: ${count}`);\n }\n return count;\n }\n\n // Each result is an array of rows - decode each row\n const rowArray = rows as Record<string, unknown>[];\n return rowArray.map((row) => decodeResult(row, op.table, provider));\n });\n };\n\n return new UnitOfWork(schema, uowCompiler, executor, decoder, name);\n }\n\n return {\n async find(tableName, builderFn) {\n const uow = createUOW();\n uow.find(tableName, builderFn);\n // executeRetrieve returns an array of results (one per find operation)\n // Since we only have one find, unwrap the first result\n const [result]: unknown[][] = await uow.executeRetrieve();\n return result ?? [];\n },\n\n async findFirst(tableName, builderFn) {\n const uow = createUOW();\n if (builderFn) {\n uow.find(tableName, (b) => builderFn(b as never).pageSize(1));\n } else {\n uow.find(tableName, (b) => b.whereIndex(\"primary\").pageSize(1));\n }\n // executeRetrieve runs an array of `find` operation results, which each return an array of rows\n const [result]: unknown[][] = await uow.executeRetrieve();\n return result?.[0] ?? null;\n },\n\n async create(tableName, values) {\n const uow = createUOW();\n uow.create(tableName, values);\n const { success } = await uow.executeMutations();\n if (!success) {\n // This should not happen because we don't `.check()` this call.\n // TODO: Verify what happens when there are unique constraints\n throw new Error(\"Failed to create record\");\n }\n\n const [createdId] = uow.getCreatedIds();\n if (!createdId) {\n throw new Error(\"Failed to get created ID\");\n }\n return createdId;\n },\n\n async createMany(tableName, valuesArray) {\n const uow = createUOW();\n for (const values of valuesArray) {\n uow.create(tableName, values);\n }\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to create records\");\n }\n\n return uow.getCreatedIds();\n },\n\n async update(tableName, id, builderFn) {\n const uow = createUOW();\n uow.update(tableName, id, builderFn as never);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to update record (version conflict or record not found)\");\n }\n },\n\n async updateMany(tableName, builderFn) {\n // Create a special builder that captures both where and set operations\n let whereConfig: { indexName?: string; condition?: unknown } = {};\n let setValues: unknown;\n\n const specialBuilder = {\n whereIndex(indexName: string, condition?: unknown) {\n whereConfig = { indexName, condition };\n return this;\n },\n set(values: unknown) {\n setValues = values;\n return this;\n },\n };\n\n builderFn(specialBuilder);\n\n if (!whereConfig.indexName) {\n throw new Error(\"whereIndex() must be called in updateMany\");\n }\n if (!setValues) {\n throw new Error(\"set() must be called in updateMany\");\n }\n\n // First, find all matching records\n const findUow = createUOW();\n findUow.find(tableName, (b) => {\n if (whereConfig.condition) {\n return b.whereIndex(whereConfig.indexName as never, whereConfig.condition as never);\n }\n return b.whereIndex(whereConfig.indexName as never);\n });\n const findResults: unknown[][] = await findUow.executeRetrieve();\n const records = findResults[0];\n\n if (!records || records.length === 0) {\n return;\n }\n\n // Now update all found records\n const updateUow = createUOW();\n for (const record of records as never as Array<{ id: unknown }>) {\n updateUow.update(tableName as string, record.id as string, (b) =>\n b.set(setValues as never),\n );\n }\n const { success } = await updateUow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to update records (version conflict)\");\n }\n },\n\n async delete(tableName, id, builderFn) {\n const uow = createUOW();\n uow.delete(tableName, id, builderFn as never);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to delete record (version conflict or record not found)\");\n }\n },\n\n async deleteMany(tableName, builderFn) {\n // Create a special builder that captures where configuration\n let whereConfig: { indexName?: string; condition?: unknown } = {};\n\n const specialBuilder = {\n whereIndex(indexName: string, condition?: unknown) {\n whereConfig = { indexName, condition };\n return this;\n },\n };\n\n // Safe: Call builderFn to capture the configuration\n builderFn(specialBuilder as never);\n\n if (!whereConfig.indexName) {\n throw new Error(\"whereIndex() must be called in deleteMany\");\n }\n\n // First, find all matching records\n const findUow = createUOW();\n findUow.find(tableName as string, (b) => {\n if (whereConfig.condition) {\n return b.whereIndex(whereConfig.indexName as never, whereConfig.condition as never);\n }\n return b.whereIndex(whereConfig.indexName as never);\n });\n const findResults2 = await findUow.executeRetrieve();\n const records = (findResults2 as unknown as [unknown])[0];\n\n // @ts-expect-error - Type narrowing doesn't work through unknown cast\n if (!records || records.length === 0) {\n return;\n }\n\n // Now delete all found records\n const deleteUow = createUOW();\n for (const record of records as never as Array<{ id: unknown }>) {\n deleteUow.delete(tableName as string, record.id as string);\n }\n const { success } = await deleteUow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to delete records (version conflict)\");\n }\n },\n\n createUnitOfWork(name) {\n return createUOW(name);\n },\n } as AbstractQuery<T>;\n}\n"],"mappings":"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"}
@@ -17,8 +17,8 @@ import { createKyselyQueryCompiler } from "./kysely-query-compiler.js";
17
17
  */
18
18
  function createKyselyUOWCompiler(schema, config, mapper) {
19
19
  const queryCompiler = createKyselyQueryCompiler(schema, config, mapper);
20
- const queryBuilder = createKyselyQueryBuilder(config.db, config.provider, mapper);
21
- const { provider } = config;
20
+ const { db, provider } = config;
21
+ const queryBuilder = createKyselyQueryBuilder(typeof db === "function" ? db() : db, provider, mapper);
22
22
  function toTable(name) {
23
23
  const table = schema.tables[name];
24
24
  if (!table) throw new Error(`Invalid table name ${name}.`);
@@ -1 +1 @@
1
- {"version":3,"file":"kysely-uow-compiler.js","names":["indexColumns: AnyColumn[]","orderDirection: \"asc\" | \"desc\"","orderBy: [AnyColumn, \"asc\" | \"desc\"][] | undefined","cursorCondition: Condition | undefined","combinedWhere: Condition | undefined"],"sources":["../../../src/adapters/kysely/kysely-uow-compiler.ts"],"sourcesContent":["import type { CompiledQuery } from \"kysely\";\nimport type { AnyColumn, AnySchema, FragnoId } from \"../../schema/create\";\nimport type {\n CompiledMutation,\n MutationOperation,\n RetrievalOperation,\n UOWCompiler,\n} from \"../../query/unit-of-work\";\nimport type { KyselyConfig } from \"./kysely-adapter\";\nimport { createKyselyQueryCompiler } from \"./kysely-query-compiler\";\nimport { createKyselyQueryBuilder } from \"./kysely-query-builder\";\nimport { buildCondition, type Condition } from \"../../query/condition-builder\";\nimport { decodeCursor, serializeCursorValues } from \"../../query/cursor\";\nimport type { AnySelectClause } from \"../../query/query\";\nimport type { TableNameMapper } from \"./kysely-shared\";\n\n/**\n * Create a Kysely-specific Unit of Work compiler\n *\n * This compiler translates UOW operations into Kysely CompiledQuery objects\n * that can be executed as a batch/transaction.\n *\n * @param schema - The database schema\n * @param config - Kysely configuration\n * @param mapper - Optional table name mapper for namespace prefixing\n * @returns A UOWCompiler instance for Kysely\n */\nexport function createKyselyUOWCompiler<TSchema extends AnySchema>(\n schema: TSchema,\n config: KyselyConfig,\n mapper?: TableNameMapper,\n): UOWCompiler<TSchema, CompiledQuery> {\n const queryCompiler = createKyselyQueryCompiler(schema, config, mapper);\n const queryBuilder = createKyselyQueryBuilder(config.db, config.provider, mapper);\n const { provider } = config;\n\n function toTable(name: unknown) {\n const table = schema.tables[name as string];\n if (!table) {\n throw new Error(`Invalid table name ${name}.`);\n }\n return table;\n }\n\n return {\n compileRetrievalOperation(op: RetrievalOperation<TSchema>): CompiledQuery | null {\n switch (op.type) {\n case \"count\": {\n return queryCompiler.count(op.table.name, {\n where: op.options.where,\n });\n }\n\n case \"find\": {\n // Map UOW FindOptions to query compiler's FindManyOptions\n const {\n useIndex: _useIndex,\n orderByIndex,\n joins: join,\n after,\n before,\n pageSize,\n ...findManyOptions\n } = op.options;\n\n // Get index columns for ordering and cursor pagination\n let indexColumns: AnyColumn[] = [];\n let orderDirection: \"asc\" | \"desc\" = \"asc\";\n\n if (orderByIndex) {\n const index = op.table.indexes[orderByIndex.indexName];\n orderDirection = orderByIndex.direction;\n\n if (!index) {\n // If _primary index doesn't exist, fall back to internal ID column\n // (which is the actual primary key and maintains insertion order)\n if (orderByIndex.indexName === \"_primary\") {\n indexColumns = [op.table.getIdColumn()];\n } else {\n throw new Error(\n `Index \"${orderByIndex.indexName}\" not found on table \"${op.table.name}\"`,\n );\n }\n } else {\n // Order by all columns in the index with the specified direction\n indexColumns = index.columns;\n }\n }\n\n // Convert orderByIndex to orderBy format\n let orderBy: [AnyColumn, \"asc\" | \"desc\"][] | undefined;\n if (indexColumns.length > 0) {\n orderBy = indexColumns.map((col) => [col, orderDirection]);\n }\n\n // Handle cursor pagination - build a cursor condition\n let cursorCondition: Condition | undefined;\n\n if ((after || before) && indexColumns.length > 0) {\n const cursor = after || before;\n const cursorData = decodeCursor(cursor!);\n const serializedValues = serializeCursorValues(cursorData, indexColumns, provider);\n\n // Build tuple comparison for cursor pagination\n // For \"after\" with \"asc\": (col1, col2, ...) > (val1, val2, ...)\n // For \"before\" with \"desc\": reverse the comparison\n const isAfter = !!after;\n const useGreaterThan =\n (isAfter && orderDirection === \"asc\") || (!isAfter && orderDirection === \"desc\");\n\n if (indexColumns.length === 1) {\n // Simple single-column case\n const col = indexColumns[0]!;\n const val = serializedValues[col.ormName];\n const operator = useGreaterThan ? \">\" : \"<\";\n cursorCondition = {\n type: \"compare\",\n a: col,\n operator,\n b: val,\n };\n } else {\n // Multi-column tuple comparison - not yet supported for Kysely\n throw new Error(\n \"Multi-column cursor pagination is not yet supported in Kysely Unit of Work implementation\",\n );\n }\n }\n\n // Combine user where clause with cursor condition\n let combinedWhere: Condition | undefined;\n if (findManyOptions.where) {\n const whereResult = buildCondition(op.table.columns, findManyOptions.where);\n if (whereResult === true) {\n combinedWhere = undefined;\n } else if (whereResult === false) {\n return null;\n } else {\n combinedWhere = whereResult;\n }\n }\n\n if (cursorCondition) {\n if (combinedWhere) {\n combinedWhere = {\n type: \"and\",\n items: [combinedWhere, cursorCondition],\n };\n } else {\n combinedWhere = cursorCondition;\n }\n }\n\n // When we have joins or need to bypass buildFindOptions, use queryBuilder directly\n if (join && join.length > 0) {\n return queryBuilder.findMany(op.table, {\n // Safe cast: select from UOW matches SimplifyFindOptions requirement\n select: (findManyOptions.select ?? true) as AnySelectClause,\n where: combinedWhere,\n orderBy,\n limit: pageSize,\n join,\n });\n }\n\n return queryCompiler.findMany(op.table.name, {\n ...findManyOptions,\n where: combinedWhere ? () => combinedWhere! : undefined,\n orderBy: orderBy?.map(([col, dir]) => [col.ormName, dir]),\n limit: pageSize,\n });\n }\n }\n },\n\n compileMutationOperation(\n op: MutationOperation<TSchema>,\n ): CompiledMutation<CompiledQuery> | null {\n switch (op.type) {\n case \"create\":\n // queryCompiler.create() calls encodeValues() which handles runtime defaults\n return {\n query: queryCompiler.create(op.table, op.values),\n expectedAffectedRows: null, // creates don't need affected row checks\n };\n\n case \"update\": {\n const table = toTable(op.table);\n const idColumn = table.getIdColumn();\n const versionColumn = table.getVersionColumn();\n\n const externalId = typeof op.id === \"string\" ? op.id : op.id.externalId;\n const versionToCheck = getVersionToCheck(op.id, op.checkVersion);\n\n // Build WHERE clause that filters by ID and optionally by version\n const whereClause =\n versionToCheck !== undefined\n ? () =>\n buildCondition(table.columns, (eb) =>\n eb.and(\n eb(idColumn.ormName, \"=\", externalId),\n eb(versionColumn.ormName, \"=\", versionToCheck),\n ),\n )\n : () => buildCondition(table.columns, (eb) => eb(idColumn.ormName, \"=\", externalId));\n\n const query = queryCompiler.updateMany(op.table, {\n where: whereClause,\n set: op.set,\n });\n\n return query\n ? {\n query,\n expectedAffectedRows: op.checkVersion ? 1 : null,\n }\n : null;\n }\n\n case \"delete\": {\n const table = toTable(op.table);\n const idColumn = table.getIdColumn();\n const versionColumn = table.getVersionColumn();\n\n // Extract external ID based on whether op.id is FragnoId or string\n const externalId = typeof op.id === \"string\" ? op.id : op.id.externalId;\n const versionToCheck = getVersionToCheck(op.id, op.checkVersion);\n\n // Build WHERE clause that filters by ID and optionally by version\n const whereClause =\n versionToCheck !== undefined\n ? () =>\n buildCondition(table.columns, (eb) =>\n eb.and(\n eb(idColumn.ormName, \"=\", externalId),\n eb(versionColumn.ormName, \"=\", versionToCheck),\n ),\n )\n : () => buildCondition(table.columns, (eb) => eb(idColumn.ormName, \"=\", externalId));\n\n const query = queryCompiler.deleteMany(op.table, {\n where: whereClause,\n });\n\n return query\n ? {\n query,\n expectedAffectedRows: op.checkVersion ? 1 : null,\n }\n : null;\n }\n }\n },\n };\n}\n\n/**\n * Get the version to check for a given ID and checkVersion flag.\n * @returns The version to check or undefined if no check is required.\n * @throws Error if the ID is a string and checkVersion is true.\n */\nfunction getVersionToCheck(id: FragnoId | string, checkVersion: boolean): number | undefined {\n if (!checkVersion) {\n return undefined;\n }\n\n if (typeof id === \"string\") {\n throw new Error(\n `Cannot use checkVersion with a string ID. Version checking requires a FragnoId with version information.`,\n );\n }\n\n return id.version;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA2BA,SAAgB,wBACd,QACA,QACA,QACqC;CACrC,MAAM,gBAAgB,0BAA0B,QAAQ,QAAQ,OAAO;CACvE,MAAM,eAAe,yBAAyB,OAAO,IAAI,OAAO,UAAU,OAAO;CACjF,MAAM,EAAE,aAAa;CAErB,SAAS,QAAQ,MAAe;EAC9B,MAAM,QAAQ,OAAO,OAAO;AAC5B,MAAI,CAAC,MACH,OAAM,IAAI,MAAM,sBAAsB,KAAK,GAAG;AAEhD,SAAO;;AAGT,QAAO;EACL,0BAA0B,IAAuD;AAC/E,WAAQ,GAAG,MAAX;IACE,KAAK,QACH,QAAO,cAAc,MAAM,GAAG,MAAM,MAAM,EACxC,OAAO,GAAG,QAAQ,OACnB,CAAC;IAGJ,KAAK,QAAQ;KAEX,MAAM,EACJ,UAAU,WACV,cACA,OAAO,MACP,OACA,QACA,SACA,GAAG,oBACD,GAAG;KAGP,IAAIA,eAA4B,EAAE;KAClC,IAAIC,iBAAiC;AAErC,SAAI,cAAc;MAChB,MAAM,QAAQ,GAAG,MAAM,QAAQ,aAAa;AAC5C,uBAAiB,aAAa;AAE9B,UAAI,CAAC,MAGH,KAAI,aAAa,cAAc,WAC7B,gBAAe,CAAC,GAAG,MAAM,aAAa,CAAC;UAEvC,OAAM,IAAI,MACR,UAAU,aAAa,UAAU,wBAAwB,GAAG,MAAM,KAAK,GACxE;UAIH,gBAAe,MAAM;;KAKzB,IAAIC;AACJ,SAAI,aAAa,SAAS,EACxB,WAAU,aAAa,KAAK,QAAQ,CAAC,KAAK,eAAe,CAAC;KAI5D,IAAIC;AAEJ,UAAK,SAAS,WAAW,aAAa,SAAS,GAAG;MAGhD,MAAM,mBAAmB,sBADN,aADJ,SAAS,OACgB,EACmB,cAAc,SAAS;MAKlF,MAAM,UAAU,CAAC,CAAC;MAClB,MAAM,iBACH,WAAW,mBAAmB,SAAW,CAAC,WAAW,mBAAmB;AAE3E,UAAI,aAAa,WAAW,GAAG;OAE7B,MAAM,MAAM,aAAa;OACzB,MAAM,MAAM,iBAAiB,IAAI;AAEjC,yBAAkB;QAChB,MAAM;QACN,GAAG;QACH,UAJe,iBAAiB,MAAM;QAKtC,GAAG;QACJ;YAGD,OAAM,IAAI,MACR,4FACD;;KAKL,IAAIC;AACJ,SAAI,gBAAgB,OAAO;MACzB,MAAM,cAAc,eAAe,GAAG,MAAM,SAAS,gBAAgB,MAAM;AAC3E,UAAI,gBAAgB,KAClB,iBAAgB;eACP,gBAAgB,MACzB,QAAO;UAEP,iBAAgB;;AAIpB,SAAI,gBACF,KAAI,cACF,iBAAgB;MACd,MAAM;MACN,OAAO,CAAC,eAAe,gBAAgB;MACxC;SAED,iBAAgB;AAKpB,SAAI,QAAQ,KAAK,SAAS,EACxB,QAAO,aAAa,SAAS,GAAG,OAAO;MAErC,QAAS,gBAAgB,UAAU;MACnC,OAAO;MACP;MACA,OAAO;MACP;MACD,CAAC;AAGJ,YAAO,cAAc,SAAS,GAAG,MAAM,MAAM;MAC3C,GAAG;MACH,OAAO,sBAAsB,gBAAiB;MAC9C,SAAS,SAAS,KAAK,CAAC,KAAK,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC;MACzD,OAAO;MACR,CAAC;;;;EAKR,yBACE,IACwC;AACxC,WAAQ,GAAG,MAAX;IACE,KAAK,SAEH,QAAO;KACL,OAAO,cAAc,OAAO,GAAG,OAAO,GAAG,OAAO;KAChD,sBAAsB;KACvB;IAEH,KAAK,UAAU;KACb,MAAM,QAAQ,QAAQ,GAAG,MAAM;KAC/B,MAAM,WAAW,MAAM,aAAa;KACpC,MAAM,gBAAgB,MAAM,kBAAkB;KAE9C,MAAM,aAAa,OAAO,GAAG,OAAO,WAAW,GAAG,KAAK,GAAG,GAAG;KAC7D,MAAM,iBAAiB,kBAAkB,GAAG,IAAI,GAAG,aAAa;KAGhE,MAAM,cACJ,mBAAmB,eAEb,eAAe,MAAM,UAAU,OAC7B,GAAG,IACD,GAAG,SAAS,SAAS,KAAK,WAAW,EACrC,GAAG,cAAc,SAAS,KAAK,eAAe,CAC/C,CACF,SACG,eAAe,MAAM,UAAU,OAAO,GAAG,SAAS,SAAS,KAAK,WAAW,CAAC;KAExF,MAAM,QAAQ,cAAc,WAAW,GAAG,OAAO;MAC/C,OAAO;MACP,KAAK,GAAG;MACT,CAAC;AAEF,YAAO,QACH;MACE;MACA,sBAAsB,GAAG,eAAe,IAAI;MAC7C,GACD;;IAGN,KAAK,UAAU;KACb,MAAM,QAAQ,QAAQ,GAAG,MAAM;KAC/B,MAAM,WAAW,MAAM,aAAa;KACpC,MAAM,gBAAgB,MAAM,kBAAkB;KAG9C,MAAM,aAAa,OAAO,GAAG,OAAO,WAAW,GAAG,KAAK,GAAG,GAAG;KAC7D,MAAM,iBAAiB,kBAAkB,GAAG,IAAI,GAAG,aAAa;KAGhE,MAAM,cACJ,mBAAmB,eAEb,eAAe,MAAM,UAAU,OAC7B,GAAG,IACD,GAAG,SAAS,SAAS,KAAK,WAAW,EACrC,GAAG,cAAc,SAAS,KAAK,eAAe,CAC/C,CACF,SACG,eAAe,MAAM,UAAU,OAAO,GAAG,SAAS,SAAS,KAAK,WAAW,CAAC;KAExF,MAAM,QAAQ,cAAc,WAAW,GAAG,OAAO,EAC/C,OAAO,aACR,CAAC;AAEF,YAAO,QACH;MACE;MACA,sBAAsB,GAAG,eAAe,IAAI;MAC7C,GACD;;;;EAIX;;;;;;;AAQH,SAAS,kBAAkB,IAAuB,cAA2C;AAC3F,KAAI,CAAC,aACH;AAGF,KAAI,OAAO,OAAO,SAChB,OAAM,IAAI,MACR,2GACD;AAGH,QAAO,GAAG"}
1
+ {"version":3,"file":"kysely-uow-compiler.js","names":["indexColumns: AnyColumn[]","orderDirection: \"asc\" | \"desc\"","orderBy: [AnyColumn, \"asc\" | \"desc\"][] | undefined","cursorCondition: Condition | undefined","combinedWhere: Condition | undefined"],"sources":["../../../src/adapters/kysely/kysely-uow-compiler.ts"],"sourcesContent":["import type { CompiledQuery } from \"kysely\";\nimport type { AnyColumn, AnySchema, FragnoId } from \"../../schema/create\";\nimport type {\n CompiledMutation,\n MutationOperation,\n RetrievalOperation,\n UOWCompiler,\n} from \"../../query/unit-of-work\";\nimport type { KyselyConfig } from \"./kysely-adapter\";\nimport { createKyselyQueryCompiler } from \"./kysely-query-compiler\";\nimport { createKyselyQueryBuilder } from \"./kysely-query-builder\";\nimport { buildCondition, type Condition } from \"../../query/condition-builder\";\nimport { decodeCursor, serializeCursorValues } from \"../../query/cursor\";\nimport type { AnySelectClause } from \"../../query/query\";\nimport type { TableNameMapper } from \"./kysely-shared\";\n\n/**\n * Create a Kysely-specific Unit of Work compiler\n *\n * This compiler translates UOW operations into Kysely CompiledQuery objects\n * that can be executed as a batch/transaction.\n *\n * @param schema - The database schema\n * @param config - Kysely configuration\n * @param mapper - Optional table name mapper for namespace prefixing\n * @returns A UOWCompiler instance for Kysely\n */\nexport function createKyselyUOWCompiler<TSchema extends AnySchema>(\n schema: TSchema,\n config: KyselyConfig,\n mapper?: TableNameMapper,\n): UOWCompiler<TSchema, CompiledQuery> {\n const queryCompiler = createKyselyQueryCompiler(schema, config, mapper);\n const { db, provider } = config;\n // Resolve the db instance if it's a function\n const kysely = typeof db === \"function\" ? db() : db;\n const queryBuilder = createKyselyQueryBuilder(kysely, provider, mapper);\n\n function toTable(name: unknown) {\n const table = schema.tables[name as string];\n if (!table) {\n throw new Error(`Invalid table name ${name}.`);\n }\n return table;\n }\n\n return {\n compileRetrievalOperation(op: RetrievalOperation<TSchema>): CompiledQuery | null {\n switch (op.type) {\n case \"count\": {\n return queryCompiler.count(op.table.name, {\n where: op.options.where,\n });\n }\n\n case \"find\": {\n // Map UOW FindOptions to query compiler's FindManyOptions\n const {\n useIndex: _useIndex,\n orderByIndex,\n joins: join,\n after,\n before,\n pageSize,\n ...findManyOptions\n } = op.options;\n\n // Get index columns for ordering and cursor pagination\n let indexColumns: AnyColumn[] = [];\n let orderDirection: \"asc\" | \"desc\" = \"asc\";\n\n if (orderByIndex) {\n const index = op.table.indexes[orderByIndex.indexName];\n orderDirection = orderByIndex.direction;\n\n if (!index) {\n // If _primary index doesn't exist, fall back to internal ID column\n // (which is the actual primary key and maintains insertion order)\n if (orderByIndex.indexName === \"_primary\") {\n indexColumns = [op.table.getIdColumn()];\n } else {\n throw new Error(\n `Index \"${orderByIndex.indexName}\" not found on table \"${op.table.name}\"`,\n );\n }\n } else {\n // Order by all columns in the index with the specified direction\n indexColumns = index.columns;\n }\n }\n\n // Convert orderByIndex to orderBy format\n let orderBy: [AnyColumn, \"asc\" | \"desc\"][] | undefined;\n if (indexColumns.length > 0) {\n orderBy = indexColumns.map((col) => [col, orderDirection]);\n }\n\n // Handle cursor pagination - build a cursor condition\n let cursorCondition: Condition | undefined;\n\n if ((after || before) && indexColumns.length > 0) {\n const cursor = after || before;\n const cursorData = decodeCursor(cursor!);\n const serializedValues = serializeCursorValues(cursorData, indexColumns, provider);\n\n // Build tuple comparison for cursor pagination\n // For \"after\" with \"asc\": (col1, col2, ...) > (val1, val2, ...)\n // For \"before\" with \"desc\": reverse the comparison\n const isAfter = !!after;\n const useGreaterThan =\n (isAfter && orderDirection === \"asc\") || (!isAfter && orderDirection === \"desc\");\n\n if (indexColumns.length === 1) {\n // Simple single-column case\n const col = indexColumns[0]!;\n const val = serializedValues[col.ormName];\n const operator = useGreaterThan ? \">\" : \"<\";\n cursorCondition = {\n type: \"compare\",\n a: col,\n operator,\n b: val,\n };\n } else {\n // Multi-column tuple comparison - not yet supported for Kysely\n throw new Error(\n \"Multi-column cursor pagination is not yet supported in Kysely Unit of Work implementation\",\n );\n }\n }\n\n // Combine user where clause with cursor condition\n let combinedWhere: Condition | undefined;\n if (findManyOptions.where) {\n const whereResult = buildCondition(op.table.columns, findManyOptions.where);\n if (whereResult === true) {\n combinedWhere = undefined;\n } else if (whereResult === false) {\n return null;\n } else {\n combinedWhere = whereResult;\n }\n }\n\n if (cursorCondition) {\n if (combinedWhere) {\n combinedWhere = {\n type: \"and\",\n items: [combinedWhere, cursorCondition],\n };\n } else {\n combinedWhere = cursorCondition;\n }\n }\n\n // When we have joins or need to bypass buildFindOptions, use queryBuilder directly\n if (join && join.length > 0) {\n return queryBuilder.findMany(op.table, {\n // Safe cast: select from UOW matches SimplifyFindOptions requirement\n select: (findManyOptions.select ?? true) as AnySelectClause,\n where: combinedWhere,\n orderBy,\n limit: pageSize,\n join,\n });\n }\n\n return queryCompiler.findMany(op.table.name, {\n ...findManyOptions,\n where: combinedWhere ? () => combinedWhere! : undefined,\n orderBy: orderBy?.map(([col, dir]) => [col.ormName, dir]),\n limit: pageSize,\n });\n }\n }\n },\n\n compileMutationOperation(\n op: MutationOperation<TSchema>,\n ): CompiledMutation<CompiledQuery> | null {\n switch (op.type) {\n case \"create\":\n // queryCompiler.create() calls encodeValues() which handles runtime defaults\n return {\n query: queryCompiler.create(op.table, op.values),\n expectedAffectedRows: null, // creates don't need affected row checks\n };\n\n case \"update\": {\n const table = toTable(op.table);\n const idColumn = table.getIdColumn();\n const versionColumn = table.getVersionColumn();\n\n const externalId = typeof op.id === \"string\" ? op.id : op.id.externalId;\n const versionToCheck = getVersionToCheck(op.id, op.checkVersion);\n\n // Build WHERE clause that filters by ID and optionally by version\n const whereClause =\n versionToCheck !== undefined\n ? () =>\n buildCondition(table.columns, (eb) =>\n eb.and(\n eb(idColumn.ormName, \"=\", externalId),\n eb(versionColumn.ormName, \"=\", versionToCheck),\n ),\n )\n : () => buildCondition(table.columns, (eb) => eb(idColumn.ormName, \"=\", externalId));\n\n const query = queryCompiler.updateMany(op.table, {\n where: whereClause,\n set: op.set,\n });\n\n return query\n ? {\n query,\n expectedAffectedRows: op.checkVersion ? 1 : null,\n }\n : null;\n }\n\n case \"delete\": {\n const table = toTable(op.table);\n const idColumn = table.getIdColumn();\n const versionColumn = table.getVersionColumn();\n\n // Extract external ID based on whether op.id is FragnoId or string\n const externalId = typeof op.id === \"string\" ? op.id : op.id.externalId;\n const versionToCheck = getVersionToCheck(op.id, op.checkVersion);\n\n // Build WHERE clause that filters by ID and optionally by version\n const whereClause =\n versionToCheck !== undefined\n ? () =>\n buildCondition(table.columns, (eb) =>\n eb.and(\n eb(idColumn.ormName, \"=\", externalId),\n eb(versionColumn.ormName, \"=\", versionToCheck),\n ),\n )\n : () => buildCondition(table.columns, (eb) => eb(idColumn.ormName, \"=\", externalId));\n\n const query = queryCompiler.deleteMany(op.table, {\n where: whereClause,\n });\n\n return query\n ? {\n query,\n expectedAffectedRows: op.checkVersion ? 1 : null,\n }\n : null;\n }\n }\n },\n };\n}\n\n/**\n * Get the version to check for a given ID and checkVersion flag.\n * @returns The version to check or undefined if no check is required.\n * @throws Error if the ID is a string and checkVersion is true.\n */\nfunction getVersionToCheck(id: FragnoId | string, checkVersion: boolean): number | undefined {\n if (!checkVersion) {\n return undefined;\n }\n\n if (typeof id === \"string\") {\n throw new Error(\n `Cannot use checkVersion with a string ID. Version checking requires a FragnoId with version information.`,\n );\n }\n\n return id.version;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA2BA,SAAgB,wBACd,QACA,QACA,QACqC;CACrC,MAAM,gBAAgB,0BAA0B,QAAQ,QAAQ,OAAO;CACvE,MAAM,EAAE,IAAI,aAAa;CAGzB,MAAM,eAAe,yBADN,OAAO,OAAO,aAAa,IAAI,GAAG,IACK,UAAU,OAAO;CAEvE,SAAS,QAAQ,MAAe;EAC9B,MAAM,QAAQ,OAAO,OAAO;AAC5B,MAAI,CAAC,MACH,OAAM,IAAI,MAAM,sBAAsB,KAAK,GAAG;AAEhD,SAAO;;AAGT,QAAO;EACL,0BAA0B,IAAuD;AAC/E,WAAQ,GAAG,MAAX;IACE,KAAK,QACH,QAAO,cAAc,MAAM,GAAG,MAAM,MAAM,EACxC,OAAO,GAAG,QAAQ,OACnB,CAAC;IAGJ,KAAK,QAAQ;KAEX,MAAM,EACJ,UAAU,WACV,cACA,OAAO,MACP,OACA,QACA,SACA,GAAG,oBACD,GAAG;KAGP,IAAIA,eAA4B,EAAE;KAClC,IAAIC,iBAAiC;AAErC,SAAI,cAAc;MAChB,MAAM,QAAQ,GAAG,MAAM,QAAQ,aAAa;AAC5C,uBAAiB,aAAa;AAE9B,UAAI,CAAC,MAGH,KAAI,aAAa,cAAc,WAC7B,gBAAe,CAAC,GAAG,MAAM,aAAa,CAAC;UAEvC,OAAM,IAAI,MACR,UAAU,aAAa,UAAU,wBAAwB,GAAG,MAAM,KAAK,GACxE;UAIH,gBAAe,MAAM;;KAKzB,IAAIC;AACJ,SAAI,aAAa,SAAS,EACxB,WAAU,aAAa,KAAK,QAAQ,CAAC,KAAK,eAAe,CAAC;KAI5D,IAAIC;AAEJ,UAAK,SAAS,WAAW,aAAa,SAAS,GAAG;MAGhD,MAAM,mBAAmB,sBADN,aADJ,SAAS,OACgB,EACmB,cAAc,SAAS;MAKlF,MAAM,UAAU,CAAC,CAAC;MAClB,MAAM,iBACH,WAAW,mBAAmB,SAAW,CAAC,WAAW,mBAAmB;AAE3E,UAAI,aAAa,WAAW,GAAG;OAE7B,MAAM,MAAM,aAAa;OACzB,MAAM,MAAM,iBAAiB,IAAI;AAEjC,yBAAkB;QAChB,MAAM;QACN,GAAG;QACH,UAJe,iBAAiB,MAAM;QAKtC,GAAG;QACJ;YAGD,OAAM,IAAI,MACR,4FACD;;KAKL,IAAIC;AACJ,SAAI,gBAAgB,OAAO;MACzB,MAAM,cAAc,eAAe,GAAG,MAAM,SAAS,gBAAgB,MAAM;AAC3E,UAAI,gBAAgB,KAClB,iBAAgB;eACP,gBAAgB,MACzB,QAAO;UAEP,iBAAgB;;AAIpB,SAAI,gBACF,KAAI,cACF,iBAAgB;MACd,MAAM;MACN,OAAO,CAAC,eAAe,gBAAgB;MACxC;SAED,iBAAgB;AAKpB,SAAI,QAAQ,KAAK,SAAS,EACxB,QAAO,aAAa,SAAS,GAAG,OAAO;MAErC,QAAS,gBAAgB,UAAU;MACnC,OAAO;MACP;MACA,OAAO;MACP;MACD,CAAC;AAGJ,YAAO,cAAc,SAAS,GAAG,MAAM,MAAM;MAC3C,GAAG;MACH,OAAO,sBAAsB,gBAAiB;MAC9C,SAAS,SAAS,KAAK,CAAC,KAAK,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC;MACzD,OAAO;MACR,CAAC;;;;EAKR,yBACE,IACwC;AACxC,WAAQ,GAAG,MAAX;IACE,KAAK,SAEH,QAAO;KACL,OAAO,cAAc,OAAO,GAAG,OAAO,GAAG,OAAO;KAChD,sBAAsB;KACvB;IAEH,KAAK,UAAU;KACb,MAAM,QAAQ,QAAQ,GAAG,MAAM;KAC/B,MAAM,WAAW,MAAM,aAAa;KACpC,MAAM,gBAAgB,MAAM,kBAAkB;KAE9C,MAAM,aAAa,OAAO,GAAG,OAAO,WAAW,GAAG,KAAK,GAAG,GAAG;KAC7D,MAAM,iBAAiB,kBAAkB,GAAG,IAAI,GAAG,aAAa;KAGhE,MAAM,cACJ,mBAAmB,eAEb,eAAe,MAAM,UAAU,OAC7B,GAAG,IACD,GAAG,SAAS,SAAS,KAAK,WAAW,EACrC,GAAG,cAAc,SAAS,KAAK,eAAe,CAC/C,CACF,SACG,eAAe,MAAM,UAAU,OAAO,GAAG,SAAS,SAAS,KAAK,WAAW,CAAC;KAExF,MAAM,QAAQ,cAAc,WAAW,GAAG,OAAO;MAC/C,OAAO;MACP,KAAK,GAAG;MACT,CAAC;AAEF,YAAO,QACH;MACE;MACA,sBAAsB,GAAG,eAAe,IAAI;MAC7C,GACD;;IAGN,KAAK,UAAU;KACb,MAAM,QAAQ,QAAQ,GAAG,MAAM;KAC/B,MAAM,WAAW,MAAM,aAAa;KACpC,MAAM,gBAAgB,MAAM,kBAAkB;KAG9C,MAAM,aAAa,OAAO,GAAG,OAAO,WAAW,GAAG,KAAK,GAAG,GAAG;KAC7D,MAAM,iBAAiB,kBAAkB,GAAG,IAAI,GAAG,aAAa;KAGhE,MAAM,cACJ,mBAAmB,eAEb,eAAe,MAAM,UAAU,OAC7B,GAAG,IACD,GAAG,SAAS,SAAS,KAAK,WAAW,EACrC,GAAG,cAAc,SAAS,KAAK,eAAe,CAC/C,CACF,SACG,eAAe,MAAM,UAAU,OAAO,GAAG,SAAS,SAAS,KAAK,WAAW,CAAC;KAExF,MAAM,QAAQ,cAAc,WAAW,GAAG,OAAO,EAC/C,OAAO,aACR,CAAC;AAEF,YAAO,QACH;MACE;MACA,sBAAsB,GAAG,eAAe,IAAI;MAC7C,GACD;;;;EAIX;;;;;;;AAQH,SAAS,kBAAkB,IAAuB,cAA2C;AAC3F,KAAI,CAAC,aACH;AAGF,KAAI,OAAO,OAAO,SAChB,OAAM,IAAI,MACR,2GACD;AAGH,QAAO,GAAG"}
@@ -9,12 +9,13 @@ import { MssqlMigrationExecutor } from "./execute-mssql.js";
9
9
  */
10
10
  function createMigrationExecutor(config) {
11
11
  const { db, provider } = config;
12
+ const kysely = typeof db === "function" ? db() : db;
12
13
  switch (provider) {
13
- case "sqlite": return new SqliteMigrationExecutor(db, provider);
14
+ case "sqlite": return new SqliteMigrationExecutor(kysely, provider);
14
15
  case "postgresql":
15
- case "cockroachdb": return new PostgresMigrationExecutor(db, provider);
16
- case "mysql": return new MysqlMigrationExecutor(db, provider);
17
- case "mssql": return new MssqlMigrationExecutor(db, provider);
16
+ case "cockroachdb": return new PostgresMigrationExecutor(kysely, provider);
17
+ case "mysql": return new MysqlMigrationExecutor(kysely, provider);
18
+ case "mssql": return new MssqlMigrationExecutor(kysely, provider);
18
19
  default: {
19
20
  const _exhaustive = provider;
20
21
  throw new Error(`Unsupported provider: ${_exhaustive}`);
@@ -1 +1 @@
1
- {"version":3,"file":"execute-factory.js","names":["_exhaustive: never"],"sources":["../../../../src/adapters/kysely/migration/execute-factory.ts"],"sourcesContent":["import type { KyselyConfig } from \"../kysely-adapter\";\nimport type { MigrationExecutor } from \"./execute-base\";\nimport { SqliteMigrationExecutor } from \"./execute-sqlite\";\nimport { PostgresMigrationExecutor } from \"./execute-postgres\";\nimport { MysqlMigrationExecutor } from \"./execute-mysql\";\nimport { MssqlMigrationExecutor } from \"./execute-mssql\";\n\n/**\n * Create a provider-specific migration executor.\n */\nexport function createMigrationExecutor(config: KyselyConfig): MigrationExecutor {\n const { db, provider } = config;\n\n switch (provider) {\n case \"sqlite\":\n return new SqliteMigrationExecutor(db, provider);\n case \"postgresql\":\n case \"cockroachdb\":\n return new PostgresMigrationExecutor(db, provider);\n case \"mysql\":\n return new MysqlMigrationExecutor(db, provider);\n case \"mssql\":\n return new MssqlMigrationExecutor(db, provider);\n default: {\n // Ensure exhaustive switch\n const _exhaustive: never = provider;\n throw new Error(`Unsupported provider: ${_exhaustive}`);\n }\n }\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,wBAAwB,QAAyC;CAC/E,MAAM,EAAE,IAAI,aAAa;AAEzB,SAAQ,UAAR;EACE,KAAK,SACH,QAAO,IAAI,wBAAwB,IAAI,SAAS;EAClD,KAAK;EACL,KAAK,cACH,QAAO,IAAI,0BAA0B,IAAI,SAAS;EACpD,KAAK,QACH,QAAO,IAAI,uBAAuB,IAAI,SAAS;EACjD,KAAK,QACH,QAAO,IAAI,uBAAuB,IAAI,SAAS;EACjD,SAAS;GAEP,MAAMA,cAAqB;AAC3B,SAAM,IAAI,MAAM,yBAAyB,cAAc"}
1
+ {"version":3,"file":"execute-factory.js","names":["_exhaustive: never"],"sources":["../../../../src/adapters/kysely/migration/execute-factory.ts"],"sourcesContent":["import type { KyselyConfig } from \"../kysely-adapter\";\nimport type { MigrationExecutor } from \"./execute-base\";\nimport { SqliteMigrationExecutor } from \"./execute-sqlite\";\nimport { PostgresMigrationExecutor } from \"./execute-postgres\";\nimport { MysqlMigrationExecutor } from \"./execute-mysql\";\nimport { MssqlMigrationExecutor } from \"./execute-mssql\";\n\n/**\n * Create a provider-specific migration executor.\n */\nexport function createMigrationExecutor(config: KyselyConfig): MigrationExecutor {\n const { db, provider } = config;\n // Resolve the db instance if it's a function\n const kysely = typeof db === \"function\" ? db() : db;\n\n switch (provider) {\n case \"sqlite\":\n return new SqliteMigrationExecutor(kysely, provider);\n case \"postgresql\":\n case \"cockroachdb\":\n return new PostgresMigrationExecutor(kysely, provider);\n case \"mysql\":\n return new MysqlMigrationExecutor(kysely, provider);\n case \"mssql\":\n return new MssqlMigrationExecutor(kysely, provider);\n default: {\n // Ensure exhaustive switch\n const _exhaustive: never = provider;\n throw new Error(`Unsupported provider: ${_exhaustive}`);\n }\n }\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,wBAAwB,QAAyC;CAC/E,MAAM,EAAE,IAAI,aAAa;CAEzB,MAAM,SAAS,OAAO,OAAO,aAAa,IAAI,GAAG;AAEjD,SAAQ,UAAR;EACE,KAAK,SACH,QAAO,IAAI,wBAAwB,QAAQ,SAAS;EACtD,KAAK;EACL,KAAK,cACH,QAAO,IAAI,0BAA0B,QAAQ,SAAS;EACxD,KAAK,QACH,QAAO,IAAI,uBAAuB,QAAQ,SAAS;EACrD,KAAK,QACH,QAAO,IAAI,uBAAuB,QAAQ,SAAS;EACrD,SAAS;GAEP,MAAMA,cAAqB;AAC3B,SAAM,IAAI,MAAM,yBAAyB,cAAc"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragno-dev/db",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -100,7 +100,7 @@ describe("DrizzleAdapter PGLite", () => {
100
100
  }
101
101
 
102
102
  adapter = new DrizzleAdapter({
103
- db,
103
+ db: () => db,
104
104
  provider: "postgresql",
105
105
  });
106
106
 
@@ -9,7 +9,7 @@ import { createSettingsManager, settingsSchema } from "../../shared/settings-sch
9
9
  import { sql } from "drizzle-orm";
10
10
 
11
11
  export interface DrizzleConfig {
12
- db: unknown;
12
+ db: unknown | (() => unknown);
13
13
  provider: "sqlite" | "mysql" | "postgresql";
14
14
  }
15
15
 
@@ -24,9 +24,14 @@ export class DrizzleAdapter implements DatabaseAdapter<DrizzleUOWConfig> {
24
24
  return this.#drizzleConfig.provider;
25
25
  }
26
26
 
27
+ #getDb(): DBType {
28
+ const db = this.#drizzleConfig.db;
29
+ return (typeof db === "function" ? db() : db) as DBType;
30
+ }
31
+
27
32
  async isConnectionHealthy(): Promise<boolean> {
28
33
  try {
29
- const result = await (this.#drizzleConfig.db as DBType).execute(sql`SELECT 1 as healthy`);
34
+ const result = await this.#getDb().execute(sql`SELECT 1 as healthy`);
30
35
 
31
36
  // Handle different result formats across providers
32
37
  // PostgreSQL/MySQL: { rows: [...] }
@@ -57,7 +62,12 @@ export class DrizzleAdapter implements DatabaseAdapter<DrizzleUOWConfig> {
57
62
  ): AbstractQuery<TSchema, DrizzleUOWConfig> {
58
63
  // Only create mapper if namespace is non-empty
59
64
  const mapper = namespace ? createTableNameMapper(namespace) : undefined;
60
- return fromDrizzle(schema, this.#drizzleConfig, mapper);
65
+ // Resolve the db instance if it's a function
66
+ const resolvedConfig: DrizzleConfig = {
67
+ db: this.#getDb(),
68
+ provider: this.#drizzleConfig.provider,
69
+ };
70
+ return fromDrizzle(schema, resolvedConfig, mapper);
61
71
  }
62
72
 
63
73
  createSchemaGenerator(
@@ -15,7 +15,7 @@ import { SETTINGS_TABLE_NAME } from "../../shared/settings-schema";
15
15
  type KyselyAny = Kysely<any>;
16
16
 
17
17
  export interface KyselyConfig {
18
- db: KyselyAny;
18
+ db: KyselyAny | (() => KyselyAny);
19
19
  provider: SQLProvider;
20
20
  }
21
21
 
@@ -26,17 +26,26 @@ export class KyselyAdapter implements DatabaseAdapter {
26
26
  this.#kyselyConfig = config;
27
27
  }
28
28
 
29
+ #getDb(): KyselyAny {
30
+ const db = this.#kyselyConfig.db;
31
+ return typeof db === "function" ? db() : db;
32
+ }
33
+
29
34
  createQueryEngine<T extends AnySchema>(schema: T, namespace: string): AbstractQuery<T> {
30
35
  // Only create mapper if namespace is non-empty
31
36
  const mapper = namespace ? createTableNameMapper(namespace) : undefined;
32
- return fromKysely(schema, this.#kyselyConfig, mapper);
37
+ // Resolve the db instance if it's a function
38
+ const resolvedConfig: KyselyConfig = {
39
+ db: this.#getDb(),
40
+ provider: this.#kyselyConfig.provider,
41
+ };
42
+ return fromKysely(schema, resolvedConfig, mapper);
33
43
  }
34
44
 
35
45
  async isConnectionHealthy(): Promise<boolean> {
36
46
  try {
37
- const result = await this.#kyselyConfig.db.executeQuery(
38
- sql`SELECT 1 as healthy`.compile(this.#kyselyConfig.db),
39
- );
47
+ const db = this.#getDb();
48
+ const result = await db.executeQuery(sql`SELECT 1 as healthy`.compile(db));
40
49
  return (result.rows[0] as Record<string, unknown>)["healthy"] === 1;
41
50
  } catch {
42
51
  return false;
@@ -44,7 +53,7 @@ export class KyselyAdapter implements DatabaseAdapter {
44
53
  }
45
54
 
46
55
  createMigrationEngine(schema: AnySchema, namespace: string): Migrator {
47
- const manager = createSettingsManager(this.#kyselyConfig.db, namespace);
56
+ const manager = createSettingsManager(this.#getDb(), namespace);
48
57
  const mapper = namespace ? createTableNameMapper(namespace) : undefined;
49
58
 
50
59
  const preprocessMigrationOperations = (operations: MigrationOperation[]) => {
@@ -82,12 +91,13 @@ export class KyselyAdapter implements DatabaseAdapter {
82
91
  const migrator = createMigrator({
83
92
  schema,
84
93
  executor: async (operations) => {
94
+ const db = this.#getDb();
85
95
  // For SQLite, execute PRAGMA defer_foreign_keys BEFORE transaction
86
96
  if (this.#kyselyConfig.provider === "sqlite") {
87
- await sql.raw("PRAGMA defer_foreign_keys = ON").execute(this.#kyselyConfig.db);
97
+ await sql.raw("PRAGMA defer_foreign_keys = ON").execute(db);
88
98
  }
89
99
 
90
- await this.#kyselyConfig.db.transaction().execute(async (tx) => {
100
+ await db.transaction().execute(async (tx) => {
91
101
  const preprocessed = preprocessMigrationOperations(operations);
92
102
  const nodes = toExecutableNodes(preprocessed, tx);
93
103
  for (const node of nodes) {
@@ -110,7 +120,7 @@ export class KyselyAdapter implements DatabaseAdapter {
110
120
  }
111
121
 
112
122
  const preprocessed = preprocessMigrationOperations(operations);
113
- const nodes = toExecutableNodes(preprocessed, this.#kyselyConfig.db);
123
+ const nodes = toExecutableNodes(preprocessed, this.#getDb());
114
124
  const compiled = nodes.map((node) => `${node.compile().sql};`);
115
125
 
116
126
  parts.push(...compiled);
@@ -142,7 +152,7 @@ export class KyselyAdapter implements DatabaseAdapter {
142
152
  }
143
153
 
144
154
  getSchemaVersion(namespace: string) {
145
- const manager = createSettingsManager(this.#kyselyConfig.db, namespace);
155
+ const manager = createSettingsManager(this.#getDb(), namespace);
146
156
 
147
157
  return manager.get(`schema_version`);
148
158
  }
@@ -30,7 +30,9 @@ export function createKyselyQueryCompiler<T extends AnySchema>(
30
30
  config: KyselyConfig,
31
31
  mapper?: TableNameMapper,
32
32
  ): KyselyQueryCompiler {
33
- const { db: kysely, provider } = config;
33
+ const { db, provider } = config;
34
+ // Resolve the db instance if it's a function
35
+ const kysely = typeof db === "function" ? db() : db;
34
36
  const queryBuilder = createKyselyQueryBuilder(kysely, provider, mapper);
35
37
 
36
38
  function toTable(name: unknown): AnyTable {
@@ -39,7 +39,9 @@ export function fromKysely<T extends AnySchema>(
39
39
  config: KyselyConfig,
40
40
  mapper?: TableNameMapper,
41
41
  ): AbstractQuery<T> {
42
- const { db: kysely, provider } = config;
42
+ const { db, provider } = config;
43
+ // Resolve the db instance if it's a function
44
+ const kysely = typeof db === "function" ? db() : db;
43
45
  const uowCompiler = createKyselyUOWCompiler(schema, config, mapper);
44
46
 
45
47
  function createUOW(name?: string): UnitOfWork<T, []> {
@@ -31,8 +31,10 @@ export function createKyselyUOWCompiler<TSchema extends AnySchema>(
31
31
  mapper?: TableNameMapper,
32
32
  ): UOWCompiler<TSchema, CompiledQuery> {
33
33
  const queryCompiler = createKyselyQueryCompiler(schema, config, mapper);
34
- const queryBuilder = createKyselyQueryBuilder(config.db, config.provider, mapper);
35
- const { provider } = config;
34
+ const { db, provider } = config;
35
+ // Resolve the db instance if it's a function
36
+ const kysely = typeof db === "function" ? db() : db;
37
+ const queryBuilder = createKyselyQueryBuilder(kysely, provider, mapper);
36
38
 
37
39
  function toTable(name: unknown) {
38
40
  const table = schema.tables[name as string];
@@ -10,17 +10,19 @@ import { MssqlMigrationExecutor } from "./execute-mssql";
10
10
  */
11
11
  export function createMigrationExecutor(config: KyselyConfig): MigrationExecutor {
12
12
  const { db, provider } = config;
13
+ // Resolve the db instance if it's a function
14
+ const kysely = typeof db === "function" ? db() : db;
13
15
 
14
16
  switch (provider) {
15
17
  case "sqlite":
16
- return new SqliteMigrationExecutor(db, provider);
18
+ return new SqliteMigrationExecutor(kysely, provider);
17
19
  case "postgresql":
18
20
  case "cockroachdb":
19
- return new PostgresMigrationExecutor(db, provider);
21
+ return new PostgresMigrationExecutor(kysely, provider);
20
22
  case "mysql":
21
- return new MysqlMigrationExecutor(db, provider);
23
+ return new MysqlMigrationExecutor(kysely, provider);
22
24
  case "mssql":
23
- return new MssqlMigrationExecutor(db, provider);
25
+ return new MssqlMigrationExecutor(kysely, provider);
24
26
  default: {
25
27
  // Ensure exhaustive switch
26
28
  const _exhaustive: never = provider;