@hot-updater/server 1.0.0-rc.18 → 1.0.0-rc.21
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/LICENSE +12 -14
- package/dist/adapters/drizzle.cjs +6 -8
- package/dist/adapters/drizzle.d.cts +2 -2
- package/dist/adapters/drizzle.d.mts +2 -2
- package/dist/adapters/drizzle.mjs +1 -3
- package/dist/adapters/drizzleExecutor.d.cts +1 -1
- package/dist/adapters/drizzleExecutor.d.mts +1 -1
- package/dist/adapters/kysely.cjs +4 -6
- package/dist/adapters/kysely.d.cts +3 -3
- package/dist/adapters/kysely.d.mts +3 -3
- package/dist/adapters/kysely.mjs +1 -3
- package/dist/adapters/kyselyExecutor.d.cts +1 -2
- package/dist/adapters/kyselyExecutor.d.mts +1 -2
- package/dist/adapters/mongodb.cjs +10 -21
- package/dist/adapters/mongodb.d.cts +1 -1
- package/dist/adapters/mongodb.d.mts +1 -1
- package/dist/adapters/mongodb.mjs +9 -20
- package/dist/adapters/mongodbAdapter.cjs +11 -11
- package/dist/adapters/mongodbAdapter.d.cts +1 -1
- package/dist/adapters/mongodbAdapter.d.mts +1 -1
- package/dist/adapters/mongodbAdapter.mjs +1 -1
- package/dist/adapters/prisma.cjs +7 -9
- package/dist/adapters/prisma.d.cts +1 -1
- package/dist/adapters/prisma.d.mts +1 -1
- package/dist/adapters/prisma.mjs +1 -3
- package/dist/adapters/prismaExecutor.cjs +2 -3
- package/dist/adapters/prismaExecutor.mjs +1 -2
- package/dist/adapters/sqlProviders.cjs +7 -2
- package/dist/adapters/sqlProviders.mjs +6 -1
- package/dist/assembly/assemblePlugins.cjs +26 -48
- package/dist/assembly/assemblePlugins.d.cts +2 -5
- package/dist/assembly/assemblePlugins.d.mts +2 -5
- package/dist/assembly/assemblePlugins.mjs +19 -45
- package/dist/assembly/clientPlugins.cjs +6 -4
- package/dist/assembly/clientPlugins.mjs +2 -0
- package/dist/assembly/configError.d.cts +1 -6
- package/dist/assembly/configError.d.mts +1 -6
- package/dist/assembly/configError.mjs +1 -6
- package/dist/core/api.cjs +0 -40
- package/dist/core/api.d.cts +5 -16
- package/dist/core/api.d.mts +5 -16
- package/dist/core/api.mjs +1 -37
- package/dist/core/baseCandidates.cjs +0 -43
- package/dist/core/baseCandidates.mjs +2 -43
- package/dist/core/operations.cjs +13 -12
- package/dist/core/operations.mjs +6 -5
- package/dist/core/reads.cjs +4 -4
- package/dist/core/reads.d.cts +2 -41
- package/dist/core/reads.d.mts +2 -41
- package/dist/core/reads.mjs +3 -3
- package/dist/core/releases.cjs +6 -6
- package/dist/core/releases.mjs +1 -1
- package/dist/core/writes.cjs +2 -2
- package/dist/core/writes.mjs +1 -1
- package/dist/createHotUpdaterCore.cjs +39 -39
- package/dist/createHotUpdaterCore.d.cts +61 -8
- package/dist/createHotUpdaterCore.d.mts +61 -8
- package/dist/createHotUpdaterCore.mjs +35 -32
- package/dist/db/engineDrizzleSchema.cjs +3 -4
- package/dist/db/engineDrizzleSchema.mjs +1 -2
- package/dist/db/enginePrismaSchema.cjs +4 -5
- package/dist/db/enginePrismaSchema.d.cts +1 -1
- package/dist/db/enginePrismaSchema.d.mts +1 -1
- package/dist/db/enginePrismaSchema.mjs +1 -2
- package/dist/db/releaseCatalog.cjs +6 -6
- package/dist/db/releaseCatalog.mjs +1 -1
- package/dist/db/updateArtifacts.cjs +6 -6
- package/dist/db/updateArtifacts.mjs +1 -1
- package/dist/handler.cjs +3 -4
- package/dist/handler.mjs +1 -1
- package/dist/handlerAdminRoutes.cjs +1 -2
- package/dist/handlerAdminRoutes.mjs +1 -2
- package/dist/handlerVersionRoutes.cjs +2 -2
- package/dist/handlerVersionRoutes.mjs +2 -2
- package/dist/index.cjs +9 -2
- package/dist/index.d.cts +4 -3
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +2 -1
- package/dist/node.cjs +3 -6
- package/dist/node.d.cts +3 -3
- package/dist/node.d.mts +3 -3
- package/dist/node.mjs +4 -4
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugins/api-keys/index.cjs +8 -52
- package/dist/plugins/api-keys/index.d.cts +1 -84
- package/dist/plugins/api-keys/index.d.mts +1 -84
- package/dist/plugins/api-keys/index.mjs +2 -49
- package/dist/plugins/definePlugin.d.cts +2 -200
- package/dist/plugins/definePlugin.d.mts +2 -200
- package/dist/plugins/insights/index.cjs +7 -126
- package/dist/plugins/insights/index.d.cts +1 -398
- package/dist/plugins/insights/index.d.mts +1 -398
- package/dist/plugins/insights/index.mjs +2 -121
- package/dist/plugins/official.cjs +30 -0
- package/dist/plugins/official.mjs +29 -0
- package/dist/storageAccess.cjs +13 -10
- package/dist/storageAccess.mjs +13 -10
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.mts +1 -1
- package/package.json +15 -37
- package/dist/_virtual/_rolldown/runtime.cjs +0 -23
- package/dist/assembly/clientPlugins.d.cts +0 -16
- package/dist/assembly/clientPlugins.d.mts +0 -16
- package/dist/assembly/configError.cjs +0 -7
- package/dist/assembly/databasePlugins.cjs +0 -27
- package/dist/assembly/databasePlugins.d.cts +0 -43
- package/dist/assembly/databasePlugins.d.mts +0 -43
- package/dist/assembly/databasePlugins.mjs +0 -26
- package/dist/assembly/pluginCli.cjs +0 -125
- package/dist/assembly/pluginCli.d.cts +0 -59
- package/dist/assembly/pluginCli.d.mts +0 -59
- package/dist/assembly/pluginCli.mjs +0 -121
- package/dist/core/baseCandidates.d.cts +0 -17
- package/dist/core/baseCandidates.d.mts +0 -17
- package/dist/core/schema.cjs +0 -279
- package/dist/core/schema.d.cts +0 -307
- package/dist/core/schema.d.mts +0 -307
- package/dist/core/schema.mjs +0 -277
- package/dist/database/aggregateBatching.cjs +0 -626
- package/dist/database/aggregateBatching.d.cts +0 -10
- package/dist/database/aggregateBatching.d.mts +0 -10
- package/dist/database/aggregateBatching.mjs +0 -625
- package/dist/database/busy.cjs +0 -36
- package/dist/database/busy.d.cts +0 -12
- package/dist/database/busy.d.mts +0 -12
- package/dist/database/busy.mjs +0 -36
- package/dist/database/cursor.cjs +0 -44
- package/dist/database/cursor.d.cts +0 -7
- package/dist/database/cursor.d.mts +0 -7
- package/dist/database/cursor.mjs +0 -40
- package/dist/database/database.cjs +0 -63
- package/dist/database/database.d.cts +0 -136
- package/dist/database/database.d.mts +0 -136
- package/dist/database/database.mjs +0 -63
- package/dist/database/definitions.d.cts +0 -78
- package/dist/database/definitions.d.mts +0 -78
- package/dist/database/engine.cjs +0 -37
- package/dist/database/engine.d.cts +0 -41
- package/dist/database/engine.d.mts +0 -41
- package/dist/database/engine.mjs +0 -37
- package/dist/database/engineAggregates.cjs +0 -118
- package/dist/database/engineAggregates.mjs +0 -115
- package/dist/database/engineReads.cjs +0 -182
- package/dist/database/engineReads.d.cts +0 -35
- package/dist/database/engineReads.d.mts +0 -35
- package/dist/database/engineReads.mjs +0 -181
- package/dist/database/engineTransaction.cjs +0 -399
- package/dist/database/engineTransaction.d.cts +0 -26
- package/dist/database/engineTransaction.d.mts +0 -26
- package/dist/database/engineTransaction.mjs +0 -398
- package/dist/database/errors.cjs +0 -27
- package/dist/database/errors.d.cts +0 -21
- package/dist/database/errors.d.mts +0 -21
- package/dist/database/errors.mjs +0 -24
- package/dist/database/fence.cjs +0 -125
- package/dist/database/fence.d.cts +0 -42
- package/dist/database/fence.d.mts +0 -42
- package/dist/database/fence.mjs +0 -117
- package/dist/database/index.cjs +0 -136
- package/dist/database/index.d.cts +0 -18
- package/dist/database/index.d.mts +0 -18
- package/dist/database/index.mjs +0 -16
- package/dist/database/kv/kvAdapter.cjs +0 -285
- package/dist/database/kv/kvAdapter.d.cts +0 -109
- package/dist/database/kv/kvAdapter.d.mts +0 -109
- package/dist/database/kv/kvAdapter.mjs +0 -284
- package/dist/database/resolveSchema.cjs +0 -199
- package/dist/database/resolveSchema.d.cts +0 -42
- package/dist/database/resolveSchema.d.mts +0 -42
- package/dist/database/resolveSchema.mjs +0 -196
- package/dist/database/retention.cjs +0 -92
- package/dist/database/retention.mjs +0 -90
- package/dist/database/schema.cjs +0 -24
- package/dist/database/schema.d.cts +0 -90
- package/dist/database/schema.d.mts +0 -90
- package/dist/database/schema.mjs +0 -23
- package/dist/database/sql/sqlAdapter.cjs +0 -290
- package/dist/database/sql/sqlAdapter.d.cts +0 -46
- package/dist/database/sql/sqlAdapter.d.mts +0 -46
- package/dist/database/sql/sqlAdapter.mjs +0 -287
- package/dist/database/sql/sqlSchema.cjs +0 -171
- package/dist/database/sql/sqlSchema.d.cts +0 -8
- package/dist/database/sql/sqlSchema.d.mts +0 -8
- package/dist/database/sql/sqlSchema.mjs +0 -165
- package/dist/db/coreDatabase.cjs +0 -85
- package/dist/db/coreDatabase.d.cts +0 -57
- package/dist/db/coreDatabase.d.mts +0 -57
- package/dist/db/coreDatabase.mjs +0 -78
- package/dist/db/createBundleDiff.cjs +0 -144
- package/dist/db/createBundleDiff.d.cts +0 -17
- package/dist/db/createBundleDiff.d.mts +0 -17
- package/dist/db/createBundleDiff.mjs +0 -141
- package/dist/db/engineMigrator.cjs +0 -53
- package/dist/db/engineMigrator.mjs +0 -53
- package/dist/db/engineSql.cjs +0 -26
- package/dist/db/engineSql.d.cts +0 -17
- package/dist/db/engineSql.d.mts +0 -17
- package/dist/db/engineSql.mjs +0 -25
- package/dist/db/engineSqlMigrator.cjs +0 -66
- package/dist/db/engineSqlMigrator.mjs +0 -66
- package/dist/db/fixedMigratorShared.cjs +0 -12
- package/dist/db/fixedMigratorShared.mjs +0 -11
- package/dist/db/index.cjs +0 -50
- package/dist/db/index.d.cts +0 -23
- package/dist/db/index.d.mts +0 -23
- package/dist/db/index.mjs +0 -33
- package/dist/db/releaseCatalog.d.cts +0 -16
- package/dist/db/releaseCatalog.d.mts +0 -16
- package/dist/db/schemaSettings.cjs +0 -63
- package/dist/db/schemaSettings.d.cts +0 -12
- package/dist/db/schemaSettings.d.mts +0 -12
- package/dist/db/schemaSettings.mjs +0 -62
- package/dist/db/settingsMigrator.cjs +0 -92
- package/dist/db/settingsMigrator.mjs +0 -89
- package/dist/db/types.cjs +0 -11
- package/dist/db/types.d.cts +0 -78
- package/dist/db/types.d.mts +0 -78
- package/dist/db/types.mjs +0 -10
- package/dist/diff.cjs +0 -3
- package/dist/diff.d.cts +0 -2
- package/dist/diff.d.mts +0 -2
- package/dist/diff.mjs +0 -2
- package/dist/plugins/api-keys/apiKeys.cjs +0 -139
- package/dist/plugins/api-keys/apiKeys.d.cts +0 -27
- package/dist/plugins/api-keys/apiKeys.d.mts +0 -27
- package/dist/plugins/api-keys/apiKeys.mjs +0 -129
- package/dist/plugins/api-keys/cli.cjs +0 -115
- package/dist/plugins/api-keys/cli.mjs +0 -114
- package/dist/plugins/api-keys/model.cjs +0 -58
- package/dist/plugins/api-keys/model.d.cts +0 -26
- package/dist/plugins/api-keys/model.d.mts +0 -26
- package/dist/plugins/api-keys/model.mjs +0 -58
- package/dist/plugins/api-keys/schema.cjs +0 -38
- package/dist/plugins/api-keys/schema.d.cts +0 -44
- package/dist/plugins/api-keys/schema.d.mts +0 -44
- package/dist/plugins/api-keys/schema.mjs +0 -39
- package/dist/plugins/definePlugin.cjs +0 -5
- package/dist/plugins/definePlugin.mjs +0 -5
- package/dist/plugins/index.cjs +0 -38
- package/dist/plugins/index.d.cts +0 -12
- package/dist/plugins/index.d.mts +0 -12
- package/dist/plugins/index.mjs +0 -9
- package/dist/plugins/insights/contract.cjs +0 -193
- package/dist/plugins/insights/contract.mjs +0 -189
- package/dist/plugins/insights/domain.d.cts +0 -149
- package/dist/plugins/insights/domain.d.mts +0 -149
- package/dist/plugins/insights/errors.cjs +0 -15
- package/dist/plugins/insights/errors.mjs +0 -14
- package/dist/plugins/insights/eventInput.cjs +0 -284
- package/dist/plugins/insights/eventInput.mjs +0 -282
- package/dist/plugins/insights/eventRow.cjs +0 -49
- package/dist/plugins/insights/eventRow.d.cts +0 -64
- package/dist/plugins/insights/eventRow.d.mts +0 -64
- package/dist/plugins/insights/eventRow.mjs +0 -47
- package/dist/plugins/insights/model.cjs +0 -17
- package/dist/plugins/insights/model.d.cts +0 -10
- package/dist/plugins/insights/model.d.mts +0 -10
- package/dist/plugins/insights/model.mjs +0 -17
- package/dist/plugins/insights/modelTypes.d.cts +0 -176
- package/dist/plugins/insights/modelTypes.d.mts +0 -176
- package/dist/plugins/insights/overview.cjs +0 -109
- package/dist/plugins/insights/overview.d.cts +0 -15
- package/dist/plugins/insights/overview.d.mts +0 -15
- package/dist/plugins/insights/overview.mjs +0 -107
- package/dist/plugins/insights/provider.cjs +0 -375
- package/dist/plugins/insights/provider.d.cts +0 -6
- package/dist/plugins/insights/provider.d.mts +0 -6
- package/dist/plugins/insights/provider.mjs +0 -374
- package/dist/plugins/insights/queryInput.cjs +0 -93
- package/dist/plugins/insights/queryInput.mjs +0 -91
- package/dist/plugins/insights/reads.cjs +0 -681
- package/dist/plugins/insights/reads.d.cts +0 -61
- package/dist/plugins/insights/reads.d.mts +0 -61
- package/dist/plugins/insights/reads.mjs +0 -674
- package/dist/plugins/insights/recordEvent.cjs +0 -319
- package/dist/plugins/insights/recordEvent.d.cts +0 -18
- package/dist/plugins/insights/recordEvent.d.mts +0 -18
- package/dist/plugins/insights/recordEvent.mjs +0 -316
- package/dist/plugins/insights/routes.cjs +0 -96
- package/dist/plugins/insights/routes.mjs +0 -95
- package/dist/plugins/insights/schema.cjs +0 -489
- package/dist/plugins/insights/schema.d.cts +0 -698
- package/dist/plugins/insights/schema.d.mts +0 -698
- package/dist/plugins/insights/schema.mjs +0 -483
- package/dist/plugins/insights/testing/eventRow.d.mts +0 -64
- package/dist/plugins/insights/testing/expectInsightsIndex.mjs +0 -18
- package/dist/plugins/insights/testing/fixtures.d.mts +0 -8
- package/dist/plugins/insights/testing/fixtures.mjs +0 -25
- package/dist/plugins/insights/testing/index.d.mts +0 -24
- package/dist/plugins/insights/testing/index.mjs +0 -25
- package/dist/plugins/insights/testing/insightsModelTests.mjs +0 -714
- package/dist/plugins/insights/testing/modelTypes.d.mts +0 -176
- package/dist/plugins/insights/testing/setupInsightsHttpTestSuite.d.mts +0 -11
- package/dist/plugins/insights/testing/setupInsightsHttpTestSuite.mjs +0 -107
- package/dist/plugins/insights/testing/setupInsightsModelTestSuite.d.mts +0 -11
- package/dist/plugins/insights/testing/setupInsightsModelTestSuite.mjs +0 -31
- package/dist/plugins/insights/testing/types.d.mts +0 -26
- package/dist/plugins/insights/types.d.cts +0 -33
- package/dist/plugins/insights/types.d.mts +0 -33
- package/src/adapters/drizzle.conformance.integration.spec.ts +0 -34
- package/src/adapters/drizzle.readBudgets.integration.spec.ts +0 -43
- package/src/adapters/drizzle.spec.ts +0 -314
- package/src/adapters/drizzle.ts +0 -64
- package/src/adapters/drizzleExecutor.ts +0 -166
- package/src/adapters/kysely.conformance.integration.spec.ts +0 -36
- package/src/adapters/kysely.readBudgets.integration.spec.ts +0 -44
- package/src/adapters/kysely.spec.ts +0 -244
- package/src/adapters/kysely.ts +0 -46
- package/src/adapters/kyselyExecutor.ts +0 -53
- package/src/adapters/mongodb.integration.spec.ts +0 -271
- package/src/adapters/mongodb.readBudgets.integration.spec.ts +0 -61
- package/src/adapters/mongodb.ts +0 -45
- package/src/adapters/mongodbAdapter.ts +0 -307
- package/src/adapters/prisma.conformance.integration.spec.ts +0 -36
- package/src/adapters/prisma.integration.spec.ts +0 -146
- package/src/adapters/prisma.readBudgets.integration.spec.ts +0 -43
- package/src/adapters/prisma.spec.ts +0 -257
- package/src/adapters/prisma.ts +0 -74
- package/src/adapters/prismaExecutor.ts +0 -107
- package/src/adapters/prismaTestClients.ts +0 -182
- package/src/adapters/sqlProviders.ts +0 -14
- package/src/assembly/assemblePlugins.ts +0 -302
- package/src/assembly/assembly.spec.ts +0 -377
- package/src/assembly/assembly.types.spec.ts +0 -203
- package/src/assembly/clientPlugins.ts +0 -113
- package/src/assembly/configError.ts +0 -4
- package/src/assembly/databasePlugins.spec.ts +0 -71
- package/src/assembly/databasePlugins.ts +0 -102
- package/src/assembly/pluginCli.spec.ts +0 -254
- package/src/assembly/pluginCli.ts +0 -248
- package/src/assembly/pluginRoutes.spec.ts +0 -186
- package/src/core/api.ts +0 -139
- package/src/core/baseCandidates.spec.ts +0 -378
- package/src/core/baseCandidates.ts +0 -136
- package/src/core/index.ts +0 -44
- package/src/core/operations.spec.ts +0 -415
- package/src/core/operations.ts +0 -551
- package/src/core/reads.spec.ts +0 -300
- package/src/core/reads.ts +0 -417
- package/src/core/releases.spec.ts +0 -308
- package/src/core/releases.ts +0 -345
- package/src/core/schema.ts +0 -173
- package/src/core/writes.ts +0 -160
- package/src/createHotUpdaterCore.ts +0 -260
- package/src/database/aggregateBatching.spec.ts +0 -577
- package/src/database/aggregateBatching.ts +0 -803
- package/src/database/busy.spec.ts +0 -45
- package/src/database/busy.ts +0 -50
- package/src/database/cursor.ts +0 -65
- package/src/database/database.ts +0 -366
- package/src/database/database.types.spec.ts +0 -135
- package/src/database/definitions.ts +0 -76
- package/src/database/engine.ts +0 -62
- package/src/database/engineAggregates.spec.ts +0 -536
- package/src/database/engineAggregates.ts +0 -189
- package/src/database/engineReads.spec.ts +0 -219
- package/src/database/engineReads.ts +0 -304
- package/src/database/engineTransaction.spec.ts +0 -710
- package/src/database/engineTransaction.ts +0 -582
- package/src/database/errors.ts +0 -30
- package/src/database/fence.spec.ts +0 -223
- package/src/database/fence.ts +0 -175
- package/src/database/index.ts +0 -160
- package/src/database/kv/kvAdapter.batching.integration.spec.ts +0 -15
- package/src/database/kv/kvAdapter.conformance.integration.spec.ts +0 -19
- package/src/database/kv/kvAdapter.readBudgets.integration.spec.ts +0 -17
- package/src/database/kv/kvAdapter.spec.ts +0 -595
- package/src/database/kv/kvAdapter.ts +0 -479
- package/src/database/kv/kvTestStore.ts +0 -118
- package/src/database/memory.readBudgets.integration.spec.ts +0 -13
- package/src/database/resolveSchema.spec.ts +0 -230
- package/src/database/resolveSchema.ts +0 -375
- package/src/database/retention.spec.ts +0 -314
- package/src/database/retention.ts +0 -129
- package/src/database/schema.ts +0 -213
- package/src/database/schema.types.spec.ts +0 -94
- package/src/database/sql/docker-compose.yml +0 -36
- package/src/database/sql/sqlAdapter.integration.spec.ts +0 -145
- package/src/database/sql/sqlAdapter.readBudgets.integration.spec.ts +0 -123
- package/src/database/sql/sqlAdapter.spec.ts +0 -343
- package/src/database/sql/sqlAdapter.ts +0 -552
- package/src/database/sql/sqlSchema.ts +0 -286
- package/src/database/sql/sqlTestExecutors.ts +0 -183
- package/src/databaseTestSuite.spec.ts +0 -44
- package/src/db/bundleRows.spec.ts +0 -164
- package/src/db/bundleRows.ts +0 -10
- package/src/db/coreDatabase.ts +0 -153
- package/src/db/createBundleDiff.spec.ts +0 -464
- package/src/db/createBundleDiff.ts +0 -370
- package/src/db/engineDrizzleSchema.ts +0 -72
- package/src/db/engineMigrator.ts +0 -105
- package/src/db/enginePrismaSchema.ts +0 -147
- package/src/db/engineSql.spec.ts +0 -130
- package/src/db/engineSql.ts +0 -48
- package/src/db/engineSqlMigrator.ts +0 -116
- package/src/db/fixedMigratorShared.ts +0 -17
- package/src/db/index.spec.ts +0 -554
- package/src/db/index.ts +0 -93
- package/src/db/node-sqlite.d.ts +0 -25
- package/src/db/pluginTables.spec.ts +0 -248
- package/src/db/releaseCatalog.ts +0 -106
- package/src/db/schemaSettings.ts +0 -104
- package/src/db/settingsMigrator.spec.ts +0 -65
- package/src/db/settingsMigrator.ts +0 -152
- package/src/db/types.ts +0 -82
- package/src/db/updateArtifacts.spec.ts +0 -235
- package/src/db/updateArtifacts.ts +0 -473
- package/src/db/updateCheck.bench.ts +0 -47
- package/src/diff.ts +0 -6
- package/src/handler-standalone.integration.spec.ts +0 -321
- package/src/handler.spec.ts +0 -273
- package/src/handler.testFixtures.ts +0 -25
- package/src/handler.ts +0 -302
- package/src/handlerAdminRoutes.spec.ts +0 -183
- package/src/handlerAdminRoutes.ts +0 -536
- package/src/handlerAuth.integration.spec.ts +0 -33
- package/src/handlerErrors.ts +0 -7
- package/src/handlerManagement.spec.ts +0 -202
- package/src/handlerParameters.ts +0 -105
- package/src/handlerReleaseCatalogRoutes.ts +0 -176
- package/src/handlerTypes.ts +0 -19
- package/src/handlerVersionRoutes.ts +0 -25
- package/src/index.ts +0 -13
- package/src/internalRouter.ts +0 -104
- package/src/lintRules.spec.ts +0 -76
- package/src/node.spec.ts +0 -119
- package/src/node.ts +0 -111
- package/src/plugins/api-keys/apiKeys.integration.spec.ts +0 -92
- package/src/plugins/api-keys/apiKeys.spec.ts +0 -166
- package/src/plugins/api-keys/apiKeys.ts +0 -214
- package/src/plugins/api-keys/apiKeysPlugin.spec.ts +0 -168
- package/src/plugins/api-keys/cli.spec.ts +0 -187
- package/src/plugins/api-keys/cli.ts +0 -140
- package/src/plugins/api-keys/index.ts +0 -73
- package/src/plugins/api-keys/model.ts +0 -88
- package/src/plugins/api-keys/schema.ts +0 -22
- package/src/plugins/definePlugin.ts +0 -242
- package/src/plugins/index.ts +0 -73
- package/src/plugins/insights/contract.spec.ts +0 -285
- package/src/plugins/insights/contract.ts +0 -372
- package/src/plugins/insights/domain.ts +0 -176
- package/src/plugins/insights/errors.ts +0 -11
- package/src/plugins/insights/eventInput.ts +0 -381
- package/src/plugins/insights/eventRow.ts +0 -209
- package/src/plugins/insights/index.ts +0 -222
- package/src/plugins/insights/insights.integration.spec.ts +0 -921
- package/src/plugins/insights/insightsRollout.integration.spec.ts +0 -186
- package/src/plugins/insights/model.spec.ts +0 -64
- package/src/plugins/insights/model.ts +0 -18
- package/src/plugins/insights/modelTypes.ts +0 -197
- package/src/plugins/insights/overview.spec.ts +0 -64
- package/src/plugins/insights/overview.ts +0 -214
- package/src/plugins/insights/provider.spec.ts +0 -585
- package/src/plugins/insights/provider.ts +0 -704
- package/src/plugins/insights/queryInput.ts +0 -142
- package/src/plugins/insights/reads.spec.ts +0 -1013
- package/src/plugins/insights/reads.ts +0 -1037
- package/src/plugins/insights/recordEvent.spec.ts +0 -897
- package/src/plugins/insights/recordEvent.ts +0 -476
- package/src/plugins/insights/retention.spec.ts +0 -115
- package/src/plugins/insights/routes.ts +0 -149
- package/src/plugins/insights/schema.ts +0 -409
- package/src/plugins/insights/testing/expectInsightsIndex.spec.ts +0 -42
- package/src/plugins/insights/testing/expectInsightsIndex.ts +0 -20
- package/src/plugins/insights/testing/fixtures.ts +0 -30
- package/src/plugins/insights/testing/index.ts +0 -45
- package/src/plugins/insights/testing/insightsModelTests.ts +0 -860
- package/src/plugins/insights/testing/setupInsightsHttpTestSuite.ts +0 -152
- package/src/plugins/insights/testing/setupInsightsModelTestSuite.ts +0 -36
- package/src/plugins/insights/testing/types.ts +0 -30
- package/src/plugins/insights/types.ts +0 -55
- package/src/plugins/pluginTestHarness.spec.ts +0 -56
- package/src/readBudgets.testFixtures.ts +0 -15
- package/src/releaseCatalogRoutes.integration.spec.ts +0 -200
- package/src/retention.spec.ts +0 -73
- package/src/runtime.spec.ts +0 -207
- package/src/runtime.testFixtures.ts +0 -60
- package/src/runtimeBundles.integration.spec.ts +0 -112
- package/src/storageAccess.spec.ts +0 -152
- package/src/storageAccess.ts +0 -141
- package/src/testUtilsMutation.integration.spec.ts +0 -216
- package/src/testUtilsPackage.integration.spec.ts +0 -180
- package/src/types/index.ts +0 -2
- package/src/version.ts +0 -3
package/dist/db/types.d.mts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { SchemaSettings } from "../database/fence.mjs";
|
|
2
|
-
import { ResolvedSchema } from "../database/resolveSchema.mjs";
|
|
3
|
-
import { EngineDatabase } from "@hot-updater/plugin-core";
|
|
4
|
-
//#region src/db/types.d.ts
|
|
5
|
-
declare const sqlProviders: readonly ["sqlite", "mysql", "postgresql"];
|
|
6
|
-
declare const providers: readonly ["sqlite", "mysql", "postgresql", "mongodb"];
|
|
7
|
-
type ORMProvider = (typeof providers)[number];
|
|
8
|
-
type ORMSQLProvider = (typeof sqlProviders)[number];
|
|
9
|
-
interface MigrateOptions {
|
|
10
|
-
mode?: "from-schema" | "from-database";
|
|
11
|
-
updateSettings?: boolean;
|
|
12
|
-
unsafe?: boolean;
|
|
13
|
-
}
|
|
14
|
-
type MigrationOperation = {
|
|
15
|
-
type: "create-table";
|
|
16
|
-
value: {
|
|
17
|
-
ormName: string;
|
|
18
|
-
columns: Record<string, {
|
|
19
|
-
ormName: string;
|
|
20
|
-
type: string;
|
|
21
|
-
}>;
|
|
22
|
-
};
|
|
23
|
-
} | {
|
|
24
|
-
type: "custom";
|
|
25
|
-
description: string;
|
|
26
|
-
} | {
|
|
27
|
-
type: "custom";
|
|
28
|
-
sql: string;
|
|
29
|
-
} | {
|
|
30
|
-
type: "custom";
|
|
31
|
-
key: string;
|
|
32
|
-
value: unknown;
|
|
33
|
-
};
|
|
34
|
-
interface MigrationResult {
|
|
35
|
-
operations: MigrationOperation[];
|
|
36
|
-
execute: () => Promise<void>;
|
|
37
|
-
getSQL?: () => string;
|
|
38
|
-
}
|
|
39
|
-
interface Migrator {
|
|
40
|
-
getVersion: () => Promise<string | undefined>;
|
|
41
|
-
getNameVariants: () => Promise<unknown>;
|
|
42
|
-
next: () => Promise<{
|
|
43
|
-
version: string;
|
|
44
|
-
} | undefined>;
|
|
45
|
-
previous: () => Promise<{
|
|
46
|
-
version: string;
|
|
47
|
-
} | undefined>;
|
|
48
|
-
up: (options?: MigrateOptions) => Promise<MigrationResult>;
|
|
49
|
-
down: (options?: MigrateOptions) => Promise<MigrationResult>;
|
|
50
|
-
migrateTo: (version: string, options?: MigrateOptions) => Promise<MigrationResult>;
|
|
51
|
-
migrateToLatest: (options?: MigrateOptions) => Promise<MigrationResult>;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* The tables `db migrate` and `db generate` create and the settings rows they
|
|
55
|
-
* write: core's, and those of each plugin the server runs.
|
|
56
|
-
*/
|
|
57
|
-
interface ToolingTarget {
|
|
58
|
-
readonly schema: ResolvedSchema;
|
|
59
|
-
readonly settings: SchemaSettings;
|
|
60
|
-
}
|
|
61
|
-
type SchemaGenerator = (version: string | "latest", name?: string, target?: ToolingTarget) => {
|
|
62
|
-
code: string;
|
|
63
|
-
path: string;
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* What `hot-updater db generate` and `db migrate` run for a provider's
|
|
67
|
-
* database, beside the database itself. Without a target they cover core's
|
|
68
|
-
* tables.
|
|
69
|
-
*/
|
|
70
|
-
interface DatabaseTooling {
|
|
71
|
-
readonly provider?: ORMProvider;
|
|
72
|
-
readonly createMigrator?: (target?: ToolingTarget) => Migrator;
|
|
73
|
-
readonly generateSchema?: SchemaGenerator;
|
|
74
|
-
}
|
|
75
|
-
/** A provider's database on the storage engine, with its tooling. */
|
|
76
|
-
type ToolingDatabase = EngineDatabase & DatabaseTooling;
|
|
77
|
-
//#endregion
|
|
78
|
-
export { DatabaseTooling, MigrateOptions, MigrationOperation, MigrationResult, Migrator, ORMProvider, ORMSQLProvider, SchemaGenerator, ToolingDatabase, ToolingTarget, providers, sqlProviders };
|
package/dist/db/types.mjs
DELETED
package/dist/diff.cjs
DELETED
package/dist/diff.d.cts
DELETED
package/dist/diff.d.mts
DELETED
package/dist/diff.mjs
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
//#region src/plugins/api-keys/apiKeys.ts
|
|
2
|
-
const API_KEY_HEADER_NAME = "x-api-key";
|
|
3
|
-
const BASE64URL_32_PATTERN = /^[A-Za-z0-9_-]{43}$/u;
|
|
4
|
-
const bytesToBase64Url = (bytes) => {
|
|
5
|
-
let binary = "";
|
|
6
|
-
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
7
|
-
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
8
|
-
};
|
|
9
|
-
const isApiKey = (value) => {
|
|
10
|
-
if (!BASE64URL_32_PATTERN.test(value)) return false;
|
|
11
|
-
try {
|
|
12
|
-
const base64 = value.replaceAll("-", "+").replaceAll("_", "/");
|
|
13
|
-
const binary = atob(`${base64}=`);
|
|
14
|
-
const bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));
|
|
15
|
-
return bytes.byteLength === 32 && bytesToBase64Url(bytes) === value;
|
|
16
|
-
} catch {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
const normalizeApiKeyHeaderName = (value = API_KEY_HEADER_NAME) => {
|
|
21
|
-
if (typeof value !== "string" || value.length === 0) throw new TypeError("apiKeys({ headerName }) must name a valid header.");
|
|
22
|
-
try {
|
|
23
|
-
const headers = new Headers();
|
|
24
|
-
headers.set(value, "");
|
|
25
|
-
return headers.keys().next().value;
|
|
26
|
-
} catch {
|
|
27
|
-
throw new TypeError("apiKeys({ headerName }) must name a valid header.");
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
const hashApiKey = async (apiKey) => {
|
|
31
|
-
if (!isApiKey(apiKey)) throw new TypeError("API key must be a canonical 32-byte base64url value.");
|
|
32
|
-
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(apiKey));
|
|
33
|
-
return bytesToBase64Url(new Uint8Array(digest));
|
|
34
|
-
};
|
|
35
|
-
const apiKeyId = () => {
|
|
36
|
-
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
37
|
-
crypto.getRandomValues(bytes);
|
|
38
|
-
return `api-${bytesToBase64Url(bytes)}`;
|
|
39
|
-
};
|
|
40
|
-
const normalizeApiKeyName = (name) => {
|
|
41
|
-
const normalized = name.trim();
|
|
42
|
-
if (normalized.length === 0 || normalized.length > 64 || /[\p{Cc}\p{Cf}]/u.test(normalized)) throw new TypeError("API key names must contain 1-64 visible characters.");
|
|
43
|
-
return normalized;
|
|
44
|
-
};
|
|
45
|
-
const toApiKeyMetadata = ({ hash: _hash, ...metadata }) => Object.freeze(metadata);
|
|
46
|
-
const registerApiKey = async (input) => {
|
|
47
|
-
const hash = await hashApiKey(input.apiKey);
|
|
48
|
-
const createdAtMs = input.createdAtMs ?? Date.now();
|
|
49
|
-
if (!Number.isSafeInteger(createdAtMs) || createdAtMs < 0) throw new TypeError("API key creation time must be non-negative.");
|
|
50
|
-
const record = Object.freeze({
|
|
51
|
-
created_at_ms: createdAtMs,
|
|
52
|
-
hash,
|
|
53
|
-
id: apiKeyId(),
|
|
54
|
-
name: normalizeApiKeyName(input.name),
|
|
55
|
-
prefix: input.apiKey.slice(0, 6),
|
|
56
|
-
revoked_at_ms: null,
|
|
57
|
-
role: "client"
|
|
58
|
-
});
|
|
59
|
-
if (await input.apiKeys.create(record) === "existing") {
|
|
60
|
-
const existing = await input.apiKeys.findByHash(hash);
|
|
61
|
-
if (existing === null || existing.revoked_at_ms !== null) throw new Error("The API key has been revoked.");
|
|
62
|
-
return Object.freeze({
|
|
63
|
-
apiKey: input.apiKey,
|
|
64
|
-
record: toApiKeyMetadata(existing)
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return Object.freeze({
|
|
68
|
-
apiKey: input.apiKey,
|
|
69
|
-
record: toApiKeyMetadata(record)
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
const createApiKey = (input) => {
|
|
73
|
-
const bytes = /* @__PURE__ */ new Uint8Array(32);
|
|
74
|
-
crypto.getRandomValues(bytes);
|
|
75
|
-
return registerApiKey({
|
|
76
|
-
apiKey: bytesToBase64Url(bytes),
|
|
77
|
-
apiKeys: input.apiKeys,
|
|
78
|
-
name: input.name
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* Provisions the client API key used by managed init.
|
|
83
|
-
*
|
|
84
|
-
* A saved plaintext key is registered idempotently; otherwise a new key is
|
|
85
|
-
* created. Callers must persist or display the returned plaintext because the
|
|
86
|
-
* database stores only its hash.
|
|
87
|
-
*/
|
|
88
|
-
const provisionApiKey = (input) => {
|
|
89
|
-
const existingApiKey = input.existingApiKey?.trim();
|
|
90
|
-
return existingApiKey ? registerApiKey({
|
|
91
|
-
apiKey: existingApiKey,
|
|
92
|
-
apiKeys: input.apiKeys,
|
|
93
|
-
name: input.name
|
|
94
|
-
}) : createApiKey({
|
|
95
|
-
apiKeys: input.apiKeys,
|
|
96
|
-
name: input.name
|
|
97
|
-
});
|
|
98
|
-
};
|
|
99
|
-
const authenticateApiKey = async (input) => {
|
|
100
|
-
const apiKey = input.request.headers.get(normalizeApiKeyHeaderName(input.headerName));
|
|
101
|
-
if (apiKey === null || !isApiKey(apiKey)) return false;
|
|
102
|
-
const hash = await hashApiKey(apiKey);
|
|
103
|
-
const record = await input.apiKeys.findByHash(hash);
|
|
104
|
-
return record !== null && record.hash === hash && record.role === "client" && record.revoked_at_ms === null;
|
|
105
|
-
};
|
|
106
|
-
const createApiKeyManagement = (input) => Object.freeze({
|
|
107
|
-
async create({ name }) {
|
|
108
|
-
const created = await createApiKey({
|
|
109
|
-
apiKeys: input.apiKeys,
|
|
110
|
-
name
|
|
111
|
-
});
|
|
112
|
-
return Object.freeze({
|
|
113
|
-
apiKey: created.apiKey,
|
|
114
|
-
record: created.record
|
|
115
|
-
});
|
|
116
|
-
},
|
|
117
|
-
async list() {
|
|
118
|
-
return Object.freeze((await input.apiKeys.list()).map(toApiKeyMetadata));
|
|
119
|
-
},
|
|
120
|
-
async revoke({ id }) {
|
|
121
|
-
const record = await input.apiKeys.revoke({
|
|
122
|
-
id,
|
|
123
|
-
revokedAtMs: Date.now()
|
|
124
|
-
});
|
|
125
|
-
return record === null ? null : toApiKeyMetadata(record);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
//#endregion
|
|
129
|
-
exports.API_KEY_HEADER_NAME = API_KEY_HEADER_NAME;
|
|
130
|
-
exports.apiKeyId = apiKeyId;
|
|
131
|
-
exports.authenticateApiKey = authenticateApiKey;
|
|
132
|
-
exports.createApiKey = createApiKey;
|
|
133
|
-
exports.createApiKeyManagement = createApiKeyManagement;
|
|
134
|
-
exports.hashApiKey = hashApiKey;
|
|
135
|
-
exports.isApiKey = isApiKey;
|
|
136
|
-
exports.normalizeApiKeyHeaderName = normalizeApiKeyHeaderName;
|
|
137
|
-
exports.normalizeApiKeyName = normalizeApiKeyName;
|
|
138
|
-
exports.provisionApiKey = provisionApiKey;
|
|
139
|
-
exports.registerApiKey = registerApiKey;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ApiKeyRow } from "./model.cjs";
|
|
2
|
-
//#region src/plugins/api-keys/apiKeys.d.ts
|
|
3
|
-
declare const API_KEY_HEADER_NAME = "x-api-key";
|
|
4
|
-
type ApiKeyMetadata = Omit<ApiKeyRow, "hash">;
|
|
5
|
-
interface CreatedApiKey {
|
|
6
|
-
/** Plaintext credential. It cannot be recovered after this call returns. */
|
|
7
|
-
readonly apiKey: string;
|
|
8
|
-
/** Non-secret metadata. The persisted SHA-256 hash is never exposed. */
|
|
9
|
-
readonly record: ApiKeyMetadata;
|
|
10
|
-
}
|
|
11
|
-
interface ApiKeyManagementAPI {
|
|
12
|
-
/** Creates an API key and returns its plaintext exactly once. */
|
|
13
|
-
create(input: {
|
|
14
|
-
readonly name: string;
|
|
15
|
-
}): Promise<{
|
|
16
|
-
readonly apiKey: string;
|
|
17
|
-
readonly record: ApiKeyMetadata;
|
|
18
|
-
}>;
|
|
19
|
-
/** Lists non-secret API key metadata, including revoked keys. */
|
|
20
|
-
list(): Promise<readonly ApiKeyMetadata[]>;
|
|
21
|
-
/** Revokes an API key immediately and returns only non-secret metadata. */
|
|
22
|
-
revoke(input: {
|
|
23
|
-
readonly id: string;
|
|
24
|
-
}): Promise<ApiKeyMetadata | null>;
|
|
25
|
-
}
|
|
26
|
-
//#endregion
|
|
27
|
-
export { API_KEY_HEADER_NAME, ApiKeyManagementAPI, ApiKeyMetadata, CreatedApiKey };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ApiKeyRow } from "./model.mjs";
|
|
2
|
-
//#region src/plugins/api-keys/apiKeys.d.ts
|
|
3
|
-
declare const API_KEY_HEADER_NAME = "x-api-key";
|
|
4
|
-
type ApiKeyMetadata = Omit<ApiKeyRow, "hash">;
|
|
5
|
-
interface CreatedApiKey {
|
|
6
|
-
/** Plaintext credential. It cannot be recovered after this call returns. */
|
|
7
|
-
readonly apiKey: string;
|
|
8
|
-
/** Non-secret metadata. The persisted SHA-256 hash is never exposed. */
|
|
9
|
-
readonly record: ApiKeyMetadata;
|
|
10
|
-
}
|
|
11
|
-
interface ApiKeyManagementAPI {
|
|
12
|
-
/** Creates an API key and returns its plaintext exactly once. */
|
|
13
|
-
create(input: {
|
|
14
|
-
readonly name: string;
|
|
15
|
-
}): Promise<{
|
|
16
|
-
readonly apiKey: string;
|
|
17
|
-
readonly record: ApiKeyMetadata;
|
|
18
|
-
}>;
|
|
19
|
-
/** Lists non-secret API key metadata, including revoked keys. */
|
|
20
|
-
list(): Promise<readonly ApiKeyMetadata[]>;
|
|
21
|
-
/** Revokes an API key immediately and returns only non-secret metadata. */
|
|
22
|
-
revoke(input: {
|
|
23
|
-
readonly id: string;
|
|
24
|
-
}): Promise<ApiKeyMetadata | null>;
|
|
25
|
-
}
|
|
26
|
-
//#endregion
|
|
27
|
-
export { API_KEY_HEADER_NAME, ApiKeyManagementAPI, ApiKeyMetadata, CreatedApiKey };
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
//#region src/plugins/api-keys/apiKeys.ts
|
|
2
|
-
const API_KEY_HEADER_NAME = "x-api-key";
|
|
3
|
-
const BASE64URL_32_PATTERN = /^[A-Za-z0-9_-]{43}$/u;
|
|
4
|
-
const bytesToBase64Url = (bytes) => {
|
|
5
|
-
let binary = "";
|
|
6
|
-
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
7
|
-
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
8
|
-
};
|
|
9
|
-
const isApiKey = (value) => {
|
|
10
|
-
if (!BASE64URL_32_PATTERN.test(value)) return false;
|
|
11
|
-
try {
|
|
12
|
-
const base64 = value.replaceAll("-", "+").replaceAll("_", "/");
|
|
13
|
-
const binary = atob(`${base64}=`);
|
|
14
|
-
const bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));
|
|
15
|
-
return bytes.byteLength === 32 && bytesToBase64Url(bytes) === value;
|
|
16
|
-
} catch {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
const normalizeApiKeyHeaderName = (value = API_KEY_HEADER_NAME) => {
|
|
21
|
-
if (typeof value !== "string" || value.length === 0) throw new TypeError("apiKeys({ headerName }) must name a valid header.");
|
|
22
|
-
try {
|
|
23
|
-
const headers = new Headers();
|
|
24
|
-
headers.set(value, "");
|
|
25
|
-
return headers.keys().next().value;
|
|
26
|
-
} catch {
|
|
27
|
-
throw new TypeError("apiKeys({ headerName }) must name a valid header.");
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
const hashApiKey = async (apiKey) => {
|
|
31
|
-
if (!isApiKey(apiKey)) throw new TypeError("API key must be a canonical 32-byte base64url value.");
|
|
32
|
-
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(apiKey));
|
|
33
|
-
return bytesToBase64Url(new Uint8Array(digest));
|
|
34
|
-
};
|
|
35
|
-
const apiKeyId = () => {
|
|
36
|
-
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
37
|
-
crypto.getRandomValues(bytes);
|
|
38
|
-
return `api-${bytesToBase64Url(bytes)}`;
|
|
39
|
-
};
|
|
40
|
-
const normalizeApiKeyName = (name) => {
|
|
41
|
-
const normalized = name.trim();
|
|
42
|
-
if (normalized.length === 0 || normalized.length > 64 || /[\p{Cc}\p{Cf}]/u.test(normalized)) throw new TypeError("API key names must contain 1-64 visible characters.");
|
|
43
|
-
return normalized;
|
|
44
|
-
};
|
|
45
|
-
const toApiKeyMetadata = ({ hash: _hash, ...metadata }) => Object.freeze(metadata);
|
|
46
|
-
const registerApiKey = async (input) => {
|
|
47
|
-
const hash = await hashApiKey(input.apiKey);
|
|
48
|
-
const createdAtMs = input.createdAtMs ?? Date.now();
|
|
49
|
-
if (!Number.isSafeInteger(createdAtMs) || createdAtMs < 0) throw new TypeError("API key creation time must be non-negative.");
|
|
50
|
-
const record = Object.freeze({
|
|
51
|
-
created_at_ms: createdAtMs,
|
|
52
|
-
hash,
|
|
53
|
-
id: apiKeyId(),
|
|
54
|
-
name: normalizeApiKeyName(input.name),
|
|
55
|
-
prefix: input.apiKey.slice(0, 6),
|
|
56
|
-
revoked_at_ms: null,
|
|
57
|
-
role: "client"
|
|
58
|
-
});
|
|
59
|
-
if (await input.apiKeys.create(record) === "existing") {
|
|
60
|
-
const existing = await input.apiKeys.findByHash(hash);
|
|
61
|
-
if (existing === null || existing.revoked_at_ms !== null) throw new Error("The API key has been revoked.");
|
|
62
|
-
return Object.freeze({
|
|
63
|
-
apiKey: input.apiKey,
|
|
64
|
-
record: toApiKeyMetadata(existing)
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return Object.freeze({
|
|
68
|
-
apiKey: input.apiKey,
|
|
69
|
-
record: toApiKeyMetadata(record)
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
const createApiKey = (input) => {
|
|
73
|
-
const bytes = /* @__PURE__ */ new Uint8Array(32);
|
|
74
|
-
crypto.getRandomValues(bytes);
|
|
75
|
-
return registerApiKey({
|
|
76
|
-
apiKey: bytesToBase64Url(bytes),
|
|
77
|
-
apiKeys: input.apiKeys,
|
|
78
|
-
name: input.name
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* Provisions the client API key used by managed init.
|
|
83
|
-
*
|
|
84
|
-
* A saved plaintext key is registered idempotently; otherwise a new key is
|
|
85
|
-
* created. Callers must persist or display the returned plaintext because the
|
|
86
|
-
* database stores only its hash.
|
|
87
|
-
*/
|
|
88
|
-
const provisionApiKey = (input) => {
|
|
89
|
-
const existingApiKey = input.existingApiKey?.trim();
|
|
90
|
-
return existingApiKey ? registerApiKey({
|
|
91
|
-
apiKey: existingApiKey,
|
|
92
|
-
apiKeys: input.apiKeys,
|
|
93
|
-
name: input.name
|
|
94
|
-
}) : createApiKey({
|
|
95
|
-
apiKeys: input.apiKeys,
|
|
96
|
-
name: input.name
|
|
97
|
-
});
|
|
98
|
-
};
|
|
99
|
-
const authenticateApiKey = async (input) => {
|
|
100
|
-
const apiKey = input.request.headers.get(normalizeApiKeyHeaderName(input.headerName));
|
|
101
|
-
if (apiKey === null || !isApiKey(apiKey)) return false;
|
|
102
|
-
const hash = await hashApiKey(apiKey);
|
|
103
|
-
const record = await input.apiKeys.findByHash(hash);
|
|
104
|
-
return record !== null && record.hash === hash && record.role === "client" && record.revoked_at_ms === null;
|
|
105
|
-
};
|
|
106
|
-
const createApiKeyManagement = (input) => Object.freeze({
|
|
107
|
-
async create({ name }) {
|
|
108
|
-
const created = await createApiKey({
|
|
109
|
-
apiKeys: input.apiKeys,
|
|
110
|
-
name
|
|
111
|
-
});
|
|
112
|
-
return Object.freeze({
|
|
113
|
-
apiKey: created.apiKey,
|
|
114
|
-
record: created.record
|
|
115
|
-
});
|
|
116
|
-
},
|
|
117
|
-
async list() {
|
|
118
|
-
return Object.freeze((await input.apiKeys.list()).map(toApiKeyMetadata));
|
|
119
|
-
},
|
|
120
|
-
async revoke({ id }) {
|
|
121
|
-
const record = await input.apiKeys.revoke({
|
|
122
|
-
id,
|
|
123
|
-
revokedAtMs: Date.now()
|
|
124
|
-
});
|
|
125
|
-
return record === null ? null : toApiKeyMetadata(record);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
//#endregion
|
|
129
|
-
export { API_KEY_HEADER_NAME, apiKeyId, authenticateApiKey, createApiKey, createApiKeyManagement, hashApiKey, isApiKey, normalizeApiKeyHeaderName, normalizeApiKeyName, provisionApiKey, registerApiKey };
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
//#region src/plugins/api-keys/cli.ts
|
|
2
|
-
/** The environment variable init stores the app's API key in. */
|
|
3
|
-
const API_KEY_ENV = "HOT_UPDATER_API_KEY";
|
|
4
|
-
/** A new API key: 32 random bytes, base64url, as the plugin creates them. */
|
|
5
|
-
const generateApiKey = () => {
|
|
6
|
-
const bytes = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(32));
|
|
7
|
-
return btoa(String.fromCharCode(...bytes)).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
8
|
-
};
|
|
9
|
-
const formatList = (ui, records) => records.length === 0 ? ui.muted("(no API keys)") : ui.table([
|
|
10
|
-
{
|
|
11
|
-
key: "id",
|
|
12
|
-
label: "ID",
|
|
13
|
-
format: ui.id
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
key: "name",
|
|
17
|
-
label: "Name"
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
key: "prefix",
|
|
21
|
-
label: "Prefix",
|
|
22
|
-
format: ui.muted
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
key: "status",
|
|
26
|
-
label: "Status",
|
|
27
|
-
format: (value) => value.trim() === "active" ? ui.success(value) : ui.danger(value)
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
key: "created",
|
|
31
|
-
label: "Created",
|
|
32
|
-
format: ui.muted
|
|
33
|
-
}
|
|
34
|
-
], records.map((record) => ({
|
|
35
|
-
created: new Date(record.created_at_ms).toISOString(),
|
|
36
|
-
id: record.id,
|
|
37
|
-
name: record.name,
|
|
38
|
-
prefix: record.prefix,
|
|
39
|
-
status: record.revoked_at_ms === null ? "active" : "revoked"
|
|
40
|
-
})));
|
|
41
|
-
/**
|
|
42
|
-
* `hot-updater api-key create|list|revoke`, and the API key that init
|
|
43
|
-
* provisions for an app, sent in `headerName`.
|
|
44
|
-
*/
|
|
45
|
-
const apiKeysCli = (headerName) => ({
|
|
46
|
-
commands: [{
|
|
47
|
-
name: "api-key",
|
|
48
|
-
description: "Manage API keys",
|
|
49
|
-
commands: [
|
|
50
|
-
{
|
|
51
|
-
name: "create",
|
|
52
|
-
description: "Create an API key",
|
|
53
|
-
options: [{
|
|
54
|
-
flags: "--name <name>",
|
|
55
|
-
description: "name used to identify the API key",
|
|
56
|
-
required: true
|
|
57
|
-
}],
|
|
58
|
-
async run({ api, options, ui }) {
|
|
59
|
-
const created = await api.create({ name: String(options.name) });
|
|
60
|
-
ui.message(ui.block("API key created", [
|
|
61
|
-
ui.kv("Name", created.record.name),
|
|
62
|
-
ui.kv("ID", ui.id(created.record.id)),
|
|
63
|
-
ui.kv("API key", ui.warning(created.apiKey))
|
|
64
|
-
]));
|
|
65
|
-
ui.warn("Save this API key now. It will not be shown again.");
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: "list",
|
|
70
|
-
description: "List API keys",
|
|
71
|
-
options: [{
|
|
72
|
-
flags: "--json",
|
|
73
|
-
description: "output API key metadata as JSON"
|
|
74
|
-
}],
|
|
75
|
-
async run({ api, options, ui }) {
|
|
76
|
-
const records = [...await api.list()].sort((left, right) => right.created_at_ms - left.created_at_ms);
|
|
77
|
-
if (options.json) ui.print(JSON.stringify(records, null, 2));
|
|
78
|
-
else ui.message(formatList(ui, records));
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: "revoke",
|
|
83
|
-
description: "Revoke an API key",
|
|
84
|
-
arguments: [{
|
|
85
|
-
name: "id",
|
|
86
|
-
description: "API key id"
|
|
87
|
-
}],
|
|
88
|
-
options: [{
|
|
89
|
-
flags: "-y, --yes",
|
|
90
|
-
description: "skip confirmation prompt"
|
|
91
|
-
}],
|
|
92
|
-
async run({ api, args, options, ui }) {
|
|
93
|
-
const id = String(args.id);
|
|
94
|
-
if (!options.yes) await ui.confirm(`Revoke API key ${id}?`);
|
|
95
|
-
const revoked = await api.revoke({ id });
|
|
96
|
-
if (revoked === null) throw new Error(`API key "${id}" was not found.`);
|
|
97
|
-
ui.message(ui.block("API key revoked", [ui.kv("Name", revoked.name), ui.kv("ID", ui.id(revoked.id))]));
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
]
|
|
101
|
-
}],
|
|
102
|
-
clientCredential: {
|
|
103
|
-
label: "API key",
|
|
104
|
-
header: headerName,
|
|
105
|
-
env: API_KEY_ENV,
|
|
106
|
-
generate: generateApiKey,
|
|
107
|
-
provision: async (api, { existing, name }) => (await api.provision({
|
|
108
|
-
...existing === void 0 ? {} : { existingApiKey: existing },
|
|
109
|
-
name
|
|
110
|
-
})).apiKey
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
//#endregion
|
|
114
|
-
exports.API_KEY_ENV = API_KEY_ENV;
|
|
115
|
-
exports.apiKeysCli = apiKeysCli;
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
//#region src/plugins/api-keys/cli.ts
|
|
2
|
-
/** The environment variable init stores the app's API key in. */
|
|
3
|
-
const API_KEY_ENV = "HOT_UPDATER_API_KEY";
|
|
4
|
-
/** A new API key: 32 random bytes, base64url, as the plugin creates them. */
|
|
5
|
-
const generateApiKey = () => {
|
|
6
|
-
const bytes = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(32));
|
|
7
|
-
return btoa(String.fromCharCode(...bytes)).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
8
|
-
};
|
|
9
|
-
const formatList = (ui, records) => records.length === 0 ? ui.muted("(no API keys)") : ui.table([
|
|
10
|
-
{
|
|
11
|
-
key: "id",
|
|
12
|
-
label: "ID",
|
|
13
|
-
format: ui.id
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
key: "name",
|
|
17
|
-
label: "Name"
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
key: "prefix",
|
|
21
|
-
label: "Prefix",
|
|
22
|
-
format: ui.muted
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
key: "status",
|
|
26
|
-
label: "Status",
|
|
27
|
-
format: (value) => value.trim() === "active" ? ui.success(value) : ui.danger(value)
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
key: "created",
|
|
31
|
-
label: "Created",
|
|
32
|
-
format: ui.muted
|
|
33
|
-
}
|
|
34
|
-
], records.map((record) => ({
|
|
35
|
-
created: new Date(record.created_at_ms).toISOString(),
|
|
36
|
-
id: record.id,
|
|
37
|
-
name: record.name,
|
|
38
|
-
prefix: record.prefix,
|
|
39
|
-
status: record.revoked_at_ms === null ? "active" : "revoked"
|
|
40
|
-
})));
|
|
41
|
-
/**
|
|
42
|
-
* `hot-updater api-key create|list|revoke`, and the API key that init
|
|
43
|
-
* provisions for an app, sent in `headerName`.
|
|
44
|
-
*/
|
|
45
|
-
const apiKeysCli = (headerName) => ({
|
|
46
|
-
commands: [{
|
|
47
|
-
name: "api-key",
|
|
48
|
-
description: "Manage API keys",
|
|
49
|
-
commands: [
|
|
50
|
-
{
|
|
51
|
-
name: "create",
|
|
52
|
-
description: "Create an API key",
|
|
53
|
-
options: [{
|
|
54
|
-
flags: "--name <name>",
|
|
55
|
-
description: "name used to identify the API key",
|
|
56
|
-
required: true
|
|
57
|
-
}],
|
|
58
|
-
async run({ api, options, ui }) {
|
|
59
|
-
const created = await api.create({ name: String(options.name) });
|
|
60
|
-
ui.message(ui.block("API key created", [
|
|
61
|
-
ui.kv("Name", created.record.name),
|
|
62
|
-
ui.kv("ID", ui.id(created.record.id)),
|
|
63
|
-
ui.kv("API key", ui.warning(created.apiKey))
|
|
64
|
-
]));
|
|
65
|
-
ui.warn("Save this API key now. It will not be shown again.");
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: "list",
|
|
70
|
-
description: "List API keys",
|
|
71
|
-
options: [{
|
|
72
|
-
flags: "--json",
|
|
73
|
-
description: "output API key metadata as JSON"
|
|
74
|
-
}],
|
|
75
|
-
async run({ api, options, ui }) {
|
|
76
|
-
const records = [...await api.list()].sort((left, right) => right.created_at_ms - left.created_at_ms);
|
|
77
|
-
if (options.json) ui.print(JSON.stringify(records, null, 2));
|
|
78
|
-
else ui.message(formatList(ui, records));
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: "revoke",
|
|
83
|
-
description: "Revoke an API key",
|
|
84
|
-
arguments: [{
|
|
85
|
-
name: "id",
|
|
86
|
-
description: "API key id"
|
|
87
|
-
}],
|
|
88
|
-
options: [{
|
|
89
|
-
flags: "-y, --yes",
|
|
90
|
-
description: "skip confirmation prompt"
|
|
91
|
-
}],
|
|
92
|
-
async run({ api, args, options, ui }) {
|
|
93
|
-
const id = String(args.id);
|
|
94
|
-
if (!options.yes) await ui.confirm(`Revoke API key ${id}?`);
|
|
95
|
-
const revoked = await api.revoke({ id });
|
|
96
|
-
if (revoked === null) throw new Error(`API key "${id}" was not found.`);
|
|
97
|
-
ui.message(ui.block("API key revoked", [ui.kv("Name", revoked.name), ui.kv("ID", ui.id(revoked.id))]));
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
]
|
|
101
|
-
}],
|
|
102
|
-
clientCredential: {
|
|
103
|
-
label: "API key",
|
|
104
|
-
header: headerName,
|
|
105
|
-
env: API_KEY_ENV,
|
|
106
|
-
generate: generateApiKey,
|
|
107
|
-
provision: async (api, { existing, name }) => (await api.provision({
|
|
108
|
-
...existing === void 0 ? {} : { existingApiKey: existing },
|
|
109
|
-
name
|
|
110
|
-
})).apiKey
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
//#endregion
|
|
114
|
-
export { API_KEY_ENV, apiKeysCli };
|