@hot-updater/server 0.36.7 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/dist/adapters/databaseConstraintErrors.cjs +23 -0
  2. package/dist/adapters/databaseConstraintErrors.mjs +21 -0
  3. package/dist/adapters/databasePluginUtils.cjs +117 -0
  4. package/dist/adapters/databasePluginUtils.mjs +106 -0
  5. package/dist/adapters/drizzle.cjs +53 -176
  6. package/dist/adapters/drizzle.d.cts +6 -4
  7. package/dist/adapters/drizzle.d.mts +6 -4
  8. package/dist/adapters/drizzle.mjs +54 -177
  9. package/dist/adapters/drizzleCrud.cjs +250 -0
  10. package/dist/adapters/drizzleCrud.mjs +249 -0
  11. package/dist/adapters/drizzleLazyDB.cjs +84 -36
  12. package/dist/adapters/drizzleLazyDB.mjs +84 -36
  13. package/dist/adapters/drizzleQuery.cjs +68 -0
  14. package/dist/adapters/drizzleQuery.mjs +67 -0
  15. package/dist/adapters/kysely.cjs +18 -138
  16. package/dist/adapters/kysely.d.cts +3 -12
  17. package/dist/adapters/kysely.d.mts +3 -12
  18. package/dist/adapters/kysely.mjs +19 -139
  19. package/dist/adapters/kyselyCrud.cjs +254 -0
  20. package/dist/adapters/kyselyCrud.mjs +253 -0
  21. package/dist/adapters/kyselyQuery.cjs +56 -0
  22. package/dist/adapters/kyselyQuery.mjs +55 -0
  23. package/dist/adapters/mongodb.cjs +21 -174
  24. package/dist/adapters/mongodb.d.cts +3 -2
  25. package/dist/adapters/mongodb.d.mts +3 -2
  26. package/dist/adapters/mongodb.mjs +21 -174
  27. package/dist/adapters/mongodbCollections.cjs +36 -0
  28. package/dist/adapters/mongodbCollections.mjs +30 -0
  29. package/dist/adapters/mongodbQuery.cjs +77 -0
  30. package/dist/adapters/mongodbQuery.mjs +70 -0
  31. package/dist/adapters/mongodbReads.cjs +148 -0
  32. package/dist/adapters/mongodbReads.mjs +147 -0
  33. package/dist/adapters/mongodbWrites.cjs +134 -0
  34. package/dist/adapters/mongodbWrites.mjs +133 -0
  35. package/dist/adapters/prisma.cjs +205 -180
  36. package/dist/adapters/prisma.d.cts +3 -3
  37. package/dist/adapters/prisma.d.mts +3 -3
  38. package/dist/adapters/prisma.mjs +206 -181
  39. package/dist/adapters/prismaQuery.cjs +58 -0
  40. package/dist/adapters/prismaQuery.mjs +56 -0
  41. package/dist/adapters/prismaRows.cjs +198 -0
  42. package/dist/adapters/prismaRows.mjs +188 -0
  43. package/dist/analytics/bounded/activeOverview.cjs +87 -0
  44. package/dist/analytics/bounded/activeOverview.mjs +85 -0
  45. package/dist/analytics/bounded/installationSearch.cjs +42 -0
  46. package/dist/analytics/bounded/installationSearch.mjs +42 -0
  47. package/dist/analytics/bounded/persistence.cjs +39 -0
  48. package/dist/analytics/bounded/persistence.mjs +38 -0
  49. package/dist/analytics/bounded/provider.cjs +170 -0
  50. package/dist/analytics/bounded/provider.d.cts +7 -0
  51. package/dist/analytics/bounded/provider.d.mts +7 -0
  52. package/dist/analytics/bounded/provider.mjs +170 -0
  53. package/dist/analytics/bounded/scan.cjs +144 -0
  54. package/dist/analytics/bounded/scan.mjs +138 -0
  55. package/dist/analytics/domain.d.cts +121 -0
  56. package/dist/analytics/domain.d.mts +121 -0
  57. package/dist/analytics/errors.cjs +22 -0
  58. package/dist/analytics/errors.mjs +20 -0
  59. package/dist/analytics/eventInput.cjs +111 -0
  60. package/dist/analytics/eventInput.mjs +111 -0
  61. package/dist/analytics/persistence.d.cts +6 -0
  62. package/dist/analytics/persistence.d.mts +6 -0
  63. package/dist/analytics/queryInput.cjs +58 -0
  64. package/dist/analytics/queryInput.mjs +55 -0
  65. package/dist/analytics/routes.cjs +63 -0
  66. package/dist/analytics/routes.mjs +61 -0
  67. package/dist/analytics/types.d.cts +17 -0
  68. package/dist/analytics/types.d.mts +17 -0
  69. package/dist/apiKeys.cjs +139 -0
  70. package/dist/apiKeys.d.cts +50 -0
  71. package/dist/apiKeys.d.mts +50 -0
  72. package/dist/apiKeys.mjs +133 -0
  73. package/dist/createHotUpdaterCore.cjs +48 -26
  74. package/dist/createHotUpdaterCore.d.cts +49 -17
  75. package/dist/createHotUpdaterCore.d.mts +49 -17
  76. package/dist/createHotUpdaterCore.mjs +51 -29
  77. package/dist/db/createBundleDiff.cjs +45 -68
  78. package/dist/db/createBundleDiff.d.cts +3 -3
  79. package/dist/db/createBundleDiff.d.mts +3 -3
  80. package/dist/db/createBundleDiff.mjs +47 -68
  81. package/dist/db/databasePluginCore.cjs +138 -0
  82. package/dist/db/databasePluginCore.mjs +137 -0
  83. package/dist/db/fixedMigrator.cjs +36 -93
  84. package/dist/db/fixedMigrator.mjs +36 -93
  85. package/dist/db/fixedMigratorMongo.cjs +319 -0
  86. package/dist/db/fixedMigratorMongo.mjs +319 -0
  87. package/dist/db/fixedMigratorShared.cjs +23 -0
  88. package/dist/db/fixedMigratorShared.mjs +18 -0
  89. package/dist/db/mongoMigrationExecution.cjs +11 -0
  90. package/dist/db/mongoMigrationExecution.mjs +11 -0
  91. package/dist/db/releaseCatalog.cjs +66 -0
  92. package/dist/db/releaseCatalog.d.cts +17 -0
  93. package/dist/db/releaseCatalog.d.mts +17 -0
  94. package/dist/db/releaseCatalog.mjs +64 -0
  95. package/dist/db/schema/mongodb.cjs +14 -6
  96. package/dist/db/schema/mongodb.mjs +14 -6
  97. package/dist/db/schema/registry.cjs +0 -2
  98. package/dist/db/schema/registry.mjs +1 -2
  99. package/dist/db/schema/sql.cjs +31 -14
  100. package/dist/db/schema/sql.mjs +32 -13
  101. package/dist/db/schema/sqlOperations.cjs +4 -4
  102. package/dist/db/schema/sqlOperations.mjs +5 -5
  103. package/dist/db/schemaGenerators.cjs +52 -18
  104. package/dist/db/schemaGenerators.mjs +52 -18
  105. package/dist/db/schemaReadiness.cjs +4 -3
  106. package/dist/db/schemaReadiness.mjs +4 -3
  107. package/dist/db/sqlMigrationExecution.cjs +67 -0
  108. package/dist/db/sqlMigrationExecution.mjs +66 -0
  109. package/dist/db/types.cjs +2 -6
  110. package/dist/db/types.d.cts +60 -16
  111. package/dist/db/types.d.mts +60 -16
  112. package/dist/db/types.mjs +3 -6
  113. package/dist/db/updateArtifacts.cjs +114 -60
  114. package/dist/db/updateArtifacts.mjs +117 -62
  115. package/dist/handler.cjs +108 -282
  116. package/dist/handler.d.cts +3 -46
  117. package/dist/handler.d.mts +3 -46
  118. package/dist/handler.mjs +107 -281
  119. package/dist/handlerBundleRoutes.cjs +155 -0
  120. package/dist/handlerBundleRoutes.mjs +155 -0
  121. package/dist/handlerErrors.cjs +9 -0
  122. package/dist/handlerErrors.mjs +9 -0
  123. package/dist/handlerParameters.cjs +39 -0
  124. package/dist/handlerParameters.mjs +34 -0
  125. package/dist/handlerReleaseCatalogRoutes.cjs +111 -0
  126. package/dist/handlerReleaseCatalogRoutes.mjs +110 -0
  127. package/dist/handlerReleaseManagementRoutes.cjs +125 -0
  128. package/dist/handlerReleaseManagementRoutes.mjs +124 -0
  129. package/dist/handlerTypes.d.cts +63 -0
  130. package/dist/handlerTypes.d.mts +63 -0
  131. package/dist/handlerVersionRoutes.cjs +10 -0
  132. package/dist/handlerVersionRoutes.d.cts +4 -0
  133. package/dist/handlerVersionRoutes.d.mts +4 -0
  134. package/dist/handlerVersionRoutes.mjs +9 -0
  135. package/dist/index.cjs +10 -1
  136. package/dist/index.d.cts +9 -3
  137. package/dist/index.d.mts +9 -3
  138. package/dist/index.mjs +5 -2
  139. package/dist/node.cjs +19 -12
  140. package/dist/node.d.cts +15 -10
  141. package/dist/node.d.mts +15 -10
  142. package/dist/node.mjs +19 -13
  143. package/dist/package.cjs +1 -1
  144. package/dist/package.mjs +1 -1
  145. package/dist/schema/dsl.cjs +19 -2
  146. package/dist/schema/dsl.mjs +17 -3
  147. package/dist/schema/index.cjs +1 -8
  148. package/dist/schema/index.mjs +2 -8
  149. package/dist/schema/types.cjs +3 -1
  150. package/dist/schema/types.mjs +3 -2
  151. package/dist/schema/v1_0_0.cjs +364 -0
  152. package/dist/schema/v1_0_0.mjs +357 -0
  153. package/dist/storageAccess.cjs +69 -25
  154. package/dist/storageAccess.mjs +68 -25
  155. package/dist/types/index.d.cts +4 -3
  156. package/dist/types/index.d.mts +5 -4
  157. package/package.json +8 -7
  158. package/src/adapters/databaseConstraintErrors.ts +25 -0
  159. package/src/adapters/databasePluginTestDatabase.ts +106 -0
  160. package/src/adapters/databasePluginUtils.spec.ts +29 -0
  161. package/src/adapters/databasePluginUtils.ts +214 -0
  162. package/src/adapters/drizzle.spec.ts +208 -47
  163. package/src/adapters/drizzle.ts +106 -293
  164. package/src/adapters/drizzleCrud.ts +419 -0
  165. package/src/adapters/drizzleLazyDB.ts +206 -100
  166. package/src/adapters/drizzleQuery.ts +164 -0
  167. package/src/adapters/kysely.spec.ts +126 -88
  168. package/src/adapters/kysely.ts +76 -334
  169. package/src/adapters/kyselyCrud.ts +588 -0
  170. package/src/adapters/kyselyQuery.ts +128 -0
  171. package/src/adapters/mongodb.spec.ts +141 -0
  172. package/src/adapters/mongodb.ts +60 -288
  173. package/src/adapters/mongodbCollections.ts +62 -0
  174. package/src/adapters/mongodbQuery.ts +226 -0
  175. package/src/adapters/mongodbReads.ts +311 -0
  176. package/src/adapters/mongodbRows.spec.ts +64 -0
  177. package/src/adapters/mongodbRows.ts +118 -0
  178. package/src/adapters/mongodbTestClient.ts +342 -0
  179. package/src/adapters/mongodbTestFilter.ts +166 -0
  180. package/src/adapters/mongodbWrites.ts +260 -0
  181. package/src/adapters/prisma.spec.ts +196 -0
  182. package/src/adapters/prisma.ts +417 -292
  183. package/src/adapters/prismaQuery.ts +129 -0
  184. package/src/adapters/prismaRows.spec.ts +98 -0
  185. package/src/adapters/prismaRows.ts +301 -0
  186. package/src/adapters/prismaTestClient.ts +396 -0
  187. package/src/analytics/analytics.integration.spec.ts +144 -0
  188. package/src/analytics/bounded/activeOverview.spec.ts +189 -0
  189. package/src/analytics/bounded/activeOverview.ts +148 -0
  190. package/src/analytics/bounded/installationSearch.spec.ts +130 -0
  191. package/src/analytics/bounded/installationSearch.ts +69 -0
  192. package/src/analytics/bounded/persistence.ts +43 -0
  193. package/src/analytics/bounded/provider.spec.ts +219 -0
  194. package/src/analytics/bounded/provider.ts +229 -0
  195. package/src/analytics/bounded/scan.ts +235 -0
  196. package/src/analytics/domain.ts +139 -0
  197. package/src/analytics/errors.ts +18 -0
  198. package/src/analytics/eventInput.ts +168 -0
  199. package/src/analytics/persistence.ts +10 -0
  200. package/src/analytics/queryInput.ts +102 -0
  201. package/src/analytics/routes.ts +123 -0
  202. package/src/analytics/types.ts +44 -0
  203. package/src/apiKeys.integration.spec.ts +192 -0
  204. package/src/apiKeys.spec.ts +162 -0
  205. package/src/apiKeys.ts +220 -0
  206. package/src/createHotUpdaterCore.ts +164 -100
  207. package/src/db/bundleRows.spec.ts +164 -0
  208. package/src/db/bundleRows.ts +10 -140
  209. package/src/db/createBundleDiff.spec.ts +172 -127
  210. package/src/db/createBundleDiff.ts +91 -110
  211. package/src/db/databasePluginCore.spec.ts +62 -0
  212. package/src/db/databasePluginCore.testFixtures.ts +76 -0
  213. package/src/db/databasePluginCore.ts +185 -0
  214. package/src/db/databasePluginUpdateCheck.bench.ts +107 -0
  215. package/src/db/fixedMigrator.spec.ts +184 -42
  216. package/src/db/fixedMigrator.ts +64 -205
  217. package/src/db/fixedMigratorMongo.spec.ts +192 -0
  218. package/src/db/fixedMigratorMongo.ts +425 -0
  219. package/src/db/fixedMigratorShared.ts +36 -0
  220. package/src/db/hotUpdaterSchema.ts +0 -1
  221. package/src/db/index.spec.ts +333 -1025
  222. package/src/db/mongoMigrationExecution.ts +23 -0
  223. package/src/db/node-sqlite.d.ts +25 -0
  224. package/src/db/releaseCatalog.ts +148 -0
  225. package/src/db/schema/mongodb.ts +20 -6
  226. package/src/db/schema/sql.ts +52 -11
  227. package/src/db/schema/sqlOperations.ts +5 -4
  228. package/src/db/schemaGenerators.ts +107 -23
  229. package/src/db/schemaReadiness.ts +2 -1
  230. package/src/db/sqlMigrationExecution.spec.ts +65 -0
  231. package/src/db/sqlMigrationExecution.ts +108 -0
  232. package/src/db/types.spec.ts +55 -0
  233. package/src/db/types.ts +129 -65
  234. package/src/db/updateArtifacts.spec.ts +359 -0
  235. package/src/db/updateArtifacts.ts +290 -126
  236. package/src/handler-standalone.integration.spec.ts +401 -364
  237. package/src/handler.spec.ts +137 -582
  238. package/src/handler.testFixtures.ts +30 -0
  239. package/src/handler.ts +218 -616
  240. package/src/handlerAuth.integration.spec.ts +33 -0
  241. package/src/handlerBundleRoutes.ts +259 -0
  242. package/src/handlerErrors.ts +7 -0
  243. package/src/handlerManagement.spec.ts +262 -0
  244. package/src/handlerParameters.ts +105 -0
  245. package/src/handlerReleaseCatalogRoutes.ts +154 -0
  246. package/src/handlerReleaseManagementRoutes.ts +213 -0
  247. package/src/handlerTypes.ts +96 -0
  248. package/src/handlerVersionRoutes.ts +12 -0
  249. package/src/index.ts +22 -2
  250. package/src/node.spec.ts +79 -10
  251. package/src/node.ts +20 -17
  252. package/src/releaseCatalogRoutes.integration.spec.ts +238 -0
  253. package/src/runtime.spec.ts +126 -959
  254. package/src/runtime.testFixtures.ts +71 -0
  255. package/src/schema/dsl-all-versions.spec.ts +26 -17
  256. package/src/schema/dsl.ts +41 -2
  257. package/src/schema/index.ts +3 -9
  258. package/src/schema/types.ts +9 -3
  259. package/src/schema/v1_0_0.spec.ts +146 -0
  260. package/src/schema/v1_0_0.ts +465 -0
  261. package/src/storageAccess.spec.ts +127 -32
  262. package/src/storageAccess.ts +106 -55
  263. package/src/types/index.ts +2 -1
  264. package/dist/db/bundleRows.cjs +0 -82
  265. package/dist/db/bundleRows.d.cts +0 -33
  266. package/dist/db/bundleRows.d.mts +0 -33
  267. package/dist/db/bundleRows.mjs +0 -79
  268. package/dist/db/pluginCore.cjs +0 -242
  269. package/dist/db/pluginCore.mjs +0 -241
  270. package/dist/db/schema/sqlMigrations.cjs +0 -74
  271. package/dist/db/schema/sqlMigrations.mjs +0 -73
  272. package/dist/db/schemaEnhancements.cjs +0 -20
  273. package/dist/db/schemaEnhancements.mjs +0 -19
  274. package/dist/route.cjs +0 -7
  275. package/dist/route.mjs +0 -7
  276. package/dist/schema/v0_21_0.cjs +0 -38
  277. package/dist/schema/v0_21_0.mjs +0 -37
  278. package/dist/schema/v0_29_0.cjs +0 -45
  279. package/dist/schema/v0_29_0.mjs +0 -44
  280. package/dist/schema/v0_31_0.cjs +0 -82
  281. package/dist/schema/v0_31_0.mjs +0 -80
  282. package/src/db/pluginCore.spec.ts +0 -1095
  283. package/src/db/pluginCore.ts +0 -475
  284. package/src/db/pluginUpdateCheck.bench.ts +0 -254
  285. package/src/db/schema/sqlMigrations.ts +0 -219
  286. package/src/db/schemaEnhancements.ts +0 -55
  287. package/src/route.ts +0 -7
  288. package/src/schema/v0_21_0.ts +0 -52
  289. package/src/schema/v0_29_0.ts +0 -62
  290. package/src/schema/v0_31_0.spec.ts +0 -73
  291. package/src/schema/v0_31_0.ts +0 -120
@@ -1,326 +1,139 @@
1
- import { NIL_UUID } from "@hot-updater/core";
2
- import type {
3
- Bundle,
4
- DatabaseBundleQueryOptions,
5
- DatabaseBundleQueryWhere,
6
- } from "@hot-updater/plugin-core";
7
- import {
8
- calculatePagination,
9
- createDatabasePlugin,
10
- filterCompatibleAppVersions,
11
- resolveUpdateInfoFromBundles,
12
- } from "@hot-updater/plugin-core";
1
+ import { createDatabasePlugin } from "@hot-updater/plugin-core";
13
2
  import {
14
- and,
15
- asc,
16
- desc,
17
- eq,
18
- gt,
19
- gte,
20
- inArray,
21
- isNotNull,
22
- isNull,
23
- lt,
24
- lte,
25
- } from "drizzle-orm";
26
- import type { SQLWrapper } from "drizzle-orm";
3
+ createDatabasePluginAdapter,
4
+ type DatabasePluginImplementation,
5
+ type TransactionDatabasePluginImplementation,
6
+ } from "@hot-updater/plugin-core/internal";
27
7
 
28
- import {
29
- bundleToPatchRows,
30
- bundleToRow,
31
- type BundlePatchRow,
32
- type BundleRow,
33
- rowToBundle,
34
- } from "../db/bundleRows";
35
8
  import {
36
9
  getHotUpdaterSchemaVersion,
37
10
  hotUpdaterSchema,
38
11
  } from "../db/schema/registry";
39
12
  import { generateDrizzleSchema } from "../db/schemaGenerators";
40
13
  import type {
41
- DatabasePluginFactory,
14
+ DatabaseAdapterWithCapabilities,
42
15
  ORMProvider,
43
- ORMSQLProvider,
44
16
  SchemaGenerator,
45
17
  } from "../db/types";
46
- import {
47
- createLazyDB,
48
- type DrizzleDB,
49
- type DrizzleTable,
50
- } from "./drizzleLazyDB";
18
+ import { createDrizzleCrud } from "./drizzleCrud";
19
+ import { createLazyDB } from "./drizzleLazyDB";
20
+
21
+ export type DrizzleProvider = Exclude<
22
+ ORMProvider,
23
+ "cockroachdb" | "mongodb" | "mssql"
24
+ >;
51
25
 
52
26
  export interface DrizzleConfig {
53
27
  readonly db: unknown | (() => unknown | Promise<unknown>);
54
- readonly provider: Exclude<ORMProvider, "cockroachdb" | "mongodb" | "mssql">;
28
+ readonly provider: DrizzleProvider;
55
29
  readonly schema?: Record<string, unknown>;
30
+ readonly transaction?: boolean;
56
31
  }
57
32
 
58
- const getTable = (db: DrizzleDB, name: string) => {
59
- const table = db._.fullSchema[name];
60
- if (!table) throw new Error(`Drizzle schema is missing table "${name}".`);
61
- return table;
62
- };
63
-
64
- const column = (table: DrizzleTable, name: string): SQLWrapper =>
65
- table[name] as SQLWrapper;
66
-
67
- const buildWhere = (
68
- table: DrizzleTable,
69
- where: DatabaseBundleQueryWhere | undefined,
70
- ) => {
71
- const conditions = [];
72
- if (where?.channel !== undefined)
73
- conditions.push(eq(column(table, "channel"), where.channel));
74
- if (where?.platform !== undefined)
75
- conditions.push(eq(column(table, "platform"), where.platform));
76
- if (where?.enabled !== undefined)
77
- conditions.push(eq(column(table, "enabled"), where.enabled));
78
- if (where?.fingerprintHash !== undefined) {
79
- conditions.push(
80
- where.fingerprintHash === null
81
- ? isNull(column(table, "fingerprint_hash"))
82
- : eq(column(table, "fingerprint_hash"), where.fingerprintHash),
83
- );
84
- }
85
- if (where?.targetAppVersion !== undefined) {
86
- conditions.push(
87
- where.targetAppVersion === null
88
- ? isNull(column(table, "target_app_version"))
89
- : eq(column(table, "target_app_version"), where.targetAppVersion),
90
- );
91
- }
92
- if (where?.targetAppVersionIn) {
93
- conditions.push(
94
- inArray(column(table, "target_app_version"), where.targetAppVersionIn),
95
- );
96
- }
97
- if (where?.targetAppVersionNotNull) {
98
- conditions.push(isNotNull(column(table, "target_app_version")));
99
- }
100
- if (where?.id?.eq) conditions.push(eq(column(table, "id"), where.id.eq));
101
- if (where?.id?.gt) conditions.push(gt(column(table, "id"), where.id.gt));
102
- if (where?.id?.gte) conditions.push(gte(column(table, "id"), where.id.gte));
103
- if (where?.id?.lt) conditions.push(lt(column(table, "id"), where.id.lt));
104
- if (where?.id?.lte) conditions.push(lte(column(table, "id"), where.id.lte));
105
- if (where?.id?.in) conditions.push(inArray(column(table, "id"), where.id.in));
106
- return conditions.length > 0 ? and(...conditions) : undefined;
107
- };
108
-
109
- const createDrizzlePlugin = createDatabasePlugin<DrizzleConfig>({
110
- name: "drizzle",
111
- factory: (config) => {
112
- const db = createLazyDB(config);
113
- const bundles = getTable(db, "bundles");
114
- const patches = getTable(db, "bundle_patches");
115
- const runInTransaction = async <T>(
116
- operation: (activeDB: DrizzleDB) => Promise<T>,
117
- ) => {
118
- if (typeof db.transaction !== "function") return operation(db);
119
- return db.transaction(operation);
120
- };
121
- const fetchPatchMap = async (bundleIds: readonly string[]) => {
122
- const patchMap = new Map<string, BundlePatchRow[]>();
123
- if (bundleIds.length === 0) return patchMap;
124
- const rows = await db.query["bundle_patches"]?.findMany({
125
- where: inArray(column(patches, "bundle_id"), [...bundleIds]),
126
- orderBy: [asc(column(patches, "order_index"))],
127
- });
128
- for (const row of rows ?? []) {
129
- const patch = row as BundlePatchRow;
130
- const current = patchMap.get(patch.bundle_id) ?? [];
131
- current.push(patch);
132
- patchMap.set(patch.bundle_id, current);
33
+ const createImplementation = (
34
+ config: DrizzleConfig,
35
+ ): DatabasePluginImplementation => {
36
+ const db = createLazyDB(config);
37
+ const crud = createDrizzleCrud(db, config.provider);
38
+ const transaction = db.transaction?.bind(db);
39
+ return {
40
+ ...crud,
41
+ deleteChannel: (input) => {
42
+ if (transaction === undefined) {
43
+ throw new Error(
44
+ "Drizzle channel deletion requires transaction support.",
45
+ );
133
46
  }
134
- return patchMap;
135
- };
136
- const mapRowsToBundles = async (
137
- rows: readonly Record<string, unknown>[],
138
- ): Promise<Bundle[]> => {
139
- const patchMap = await fetchPatchMap(
140
- rows.map((row) => String(row["id"])),
141
- );
142
- return rows.map((row) =>
143
- rowToBundle(row as BundleRow, patchMap.get(String(row["id"])) ?? []),
47
+ return transaction((transactionDatabase) =>
48
+ createDrizzleCrud(transactionDatabase, config.provider).deleteChannel(
49
+ input,
50
+ ),
144
51
  );
145
- };
146
- const upsertBundle = async (activeDB: DrizzleDB, bundle: Bundle) => {
147
- const row = bundleToRow(bundle);
148
- const current = await activeDB.query["bundles"]?.findFirst({
149
- where: eq(column(bundles, "id"), bundle.id),
150
- });
151
- if (current) {
152
- await activeDB
153
- .update(bundles)
154
- .set(row)
155
- .where(eq(column(bundles, "id"), bundle.id));
156
- } else {
157
- const inserted = activeDB.insert(bundles).values(row);
158
- if (inserted.execute) await inserted.execute();
159
- else await inserted;
160
- }
161
- await activeDB
162
- .delete(patches)
163
- .where(eq(column(patches, "bundle_id"), bundle.id));
164
- const patchRows = bundleToPatchRows(bundle);
165
- if (patchRows.length > 0) {
166
- const inserted = activeDB.insert(patches).values(patchRows);
167
- if (inserted.execute) await inserted.execute();
168
- else await inserted;
169
- }
170
- };
171
- return {
172
- async getBundleById(bundleId) {
173
- const row = await db.query["bundles"]?.findFirst({
174
- where: eq(column(bundles, "id"), bundleId),
175
- });
176
- if (!row) return null;
177
- const patchMap = await fetchPatchMap([bundleId]);
178
- return rowToBundle(row as BundleRow, patchMap.get(bundleId) ?? []);
179
- },
180
- async getBundles(
181
- options: DatabaseBundleQueryOptions & { offset?: number },
182
- ) {
183
- const offset = options.offset ?? 0;
184
- const orderBy = options.orderBy ?? { field: "id", direction: "desc" };
185
- const where = buildWhere(bundles, options.where);
186
- const total = await db.$count(bundles, where);
187
- const rows = await db.query["bundles"]?.findMany({
188
- where,
189
- orderBy: [
190
- orderBy.direction === "asc"
191
- ? asc(column(bundles, "id"))
192
- : desc(column(bundles, "id")),
193
- ],
194
- limit: options.limit,
195
- offset,
196
- });
197
- const dataRows = rows ?? [];
198
- const patchMap = await fetchPatchMap(
199
- dataRows.map((row) => String(row["id"])),
200
- );
201
- return {
202
- data: dataRows.map((row) =>
203
- rowToBundle(
204
- row as BundleRow,
205
- patchMap.get(String(row["id"])) ?? [],
52
+ },
53
+ ...(transaction
54
+ ? {
55
+ delete: (input: Parameters<typeof crud.delete>[0]) =>
56
+ transaction((transactionDatabase) =>
57
+ createDrizzleCrud(transactionDatabase, config.provider).delete(
58
+ input,
59
+ ),
206
60
  ),
207
- ),
208
- pagination: calculatePagination(total, {
209
- limit: options.limit,
210
- offset,
211
- }),
212
- };
213
- },
214
- async getUpdateInfo(args, context) {
215
- if (args._updateStrategy === "appVersion") {
216
- const channel = args.channel ?? "production";
217
- const minBundleId = args.minBundleId ?? NIL_UUID;
218
- const rows = await db.query["bundles"]?.findMany({
219
- columns: { target_app_version: true },
220
- where: buildWhere(bundles, {
221
- enabled: true,
222
- platform: args.platform,
223
- channel,
224
- id: { gte: minBundleId },
225
- targetAppVersionNotNull: true,
226
- }),
227
- });
228
-
229
- const targetAppVersions = Array.from(
230
- new Set(
231
- (rows ?? [])
232
- .map((row) => row["target_app_version"])
233
- .filter(
234
- (value): value is string =>
235
- typeof value === "string" && value.length > 0,
236
- ),
61
+ }
62
+ : {}),
63
+ ...(transaction
64
+ ? {
65
+ transaction: async <TResult>(
66
+ callback: (
67
+ transaction: TransactionDatabasePluginImplementation,
68
+ ) => Promise<TResult>,
69
+ ): Promise<TResult> =>
70
+ transaction((transaction) =>
71
+ callback(createDrizzleCrud(transaction, config.provider)),
237
72
  ),
238
- );
239
- const compatibleAppVersions = filterCompatibleAppVersions(
240
- targetAppVersions,
241
- args.appVersion,
242
- );
243
- const updateRows =
244
- compatibleAppVersions.length > 0
245
- ? await db.query["bundles"]?.findMany({
246
- where: buildWhere(bundles, {
247
- enabled: true,
248
- platform: args.platform,
249
- channel,
250
- id: { gte: minBundleId },
251
- targetAppVersionIn: compatibleAppVersions,
252
- }),
253
- orderBy: [desc(column(bundles, "id"))],
254
- })
255
- : [];
256
-
257
- return resolveUpdateInfoFromBundles({
258
- args: { ...args, channel, minBundleId },
259
- bundles: await mapRowsToBundles(updateRows ?? []),
260
- context,
261
- });
262
73
  }
74
+ : {}),
75
+ };
76
+ };
263
77
 
264
- const channel = args.channel ?? "production";
265
- const minBundleId = args.minBundleId ?? NIL_UUID;
266
- const rows = await db.query["bundles"]?.findMany({
267
- where: buildWhere(bundles, {
268
- enabled: true,
269
- platform: args.platform,
270
- channel,
271
- id: { gte: minBundleId },
272
- fingerprintHash: args.fingerprintHash,
273
- }),
274
- orderBy: [desc(column(bundles, "id"))],
275
- });
276
-
277
- return resolveUpdateInfoFromBundles({
278
- args: { ...args, channel, minBundleId },
279
- bundles: await mapRowsToBundles(rows ?? []),
280
- context,
281
- });
78
+ export const drizzleAdapter = (
79
+ config: DrizzleConfig,
80
+ ): DatabaseAdapterWithCapabilities => {
81
+ let adapter: ReturnType<typeof createDatabasePluginAdapter> | undefined;
82
+ const getAdapter = () => {
83
+ adapter ??= createDatabasePluginAdapter(
84
+ "drizzle",
85
+ createImplementation(config),
86
+ );
87
+ return adapter;
88
+ };
89
+ const plugin = createDatabasePlugin({
90
+ name: "drizzle",
91
+ models: {
92
+ bundles: {
93
+ findById: (id) => getAdapter().models.bundles.findById(id),
94
+ findMany: (query) => getAdapter().models.bundles.findMany(query),
95
+ count: (where) => getAdapter().models.bundles.count(where),
282
96
  },
283
- async getChannels() {
284
- const rows = await db.query["bundles"]?.findMany({
285
- columns: { channel: true },
286
- orderBy: [asc(column(bundles, "channel"))],
287
- });
288
- return Array.from(
289
- new Set((rows ?? []).map((row) => String(row["channel"]))),
290
- );
97
+ bundlePatches: {
98
+ findByBundleIds: (bundleIds) =>
99
+ getAdapter().models.bundlePatches.findByBundleIds(bundleIds),
291
100
  },
292
- async commitBundle({ changedSets }) {
293
- await runInTransaction(async (activeDB) => {
294
- for (const change of changedSets) {
295
- if (change.operation === "delete") {
296
- await activeDB
297
- .delete(patches)
298
- .where(eq(column(patches, "bundle_id"), change.data.id));
299
- await activeDB
300
- .delete(patches)
301
- .where(eq(column(patches, "base_bundle_id"), change.data.id));
302
- await activeDB
303
- .delete(bundles)
304
- .where(eq(column(bundles, "id"), change.data.id));
305
- continue;
306
- }
307
- await upsertBundle(activeDB, change.data);
308
- }
309
- });
101
+ releases: {
102
+ findById: (id) => getAdapter().models.releases.findById(id),
103
+ findMany: (input) => getAdapter().models.releases.findMany(input),
104
+ findManyByScope: (input) =>
105
+ getAdapter().models.releases.findManyByScope(input),
310
106
  },
311
- };
312
- },
313
- });
314
-
315
- export const drizzleAdapter = (
316
- config: DrizzleConfig,
317
- ): DatabasePluginFactory => {
318
- return Object.assign(createDrizzlePlugin(config), {
107
+ releaseCatalogs: {
108
+ findByScopeKey: (scopeKey) =>
109
+ getAdapter().models.releaseCatalogs.findByScopeKey(scopeKey),
110
+ findMany: (input) =>
111
+ getAdapter().models.releaseCatalogs.findMany(input),
112
+ },
113
+ channels: {
114
+ insert: (input) => getAdapter().models.channels.insert(input),
115
+ list: (input) => getAdapter().models.channels.list(input),
116
+ delete: (input) => getAdapter().models.channels.delete(input),
117
+ },
118
+ analytics: {
119
+ append: (row) => getAdapter().models.analytics.append(row),
120
+ scan: (input) => getAdapter().models.analytics.scan(input),
121
+ },
122
+ apiKeys: {
123
+ create: (row) => getAdapter().models.apiKeys.create(row),
124
+ findByHash: (hash) => getAdapter().models.apiKeys.findByHash(hash),
125
+ list: () => getAdapter().models.apiKeys.list(),
126
+ revoke: (input) => getAdapter().models.apiKeys.revoke(input),
127
+ },
128
+ },
129
+ commit: (input) => getAdapter().commit(input),
130
+ });
131
+ return Object.assign(plugin, {
319
132
  adapterName: "drizzle",
320
133
  provider: config.provider,
321
134
  generateSchema: (version: Parameters<SchemaGenerator>[0]) => ({
322
135
  code: generateDrizzleSchema(
323
- config.provider as ORMSQLProvider,
136
+ config.provider,
324
137
  version === "latest"
325
138
  ? hotUpdaterSchema
326
139
  : getHotUpdaterSchemaVersion(version),