@hot-updater/server 1.0.0-rc.1 → 1.0.0-rc.16

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 (542) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +1 -1
  2. package/dist/adapters/drizzle.cjs +35 -69
  3. package/dist/adapters/drizzle.d.cts +13 -6
  4. package/dist/adapters/drizzle.d.mts +13 -6
  5. package/dist/adapters/drizzle.mjs +34 -69
  6. package/dist/adapters/drizzleExecutor.cjs +114 -0
  7. package/dist/adapters/drizzleExecutor.d.cts +9 -0
  8. package/dist/adapters/drizzleExecutor.d.mts +9 -0
  9. package/dist/adapters/drizzleExecutor.mjs +112 -0
  10. package/dist/adapters/kysely.cjs +25 -31
  11. package/dist/adapters/kysely.d.cts +10 -7
  12. package/dist/adapters/kysely.d.mts +10 -7
  13. package/dist/adapters/kysely.mjs +25 -31
  14. package/dist/adapters/kyselyExecutor.cjs +32 -0
  15. package/dist/adapters/kyselyExecutor.d.cts +12 -0
  16. package/dist/adapters/kyselyExecutor.d.mts +12 -0
  17. package/dist/adapters/kyselyExecutor.mjs +32 -0
  18. package/dist/adapters/mongodb.cjs +28 -27
  19. package/dist/adapters/mongodb.d.cts +10 -5
  20. package/dist/adapters/mongodb.d.mts +10 -5
  21. package/dist/adapters/mongodb.mjs +28 -27
  22. package/dist/adapters/mongodbAdapter.cjs +174 -0
  23. package/dist/adapters/mongodbAdapter.d.cts +9 -0
  24. package/dist/adapters/mongodbAdapter.d.mts +9 -0
  25. package/dist/adapters/mongodbAdapter.mjs +173 -0
  26. package/dist/adapters/prisma.cjs +38 -220
  27. package/dist/adapters/prisma.d.cts +12 -8
  28. package/dist/adapters/prisma.d.mts +12 -8
  29. package/dist/adapters/prisma.mjs +38 -219
  30. package/dist/adapters/prismaExecutor.cjs +64 -0
  31. package/dist/adapters/prismaExecutor.mjs +64 -0
  32. package/dist/adapters/sqlProviders.cjs +9 -0
  33. package/dist/adapters/sqlProviders.mjs +9 -0
  34. package/dist/apiKeys.cjs +8 -8
  35. package/dist/apiKeys.d.cts +1 -24
  36. package/dist/apiKeys.d.mts +1 -24
  37. package/dist/apiKeys.mjs +5 -9
  38. package/dist/assembly/assemblePlugins.cjs +147 -0
  39. package/dist/assembly/assemblePlugins.d.cts +12 -0
  40. package/dist/assembly/assemblePlugins.d.mts +12 -0
  41. package/dist/assembly/assemblePlugins.mjs +146 -0
  42. package/dist/assembly/databasePlugins.cjs +23 -0
  43. package/dist/assembly/databasePlugins.d.cts +43 -0
  44. package/dist/assembly/databasePlugins.d.mts +43 -0
  45. package/dist/assembly/databasePlugins.mjs +22 -0
  46. package/dist/core/api.cjs +91 -0
  47. package/dist/core/api.d.cts +65 -0
  48. package/dist/core/api.d.mts +65 -0
  49. package/dist/core/api.mjs +87 -0
  50. package/dist/core/baseCandidates.cjs +71 -0
  51. package/dist/core/baseCandidates.d.cts +17 -0
  52. package/dist/core/baseCandidates.d.mts +17 -0
  53. package/dist/core/baseCandidates.mjs +69 -0
  54. package/dist/core/operations.cjs +350 -0
  55. package/dist/core/operations.mjs +350 -0
  56. package/dist/core/reads.cjs +273 -0
  57. package/dist/core/reads.d.cts +48 -0
  58. package/dist/core/reads.d.mts +48 -0
  59. package/dist/core/reads.mjs +267 -0
  60. package/dist/core/releases.cjs +193 -0
  61. package/dist/core/releases.mjs +190 -0
  62. package/dist/core/schema.cjs +279 -0
  63. package/dist/core/schema.d.cts +307 -0
  64. package/dist/core/schema.d.mts +307 -0
  65. package/dist/core/schema.mjs +277 -0
  66. package/dist/core/writes.cjs +96 -0
  67. package/dist/core/writes.mjs +91 -0
  68. package/dist/createHotUpdaterCore.cjs +61 -63
  69. package/dist/createHotUpdaterCore.d.cts +53 -45
  70. package/dist/createHotUpdaterCore.d.mts +53 -45
  71. package/dist/createHotUpdaterCore.mjs +61 -63
  72. package/dist/database/cursor.cjs +44 -0
  73. package/dist/database/cursor.d.cts +7 -0
  74. package/dist/database/cursor.d.mts +7 -0
  75. package/dist/database/cursor.mjs +40 -0
  76. package/dist/database/database.cjs +44 -0
  77. package/dist/database/database.d.cts +123 -0
  78. package/dist/database/database.d.mts +123 -0
  79. package/dist/database/database.mjs +44 -0
  80. package/dist/database/definitions.d.cts +68 -0
  81. package/dist/database/definitions.d.mts +68 -0
  82. package/dist/database/engine.cjs +37 -0
  83. package/dist/database/engine.d.cts +40 -0
  84. package/dist/database/engine.d.mts +40 -0
  85. package/dist/database/engine.mjs +37 -0
  86. package/dist/database/engineAggregates.cjs +115 -0
  87. package/dist/database/engineAggregates.mjs +112 -0
  88. package/dist/database/engineReads.cjs +180 -0
  89. package/dist/database/engineReads.d.cts +35 -0
  90. package/dist/database/engineReads.d.mts +35 -0
  91. package/dist/database/engineReads.mjs +179 -0
  92. package/dist/database/engineTransaction.cjs +403 -0
  93. package/dist/database/engineTransaction.d.cts +26 -0
  94. package/dist/database/engineTransaction.d.mts +26 -0
  95. package/dist/database/engineTransaction.mjs +402 -0
  96. package/dist/database/errors.cjs +27 -0
  97. package/dist/database/errors.d.cts +21 -0
  98. package/dist/database/errors.d.mts +21 -0
  99. package/dist/database/errors.mjs +24 -0
  100. package/dist/database/fence.cjs +124 -0
  101. package/dist/database/fence.d.cts +42 -0
  102. package/dist/database/fence.d.mts +42 -0
  103. package/dist/database/fence.mjs +116 -0
  104. package/dist/database/index.cjs +127 -0
  105. package/dist/database/index.d.cts +17 -0
  106. package/dist/database/index.d.mts +17 -0
  107. package/dist/database/index.mjs +15 -0
  108. package/dist/database/kv/kvAdapter.cjs +273 -0
  109. package/dist/database/kv/kvAdapter.d.cts +101 -0
  110. package/dist/database/kv/kvAdapter.d.mts +101 -0
  111. package/dist/database/kv/kvAdapter.mjs +272 -0
  112. package/dist/database/resolveSchema.cjs +196 -0
  113. package/dist/database/resolveSchema.d.cts +42 -0
  114. package/dist/database/resolveSchema.d.mts +42 -0
  115. package/dist/database/resolveSchema.mjs +193 -0
  116. package/dist/database/schema.cjs +21 -0
  117. package/dist/database/schema.d.cts +61 -0
  118. package/dist/database/schema.d.mts +61 -0
  119. package/dist/database/schema.mjs +20 -0
  120. package/dist/database/sql/sqlAdapter.cjs +282 -0
  121. package/dist/database/sql/sqlAdapter.d.cts +46 -0
  122. package/dist/database/sql/sqlAdapter.d.mts +46 -0
  123. package/dist/database/sql/sqlAdapter.mjs +279 -0
  124. package/dist/database/sql/sqlSchema.cjs +115 -0
  125. package/dist/database/sql/sqlSchema.d.cts +8 -0
  126. package/dist/database/sql/sqlSchema.d.mts +8 -0
  127. package/dist/database/sql/sqlSchema.mjs +111 -0
  128. package/dist/db/builtInDatabase.cjs +104 -0
  129. package/dist/db/builtInDatabase.d.cts +38 -0
  130. package/dist/db/builtInDatabase.d.mts +38 -0
  131. package/dist/db/builtInDatabase.mjs +97 -0
  132. package/dist/db/createBundleDiff.cjs +6 -6
  133. package/dist/db/createBundleDiff.d.cts +4 -7
  134. package/dist/db/createBundleDiff.d.mts +4 -7
  135. package/dist/db/createBundleDiff.mjs +5 -5
  136. package/dist/db/engineDrizzleSchema.cjs +54 -0
  137. package/dist/db/engineDrizzleSchema.mjs +54 -0
  138. package/dist/db/engineMigrator.cjs +53 -0
  139. package/dist/db/engineMigrator.mjs +53 -0
  140. package/dist/db/enginePrismaSchema.cjs +85 -0
  141. package/dist/db/enginePrismaSchema.d.cts +5 -0
  142. package/dist/db/enginePrismaSchema.d.mts +5 -0
  143. package/dist/db/enginePrismaSchema.mjs +84 -0
  144. package/dist/db/engineSql.cjs +26 -0
  145. package/dist/db/engineSql.d.cts +17 -0
  146. package/dist/db/engineSql.d.mts +17 -0
  147. package/dist/db/engineSql.mjs +25 -0
  148. package/dist/db/engineSqlMigrator.cjs +66 -0
  149. package/dist/db/engineSqlMigrator.mjs +66 -0
  150. package/dist/db/fixedMigratorShared.cjs +0 -11
  151. package/dist/db/fixedMigratorShared.mjs +1 -8
  152. package/dist/db/index.cjs +23 -8
  153. package/dist/db/index.d.cts +10 -4
  154. package/dist/db/index.d.mts +10 -4
  155. package/dist/db/index.mjs +16 -8
  156. package/dist/db/releaseCatalog.cjs +20 -44
  157. package/dist/db/releaseCatalog.d.cts +2 -3
  158. package/dist/db/releaseCatalog.d.mts +2 -3
  159. package/dist/db/releaseCatalog.mjs +20 -44
  160. package/dist/db/schemaSettings.cjs +63 -0
  161. package/dist/db/schemaSettings.d.cts +12 -0
  162. package/dist/db/schemaSettings.d.mts +12 -0
  163. package/dist/db/schemaSettings.mjs +62 -0
  164. package/dist/db/settingsMigrator.cjs +92 -0
  165. package/dist/db/settingsMigrator.mjs +89 -0
  166. package/dist/db/types.cjs +3 -12
  167. package/dist/db/types.d.cts +26 -69
  168. package/dist/db/types.d.mts +26 -69
  169. package/dist/db/types.mjs +2 -11
  170. package/dist/db/updateArtifacts.cjs +38 -68
  171. package/dist/db/updateArtifacts.mjs +40 -69
  172. package/dist/handler.cjs +72 -43
  173. package/dist/handler.d.cts +3 -6
  174. package/dist/handler.d.mts +3 -6
  175. package/dist/handler.mjs +73 -43
  176. package/dist/handlerAdminRoutes.cjs +375 -0
  177. package/dist/handlerAdminRoutes.mjs +373 -0
  178. package/dist/handlerParameters.cjs +6 -11
  179. package/dist/handlerParameters.mjs +6 -10
  180. package/dist/handlerReleaseCatalogRoutes.cjs +11 -14
  181. package/dist/handlerReleaseCatalogRoutes.mjs +11 -13
  182. package/dist/handlerTypes.d.cts +2 -56
  183. package/dist/handlerTypes.d.mts +2 -56
  184. package/dist/handlerVersionRoutes.cjs +20 -4
  185. package/dist/handlerVersionRoutes.d.cts +1 -0
  186. package/dist/handlerVersionRoutes.d.mts +1 -0
  187. package/dist/handlerVersionRoutes.mjs +20 -4
  188. package/dist/index.cjs +4 -7
  189. package/dist/index.d.cts +10 -9
  190. package/dist/index.d.mts +10 -9
  191. package/dist/index.mjs +4 -4
  192. package/dist/insights/domain.d.cts +53 -70
  193. package/dist/insights/domain.d.mts +53 -70
  194. package/dist/insights/errors.cjs +35 -8
  195. package/dist/insights/errors.mjs +35 -8
  196. package/dist/insights/eventInput.cjs +64 -24
  197. package/dist/insights/eventInput.mjs +63 -25
  198. package/dist/insights/provider.cjs +356 -0
  199. package/dist/insights/provider.d.cts +6 -0
  200. package/dist/insights/provider.d.mts +6 -0
  201. package/dist/insights/provider.mjs +355 -0
  202. package/dist/insights/queryInput.cjs +78 -43
  203. package/dist/insights/queryInput.mjs +76 -40
  204. package/dist/insights/routes.cjs +94 -34
  205. package/dist/insights/routes.mjs +93 -35
  206. package/dist/insights/types.d.cts +27 -12
  207. package/dist/insights/types.d.mts +27 -12
  208. package/dist/node.d.cts +1 -2
  209. package/dist/node.d.mts +1 -2
  210. package/dist/package.cjs +1 -1
  211. package/dist/package.mjs +1 -1
  212. package/dist/plugins/api-keys/index.cjs +50 -0
  213. package/dist/plugins/api-keys/index.d.cts +85 -0
  214. package/dist/plugins/api-keys/index.d.mts +85 -0
  215. package/dist/plugins/api-keys/index.mjs +47 -0
  216. package/dist/plugins/api-keys/model.cjs +58 -0
  217. package/dist/plugins/api-keys/model.d.cts +8 -0
  218. package/dist/plugins/api-keys/model.d.mts +8 -0
  219. package/dist/plugins/api-keys/model.mjs +58 -0
  220. package/dist/plugins/api-keys/schema.cjs +38 -0
  221. package/dist/plugins/api-keys/schema.d.cts +44 -0
  222. package/dist/plugins/api-keys/schema.d.mts +44 -0
  223. package/dist/plugins/api-keys/schema.mjs +39 -0
  224. package/dist/plugins/builtIn.cjs +7 -0
  225. package/dist/plugins/builtIn.mjs +6 -0
  226. package/dist/plugins/definePlugin.cjs +5 -0
  227. package/dist/plugins/definePlugin.d.cts +73 -0
  228. package/dist/plugins/definePlugin.d.mts +73 -0
  229. package/dist/plugins/definePlugin.mjs +5 -0
  230. package/dist/plugins/index.cjs +17 -0
  231. package/dist/plugins/index.d.cts +9 -0
  232. package/dist/plugins/index.d.mts +9 -0
  233. package/dist/plugins/index.mjs +7 -0
  234. package/dist/plugins/insights/index.cjs +48 -0
  235. package/dist/plugins/insights/index.d.cts +295 -0
  236. package/dist/plugins/insights/index.d.mts +295 -0
  237. package/dist/plugins/insights/index.mjs +44 -0
  238. package/dist/plugins/insights/model.cjs +17 -0
  239. package/dist/plugins/insights/model.d.cts +10 -0
  240. package/dist/plugins/insights/model.d.mts +10 -0
  241. package/dist/plugins/insights/model.mjs +17 -0
  242. package/dist/plugins/insights/reads.cjs +471 -0
  243. package/dist/plugins/insights/reads.mjs +466 -0
  244. package/dist/plugins/insights/recordEvent.cjs +135 -0
  245. package/dist/plugins/insights/recordEvent.d.cts +13 -0
  246. package/dist/plugins/insights/recordEvent.d.mts +13 -0
  247. package/dist/plugins/insights/recordEvent.mjs +132 -0
  248. package/dist/plugins/insights/schema.cjs +347 -0
  249. package/dist/plugins/insights/schema.d.cts +258 -0
  250. package/dist/plugins/insights/schema.d.mts +258 -0
  251. package/dist/plugins/insights/schema.mjs +344 -0
  252. package/dist/storageAccess.cjs +0 -1
  253. package/dist/types/index.d.cts +2 -29
  254. package/dist/types/index.d.mts +2 -29
  255. package/package.json +30 -7
  256. package/src/adapters/drizzle.conformance.integration.spec.ts +34 -0
  257. package/src/adapters/drizzle.readBudgets.integration.spec.ts +41 -0
  258. package/src/adapters/drizzle.spec.ts +277 -208
  259. package/src/adapters/drizzle.ts +48 -128
  260. package/src/adapters/drizzleExecutor.ts +166 -0
  261. package/src/adapters/kysely.conformance.integration.spec.ts +36 -0
  262. package/src/adapters/kysely.readBudgets.integration.spec.ts +42 -0
  263. package/src/adapters/kysely.spec.ts +212 -117
  264. package/src/adapters/kysely.ts +32 -87
  265. package/src/adapters/kyselyExecutor.ts +53 -0
  266. package/src/adapters/mongodb.integration.spec.ts +180 -0
  267. package/src/adapters/mongodb.readBudgets.integration.spec.ts +61 -0
  268. package/src/adapters/mongodb.ts +36 -65
  269. package/src/adapters/mongodbAdapter.ts +293 -0
  270. package/src/adapters/prisma.conformance.integration.spec.ts +36 -0
  271. package/src/adapters/prisma.integration.spec.ts +138 -0
  272. package/src/adapters/prisma.readBudgets.integration.spec.ts +40 -0
  273. package/src/adapters/prisma.spec.ts +226 -173
  274. package/src/adapters/prisma.ts +60 -451
  275. package/src/adapters/prismaExecutor.ts +107 -0
  276. package/src/adapters/prismaTestClients.ts +175 -0
  277. package/src/adapters/sqlProviders.ts +14 -0
  278. package/src/apiKeys.integration.spec.ts +19 -119
  279. package/src/apiKeys.spec.ts +39 -35
  280. package/src/apiKeys.ts +2 -8
  281. package/src/assembly/assemblePlugins.ts +269 -0
  282. package/src/assembly/assembly.spec.ts +325 -0
  283. package/src/assembly/assembly.types.spec.ts +155 -0
  284. package/src/assembly/builtInRoutes.spec.ts +213 -0
  285. package/src/assembly/databasePlugins.spec.ts +71 -0
  286. package/src/assembly/databasePlugins.ts +96 -0
  287. package/src/core/api.ts +139 -0
  288. package/src/core/baseCandidates.spec.ts +378 -0
  289. package/src/core/baseCandidates.ts +136 -0
  290. package/src/core/index.ts +44 -0
  291. package/src/core/operations.spec.ts +415 -0
  292. package/src/core/operations.ts +551 -0
  293. package/src/core/reads.spec.ts +300 -0
  294. package/src/core/reads.ts +417 -0
  295. package/src/core/releases.spec.ts +308 -0
  296. package/src/core/releases.ts +345 -0
  297. package/src/core/schema.ts +173 -0
  298. package/src/core/writes.ts +160 -0
  299. package/src/createHotUpdaterCore.ts +191 -167
  300. package/src/database/cursor.ts +65 -0
  301. package/src/database/database.ts +335 -0
  302. package/src/database/database.types.spec.ts +135 -0
  303. package/src/database/definitions.ts +72 -0
  304. package/src/database/engine.ts +62 -0
  305. package/src/database/engineAggregates.spec.ts +539 -0
  306. package/src/database/engineAggregates.ts +193 -0
  307. package/src/database/engineReads.spec.ts +219 -0
  308. package/src/database/engineReads.ts +302 -0
  309. package/src/database/engineTransaction.spec.ts +710 -0
  310. package/src/database/engineTransaction.ts +588 -0
  311. package/src/database/errors.ts +30 -0
  312. package/src/database/fence.spec.ts +223 -0
  313. package/src/database/fence.ts +171 -0
  314. package/src/database/index.ts +154 -0
  315. package/src/database/kv/kvAdapter.conformance.integration.spec.ts +17 -0
  316. package/src/database/kv/kvAdapter.readBudgets.integration.spec.ts +17 -0
  317. package/src/database/kv/kvAdapter.spec.ts +468 -0
  318. package/src/database/kv/kvAdapter.ts +450 -0
  319. package/src/database/kv/kvTestStore.ts +91 -0
  320. package/src/database/memory.readBudgets.integration.spec.ts +13 -0
  321. package/src/database/resolveSchema.spec.ts +230 -0
  322. package/src/database/resolveSchema.ts +372 -0
  323. package/src/database/schema.ts +169 -0
  324. package/src/database/schema.types.spec.ts +94 -0
  325. package/src/database/sql/docker-compose.yml +36 -0
  326. package/src/database/sql/sqlAdapter.integration.spec.ts +148 -0
  327. package/src/database/sql/sqlAdapter.readBudgets.integration.spec.ts +109 -0
  328. package/src/database/sql/sqlAdapter.spec.ts +255 -0
  329. package/src/database/sql/sqlAdapter.ts +532 -0
  330. package/src/database/sql/sqlSchema.ts +205 -0
  331. package/src/database/sql/sqlTestExecutors.ts +183 -0
  332. package/src/databaseTestSuite.spec.ts +39 -0
  333. package/src/db/builtInDatabase.ts +149 -0
  334. package/src/db/bundleRows.spec.ts +3 -3
  335. package/src/db/createBundleDiff.spec.ts +43 -29
  336. package/src/db/createBundleDiff.ts +13 -7
  337. package/src/db/engineDrizzleSchema.ts +72 -0
  338. package/src/db/engineMigrator.ts +105 -0
  339. package/src/db/enginePrismaSchema.ts +147 -0
  340. package/src/db/engineSql.spec.ts +129 -0
  341. package/src/db/engineSql.ts +48 -0
  342. package/src/db/engineSqlMigrator.ts +116 -0
  343. package/src/db/fixedMigratorShared.ts +1 -20
  344. package/src/db/index.spec.ts +116 -824
  345. package/src/db/index.ts +43 -14
  346. package/src/db/pluginTables.spec.ts +218 -0
  347. package/src/db/releaseCatalog.ts +48 -90
  348. package/src/db/schemaSettings.ts +104 -0
  349. package/src/db/settingsMigrator.spec.ts +65 -0
  350. package/src/db/settingsMigrator.ts +152 -0
  351. package/src/db/types.ts +25 -165
  352. package/src/db/updateArtifacts.spec.ts +170 -294
  353. package/src/db/updateArtifacts.ts +74 -142
  354. package/src/db/updateCheck.bench.ts +47 -0
  355. package/src/handler-standalone.integration.spec.ts +204 -412
  356. package/src/handler.spec.ts +134 -51
  357. package/src/handler.testFixtures.ts +14 -19
  358. package/src/handler.ts +163 -75
  359. package/src/handlerAdminRoutes.spec.ts +183 -0
  360. package/src/handlerAdminRoutes.ts +536 -0
  361. package/src/handlerAuth.integration.spec.ts +3 -3
  362. package/src/handlerManagement.spec.ts +136 -196
  363. package/src/handlerReleaseCatalogRoutes.ts +15 -17
  364. package/src/handlerTypes.ts +3 -80
  365. package/src/handlerVersionRoutes.ts +20 -7
  366. package/src/index.ts +7 -14
  367. package/src/insights/domain.ts +56 -77
  368. package/src/insights/errors.spec.ts +48 -0
  369. package/src/insights/errors.ts +50 -6
  370. package/src/insights/eventInput.ts +80 -27
  371. package/src/insights/insights.integration.spec.ts +525 -44
  372. package/src/insights/provider.spec.ts +574 -0
  373. package/src/insights/provider.ts +667 -0
  374. package/src/insights/queryInput.ts +113 -73
  375. package/src/insights/routes.ts +125 -69
  376. package/src/insights/types.ts +47 -36
  377. package/src/lintRules.spec.ts +76 -0
  378. package/src/plugins/api-keys/apiKeysPlugin.spec.ts +172 -0
  379. package/src/plugins/api-keys/index.ts +66 -0
  380. package/src/plugins/api-keys/model.ts +69 -0
  381. package/src/plugins/api-keys/schema.ts +22 -0
  382. package/src/plugins/builtIn.ts +5 -0
  383. package/src/plugins/definePlugin.ts +100 -0
  384. package/src/plugins/index.ts +55 -0
  385. package/src/plugins/insights/index.ts +86 -0
  386. package/src/plugins/insights/insightsRollout.integration.spec.ts +187 -0
  387. package/src/plugins/insights/model.spec.ts +66 -0
  388. package/src/plugins/insights/model.ts +19 -0
  389. package/src/plugins/insights/reads.spec.ts +725 -0
  390. package/src/plugins/insights/reads.ts +707 -0
  391. package/src/plugins/insights/recordEvent.spec.ts +443 -0
  392. package/src/plugins/insights/recordEvent.ts +238 -0
  393. package/src/plugins/insights/schema.ts +229 -0
  394. package/src/plugins/pluginTestHarness.spec.ts +56 -0
  395. package/src/readBudgets.testFixtures.ts +15 -0
  396. package/src/releaseCatalogRoutes.integration.spec.ts +47 -92
  397. package/src/runtime.spec.ts +91 -77
  398. package/src/runtime.testFixtures.ts +28 -44
  399. package/src/runtimeBundles.integration.spec.ts +112 -0
  400. package/src/testUtilsMutation.integration.spec.ts +215 -0
  401. package/src/testUtilsPackage.integration.spec.ts +176 -0
  402. package/src/types/index.ts +0 -32
  403. package/dist/adapters/databaseConstraintErrors.cjs +0 -23
  404. package/dist/adapters/databaseConstraintErrors.mjs +0 -21
  405. package/dist/adapters/databasePluginUtils.cjs +0 -117
  406. package/dist/adapters/databasePluginUtils.mjs +0 -106
  407. package/dist/adapters/drizzleCrud.cjs +0 -250
  408. package/dist/adapters/drizzleCrud.mjs +0 -249
  409. package/dist/adapters/drizzleLazyDB.cjs +0 -101
  410. package/dist/adapters/drizzleLazyDB.mjs +0 -101
  411. package/dist/adapters/drizzleQuery.cjs +0 -68
  412. package/dist/adapters/drizzleQuery.mjs +0 -67
  413. package/dist/adapters/kyselyCrud.cjs +0 -254
  414. package/dist/adapters/kyselyCrud.mjs +0 -253
  415. package/dist/adapters/kyselyQuery.cjs +0 -56
  416. package/dist/adapters/kyselyQuery.mjs +0 -55
  417. package/dist/adapters/mongodbCollections.cjs +0 -36
  418. package/dist/adapters/mongodbCollections.mjs +0 -30
  419. package/dist/adapters/mongodbQuery.cjs +0 -77
  420. package/dist/adapters/mongodbQuery.mjs +0 -70
  421. package/dist/adapters/mongodbReads.cjs +0 -148
  422. package/dist/adapters/mongodbReads.mjs +0 -147
  423. package/dist/adapters/mongodbWrites.cjs +0 -134
  424. package/dist/adapters/mongodbWrites.mjs +0 -133
  425. package/dist/adapters/prismaQuery.cjs +0 -58
  426. package/dist/adapters/prismaQuery.mjs +0 -56
  427. package/dist/adapters/prismaRows.cjs +0 -198
  428. package/dist/adapters/prismaRows.mjs +0 -188
  429. package/dist/db/databasePluginCore.cjs +0 -138
  430. package/dist/db/databasePluginCore.mjs +0 -137
  431. package/dist/db/fixedMigrator.cjs +0 -79
  432. package/dist/db/fixedMigrator.mjs +0 -78
  433. package/dist/db/fixedMigratorMongo.cjs +0 -319
  434. package/dist/db/fixedMigratorMongo.mjs +0 -319
  435. package/dist/db/mongoMigrationExecution.cjs +0 -11
  436. package/dist/db/mongoMigrationExecution.mjs +0 -11
  437. package/dist/db/schema/mongodb.cjs +0 -25
  438. package/dist/db/schema/mongodb.mjs +0 -25
  439. package/dist/db/schema/registry.cjs +0 -21
  440. package/dist/db/schema/registry.mjs +0 -17
  441. package/dist/db/schema/sql.cjs +0 -101
  442. package/dist/db/schema/sql.mjs +0 -97
  443. package/dist/db/schema/sqlOperations.cjs +0 -27
  444. package/dist/db/schema/sqlOperations.mjs +0 -26
  445. package/dist/db/schemaGenerators.cjs +0 -256
  446. package/dist/db/schemaGenerators.mjs +0 -254
  447. package/dist/db/schemaReadiness.cjs +0 -24
  448. package/dist/db/schemaReadiness.d.cts +0 -8
  449. package/dist/db/schemaReadiness.d.mts +0 -8
  450. package/dist/db/schemaReadiness.mjs +0 -23
  451. package/dist/db/sqlMigrationExecution.cjs +0 -67
  452. package/dist/db/sqlMigrationExecution.mjs +0 -66
  453. package/dist/handlerBundleRoutes.cjs +0 -155
  454. package/dist/handlerBundleRoutes.mjs +0 -155
  455. package/dist/handlerReleaseManagementRoutes.cjs +0 -125
  456. package/dist/handlerReleaseManagementRoutes.mjs +0 -124
  457. package/dist/insights/bounded/activeOverview.cjs +0 -87
  458. package/dist/insights/bounded/activeOverview.mjs +0 -85
  459. package/dist/insights/bounded/installationSearch.cjs +0 -42
  460. package/dist/insights/bounded/installationSearch.mjs +0 -42
  461. package/dist/insights/bounded/persistence.cjs +0 -39
  462. package/dist/insights/bounded/persistence.mjs +0 -38
  463. package/dist/insights/bounded/provider.cjs +0 -170
  464. package/dist/insights/bounded/provider.d.cts +0 -7
  465. package/dist/insights/bounded/provider.d.mts +0 -7
  466. package/dist/insights/bounded/provider.mjs +0 -170
  467. package/dist/insights/bounded/scan.cjs +0 -144
  468. package/dist/insights/bounded/scan.mjs +0 -138
  469. package/dist/insights/persistence.d.cts +0 -6
  470. package/dist/insights/persistence.d.mts +0 -6
  471. package/dist/schema/dsl.cjs +0 -103
  472. package/dist/schema/dsl.mjs +0 -87
  473. package/dist/schema/index.cjs +0 -6
  474. package/dist/schema/index.mjs +0 -7
  475. package/dist/schema/settings.cjs +0 -9
  476. package/dist/schema/settings.mjs +0 -9
  477. package/dist/schema/types.cjs +0 -8
  478. package/dist/schema/types.mjs +0 -6
  479. package/dist/schema/v1_0_0.cjs +0 -364
  480. package/dist/schema/v1_0_0.mjs +0 -357
  481. package/src/adapters/databaseConstraintErrors.ts +0 -25
  482. package/src/adapters/databasePluginTestDatabase.ts +0 -106
  483. package/src/adapters/databasePluginUtils.spec.ts +0 -29
  484. package/src/adapters/databasePluginUtils.ts +0 -214
  485. package/src/adapters/drizzleCrud.ts +0 -419
  486. package/src/adapters/drizzleLazyDB.ts +0 -257
  487. package/src/adapters/drizzleQuery.ts +0 -164
  488. package/src/adapters/kyselyCrud.ts +0 -588
  489. package/src/adapters/kyselyQuery.ts +0 -128
  490. package/src/adapters/mongodb.spec.ts +0 -141
  491. package/src/adapters/mongodbCollections.ts +0 -62
  492. package/src/adapters/mongodbQuery.ts +0 -226
  493. package/src/adapters/mongodbReads.ts +0 -311
  494. package/src/adapters/mongodbRows.spec.ts +0 -64
  495. package/src/adapters/mongodbRows.ts +0 -118
  496. package/src/adapters/mongodbTestClient.ts +0 -342
  497. package/src/adapters/mongodbTestFilter.ts +0 -166
  498. package/src/adapters/mongodbWrites.ts +0 -260
  499. package/src/adapters/prismaQuery.ts +0 -129
  500. package/src/adapters/prismaRows.spec.ts +0 -98
  501. package/src/adapters/prismaRows.ts +0 -301
  502. package/src/adapters/prismaTestClient.ts +0 -396
  503. package/src/calculatePagination.ts +0 -34
  504. package/src/db/databasePluginCore.spec.ts +0 -62
  505. package/src/db/databasePluginCore.testFixtures.ts +0 -76
  506. package/src/db/databasePluginCore.ts +0 -185
  507. package/src/db/databasePluginUpdateCheck.bench.ts +0 -107
  508. package/src/db/fixedMigrator.spec.ts +0 -231
  509. package/src/db/fixedMigrator.ts +0 -147
  510. package/src/db/fixedMigratorMongo.spec.ts +0 -192
  511. package/src/db/fixedMigratorMongo.ts +0 -425
  512. package/src/db/hotUpdaterSchema.ts +0 -5
  513. package/src/db/mongoMigrationExecution.ts +0 -23
  514. package/src/db/schema/definitions.ts +0 -1
  515. package/src/db/schema/mongodb.ts +0 -40
  516. package/src/db/schema/registry.ts +0 -55
  517. package/src/db/schema/sql.ts +0 -241
  518. package/src/db/schema/sqlOperations.ts +0 -63
  519. package/src/db/schema/types.ts +0 -1
  520. package/src/db/schemaGenerators.ts +0 -466
  521. package/src/db/schemaReadiness.ts +0 -34
  522. package/src/db/sqlMigrationExecution.spec.ts +0 -65
  523. package/src/db/sqlMigrationExecution.ts +0 -108
  524. package/src/db/types.spec.ts +0 -55
  525. package/src/handlerBundleRoutes.ts +0 -259
  526. package/src/handlerReleaseManagementRoutes.ts +0 -213
  527. package/src/insights/bounded/activeOverview.spec.ts +0 -189
  528. package/src/insights/bounded/activeOverview.ts +0 -148
  529. package/src/insights/bounded/installationSearch.spec.ts +0 -130
  530. package/src/insights/bounded/installationSearch.ts +0 -69
  531. package/src/insights/bounded/persistence.ts +0 -43
  532. package/src/insights/bounded/provider.spec.ts +0 -219
  533. package/src/insights/bounded/provider.ts +0 -229
  534. package/src/insights/bounded/scan.ts +0 -235
  535. package/src/insights/persistence.ts +0 -10
  536. package/src/schema/dsl-all-versions.spec.ts +0 -35
  537. package/src/schema/dsl.ts +0 -187
  538. package/src/schema/index.ts +0 -10
  539. package/src/schema/settings.ts +0 -15
  540. package/src/schema/types.ts +0 -79
  541. package/src/schema/v1_0_0.spec.ts +0 -146
  542. package/src/schema/v1_0_0.ts +0 -465
@@ -0,0 +1,205 @@
1
+ import {
2
+ DatabaseSchemaError,
3
+ findPhysicalColumn,
4
+ indexOrderColumns,
5
+ type PhysicalColumn,
6
+ type PhysicalIndex,
7
+ type PhysicalTable,
8
+ } from "@hot-updater/plugin-core/internal";
9
+
10
+ export type SqlDialect = "postgresql" | "mysql" | "sqlite";
11
+
12
+ /** Quotes an identifier: backticks on MySQL, double quotes elsewhere. */
13
+ export const quoteSql = (dialect: SqlDialect, name: string) =>
14
+ dialect === "mysql"
15
+ ? `\`${name.replaceAll("`", "``")}\``
16
+ : `"${name.replaceAll('"', '""')}"`;
17
+
18
+ export const isMultiIndex = (table: PhysicalTable, index: PhysicalIndex) =>
19
+ index.eq.some((column) => findPhysicalColumn(table, column).multi);
20
+
21
+ /** Keeps an identifier within PostgreSQL's 63 and MySQL's 64 characters. */
22
+ export const shortSqlName = (name: string) => {
23
+ if (name.length <= 60) return name;
24
+ let hash = 0x811c9dc5;
25
+ for (const char of name)
26
+ hash = Math.imul(hash ^ char.charCodeAt(0), 0x01000193) >>> 0;
27
+ return `${name.slice(0, 51)}_${hash.toString(36)}`;
28
+ };
29
+
30
+ /** The column type; `entry` types one value of a multi-valued column in its index table. */
31
+ const columnType = (
32
+ dialect: SqlDialect,
33
+ column: PhysicalColumn,
34
+ indexed: boolean,
35
+ entry = false,
36
+ ): string => {
37
+ if ((column.multi && !entry) || column.type === "json") {
38
+ return { postgresql: "jsonb", mysql: "json", sqlite: "TEXT" }[dialect];
39
+ }
40
+ if (column.type === "string") {
41
+ const length = column.maxLength ?? (indexed ? 255 : undefined);
42
+ if (dialect === "sqlite") return "TEXT";
43
+ if (dialect === "postgresql") {
44
+ return `${column.maxLength ? `varchar(${column.maxLength})` : "text"} COLLATE "C"`;
45
+ }
46
+ const charset = column.ascii
47
+ ? "ascii COLLATE ascii_bin"
48
+ : "utf8mb4 COLLATE utf8mb4_0900_bin";
49
+ return `${length ? `varchar(${length})` : "longtext"} CHARACTER SET ${charset}`;
50
+ }
51
+ if (column.type === "integer")
52
+ return dialect === "sqlite" ? "INTEGER" : "bigint";
53
+ if (column.type === "number") {
54
+ return { postgresql: "double precision", mysql: "double", sqlite: "REAL" }[
55
+ dialect
56
+ ];
57
+ }
58
+ return dialect === "sqlite" ? "INTEGER" : "boolean";
59
+ };
60
+
61
+ /** InnoDB's limit on the bytes of one key or index. */
62
+ const MYSQL_KEY_BYTES = 3072;
63
+
64
+ /** Refuses a MySQL key or index over InnoDB's limit before any DDL runs. */
65
+ const checkMysqlKey = (
66
+ table: PhysicalTable,
67
+ name: string,
68
+ columns: readonly string[],
69
+ ) => {
70
+ const bytes = columns.reduce((sum, column) => {
71
+ const { type, maxLength, ascii } = findPhysicalColumn(table, column);
72
+ if (type === "string") return sum + (maxLength ?? 255) * (ascii ? 1 : 4);
73
+ return sum + (type === "boolean" ? 1 : 8);
74
+ }, 0);
75
+ if (bytes > MYSQL_KEY_BYTES) {
76
+ throw new DatabaseSchemaError(
77
+ `${table.name} ${name} needs ${bytes} bytes on MySQL, over its ${MYSQL_KEY_BYTES}; shorten its strings or mark ASCII ones ascii.`,
78
+ );
79
+ }
80
+ };
81
+
82
+ export interface SqlColumnShape {
83
+ readonly name: string;
84
+ /** The column's DDL type, collation included. */
85
+ readonly type: string;
86
+ readonly notNull: boolean;
87
+ readonly default?: number;
88
+ }
89
+
90
+ export interface SqlTableShape {
91
+ readonly name: string;
92
+ readonly columns: readonly SqlColumnShape[];
93
+ readonly key: readonly string[];
94
+ /** Indexes, and index tables for multi-valued fields, in declaration order. */
95
+ readonly indexes: readonly (
96
+ | {
97
+ readonly kind: "index";
98
+ readonly name: string;
99
+ readonly unique: boolean;
100
+ readonly columns: readonly string[];
101
+ }
102
+ | { readonly kind: "table"; readonly table: SqlTableShape }
103
+ )[];
104
+ }
105
+
106
+ /**
107
+ * Each table as the DDL creates it, for the DDL below and for ORM schema
108
+ * generators: binary collation, one index per declared index, and an index
109
+ * table `<table>__<index>` for each index over a multi-valued field, keyed by
110
+ * every column it holds.
111
+ */
112
+ export const sqlTableShapes = (
113
+ dialect: SqlDialect,
114
+ tables: readonly PhysicalTable[],
115
+ tablePrefix = "",
116
+ ): SqlTableShape[] =>
117
+ tables.map((table) => {
118
+ const name = tablePrefix + table.name;
119
+ const indexed = new Set([
120
+ ...table.key,
121
+ ...table.indexes.flatMap(({ eq, sort }) => [...eq, ...sort]),
122
+ ]);
123
+ if (dialect === "mysql") checkMysqlKey(table, "key", table.key);
124
+ const indexes = table.indexes.flatMap((index): SqlTableShape["indexes"] => {
125
+ const columns = [...index.eq, ...indexOrderColumns(table, index)];
126
+ if (dialect === "mysql") {
127
+ checkMysqlKey(table, `index ${index.name}`, columns);
128
+ }
129
+ if (isMultiIndex(table, index)) {
130
+ const entries = columns.map((column) => ({
131
+ name: column,
132
+ type: columnType(
133
+ dialect,
134
+ findPhysicalColumn(table, column),
135
+ true,
136
+ true,
137
+ ),
138
+ notNull: true,
139
+ }));
140
+ const indexTable = {
141
+ name: `${name}__${index.name}`,
142
+ columns: entries,
143
+ key: columns,
144
+ indexes: [],
145
+ };
146
+ return [{ kind: "table", table: indexTable }];
147
+ }
148
+ if (!index.unique && columns.join() === table.key.join()) return [];
149
+ return [
150
+ {
151
+ kind: "index",
152
+ name: shortSqlName(`${name}_${index.name}`),
153
+ unique: index.unique === true,
154
+ columns: index.unique ? index.eq : columns,
155
+ },
156
+ ];
157
+ });
158
+ return {
159
+ name,
160
+ columns: table.columns.map((column) => ({
161
+ name: column.name,
162
+ type: columnType(dialect, column, indexed.has(column.name)),
163
+ notNull: !column.nullable,
164
+ ...(column.default === undefined ? {} : { default: column.default }),
165
+ })),
166
+ key: table.key,
167
+ indexes,
168
+ };
169
+ });
170
+
171
+ /** DDL for the tables' shapes: each table, then its indexes and index tables. */
172
+ export const createTableStatements = (
173
+ dialect: SqlDialect,
174
+ tables: readonly PhysicalTable[],
175
+ tablePrefix = "",
176
+ ): string[] => {
177
+ const quote = (name: string) => quoteSql(dialect, name);
178
+ const list = (columns: readonly string[]) => columns.map(quote).join(", ");
179
+ const render = (shape: SqlTableShape): string[] => {
180
+ const definitions = shape.columns.map(
181
+ (column) =>
182
+ `${quote(column.name)} ${column.type}${column.notNull ? " NOT NULL" : ""}${column.default === undefined ? "" : ` DEFAULT ${column.default}`}`,
183
+ );
184
+ definitions.push(`PRIMARY KEY (${list(shape.key)})`);
185
+ const after: string[] = [];
186
+ for (const index of shape.indexes) {
187
+ if (index.kind === "table") {
188
+ after.push(...render(index.table));
189
+ } else if (dialect === "mysql") {
190
+ definitions.push(
191
+ `${index.unique ? "UNIQUE " : ""}INDEX ${quote(index.name)} (${list(index.columns)})`,
192
+ );
193
+ } else {
194
+ after.push(
195
+ `CREATE ${index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${quote(index.name)} ON ${quote(shape.name)} (${list(index.columns)})`,
196
+ );
197
+ }
198
+ }
199
+ return [
200
+ `CREATE TABLE IF NOT EXISTS ${quote(shape.name)} (${definitions.join(", ")})`,
201
+ ...after,
202
+ ];
203
+ };
204
+ return sqlTableShapes(dialect, tables, tablePrefix).flatMap(render);
205
+ };
@@ -0,0 +1,183 @@
1
+ import type { DatabaseSync, SqliteValue } from "node:sqlite";
2
+
3
+ import type { PGlite } from "@electric-sql/pglite";
4
+ import type { Pool as MysqlPool, PoolConnection } from "mysql2/promise";
5
+ import type { Pool as PgPool, PoolClient } from "pg";
6
+
7
+ import type {
8
+ SqlConnection,
9
+ SqlExecutor,
10
+ SqlResult,
11
+ SqlStatement,
12
+ } from "./sqlAdapter";
13
+
14
+ /** Test executors for the SQL core; provider executors arrive with D1–D3. */
15
+
16
+ export const pgliteExecutor = (db: PGlite): SqlExecutor => {
17
+ const over = (runner: Pick<PGlite, "query">): SqlConnection => ({
18
+ execute: async ({ sql, params }) => {
19
+ const result = await runner.query<Record<string, unknown>>(sql, [
20
+ ...params,
21
+ ]);
22
+ return { rows: result.rows, changes: result.affectedRows ?? 0 };
23
+ },
24
+ });
25
+ return {
26
+ dialect: "postgresql",
27
+ ...over(db),
28
+ transaction: (fn) => db.transaction((tx) => fn(over(tx))),
29
+ };
30
+ };
31
+
32
+ /** One connection, so statements and transactions run one at a time. */
33
+ export const sqliteExecutor = (db: DatabaseSync): SqlExecutor => {
34
+ let queue: Promise<unknown> = Promise.resolve();
35
+ const serial = <T>(task: () => Promise<T>): Promise<T> => {
36
+ const next = queue.then(task);
37
+ queue = next.catch(() => undefined);
38
+ return next;
39
+ };
40
+ const execute = async ({ sql, params }: SqlStatement): Promise<SqlResult> => {
41
+ const statement = db.prepare(sql);
42
+ const values = params as SqliteValue[];
43
+ if (statement.columns().length > 0) {
44
+ return { rows: statement.all(...values), changes: 0 };
45
+ }
46
+ return { rows: [], changes: Number(statement.run(...values).changes) };
47
+ };
48
+ return {
49
+ dialect: "sqlite",
50
+ execute: (statement) => serial(() => execute(statement)),
51
+ transaction: (fn) =>
52
+ serial(async () => {
53
+ db.exec("BEGIN IMMEDIATE");
54
+ try {
55
+ const result = await fn({ execute });
56
+ db.exec("COMMIT");
57
+ return result;
58
+ } catch (error) {
59
+ db.exec("ROLLBACK");
60
+ throw error;
61
+ }
62
+ }),
63
+ };
64
+ };
65
+
66
+ /**
67
+ * An executor without interactive transactions, as D1's: writes run as one
68
+ * atomic batch, here in a SQLite transaction that rolls back on any error.
69
+ */
70
+ export const sqliteBatchExecutor = (db: DatabaseSync): SqlExecutor => {
71
+ const executor = sqliteExecutor(db);
72
+ return {
73
+ dialect: "sqlite",
74
+ execute: executor.execute,
75
+ transaction: () => {
76
+ throw new Error("A batch executor has no interactive transactions.");
77
+ },
78
+ batch: (statements) =>
79
+ executor.transaction(async (connection) => {
80
+ const results: SqlResult[] = [];
81
+ for (const statement of statements) {
82
+ results.push(await connection.execute(statement));
83
+ }
84
+ return results;
85
+ }),
86
+ };
87
+ };
88
+
89
+ /** PGlite without interactive transactions, as an RPC applying a batch would be. */
90
+ export const pgliteBatchExecutor = (db: PGlite): SqlExecutor => {
91
+ const executor = pgliteExecutor(db);
92
+ return {
93
+ dialect: "postgresql",
94
+ execute: executor.execute,
95
+ transaction: () => {
96
+ throw new Error("A batch executor has no interactive transactions.");
97
+ },
98
+ batch: (statements) =>
99
+ executor.transaction(async (connection) => {
100
+ const results: SqlResult[] = [];
101
+ for (const statement of statements) {
102
+ results.push(await connection.execute(statement));
103
+ }
104
+ return results;
105
+ }),
106
+ };
107
+ };
108
+
109
+ export const pgExecutor = (pool: PgPool): SqlExecutor => {
110
+ const over = (runner: PgPool | PoolClient): SqlConnection => ({
111
+ execute: async ({ sql, params }) => {
112
+ const result = await runner.query(sql, [...params]);
113
+ return { rows: result.rows, changes: result.rowCount ?? 0 };
114
+ },
115
+ });
116
+ return {
117
+ dialect: "postgresql",
118
+ ...over(pool),
119
+ async transaction(fn) {
120
+ const client = await pool.connect();
121
+ try {
122
+ await client.query("BEGIN");
123
+ const result = await fn(over(client));
124
+ await client.query("COMMIT");
125
+ return result;
126
+ } catch (error) {
127
+ await client.query("ROLLBACK").catch(() => undefined);
128
+ throw error;
129
+ } finally {
130
+ client.release();
131
+ }
132
+ },
133
+ };
134
+ };
135
+
136
+ /** A pooled PostgreSQL batch: one READ COMMITTED transaction per write, as Supabase's apply RPC runs. */
137
+ export const pgBatchExecutor = (pool: PgPool): SqlExecutor => {
138
+ const executor = pgExecutor(pool);
139
+ return {
140
+ dialect: "postgresql",
141
+ execute: executor.execute,
142
+ transaction: () => {
143
+ throw new Error("A batch executor has no interactive transactions.");
144
+ },
145
+ batch: (statements) =>
146
+ executor.transaction(async (connection) => {
147
+ const results: SqlResult[] = [];
148
+ for (const statement of statements) {
149
+ results.push(await connection.execute(statement));
150
+ }
151
+ return results;
152
+ }),
153
+ };
154
+ };
155
+
156
+ export const mysqlExecutor = (pool: MysqlPool): SqlExecutor => {
157
+ const over = (runner: MysqlPool | PoolConnection): SqlConnection => ({
158
+ execute: async ({ sql, params }) => {
159
+ const [result] = await runner.query(sql, [...params]);
160
+ return Array.isArray(result)
161
+ ? { rows: result as Record<string, unknown>[], changes: 0 }
162
+ : { rows: [], changes: result.affectedRows };
163
+ },
164
+ });
165
+ return {
166
+ dialect: "mysql",
167
+ ...over(pool),
168
+ async transaction(fn) {
169
+ const connection = await pool.getConnection();
170
+ try {
171
+ await connection.beginTransaction();
172
+ const result = await fn(over(connection));
173
+ await connection.commit();
174
+ return result;
175
+ } catch (error) {
176
+ await connection.rollback().catch(() => undefined);
177
+ throw error;
178
+ } finally {
179
+ connection.release();
180
+ }
181
+ },
182
+ };
183
+ };
@@ -0,0 +1,39 @@
1
+ import { createMemoryAdapter } from "@hot-updater/plugin-core/internal";
2
+ import {
3
+ setupDatabaseTestSuite,
4
+ startHttpTestServer,
5
+ } from "@hot-updater/test-utils";
6
+
7
+ import { createDatabasePluginApis } from "./assembly/databasePlugins";
8
+ import { createHotUpdater } from "./index";
9
+ import { createInsightsModel, insights } from "./plugins/insights";
10
+
11
+ let adapter = createMemoryAdapter();
12
+
13
+ setupDatabaseTestSuite({
14
+ name: "in-memory engine database",
15
+ migrate: () => undefined,
16
+ createDatabase: () => ({
17
+ name: "memory",
18
+ // Each test's reset swaps in an empty adapter.
19
+ adapter: new Proxy({} as typeof adapter, {
20
+ get: (_target, key) => Reflect.get(adapter, key),
21
+ }),
22
+ }),
23
+ reset: () => {
24
+ adapter = createMemoryAdapter();
25
+ },
26
+ dispose: () => undefined,
27
+ createHttpClient: (options) =>
28
+ startHttpTestServer(
29
+ createHotUpdater({
30
+ ...options,
31
+ plugins: [insights()],
32
+ clientAccess: "public",
33
+ }).handlers,
34
+ ),
35
+ createInsightsModel: (database) =>
36
+ createInsightsModel(
37
+ createDatabasePluginApis(database, [insights()]).insights,
38
+ ),
39
+ });
@@ -0,0 +1,149 @@
1
+ import type { DatabaseAdapter } from "@hot-updater/plugin-core/internal";
2
+
3
+ import { coreModule, HOT_UPDATER_SCHEMA_VERSION } from "../core/schema";
4
+ import type { ModelShape } from "../database/definitions";
5
+ import {
6
+ ENGINE_SCHEMA_KEY,
7
+ ENGINE_SCHEMA_VERSION,
8
+ isMissingSchemaError,
9
+ readSettings,
10
+ withSchemaFence,
11
+ type SchemaSettings,
12
+ } from "../database/fence";
13
+ import { resolveSchema, type SchemaModule } from "../database/resolveSchema";
14
+ import { apiKeys, apiKeysSchema } from "../plugins/api-keys";
15
+ import { builtInPlugin } from "../plugins/builtIn";
16
+ import { insights, insightsSchema } from "../plugins/insights";
17
+ import { createEngineMigrator } from "./engineMigrator";
18
+ import { migrateSchema } from "./schemaSettings";
19
+ import type { ToolingDatabase, ToolingTarget } from "./types";
20
+
21
+ /** Core and the built-in plugins: their tables keep their names. */
22
+ export const builtInModules: readonly SchemaModule[] = [
23
+ coreModule,
24
+ { id: "insights", schema: insightsSchema },
25
+ { id: "apiKeys", schema: apiKeysSchema },
26
+ ];
27
+
28
+ /**
29
+ * Core's tables and the built-in plugins' (Insights and API keys): the tables
30
+ * every provider's tooling creates, whichever plugins a server runs.
31
+ */
32
+ export const builtInSchema = resolveSchema(builtInModules);
33
+
34
+ /** The settings rows a provider's database is fenced by. */
35
+ export const builtInSettings: SchemaSettings = {
36
+ [ENGINE_SCHEMA_KEY]: ENGINE_SCHEMA_VERSION,
37
+ "schema.core": HOT_UPDATER_SCHEMA_VERSION,
38
+ "schema.insights": insights().schemaVersion,
39
+ "schema.apiKeys": apiKeys().schemaVersion,
40
+ };
41
+
42
+ /** Creates the built-in tables, then writes their settings rows. */
43
+ export const migrateBuiltInSchema = (adapter: DatabaseAdapter, name: string) =>
44
+ migrateSchema(adapter, name, builtInSchema.tables, builtInSettings);
45
+
46
+ /** What `hot-updater db` creates for a server without third-party plugins. */
47
+ export const builtInTarget: ToolingTarget = {
48
+ schema: builtInSchema,
49
+ settings: builtInSettings,
50
+ };
51
+
52
+ /** A plugin as the tooling reads it: its id, its tables, and their version. */
53
+ export interface PluginTables {
54
+ readonly id: string;
55
+ readonly schemaVersion: string;
56
+ readonly schema: Readonly<Record<string, ModelShape>>;
57
+ }
58
+
59
+ const addedPlugins = (plugins: readonly PluginTables[]) =>
60
+ plugins.filter((plugin) => !(builtInPlugin in plugin));
61
+
62
+ /** Each third-party plugin's `schema.<id>` settings row. */
63
+ export const addedSettings = (
64
+ plugins: readonly PluginTables[],
65
+ ): SchemaSettings =>
66
+ Object.fromEntries(
67
+ addedPlugins(plugins).map(({ id, schemaVersion }) => [
68
+ `schema.${id}`,
69
+ schemaVersion,
70
+ ]),
71
+ );
72
+
73
+ /**
74
+ * What `hot-updater db` creates for a server's plugins: the built-in tables,
75
+ * then each third-party plugin's tables with its `schema.<id>` settings row.
76
+ */
77
+ export const toolingTargetOf = (
78
+ plugins: readonly PluginTables[],
79
+ ): ToolingTarget => {
80
+ const settings = addedSettings(plugins);
81
+ if (Object.keys(settings).length === 0) return builtInTarget;
82
+ return {
83
+ schema: resolveSchema([
84
+ ...builtInModules,
85
+ ...addedPlugins(plugins).map(({ id, schema }) => ({
86
+ id,
87
+ schema,
88
+ namespace: id,
89
+ })),
90
+ ]),
91
+ settings: { ...builtInSettings, ...settings },
92
+ };
93
+ };
94
+
95
+ export interface EngineDatabaseOptions {
96
+ readonly name: string;
97
+ readonly adapter: DatabaseAdapter;
98
+ /**
99
+ * Purges a CDN's copies of the cacheable client routes. Core calls it after
100
+ * a committed write that changes what those routes answer, since only core
101
+ * knows which of its tables they read.
102
+ */
103
+ readonly onCachedRoutesChange?: () => Promise<void>;
104
+ }
105
+
106
+ /**
107
+ * A provider's database on the storage engine: its adapter behind the schema
108
+ * fence, which checks the built-in settings rows before the first read or
109
+ * write and names `hot-updater db migrate` when they are missing or stale.
110
+ * When the adapter creates its own tables, `hot-updater db migrate` creates
111
+ * the built-in tables and the server's plugin tables, then writes their
112
+ * settings rows.
113
+ */
114
+ export const createEngineDatabase = ({
115
+ name,
116
+ adapter,
117
+ onCachedRoutesChange,
118
+ }: EngineDatabaseOptions): ToolingDatabase => {
119
+ const fenced = withSchemaFence(adapter, name, builtInSettings);
120
+ const createMigrator = ({ schema, settings } = builtInTarget) =>
121
+ createEngineMigrator({
122
+ adapterName: name,
123
+ adapter,
124
+ schema,
125
+ settings,
126
+ readSettings: async () => {
127
+ const rows = await readSettings(adapter, Object.keys(settings)).catch(
128
+ (error: unknown) => {
129
+ if (isMissingSchemaError(error)) return [];
130
+ throw error;
131
+ },
132
+ );
133
+ return new Map(
134
+ rows.flatMap((row) =>
135
+ row === null ? [] : [[String(row.key), row.value]],
136
+ ),
137
+ );
138
+ },
139
+ });
140
+ return {
141
+ name,
142
+ adapter: fenced,
143
+ ...(onCachedRoutesChange === undefined ? {} : { onCachedRoutesChange }),
144
+ ...(adapter.dispose === undefined
145
+ ? {}
146
+ : { dispose: () => adapter.dispose!() }),
147
+ ...(adapter.migrations === undefined ? {} : { createMigrator }),
148
+ };
149
+ };
@@ -13,10 +13,10 @@ import {
13
13
  const createBundle = (id: string): Bundle => ({
14
14
  id,
15
15
  platform: "ios",
16
- fileHash: `hash-${id}`,
17
16
  gitCommitHash: null,
18
- storageUri: `s3://bucket/${id}.zip`,
19
- archiveByteSize: 3_000_000_001,
17
+ manifestStorageUri: `s3://bucket/${id}/manifest.json`,
18
+ manifestFileHash: `manifest-hash-${id}`,
19
+ assetBaseStorageUri: "s3://bucket/assets",
20
20
  });
21
21
 
22
22
  const toRow = (bundle: Bundle): BundleRow => bundleToRow(bundle);