@hot-updater/server 0.30.12 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +25 -0
  2. package/dist/_virtual/_rolldown/runtime.mjs +6 -0
  3. package/dist/adapters/drizzle.cjs +6 -9
  4. package/dist/adapters/drizzle.d.cts +8 -1
  5. package/dist/adapters/drizzle.d.mts +8 -1
  6. package/dist/adapters/drizzle.mjs +5 -2
  7. package/dist/adapters/kysely.cjs +7 -9
  8. package/dist/adapters/kysely.d.cts +14 -1
  9. package/dist/adapters/kysely.d.mts +14 -1
  10. package/dist/adapters/kysely.mjs +6 -2
  11. package/dist/adapters/mongodb.cjs +7 -9
  12. package/dist/adapters/mongodb.d.cts +9 -1
  13. package/dist/adapters/mongodb.d.mts +9 -1
  14. package/dist/adapters/mongodb.mjs +5 -2
  15. package/dist/adapters/prisma.cjs +6 -9
  16. package/dist/adapters/prisma.d.cts +8 -1
  17. package/dist/adapters/prisma.d.mts +8 -1
  18. package/dist/adapters/prisma.mjs +5 -2
  19. package/dist/db/createBundleDiff.cjs +166 -0
  20. package/dist/db/createBundleDiff.d.cts +20 -0
  21. package/dist/db/createBundleDiff.d.mts +20 -0
  22. package/dist/db/createBundleDiff.mjs +161 -0
  23. package/dist/db/index.cjs +15 -16
  24. package/dist/db/index.d.cts +5 -4
  25. package/dist/db/index.d.mts +5 -4
  26. package/dist/db/index.mjs +14 -16
  27. package/dist/db/ormCore.cjs +173 -65
  28. package/dist/db/ormCore.d.cts +100 -34
  29. package/dist/db/ormCore.d.mts +100 -34
  30. package/dist/db/ormCore.mjs +171 -64
  31. package/dist/db/pluginCore.cjs +37 -3
  32. package/dist/db/pluginCore.mjs +36 -3
  33. package/dist/db/schemaEnhancements.cjs +171 -0
  34. package/dist/db/schemaEnhancements.mjs +167 -0
  35. package/dist/db/types.cjs +6 -0
  36. package/dist/db/types.d.cts +19 -7
  37. package/dist/db/types.d.mts +22 -10
  38. package/dist/db/types.mjs +6 -1
  39. package/dist/db/updateArtifacts.cjs +127 -0
  40. package/dist/db/updateArtifacts.mjs +125 -0
  41. package/dist/handler.cjs +61 -5
  42. package/dist/handler.d.cts +2 -2
  43. package/dist/handler.d.mts +5 -5
  44. package/dist/handler.mjs +59 -5
  45. package/dist/index.cjs +2 -0
  46. package/dist/index.d.cts +3 -2
  47. package/dist/index.d.mts +3 -2
  48. package/dist/index.mjs +2 -1
  49. package/dist/node.d.cts +0 -1
  50. package/dist/node.d.mts +0 -1
  51. package/dist/node_modules/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/_u64.cjs +112 -0
  52. package/dist/node_modules/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/_u64.mjs +108 -0
  53. package/dist/node_modules/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/cryptoNode.cjs +22 -0
  54. package/dist/node_modules/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/cryptoNode.mjs +18 -0
  55. package/dist/node_modules/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/sha3.cjs +219 -0
  56. package/dist/node_modules/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/sha3.mjs +214 -0
  57. package/dist/node_modules/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/utils.cjs +275 -0
  58. package/dist/node_modules/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/utils.mjs +270 -0
  59. package/dist/node_modules/.pnpm/@paralleldrive_cuid2@2.3.1/node_modules/@paralleldrive/cuid2/index.cjs +17 -0
  60. package/dist/node_modules/.pnpm/@paralleldrive_cuid2@2.3.1/node_modules/@paralleldrive/cuid2/index.mjs +13 -0
  61. package/dist/node_modules/.pnpm/@paralleldrive_cuid2@2.3.1/node_modules/@paralleldrive/cuid2/src/index.cjs +69 -0
  62. package/dist/node_modules/.pnpm/@paralleldrive_cuid2@2.3.1/node_modules/@paralleldrive/cuid2/src/index.mjs +65 -0
  63. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/column.cjs +52 -0
  64. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/column.mjs +52 -0
  65. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/entity.cjs +16 -0
  66. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/entity.mjs +15 -0
  67. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/pg-core/columns/enum.cjs +7 -0
  68. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/pg-core/columns/enum.mjs +7 -0
  69. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/sql/expressions/conditions.cjs +92 -0
  70. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/sql/expressions/conditions.mjs +78 -0
  71. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/sql/expressions/select.cjs +11 -0
  72. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/sql/expressions/select.mjs +10 -0
  73. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/sql/sql.cjs +383 -0
  74. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/sql/sql.mjs +366 -0
  75. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/subquery.cjs +17 -0
  76. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/subquery.mjs +17 -0
  77. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/table.cjs +60 -0
  78. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/table.mjs +59 -0
  79. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/table.utils.cjs +4 -0
  80. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/table.utils.mjs +4 -0
  81. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/tracing.cjs +6 -0
  82. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/tracing.mjs +6 -0
  83. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/view-common.cjs +4 -0
  84. package/dist/node_modules/.pnpm/drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pglite@0.2.17_@_31f44b782f9321d71f3ce9d35aa1edf7/node_modules/drizzle-orm/view-common.mjs +4 -0
  85. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/drizzle/index.cjs +383 -0
  86. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/drizzle/index.d.cts +12 -0
  87. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/drizzle/index.d.mts +12 -0
  88. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/drizzle/index.mjs +383 -0
  89. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/kysely/index.cjs +4 -0
  90. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/kysely/index.mjs +5 -0
  91. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/prisma/index.cjs +339 -0
  92. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/prisma/index.d.cts +70 -0
  93. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/prisma/index.d.mts +70 -0
  94. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/adapters/prisma/index.mjs +339 -0
  95. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-7PZK4ONR.cjs +57 -0
  96. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-7PZK4ONR.mjs +56 -0
  97. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-C6OTUURW.cjs +330 -0
  98. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-C6OTUURW.mjs +326 -0
  99. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-CHTIKPQU.cjs +166 -0
  100. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-CHTIKPQU.mjs +163 -0
  101. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-GUE4GMNC.cjs +14 -0
  102. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-GUE4GMNC.mjs +13 -0
  103. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-LHHP6UVP.cjs +24 -0
  104. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-LHHP6UVP.mjs +24 -0
  105. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-LVCPMTAT.cjs +1190 -0
  106. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-LVCPMTAT.mjs +1189 -0
  107. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-PK2W2SQ7.cjs +197 -0
  108. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-PK2W2SQ7.mjs +197 -0
  109. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-ZEQMAIFI.cjs +410 -0
  110. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-ZEQMAIFI.mjs +400 -0
  111. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-ZOCGSAWS.cjs +213 -0
  112. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/chunk-ZOCGSAWS.mjs +212 -0
  113. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/create-tg0451Y_.d.cts +285 -0
  114. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/create-tg0451Y_.d.mts +285 -0
  115. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/index-CMqePMTF.d.cts +45 -0
  116. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/index-CMqePMTF.d.mts +45 -0
  117. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/index.cjs +69 -0
  118. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/index.d.cts +49 -0
  119. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/index.d.mts +49 -0
  120. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/index.mjs +67 -0
  121. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/query/index.d.cts +156 -0
  122. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/query/index.d.mts +156 -0
  123. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/schema/index.cjs +1 -0
  124. package/dist/node_modules/.pnpm/fumadb@0.2.2_drizzle-orm@0.44.7_@cloudflare_workers-types@4.20260313.1_@electric-sql_pg_c72c8c754becd21f6d6662e8fbd28e7f/node_modules/fumadb/dist/schema/index.mjs +2 -0
  125. package/dist/{package.cjs → packages/server/package.cjs} +1 -1
  126. package/dist/{package.mjs → packages/server/package.mjs} +1 -1
  127. package/dist/runtime.cjs +13 -13
  128. package/dist/runtime.d.cts +4 -4
  129. package/dist/runtime.d.mts +4 -4
  130. package/dist/runtime.mjs +12 -13
  131. package/dist/schema/v0_21_0.cjs +16 -15
  132. package/dist/schema/v0_21_0.mjs +3 -2
  133. package/dist/schema/v0_29_0.cjs +18 -17
  134. package/dist/schema/v0_29_0.mjs +3 -2
  135. package/dist/schema/v0_31_0.cjs +48 -0
  136. package/dist/schema/v0_31_0.mjs +48 -0
  137. package/dist/storageAccess.cjs +44 -0
  138. package/dist/storageAccess.mjs +44 -0
  139. package/dist/version.cjs +1 -1
  140. package/dist/version.mjs +1 -1
  141. package/package.json +15 -7
  142. package/src/adapters/drizzle.ts +15 -1
  143. package/src/adapters/kysely.ts +24 -1
  144. package/src/adapters/mongodb.ts +19 -1
  145. package/src/adapters/prisma.ts +15 -1
  146. package/src/db/createBundleDiff.spec.ts +402 -0
  147. package/src/db/createBundleDiff.ts +375 -0
  148. package/src/db/index.spec.ts +528 -27
  149. package/src/db/index.ts +22 -36
  150. package/src/db/ormCore.ts +308 -75
  151. package/src/db/pluginCore.spec.ts +385 -0
  152. package/src/db/pluginCore.ts +45 -4
  153. package/src/db/schemaEnhancements.ts +460 -0
  154. package/src/db/types.ts +38 -7
  155. package/src/db/updateArtifacts.ts +388 -0
  156. package/src/handler-standalone.integration.spec.ts +1 -0
  157. package/src/handler.spec.ts +121 -0
  158. package/src/handler.ts +117 -5
  159. package/src/runtime.spec.ts +287 -55
  160. package/src/runtime.ts +21 -37
  161. package/src/schema/v0_21_0.ts +1 -1
  162. package/src/schema/v0_29_0.ts +1 -1
  163. package/src/schema/v0_31_0.ts +58 -0
  164. package/src/storageAccess.spec.ts +57 -0
  165. package/src/storageAccess.ts +90 -0
@@ -2,7 +2,7 @@ import { PGlite } from "@electric-sql/pglite";
2
2
  import type { Bundle, GetBundlesArgs, UpdateInfo } from "@hot-updater/core";
3
3
  import { NIL_UUID } from "@hot-updater/core";
4
4
  import type {
5
- StoragePlugin,
5
+ RuntimeStoragePlugin,
6
6
  StorageResolveContext,
7
7
  } from "@hot-updater/plugin-core";
8
8
  import { createDatabasePlugin } from "@hot-updater/plugin-core";
@@ -25,6 +25,116 @@ import {
25
25
 
26
26
  import { kyselyAdapter } from "../adapters/kysely";
27
27
  import { createHotUpdater } from "./index";
28
+ import type { ORMDatabaseAdapter, ORMProvider } from "./types";
29
+
30
+ const RAW_PRISMA_SCHEMA = `model bundles {
31
+ id String @id
32
+ platform String
33
+ should_force_update Boolean
34
+ enabled Boolean
35
+ file_hash String
36
+ git_commit_hash String?
37
+ message String?
38
+ channel String @default("production")
39
+ storage_uri String
40
+ target_app_version String?
41
+ fingerprint_hash String?
42
+ metadata Json
43
+ manifest_storage_uri String?
44
+ manifest_file_hash String?
45
+ asset_base_storage_uri String?
46
+ rollout_cohort_count Int @default(1000)
47
+ target_cohorts Json?
48
+ }
49
+ model bundle_patches {
50
+ id String @id
51
+ bundle_id String
52
+ base_bundle_id String
53
+ base_file_hash String
54
+ patch_file_hash String
55
+ patch_storage_uri String
56
+ order_index Int @default(0)
57
+ bundle bundles @relation("bundle_patches_bundles_patches", fields: [bundle_id], references: [id], onUpdate: Restrict, onDelete: Cascade)
58
+ baseBundle bundles @relation("bundle_patches_bundles_baseForPatches", fields: [base_bundle_id], references: [id], onUpdate: Restrict, onDelete: Cascade)
59
+ }
60
+ model private_hot_updater_settings {
61
+ key String @id
62
+ value String @default("0.31.0")
63
+ }`;
64
+
65
+ const RAW_DRIZZLE_SCHEMA = `import { relations } from "drizzle-orm";
66
+ import {
67
+ pgTable,
68
+ uuid,
69
+ text,
70
+ boolean,
71
+ json,
72
+ integer,
73
+ varchar,
74
+ foreignKey,
75
+ } from "drizzle-orm/pg-core";
76
+
77
+ export const bundles = pgTable("bundles", {
78
+ id: uuid("id").primaryKey().notNull(),
79
+ platform: text("platform").notNull(),
80
+ should_force_update: boolean("should_force_update").notNull(),
81
+ enabled: boolean("enabled").notNull(),
82
+ file_hash: text("file_hash").notNull(),
83
+ git_commit_hash: text("git_commit_hash"),
84
+ message: text("message"),
85
+ channel: text("channel").notNull().default("production"),
86
+ storage_uri: text("storage_uri").notNull(),
87
+ target_app_version: text("target_app_version"),
88
+ fingerprint_hash: text("fingerprint_hash"),
89
+ metadata: json("metadata").notNull(),
90
+ manifest_storage_uri: text("manifest_storage_uri"),
91
+ manifest_file_hash: text("manifest_file_hash"),
92
+ asset_base_storage_uri: text("asset_base_storage_uri"),
93
+ rollout_cohort_count: integer("rollout_cohort_count")
94
+ .notNull()
95
+ .default(1000),
96
+ target_cohorts: json("target_cohorts"),
97
+ })
98
+
99
+ export const bundle_patches = pgTable(
100
+ "bundle_patches",
101
+ {
102
+ id: varchar("id", { length: 255 }).primaryKey().notNull(),
103
+ bundle_id: uuid("bundle_id").notNull(),
104
+ base_bundle_id: uuid("base_bundle_id").notNull(),
105
+ base_file_hash: text("base_file_hash").notNull(),
106
+ patch_file_hash: text("patch_file_hash").notNull(),
107
+ patch_storage_uri: text("patch_storage_uri").notNull(),
108
+ order_index: integer("order_index").notNull().default(0),
109
+ }, (table) => [
110
+ foreignKey({
111
+ columns: [table.bundle_id],
112
+ foreignColumns: [bundles.id],
113
+ name: "bundle_patches_bundle_id_fk",
114
+ })
115
+ .onUpdate("restrict")
116
+ .onDelete("cascade"),
117
+ foreignKey({
118
+ columns: [table.base_bundle_id],
119
+ foreignColumns: [bundles.id],
120
+ name: "bundle_patches_base_bundle_id_fk",
121
+ })
122
+ .onUpdate("restrict")
123
+ .onDelete("cascade"),
124
+ ])
125
+
126
+ export const bundle_patchesRelations = relations(bundle_patches, ({ one, many }) => ({
127
+ bundle: one(bundles, {
128
+ relationName: "bundle_patches_bundles_patches",
129
+ fields: [bundle_patches.bundle_id],
130
+ references: [bundles.id],
131
+ }),
132
+ baseBundle: one(bundles, {
133
+ relationName: "bundle_patches_bundles_baseForPatches",
134
+ fields: [bundle_patches.base_bundle_id],
135
+ references: [bundles.id],
136
+ }),
137
+ }));`;
28
138
 
29
139
  function createTestStoragePlugin(
30
140
  protocol: string,
@@ -32,19 +142,48 @@ function createTestStoragePlugin(
32
142
  storageUri: string,
33
143
  context?: StorageResolveContext,
34
144
  ) => string,
35
- ): StoragePlugin {
145
+ readText: (storageUri: string) => Promise<string | null> = async () => null,
146
+ ): RuntimeStoragePlugin {
36
147
  return {
37
148
  name: `${protocol}TestStorage`,
38
149
  supportedProtocol: protocol,
39
- async upload(key) {
150
+ profiles: {
151
+ runtime: {
152
+ readText,
153
+ async getDownloadUrl(storageUri, context) {
154
+ return { fileUrl: resolveFileUrl(storageUri, context) };
155
+ },
156
+ },
157
+ },
158
+ };
159
+ }
160
+
161
+ function createSchemaOnlyAdapter({
162
+ code,
163
+ name,
164
+ provider,
165
+ path,
166
+ }: {
167
+ code: string;
168
+ name: string;
169
+ provider: ORMProvider;
170
+ path: string;
171
+ }): ORMDatabaseAdapter {
172
+ return {
173
+ name,
174
+ provider,
175
+ createORM() {
176
+ throw new Error("Schema-only adapter cannot create ORM");
177
+ },
178
+ async getSchemaVersion() {
179
+ return undefined;
180
+ },
181
+ generateSchema(_schema, schemaName) {
40
182
  return {
41
- storageUri: `${protocol}://test-bucket/${key}`,
183
+ code,
184
+ path: path || schemaName,
42
185
  };
43
186
  },
44
- async delete() {},
45
- async getDownloadUrl(storageUri, context) {
46
- return { fileUrl: resolveFileUrl(storageUri, context) };
47
- },
48
187
  };
49
188
  }
50
189
 
@@ -52,6 +191,14 @@ describe("server/db hotUpdater getUpdateInfo (PGlite + Kysely)", async () => {
52
191
  const db = new PGlite();
53
192
 
54
193
  const kysely = new Kysely({ dialect: new PGliteDialect(db) });
194
+ const storageTexts = new Map<string, string | Error>();
195
+ const readStoredText = async (storageUri: string) => {
196
+ const text = storageTexts.get(storageUri);
197
+ if (text instanceof Error) {
198
+ throw text;
199
+ }
200
+ return text ?? null;
201
+ };
55
202
 
56
203
  const hotUpdater = createHotUpdater({
57
204
  database: kyselyAdapter({
@@ -59,31 +206,67 @@ describe("server/db hotUpdater getUpdateInfo (PGlite + Kysely)", async () => {
59
206
  provider: "postgresql",
60
207
  }),
61
208
  storages: [
62
- createTestStoragePlugin("s3", (storageUri) =>
63
- storageUri
64
- .replace("s3://", "https://s3.example.com/")
65
- .replace(/([^:]\/)\/+/g, "$1"),
209
+ createTestStoragePlugin(
210
+ "s3",
211
+ (storageUri) =>
212
+ storageUri
213
+ .replace("s3://", "https://s3.example.com/")
214
+ .replace(/([^:]\/)\/+/g, "$1"),
215
+ readStoredText,
66
216
  ),
67
- createTestStoragePlugin("r2", (storageUri) =>
68
- storageUri
69
- .replace("r2://", "https://r2.example.com/")
70
- .replace(/([^:]\/)\/+/g, "$1"),
217
+ createTestStoragePlugin(
218
+ "r2",
219
+ (storageUri) =>
220
+ storageUri
221
+ .replace("r2://", "https://r2.example.com/")
222
+ .replace(/([^:]\/)\/+/g, "$1"),
223
+ readStoredText,
71
224
  ),
72
- createTestStoragePlugin("supabase-storage", (storageUri) =>
73
- storageUri
74
- .replace(
75
- "supabase-storage://",
76
- "https://supabase.example.com/storage/v1/object/sign/",
77
- )
78
- .replace(/([^:]\/)\/+/g, "$1"),
225
+ createTestStoragePlugin(
226
+ "supabase-storage",
227
+ (storageUri) =>
228
+ storageUri
229
+ .replace(
230
+ "supabase-storage://",
231
+ "https://supabase.example.com/storage/v1/object/sign/",
232
+ )
233
+ .replace(/([^:]\/)\/+/g, "$1"),
234
+ readStoredText,
79
235
  ),
80
- createTestStoragePlugin("gs", (storageUri) =>
81
- storageUri
82
- .replace("gs://", "https://firebase.example.com/")
83
- .replace(/([^:]\/)\/+/g, "$1"),
236
+ createTestStoragePlugin(
237
+ "gs",
238
+ (storageUri) =>
239
+ storageUri
240
+ .replace("gs://", "https://firebase.example.com/")
241
+ .replace(/([^:]\/)\/+/g, "$1"),
242
+ readStoredText,
84
243
  ),
85
244
  ],
86
245
  });
246
+ const prismaSchemaHotUpdater = createHotUpdater({
247
+ database: createSchemaOnlyAdapter({
248
+ code: RAW_PRISMA_SCHEMA,
249
+ name: "prisma",
250
+ path: "schema.prisma",
251
+ provider: "postgresql",
252
+ }),
253
+ });
254
+ const sqlitePrismaSchemaHotUpdater = createHotUpdater({
255
+ database: createSchemaOnlyAdapter({
256
+ code: RAW_PRISMA_SCHEMA,
257
+ name: "prisma",
258
+ path: "schema.prisma",
259
+ provider: "sqlite",
260
+ }),
261
+ });
262
+ const drizzleSchemaHotUpdater = createHotUpdater({
263
+ database: createSchemaOnlyAdapter({
264
+ code: RAW_DRIZZLE_SCHEMA,
265
+ name: "drizzle",
266
+ path: "hot-updater-schema.ts",
267
+ provider: "postgresql",
268
+ }),
269
+ });
87
270
 
88
271
  beforeAll(async () => {
89
272
  // Initialize FumaDB schema to latest (creates tables under the hood)
@@ -96,6 +279,8 @@ describe("server/db hotUpdater getUpdateInfo (PGlite + Kysely)", async () => {
96
279
  });
97
280
 
98
281
  beforeEach(async () => {
282
+ storageTexts.clear();
283
+ await db.exec("DELETE FROM bundle_patches");
99
284
  await db.exec("DELETE FROM bundles");
100
285
  });
101
286
 
@@ -125,6 +310,129 @@ describe("server/db hotUpdater getUpdateInfo (PGlite + Kysely)", async () => {
125
310
  deleteBundleById: hotUpdater.deleteBundleById.bind(hotUpdater),
126
311
  });
127
312
 
313
+ describe("schema generation", () => {
314
+ it("includes relations, defaults, and indexes in Prisma output", () => {
315
+ const code = prismaSchemaHotUpdater.generateSchema("latest").code;
316
+
317
+ expect(code).toContain('channel String @default("production")');
318
+ expect(code).toContain('metadata Json @default("{}")');
319
+ expect(code).toContain(
320
+ 'patches bundle_patches[] @relation("bundle_patches_bundles_patches")',
321
+ );
322
+ expect(code).toContain(
323
+ 'baseForPatches bundle_patches[] @relation("bundle_patches_bundles_baseForPatches")',
324
+ );
325
+ expect(code).toContain(
326
+ 'bundle bundles @relation("bundle_patches_bundles_patches"',
327
+ );
328
+ expect(code).toContain(
329
+ 'baseBundle bundles @relation("bundle_patches_bundles_baseForPatches"',
330
+ );
331
+ expect(code).toContain('@@index([channel], map: "bundles_channel_idx")');
332
+ expect(code).toContain(
333
+ '@@index([bundle_id], map: "bundle_patches_bundle_id_idx")',
334
+ );
335
+ });
336
+
337
+ it("omits the metadata JSON default for SQLite Prisma output", () => {
338
+ const code = sqlitePrismaSchemaHotUpdater.generateSchema("latest").code;
339
+
340
+ expect(code).toContain("metadata Json");
341
+ expect(code).not.toContain('metadata Json @default("{}")');
342
+ });
343
+
344
+ it("includes foreign keys and indexes in Drizzle output", () => {
345
+ const code = drizzleSchemaHotUpdater.generateSchema("latest").code;
346
+ const bundlesBlock = code.match(
347
+ /export const bundles = [\s\S]*?(?=\n\nexport const bundle_patches = )/,
348
+ )?.[0];
349
+ const bundlePatchesBlock = code.match(
350
+ /export const bundle_patches = [\s\S]*?(?=\n\nexport const bundle_patchesRelations = )/,
351
+ )?.[0];
352
+
353
+ expect(code).toContain(
354
+ 'channel: text("channel").notNull().default("production")',
355
+ );
356
+ expect(code).toContain(
357
+ 'metadata: json("metadata").notNull().default({})',
358
+ );
359
+ expect(code).toContain('name: "bundle_patches_bundle_id_fk"');
360
+ expect(code).toContain('name: "bundle_patches_base_bundle_id_fk"');
361
+ expect(bundlesBlock).toContain(
362
+ 'index("bundles_channel_idx").on(table.channel)',
363
+ );
364
+ expect(bundlesBlock).toContain(
365
+ 'index("bundles_target_app_version_idx").on(table.target_app_version)',
366
+ );
367
+ expect(bundlesBlock).not.toContain(
368
+ 'index("bundle_patches_bundle_id_idx").on(table.bundle_id)',
369
+ );
370
+ expect(bundlePatchesBlock).toContain(
371
+ 'index("bundle_patches_bundle_id_idx").on(table.bundle_id)',
372
+ );
373
+ expect(bundlePatchesBlock).not.toContain(
374
+ 'index("bundles_target_app_version_idx").on(table.target_app_version)',
375
+ );
376
+ });
377
+ });
378
+
379
+ describe("migrator enhancements", () => {
380
+ it("adds custom indexes and constraints to generated SQL", async () => {
381
+ const migrationDb = new PGlite();
382
+ const migrationKysely = new Kysely({
383
+ dialect: new PGliteDialect(migrationDb),
384
+ });
385
+ const migrationHotUpdater = createHotUpdater({
386
+ database: kyselyAdapter({
387
+ db: migrationKysely,
388
+ provider: "postgresql",
389
+ }),
390
+ });
391
+
392
+ try {
393
+ const migrator = migrationHotUpdater.createMigrator();
394
+ const result = await migrator.migrateToLatest({
395
+ mode: "from-schema",
396
+ updateSettings: false,
397
+ });
398
+ const sql = result.getSQL?.() ?? "";
399
+
400
+ expect(sql).toContain("create index bundles_channel_idx on bundles");
401
+ expect(sql).toContain(
402
+ "add constraint check_version_or_fingerprint check",
403
+ );
404
+ expect(sql).toContain(
405
+ "create index bundle_patches_bundle_id_idx on bundle_patches",
406
+ );
407
+ } finally {
408
+ await migrationKysely.destroy();
409
+ await migrationDb.close();
410
+ }
411
+ });
412
+ });
413
+
414
+ describe("bundle validation", () => {
415
+ it("rejects bundles without targeting information", async () => {
416
+ await expect(
417
+ hotUpdater.insertBundle({
418
+ id: "00000000-0000-0000-0000-000000000999",
419
+ platform: "ios",
420
+ shouldForceUpdate: false,
421
+ enabled: true,
422
+ fileHash: "missing-target",
423
+ gitCommitHash: null,
424
+ message: null,
425
+ channel: "production",
426
+ storageUri: "s3://test-bucket/missing-target.zip",
427
+ targetAppVersion: null,
428
+ fingerprintHash: null,
429
+ }),
430
+ ).rejects.toThrow(
431
+ "Bundle must define either targetAppVersion or fingerprintHash.",
432
+ );
433
+ });
434
+ });
435
+
128
436
  describe("getBundleById", () => {
129
437
  it("should retrieve bundle by id without Prisma validation errors", async () => {
130
438
  const bundle: Bundle = {
@@ -362,6 +670,199 @@ describe("server/db hotUpdater getUpdateInfo (PGlite + Kysely)", async () => {
362
670
  "https://s3.example.com/test-bucket/fp-bundle.zip",
363
671
  );
364
672
  });
673
+
674
+ it("returns manifest metadata and hbc patch descriptors for createHotUpdater", async () => {
675
+ const currentManifestStorageUri =
676
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000101/manifest.json";
677
+ const nextManifestStorageUri =
678
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000102/manifest.json";
679
+ const olderBundle: Bundle = {
680
+ id: "00000000-0000-0000-0000-000000000100",
681
+ platform: "ios",
682
+ shouldForceUpdate: false,
683
+ enabled: true,
684
+ fileHash: "hash-older-zip",
685
+ gitCommitHash: null,
686
+ message: "Older bundle",
687
+ channel: "production",
688
+ storageUri:
689
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000100/bundle.zip",
690
+ targetAppVersion: "1.0.0",
691
+ fingerprintHash: null,
692
+ };
693
+ const currentBundle: Bundle = {
694
+ id: "00000000-0000-0000-0000-000000000101",
695
+ platform: "ios",
696
+ shouldForceUpdate: false,
697
+ enabled: true,
698
+ fileHash: "hash-current-zip",
699
+ gitCommitHash: null,
700
+ message: "Current bundle",
701
+ channel: "production",
702
+ storageUri:
703
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000101/bundle.zip",
704
+ targetAppVersion: "1.0.0",
705
+ fingerprintHash: null,
706
+ assetBaseStorageUri:
707
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000101/files",
708
+ manifestFileHash: "sig:manifest-current",
709
+ manifestStorageUri: currentManifestStorageUri,
710
+ };
711
+ const nextBundle: Bundle = {
712
+ id: "00000000-0000-0000-0000-000000000102",
713
+ platform: "ios",
714
+ shouldForceUpdate: false,
715
+ enabled: true,
716
+ fileHash: "hash-next-zip",
717
+ gitCommitHash: null,
718
+ message: "Next bundle",
719
+ channel: "production",
720
+ storageUri:
721
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000102/bundle.zip",
722
+ targetAppVersion: "1.0.0",
723
+ fingerprintHash: null,
724
+ assetBaseStorageUri:
725
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000102/files",
726
+ manifestFileHash: "sig:manifest-next",
727
+ manifestStorageUri: nextManifestStorageUri,
728
+ patches: [
729
+ {
730
+ baseBundleId: "00000000-0000-0000-0000-000000000100",
731
+ baseFileHash: "hash-older-bundle",
732
+ patchFileHash: "hash-older-bsdiff",
733
+ patchStorageUri:
734
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000102/patches/00000000-0000-0000-0000-000000000100/index.ios.bundle.bsdiff",
735
+ },
736
+ {
737
+ baseBundleId: currentBundle.id,
738
+ baseFileHash: "hash-old-bundle",
739
+ patchFileHash: "hash-bsdiff",
740
+ patchStorageUri:
741
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000102/patches/00000000-0000-0000-0000-000000000101/index.ios.bundle.bsdiff",
742
+ },
743
+ ],
744
+ };
745
+ storageTexts.set(
746
+ currentManifestStorageUri,
747
+ JSON.stringify({
748
+ assets: {
749
+ "assets/logo.png": {
750
+ fileHash: "hash-logo",
751
+ },
752
+ "index.ios.bundle": {
753
+ fileHash: "hash-old-bundle",
754
+ },
755
+ },
756
+ bundleId: currentBundle.id,
757
+ }),
758
+ );
759
+ storageTexts.set(
760
+ nextManifestStorageUri,
761
+ JSON.stringify({
762
+ assets: {
763
+ "assets/logo.png": {
764
+ fileHash: "hash-logo",
765
+ },
766
+ "index.ios.bundle": {
767
+ fileHash: "hash-new-bundle",
768
+ },
769
+ },
770
+ bundleId: nextBundle.id,
771
+ }),
772
+ );
773
+ const fetchMock = vi.fn<typeof fetch>(async () => {
774
+ return new Response("manifest fetch should not be used", {
775
+ status: 500,
776
+ });
777
+ });
778
+
779
+ await hotUpdater.insertBundle(olderBundle);
780
+ await hotUpdater.insertBundle(currentBundle);
781
+ await hotUpdater.insertBundle(nextBundle);
782
+ vi.stubGlobal("fetch", fetchMock);
783
+
784
+ try {
785
+ await expect(
786
+ hotUpdater.getAppUpdateInfo({
787
+ appVersion: "1.0.0",
788
+ bundleId: currentBundle.id,
789
+ channel: "production",
790
+ platform: "ios",
791
+ _updateStrategy: "appVersion",
792
+ }),
793
+ ).resolves.toEqual({
794
+ changedAssets: {
795
+ "index.ios.bundle": {
796
+ file: {
797
+ compression: "br",
798
+ url: "https://s3.example.com/test-bucket/releases/00000000-0000-0000-0000-000000000102/files/index.ios.bundle.br",
799
+ },
800
+ fileHash: "hash-new-bundle",
801
+ patch: {
802
+ algorithm: "bsdiff",
803
+ baseBundleId: currentBundle.id,
804
+ baseFileHash: "hash-old-bundle",
805
+ patchFileHash: "hash-bsdiff",
806
+ patchUrl:
807
+ "https://s3.example.com/test-bucket/releases/00000000-0000-0000-0000-000000000102/patches/00000000-0000-0000-0000-000000000101/index.ios.bundle.bsdiff",
808
+ },
809
+ },
810
+ },
811
+ fileHash: "hash-next-zip",
812
+ fileUrl:
813
+ "https://s3.example.com/test-bucket/releases/00000000-0000-0000-0000-000000000102/bundle.zip",
814
+ id: nextBundle.id,
815
+ manifestFileHash: "sig:manifest-next",
816
+ manifestUrl:
817
+ "https://s3.example.com/test-bucket/releases/00000000-0000-0000-0000-000000000102/manifest.json",
818
+ message: "Next bundle",
819
+ shouldForceUpdate: false,
820
+ status: "UPDATE",
821
+ });
822
+ expect(fetchMock).not.toHaveBeenCalled();
823
+ } finally {
824
+ vi.unstubAllGlobals();
825
+ }
826
+ });
827
+
828
+ it("propagates manifest storage read failures for createHotUpdater", async () => {
829
+ const nextManifestStorageUri =
830
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000109/manifest.json";
831
+ const nextBundle: Bundle = {
832
+ id: "00000000-0000-0000-0000-000000000109",
833
+ platform: "ios",
834
+ shouldForceUpdate: false,
835
+ enabled: true,
836
+ fileHash: "hash-next-zip",
837
+ gitCommitHash: null,
838
+ message: "Next bundle",
839
+ channel: "production",
840
+ storageUri:
841
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000109/bundle.zip",
842
+ targetAppVersion: "1.0.0",
843
+ fingerprintHash: null,
844
+ assetBaseStorageUri:
845
+ "s3://test-bucket/releases/00000000-0000-0000-0000-000000000109/files",
846
+ manifestFileHash: "sig:manifest-next",
847
+ manifestStorageUri: nextManifestStorageUri,
848
+ };
849
+
850
+ await hotUpdater.insertBundle(nextBundle);
851
+ storageTexts.set(
852
+ nextManifestStorageUri,
853
+ new Error("storage read failed"),
854
+ );
855
+
856
+ await expect(
857
+ hotUpdater.getAppUpdateInfo({
858
+ appVersion: "1.0.0",
859
+ bundleId: NIL_UUID,
860
+ channel: "production",
861
+ platform: "ios",
862
+ _updateStrategy: "appVersion",
863
+ }),
864
+ ).rejects.toThrow("storage read failed");
865
+ });
365
866
  });
366
867
 
367
868
  describe("database plugin factories", () => {