@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,378 @@
1
+ import type { Bundle } from "@hot-updater/core";
2
+ import type { HotUpdaterCoreApi } from "@hot-updater/plugin-core";
3
+ import { createMemoryAdapter } from "@hot-updater/plugin-core/internal";
4
+ import { normalizeRange, rangesIntersect } from "verkit";
5
+ import { describe, expect, it } from "vitest";
6
+
7
+ import { createBundleFixture } from "../../../test-utils/src/databaseTestFixtures";
8
+ import { createInProcessCoreApi } from "./api";
9
+ import {
10
+ parseBaseCandidateKey,
11
+ targetBaseCandidateKey,
12
+ type BaseCandidateTarget,
13
+ } from "./baseCandidates";
14
+
15
+ type Target = Pick<BaseCandidateTarget, "appVersion" | "fingerprintHash">;
16
+
17
+ /**
18
+ * The rule `deploy.ts` used before base candidates came from the catalog
19
+ * (`getPatchBaseBundles` on `next`): page the channel and platform's enabled
20
+ * releases newest first, keep bundle releases older than the new bundle with
21
+ * the same fingerprint or an intersecting range, each bundle once.
22
+ */
23
+ const referenceBaseBundleIds = async (
24
+ core: HotUpdaterCoreApi,
25
+ channel: string,
26
+ target: Target,
27
+ bundleId: string,
28
+ maxBaseBundles: number,
29
+ ): Promise<string[]> => {
30
+ const channelRow = await core.findChannelByName(channel);
31
+ if (channelRow === null) return [];
32
+ const pageSize = Math.max(maxBaseBundles * 3, 10);
33
+ const found: string[] = [];
34
+ let after: string | undefined;
35
+ while (found.length < maxBaseBundles) {
36
+ const releases = await core.listReleases({
37
+ filter: {
38
+ kind: "channelPlatform",
39
+ channelId: channelRow.id,
40
+ platform: "ios",
41
+ enabled: true,
42
+ },
43
+ order: "desc",
44
+ limit: pageSize,
45
+ ...(after === undefined ? {} : { after }),
46
+ });
47
+ for (const release of releases) {
48
+ const left = target.appVersion && normalizeRange(target.appVersion);
49
+ const right =
50
+ release.target_app_version &&
51
+ normalizeRange(release.target_app_version);
52
+ const compatible = target.fingerprintHash
53
+ ? release.strategy === "FINGERPRINT" &&
54
+ release.fingerprint_hash === target.fingerprintHash
55
+ : release.strategy === "APP_VERSION" &&
56
+ !!left &&
57
+ !!right &&
58
+ rangesIntersect(left, right);
59
+ const id = release.bundle_id;
60
+ if (
61
+ compatible &&
62
+ release.kind === "BUNDLE" &&
63
+ id !== null &&
64
+ id < bundleId &&
65
+ !found.includes(id) &&
66
+ found.length < maxBaseBundles
67
+ ) {
68
+ found.push(id);
69
+ }
70
+ }
71
+ if (releases.length < pageSize) break;
72
+ after = releases.at(-1)!.id;
73
+ }
74
+ return found;
75
+ };
76
+
77
+ const baseBundleIds = (
78
+ core: HotUpdaterCoreApi,
79
+ channel: string,
80
+ target: Target,
81
+ bundleId: string,
82
+ maxBaseBundles: number,
83
+ ): Promise<string[]> => {
84
+ const key = targetBaseCandidateKey({ channel, platform: "ios", ...target });
85
+ return key === null
86
+ ? Promise.resolve([])
87
+ : core.findBaseBundleIds(key, bundleId, maxBaseBundles);
88
+ };
89
+
90
+ const bundleOf = (n: number): Bundle => ({
91
+ ...createBundleFixture(String(n)),
92
+ patches: [],
93
+ });
94
+ const idOf = (n: number) => createBundleFixture(String(n)).id;
95
+ const NEWEST = idOf(999);
96
+
97
+ const policy = (overrides: {
98
+ readonly channel?: string;
99
+ readonly targetAppVersion?: string | null;
100
+ readonly fingerprintHash?: string | null;
101
+ }) => ({
102
+ channel: "production",
103
+ enabled: true,
104
+ fingerprintHash: null,
105
+ message: null,
106
+ shouldForceUpdate: false,
107
+ targetAppVersion: null,
108
+ ...overrides,
109
+ });
110
+
111
+ const RELEASE_RANGES = [
112
+ "1.0.0",
113
+ "1.2.3",
114
+ "1.2.9",
115
+ "1.3.0",
116
+ "2.0.0",
117
+ "0.2.5",
118
+ "1.2.3-beta.1",
119
+ "1.2",
120
+ "1.2.x",
121
+ "2.x",
122
+ "~1.2.3",
123
+ "~1.2.5",
124
+ "^0.2.3",
125
+ ">=1.0.0 <1.4.0",
126
+ ">=1.2.0 <=1.2.5",
127
+ "1.2.3 - 1.4.0",
128
+ ">=1.0.0 <1.16.0",
129
+ "1.2.x || 1.5.x",
130
+ "1.0.0 || 2.0.0",
131
+ "1.x",
132
+ "^1.2.3",
133
+ ">=1.2.0",
134
+ "<2.0.0",
135
+ "*",
136
+ "1.20.0",
137
+ "1.20.x",
138
+ ">=1.5.0 <2.1.0",
139
+ "3.0.0",
140
+ ];
141
+
142
+ const TARGET_RANGES = [
143
+ "1.0.0",
144
+ "1.2.0",
145
+ "1.2.3",
146
+ "1.2.4",
147
+ "1.2.9",
148
+ "1.3.0",
149
+ "1.5.2",
150
+ "1.15.2",
151
+ "1.16.0",
152
+ "1.20.0",
153
+ "2.0.0",
154
+ "3.0.0",
155
+ "0.2.5",
156
+ "1.2",
157
+ "1.2.x",
158
+ "~1.2.3",
159
+ "^1.2.3",
160
+ "1.x",
161
+ "2.x",
162
+ "0.x",
163
+ ">=1.2.0 <2",
164
+ ">=1.0.0",
165
+ "1.2.3 || 2.0.0",
166
+ "*",
167
+ ];
168
+
169
+ describe("base candidate keys", () => {
170
+ it("names the target's catalog scope and normalized range", () => {
171
+ const key = targetBaseCandidateKey({
172
+ channel: "채널-🚀",
173
+ platform: "ios",
174
+ fingerprintHash: null,
175
+ appVersion: "1.2.x",
176
+ })!;
177
+ expect(key).toMatch(/^[\x20-\x7e]+$/u);
178
+ expect(parseBaseCandidateKey(key)).toEqual({
179
+ scopeKey: expect.stringMatching(/^v1:app-version:ios:/),
180
+ range: ">=1.2.0 <1.3.0-0",
181
+ });
182
+ expect(
183
+ parseBaseCandidateKey(
184
+ targetBaseCandidateKey({
185
+ channel: "production",
186
+ platform: "android",
187
+ fingerprintHash: "fp",
188
+ appVersion: "1.x",
189
+ })!,
190
+ ),
191
+ ).toEqual({
192
+ scopeKey: expect.stringMatching(/^v1:fingerprint:android:.*:fp$/),
193
+ range: null,
194
+ });
195
+ });
196
+
197
+ it("names nothing for an invalid range or key", () => {
198
+ expect(
199
+ targetBaseCandidateKey({
200
+ channel: "production",
201
+ platform: "ios",
202
+ fingerprintHash: null,
203
+ appVersion: "not a range",
204
+ }),
205
+ ).toBeNull();
206
+ for (const key of [
207
+ "",
208
+ "[]",
209
+ '["v1:app-version:ios"]',
210
+ '["x", "*"]',
211
+ '["v1:app-version:ios:cHJvZHVjdGlvbg", "not a range"]',
212
+ ]) {
213
+ expect(parseBaseCandidateKey(key)).toBeNull();
214
+ }
215
+ });
216
+ });
217
+
218
+ describe("auto-patch bases against the rule deploy used before", () => {
219
+ it("finds exactly the bases the reference finds, for every range pair", async () => {
220
+ const core = createInProcessCoreApi(createMemoryAdapter());
221
+ for (const [n, range] of RELEASE_RANGES.entries()) {
222
+ await core.deploy([
223
+ {
224
+ bundle: bundleOf(100 + n),
225
+ release: policy({ targetAppVersion: range }),
226
+ },
227
+ ]);
228
+ }
229
+ const differences: string[] = [];
230
+ const withoutBases: string[] = [];
231
+ let matches = 0;
232
+ for (const range of TARGET_RANGES) {
233
+ const target = { appVersion: range, fingerprintHash: null };
234
+ const reference = await referenceBaseBundleIds(
235
+ core,
236
+ "production",
237
+ target,
238
+ NEWEST,
239
+ 100,
240
+ );
241
+ matches += reference.length;
242
+ if (reference.length === 0) withoutBases.push(range);
243
+ const found = await baseBundleIds(
244
+ core,
245
+ "production",
246
+ target,
247
+ NEWEST,
248
+ 100,
249
+ );
250
+ if (JSON.stringify(found) !== JSON.stringify(reference)) {
251
+ differences.push(range);
252
+ }
253
+ // `maxBaseBundles` keeps the newest releases first, as before
254
+ await expect(
255
+ baseBundleIds(core, "production", target, NEWEST, 3),
256
+ ).resolves.toEqual(reference.slice(0, 3));
257
+ }
258
+ expect(differences).toEqual([]);
259
+ // 299 of the 672 pairs meet, and every target, `*` and `1.x` included,
260
+ // finds bases
261
+ expect(matches).toBe(299);
262
+ expect(withoutBases).toEqual([]);
263
+ });
264
+
265
+ it("pairs no target in the gap of a lone release's range", async () => {
266
+ const core = createInProcessCoreApi(createMemoryAdapter());
267
+ await core.deploy([
268
+ {
269
+ bundle: bundleOf(100),
270
+ release: policy({ targetAppVersion: "1.2.x || 1.5.x" }),
271
+ },
272
+ ]);
273
+ for (const [appVersion, bases] of [
274
+ ["1.4.0", []],
275
+ ["1.2.4", [idOf(100)]],
276
+ ["1.5.2", [idOf(100)]],
277
+ ] as const) {
278
+ const target = { appVersion, fingerprintHash: null };
279
+ await expect(
280
+ referenceBaseBundleIds(core, "production", target, NEWEST, 3),
281
+ ).resolves.toEqual(bases);
282
+ await expect(
283
+ baseBundleIds(core, "production", target, NEWEST, 3),
284
+ ).resolves.toEqual(bases);
285
+ }
286
+ });
287
+
288
+ it("differs only for an exact prerelease target that a release names", async () => {
289
+ // Both rules pair `1.2.3-beta.1` only with ranges that allow its
290
+ // prerelease; the catalog keeps no range text, so once a release names
291
+ // that prerelease, the other ranges around it pair with it too. No
292
+ // device runs a prerelease app version: the update check coerces it.
293
+ const core = createInProcessCoreApi(createMemoryAdapter());
294
+ for (const [n, range] of ["1.2.x", "1.2.3-beta.1"].entries()) {
295
+ await core.deploy([
296
+ {
297
+ bundle: bundleOf(100 + n),
298
+ release: policy({ targetAppVersion: range }),
299
+ },
300
+ ]);
301
+ }
302
+ const target = { appVersion: "1.2.3-beta.1", fingerprintHash: null };
303
+ await expect(
304
+ referenceBaseBundleIds(core, "production", target, NEWEST, 3),
305
+ ).resolves.toEqual([idOf(101)]);
306
+ await expect(
307
+ baseBundleIds(core, "production", target, NEWEST, 3),
308
+ ).resolves.toEqual([idOf(101), idOf(100)]);
309
+ const ranged = { appVersion: "1.2.x", fingerprintHash: null };
310
+ await expect(
311
+ baseBundleIds(core, "production", ranged, NEWEST, 3),
312
+ ).resolves.toEqual(
313
+ await referenceBaseBundleIds(core, "production", ranged, NEWEST, 3),
314
+ );
315
+ });
316
+
317
+ it("orders by release like the reference: promotions, republishes, disabled releases, fingerprints", async () => {
318
+ const core = createInProcessCoreApi(createMemoryAdapter());
319
+ const both = async (target: Target) => {
320
+ const reference = await referenceBaseBundleIds(
321
+ core,
322
+ "production",
323
+ target,
324
+ NEWEST,
325
+ 3,
326
+ );
327
+ await expect(
328
+ baseBundleIds(core, "production", target, NEWEST, 3),
329
+ ).resolves.toEqual(reference);
330
+ return reference;
331
+ };
332
+ const v1 = { appVersion: "1.0.0", fingerprintHash: null };
333
+ const [staged] = await core.deploy([
334
+ {
335
+ bundle: bundleOf(10),
336
+ release: policy({ channel: "staging", targetAppVersion: "1.0.0" }),
337
+ },
338
+ ]);
339
+ const releaseIds: string[] = [];
340
+ for (let n = 11; n <= 15; n += 1) {
341
+ const [deployed] = await core.deploy([
342
+ { bundle: bundleOf(n), release: policy({ targetAppVersion: "1.0.0" }) },
343
+ ]);
344
+ releaseIds.push(deployed!.release!.id);
345
+ }
346
+ expect(await both(v1)).toEqual([15, 14, 13].map(idOf));
347
+ // a promotion is the newest release of an older bundle
348
+ await core.promoteRelease({
349
+ releaseId: staged!.release!.id,
350
+ targetChannel: "production",
351
+ });
352
+ expect(await both(v1)).toEqual([10, 15, 14].map(idOf));
353
+ await core.deploy([
354
+ { bundleId: idOf(11), release: policy({ targetAppVersion: "1.0.0" }) },
355
+ ]);
356
+ expect(await both(v1)).toEqual([11, 10, 15].map(idOf));
357
+ await core.updateReleasePolicy({
358
+ releaseId: releaseIds[4]!,
359
+ patch: { enabled: false },
360
+ });
361
+ expect(await both(v1)).toEqual([11, 10, 14].map(idOf));
362
+ for (let n = 20; n <= 23; n += 1) {
363
+ await core.deploy([
364
+ {
365
+ bundle: bundleOf(n),
366
+ release: policy({ fingerprintHash: n === 22 ? "fp-b" : "fp-a" }),
367
+ },
368
+ ]);
369
+ }
370
+ expect(await both({ appVersion: null, fingerprintHash: "fp-a" })).toEqual(
371
+ [23, 21, 20].map(idOf),
372
+ );
373
+ // the new bundle is never its own base, nor is a newer one
374
+ await expect(
375
+ baseBundleIds(core, "production", v1, idOf(14), 3),
376
+ ).resolves.toEqual([11, 10, 13].map(idOf));
377
+ });
378
+ });
@@ -0,0 +1,136 @@
1
+ import {
2
+ createReleaseCatalogScopeKey,
3
+ encodeChannelKey,
4
+ parseReleaseCatalogScopeKey,
5
+ } from "@hot-updater/core";
6
+ import type {
7
+ CompiledCatalogSegment,
8
+ ReleaseCatalogRow,
9
+ } from "@hot-updater/plugin-core";
10
+ import { normalizeRange, rangesIntersect } from "verkit";
11
+
12
+ import { parseCompiledCatalog } from "../db/releaseCatalog";
13
+
14
+ /** A new bundle's auto-patch target: where it is released, and to whom. */
15
+ export interface BaseCandidateTarget {
16
+ readonly channel: string;
17
+ readonly platform: "ios" | "android";
18
+ readonly fingerprintHash: string | null;
19
+ readonly appVersion: string | null;
20
+ }
21
+
22
+ /** What a base-candidate key names: a catalog scope, and an app-version scope's target range. */
23
+ export interface BaseCandidateQuery {
24
+ readonly scopeKey: string;
25
+ readonly range: string | null;
26
+ }
27
+
28
+ /**
29
+ * A new bundle's base-candidate key: the Release Catalog scope its devices
30
+ * update from, and for an app version its normalized range; null for a
31
+ * target without a valid range.
32
+ */
33
+ export const targetBaseCandidateKey = (
34
+ target: BaseCandidateTarget,
35
+ ): string | null => {
36
+ const channelKey = encodeChannelKey(target.channel);
37
+ if (target.fingerprintHash) {
38
+ return JSON.stringify([
39
+ createReleaseCatalogScopeKey({
40
+ channelKey,
41
+ fingerprintHash: target.fingerprintHash,
42
+ platform: target.platform,
43
+ strategy: "FINGERPRINT",
44
+ }),
45
+ ]);
46
+ }
47
+ const range =
48
+ target.appVersion === null ? null : normalizeRange(target.appVersion);
49
+ return range === null
50
+ ? null
51
+ : JSON.stringify([
52
+ createReleaseCatalogScopeKey({
53
+ channelKey,
54
+ platform: target.platform,
55
+ strategy: "APP_VERSION",
56
+ }),
57
+ range,
58
+ ]);
59
+ };
60
+
61
+ /** The scope and range a base-candidate key names; null for any other string. */
62
+ export const parseBaseCandidateKey = (
63
+ key: string,
64
+ ): BaseCandidateQuery | null => {
65
+ try {
66
+ const parsed: unknown = JSON.parse(key);
67
+ if (!Array.isArray(parsed) || typeof parsed[0] !== "string") return null;
68
+ const [scopeKey, text] = parsed as [string, unknown];
69
+ const { strategy } = parseReleaseCatalogScopeKey(scopeKey);
70
+ if (strategy === "FINGERPRINT") {
71
+ return parsed.length === 1 ? { scopeKey, range: null } : null;
72
+ }
73
+ const range =
74
+ parsed.length === 2 && typeof text === "string"
75
+ ? normalizeRange(text)
76
+ : null;
77
+ return range === null ? null : { scopeKey, range };
78
+ } catch {
79
+ return null;
80
+ }
81
+ };
82
+
83
+ /** A compiled segment as a range: its version when it holds exactly one. */
84
+ const segmentRange = ({ lower, upper }: CompiledCatalogSegment): string =>
85
+ lower?.inclusive && upper?.inclusive && lower.version === upper.version
86
+ ? lower.version
87
+ : [
88
+ lower === null ? "" : `${lower.inclusive ? ">=" : ">"}${lower.version}`,
89
+ upper === null ? "" : `${upper.inclusive ? "<=" : "<"}${upper.version}`,
90
+ ]
91
+ .join(" ")
92
+ .trim() || "*";
93
+
94
+ /**
95
+ * Auto-patch bases from a scope's compiled Release Catalog, which holds
96
+ * every enabled bundle release of the scope: those whose range intersects
97
+ * `range` (all of them in a fingerprint scope), newest release first, each
98
+ * bundle once and older than `bundleId`, at most `limit`.
99
+ */
100
+ export const baseBundleIdsOf = (
101
+ row: ReleaseCatalogRow,
102
+ range: string | null,
103
+ bundleId: string,
104
+ limit: number,
105
+ ): string[] => {
106
+ const catalog = parseCompiledCatalog(row.payload, row.strategy);
107
+ const serving = new Set(
108
+ catalog.strategy === "FINGERPRINT"
109
+ ? catalog.rollbackReleaseIndexes
110
+ : catalog.segments.flatMap((segment) =>
111
+ range !== null && rangesIntersect(range, segmentRange(segment))
112
+ ? segment.rollbackReleaseIndexes
113
+ : [],
114
+ ),
115
+ );
116
+ const newestFirst = catalog.releaseDescriptors
117
+ .map((descriptor, index) => ({ descriptor, index }))
118
+ .sort((left, right) =>
119
+ left.descriptor.releaseId < right.descriptor.releaseId ? 1 : -1,
120
+ );
121
+ const ids: string[] = [];
122
+ for (const { descriptor, index } of newestFirst) {
123
+ if (ids.length >= limit) break;
124
+ const id = descriptor.bundleId;
125
+ if (
126
+ serving.has(index) &&
127
+ descriptor.kind === "BUNDLE" &&
128
+ id !== null &&
129
+ id < bundleId &&
130
+ !ids.includes(id)
131
+ ) {
132
+ ids.push(id);
133
+ }
134
+ }
135
+ return ids;
136
+ };
@@ -0,0 +1,44 @@
1
+ export {
2
+ targetBaseCandidateKey,
3
+ type BaseCandidateTarget,
4
+ } from "./baseCandidates";
5
+ export {
6
+ createCoreApi,
7
+ createDatabaseCoreApi,
8
+ createInProcessCoreApi,
9
+ type CoreApi,
10
+ } from "./api";
11
+ export { createCoreOperations } from "./operations";
12
+ export {
13
+ changeReleases,
14
+ rebuildCatalog,
15
+ type ReleaseChange,
16
+ type ReleaseChangeInput,
17
+ type ReleaseChangeResult,
18
+ } from "./releases";
19
+ export {
20
+ createCoreReads,
21
+ toBundleRow,
22
+ toCatalogRow,
23
+ toChannelRow,
24
+ toPatchRow,
25
+ toReleaseRow,
26
+ type BundleDetail,
27
+ type CoreDatabase,
28
+ type CoreReads,
29
+ type CoreStorage,
30
+ type KeysetInput,
31
+ type ReleaseFilter,
32
+ } from "./reads";
33
+ export {
34
+ coreModule,
35
+ coreSchema,
36
+ HOT_UPDATER_SCHEMA_VERSION,
37
+ type CoreSchema,
38
+ } from "./schema";
39
+ export {
40
+ deleteChannel,
41
+ insertBundle,
42
+ insertChannel,
43
+ type CoreTransaction,
44
+ } from "./writes";