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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/dist/adapters/databaseConstraintErrors.cjs +23 -0
  2. package/dist/adapters/databaseConstraintErrors.mjs +21 -0
  3. package/dist/adapters/databasePluginUtils.cjs +117 -0
  4. package/dist/adapters/databasePluginUtils.mjs +106 -0
  5. package/dist/adapters/drizzle.cjs +53 -176
  6. package/dist/adapters/drizzle.d.cts +6 -4
  7. package/dist/adapters/drizzle.d.mts +6 -4
  8. package/dist/adapters/drizzle.mjs +54 -177
  9. package/dist/adapters/drizzleCrud.cjs +250 -0
  10. package/dist/adapters/drizzleCrud.mjs +249 -0
  11. package/dist/adapters/drizzleLazyDB.cjs +84 -36
  12. package/dist/adapters/drizzleLazyDB.mjs +84 -36
  13. package/dist/adapters/drizzleQuery.cjs +68 -0
  14. package/dist/adapters/drizzleQuery.mjs +67 -0
  15. package/dist/adapters/kysely.cjs +18 -138
  16. package/dist/adapters/kysely.d.cts +3 -12
  17. package/dist/adapters/kysely.d.mts +3 -12
  18. package/dist/adapters/kysely.mjs +19 -139
  19. package/dist/adapters/kyselyCrud.cjs +254 -0
  20. package/dist/adapters/kyselyCrud.mjs +253 -0
  21. package/dist/adapters/kyselyQuery.cjs +56 -0
  22. package/dist/adapters/kyselyQuery.mjs +55 -0
  23. package/dist/adapters/mongodb.cjs +21 -174
  24. package/dist/adapters/mongodb.d.cts +3 -2
  25. package/dist/adapters/mongodb.d.mts +3 -2
  26. package/dist/adapters/mongodb.mjs +21 -174
  27. package/dist/adapters/mongodbCollections.cjs +36 -0
  28. package/dist/adapters/mongodbCollections.mjs +30 -0
  29. package/dist/adapters/mongodbQuery.cjs +77 -0
  30. package/dist/adapters/mongodbQuery.mjs +70 -0
  31. package/dist/adapters/mongodbReads.cjs +148 -0
  32. package/dist/adapters/mongodbReads.mjs +147 -0
  33. package/dist/adapters/mongodbWrites.cjs +134 -0
  34. package/dist/adapters/mongodbWrites.mjs +133 -0
  35. package/dist/adapters/prisma.cjs +205 -180
  36. package/dist/adapters/prisma.d.cts +3 -3
  37. package/dist/adapters/prisma.d.mts +3 -3
  38. package/dist/adapters/prisma.mjs +206 -181
  39. package/dist/adapters/prismaQuery.cjs +58 -0
  40. package/dist/adapters/prismaQuery.mjs +56 -0
  41. package/dist/adapters/prismaRows.cjs +198 -0
  42. package/dist/adapters/prismaRows.mjs +188 -0
  43. package/dist/analytics/bounded/activeOverview.cjs +87 -0
  44. package/dist/analytics/bounded/activeOverview.mjs +85 -0
  45. package/dist/analytics/bounded/installationSearch.cjs +42 -0
  46. package/dist/analytics/bounded/installationSearch.mjs +42 -0
  47. package/dist/analytics/bounded/persistence.cjs +39 -0
  48. package/dist/analytics/bounded/persistence.mjs +38 -0
  49. package/dist/analytics/bounded/provider.cjs +170 -0
  50. package/dist/analytics/bounded/provider.d.cts +7 -0
  51. package/dist/analytics/bounded/provider.d.mts +7 -0
  52. package/dist/analytics/bounded/provider.mjs +170 -0
  53. package/dist/analytics/bounded/scan.cjs +144 -0
  54. package/dist/analytics/bounded/scan.mjs +138 -0
  55. package/dist/analytics/domain.d.cts +121 -0
  56. package/dist/analytics/domain.d.mts +121 -0
  57. package/dist/analytics/errors.cjs +22 -0
  58. package/dist/analytics/errors.mjs +20 -0
  59. package/dist/analytics/eventInput.cjs +111 -0
  60. package/dist/analytics/eventInput.mjs +111 -0
  61. package/dist/analytics/persistence.d.cts +6 -0
  62. package/dist/analytics/persistence.d.mts +6 -0
  63. package/dist/analytics/queryInput.cjs +58 -0
  64. package/dist/analytics/queryInput.mjs +55 -0
  65. package/dist/analytics/routes.cjs +63 -0
  66. package/dist/analytics/routes.mjs +61 -0
  67. package/dist/analytics/types.d.cts +17 -0
  68. package/dist/analytics/types.d.mts +17 -0
  69. package/dist/apiKeys.cjs +139 -0
  70. package/dist/apiKeys.d.cts +50 -0
  71. package/dist/apiKeys.d.mts +50 -0
  72. package/dist/apiKeys.mjs +133 -0
  73. package/dist/createHotUpdaterCore.cjs +48 -26
  74. package/dist/createHotUpdaterCore.d.cts +49 -17
  75. package/dist/createHotUpdaterCore.d.mts +49 -17
  76. package/dist/createHotUpdaterCore.mjs +51 -29
  77. package/dist/db/createBundleDiff.cjs +45 -68
  78. package/dist/db/createBundleDiff.d.cts +3 -3
  79. package/dist/db/createBundleDiff.d.mts +3 -3
  80. package/dist/db/createBundleDiff.mjs +47 -68
  81. package/dist/db/databasePluginCore.cjs +138 -0
  82. package/dist/db/databasePluginCore.mjs +137 -0
  83. package/dist/db/fixedMigrator.cjs +36 -93
  84. package/dist/db/fixedMigrator.mjs +36 -93
  85. package/dist/db/fixedMigratorMongo.cjs +319 -0
  86. package/dist/db/fixedMigratorMongo.mjs +319 -0
  87. package/dist/db/fixedMigratorShared.cjs +23 -0
  88. package/dist/db/fixedMigratorShared.mjs +18 -0
  89. package/dist/db/mongoMigrationExecution.cjs +11 -0
  90. package/dist/db/mongoMigrationExecution.mjs +11 -0
  91. package/dist/db/releaseCatalog.cjs +66 -0
  92. package/dist/db/releaseCatalog.d.cts +17 -0
  93. package/dist/db/releaseCatalog.d.mts +17 -0
  94. package/dist/db/releaseCatalog.mjs +64 -0
  95. package/dist/db/schema/mongodb.cjs +14 -6
  96. package/dist/db/schema/mongodb.mjs +14 -6
  97. package/dist/db/schema/registry.cjs +0 -2
  98. package/dist/db/schema/registry.mjs +1 -2
  99. package/dist/db/schema/sql.cjs +31 -14
  100. package/dist/db/schema/sql.mjs +32 -13
  101. package/dist/db/schema/sqlOperations.cjs +4 -4
  102. package/dist/db/schema/sqlOperations.mjs +5 -5
  103. package/dist/db/schemaGenerators.cjs +52 -18
  104. package/dist/db/schemaGenerators.mjs +52 -18
  105. package/dist/db/schemaReadiness.cjs +4 -3
  106. package/dist/db/schemaReadiness.mjs +4 -3
  107. package/dist/db/sqlMigrationExecution.cjs +67 -0
  108. package/dist/db/sqlMigrationExecution.mjs +66 -0
  109. package/dist/db/types.cjs +2 -6
  110. package/dist/db/types.d.cts +60 -16
  111. package/dist/db/types.d.mts +60 -16
  112. package/dist/db/types.mjs +3 -6
  113. package/dist/db/updateArtifacts.cjs +114 -60
  114. package/dist/db/updateArtifacts.mjs +117 -62
  115. package/dist/handler.cjs +108 -282
  116. package/dist/handler.d.cts +3 -46
  117. package/dist/handler.d.mts +3 -46
  118. package/dist/handler.mjs +107 -281
  119. package/dist/handlerBundleRoutes.cjs +155 -0
  120. package/dist/handlerBundleRoutes.mjs +155 -0
  121. package/dist/handlerErrors.cjs +9 -0
  122. package/dist/handlerErrors.mjs +9 -0
  123. package/dist/handlerParameters.cjs +39 -0
  124. package/dist/handlerParameters.mjs +34 -0
  125. package/dist/handlerReleaseCatalogRoutes.cjs +111 -0
  126. package/dist/handlerReleaseCatalogRoutes.mjs +110 -0
  127. package/dist/handlerReleaseManagementRoutes.cjs +125 -0
  128. package/dist/handlerReleaseManagementRoutes.mjs +124 -0
  129. package/dist/handlerTypes.d.cts +63 -0
  130. package/dist/handlerTypes.d.mts +63 -0
  131. package/dist/handlerVersionRoutes.cjs +10 -0
  132. package/dist/handlerVersionRoutes.d.cts +4 -0
  133. package/dist/handlerVersionRoutes.d.mts +4 -0
  134. package/dist/handlerVersionRoutes.mjs +9 -0
  135. package/dist/index.cjs +10 -1
  136. package/dist/index.d.cts +9 -3
  137. package/dist/index.d.mts +9 -3
  138. package/dist/index.mjs +5 -2
  139. package/dist/node.cjs +19 -12
  140. package/dist/node.d.cts +15 -10
  141. package/dist/node.d.mts +15 -10
  142. package/dist/node.mjs +19 -13
  143. package/dist/package.cjs +1 -1
  144. package/dist/package.mjs +1 -1
  145. package/dist/schema/dsl.cjs +19 -2
  146. package/dist/schema/dsl.mjs +17 -3
  147. package/dist/schema/index.cjs +1 -8
  148. package/dist/schema/index.mjs +2 -8
  149. package/dist/schema/types.cjs +3 -1
  150. package/dist/schema/types.mjs +3 -2
  151. package/dist/schema/v1_0_0.cjs +364 -0
  152. package/dist/schema/v1_0_0.mjs +357 -0
  153. package/dist/storageAccess.cjs +69 -25
  154. package/dist/storageAccess.mjs +68 -25
  155. package/dist/types/index.d.cts +4 -3
  156. package/dist/types/index.d.mts +5 -4
  157. package/package.json +8 -7
  158. package/src/adapters/databaseConstraintErrors.ts +25 -0
  159. package/src/adapters/databasePluginTestDatabase.ts +106 -0
  160. package/src/adapters/databasePluginUtils.spec.ts +29 -0
  161. package/src/adapters/databasePluginUtils.ts +214 -0
  162. package/src/adapters/drizzle.spec.ts +208 -47
  163. package/src/adapters/drizzle.ts +106 -293
  164. package/src/adapters/drizzleCrud.ts +419 -0
  165. package/src/adapters/drizzleLazyDB.ts +206 -100
  166. package/src/adapters/drizzleQuery.ts +164 -0
  167. package/src/adapters/kysely.spec.ts +126 -88
  168. package/src/adapters/kysely.ts +76 -334
  169. package/src/adapters/kyselyCrud.ts +588 -0
  170. package/src/adapters/kyselyQuery.ts +128 -0
  171. package/src/adapters/mongodb.spec.ts +141 -0
  172. package/src/adapters/mongodb.ts +60 -288
  173. package/src/adapters/mongodbCollections.ts +62 -0
  174. package/src/adapters/mongodbQuery.ts +226 -0
  175. package/src/adapters/mongodbReads.ts +311 -0
  176. package/src/adapters/mongodbRows.spec.ts +64 -0
  177. package/src/adapters/mongodbRows.ts +118 -0
  178. package/src/adapters/mongodbTestClient.ts +342 -0
  179. package/src/adapters/mongodbTestFilter.ts +166 -0
  180. package/src/adapters/mongodbWrites.ts +260 -0
  181. package/src/adapters/prisma.spec.ts +196 -0
  182. package/src/adapters/prisma.ts +417 -292
  183. package/src/adapters/prismaQuery.ts +129 -0
  184. package/src/adapters/prismaRows.spec.ts +98 -0
  185. package/src/adapters/prismaRows.ts +301 -0
  186. package/src/adapters/prismaTestClient.ts +396 -0
  187. package/src/analytics/analytics.integration.spec.ts +144 -0
  188. package/src/analytics/bounded/activeOverview.spec.ts +189 -0
  189. package/src/analytics/bounded/activeOverview.ts +148 -0
  190. package/src/analytics/bounded/installationSearch.spec.ts +130 -0
  191. package/src/analytics/bounded/installationSearch.ts +69 -0
  192. package/src/analytics/bounded/persistence.ts +43 -0
  193. package/src/analytics/bounded/provider.spec.ts +219 -0
  194. package/src/analytics/bounded/provider.ts +229 -0
  195. package/src/analytics/bounded/scan.ts +235 -0
  196. package/src/analytics/domain.ts +139 -0
  197. package/src/analytics/errors.ts +18 -0
  198. package/src/analytics/eventInput.ts +168 -0
  199. package/src/analytics/persistence.ts +10 -0
  200. package/src/analytics/queryInput.ts +102 -0
  201. package/src/analytics/routes.ts +123 -0
  202. package/src/analytics/types.ts +44 -0
  203. package/src/apiKeys.integration.spec.ts +192 -0
  204. package/src/apiKeys.spec.ts +162 -0
  205. package/src/apiKeys.ts +220 -0
  206. package/src/createHotUpdaterCore.ts +164 -100
  207. package/src/db/bundleRows.spec.ts +164 -0
  208. package/src/db/bundleRows.ts +10 -140
  209. package/src/db/createBundleDiff.spec.ts +172 -127
  210. package/src/db/createBundleDiff.ts +91 -110
  211. package/src/db/databasePluginCore.spec.ts +62 -0
  212. package/src/db/databasePluginCore.testFixtures.ts +76 -0
  213. package/src/db/databasePluginCore.ts +185 -0
  214. package/src/db/databasePluginUpdateCheck.bench.ts +107 -0
  215. package/src/db/fixedMigrator.spec.ts +184 -42
  216. package/src/db/fixedMigrator.ts +64 -205
  217. package/src/db/fixedMigratorMongo.spec.ts +192 -0
  218. package/src/db/fixedMigratorMongo.ts +425 -0
  219. package/src/db/fixedMigratorShared.ts +36 -0
  220. package/src/db/hotUpdaterSchema.ts +0 -1
  221. package/src/db/index.spec.ts +333 -1025
  222. package/src/db/mongoMigrationExecution.ts +23 -0
  223. package/src/db/node-sqlite.d.ts +25 -0
  224. package/src/db/releaseCatalog.ts +148 -0
  225. package/src/db/schema/mongodb.ts +20 -6
  226. package/src/db/schema/sql.ts +52 -11
  227. package/src/db/schema/sqlOperations.ts +5 -4
  228. package/src/db/schemaGenerators.ts +107 -23
  229. package/src/db/schemaReadiness.ts +2 -1
  230. package/src/db/sqlMigrationExecution.spec.ts +65 -0
  231. package/src/db/sqlMigrationExecution.ts +108 -0
  232. package/src/db/types.spec.ts +55 -0
  233. package/src/db/types.ts +129 -65
  234. package/src/db/updateArtifacts.spec.ts +359 -0
  235. package/src/db/updateArtifacts.ts +290 -126
  236. package/src/handler-standalone.integration.spec.ts +401 -364
  237. package/src/handler.spec.ts +137 -582
  238. package/src/handler.testFixtures.ts +30 -0
  239. package/src/handler.ts +218 -616
  240. package/src/handlerAuth.integration.spec.ts +33 -0
  241. package/src/handlerBundleRoutes.ts +259 -0
  242. package/src/handlerErrors.ts +7 -0
  243. package/src/handlerManagement.spec.ts +262 -0
  244. package/src/handlerParameters.ts +105 -0
  245. package/src/handlerReleaseCatalogRoutes.ts +154 -0
  246. package/src/handlerReleaseManagementRoutes.ts +213 -0
  247. package/src/handlerTypes.ts +96 -0
  248. package/src/handlerVersionRoutes.ts +12 -0
  249. package/src/index.ts +22 -2
  250. package/src/node.spec.ts +79 -10
  251. package/src/node.ts +20 -17
  252. package/src/releaseCatalogRoutes.integration.spec.ts +238 -0
  253. package/src/runtime.spec.ts +126 -959
  254. package/src/runtime.testFixtures.ts +71 -0
  255. package/src/schema/dsl-all-versions.spec.ts +26 -17
  256. package/src/schema/dsl.ts +41 -2
  257. package/src/schema/index.ts +3 -9
  258. package/src/schema/types.ts +9 -3
  259. package/src/schema/v1_0_0.spec.ts +146 -0
  260. package/src/schema/v1_0_0.ts +465 -0
  261. package/src/storageAccess.spec.ts +127 -32
  262. package/src/storageAccess.ts +106 -55
  263. package/src/types/index.ts +2 -1
  264. package/dist/db/bundleRows.cjs +0 -82
  265. package/dist/db/bundleRows.d.cts +0 -33
  266. package/dist/db/bundleRows.d.mts +0 -33
  267. package/dist/db/bundleRows.mjs +0 -79
  268. package/dist/db/pluginCore.cjs +0 -242
  269. package/dist/db/pluginCore.mjs +0 -241
  270. package/dist/db/schema/sqlMigrations.cjs +0 -74
  271. package/dist/db/schema/sqlMigrations.mjs +0 -73
  272. package/dist/db/schemaEnhancements.cjs +0 -20
  273. package/dist/db/schemaEnhancements.mjs +0 -19
  274. package/dist/route.cjs +0 -7
  275. package/dist/route.mjs +0 -7
  276. package/dist/schema/v0_21_0.cjs +0 -38
  277. package/dist/schema/v0_21_0.mjs +0 -37
  278. package/dist/schema/v0_29_0.cjs +0 -45
  279. package/dist/schema/v0_29_0.mjs +0 -44
  280. package/dist/schema/v0_31_0.cjs +0 -82
  281. package/dist/schema/v0_31_0.mjs +0 -80
  282. package/src/db/pluginCore.spec.ts +0 -1095
  283. package/src/db/pluginCore.ts +0 -475
  284. package/src/db/pluginUpdateCheck.bench.ts +0 -254
  285. package/src/db/schema/sqlMigrations.ts +0 -219
  286. package/src/db/schemaEnhancements.ts +0 -55
  287. package/src/route.ts +0 -7
  288. package/src/schema/v0_21_0.ts +0 -52
  289. package/src/schema/v0_29_0.ts +0 -62
  290. package/src/schema/v0_31_0.spec.ts +0 -73
  291. package/src/schema/v0_31_0.ts +0 -120
@@ -0,0 +1,319 @@
1
+ import { HOT_UPDATER_CORE_SCHEMA_KEY, HOT_UPDATER_SCHEMA_VERSION, HOT_UPDATER_SETTINGS_TABLE } from "../schema/types.mjs";
2
+ import { assertCurrentOrEmptySchemaVersion, assertSupportedMigrationMode, getEmptyMigrationResult, inferLegacyCoreSchemaVersion, isCurrentSchemaVersion } from "./fixedMigratorShared.mjs";
3
+ import { hotUpdaterSchema, schemaIndexAppliesToProvider } from "./schema/registry.mjs";
4
+ import { executeMongoMigration } from "./mongoMigrationExecution.mjs";
5
+ import { createMongoMigrationOperations } from "./schema/mongodb.mjs";
6
+ //#region src/db/fixedMigratorMongo.ts
7
+ const isMongoNamespaceExistsError = (error) => {
8
+ if (!(error instanceof Error)) return false;
9
+ const mongoError = error;
10
+ return mongoError.code === 48 || mongoError.codeName === "NamespaceExists";
11
+ };
12
+ const isMongoNamespaceNotFoundError = (error) => {
13
+ if (!(error instanceof Error)) return false;
14
+ const mongoError = error;
15
+ return mongoError.code === 26 || mongoError.codeName === "NamespaceNotFound";
16
+ };
17
+ const ignoreExistingCollection = (error) => {
18
+ if (isMongoNamespaceExistsError(error)) return;
19
+ throw error;
20
+ };
21
+ const mongoNullableString = { bsonType: ["string", "null"] };
22
+ const mongoByteSize = {
23
+ bsonType: [
24
+ "double",
25
+ "int",
26
+ "long"
27
+ ],
28
+ maximum: Number.MAX_SAFE_INTEGER,
29
+ minimum: 0
30
+ };
31
+ const mongoBundleValidator = { $and: [{ $jsonSchema: {
32
+ bsonType: "object",
33
+ properties: {
34
+ archive_byte_size: mongoByteSize,
35
+ asset_base_storage_uri: mongoNullableString,
36
+ file_hash: { bsonType: "string" },
37
+ git_commit_hash: mongoNullableString,
38
+ id: { bsonType: "string" },
39
+ manifest_file_hash: mongoNullableString,
40
+ manifest_storage_uri: mongoNullableString,
41
+ metadata: { bsonType: "object" },
42
+ platform: { enum: ["ios", "android"] },
43
+ storage_uri: { bsonType: "string" }
44
+ },
45
+ required: [
46
+ "id",
47
+ "platform",
48
+ "file_hash",
49
+ "git_commit_hash",
50
+ "storage_uri",
51
+ "archive_byte_size",
52
+ "metadata",
53
+ "manifest_storage_uri",
54
+ "manifest_file_hash",
55
+ "asset_base_storage_uri"
56
+ ]
57
+ } }, { $expr: { $eq: [{ $trunc: "$archive_byte_size" }, "$archive_byte_size"] } }] };
58
+ const mongoPatchValidator = { $and: [{ $jsonSchema: {
59
+ bsonType: "object",
60
+ properties: {
61
+ base_bundle_id: { bsonType: "string" },
62
+ base_file_hash: { bsonType: "string" },
63
+ bundle_id: { bsonType: "string" },
64
+ id: { bsonType: "string" },
65
+ order_index: mongoByteSize,
66
+ byte_size: mongoByteSize,
67
+ patch_file_hash: { bsonType: "string" },
68
+ patch_storage_uri: { bsonType: "string" }
69
+ },
70
+ required: [
71
+ "id",
72
+ "bundle_id",
73
+ "base_bundle_id",
74
+ "base_file_hash",
75
+ "patch_file_hash",
76
+ "patch_storage_uri",
77
+ "byte_size",
78
+ "order_index"
79
+ ]
80
+ } }, { $expr: { $and: [{ $eq: [{ $trunc: "$order_index" }, "$order_index"] }, { $eq: [{ $trunc: "$byte_size" }, "$byte_size"] }] } }] };
81
+ const mongoReleaseValidator = { $jsonSchema: {
82
+ bsonType: "object",
83
+ properties: {
84
+ bundle_id: mongoNullableString,
85
+ channel_id: { bsonType: "string" },
86
+ created_at_ms: { bsonType: [
87
+ "double",
88
+ "int",
89
+ "long"
90
+ ] },
91
+ enabled: { bsonType: "bool" },
92
+ fingerprint_hash: mongoNullableString,
93
+ id: { bsonType: "string" },
94
+ kind: { enum: ["BUNDLE", "EMBEDDED"] },
95
+ message: mongoNullableString,
96
+ operation: { enum: [
97
+ "DEPLOY",
98
+ "PROMOTE",
99
+ "ROLLBACK"
100
+ ] },
101
+ platform: { enum: ["ios", "android"] },
102
+ revision: { bsonType: ["int", "long"] },
103
+ rollout_cohort_count: { bsonType: ["int", "long"] },
104
+ scope_key: { bsonType: "string" },
105
+ should_force_update: { bsonType: "bool" },
106
+ source_release_id: mongoNullableString,
107
+ strategy: { enum: ["APP_VERSION", "FINGERPRINT"] },
108
+ target_app_version: mongoNullableString,
109
+ target_cohorts: {
110
+ bsonType: "array",
111
+ items: { bsonType: "string" }
112
+ },
113
+ updated_at_ms: { bsonType: [
114
+ "double",
115
+ "int",
116
+ "long"
117
+ ] }
118
+ },
119
+ required: [
120
+ "id",
121
+ "revision",
122
+ "scope_key",
123
+ "channel_id",
124
+ "platform",
125
+ "kind",
126
+ "bundle_id",
127
+ "strategy",
128
+ "target_app_version",
129
+ "fingerprint_hash",
130
+ "enabled",
131
+ "should_force_update",
132
+ "message",
133
+ "rollout_cohort_count",
134
+ "target_cohorts",
135
+ "operation",
136
+ "source_release_id",
137
+ "created_at_ms",
138
+ "updated_at_ms"
139
+ ]
140
+ } };
141
+ const mongoReleaseCatalogValidator = { $jsonSchema: {
142
+ bsonType: "object",
143
+ properties: {
144
+ catalog_id: { bsonType: "string" },
145
+ byte_size: { bsonType: ["int", "long"] },
146
+ catalog_hash: { bsonType: "string" },
147
+ channel_id: { bsonType: "string" },
148
+ channel_key: { bsonType: "string" },
149
+ fingerprint_hash: mongoNullableString,
150
+ generation: { bsonType: [
151
+ "double",
152
+ "int",
153
+ "long"
154
+ ] },
155
+ is_tombstone: { bsonType: "bool" },
156
+ payload: { bsonType: "string" },
157
+ platform: { enum: ["ios", "android"] },
158
+ scope_key: { bsonType: "string" },
159
+ strategy: { enum: ["APP_VERSION", "FINGERPRINT"] },
160
+ updated_at_ms: { bsonType: [
161
+ "double",
162
+ "int",
163
+ "long"
164
+ ] }
165
+ },
166
+ required: [
167
+ "scope_key",
168
+ "catalog_id",
169
+ "strategy",
170
+ "channel_id",
171
+ "channel_key",
172
+ "platform",
173
+ "fingerprint_hash",
174
+ "generation",
175
+ "payload",
176
+ "catalog_hash",
177
+ "byte_size",
178
+ "is_tombstone",
179
+ "updated_at_ms"
180
+ ]
181
+ } };
182
+ const createSettingsKeyIndexOperation = () => ({
183
+ description: `Ensure unique MongoDB index: ${HOT_UPDATER_SETTINGS_TABLE}(key)`,
184
+ type: "custom"
185
+ });
186
+ const createMongoMigrator = (client) => {
187
+ const settings = client.db().collection(HOT_UPDATER_SETTINGS_TABLE);
188
+ const getSetting = async (key) => {
189
+ const [row, duplicate] = await settings.find({ key }).limit(2).toArray();
190
+ if (!row) return void 0;
191
+ if (duplicate) throw new Error(`Duplicate Hot Updater schema setting: ${key}`);
192
+ if (typeof row.value !== "string") throw new Error(`Invalid Hot Updater schema setting: ${key}`);
193
+ return row.value;
194
+ };
195
+ const getCoreVersion = () => getSetting(HOT_UPDATER_CORE_SCHEMA_KEY);
196
+ const getSchemaVersions = async () => {
197
+ return {
198
+ coreVersion: await getCoreVersion(),
199
+ legacyCoreVersion: inferLegacyCoreSchemaVersion(await getSetting("version"))
200
+ };
201
+ };
202
+ const getVersion = async () => {
203
+ const { coreVersion, legacyCoreVersion } = await getSchemaVersions();
204
+ return coreVersion ?? legacyCoreVersion;
205
+ };
206
+ const getSettingsKeyIndexState = async () => {
207
+ const index = (await settings.listIndexes().toArray().catch((error) => {
208
+ if (isMongoNamespaceNotFoundError(error)) return [];
209
+ throw error;
210
+ })).find(({ key }) => {
211
+ const fields = Object.entries(key);
212
+ return fields.length === 1 && fields[0]?.[0] === "key" && fields[0][1] === 1;
213
+ });
214
+ if (!index) return "missing";
215
+ return index.unique === true && index.sparse !== true && index.partialFilterExpression === void 0 ? "unique" : "non-unique";
216
+ };
217
+ const rejectNonUniqueSettingsKeyIndex = () => {
218
+ throw new Error("Hot Updater settings key index must enforce uniqueness for every key.");
219
+ };
220
+ const ensureSettingsKeyIndex = async () => {
221
+ const state = await getSettingsKeyIndexState();
222
+ if (state === "unique") return;
223
+ if (state === "non-unique") rejectNonUniqueSettingsKeyIndex();
224
+ await settings.createIndex({ key: 1 }, { unique: true });
225
+ };
226
+ const makeResult = async (options = {}) => {
227
+ assertSupportedMigrationMode(options);
228
+ const { coreVersion, legacyCoreVersion } = await getSchemaVersions();
229
+ const settingsKeyIndexState = await getSettingsKeyIndexState();
230
+ if (settingsKeyIndexState === "non-unique") rejectNonUniqueSettingsKeyIndex();
231
+ if (isCurrentSchemaVersion(coreVersion)) {
232
+ if (settingsKeyIndexState === "unique") return getEmptyMigrationResult();
233
+ return {
234
+ ...getEmptyMigrationResult(),
235
+ execute: ensureSettingsKeyIndex,
236
+ operations: [createSettingsKeyIndexOperation()]
237
+ };
238
+ }
239
+ assertCurrentOrEmptySchemaVersion(coreVersion ?? legacyCoreVersion);
240
+ const settingsOperation = options.updateSettings === false ? void 0 : {
241
+ type: "custom",
242
+ key: HOT_UPDATER_CORE_SCHEMA_KEY,
243
+ value: HOT_UPDATER_SCHEMA_VERSION
244
+ };
245
+ return {
246
+ operations: [createSettingsKeyIndexOperation(), ...createMongoMigrationOperations(settingsOperation)],
247
+ execute: async () => {
248
+ const db = client.db();
249
+ await executeMongoMigration({
250
+ updateSettings: options.updateSettings !== false,
251
+ backend: {
252
+ ensureCollections: async () => {
253
+ for (const table of hotUpdaterSchema.tables) {
254
+ if (table.internal) continue;
255
+ await db.createCollection(table.ormName).catch(ignoreExistingCollection);
256
+ }
257
+ },
258
+ ensureIndexes: async () => {
259
+ await ensureSettingsKeyIndex();
260
+ for (const table of hotUpdaterSchema.tables) {
261
+ if (table.internal) continue;
262
+ const collection = db.collection(table.ormName);
263
+ const primaryKey = table.columns.find((column) => column.primaryKey);
264
+ if (!primaryKey) throw new Error(`MongoDB table ${table.ormName} does not define a primary key.`);
265
+ const idIndexName = `${table.ormName}_${primaryKey.ormName}_idx`;
266
+ const existingIdIndex = (await collection.listIndexes().toArray()).find(({ name }) => name === idIndexName);
267
+ if (existingIdIndex && existingIdIndex.unique !== true) await collection.dropIndex(idIndexName);
268
+ await collection.createIndex({ [primaryKey.ormName]: 1 }, {
269
+ name: idIndexName,
270
+ unique: true
271
+ });
272
+ for (const index of (table.indexes ?? []).filter((item) => schemaIndexAppliesToProvider(item, "mongodb"))) await collection.createIndex(Object.fromEntries(index.columns.map((column) => [column, 1])), {
273
+ name: index.name,
274
+ ...index.unique ? { unique: true } : {}
275
+ });
276
+ }
277
+ },
278
+ enforceSchema: async () => {
279
+ for (const [collection, validator] of [
280
+ ["bundles", mongoBundleValidator],
281
+ ["bundle_patches", mongoPatchValidator],
282
+ ["releases", mongoReleaseValidator],
283
+ ["release_catalogs", mongoReleaseCatalogValidator]
284
+ ]) await db.command({
285
+ collMod: collection,
286
+ validationAction: "error",
287
+ validationLevel: "strict",
288
+ validator
289
+ });
290
+ },
291
+ updateVersion: async () => {
292
+ await settings.updateOne({ key: HOT_UPDATER_CORE_SCHEMA_KEY }, { $set: { value: HOT_UPDATER_SCHEMA_VERSION } }, { upsert: true });
293
+ }
294
+ }
295
+ });
296
+ }
297
+ };
298
+ };
299
+ return {
300
+ getVersion,
301
+ getNameVariants: async () => void 0,
302
+ next: async () => {
303
+ const { coreVersion } = await getSchemaVersions();
304
+ return isCurrentSchemaVersion(coreVersion) ? void 0 : { version: HOT_UPDATER_SCHEMA_VERSION };
305
+ },
306
+ previous: async () => void 0,
307
+ up: makeResult,
308
+ down: async () => {
309
+ throw new Error("No previous schema to migrate to.");
310
+ },
311
+ migrateTo: async (version, options) => {
312
+ if (version !== "1.0.0") throw new Error(`Invalid version ${version}`);
313
+ return makeResult(options);
314
+ },
315
+ migrateToLatest: makeResult
316
+ };
317
+ };
318
+ //#endregion
319
+ export { createMongoMigrator };
@@ -0,0 +1,23 @@
1
+ const require_types = require("../schema/types.cjs");
2
+ //#region src/db/fixedMigratorShared.ts
3
+ const getEmptyMigrationResult = () => ({
4
+ operations: [],
5
+ execute: async () => {},
6
+ getSQL: () => ""
7
+ });
8
+ const assertSupportedMigrationMode = (options) => {
9
+ if (options.mode === "from-database") throw new Error("Hot Updater migrations support only mode: 'from-schema'.");
10
+ };
11
+ const unsupportedSchemaUpgradeMessage = (version) => `Hot Updater v1 cannot migrate schema ${version} in place. Create a new empty database and run migrate or generate against schema ${require_types.HOT_UPDATER_SCHEMA_VERSION}.`;
12
+ const assertCurrentOrEmptySchemaVersion = (currentVersion) => {
13
+ if (currentVersion !== void 0 && currentVersion !== "1.0.0") throw new Error(unsupportedSchemaUpgradeMessage(currentVersion));
14
+ };
15
+ const inferLegacyCoreSchemaVersion = (legacyVersion) => legacyVersion;
16
+ const isCurrentSchemaVersion = (currentVersion) => currentVersion === require_types.HOT_UPDATER_SCHEMA_VERSION;
17
+ //#endregion
18
+ exports.assertCurrentOrEmptySchemaVersion = assertCurrentOrEmptySchemaVersion;
19
+ exports.assertSupportedMigrationMode = assertSupportedMigrationMode;
20
+ exports.getEmptyMigrationResult = getEmptyMigrationResult;
21
+ exports.inferLegacyCoreSchemaVersion = inferLegacyCoreSchemaVersion;
22
+ exports.isCurrentSchemaVersion = isCurrentSchemaVersion;
23
+ exports.unsupportedSchemaUpgradeMessage = unsupportedSchemaUpgradeMessage;
@@ -0,0 +1,18 @@
1
+ import { HOT_UPDATER_SCHEMA_VERSION } from "../schema/types.mjs";
2
+ //#region src/db/fixedMigratorShared.ts
3
+ const getEmptyMigrationResult = () => ({
4
+ operations: [],
5
+ execute: async () => {},
6
+ getSQL: () => ""
7
+ });
8
+ const assertSupportedMigrationMode = (options) => {
9
+ if (options.mode === "from-database") throw new Error("Hot Updater migrations support only mode: 'from-schema'.");
10
+ };
11
+ const unsupportedSchemaUpgradeMessage = (version) => `Hot Updater v1 cannot migrate schema ${version} in place. Create a new empty database and run migrate or generate against schema ${HOT_UPDATER_SCHEMA_VERSION}.`;
12
+ const assertCurrentOrEmptySchemaVersion = (currentVersion) => {
13
+ if (currentVersion !== void 0 && currentVersion !== "1.0.0") throw new Error(unsupportedSchemaUpgradeMessage(currentVersion));
14
+ };
15
+ const inferLegacyCoreSchemaVersion = (legacyVersion) => legacyVersion;
16
+ const isCurrentSchemaVersion = (currentVersion) => currentVersion === HOT_UPDATER_SCHEMA_VERSION;
17
+ //#endregion
18
+ export { assertCurrentOrEmptySchemaVersion, assertSupportedMigrationMode, getEmptyMigrationResult, inferLegacyCoreSchemaVersion, isCurrentSchemaVersion, unsupportedSchemaUpgradeMessage };
@@ -0,0 +1,11 @@
1
+ //#region src/db/mongoMigrationExecution.ts
2
+ const executeMongoMigration = async ({ backend, updateSettings }) => {
3
+ await backend.ensureCollections();
4
+ await backend.backfillData?.();
5
+ await backend.validateData?.();
6
+ await backend.ensureIndexes();
7
+ await backend.enforceSchema?.();
8
+ if (updateSettings) await backend.updateVersion();
9
+ };
10
+ //#endregion
11
+ exports.executeMongoMigration = executeMongoMigration;
@@ -0,0 +1,11 @@
1
+ //#region src/db/mongoMigrationExecution.ts
2
+ const executeMongoMigration = async ({ backend, updateSettings }) => {
3
+ await backend.ensureCollections();
4
+ await backend.backfillData?.();
5
+ await backend.validateData?.();
6
+ await backend.ensureIndexes();
7
+ await backend.enforceSchema?.();
8
+ if (updateSettings) await backend.updateVersion();
9
+ };
10
+ //#endregion
11
+ export { executeMongoMigration };
@@ -0,0 +1,66 @@
1
+ require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_updateArtifacts = require("./updateArtifacts.cjs");
3
+ let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
4
+ let _hot_updater_core = require("@hot-updater/core");
5
+ //#region src/db/releaseCatalog.ts
6
+ const parseCompiledCatalog = (payload, strategy) => {
7
+ const parsed = JSON.parse(payload);
8
+ if (typeof parsed !== "object" || parsed === null || Reflect.get(parsed, "schemaVersion") !== _hot_updater_core.RELEASE_CATALOG_SCHEMA_VERSION || Reflect.get(parsed, "strategy") !== strategy || Reflect.get(parsed, "fallbackPolicy") !== _hot_updater_core.RELEASE_CATALOG_FALLBACK_POLICY || !Array.isArray(Reflect.get(parsed, "releaseDescriptors"))) throw new Error("Stored Release catalog payload is invalid");
9
+ if (strategy === "APP_VERSION" && !Array.isArray(Reflect.get(parsed, "segments"))) throw new Error("Stored app-version Release catalog is invalid");
10
+ if (strategy === "FINGERPRINT" && !Array.isArray(Reflect.get(parsed, "releaseIndexes"))) throw new Error("Stored fingerprint Release catalog is invalid");
11
+ return parsed;
12
+ };
13
+ const createReleaseCatalogReader = (database) => async (input) => {
14
+ const scopeKey = input.strategy === "APP_VERSION" ? (0, _hot_updater_core.createReleaseCatalogScopeKey)({
15
+ channelKey: input.channelKey,
16
+ platform: input.platform,
17
+ strategy: "APP_VERSION"
18
+ }) : (0, _hot_updater_core.createReleaseCatalogScopeKey)({
19
+ channelKey: input.channelKey,
20
+ fingerprintHash: input.fingerprintHash,
21
+ platform: input.platform,
22
+ strategy: "FINGERPRINT"
23
+ });
24
+ const row = await database.models.releaseCatalogs.findByScopeKey(scopeKey);
25
+ if (row === null || row.platform !== input.platform || row.strategy !== input.strategy || row.channel_key !== input.channelKey || row.scope_key !== scopeKey || row.fingerprint_hash !== (input.strategy === "FINGERPRINT" ? input.fingerprintHash : null)) return null;
26
+ const compiled = parseCompiledCatalog(row.payload, input.strategy);
27
+ const releases = (0, _hot_updater_plugin_core.projectCompiledCatalog)(compiled, input.strategy === "APP_VERSION" ? input.appVersion : void 0);
28
+ const rollbackReleases = (0, _hot_updater_plugin_core.projectCompiledRollbackCatalog)(compiled, input.strategy === "APP_VERSION" ? input.appVersion : void 0);
29
+ return {
30
+ catalogId: row.catalog_id,
31
+ catalogHash: row.catalog_hash,
32
+ fallbackPolicy: _hot_updater_core.RELEASE_CATALOG_FALLBACK_POLICY,
33
+ generation: row.generation,
34
+ releases,
35
+ rollbackReleases,
36
+ schemaVersion: _hot_updater_core.RELEASE_CATALOG_SCHEMA_VERSION,
37
+ scopeKey
38
+ };
39
+ };
40
+ const createArtifactResolver = (input) => {
41
+ const databaseClient = (0, _hot_updater_plugin_core.createDatabaseClient)(input.database);
42
+ return async (targetBundleId, currentBundleId) => {
43
+ const [targetBundle, currentBundle] = await Promise.all([databaseClient.getBundleById(targetBundleId), currentBundleId === _hot_updater_core.NIL_UUID ? null : databaseClient.getBundleById(currentBundleId)]);
44
+ if (targetBundle === null) return null;
45
+ const fileUrl = await input.resolveFileUrl(targetBundle.storageUri);
46
+ const base = {
47
+ fileHash: targetBundle.fileHash,
48
+ fileUrl
49
+ };
50
+ if (input.readStorageText === void 0) return base;
51
+ const manifest = await require_updateArtifacts.resolveManifestArtifacts({
52
+ archiveUrlUsable: fileUrl !== null,
53
+ currentBundle,
54
+ readStorageText: input.readStorageText,
55
+ resolveFileUrl: input.resolveFileUrl,
56
+ targetBundle
57
+ });
58
+ return manifest === null ? base : {
59
+ ...base,
60
+ ...manifest
61
+ };
62
+ };
63
+ };
64
+ //#endregion
65
+ exports.createArtifactResolver = createArtifactResolver;
66
+ exports.createReleaseCatalogReader = createReleaseCatalogReader;
@@ -0,0 +1,17 @@
1
+ import { ArtifactInfo, ReleaseCatalog } from "@hot-updater/core";
2
+ import { DatabasePlugin } from "@hot-updater/plugin-core";
3
+
4
+ //#region src/db/releaseCatalog.d.ts
5
+ type ReleaseCatalogRequest = {
6
+ readonly strategy: "APP_VERSION";
7
+ readonly platform: "ios" | "android";
8
+ readonly channelKey: string;
9
+ readonly appVersion: string;
10
+ } | {
11
+ readonly strategy: "FINGERPRINT";
12
+ readonly platform: "ios" | "android";
13
+ readonly channelKey: string;
14
+ readonly fingerprintHash: string;
15
+ };
16
+ //#endregion
17
+ export { ReleaseCatalogRequest };
@@ -0,0 +1,17 @@
1
+ import { DatabasePlugin } from "@hot-updater/plugin-core";
2
+ import { ArtifactInfo, ReleaseCatalog } from "@hot-updater/core";
3
+
4
+ //#region src/db/releaseCatalog.d.ts
5
+ type ReleaseCatalogRequest = {
6
+ readonly strategy: "APP_VERSION";
7
+ readonly platform: "ios" | "android";
8
+ readonly channelKey: string;
9
+ readonly appVersion: string;
10
+ } | {
11
+ readonly strategy: "FINGERPRINT";
12
+ readonly platform: "ios" | "android";
13
+ readonly channelKey: string;
14
+ readonly fingerprintHash: string;
15
+ };
16
+ //#endregion
17
+ export { ReleaseCatalogRequest };
@@ -0,0 +1,64 @@
1
+ import { resolveManifestArtifacts } from "./updateArtifacts.mjs";
2
+ import { createDatabaseClient, projectCompiledCatalog, projectCompiledRollbackCatalog } from "@hot-updater/plugin-core";
3
+ import { NIL_UUID, RELEASE_CATALOG_FALLBACK_POLICY, RELEASE_CATALOG_SCHEMA_VERSION, createReleaseCatalogScopeKey } from "@hot-updater/core";
4
+ //#region src/db/releaseCatalog.ts
5
+ const parseCompiledCatalog = (payload, strategy) => {
6
+ const parsed = JSON.parse(payload);
7
+ if (typeof parsed !== "object" || parsed === null || Reflect.get(parsed, "schemaVersion") !== RELEASE_CATALOG_SCHEMA_VERSION || Reflect.get(parsed, "strategy") !== strategy || Reflect.get(parsed, "fallbackPolicy") !== RELEASE_CATALOG_FALLBACK_POLICY || !Array.isArray(Reflect.get(parsed, "releaseDescriptors"))) throw new Error("Stored Release catalog payload is invalid");
8
+ if (strategy === "APP_VERSION" && !Array.isArray(Reflect.get(parsed, "segments"))) throw new Error("Stored app-version Release catalog is invalid");
9
+ if (strategy === "FINGERPRINT" && !Array.isArray(Reflect.get(parsed, "releaseIndexes"))) throw new Error("Stored fingerprint Release catalog is invalid");
10
+ return parsed;
11
+ };
12
+ const createReleaseCatalogReader = (database) => async (input) => {
13
+ const scopeKey = input.strategy === "APP_VERSION" ? createReleaseCatalogScopeKey({
14
+ channelKey: input.channelKey,
15
+ platform: input.platform,
16
+ strategy: "APP_VERSION"
17
+ }) : createReleaseCatalogScopeKey({
18
+ channelKey: input.channelKey,
19
+ fingerprintHash: input.fingerprintHash,
20
+ platform: input.platform,
21
+ strategy: "FINGERPRINT"
22
+ });
23
+ const row = await database.models.releaseCatalogs.findByScopeKey(scopeKey);
24
+ if (row === null || row.platform !== input.platform || row.strategy !== input.strategy || row.channel_key !== input.channelKey || row.scope_key !== scopeKey || row.fingerprint_hash !== (input.strategy === "FINGERPRINT" ? input.fingerprintHash : null)) return null;
25
+ const compiled = parseCompiledCatalog(row.payload, input.strategy);
26
+ const releases = projectCompiledCatalog(compiled, input.strategy === "APP_VERSION" ? input.appVersion : void 0);
27
+ const rollbackReleases = projectCompiledRollbackCatalog(compiled, input.strategy === "APP_VERSION" ? input.appVersion : void 0);
28
+ return {
29
+ catalogId: row.catalog_id,
30
+ catalogHash: row.catalog_hash,
31
+ fallbackPolicy: RELEASE_CATALOG_FALLBACK_POLICY,
32
+ generation: row.generation,
33
+ releases,
34
+ rollbackReleases,
35
+ schemaVersion: RELEASE_CATALOG_SCHEMA_VERSION,
36
+ scopeKey
37
+ };
38
+ };
39
+ const createArtifactResolver = (input) => {
40
+ const databaseClient = createDatabaseClient(input.database);
41
+ return async (targetBundleId, currentBundleId) => {
42
+ const [targetBundle, currentBundle] = await Promise.all([databaseClient.getBundleById(targetBundleId), currentBundleId === NIL_UUID ? null : databaseClient.getBundleById(currentBundleId)]);
43
+ if (targetBundle === null) return null;
44
+ const fileUrl = await input.resolveFileUrl(targetBundle.storageUri);
45
+ const base = {
46
+ fileHash: targetBundle.fileHash,
47
+ fileUrl
48
+ };
49
+ if (input.readStorageText === void 0) return base;
50
+ const manifest = await resolveManifestArtifacts({
51
+ archiveUrlUsable: fileUrl !== null,
52
+ currentBundle,
53
+ readStorageText: input.readStorageText,
54
+ resolveFileUrl: input.resolveFileUrl,
55
+ targetBundle
56
+ });
57
+ return manifest === null ? base : {
58
+ ...base,
59
+ ...manifest
60
+ };
61
+ };
62
+ };
63
+ //#endregion
64
+ export { createArtifactResolver, createReleaseCatalogReader };
@@ -3,14 +3,22 @@ const require_sql = require("./sql.cjs");
3
3
  //#region src/db/schema/mongodb.ts
4
4
  const createMongoMigrationOperations = (settingsOperation) => [
5
5
  ...require_sql.hotUpdaterCreateTableOperations,
6
- {
7
- type: "custom",
8
- sql: "create index bundles_id_idx on bundles(id)"
9
- },
6
+ ...require_registry.hotUpdaterSchema.tables.filter((table) => !table.internal).map((table) => {
7
+ const primaryKey = table.columns.find((column) => column.primaryKey);
8
+ if (!primaryKey) throw new Error(`MongoDB table ${table.ormName} does not define a primary key.`);
9
+ return {
10
+ description: `Create unique MongoDB index: ${table.ormName}_${primaryKey.ormName}_idx on ${table.ormName}(${primaryKey.ormName})`,
11
+ type: "custom"
12
+ };
13
+ }),
10
14
  ...require_registry.hotUpdaterSchema.tables.flatMap((table) => (table.indexes ?? []).filter((index) => require_registry.schemaIndexAppliesToProvider(index, "mongodb")).map((index) => ({
11
- type: "custom",
12
- sql: `create index ${index.name} on ${table.ormName}(${index.columns.join(", ")})`
15
+ description: `Create ${index.unique ? "unique " : ""}MongoDB index: ${index.name} on ${table.ormName}(${index.columns.join(", ")})`,
16
+ type: "custom"
13
17
  }))),
18
+ {
19
+ description: "Enforce final MongoDB Bundle, Release, and catalog schemas",
20
+ type: "custom"
21
+ },
14
22
  ...settingsOperation ? [settingsOperation] : []
15
23
  ];
16
24
  //#endregion
@@ -3,14 +3,22 @@ import { hotUpdaterCreateTableOperations } from "./sql.mjs";
3
3
  //#region src/db/schema/mongodb.ts
4
4
  const createMongoMigrationOperations = (settingsOperation) => [
5
5
  ...hotUpdaterCreateTableOperations,
6
- {
7
- type: "custom",
8
- sql: "create index bundles_id_idx on bundles(id)"
9
- },
6
+ ...hotUpdaterSchema.tables.filter((table) => !table.internal).map((table) => {
7
+ const primaryKey = table.columns.find((column) => column.primaryKey);
8
+ if (!primaryKey) throw new Error(`MongoDB table ${table.ormName} does not define a primary key.`);
9
+ return {
10
+ description: `Create unique MongoDB index: ${table.ormName}_${primaryKey.ormName}_idx on ${table.ormName}(${primaryKey.ormName})`,
11
+ type: "custom"
12
+ };
13
+ }),
10
14
  ...hotUpdaterSchema.tables.flatMap((table) => (table.indexes ?? []).filter((index) => schemaIndexAppliesToProvider(index, "mongodb")).map((index) => ({
11
- type: "custom",
12
- sql: `create index ${index.name} on ${table.ormName}(${index.columns.join(", ")})`
15
+ description: `Create ${index.unique ? "unique " : ""}MongoDB index: ${index.name} on ${table.ormName}(${index.columns.join(", ")})`,
16
+ type: "custom"
13
17
  }))),
18
+ {
19
+ description: "Enforce final MongoDB Bundle, Release, and catalog schemas",
20
+ type: "custom"
21
+ },
14
22
  ...settingsOperation ? [settingsOperation] : []
15
23
  ];
16
24
  //#endregion
@@ -1,7 +1,6 @@
1
1
  const require_index = require("../../schema/index.cjs");
2
2
  //#region src/db/schema/registry.ts
3
3
  const hotUpdaterSchema = require_index.hotUpdaterSchemaVersions[require_index.hotUpdaterSchemaVersions.length - 1];
4
- const getSchemaVersionIndex = (version) => require_index.hotUpdaterSchemaVersions.findIndex((schema) => schema.version === version);
5
4
  const getHotUpdaterSchemaVersion = (version) => {
6
5
  const schema = require_index.hotUpdaterSchemaVersions.find((item) => item.version === version);
7
6
  if (!schema) throw new Error(`Unsupported Hot Updater schema version: ${version}`);
@@ -17,7 +16,6 @@ const schemaIndexAppliesToProvider = (index, provider) => !index.providers || in
17
16
  //#endregion
18
17
  exports.getHotUpdaterSchemaVersion = getHotUpdaterSchemaVersion;
19
18
  exports.getSchemaColumn = getSchemaColumn;
20
- exports.getSchemaVersionIndex = getSchemaVersionIndex;
21
19
  exports.hotUpdaterDataTables = hotUpdaterDataTables;
22
20
  exports.hotUpdaterSchema = hotUpdaterSchema;
23
21
  exports.schemaIndexAppliesToProvider = schemaIndexAppliesToProvider;
@@ -1,7 +1,6 @@
1
1
  import { hotUpdaterSchemaVersions } from "../../schema/index.mjs";
2
2
  //#region src/db/schema/registry.ts
3
3
  const hotUpdaterSchema = hotUpdaterSchemaVersions[hotUpdaterSchemaVersions.length - 1];
4
- const getSchemaVersionIndex = (version) => hotUpdaterSchemaVersions.findIndex((schema) => schema.version === version);
5
4
  const getHotUpdaterSchemaVersion = (version) => {
6
5
  const schema = hotUpdaterSchemaVersions.find((item) => item.version === version);
7
6
  if (!schema) throw new Error(`Unsupported Hot Updater schema version: ${version}`);
@@ -15,4 +14,4 @@ const getSchemaColumn = (table, name) => {
15
14
  const hotUpdaterDataTables = hotUpdaterSchema.tables.filter((table) => !table.internal);
16
15
  const schemaIndexAppliesToProvider = (index, provider) => !index.providers || index.providers.includes(provider);
17
16
  //#endregion
18
- export { getHotUpdaterSchemaVersion, getSchemaColumn, getSchemaVersionIndex, hotUpdaterDataTables, hotUpdaterSchema, schemaIndexAppliesToProvider };
17
+ export { getHotUpdaterSchemaVersion, getSchemaColumn, hotUpdaterDataTables, hotUpdaterSchema, schemaIndexAppliesToProvider };