@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.
- package/dist/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/adapters/drizzle.cjs +35 -69
- package/dist/adapters/drizzle.d.cts +13 -6
- package/dist/adapters/drizzle.d.mts +13 -6
- package/dist/adapters/drizzle.mjs +34 -69
- package/dist/adapters/drizzleExecutor.cjs +114 -0
- package/dist/adapters/drizzleExecutor.d.cts +9 -0
- package/dist/adapters/drizzleExecutor.d.mts +9 -0
- package/dist/adapters/drizzleExecutor.mjs +112 -0
- package/dist/adapters/kysely.cjs +25 -31
- package/dist/adapters/kysely.d.cts +10 -7
- package/dist/adapters/kysely.d.mts +10 -7
- package/dist/adapters/kysely.mjs +25 -31
- package/dist/adapters/kyselyExecutor.cjs +32 -0
- package/dist/adapters/kyselyExecutor.d.cts +12 -0
- package/dist/adapters/kyselyExecutor.d.mts +12 -0
- package/dist/adapters/kyselyExecutor.mjs +32 -0
- package/dist/adapters/mongodb.cjs +28 -27
- package/dist/adapters/mongodb.d.cts +10 -5
- package/dist/adapters/mongodb.d.mts +10 -5
- package/dist/adapters/mongodb.mjs +28 -27
- package/dist/adapters/mongodbAdapter.cjs +174 -0
- package/dist/adapters/mongodbAdapter.d.cts +9 -0
- package/dist/adapters/mongodbAdapter.d.mts +9 -0
- package/dist/adapters/mongodbAdapter.mjs +173 -0
- package/dist/adapters/prisma.cjs +38 -220
- package/dist/adapters/prisma.d.cts +12 -8
- package/dist/adapters/prisma.d.mts +12 -8
- package/dist/adapters/prisma.mjs +38 -219
- package/dist/adapters/prismaExecutor.cjs +64 -0
- package/dist/adapters/prismaExecutor.mjs +64 -0
- package/dist/adapters/sqlProviders.cjs +9 -0
- package/dist/adapters/sqlProviders.mjs +9 -0
- package/dist/apiKeys.cjs +8 -8
- package/dist/apiKeys.d.cts +1 -24
- package/dist/apiKeys.d.mts +1 -24
- package/dist/apiKeys.mjs +5 -9
- package/dist/assembly/assemblePlugins.cjs +147 -0
- package/dist/assembly/assemblePlugins.d.cts +12 -0
- package/dist/assembly/assemblePlugins.d.mts +12 -0
- package/dist/assembly/assemblePlugins.mjs +146 -0
- package/dist/assembly/databasePlugins.cjs +23 -0
- package/dist/assembly/databasePlugins.d.cts +43 -0
- package/dist/assembly/databasePlugins.d.mts +43 -0
- package/dist/assembly/databasePlugins.mjs +22 -0
- package/dist/core/api.cjs +91 -0
- package/dist/core/api.d.cts +65 -0
- package/dist/core/api.d.mts +65 -0
- package/dist/core/api.mjs +87 -0
- package/dist/core/baseCandidates.cjs +71 -0
- package/dist/core/baseCandidates.d.cts +17 -0
- package/dist/core/baseCandidates.d.mts +17 -0
- package/dist/core/baseCandidates.mjs +69 -0
- package/dist/core/operations.cjs +350 -0
- package/dist/core/operations.mjs +350 -0
- package/dist/core/reads.cjs +273 -0
- package/dist/core/reads.d.cts +48 -0
- package/dist/core/reads.d.mts +48 -0
- package/dist/core/reads.mjs +267 -0
- package/dist/core/releases.cjs +193 -0
- package/dist/core/releases.mjs +190 -0
- package/dist/core/schema.cjs +279 -0
- package/dist/core/schema.d.cts +307 -0
- package/dist/core/schema.d.mts +307 -0
- package/dist/core/schema.mjs +277 -0
- package/dist/core/writes.cjs +96 -0
- package/dist/core/writes.mjs +91 -0
- package/dist/createHotUpdaterCore.cjs +61 -63
- package/dist/createHotUpdaterCore.d.cts +53 -45
- package/dist/createHotUpdaterCore.d.mts +53 -45
- package/dist/createHotUpdaterCore.mjs +61 -63
- package/dist/database/cursor.cjs +44 -0
- package/dist/database/cursor.d.cts +7 -0
- package/dist/database/cursor.d.mts +7 -0
- package/dist/database/cursor.mjs +40 -0
- package/dist/database/database.cjs +44 -0
- package/dist/database/database.d.cts +123 -0
- package/dist/database/database.d.mts +123 -0
- package/dist/database/database.mjs +44 -0
- package/dist/database/definitions.d.cts +68 -0
- package/dist/database/definitions.d.mts +68 -0
- package/dist/database/engine.cjs +37 -0
- package/dist/database/engine.d.cts +40 -0
- package/dist/database/engine.d.mts +40 -0
- package/dist/database/engine.mjs +37 -0
- package/dist/database/engineAggregates.cjs +115 -0
- package/dist/database/engineAggregates.mjs +112 -0
- package/dist/database/engineReads.cjs +180 -0
- package/dist/database/engineReads.d.cts +35 -0
- package/dist/database/engineReads.d.mts +35 -0
- package/dist/database/engineReads.mjs +179 -0
- package/dist/database/engineTransaction.cjs +403 -0
- package/dist/database/engineTransaction.d.cts +26 -0
- package/dist/database/engineTransaction.d.mts +26 -0
- package/dist/database/engineTransaction.mjs +402 -0
- package/dist/database/errors.cjs +27 -0
- package/dist/database/errors.d.cts +21 -0
- package/dist/database/errors.d.mts +21 -0
- package/dist/database/errors.mjs +24 -0
- package/dist/database/fence.cjs +124 -0
- package/dist/database/fence.d.cts +42 -0
- package/dist/database/fence.d.mts +42 -0
- package/dist/database/fence.mjs +116 -0
- package/dist/database/index.cjs +127 -0
- package/dist/database/index.d.cts +17 -0
- package/dist/database/index.d.mts +17 -0
- package/dist/database/index.mjs +15 -0
- package/dist/database/kv/kvAdapter.cjs +273 -0
- package/dist/database/kv/kvAdapter.d.cts +101 -0
- package/dist/database/kv/kvAdapter.d.mts +101 -0
- package/dist/database/kv/kvAdapter.mjs +272 -0
- package/dist/database/resolveSchema.cjs +196 -0
- package/dist/database/resolveSchema.d.cts +42 -0
- package/dist/database/resolveSchema.d.mts +42 -0
- package/dist/database/resolveSchema.mjs +193 -0
- package/dist/database/schema.cjs +21 -0
- package/dist/database/schema.d.cts +61 -0
- package/dist/database/schema.d.mts +61 -0
- package/dist/database/schema.mjs +20 -0
- package/dist/database/sql/sqlAdapter.cjs +282 -0
- package/dist/database/sql/sqlAdapter.d.cts +46 -0
- package/dist/database/sql/sqlAdapter.d.mts +46 -0
- package/dist/database/sql/sqlAdapter.mjs +279 -0
- package/dist/database/sql/sqlSchema.cjs +115 -0
- package/dist/database/sql/sqlSchema.d.cts +8 -0
- package/dist/database/sql/sqlSchema.d.mts +8 -0
- package/dist/database/sql/sqlSchema.mjs +111 -0
- package/dist/db/builtInDatabase.cjs +104 -0
- package/dist/db/builtInDatabase.d.cts +38 -0
- package/dist/db/builtInDatabase.d.mts +38 -0
- package/dist/db/builtInDatabase.mjs +97 -0
- package/dist/db/createBundleDiff.cjs +6 -6
- package/dist/db/createBundleDiff.d.cts +4 -7
- package/dist/db/createBundleDiff.d.mts +4 -7
- package/dist/db/createBundleDiff.mjs +5 -5
- package/dist/db/engineDrizzleSchema.cjs +54 -0
- package/dist/db/engineDrizzleSchema.mjs +54 -0
- package/dist/db/engineMigrator.cjs +53 -0
- package/dist/db/engineMigrator.mjs +53 -0
- package/dist/db/enginePrismaSchema.cjs +85 -0
- package/dist/db/enginePrismaSchema.d.cts +5 -0
- package/dist/db/enginePrismaSchema.d.mts +5 -0
- package/dist/db/enginePrismaSchema.mjs +84 -0
- package/dist/db/engineSql.cjs +26 -0
- package/dist/db/engineSql.d.cts +17 -0
- package/dist/db/engineSql.d.mts +17 -0
- package/dist/db/engineSql.mjs +25 -0
- package/dist/db/engineSqlMigrator.cjs +66 -0
- package/dist/db/engineSqlMigrator.mjs +66 -0
- package/dist/db/fixedMigratorShared.cjs +0 -11
- package/dist/db/fixedMigratorShared.mjs +1 -8
- package/dist/db/index.cjs +23 -8
- package/dist/db/index.d.cts +10 -4
- package/dist/db/index.d.mts +10 -4
- package/dist/db/index.mjs +16 -8
- package/dist/db/releaseCatalog.cjs +20 -44
- package/dist/db/releaseCatalog.d.cts +2 -3
- package/dist/db/releaseCatalog.d.mts +2 -3
- package/dist/db/releaseCatalog.mjs +20 -44
- package/dist/db/schemaSettings.cjs +63 -0
- package/dist/db/schemaSettings.d.cts +12 -0
- package/dist/db/schemaSettings.d.mts +12 -0
- package/dist/db/schemaSettings.mjs +62 -0
- package/dist/db/settingsMigrator.cjs +92 -0
- package/dist/db/settingsMigrator.mjs +89 -0
- package/dist/db/types.cjs +3 -12
- package/dist/db/types.d.cts +26 -69
- package/dist/db/types.d.mts +26 -69
- package/dist/db/types.mjs +2 -11
- package/dist/db/updateArtifacts.cjs +38 -68
- package/dist/db/updateArtifacts.mjs +40 -69
- package/dist/handler.cjs +72 -43
- package/dist/handler.d.cts +3 -6
- package/dist/handler.d.mts +3 -6
- package/dist/handler.mjs +73 -43
- package/dist/handlerAdminRoutes.cjs +375 -0
- package/dist/handlerAdminRoutes.mjs +373 -0
- package/dist/handlerParameters.cjs +6 -11
- package/dist/handlerParameters.mjs +6 -10
- package/dist/handlerReleaseCatalogRoutes.cjs +11 -14
- package/dist/handlerReleaseCatalogRoutes.mjs +11 -13
- package/dist/handlerTypes.d.cts +2 -56
- package/dist/handlerTypes.d.mts +2 -56
- package/dist/handlerVersionRoutes.cjs +20 -4
- package/dist/handlerVersionRoutes.d.cts +1 -0
- package/dist/handlerVersionRoutes.d.mts +1 -0
- package/dist/handlerVersionRoutes.mjs +20 -4
- package/dist/index.cjs +4 -7
- package/dist/index.d.cts +10 -9
- package/dist/index.d.mts +10 -9
- package/dist/index.mjs +4 -4
- package/dist/insights/domain.d.cts +53 -70
- package/dist/insights/domain.d.mts +53 -70
- package/dist/insights/errors.cjs +35 -8
- package/dist/insights/errors.mjs +35 -8
- package/dist/insights/eventInput.cjs +64 -24
- package/dist/insights/eventInput.mjs +63 -25
- package/dist/insights/provider.cjs +356 -0
- package/dist/insights/provider.d.cts +6 -0
- package/dist/insights/provider.d.mts +6 -0
- package/dist/insights/provider.mjs +355 -0
- package/dist/insights/queryInput.cjs +78 -43
- package/dist/insights/queryInput.mjs +76 -40
- package/dist/insights/routes.cjs +94 -34
- package/dist/insights/routes.mjs +93 -35
- package/dist/insights/types.d.cts +27 -12
- package/dist/insights/types.d.mts +27 -12
- package/dist/node.d.cts +1 -2
- package/dist/node.d.mts +1 -2
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugins/api-keys/index.cjs +50 -0
- package/dist/plugins/api-keys/index.d.cts +85 -0
- package/dist/plugins/api-keys/index.d.mts +85 -0
- package/dist/plugins/api-keys/index.mjs +47 -0
- package/dist/plugins/api-keys/model.cjs +58 -0
- package/dist/plugins/api-keys/model.d.cts +8 -0
- package/dist/plugins/api-keys/model.d.mts +8 -0
- package/dist/plugins/api-keys/model.mjs +58 -0
- package/dist/plugins/api-keys/schema.cjs +38 -0
- package/dist/plugins/api-keys/schema.d.cts +44 -0
- package/dist/plugins/api-keys/schema.d.mts +44 -0
- package/dist/plugins/api-keys/schema.mjs +39 -0
- package/dist/plugins/builtIn.cjs +7 -0
- package/dist/plugins/builtIn.mjs +6 -0
- package/dist/plugins/definePlugin.cjs +5 -0
- package/dist/plugins/definePlugin.d.cts +73 -0
- package/dist/plugins/definePlugin.d.mts +73 -0
- package/dist/plugins/definePlugin.mjs +5 -0
- package/dist/plugins/index.cjs +17 -0
- package/dist/plugins/index.d.cts +9 -0
- package/dist/plugins/index.d.mts +9 -0
- package/dist/plugins/index.mjs +7 -0
- package/dist/plugins/insights/index.cjs +48 -0
- package/dist/plugins/insights/index.d.cts +295 -0
- package/dist/plugins/insights/index.d.mts +295 -0
- package/dist/plugins/insights/index.mjs +44 -0
- package/dist/plugins/insights/model.cjs +17 -0
- package/dist/plugins/insights/model.d.cts +10 -0
- package/dist/plugins/insights/model.d.mts +10 -0
- package/dist/plugins/insights/model.mjs +17 -0
- package/dist/plugins/insights/reads.cjs +471 -0
- package/dist/plugins/insights/reads.mjs +466 -0
- package/dist/plugins/insights/recordEvent.cjs +135 -0
- package/dist/plugins/insights/recordEvent.d.cts +13 -0
- package/dist/plugins/insights/recordEvent.d.mts +13 -0
- package/dist/plugins/insights/recordEvent.mjs +132 -0
- package/dist/plugins/insights/schema.cjs +347 -0
- package/dist/plugins/insights/schema.d.cts +258 -0
- package/dist/plugins/insights/schema.d.mts +258 -0
- package/dist/plugins/insights/schema.mjs +344 -0
- package/dist/storageAccess.cjs +0 -1
- package/dist/types/index.d.cts +2 -29
- package/dist/types/index.d.mts +2 -29
- package/package.json +30 -7
- package/src/adapters/drizzle.conformance.integration.spec.ts +34 -0
- package/src/adapters/drizzle.readBudgets.integration.spec.ts +41 -0
- package/src/adapters/drizzle.spec.ts +277 -208
- package/src/adapters/drizzle.ts +48 -128
- package/src/adapters/drizzleExecutor.ts +166 -0
- package/src/adapters/kysely.conformance.integration.spec.ts +36 -0
- package/src/adapters/kysely.readBudgets.integration.spec.ts +42 -0
- package/src/adapters/kysely.spec.ts +212 -117
- package/src/adapters/kysely.ts +32 -87
- package/src/adapters/kyselyExecutor.ts +53 -0
- package/src/adapters/mongodb.integration.spec.ts +180 -0
- package/src/adapters/mongodb.readBudgets.integration.spec.ts +61 -0
- package/src/adapters/mongodb.ts +36 -65
- package/src/adapters/mongodbAdapter.ts +293 -0
- package/src/adapters/prisma.conformance.integration.spec.ts +36 -0
- package/src/adapters/prisma.integration.spec.ts +138 -0
- package/src/adapters/prisma.readBudgets.integration.spec.ts +40 -0
- package/src/adapters/prisma.spec.ts +226 -173
- package/src/adapters/prisma.ts +60 -451
- package/src/adapters/prismaExecutor.ts +107 -0
- package/src/adapters/prismaTestClients.ts +175 -0
- package/src/adapters/sqlProviders.ts +14 -0
- package/src/apiKeys.integration.spec.ts +19 -119
- package/src/apiKeys.spec.ts +39 -35
- package/src/apiKeys.ts +2 -8
- package/src/assembly/assemblePlugins.ts +269 -0
- package/src/assembly/assembly.spec.ts +325 -0
- package/src/assembly/assembly.types.spec.ts +155 -0
- package/src/assembly/builtInRoutes.spec.ts +213 -0
- package/src/assembly/databasePlugins.spec.ts +71 -0
- package/src/assembly/databasePlugins.ts +96 -0
- package/src/core/api.ts +139 -0
- package/src/core/baseCandidates.spec.ts +378 -0
- package/src/core/baseCandidates.ts +136 -0
- package/src/core/index.ts +44 -0
- package/src/core/operations.spec.ts +415 -0
- package/src/core/operations.ts +551 -0
- package/src/core/reads.spec.ts +300 -0
- package/src/core/reads.ts +417 -0
- package/src/core/releases.spec.ts +308 -0
- package/src/core/releases.ts +345 -0
- package/src/core/schema.ts +173 -0
- package/src/core/writes.ts +160 -0
- package/src/createHotUpdaterCore.ts +191 -167
- package/src/database/cursor.ts +65 -0
- package/src/database/database.ts +335 -0
- package/src/database/database.types.spec.ts +135 -0
- package/src/database/definitions.ts +72 -0
- package/src/database/engine.ts +62 -0
- package/src/database/engineAggregates.spec.ts +539 -0
- package/src/database/engineAggregates.ts +193 -0
- package/src/database/engineReads.spec.ts +219 -0
- package/src/database/engineReads.ts +302 -0
- package/src/database/engineTransaction.spec.ts +710 -0
- package/src/database/engineTransaction.ts +588 -0
- package/src/database/errors.ts +30 -0
- package/src/database/fence.spec.ts +223 -0
- package/src/database/fence.ts +171 -0
- package/src/database/index.ts +154 -0
- package/src/database/kv/kvAdapter.conformance.integration.spec.ts +17 -0
- package/src/database/kv/kvAdapter.readBudgets.integration.spec.ts +17 -0
- package/src/database/kv/kvAdapter.spec.ts +468 -0
- package/src/database/kv/kvAdapter.ts +450 -0
- package/src/database/kv/kvTestStore.ts +91 -0
- package/src/database/memory.readBudgets.integration.spec.ts +13 -0
- package/src/database/resolveSchema.spec.ts +230 -0
- package/src/database/resolveSchema.ts +372 -0
- package/src/database/schema.ts +169 -0
- package/src/database/schema.types.spec.ts +94 -0
- package/src/database/sql/docker-compose.yml +36 -0
- package/src/database/sql/sqlAdapter.integration.spec.ts +148 -0
- package/src/database/sql/sqlAdapter.readBudgets.integration.spec.ts +109 -0
- package/src/database/sql/sqlAdapter.spec.ts +255 -0
- package/src/database/sql/sqlAdapter.ts +532 -0
- package/src/database/sql/sqlSchema.ts +205 -0
- package/src/database/sql/sqlTestExecutors.ts +183 -0
- package/src/databaseTestSuite.spec.ts +39 -0
- package/src/db/builtInDatabase.ts +149 -0
- package/src/db/bundleRows.spec.ts +3 -3
- package/src/db/createBundleDiff.spec.ts +43 -29
- package/src/db/createBundleDiff.ts +13 -7
- package/src/db/engineDrizzleSchema.ts +72 -0
- package/src/db/engineMigrator.ts +105 -0
- package/src/db/enginePrismaSchema.ts +147 -0
- package/src/db/engineSql.spec.ts +129 -0
- package/src/db/engineSql.ts +48 -0
- package/src/db/engineSqlMigrator.ts +116 -0
- package/src/db/fixedMigratorShared.ts +1 -20
- package/src/db/index.spec.ts +116 -824
- package/src/db/index.ts +43 -14
- package/src/db/pluginTables.spec.ts +218 -0
- package/src/db/releaseCatalog.ts +48 -90
- package/src/db/schemaSettings.ts +104 -0
- package/src/db/settingsMigrator.spec.ts +65 -0
- package/src/db/settingsMigrator.ts +152 -0
- package/src/db/types.ts +25 -165
- package/src/db/updateArtifacts.spec.ts +170 -294
- package/src/db/updateArtifacts.ts +74 -142
- package/src/db/updateCheck.bench.ts +47 -0
- package/src/handler-standalone.integration.spec.ts +204 -412
- package/src/handler.spec.ts +134 -51
- package/src/handler.testFixtures.ts +14 -19
- package/src/handler.ts +163 -75
- package/src/handlerAdminRoutes.spec.ts +183 -0
- package/src/handlerAdminRoutes.ts +536 -0
- package/src/handlerAuth.integration.spec.ts +3 -3
- package/src/handlerManagement.spec.ts +136 -196
- package/src/handlerReleaseCatalogRoutes.ts +15 -17
- package/src/handlerTypes.ts +3 -80
- package/src/handlerVersionRoutes.ts +20 -7
- package/src/index.ts +7 -14
- package/src/insights/domain.ts +56 -77
- package/src/insights/errors.spec.ts +48 -0
- package/src/insights/errors.ts +50 -6
- package/src/insights/eventInput.ts +80 -27
- package/src/insights/insights.integration.spec.ts +525 -44
- package/src/insights/provider.spec.ts +574 -0
- package/src/insights/provider.ts +667 -0
- package/src/insights/queryInput.ts +113 -73
- package/src/insights/routes.ts +125 -69
- package/src/insights/types.ts +47 -36
- package/src/lintRules.spec.ts +76 -0
- package/src/plugins/api-keys/apiKeysPlugin.spec.ts +172 -0
- package/src/plugins/api-keys/index.ts +66 -0
- package/src/plugins/api-keys/model.ts +69 -0
- package/src/plugins/api-keys/schema.ts +22 -0
- package/src/plugins/builtIn.ts +5 -0
- package/src/plugins/definePlugin.ts +100 -0
- package/src/plugins/index.ts +55 -0
- package/src/plugins/insights/index.ts +86 -0
- package/src/plugins/insights/insightsRollout.integration.spec.ts +187 -0
- package/src/plugins/insights/model.spec.ts +66 -0
- package/src/plugins/insights/model.ts +19 -0
- package/src/plugins/insights/reads.spec.ts +725 -0
- package/src/plugins/insights/reads.ts +707 -0
- package/src/plugins/insights/recordEvent.spec.ts +443 -0
- package/src/plugins/insights/recordEvent.ts +238 -0
- package/src/plugins/insights/schema.ts +229 -0
- package/src/plugins/pluginTestHarness.spec.ts +56 -0
- package/src/readBudgets.testFixtures.ts +15 -0
- package/src/releaseCatalogRoutes.integration.spec.ts +47 -92
- package/src/runtime.spec.ts +91 -77
- package/src/runtime.testFixtures.ts +28 -44
- package/src/runtimeBundles.integration.spec.ts +112 -0
- package/src/testUtilsMutation.integration.spec.ts +215 -0
- package/src/testUtilsPackage.integration.spec.ts +176 -0
- package/src/types/index.ts +0 -32
- package/dist/adapters/databaseConstraintErrors.cjs +0 -23
- package/dist/adapters/databaseConstraintErrors.mjs +0 -21
- package/dist/adapters/databasePluginUtils.cjs +0 -117
- package/dist/adapters/databasePluginUtils.mjs +0 -106
- package/dist/adapters/drizzleCrud.cjs +0 -250
- package/dist/adapters/drizzleCrud.mjs +0 -249
- package/dist/adapters/drizzleLazyDB.cjs +0 -101
- package/dist/adapters/drizzleLazyDB.mjs +0 -101
- package/dist/adapters/drizzleQuery.cjs +0 -68
- package/dist/adapters/drizzleQuery.mjs +0 -67
- package/dist/adapters/kyselyCrud.cjs +0 -254
- package/dist/adapters/kyselyCrud.mjs +0 -253
- package/dist/adapters/kyselyQuery.cjs +0 -56
- package/dist/adapters/kyselyQuery.mjs +0 -55
- package/dist/adapters/mongodbCollections.cjs +0 -36
- package/dist/adapters/mongodbCollections.mjs +0 -30
- package/dist/adapters/mongodbQuery.cjs +0 -77
- package/dist/adapters/mongodbQuery.mjs +0 -70
- package/dist/adapters/mongodbReads.cjs +0 -148
- package/dist/adapters/mongodbReads.mjs +0 -147
- package/dist/adapters/mongodbWrites.cjs +0 -134
- package/dist/adapters/mongodbWrites.mjs +0 -133
- package/dist/adapters/prismaQuery.cjs +0 -58
- package/dist/adapters/prismaQuery.mjs +0 -56
- package/dist/adapters/prismaRows.cjs +0 -198
- package/dist/adapters/prismaRows.mjs +0 -188
- package/dist/db/databasePluginCore.cjs +0 -138
- package/dist/db/databasePluginCore.mjs +0 -137
- package/dist/db/fixedMigrator.cjs +0 -79
- package/dist/db/fixedMigrator.mjs +0 -78
- package/dist/db/fixedMigratorMongo.cjs +0 -319
- package/dist/db/fixedMigratorMongo.mjs +0 -319
- package/dist/db/mongoMigrationExecution.cjs +0 -11
- package/dist/db/mongoMigrationExecution.mjs +0 -11
- package/dist/db/schema/mongodb.cjs +0 -25
- package/dist/db/schema/mongodb.mjs +0 -25
- package/dist/db/schema/registry.cjs +0 -21
- package/dist/db/schema/registry.mjs +0 -17
- package/dist/db/schema/sql.cjs +0 -101
- package/dist/db/schema/sql.mjs +0 -97
- package/dist/db/schema/sqlOperations.cjs +0 -27
- package/dist/db/schema/sqlOperations.mjs +0 -26
- package/dist/db/schemaGenerators.cjs +0 -256
- package/dist/db/schemaGenerators.mjs +0 -254
- package/dist/db/schemaReadiness.cjs +0 -24
- package/dist/db/schemaReadiness.d.cts +0 -8
- package/dist/db/schemaReadiness.d.mts +0 -8
- package/dist/db/schemaReadiness.mjs +0 -23
- package/dist/db/sqlMigrationExecution.cjs +0 -67
- package/dist/db/sqlMigrationExecution.mjs +0 -66
- package/dist/handlerBundleRoutes.cjs +0 -155
- package/dist/handlerBundleRoutes.mjs +0 -155
- package/dist/handlerReleaseManagementRoutes.cjs +0 -125
- package/dist/handlerReleaseManagementRoutes.mjs +0 -124
- package/dist/insights/bounded/activeOverview.cjs +0 -87
- package/dist/insights/bounded/activeOverview.mjs +0 -85
- package/dist/insights/bounded/installationSearch.cjs +0 -42
- package/dist/insights/bounded/installationSearch.mjs +0 -42
- package/dist/insights/bounded/persistence.cjs +0 -39
- package/dist/insights/bounded/persistence.mjs +0 -38
- package/dist/insights/bounded/provider.cjs +0 -170
- package/dist/insights/bounded/provider.d.cts +0 -7
- package/dist/insights/bounded/provider.d.mts +0 -7
- package/dist/insights/bounded/provider.mjs +0 -170
- package/dist/insights/bounded/scan.cjs +0 -144
- package/dist/insights/bounded/scan.mjs +0 -138
- package/dist/insights/persistence.d.cts +0 -6
- package/dist/insights/persistence.d.mts +0 -6
- package/dist/schema/dsl.cjs +0 -103
- package/dist/schema/dsl.mjs +0 -87
- package/dist/schema/index.cjs +0 -6
- package/dist/schema/index.mjs +0 -7
- package/dist/schema/settings.cjs +0 -9
- package/dist/schema/settings.mjs +0 -9
- package/dist/schema/types.cjs +0 -8
- package/dist/schema/types.mjs +0 -6
- package/dist/schema/v1_0_0.cjs +0 -364
- package/dist/schema/v1_0_0.mjs +0 -357
- package/src/adapters/databaseConstraintErrors.ts +0 -25
- package/src/adapters/databasePluginTestDatabase.ts +0 -106
- package/src/adapters/databasePluginUtils.spec.ts +0 -29
- package/src/adapters/databasePluginUtils.ts +0 -214
- package/src/adapters/drizzleCrud.ts +0 -419
- package/src/adapters/drizzleLazyDB.ts +0 -257
- package/src/adapters/drizzleQuery.ts +0 -164
- package/src/adapters/kyselyCrud.ts +0 -588
- package/src/adapters/kyselyQuery.ts +0 -128
- package/src/adapters/mongodb.spec.ts +0 -141
- package/src/adapters/mongodbCollections.ts +0 -62
- package/src/adapters/mongodbQuery.ts +0 -226
- package/src/adapters/mongodbReads.ts +0 -311
- package/src/adapters/mongodbRows.spec.ts +0 -64
- package/src/adapters/mongodbRows.ts +0 -118
- package/src/adapters/mongodbTestClient.ts +0 -342
- package/src/adapters/mongodbTestFilter.ts +0 -166
- package/src/adapters/mongodbWrites.ts +0 -260
- package/src/adapters/prismaQuery.ts +0 -129
- package/src/adapters/prismaRows.spec.ts +0 -98
- package/src/adapters/prismaRows.ts +0 -301
- package/src/adapters/prismaTestClient.ts +0 -396
- package/src/calculatePagination.ts +0 -34
- package/src/db/databasePluginCore.spec.ts +0 -62
- package/src/db/databasePluginCore.testFixtures.ts +0 -76
- package/src/db/databasePluginCore.ts +0 -185
- package/src/db/databasePluginUpdateCheck.bench.ts +0 -107
- package/src/db/fixedMigrator.spec.ts +0 -231
- package/src/db/fixedMigrator.ts +0 -147
- package/src/db/fixedMigratorMongo.spec.ts +0 -192
- package/src/db/fixedMigratorMongo.ts +0 -425
- package/src/db/hotUpdaterSchema.ts +0 -5
- package/src/db/mongoMigrationExecution.ts +0 -23
- package/src/db/schema/definitions.ts +0 -1
- package/src/db/schema/mongodb.ts +0 -40
- package/src/db/schema/registry.ts +0 -55
- package/src/db/schema/sql.ts +0 -241
- package/src/db/schema/sqlOperations.ts +0 -63
- package/src/db/schema/types.ts +0 -1
- package/src/db/schemaGenerators.ts +0 -466
- package/src/db/schemaReadiness.ts +0 -34
- package/src/db/sqlMigrationExecution.spec.ts +0 -65
- package/src/db/sqlMigrationExecution.ts +0 -108
- package/src/db/types.spec.ts +0 -55
- package/src/handlerBundleRoutes.ts +0 -259
- package/src/handlerReleaseManagementRoutes.ts +0 -213
- package/src/insights/bounded/activeOverview.spec.ts +0 -189
- package/src/insights/bounded/activeOverview.ts +0 -148
- package/src/insights/bounded/installationSearch.spec.ts +0 -130
- package/src/insights/bounded/installationSearch.ts +0 -69
- package/src/insights/bounded/persistence.ts +0 -43
- package/src/insights/bounded/provider.spec.ts +0 -219
- package/src/insights/bounded/provider.ts +0 -229
- package/src/insights/bounded/scan.ts +0 -235
- package/src/insights/persistence.ts +0 -10
- package/src/schema/dsl-all-versions.spec.ts +0 -35
- package/src/schema/dsl.ts +0 -187
- package/src/schema/index.ts +0 -10
- package/src/schema/settings.ts +0 -15
- package/src/schema/types.ts +0 -79
- package/src/schema/v1_0_0.spec.ts +0 -146
- package/src/schema/v1_0_0.ts +0 -465
package/src/insights/domain.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The body of `POST /events`. Fields the server does not know are ignored, so
|
|
3
|
+
* a newer client's report still records on an older server.
|
|
4
|
+
*/
|
|
1
5
|
export type CreateBundleEventRequestBase = {
|
|
6
|
+
/**
|
|
7
|
+
* The report's idempotency key: a canonical lowercase UUIDv7 that the
|
|
8
|
+
* client creates once per report and repeats on every retry. The server
|
|
9
|
+
* stores the report under it, so a retried report counts once, and a
|
|
10
|
+
* report under an ID already stored changes nothing. Without it, the
|
|
11
|
+
* server creates the ID, and a retry counts as another report.
|
|
12
|
+
*/
|
|
13
|
+
readonly eventId?: string;
|
|
2
14
|
readonly installId: string;
|
|
3
15
|
readonly toBundleId: string;
|
|
4
16
|
readonly userId?: string;
|
|
@@ -15,17 +27,7 @@ export type CreateBundleEventRequestBase = {
|
|
|
15
27
|
|
|
16
28
|
export type CreateBundleEventRequest =
|
|
17
29
|
| (CreateBundleEventRequestBase & {
|
|
18
|
-
readonly type: "UPDATE_APPLIED";
|
|
19
|
-
readonly fromBundleId: string;
|
|
20
|
-
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
21
|
-
})
|
|
22
|
-
| (CreateBundleEventRequestBase & {
|
|
23
|
-
readonly type: "RECOVERED";
|
|
24
|
-
readonly fromBundleId: string;
|
|
25
|
-
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
26
|
-
})
|
|
27
|
-
| (CreateBundleEventRequestBase & {
|
|
28
|
-
readonly type: "RELEASE_ADOPTED";
|
|
30
|
+
readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED";
|
|
29
31
|
readonly fromBundleId: string;
|
|
30
32
|
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
31
33
|
})
|
|
@@ -35,28 +37,20 @@ export type CreateBundleEventRequest =
|
|
|
35
37
|
readonly updateStrategy: null;
|
|
36
38
|
});
|
|
37
39
|
|
|
38
|
-
export type BundleEventSummary = {
|
|
39
|
-
readonly installed: number;
|
|
40
|
-
readonly recovered: number;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export type BundleEventSummaryByBundle = BundleEventSummary & {
|
|
44
|
-
readonly bundleId: string;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export type BundleEventInsightsWindow = "24h" | "7d" | "30d" | "all";
|
|
48
40
|
export type ActiveInstallationWindow = "24h" | "7d" | "30d";
|
|
49
41
|
|
|
50
|
-
export type
|
|
42
|
+
export type EventHistoryRow = {
|
|
43
|
+
readonly id: string;
|
|
51
44
|
readonly installId: string;
|
|
52
|
-
readonly
|
|
53
|
-
|
|
54
|
-
readonly lastKnownBundleId: string;
|
|
55
|
-
readonly latestStatus:
|
|
45
|
+
readonly type:
|
|
46
|
+
| "UPDATE_DOWNLOADED"
|
|
56
47
|
| "UPDATE_APPLIED"
|
|
57
48
|
| "RECOVERED"
|
|
58
|
-
| "RELEASE_ADOPTED"
|
|
59
49
|
| "UNCHANGED";
|
|
50
|
+
readonly fromBundleId: string | null;
|
|
51
|
+
readonly toBundleId: string;
|
|
52
|
+
readonly username: string | null;
|
|
53
|
+
readonly userId: string | null;
|
|
60
54
|
readonly platform: "ios" | "android";
|
|
61
55
|
readonly appVersion: string;
|
|
62
56
|
readonly channel: string;
|
|
@@ -64,13 +58,19 @@ export type InstallationSearchRow = {
|
|
|
64
58
|
readonly receivedAtMs: number;
|
|
65
59
|
};
|
|
66
60
|
|
|
67
|
-
export type InstallationHistoryRow = {
|
|
68
|
-
readonly
|
|
69
|
-
readonly type: "UPDATE_APPLIED" | "RECOVERED";
|
|
61
|
+
export type InstallationHistoryRow = EventHistoryRow & {
|
|
62
|
+
readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED";
|
|
70
63
|
readonly fromBundleId: string;
|
|
71
|
-
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type InstallationRow = {
|
|
67
|
+
readonly installId: string;
|
|
72
68
|
readonly username: string | null;
|
|
73
69
|
readonly userId: string | null;
|
|
70
|
+
readonly lastKnownBundleId: string;
|
|
71
|
+
readonly pendingBundleId: string | null;
|
|
72
|
+
readonly pendingReleaseId: string | null;
|
|
73
|
+
readonly latestStatus: EventHistoryRow["type"];
|
|
74
74
|
readonly platform: "ios" | "android";
|
|
75
75
|
readonly appVersion: string;
|
|
76
76
|
readonly channel: string;
|
|
@@ -78,62 +78,41 @@ export type InstallationHistoryRow = {
|
|
|
78
78
|
readonly receivedAtMs: number;
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
export type
|
|
82
|
-
readonly data: readonly
|
|
83
|
-
readonly
|
|
84
|
-
readonly total: number;
|
|
85
|
-
readonly limit: number;
|
|
86
|
-
readonly offset: number;
|
|
87
|
-
};
|
|
81
|
+
export type CursorPage<T> = {
|
|
82
|
+
readonly data: readonly T[];
|
|
83
|
+
readonly nextCursor: string | null;
|
|
88
84
|
};
|
|
89
85
|
|
|
90
|
-
export type
|
|
91
|
-
readonly
|
|
92
|
-
readonly value: number;
|
|
86
|
+
export type EventCursorPage<T extends EventHistoryRow> = CursorPage<T> & {
|
|
87
|
+
readonly beforeReceivedAtMs: number;
|
|
93
88
|
};
|
|
94
89
|
|
|
95
|
-
export type
|
|
96
|
-
readonly
|
|
97
|
-
readonly
|
|
90
|
+
export type InsightsScope = {
|
|
91
|
+
readonly platform: "ios" | "android";
|
|
92
|
+
readonly channel: string;
|
|
98
93
|
};
|
|
99
94
|
|
|
100
|
-
export type
|
|
101
|
-
readonly
|
|
102
|
-
readonly
|
|
103
|
-
readonly installed: readonly InsightsSeriesPoint[];
|
|
104
|
-
readonly recovered: readonly InsightsSeriesPoint[];
|
|
105
|
-
};
|
|
106
|
-
readonly cohorts: {
|
|
107
|
-
readonly installed: readonly InsightsCohortPoint[];
|
|
108
|
-
readonly recovered: readonly InsightsCohortPoint[];
|
|
109
|
-
};
|
|
110
|
-
readonly recentEvents: OffsetPaginationResult<InstallationHistoryRow>;
|
|
95
|
+
export type InsightsBundleSelection = InsightsScope & {
|
|
96
|
+
readonly bundleId: string;
|
|
97
|
+
readonly outcome: "downloaded" | "applied" | "recovered" | "unchanged";
|
|
111
98
|
};
|
|
112
99
|
|
|
113
|
-
export type
|
|
114
|
-
readonly
|
|
115
|
-
readonly
|
|
116
|
-
readonly bundleId: string;
|
|
117
|
-
readonly installations: number;
|
|
118
|
-
}[];
|
|
100
|
+
export type InsightsCountMeasurement = {
|
|
101
|
+
readonly count: number;
|
|
102
|
+
readonly measuredAtMs: number;
|
|
119
103
|
};
|
|
120
104
|
|
|
121
|
-
export type
|
|
122
|
-
readonly asOfMs: number;
|
|
105
|
+
export type ReportingOverview = InsightsScope & {
|
|
123
106
|
readonly window: ActiveInstallationWindow;
|
|
124
|
-
readonly
|
|
125
|
-
readonly
|
|
126
|
-
readonly
|
|
127
|
-
|
|
128
|
-
readonly series: readonly InsightsSeriesPoint[];
|
|
129
|
-
}[];
|
|
130
|
-
readonly bundles: readonly {
|
|
107
|
+
readonly sinceMs: number;
|
|
108
|
+
readonly beforeReceivedAtMs: number;
|
|
109
|
+
readonly reportingInstallations: InsightsCountMeasurement;
|
|
110
|
+
readonly bundle?: {
|
|
131
111
|
readonly bundleId: string;
|
|
132
|
-
readonly
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
readonly userId?: string;
|
|
112
|
+
readonly reportingInstallations: InsightsCountMeasurement;
|
|
113
|
+
readonly downloadedReports: InsightsCountMeasurement;
|
|
114
|
+
readonly appliedReports: InsightsCountMeasurement;
|
|
115
|
+
readonly recoveredReports: InsightsCountMeasurement;
|
|
116
|
+
readonly unchangedReports: InsightsCountMeasurement;
|
|
117
|
+
};
|
|
139
118
|
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
DatabaseConflictError,
|
|
5
|
+
DatabaseTransactionError,
|
|
6
|
+
} from "../database/errors";
|
|
7
|
+
import { isDatabaseBusyError } from "./errors";
|
|
8
|
+
|
|
9
|
+
const failure = (message: string, fields: object) =>
|
|
10
|
+
Object.assign(new Error(message), fields);
|
|
11
|
+
|
|
12
|
+
describe("isDatabaseBusyError", () => {
|
|
13
|
+
it.each([
|
|
14
|
+
[
|
|
15
|
+
"a transaction out of retries",
|
|
16
|
+
new DatabaseConflictError("The transaction conflicted 8 times."),
|
|
17
|
+
],
|
|
18
|
+
[
|
|
19
|
+
"a throttled DynamoDB read",
|
|
20
|
+
failure("Throughput exceeds the current capacity of your table.", {
|
|
21
|
+
name: "ProvisionedThroughputExceededException",
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
24
|
+
["an HTTP 429", failure("Too Many Requests", { status: 429 })],
|
|
25
|
+
[
|
|
26
|
+
"an AWS SDK 429",
|
|
27
|
+
failure("Too Many Requests", { $metadata: { httpStatusCode: 429 } }),
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
"Firestore's RESOURCE_EXHAUSTED",
|
|
31
|
+
failure("8 RESOURCE_EXHAUSTED: Quota exceeded.", { code: 8 }),
|
|
32
|
+
],
|
|
33
|
+
])("holds for %s", (_case, error) => {
|
|
34
|
+
expect(isDatabaseBusyError(error)).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it.each([
|
|
38
|
+
["a gauge below zero", new DatabaseTransactionError("gauge below zero")],
|
|
39
|
+
["MongoDB's unknown error, also code 8", failure("unknown", { code: 8 })],
|
|
40
|
+
[
|
|
41
|
+
"a refused connection",
|
|
42
|
+
failure("connect ECONNREFUSED", { code: "ECONNREFUSED" }),
|
|
43
|
+
],
|
|
44
|
+
["a thrown string", "busy"],
|
|
45
|
+
])("does not hold for %s", (_case, error) => {
|
|
46
|
+
expect(isDatabaseBusyError(error)).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
});
|
package/src/insights/errors.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
constructor(readonly limit: number) {
|
|
3
|
-
super(`Insights event scan exceeded ${limit} rows.`);
|
|
4
|
-
this.name = "InsightsScanLimitExceededError";
|
|
5
|
-
}
|
|
6
|
-
}
|
|
1
|
+
import { DatabaseConflictError } from "../database/errors";
|
|
7
2
|
|
|
8
3
|
export class InsightsBadRequestError extends Error {
|
|
9
4
|
readonly name = "InsightsBadRequestError";
|
|
@@ -16,3 +11,52 @@ export class InsightsPayloadTooLargeError extends Error {
|
|
|
16
11
|
super(`Event payload exceeds ${maximumBytes} bytes`);
|
|
17
12
|
}
|
|
18
13
|
}
|
|
14
|
+
|
|
15
|
+
/** Error names the AWS SDKs give a throttled request, as their retry strategy classifies them. */
|
|
16
|
+
const THROTTLING_NAMES = new Set([
|
|
17
|
+
"ProvisionedThroughputExceededException",
|
|
18
|
+
"RequestLimitExceeded",
|
|
19
|
+
"RequestThrottled",
|
|
20
|
+
"RequestThrottledException",
|
|
21
|
+
"SlowDown",
|
|
22
|
+
"ThrottledException",
|
|
23
|
+
"Throttling",
|
|
24
|
+
"ThrottlingException",
|
|
25
|
+
"TooManyRequestsException",
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
/** gRPC's RESOURCE_EXHAUSTED, the status Firestore throttles a request with. */
|
|
29
|
+
const RESOURCE_EXHAUSTED = 8;
|
|
30
|
+
|
|
31
|
+
interface ErrorFields {
|
|
32
|
+
readonly name?: unknown;
|
|
33
|
+
readonly code?: unknown;
|
|
34
|
+
readonly message?: unknown;
|
|
35
|
+
readonly status?: unknown;
|
|
36
|
+
readonly statusCode?: unknown;
|
|
37
|
+
readonly $metadata?: { readonly httpStatusCode?: unknown };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Whether the database is busy rather than broken, so the same request can
|
|
42
|
+
* succeed later: a transaction ran out of retries, or the backend throttled
|
|
43
|
+
* a request. Writes already retry transient failures, throttled ones
|
|
44
|
+
* included, until the budget runs out. A throttled read throws the backend's
|
|
45
|
+
* own error, so it is recognized by what the backends call it: a name the
|
|
46
|
+
* AWS SDKs retry as throttling, HTTP 429, or gRPC's RESOURCE_EXHAUSTED.
|
|
47
|
+
*/
|
|
48
|
+
export const isDatabaseBusyError = (error: unknown): boolean => {
|
|
49
|
+
if (error instanceof DatabaseConflictError) return true;
|
|
50
|
+
if (typeof error !== "object" || error === null) return false;
|
|
51
|
+
const { name, code, message, status, statusCode, $metadata } =
|
|
52
|
+
error as ErrorFields;
|
|
53
|
+
return (
|
|
54
|
+
(typeof name === "string" && THROTTLING_NAMES.has(name)) ||
|
|
55
|
+
[status, statusCode, $metadata?.httpStatusCode].includes(429) ||
|
|
56
|
+
// A gRPC error's message starts with its status name; other drivers use
|
|
57
|
+
// numeric codes too, such as MongoDB's 8 for an unknown error.
|
|
58
|
+
(code === RESOURCE_EXHAUSTED &&
|
|
59
|
+
typeof message === "string" &&
|
|
60
|
+
message.includes("RESOURCE_EXHAUSTED"))
|
|
61
|
+
);
|
|
62
|
+
};
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createUUIDv7,
|
|
3
|
+
isUUIDv7,
|
|
4
|
+
type BundleEventRow,
|
|
5
|
+
} from "@hot-updater/plugin-core";
|
|
6
|
+
|
|
1
7
|
import type {
|
|
2
8
|
CreateBundleEventRequest,
|
|
3
9
|
CreateBundleEventRequestBase,
|
|
@@ -8,26 +14,9 @@ import {
|
|
|
8
14
|
} from "./errors";
|
|
9
15
|
|
|
10
16
|
const MAX_EVENT_STRING_LENGTH = 1_024;
|
|
17
|
+
const MAX_IDENTITY_LENGTH = 255;
|
|
11
18
|
export const EVENT_BODY_MAX_BYTES = 16 * 1_024;
|
|
12
19
|
|
|
13
|
-
const eventKeys = new Set([
|
|
14
|
-
"type",
|
|
15
|
-
"installId",
|
|
16
|
-
"toBundleId",
|
|
17
|
-
"userId",
|
|
18
|
-
"username",
|
|
19
|
-
"platform",
|
|
20
|
-
"appVersion",
|
|
21
|
-
"channel",
|
|
22
|
-
"cohort",
|
|
23
|
-
"fingerprintHash",
|
|
24
|
-
"fromBundleId",
|
|
25
|
-
"fromReleaseId",
|
|
26
|
-
"toReleaseId",
|
|
27
|
-
"updateStrategy",
|
|
28
|
-
"sdkVersion",
|
|
29
|
-
]);
|
|
30
|
-
|
|
31
20
|
function isRecord(value: unknown): value is Readonly<Record<string, unknown>> {
|
|
32
21
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
33
22
|
}
|
|
@@ -40,7 +29,10 @@ function requireStringField(
|
|
|
40
29
|
if (
|
|
41
30
|
typeof value !== "string" ||
|
|
42
31
|
value.length === 0 ||
|
|
43
|
-
value.length > MAX_EVENT_STRING_LENGTH
|
|
32
|
+
value.length > MAX_EVENT_STRING_LENGTH ||
|
|
33
|
+
new TextDecoder("utf-8", { ignoreBOM: true }).decode(
|
|
34
|
+
new TextEncoder().encode(value),
|
|
35
|
+
) !== value
|
|
44
36
|
) {
|
|
45
37
|
throw new InsightsBadRequestError(`Invalid event field: ${key}`);
|
|
46
38
|
}
|
|
@@ -55,6 +47,32 @@ function requireNullableStringField(
|
|
|
55
47
|
return requireStringField(payload, key);
|
|
56
48
|
}
|
|
57
49
|
|
|
50
|
+
function requireIdentityField(
|
|
51
|
+
payload: Readonly<Record<string, unknown>>,
|
|
52
|
+
key: "installId" | "userId",
|
|
53
|
+
): string {
|
|
54
|
+
const value = requireStringField(payload, key);
|
|
55
|
+
if (value.length > MAX_IDENTITY_LENGTH) {
|
|
56
|
+
throw new InsightsBadRequestError(`Invalid event field: ${key}`);
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The report's idempotency key, when the client sends one: it creates the
|
|
63
|
+
* UUIDv7 once and repeats it on every retry of that report.
|
|
64
|
+
*/
|
|
65
|
+
function readEventId(
|
|
66
|
+
payload: Readonly<Record<string, unknown>>,
|
|
67
|
+
): string | undefined {
|
|
68
|
+
const value = payload.eventId;
|
|
69
|
+
if (value === undefined) return undefined;
|
|
70
|
+
if (!isUUIDv7(value)) {
|
|
71
|
+
throw new InsightsBadRequestError("Invalid event field: eventId");
|
|
72
|
+
}
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
75
|
+
|
|
58
76
|
async function readBoundedText(request: Request): Promise<string> {
|
|
59
77
|
const contentLength = request.headers.get("content-length");
|
|
60
78
|
const declaredByteLength = Number(contentLength);
|
|
@@ -96,22 +114,23 @@ async function parseJson(request: Request): Promise<unknown> {
|
|
|
96
114
|
}
|
|
97
115
|
|
|
98
116
|
function requireEvent(payload: unknown): CreateBundleEventRequest {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
) {
|
|
117
|
+
// Fields this server does not know are ignored, not refused, so a report
|
|
118
|
+
// from a newer SDK that adds one still records on an older server.
|
|
119
|
+
if (!isRecord(payload)) {
|
|
103
120
|
throw new InsightsBadRequestError("Invalid event payload");
|
|
104
121
|
}
|
|
105
122
|
const platform = requireStringField(payload, "platform");
|
|
106
123
|
if (platform !== "ios" && platform !== "android") {
|
|
107
124
|
throw new InsightsBadRequestError("Invalid event field: platform");
|
|
108
125
|
}
|
|
126
|
+
const eventId = readEventId(payload);
|
|
109
127
|
const base: CreateBundleEventRequestBase = {
|
|
110
|
-
|
|
128
|
+
...(eventId === undefined ? {} : { eventId }),
|
|
129
|
+
installId: requireIdentityField(payload, "installId"),
|
|
111
130
|
toBundleId: requireStringField(payload, "toBundleId"),
|
|
112
131
|
...(payload.userId === undefined
|
|
113
132
|
? {}
|
|
114
|
-
: { userId:
|
|
133
|
+
: { userId: requireIdentityField(payload, "userId") }),
|
|
115
134
|
...(payload.username === undefined
|
|
116
135
|
? {}
|
|
117
136
|
: { username: requireStringField(payload, "username") }),
|
|
@@ -129,9 +148,9 @@ function requireEvent(payload: unknown): CreateBundleEventRequest {
|
|
|
129
148
|
};
|
|
130
149
|
const type = requireStringField(payload, "type");
|
|
131
150
|
switch (type) {
|
|
151
|
+
case "UPDATE_DOWNLOADED":
|
|
132
152
|
case "UPDATE_APPLIED":
|
|
133
|
-
case "RECOVERED":
|
|
134
|
-
case "RELEASE_ADOPTED": {
|
|
153
|
+
case "RECOVERED": {
|
|
135
154
|
const updateStrategy = requireStringField(payload, "updateStrategy");
|
|
136
155
|
if (updateStrategy !== "fingerprint" && updateStrategy !== "appVersion") {
|
|
137
156
|
throw new InsightsBadRequestError(
|
|
@@ -166,3 +185,37 @@ export async function parseBundleEventRequest(
|
|
|
166
185
|
const payload = await parseJson(request);
|
|
167
186
|
return requireEvent(payload);
|
|
168
187
|
}
|
|
188
|
+
|
|
189
|
+
export function createBundleEventRow(
|
|
190
|
+
input: CreateBundleEventRequest,
|
|
191
|
+
): BundleEventRow {
|
|
192
|
+
input = requireEvent(input);
|
|
193
|
+
const base = {
|
|
194
|
+
app_version: input.appVersion,
|
|
195
|
+
channel: input.channel,
|
|
196
|
+
from_release_id: input.fromReleaseId,
|
|
197
|
+
// The client's ID makes a retried report the same row, which records once.
|
|
198
|
+
id: input.eventId ?? createUUIDv7(),
|
|
199
|
+
install_id: input.installId,
|
|
200
|
+
platform: input.platform,
|
|
201
|
+
received_at_ms: Date.now(),
|
|
202
|
+
to_bundle_id: input.toBundleId,
|
|
203
|
+
to_release_id: input.toReleaseId,
|
|
204
|
+
user_id: input.userId ?? null,
|
|
205
|
+
metadata: {
|
|
206
|
+
cohort: input.cohort,
|
|
207
|
+
fingerprint_hash: input.fingerprintHash,
|
|
208
|
+
sdk_version: input.sdkVersion ?? null,
|
|
209
|
+
username: input.username ?? null,
|
|
210
|
+
update_strategy: input.updateStrategy,
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
switch (input.type) {
|
|
214
|
+
case "UPDATE_DOWNLOADED":
|
|
215
|
+
case "UPDATE_APPLIED":
|
|
216
|
+
case "RECOVERED":
|
|
217
|
+
return { ...base, from_bundle_id: input.fromBundleId, type: input.type };
|
|
218
|
+
case "UNCHANGED":
|
|
219
|
+
return { ...base, from_bundle_id: null, type: input.type };
|
|
220
|
+
}
|
|
221
|
+
}
|