@hot-updater/server 1.0.0-rc.2 → 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 +32 -75
- package/dist/adapters/drizzle.d.cts +13 -5
- package/dist/adapters/drizzle.d.mts +13 -5
- package/dist/adapters/drizzle.mjs +32 -77
- 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 +22 -31
- package/dist/adapters/kysely.d.cts +10 -6
- package/dist/adapters/kysely.d.mts +10 -6
- package/dist/adapters/kysely.mjs +23 -33
- package/dist/adapters/kyselyExecutor.cjs +32 -0
- package/dist/adapters/kyselyExecutor.d.cts +11 -0
- package/dist/adapters/kyselyExecutor.d.mts +11 -0
- package/dist/adapters/kyselyExecutor.mjs +32 -0
- package/dist/adapters/mongodb.cjs +18 -54
- package/dist/adapters/mongodb.d.cts +10 -5
- package/dist/adapters/mongodb.d.mts +10 -5
- package/dist/adapters/mongodb.mjs +19 -56
- package/dist/adapters/mongodbAdapter.cjs +192 -0
- package/dist/adapters/mongodbAdapter.d.cts +9 -0
- package/dist/adapters/mongodbAdapter.d.mts +9 -0
- package/dist/adapters/mongodbAdapter.mjs +191 -0
- package/dist/adapters/prisma.cjs +35 -267
- package/dist/adapters/prisma.d.cts +12 -7
- package/dist/adapters/prisma.d.mts +12 -7
- package/dist/adapters/prisma.mjs +36 -268
- package/dist/adapters/prismaExecutor.cjs +63 -0
- package/dist/adapters/prismaExecutor.mjs +63 -0
- package/dist/adapters/sqlProviders.cjs +14 -0
- package/dist/adapters/sqlProviders.mjs +14 -0
- package/dist/assembly/assemblePlugins.cjs +144 -0
- package/dist/assembly/assemblePlugins.d.cts +5 -0
- package/dist/assembly/assemblePlugins.d.mts +5 -0
- package/dist/assembly/assemblePlugins.mjs +139 -0
- package/dist/assembly/clientPlugins.cjs +88 -0
- package/dist/assembly/clientPlugins.mjs +88 -0
- package/dist/assembly/configError.d.cts +2 -0
- package/dist/assembly/configError.d.mts +2 -0
- package/dist/assembly/configError.mjs +2 -0
- package/dist/core/api.cjs +51 -0
- package/dist/core/api.d.cts +54 -0
- package/dist/core/api.d.mts +54 -0
- package/dist/core/api.mjs +51 -0
- package/dist/core/baseCandidates.cjs +28 -0
- package/dist/core/baseCandidates.mjs +28 -0
- package/dist/core/operations.cjs +351 -0
- package/dist/core/operations.mjs +351 -0
- package/dist/core/reads.cjs +273 -0
- package/dist/core/reads.d.cts +9 -0
- package/dist/core/reads.d.mts +9 -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/writes.cjs +96 -0
- package/dist/core/writes.mjs +91 -0
- package/dist/createHotUpdaterCore.cjs +72 -91
- package/dist/createHotUpdaterCore.d.cts +106 -38
- package/dist/createHotUpdaterCore.d.mts +106 -38
- package/dist/createHotUpdaterCore.mjs +74 -89
- package/dist/db/engineDrizzleSchema.cjs +53 -0
- package/dist/db/engineDrizzleSchema.mjs +53 -0
- package/dist/db/enginePrismaSchema.cjs +84 -0
- package/dist/db/enginePrismaSchema.d.cts +5 -0
- package/dist/db/enginePrismaSchema.d.mts +5 -0
- package/dist/db/enginePrismaSchema.mjs +83 -0
- package/dist/db/releaseCatalog.cjs +24 -47
- package/dist/db/releaseCatalog.mjs +20 -44
- package/dist/db/updateArtifacts.cjs +43 -72
- package/dist/db/updateArtifacts.mjs +40 -69
- package/dist/handler.cjs +59 -43
- package/dist/handler.d.cts +3 -5
- package/dist/handler.d.mts +3 -5
- package/dist/handler.mjs +61 -43
- package/dist/handlerAdminRoutes.cjs +374 -0
- package/dist/handlerAdminRoutes.mjs +372 -0
- package/dist/handlerParameters.cjs +6 -11
- package/dist/handlerParameters.mjs +6 -10
- package/dist/handlerReleaseCatalogRoutes.cjs +32 -15
- package/dist/handlerReleaseCatalogRoutes.mjs +32 -15
- package/dist/handlerTypes.d.cts +2 -55
- package/dist/handlerTypes.d.mts +2 -55
- package/dist/handlerVersionRoutes.cjs +20 -4
- package/dist/handlerVersionRoutes.mjs +20 -4
- package/dist/index.cjs +9 -9
- package/dist/index.d.cts +8 -9
- package/dist/index.d.mts +8 -9
- package/dist/index.mjs +3 -4
- package/dist/node.cjs +3 -6
- package/dist/node.d.cts +2 -2
- package/dist/node.d.mts +2 -2
- 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 +9 -0
- package/dist/plugins/api-keys/index.d.cts +1 -0
- package/dist/plugins/api-keys/index.d.mts +1 -0
- package/dist/plugins/api-keys/index.mjs +2 -0
- package/dist/plugins/definePlugin.d.cts +2 -0
- package/dist/plugins/definePlugin.d.mts +2 -0
- package/dist/plugins/insights/index.cjs +9 -0
- package/dist/plugins/insights/index.d.cts +1 -0
- package/dist/plugins/insights/index.d.mts +1 -0
- package/dist/plugins/insights/index.mjs +2 -0
- 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 +2 -28
- package/dist/types/index.d.mts +2 -28
- package/package.json +26 -14
- package/dist/_virtual/_rolldown/runtime.cjs +0 -23
- package/dist/adapters/databaseConstraintErrors.cjs +0 -22
- package/dist/adapters/databaseConstraintErrors.mjs +0 -21
- package/dist/adapters/databasePluginUtils.cjs +0 -116
- package/dist/adapters/databasePluginUtils.mjs +0 -106
- package/dist/adapters/drizzleCrud.cjs +0 -311
- package/dist/adapters/drizzleCrud.mjs +0 -308
- package/dist/adapters/drizzleLazyDB.cjs +0 -106
- package/dist/adapters/drizzleLazyDB.mjs +0 -106
- package/dist/adapters/drizzleQuery.cjs +0 -69
- package/dist/adapters/drizzleQuery.mjs +0 -69
- package/dist/adapters/insightsTransaction.cjs +0 -22
- package/dist/adapters/insightsTransaction.mjs +0 -22
- package/dist/adapters/kyselyCrud.cjs +0 -305
- package/dist/adapters/kyselyCrud.mjs +0 -304
- package/dist/adapters/kyselyQuery.cjs +0 -56
- package/dist/adapters/kyselyQuery.mjs +0 -56
- package/dist/adapters/mongodbCollections.cjs +0 -38
- package/dist/adapters/mongodbCollections.mjs +0 -32
- package/dist/adapters/mongodbQuery.cjs +0 -94
- package/dist/adapters/mongodbQuery.mjs +0 -86
- package/dist/adapters/mongodbReads.cjs +0 -210
- package/dist/adapters/mongodbReads.mjs +0 -210
- package/dist/adapters/mongodbWrites.cjs +0 -148
- package/dist/adapters/mongodbWrites.mjs +0 -148
- package/dist/adapters/prismaQuery.cjs +0 -57
- package/dist/adapters/prismaQuery.mjs +0 -56
- package/dist/adapters/prismaRows.cjs +0 -219
- package/dist/adapters/prismaRows.mjs +0 -209
- package/dist/apiKeys.cjs +0 -143
- package/dist/apiKeys.d.cts +0 -49
- package/dist/apiKeys.d.mts +0 -49
- package/dist/apiKeys.mjs +0 -133
- package/dist/db/createBundleDiff.cjs +0 -144
- package/dist/db/createBundleDiff.d.cts +0 -16
- package/dist/db/createBundleDiff.d.mts +0 -16
- package/dist/db/createBundleDiff.mjs +0 -141
- package/dist/db/databasePluginCore.cjs +0 -137
- 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 -321
- package/dist/db/fixedMigratorMongo.mjs +0 -321
- package/dist/db/fixedMigratorShared.cjs +0 -23
- package/dist/db/fixedMigratorShared.mjs +0 -18
- package/dist/db/index.cjs +0 -27
- package/dist/db/index.d.cts +0 -12
- package/dist/db/index.d.mts +0 -12
- package/dist/db/index.mjs +0 -22
- package/dist/db/mongoMigrationExecution.cjs +0 -11
- package/dist/db/mongoMigrationExecution.mjs +0 -11
- package/dist/db/releaseCatalog.d.cts +0 -16
- package/dist/db/releaseCatalog.d.mts +0 -16
- package/dist/db/schema/insightsCollation.cjs +0 -14
- package/dist/db/schema/insightsCollation.mjs +0 -14
- 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 -105
- 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 -275
- package/dist/db/schemaGenerators.mjs +0 -273
- package/dist/db/schemaReadiness.cjs +0 -26
- package/dist/db/schemaReadiness.d.cts +0 -9
- package/dist/db/schemaReadiness.d.mts +0 -9
- package/dist/db/schemaReadiness.mjs +0 -25
- package/dist/db/sqlMigrationExecution.cjs +0 -67
- package/dist/db/sqlMigrationExecution.mjs +0 -67
- package/dist/db/types.cjs +0 -22
- package/dist/db/types.d.cts +0 -118
- package/dist/db/types.d.mts +0 -118
- package/dist/db/types.mjs +0 -19
- package/dist/handlerBundleRoutes.cjs +0 -155
- package/dist/handlerBundleRoutes.mjs +0 -155
- package/dist/handlerReleaseManagementRoutes.cjs +0 -124
- package/dist/handlerReleaseManagementRoutes.mjs +0 -124
- package/dist/insights/domain.d.cts +0 -89
- package/dist/insights/domain.d.mts +0 -89
- package/dist/insights/errors.cjs +0 -15
- package/dist/insights/errors.mjs +0 -14
- package/dist/insights/eventInput.cjs +0 -155
- package/dist/insights/eventInput.mjs +0 -153
- package/dist/insights/provider.cjs +0 -314
- package/dist/insights/provider.d.cts +0 -6
- package/dist/insights/provider.d.mts +0 -6
- package/dist/insights/provider.mjs +0 -314
- package/dist/insights/queryInput.cjs +0 -93
- package/dist/insights/queryInput.mjs +0 -91
- package/dist/insights/routes.cjs +0 -58
- package/dist/insights/routes.mjs +0 -56
- package/dist/insights/types.d.cts +0 -32
- package/dist/insights/types.d.mts +0 -32
- package/dist/schema/dsl.cjs +0 -103
- package/dist/schema/dsl.mjs +0 -87
- package/dist/schema/index.cjs +0 -20
- 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 -406
- package/dist/schema/v1_0_0.mjs +0 -398
- package/src/adapters/databaseConstraintErrors.ts +0 -25
- package/src/adapters/databasePluginTestDatabase.ts +0 -120
- package/src/adapters/databasePluginUtils.spec.ts +0 -29
- package/src/adapters/databasePluginUtils.ts +0 -214
- package/src/adapters/drizzle.spec.ts +0 -336
- package/src/adapters/drizzle.ts +0 -162
- package/src/adapters/drizzleCrud.ts +0 -571
- package/src/adapters/drizzleLazyDB.ts +0 -271
- package/src/adapters/drizzleQuery.ts +0 -164
- package/src/adapters/insightsTransaction.ts +0 -32
- package/src/adapters/kysely.spec.ts +0 -174
- package/src/adapters/kysely.ts +0 -110
- package/src/adapters/kyselyCrud.ts +0 -709
- package/src/adapters/kyselyQuery.ts +0 -128
- package/src/adapters/mongodb.integration.spec.ts +0 -210
- package/src/adapters/mongodb.spec.ts +0 -209
- package/src/adapters/mongodb.ts +0 -138
- package/src/adapters/mongodbCollections.ts +0 -67
- package/src/adapters/mongodbQuery.ts +0 -255
- package/src/adapters/mongodbReads.ts +0 -380
- package/src/adapters/mongodbRows.spec.ts +0 -64
- package/src/adapters/mongodbRows.ts +0 -118
- package/src/adapters/mongodbTestClient.ts +0 -377
- package/src/adapters/mongodbTestFilter.ts +0 -169
- package/src/adapters/mongodbWrites.ts +0 -287
- package/src/adapters/prisma.spec.ts +0 -293
- package/src/adapters/prisma.ts +0 -565
- package/src/adapters/prismaQuery.ts +0 -129
- package/src/adapters/prismaRows.spec.ts +0 -98
- package/src/adapters/prismaRows.ts +0 -337
- package/src/adapters/prismaTestClient.ts +0 -413
- package/src/apiKeys.integration.spec.ts +0 -192
- package/src/apiKeys.spec.ts +0 -162
- package/src/apiKeys.ts +0 -220
- package/src/calculatePagination.ts +0 -34
- package/src/createHotUpdaterCore.ts +0 -246
- package/src/db/bundleRows.spec.ts +0 -164
- package/src/db/bundleRows.ts +0 -10
- package/src/db/createBundleDiff.spec.ts +0 -450
- package/src/db/createBundleDiff.ts +0 -364
- 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 -110
- package/src/db/fixedMigrator.spec.ts +0 -296
- package/src/db/fixedMigrator.ts +0 -147
- package/src/db/fixedMigratorMongo.spec.ts +0 -239
- package/src/db/fixedMigratorMongo.ts +0 -425
- package/src/db/fixedMigratorShared.ts +0 -36
- package/src/db/hotUpdaterSchema.ts +0 -5
- package/src/db/index.spec.ts +0 -1269
- package/src/db/index.ts +0 -47
- package/src/db/mongoMigrationExecution.ts +0 -23
- package/src/db/node-sqlite.d.ts +0 -25
- package/src/db/releaseCatalog.ts +0 -148
- package/src/db/schema/definitions.ts +0 -1
- package/src/db/schema/insightsCollation.ts +0 -21
- package/src/db/schema/mongodb.ts +0 -40
- package/src/db/schema/registry.ts +0 -55
- package/src/db/schema/sql.ts +0 -244
- package/src/db/schema/sqlOperations.ts +0 -63
- package/src/db/schema/types.ts +0 -1
- package/src/db/schemaGenerators.ts +0 -494
- 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 -63
- package/src/db/types.ts +0 -228
- package/src/db/updateArtifacts.spec.ts +0 -359
- package/src/db/updateArtifacts.ts +0 -541
- package/src/handler-standalone.integration.spec.ts +0 -528
- package/src/handler.spec.ts +0 -190
- package/src/handler.testFixtures.ts +0 -30
- package/src/handler.ts +0 -245
- package/src/handlerAuth.integration.spec.ts +0 -33
- package/src/handlerBundleRoutes.ts +0 -259
- package/src/handlerErrors.ts +0 -7
- package/src/handlerManagement.spec.ts +0 -262
- package/src/handlerParameters.ts +0 -105
- package/src/handlerReleaseCatalogRoutes.ts +0 -154
- package/src/handlerReleaseManagementRoutes.ts +0 -213
- package/src/handlerTypes.ts +0 -96
- package/src/handlerVersionRoutes.ts +0 -12
- package/src/index.ts +0 -30
- package/src/insights/domain.ts +0 -103
- package/src/insights/errors.ts +0 -11
- package/src/insights/eventInput.ts +0 -225
- package/src/insights/insights.integration.spec.ts +0 -381
- package/src/insights/provider.spec.ts +0 -385
- package/src/insights/provider.ts +0 -591
- package/src/insights/queryInput.ts +0 -141
- package/src/insights/routes.ts +0 -104
- package/src/insights/types.ts +0 -55
- package/src/internalRouter.ts +0 -104
- package/src/node.spec.ts +0 -119
- package/src/node.ts +0 -111
- package/src/releaseCatalogRoutes.integration.spec.ts +0 -238
- package/src/runtime.spec.ts +0 -194
- package/src/runtime.testFixtures.ts +0 -71
- package/src/schema/dsl-all-versions.spec.ts +0 -37
- 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 -220
- package/src/schema/v1_0_0.ts +0 -529
- package/src/storageAccess.spec.ts +0 -152
- package/src/storageAccess.ts +0 -141
- package/src/types/index.ts +0 -34
- package/src/version.ts +0 -3
|
@@ -1,100 +1,85 @@
|
|
|
1
|
+
import { HotUpdaterConfigError } from "./assembly/configError.mjs";
|
|
2
|
+
import { clientPluginsOf } from "./assembly/clientPlugins.mjs";
|
|
3
|
+
import { assemblePlugins } from "./assembly/assemblePlugins.mjs";
|
|
1
4
|
import { createHotUpdaterHandlers } from "./handler.mjs";
|
|
2
|
-
import { createInsightsProvider } from "./insights/provider.mjs";
|
|
3
|
-
import { authenticateApiKey, createApiKeyManagement, normalizeApiKeyHeaderName } from "./apiKeys.mjs";
|
|
4
|
-
import { createDatabasePluginCore } from "./db/databasePluginCore.mjs";
|
|
5
|
-
import { createSchemaReadinessChecker } from "./db/schemaReadiness.mjs";
|
|
6
|
-
import { isDatabasePlugin } from "./db/types.mjs";
|
|
7
5
|
import { createStorageAccess } from "./storageAccess.mjs";
|
|
8
6
|
import { assertStorageOperations } from "@hot-updater/plugin-core";
|
|
9
7
|
//#region src/createHotUpdaterCore.ts
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
9
|
+
const isAdapter = (value) => isRecord(value) && [
|
|
10
|
+
"fits",
|
|
11
|
+
"get",
|
|
12
|
+
"query",
|
|
13
|
+
"write"
|
|
14
|
+
].every((method) => typeof value[method] === "function");
|
|
15
|
+
/** The configured database, when it runs on the storage engine. */
|
|
16
|
+
const databaseOf = (value) => {
|
|
17
|
+
if (isRecord(value) && typeof value.name === "string") {
|
|
18
|
+
if (isAdapter(value.adapter)) return value;
|
|
19
|
+
if ("core" in value && "fetchAdmin" in value) throw new HotUpdaterConfigError("standaloneRepository reaches a server's admin API from the CLI and console. createHotUpdater needs the server's own database, such as kyselyAdapter(...).");
|
|
20
|
+
}
|
|
21
|
+
throw new HotUpdaterConfigError("database must be a Hot Updater 1.0 database, such as kyselyAdapter(...) or postgres(...). Upgrade the provider package that created it.");
|
|
19
22
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
/** `"public"`, or nothing; a `clientAccess` object says what replaced it. */
|
|
24
|
+
const isPublic = (value) => {
|
|
25
|
+
if (value === void 0) return false;
|
|
26
|
+
if (value === "public") return true;
|
|
27
|
+
throw new HotUpdaterConfigError(isRecord(value) ? "clientAccess objects were removed in 1.0. Set clientAccess: \"public\", or add a plugin that provides clientAuth to plugins." : "clientAccess must be \"public\"; to protect client routes, add a plugin that provides clientAuth to plugins.");
|
|
28
|
+
};
|
|
29
|
+
function createHotUpdater(options) {
|
|
25
30
|
for (const key of ["authorityId", "catalogId"]) if (Object.hasOwn(options, key)) throw new TypeError(`Remove ${key} from createHotUpdater options. Catalog identity is managed internally.`);
|
|
26
|
-
const database = options.database;
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
},
|
|
51
|
-
async findInstallations(input) {
|
|
52
|
-
await assertSchemaReady();
|
|
53
|
-
return plugin.models.insights.findInstallations(input);
|
|
54
|
-
},
|
|
55
|
-
async countInstallations(input) {
|
|
56
|
-
await assertSchemaReady();
|
|
57
|
-
return plugin.models.insights.countInstallations(input);
|
|
58
|
-
},
|
|
59
|
-
async countEvents(input) {
|
|
60
|
-
await assertSchemaReady();
|
|
61
|
-
return plugin.models.insights.countEvents(input);
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
const apiKeys = createApiKeyManagement({
|
|
65
|
-
apiKeys: plugin.models.apiKeys,
|
|
66
|
-
beforeOperation: assertSchemaReady
|
|
67
|
-
});
|
|
68
|
-
const handlers = createHotUpdaterHandlers(core.api, insights, clientAccess.type === "api-key" ? {
|
|
69
|
-
authenticate: (request) => authenticateApiKey({
|
|
70
|
-
apiKeys: plugin.models.apiKeys,
|
|
71
|
-
beforeLookup: assertSchemaReady,
|
|
72
|
-
headerName: clientAccess.headerName,
|
|
73
|
-
request
|
|
74
|
-
}),
|
|
75
|
-
headerName: clientAccess.headerName
|
|
76
|
-
} : void 0, downloadStorageObject);
|
|
77
|
-
const api = Object.assign({
|
|
78
|
-
adapterName: adapterCapabilities.adapterName ?? core.adapterName,
|
|
79
|
-
insights,
|
|
80
|
-
apiKeys,
|
|
81
|
-
handlers
|
|
82
|
-
}, core.api);
|
|
83
|
-
Object.defineProperty(api, hotUpdaterCoreMetadata, {
|
|
84
|
-
enumerable: false,
|
|
85
|
-
value: {
|
|
86
|
-
adapterCapabilities,
|
|
87
|
-
core
|
|
88
|
-
}
|
|
31
|
+
const database = databaseOf(options.database);
|
|
32
|
+
const storage = Object.freeze([...options.storage ?? []]);
|
|
33
|
+
const { downloadStorageObject, readStorageText, resolveFileUrl } = createStorageAccess(storage);
|
|
34
|
+
const publicClients = isPublic(options.clientAccess);
|
|
35
|
+
const configured = Object.freeze([...options.plugins ?? []]);
|
|
36
|
+
const plugins = assemblePlugins(configured, database, { storage: {
|
|
37
|
+
readStorageText,
|
|
38
|
+
resolveFileUrl
|
|
39
|
+
} });
|
|
40
|
+
const clientPlugins = Object.freeze(clientPluginsOf(configured));
|
|
41
|
+
const clientAuth = plugins.clientAuth;
|
|
42
|
+
if (clientAuth !== void 0 && publicClients) throw new HotUpdaterConfigError(`Plugin "${clientAuth.plugin}" provides clientAuth, so remove clientAccess.`);
|
|
43
|
+
if (clientAuth === void 0 && !publicClients) throw new HotUpdaterConfigError("Set clientAccess to \"public\", or add a plugin that provides clientAuth.");
|
|
44
|
+
const varyHeaders = Object.freeze((clientAuth?.varyHeaders ?? []).map((header) => header.toLowerCase()));
|
|
45
|
+
const clientPolicy = clientAuth === void 0 ? void 0 : {
|
|
46
|
+
varyHeaders,
|
|
47
|
+
authenticate: (request) => clientAuth.authenticate(request.headers)
|
|
48
|
+
};
|
|
49
|
+
const handlers = createHotUpdaterHandlers({
|
|
50
|
+
api: { core: plugins.core },
|
|
51
|
+
...clientPolicy === void 0 ? {} : { clientPolicy },
|
|
52
|
+
downloadStorageObject,
|
|
53
|
+
endpoints: plugins.endpoints,
|
|
54
|
+
plugins: Object.keys(plugins.api)
|
|
89
55
|
});
|
|
56
|
+
let serving = false;
|
|
90
57
|
return {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
58
|
+
adapterName: database.name,
|
|
59
|
+
get handlers() {
|
|
60
|
+
if (!serving) {
|
|
61
|
+
for (const adapter of storage) assertStorageOperations(adapter, ["get", "getDownloadUrl"]);
|
|
62
|
+
serving = true;
|
|
63
|
+
}
|
|
64
|
+
return handlers;
|
|
65
|
+
},
|
|
66
|
+
core: plugins.core,
|
|
67
|
+
api: plugins.api,
|
|
68
|
+
flush: plugins.flush,
|
|
69
|
+
database,
|
|
70
|
+
storage,
|
|
71
|
+
plugins: configured,
|
|
72
|
+
clientPlugins,
|
|
73
|
+
clientEndpoints: Object.freeze(plugins.endpoints.filter((endpoint) => endpoint.access === "client").map(({ plugin, method, path }) => Object.freeze({
|
|
74
|
+
plugin,
|
|
75
|
+
method,
|
|
76
|
+
path
|
|
77
|
+
}))),
|
|
78
|
+
...clientAuth === void 0 ? {} : { clientAuth: Object.freeze({
|
|
79
|
+
plugin: clientAuth.plugin,
|
|
80
|
+
varyHeaders
|
|
81
|
+
}) }
|
|
94
82
|
};
|
|
95
83
|
}
|
|
96
|
-
function createHotUpdater(options) {
|
|
97
|
-
return createHotUpdaterCore(options).api;
|
|
98
|
-
}
|
|
99
84
|
//#endregion
|
|
100
|
-
export { createHotUpdater
|
|
85
|
+
export { createHotUpdater };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
2
|
+
//#region src/db/engineDrizzleSchema.ts
|
|
3
|
+
const drizzle = {
|
|
4
|
+
postgresql: {
|
|
5
|
+
module: "drizzle-orm/pg-core",
|
|
6
|
+
table: "pgTable"
|
|
7
|
+
},
|
|
8
|
+
mysql: {
|
|
9
|
+
module: "drizzle-orm/mysql-core",
|
|
10
|
+
table: "mysqlTable"
|
|
11
|
+
},
|
|
12
|
+
sqlite: {
|
|
13
|
+
module: "drizzle-orm/sqlite-core",
|
|
14
|
+
table: "sqliteTable"
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const literal = (value) => JSON.stringify(value);
|
|
18
|
+
/**
|
|
19
|
+
* The Drizzle schema `drizzle-kit` applies for the engine's tables: every
|
|
20
|
+
* column typed exactly as the engine's DDL, keys, indexes, index tables, and
|
|
21
|
+
* the settings table. The engine keeps references itself, so there are no
|
|
22
|
+
* foreign keys. `hot-updater db migrate` then writes only the settings rows.
|
|
23
|
+
*/
|
|
24
|
+
const generateDrizzleEngineSchema = (dialect, schema) => {
|
|
25
|
+
const { module, table: tableFunction } = drizzle[dialect];
|
|
26
|
+
const tables = [...schema.tables, _hot_updater_plugin_core.SETTINGS_TABLE];
|
|
27
|
+
const blocks = [];
|
|
28
|
+
const emit = (shape) => {
|
|
29
|
+
const columns = shape.columns.map((column) => ` ${literal(column.name)}: column(${literal(column.type)})(${literal(column.name)})${column.notNull ? ".notNull()" : ""}${column.default === void 0 ? "" : `.default(${column.default})`},`);
|
|
30
|
+
const at = (name) => `table[${literal(name)}]`;
|
|
31
|
+
const extras = [`primaryKey({ columns: [${shape.key.map(at).join(", ")}] })`, ...shape.indexes.flatMap((index) => index.kind === "index" ? [`${index.unique ? "uniqueIndex" : "index"}(${literal(index.name)}).on(${index.columns.map(at).join(", ")})`] : [])];
|
|
32
|
+
blocks.push(`export const ${shape.name} = ${tableFunction}(${literal(shape.name)}, {\n${columns.join("\n")}\n}, (table) => [\n${extras.map((extra) => ` ${extra},`).join("\n")}\n]);`);
|
|
33
|
+
for (const index of shape.indexes) if (index.kind === "table") emit(index.table);
|
|
34
|
+
};
|
|
35
|
+
for (const shape of (0, _hot_updater_plugin_core.sqlTableShapes)(dialect, tables)) emit(shape);
|
|
36
|
+
return [
|
|
37
|
+
"// Generated by `hot-updater db generate` from Hot Updater's schema. Do not edit.",
|
|
38
|
+
`import { ${[
|
|
39
|
+
"customType",
|
|
40
|
+
"index",
|
|
41
|
+
"primaryKey",
|
|
42
|
+
"uniqueIndex"
|
|
43
|
+
].filter((name) => name === "customType" ? true : blocks.some((block) => block.includes(`${name}(`))).concat(tableFunction).sort().join(", ")} } from ${literal(module)};`,
|
|
44
|
+
"",
|
|
45
|
+
"/** A column typed exactly as Hot Updater's SQL schema declares it. */",
|
|
46
|
+
"const column = (type: string) =>",
|
|
47
|
+
" customType<{ data: unknown; driverData: unknown }>({ dataType: () => type });",
|
|
48
|
+
"",
|
|
49
|
+
...blocks.flatMap((block) => [block, ""])
|
|
50
|
+
].join("\n");
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
exports.generateDrizzleEngineSchema = generateDrizzleEngineSchema;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { SETTINGS_TABLE, sqlTableShapes } from "@hot-updater/plugin-core";
|
|
2
|
+
//#region src/db/engineDrizzleSchema.ts
|
|
3
|
+
const drizzle = {
|
|
4
|
+
postgresql: {
|
|
5
|
+
module: "drizzle-orm/pg-core",
|
|
6
|
+
table: "pgTable"
|
|
7
|
+
},
|
|
8
|
+
mysql: {
|
|
9
|
+
module: "drizzle-orm/mysql-core",
|
|
10
|
+
table: "mysqlTable"
|
|
11
|
+
},
|
|
12
|
+
sqlite: {
|
|
13
|
+
module: "drizzle-orm/sqlite-core",
|
|
14
|
+
table: "sqliteTable"
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const literal = (value) => JSON.stringify(value);
|
|
18
|
+
/**
|
|
19
|
+
* The Drizzle schema `drizzle-kit` applies for the engine's tables: every
|
|
20
|
+
* column typed exactly as the engine's DDL, keys, indexes, index tables, and
|
|
21
|
+
* the settings table. The engine keeps references itself, so there are no
|
|
22
|
+
* foreign keys. `hot-updater db migrate` then writes only the settings rows.
|
|
23
|
+
*/
|
|
24
|
+
const generateDrizzleEngineSchema = (dialect, schema) => {
|
|
25
|
+
const { module, table: tableFunction } = drizzle[dialect];
|
|
26
|
+
const tables = [...schema.tables, SETTINGS_TABLE];
|
|
27
|
+
const blocks = [];
|
|
28
|
+
const emit = (shape) => {
|
|
29
|
+
const columns = shape.columns.map((column) => ` ${literal(column.name)}: column(${literal(column.type)})(${literal(column.name)})${column.notNull ? ".notNull()" : ""}${column.default === void 0 ? "" : `.default(${column.default})`},`);
|
|
30
|
+
const at = (name) => `table[${literal(name)}]`;
|
|
31
|
+
const extras = [`primaryKey({ columns: [${shape.key.map(at).join(", ")}] })`, ...shape.indexes.flatMap((index) => index.kind === "index" ? [`${index.unique ? "uniqueIndex" : "index"}(${literal(index.name)}).on(${index.columns.map(at).join(", ")})`] : [])];
|
|
32
|
+
blocks.push(`export const ${shape.name} = ${tableFunction}(${literal(shape.name)}, {\n${columns.join("\n")}\n}, (table) => [\n${extras.map((extra) => ` ${extra},`).join("\n")}\n]);`);
|
|
33
|
+
for (const index of shape.indexes) if (index.kind === "table") emit(index.table);
|
|
34
|
+
};
|
|
35
|
+
for (const shape of sqlTableShapes(dialect, tables)) emit(shape);
|
|
36
|
+
return [
|
|
37
|
+
"// Generated by `hot-updater db generate` from Hot Updater's schema. Do not edit.",
|
|
38
|
+
`import { ${[
|
|
39
|
+
"customType",
|
|
40
|
+
"index",
|
|
41
|
+
"primaryKey",
|
|
42
|
+
"uniqueIndex"
|
|
43
|
+
].filter((name) => name === "customType" ? true : blocks.some((block) => block.includes(`${name}(`))).concat(tableFunction).sort().join(", ")} } from ${literal(module)};`,
|
|
44
|
+
"",
|
|
45
|
+
"/** A column typed exactly as Hot Updater's SQL schema declares it. */",
|
|
46
|
+
"const column = (type: string) =>",
|
|
47
|
+
" customType<{ data: unknown; driverData: unknown }>({ dataType: () => type });",
|
|
48
|
+
"",
|
|
49
|
+
...blocks.flatMap((block) => [block, ""])
|
|
50
|
+
].join("\n");
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { generateDrizzleEngineSchema };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
2
|
+
//#region src/db/enginePrismaSchema.ts
|
|
3
|
+
const SCALARS = {
|
|
4
|
+
TEXT: "String",
|
|
5
|
+
INTEGER: "BigInt",
|
|
6
|
+
REAL: "Float",
|
|
7
|
+
bigint: "BigInt",
|
|
8
|
+
"double precision": "Float",
|
|
9
|
+
double: "Float",
|
|
10
|
+
boolean: "Boolean",
|
|
11
|
+
jsonb: "Json",
|
|
12
|
+
json: "Json"
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A column's Prisma type from the DDL type the shared SQL schema gives it.
|
|
16
|
+
* MySQL's ASCII keys become `VarBinary`: the same bytes and order as
|
|
17
|
+
* `ascii_bin`, within InnoDB's key limit without a character set.
|
|
18
|
+
*/
|
|
19
|
+
const prismaColumn = (provider, { type }) => {
|
|
20
|
+
const length = /^varchar\((\d+)\)/u.exec(type)?.[1];
|
|
21
|
+
if (provider === "mysql" && type.includes("CHARACTER SET")) {
|
|
22
|
+
if (type.includes("CHARACTER SET ascii") && length) return {
|
|
23
|
+
scalar: "Bytes",
|
|
24
|
+
native: `@db.VarBinary(${length})`
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
scalar: "String",
|
|
28
|
+
native: length ? `@db.VarChar(${length})` : "@db.LongText",
|
|
29
|
+
collate: true
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (provider === "postgresql" && type.includes("COLLATE")) return {
|
|
33
|
+
scalar: "String",
|
|
34
|
+
...length ? { native: `@db.VarChar(${length})` } : {},
|
|
35
|
+
collate: true
|
|
36
|
+
};
|
|
37
|
+
return { scalar: SCALARS[type] ?? "String" };
|
|
38
|
+
};
|
|
39
|
+
/** Prisma fields start with a letter: `_v` becomes `hu_v`, mapped back to `_v`. */
|
|
40
|
+
const fieldName = (column) => column.startsWith("_") ? `hu${column}` : column;
|
|
41
|
+
const list = (columns) => `[${columns.map(fieldName).join(", ")}]`;
|
|
42
|
+
const flatten = (shapes) => shapes.flatMap((shape) => [shape, ...flatten(shape.indexes.flatMap((index) => index.kind === "table" ? [index.table] : []))]);
|
|
43
|
+
const shapesOf = (provider, schema) => flatten((0, _hot_updater_plugin_core.sqlTableShapes)(provider, [...schema.tables, _hot_updater_plugin_core.SETTINGS_TABLE]));
|
|
44
|
+
const renderField = (provider, column) => {
|
|
45
|
+
const { scalar, native } = prismaColumn(provider, column);
|
|
46
|
+
const name = fieldName(column.name);
|
|
47
|
+
return [
|
|
48
|
+
`${name} ${scalar}${column.notNull ? "" : "?"}`,
|
|
49
|
+
...native === void 0 ? [] : [native],
|
|
50
|
+
...column.default === void 0 ? [] : [`@default(${column.default})`],
|
|
51
|
+
...name === column.name ? [] : [`@map(${JSON.stringify(column.name)})`]
|
|
52
|
+
].join(" ");
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Hot Updater's tables as Prisma models, for `prisma db push` or
|
|
56
|
+
* `prisma migrate`: keys, indexes, index tables, and the settings table.
|
|
57
|
+
* The engine keeps references itself, so the models have no relations.
|
|
58
|
+
*/
|
|
59
|
+
const generatePrismaEngineSchema = (provider, schema) => shapesOf(provider, schema).map((shape) => {
|
|
60
|
+
const lines = [
|
|
61
|
+
...shape.columns.map((column) => renderField(provider, column)),
|
|
62
|
+
`@@id(${list(shape.key)})`,
|
|
63
|
+
...shape.indexes.flatMap((index) => index.kind === "index" ? [`@@${index.unique ? "unique" : "index"}(${list(index.columns)}, map: ${JSON.stringify(index.name)})`] : [])
|
|
64
|
+
];
|
|
65
|
+
return `model ${shape.name} {\n${lines.map((line) => ` ${line}`).join("\n")}\n}`;
|
|
66
|
+
}).join("\n\n");
|
|
67
|
+
/**
|
|
68
|
+
* The collations Prisma cannot declare, which `hot-updater db migrate` sets
|
|
69
|
+
* after Prisma created the tables: `COLLATE "C"` on PostgreSQL and binary
|
|
70
|
+
* UTF-8 on MySQL, so strings compare by their bytes as the engine expects.
|
|
71
|
+
* The settings table is only read by key, and the migrator has already read
|
|
72
|
+
* it: altering it would invalidate PostgreSQL's cached plan for that read.
|
|
73
|
+
*/
|
|
74
|
+
const prismaCollationStatements = (provider, schema) => {
|
|
75
|
+
if (provider !== "postgresql" && provider !== "mysql") return [];
|
|
76
|
+
const quote = (name) => (0, _hot_updater_plugin_core.quoteSql)(provider, name);
|
|
77
|
+
return shapesOf(provider, schema).filter((shape) => shape.name !== _hot_updater_plugin_core.SETTINGS_TABLE.name).flatMap((shape) => {
|
|
78
|
+
const changes = shape.columns.filter((column) => prismaColumn(provider, column).collate).map((column) => provider === "postgresql" ? `ALTER COLUMN ${quote(column.name)} TYPE ${column.type}` : `MODIFY ${quote(column.name)} ${column.type}${column.notNull ? " NOT NULL" : " NULL"}`);
|
|
79
|
+
return changes.length === 0 ? [] : [`ALTER TABLE ${quote(shape.name)} ${changes.join(", ")}`];
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
//#endregion
|
|
83
|
+
exports.generatePrismaEngineSchema = generatePrismaEngineSchema;
|
|
84
|
+
exports.prismaCollationStatements = prismaCollationStatements;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { SETTINGS_TABLE, quoteSql, sqlTableShapes } from "@hot-updater/plugin-core";
|
|
2
|
+
//#region src/db/enginePrismaSchema.ts
|
|
3
|
+
const SCALARS = {
|
|
4
|
+
TEXT: "String",
|
|
5
|
+
INTEGER: "BigInt",
|
|
6
|
+
REAL: "Float",
|
|
7
|
+
bigint: "BigInt",
|
|
8
|
+
"double precision": "Float",
|
|
9
|
+
double: "Float",
|
|
10
|
+
boolean: "Boolean",
|
|
11
|
+
jsonb: "Json",
|
|
12
|
+
json: "Json"
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A column's Prisma type from the DDL type the shared SQL schema gives it.
|
|
16
|
+
* MySQL's ASCII keys become `VarBinary`: the same bytes and order as
|
|
17
|
+
* `ascii_bin`, within InnoDB's key limit without a character set.
|
|
18
|
+
*/
|
|
19
|
+
const prismaColumn = (provider, { type }) => {
|
|
20
|
+
const length = /^varchar\((\d+)\)/u.exec(type)?.[1];
|
|
21
|
+
if (provider === "mysql" && type.includes("CHARACTER SET")) {
|
|
22
|
+
if (type.includes("CHARACTER SET ascii") && length) return {
|
|
23
|
+
scalar: "Bytes",
|
|
24
|
+
native: `@db.VarBinary(${length})`
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
scalar: "String",
|
|
28
|
+
native: length ? `@db.VarChar(${length})` : "@db.LongText",
|
|
29
|
+
collate: true
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (provider === "postgresql" && type.includes("COLLATE")) return {
|
|
33
|
+
scalar: "String",
|
|
34
|
+
...length ? { native: `@db.VarChar(${length})` } : {},
|
|
35
|
+
collate: true
|
|
36
|
+
};
|
|
37
|
+
return { scalar: SCALARS[type] ?? "String" };
|
|
38
|
+
};
|
|
39
|
+
/** Prisma fields start with a letter: `_v` becomes `hu_v`, mapped back to `_v`. */
|
|
40
|
+
const fieldName = (column) => column.startsWith("_") ? `hu${column}` : column;
|
|
41
|
+
const list = (columns) => `[${columns.map(fieldName).join(", ")}]`;
|
|
42
|
+
const flatten = (shapes) => shapes.flatMap((shape) => [shape, ...flatten(shape.indexes.flatMap((index) => index.kind === "table" ? [index.table] : []))]);
|
|
43
|
+
const shapesOf = (provider, schema) => flatten(sqlTableShapes(provider, [...schema.tables, SETTINGS_TABLE]));
|
|
44
|
+
const renderField = (provider, column) => {
|
|
45
|
+
const { scalar, native } = prismaColumn(provider, column);
|
|
46
|
+
const name = fieldName(column.name);
|
|
47
|
+
return [
|
|
48
|
+
`${name} ${scalar}${column.notNull ? "" : "?"}`,
|
|
49
|
+
...native === void 0 ? [] : [native],
|
|
50
|
+
...column.default === void 0 ? [] : [`@default(${column.default})`],
|
|
51
|
+
...name === column.name ? [] : [`@map(${JSON.stringify(column.name)})`]
|
|
52
|
+
].join(" ");
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Hot Updater's tables as Prisma models, for `prisma db push` or
|
|
56
|
+
* `prisma migrate`: keys, indexes, index tables, and the settings table.
|
|
57
|
+
* The engine keeps references itself, so the models have no relations.
|
|
58
|
+
*/
|
|
59
|
+
const generatePrismaEngineSchema = (provider, schema) => shapesOf(provider, schema).map((shape) => {
|
|
60
|
+
const lines = [
|
|
61
|
+
...shape.columns.map((column) => renderField(provider, column)),
|
|
62
|
+
`@@id(${list(shape.key)})`,
|
|
63
|
+
...shape.indexes.flatMap((index) => index.kind === "index" ? [`@@${index.unique ? "unique" : "index"}(${list(index.columns)}, map: ${JSON.stringify(index.name)})`] : [])
|
|
64
|
+
];
|
|
65
|
+
return `model ${shape.name} {\n${lines.map((line) => ` ${line}`).join("\n")}\n}`;
|
|
66
|
+
}).join("\n\n");
|
|
67
|
+
/**
|
|
68
|
+
* The collations Prisma cannot declare, which `hot-updater db migrate` sets
|
|
69
|
+
* after Prisma created the tables: `COLLATE "C"` on PostgreSQL and binary
|
|
70
|
+
* UTF-8 on MySQL, so strings compare by their bytes as the engine expects.
|
|
71
|
+
* The settings table is only read by key, and the migrator has already read
|
|
72
|
+
* it: altering it would invalidate PostgreSQL's cached plan for that read.
|
|
73
|
+
*/
|
|
74
|
+
const prismaCollationStatements = (provider, schema) => {
|
|
75
|
+
if (provider !== "postgresql" && provider !== "mysql") return [];
|
|
76
|
+
const quote = (name) => quoteSql(provider, name);
|
|
77
|
+
return shapesOf(provider, schema).filter((shape) => shape.name !== SETTINGS_TABLE.name).flatMap((shape) => {
|
|
78
|
+
const changes = shape.columns.filter((column) => prismaColumn(provider, column).collate).map((column) => provider === "postgresql" ? `ALTER COLUMN ${quote(column.name)} TYPE ${column.type}` : `MODIFY ${quote(column.name)} ${column.type}${column.notNull ? " NOT NULL" : " NULL"}`);
|
|
79
|
+
return changes.length === 0 ? [] : [`ALTER TABLE ${quote(shape.name)} ${changes.join(", ")}`];
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
//#endregion
|
|
83
|
+
export { generatePrismaEngineSchema, prismaCollationStatements };
|
|
@@ -1,65 +1,42 @@
|
|
|
1
|
-
const require_updateArtifacts = require("./updateArtifacts.cjs");
|
|
2
1
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
3
|
-
let
|
|
2
|
+
let _hot_updater_protocol = require("@hot-updater/protocol");
|
|
4
3
|
//#region src/db/releaseCatalog.ts
|
|
4
|
+
/** A stored catalog payload, checked against its strategy's shape. */
|
|
5
5
|
const parseCompiledCatalog = (payload, strategy) => {
|
|
6
6
|
const parsed = JSON.parse(payload);
|
|
7
|
-
if (typeof parsed !== "object" || parsed === null || Reflect.get(parsed, "schemaVersion") !==
|
|
7
|
+
if (typeof parsed !== "object" || parsed === null || Reflect.get(parsed, "schemaVersion") !== _hot_updater_protocol.RELEASE_CATALOG_SCHEMA_VERSION || Reflect.get(parsed, "strategy") !== strategy || Reflect.get(parsed, "fallbackPolicy") !== _hot_updater_protocol.RELEASE_CATALOG_FALLBACK_POLICY || !Array.isArray(Reflect.get(parsed, "releaseDescriptors"))) throw new Error("Stored Release catalog payload is invalid");
|
|
8
8
|
if (strategy === "APP_VERSION" && !Array.isArray(Reflect.get(parsed, "segments"))) throw new Error("Stored app-version Release catalog is invalid");
|
|
9
9
|
if (strategy === "FINGERPRINT" && !Array.isArray(Reflect.get(parsed, "releaseIndexes"))) throw new Error("Stored fingerprint Release catalog is invalid");
|
|
10
10
|
return parsed;
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
/** The scope key an update check reads. */
|
|
13
|
+
const releaseCatalogScopeKeyOf = (input) => input.strategy === "APP_VERSION" ? (0, _hot_updater_protocol.createReleaseCatalogScopeKey)({
|
|
14
|
+
channelKey: input.channelKey,
|
|
15
|
+
platform: input.platform,
|
|
16
|
+
strategy: "APP_VERSION"
|
|
17
|
+
}) : (0, _hot_updater_protocol.createReleaseCatalogScopeKey)({
|
|
18
|
+
channelKey: input.channelKey,
|
|
19
|
+
fingerprintHash: input.fingerprintHash,
|
|
20
|
+
platform: input.platform,
|
|
21
|
+
strategy: "FINGERPRINT"
|
|
22
|
+
});
|
|
23
|
+
/** Projects a stored catalog row for one update check; null when the row is not this scope's. */
|
|
24
|
+
const projectReleaseCatalogRow = (row, input, scopeKey = releaseCatalogScopeKeyOf(input)) => {
|
|
24
25
|
if (row === null || row.platform !== input.platform || row.strategy !== input.strategy || row.channel_key !== input.channelKey || row.scope_key !== scopeKey || row.fingerprint_hash !== (input.strategy === "FINGERPRINT" ? input.fingerprintHash : null)) return null;
|
|
25
26
|
const compiled = parseCompiledCatalog(row.payload, input.strategy);
|
|
26
|
-
const
|
|
27
|
-
const rollbackReleases = (0, _hot_updater_plugin_core.projectCompiledRollbackCatalog)(compiled, input.strategy === "APP_VERSION" ? input.appVersion : void 0);
|
|
27
|
+
const appVersion = input.strategy === "APP_VERSION" ? input.appVersion : void 0;
|
|
28
28
|
return {
|
|
29
29
|
catalogId: row.catalog_id,
|
|
30
30
|
catalogHash: row.catalog_hash,
|
|
31
|
-
fallbackPolicy:
|
|
31
|
+
fallbackPolicy: _hot_updater_protocol.RELEASE_CATALOG_FALLBACK_POLICY,
|
|
32
32
|
generation: row.generation,
|
|
33
|
-
releases,
|
|
34
|
-
rollbackReleases,
|
|
35
|
-
schemaVersion:
|
|
33
|
+
releases: (0, _hot_updater_plugin_core.projectCompiledCatalog)(compiled, appVersion),
|
|
34
|
+
rollbackReleases: (0, _hot_updater_plugin_core.projectCompiledRollbackCatalog)(compiled, appVersion),
|
|
35
|
+
schemaVersion: _hot_updater_protocol.RELEASE_CATALOG_SCHEMA_VERSION,
|
|
36
36
|
scopeKey
|
|
37
37
|
};
|
|
38
38
|
};
|
|
39
|
-
const createArtifactResolver = (input) => {
|
|
40
|
-
const databaseClient = (0, _hot_updater_plugin_core.createDatabaseClient)(input.database);
|
|
41
|
-
return async (targetBundleId, currentBundleId) => {
|
|
42
|
-
const [targetBundle, currentBundle] = await Promise.all([databaseClient.getBundleById(targetBundleId), currentBundleId === _hot_updater_core.NIL_UUID ? null : databaseClient.getBundleById(currentBundleId)]);
|
|
43
|
-
if (targetBundle === null) return null;
|
|
44
|
-
const fileUrl = await input.resolveFileUrl(targetBundle.storageUri);
|
|
45
|
-
const base = {
|
|
46
|
-
fileHash: targetBundle.fileHash,
|
|
47
|
-
fileUrl
|
|
48
|
-
};
|
|
49
|
-
if (input.readStorageText === void 0) return base;
|
|
50
|
-
const manifest = await require_updateArtifacts.resolveManifestArtifacts({
|
|
51
|
-
archiveUrlUsable: fileUrl !== null,
|
|
52
|
-
currentBundle,
|
|
53
|
-
readStorageText: input.readStorageText,
|
|
54
|
-
resolveFileUrl: input.resolveFileUrl,
|
|
55
|
-
targetBundle
|
|
56
|
-
});
|
|
57
|
-
return manifest === null ? base : {
|
|
58
|
-
...base,
|
|
59
|
-
...manifest
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
39
|
//#endregion
|
|
64
|
-
exports.
|
|
65
|
-
exports.
|
|
40
|
+
exports.parseCompiledCatalog = parseCompiledCatalog;
|
|
41
|
+
exports.projectReleaseCatalogRow = projectReleaseCatalogRow;
|
|
42
|
+
exports.releaseCatalogScopeKeyOf = releaseCatalogScopeKeyOf;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { NIL_UUID, RELEASE_CATALOG_FALLBACK_POLICY, RELEASE_CATALOG_SCHEMA_VERSION, createReleaseCatalogScopeKey } from "@hot-updater/core";
|
|
1
|
+
import { projectCompiledCatalog, projectCompiledRollbackCatalog } from "@hot-updater/plugin-core";
|
|
2
|
+
import { RELEASE_CATALOG_FALLBACK_POLICY, RELEASE_CATALOG_SCHEMA_VERSION, createReleaseCatalogScopeKey } from "@hot-updater/protocol";
|
|
4
3
|
//#region src/db/releaseCatalog.ts
|
|
4
|
+
/** A stored catalog payload, checked against its strategy's shape. */
|
|
5
5
|
const parseCompiledCatalog = (payload, strategy) => {
|
|
6
6
|
const parsed = JSON.parse(payload);
|
|
7
7
|
if (typeof parsed !== "object" || parsed === null || Reflect.get(parsed, "schemaVersion") !== RELEASE_CATALOG_SCHEMA_VERSION || Reflect.get(parsed, "strategy") !== strategy || Reflect.get(parsed, "fallbackPolicy") !== RELEASE_CATALOG_FALLBACK_POLICY || !Array.isArray(Reflect.get(parsed, "releaseDescriptors"))) throw new Error("Stored Release catalog payload is invalid");
|
|
@@ -9,56 +9,32 @@ const parseCompiledCatalog = (payload, strategy) => {
|
|
|
9
9
|
if (strategy === "FINGERPRINT" && !Array.isArray(Reflect.get(parsed, "releaseIndexes"))) throw new Error("Stored fingerprint Release catalog is invalid");
|
|
10
10
|
return parsed;
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
/** The scope key an update check reads. */
|
|
13
|
+
const releaseCatalogScopeKeyOf = (input) => input.strategy === "APP_VERSION" ? createReleaseCatalogScopeKey({
|
|
14
|
+
channelKey: input.channelKey,
|
|
15
|
+
platform: input.platform,
|
|
16
|
+
strategy: "APP_VERSION"
|
|
17
|
+
}) : createReleaseCatalogScopeKey({
|
|
18
|
+
channelKey: input.channelKey,
|
|
19
|
+
fingerprintHash: input.fingerprintHash,
|
|
20
|
+
platform: input.platform,
|
|
21
|
+
strategy: "FINGERPRINT"
|
|
22
|
+
});
|
|
23
|
+
/** Projects a stored catalog row for one update check; null when the row is not this scope's. */
|
|
24
|
+
const projectReleaseCatalogRow = (row, input, scopeKey = releaseCatalogScopeKeyOf(input)) => {
|
|
24
25
|
if (row === null || row.platform !== input.platform || row.strategy !== input.strategy || row.channel_key !== input.channelKey || row.scope_key !== scopeKey || row.fingerprint_hash !== (input.strategy === "FINGERPRINT" ? input.fingerprintHash : null)) return null;
|
|
25
26
|
const compiled = parseCompiledCatalog(row.payload, input.strategy);
|
|
26
|
-
const
|
|
27
|
-
const rollbackReleases = projectCompiledRollbackCatalog(compiled, input.strategy === "APP_VERSION" ? input.appVersion : void 0);
|
|
27
|
+
const appVersion = input.strategy === "APP_VERSION" ? input.appVersion : void 0;
|
|
28
28
|
return {
|
|
29
29
|
catalogId: row.catalog_id,
|
|
30
30
|
catalogHash: row.catalog_hash,
|
|
31
31
|
fallbackPolicy: RELEASE_CATALOG_FALLBACK_POLICY,
|
|
32
32
|
generation: row.generation,
|
|
33
|
-
releases,
|
|
34
|
-
rollbackReleases,
|
|
33
|
+
releases: projectCompiledCatalog(compiled, appVersion),
|
|
34
|
+
rollbackReleases: projectCompiledRollbackCatalog(compiled, appVersion),
|
|
35
35
|
schemaVersion: RELEASE_CATALOG_SCHEMA_VERSION,
|
|
36
36
|
scopeKey
|
|
37
37
|
};
|
|
38
38
|
};
|
|
39
|
-
const createArtifactResolver = (input) => {
|
|
40
|
-
const databaseClient = createDatabaseClient(input.database);
|
|
41
|
-
return async (targetBundleId, currentBundleId) => {
|
|
42
|
-
const [targetBundle, currentBundle] = await Promise.all([databaseClient.getBundleById(targetBundleId), currentBundleId === NIL_UUID ? null : databaseClient.getBundleById(currentBundleId)]);
|
|
43
|
-
if (targetBundle === null) return null;
|
|
44
|
-
const fileUrl = await input.resolveFileUrl(targetBundle.storageUri);
|
|
45
|
-
const base = {
|
|
46
|
-
fileHash: targetBundle.fileHash,
|
|
47
|
-
fileUrl
|
|
48
|
-
};
|
|
49
|
-
if (input.readStorageText === void 0) return base;
|
|
50
|
-
const manifest = await resolveManifestArtifacts({
|
|
51
|
-
archiveUrlUsable: fileUrl !== null,
|
|
52
|
-
currentBundle,
|
|
53
|
-
readStorageText: input.readStorageText,
|
|
54
|
-
resolveFileUrl: input.resolveFileUrl,
|
|
55
|
-
targetBundle
|
|
56
|
-
});
|
|
57
|
-
return manifest === null ? base : {
|
|
58
|
-
...base,
|
|
59
|
-
...manifest
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
39
|
//#endregion
|
|
64
|
-
export {
|
|
40
|
+
export { parseCompiledCatalog, projectReleaseCatalogRow, releaseCatalogScopeKeyOf };
|