@hot-updater/server 0.36.7 → 1.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/databaseConstraintErrors.cjs +23 -0
- package/dist/adapters/databaseConstraintErrors.mjs +21 -0
- package/dist/adapters/databasePluginUtils.cjs +117 -0
- package/dist/adapters/databasePluginUtils.mjs +106 -0
- package/dist/adapters/drizzle.cjs +53 -176
- package/dist/adapters/drizzle.d.cts +6 -4
- package/dist/adapters/drizzle.d.mts +6 -4
- package/dist/adapters/drizzle.mjs +54 -177
- package/dist/adapters/drizzleCrud.cjs +250 -0
- package/dist/adapters/drizzleCrud.mjs +249 -0
- package/dist/adapters/drizzleLazyDB.cjs +84 -36
- package/dist/adapters/drizzleLazyDB.mjs +84 -36
- package/dist/adapters/drizzleQuery.cjs +68 -0
- package/dist/adapters/drizzleQuery.mjs +67 -0
- package/dist/adapters/kysely.cjs +18 -138
- package/dist/adapters/kysely.d.cts +3 -12
- package/dist/adapters/kysely.d.mts +3 -12
- package/dist/adapters/kysely.mjs +19 -139
- package/dist/adapters/kyselyCrud.cjs +254 -0
- package/dist/adapters/kyselyCrud.mjs +253 -0
- package/dist/adapters/kyselyQuery.cjs +56 -0
- package/dist/adapters/kyselyQuery.mjs +55 -0
- package/dist/adapters/mongodb.cjs +21 -174
- package/dist/adapters/mongodb.d.cts +3 -2
- package/dist/adapters/mongodb.d.mts +3 -2
- package/dist/adapters/mongodb.mjs +21 -174
- package/dist/adapters/mongodbCollections.cjs +36 -0
- package/dist/adapters/mongodbCollections.mjs +30 -0
- package/dist/adapters/mongodbQuery.cjs +77 -0
- package/dist/adapters/mongodbQuery.mjs +70 -0
- package/dist/adapters/mongodbReads.cjs +148 -0
- package/dist/adapters/mongodbReads.mjs +147 -0
- package/dist/adapters/mongodbWrites.cjs +134 -0
- package/dist/adapters/mongodbWrites.mjs +133 -0
- package/dist/adapters/prisma.cjs +205 -180
- package/dist/adapters/prisma.d.cts +3 -3
- package/dist/adapters/prisma.d.mts +3 -3
- package/dist/adapters/prisma.mjs +206 -181
- package/dist/adapters/prismaQuery.cjs +58 -0
- package/dist/adapters/prismaQuery.mjs +56 -0
- package/dist/adapters/prismaRows.cjs +198 -0
- package/dist/adapters/prismaRows.mjs +188 -0
- package/dist/analytics/bounded/activeOverview.cjs +87 -0
- package/dist/analytics/bounded/activeOverview.mjs +85 -0
- package/dist/analytics/bounded/installationSearch.cjs +42 -0
- package/dist/analytics/bounded/installationSearch.mjs +42 -0
- package/dist/analytics/bounded/persistence.cjs +39 -0
- package/dist/analytics/bounded/persistence.mjs +38 -0
- package/dist/analytics/bounded/provider.cjs +170 -0
- package/dist/analytics/bounded/provider.d.cts +7 -0
- package/dist/analytics/bounded/provider.d.mts +7 -0
- package/dist/analytics/bounded/provider.mjs +170 -0
- package/dist/analytics/bounded/scan.cjs +144 -0
- package/dist/analytics/bounded/scan.mjs +138 -0
- package/dist/analytics/domain.d.cts +121 -0
- package/dist/analytics/domain.d.mts +121 -0
- package/dist/analytics/errors.cjs +22 -0
- package/dist/analytics/errors.mjs +20 -0
- package/dist/analytics/eventInput.cjs +111 -0
- package/dist/analytics/eventInput.mjs +111 -0
- package/dist/analytics/persistence.d.cts +6 -0
- package/dist/analytics/persistence.d.mts +6 -0
- package/dist/analytics/queryInput.cjs +58 -0
- package/dist/analytics/queryInput.mjs +55 -0
- package/dist/analytics/routes.cjs +63 -0
- package/dist/analytics/routes.mjs +61 -0
- package/dist/analytics/types.d.cts +17 -0
- package/dist/analytics/types.d.mts +17 -0
- package/dist/apiKeys.cjs +139 -0
- package/dist/apiKeys.d.cts +50 -0
- package/dist/apiKeys.d.mts +50 -0
- package/dist/apiKeys.mjs +133 -0
- package/dist/createHotUpdaterCore.cjs +48 -26
- package/dist/createHotUpdaterCore.d.cts +49 -17
- package/dist/createHotUpdaterCore.d.mts +49 -17
- package/dist/createHotUpdaterCore.mjs +51 -29
- package/dist/db/createBundleDiff.cjs +45 -68
- package/dist/db/createBundleDiff.d.cts +3 -3
- package/dist/db/createBundleDiff.d.mts +3 -3
- package/dist/db/createBundleDiff.mjs +47 -68
- package/dist/db/databasePluginCore.cjs +138 -0
- package/dist/db/databasePluginCore.mjs +137 -0
- package/dist/db/fixedMigrator.cjs +36 -93
- package/dist/db/fixedMigrator.mjs +36 -93
- package/dist/db/fixedMigratorMongo.cjs +319 -0
- package/dist/db/fixedMigratorMongo.mjs +319 -0
- package/dist/db/fixedMigratorShared.cjs +23 -0
- package/dist/db/fixedMigratorShared.mjs +18 -0
- package/dist/db/mongoMigrationExecution.cjs +11 -0
- package/dist/db/mongoMigrationExecution.mjs +11 -0
- package/dist/db/releaseCatalog.cjs +66 -0
- package/dist/db/releaseCatalog.d.cts +17 -0
- package/dist/db/releaseCatalog.d.mts +17 -0
- package/dist/db/releaseCatalog.mjs +64 -0
- package/dist/db/schema/mongodb.cjs +14 -6
- package/dist/db/schema/mongodb.mjs +14 -6
- package/dist/db/schema/registry.cjs +0 -2
- package/dist/db/schema/registry.mjs +1 -2
- package/dist/db/schema/sql.cjs +31 -14
- package/dist/db/schema/sql.mjs +32 -13
- package/dist/db/schema/sqlOperations.cjs +4 -4
- package/dist/db/schema/sqlOperations.mjs +5 -5
- package/dist/db/schemaGenerators.cjs +52 -18
- package/dist/db/schemaGenerators.mjs +52 -18
- package/dist/db/schemaReadiness.cjs +4 -3
- package/dist/db/schemaReadiness.mjs +4 -3
- package/dist/db/sqlMigrationExecution.cjs +67 -0
- package/dist/db/sqlMigrationExecution.mjs +66 -0
- package/dist/db/types.cjs +2 -6
- package/dist/db/types.d.cts +60 -16
- package/dist/db/types.d.mts +60 -16
- package/dist/db/types.mjs +3 -6
- package/dist/db/updateArtifacts.cjs +114 -60
- package/dist/db/updateArtifacts.mjs +117 -62
- package/dist/handler.cjs +108 -282
- package/dist/handler.d.cts +3 -46
- package/dist/handler.d.mts +3 -46
- package/dist/handler.mjs +107 -281
- package/dist/handlerBundleRoutes.cjs +155 -0
- package/dist/handlerBundleRoutes.mjs +155 -0
- package/dist/handlerErrors.cjs +9 -0
- package/dist/handlerErrors.mjs +9 -0
- package/dist/handlerParameters.cjs +39 -0
- package/dist/handlerParameters.mjs +34 -0
- package/dist/handlerReleaseCatalogRoutes.cjs +111 -0
- package/dist/handlerReleaseCatalogRoutes.mjs +110 -0
- package/dist/handlerReleaseManagementRoutes.cjs +125 -0
- package/dist/handlerReleaseManagementRoutes.mjs +124 -0
- package/dist/handlerTypes.d.cts +63 -0
- package/dist/handlerTypes.d.mts +63 -0
- package/dist/handlerVersionRoutes.cjs +10 -0
- package/dist/handlerVersionRoutes.d.cts +4 -0
- package/dist/handlerVersionRoutes.d.mts +4 -0
- package/dist/handlerVersionRoutes.mjs +9 -0
- package/dist/index.cjs +10 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.mts +9 -3
- package/dist/index.mjs +5 -2
- package/dist/node.cjs +19 -12
- package/dist/node.d.cts +15 -10
- package/dist/node.d.mts +15 -10
- package/dist/node.mjs +19 -13
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/schema/dsl.cjs +19 -2
- package/dist/schema/dsl.mjs +17 -3
- package/dist/schema/index.cjs +1 -8
- package/dist/schema/index.mjs +2 -8
- package/dist/schema/types.cjs +3 -1
- package/dist/schema/types.mjs +3 -2
- package/dist/schema/v1_0_0.cjs +364 -0
- package/dist/schema/v1_0_0.mjs +357 -0
- package/dist/storageAccess.cjs +69 -25
- package/dist/storageAccess.mjs +68 -25
- package/dist/types/index.d.cts +4 -3
- package/dist/types/index.d.mts +5 -4
- package/package.json +8 -7
- package/src/adapters/databaseConstraintErrors.ts +25 -0
- package/src/adapters/databasePluginTestDatabase.ts +106 -0
- package/src/adapters/databasePluginUtils.spec.ts +29 -0
- package/src/adapters/databasePluginUtils.ts +214 -0
- package/src/adapters/drizzle.spec.ts +208 -47
- package/src/adapters/drizzle.ts +106 -293
- package/src/adapters/drizzleCrud.ts +419 -0
- package/src/adapters/drizzleLazyDB.ts +206 -100
- package/src/adapters/drizzleQuery.ts +164 -0
- package/src/adapters/kysely.spec.ts +126 -88
- package/src/adapters/kysely.ts +76 -334
- package/src/adapters/kyselyCrud.ts +588 -0
- package/src/adapters/kyselyQuery.ts +128 -0
- package/src/adapters/mongodb.spec.ts +141 -0
- package/src/adapters/mongodb.ts +60 -288
- package/src/adapters/mongodbCollections.ts +62 -0
- package/src/adapters/mongodbQuery.ts +226 -0
- package/src/adapters/mongodbReads.ts +311 -0
- package/src/adapters/mongodbRows.spec.ts +64 -0
- package/src/adapters/mongodbRows.ts +118 -0
- package/src/adapters/mongodbTestClient.ts +342 -0
- package/src/adapters/mongodbTestFilter.ts +166 -0
- package/src/adapters/mongodbWrites.ts +260 -0
- package/src/adapters/prisma.spec.ts +196 -0
- package/src/adapters/prisma.ts +417 -292
- package/src/adapters/prismaQuery.ts +129 -0
- package/src/adapters/prismaRows.spec.ts +98 -0
- package/src/adapters/prismaRows.ts +301 -0
- package/src/adapters/prismaTestClient.ts +396 -0
- package/src/analytics/analytics.integration.spec.ts +144 -0
- package/src/analytics/bounded/activeOverview.spec.ts +189 -0
- package/src/analytics/bounded/activeOverview.ts +148 -0
- package/src/analytics/bounded/installationSearch.spec.ts +130 -0
- package/src/analytics/bounded/installationSearch.ts +69 -0
- package/src/analytics/bounded/persistence.ts +43 -0
- package/src/analytics/bounded/provider.spec.ts +219 -0
- package/src/analytics/bounded/provider.ts +229 -0
- package/src/analytics/bounded/scan.ts +235 -0
- package/src/analytics/domain.ts +139 -0
- package/src/analytics/errors.ts +18 -0
- package/src/analytics/eventInput.ts +168 -0
- package/src/analytics/persistence.ts +10 -0
- package/src/analytics/queryInput.ts +102 -0
- package/src/analytics/routes.ts +123 -0
- package/src/analytics/types.ts +44 -0
- package/src/apiKeys.integration.spec.ts +192 -0
- package/src/apiKeys.spec.ts +162 -0
- package/src/apiKeys.ts +220 -0
- package/src/createHotUpdaterCore.ts +164 -100
- package/src/db/bundleRows.spec.ts +164 -0
- package/src/db/bundleRows.ts +10 -140
- package/src/db/createBundleDiff.spec.ts +172 -127
- package/src/db/createBundleDiff.ts +91 -110
- package/src/db/databasePluginCore.spec.ts +62 -0
- package/src/db/databasePluginCore.testFixtures.ts +76 -0
- package/src/db/databasePluginCore.ts +185 -0
- package/src/db/databasePluginUpdateCheck.bench.ts +107 -0
- package/src/db/fixedMigrator.spec.ts +184 -42
- package/src/db/fixedMigrator.ts +64 -205
- package/src/db/fixedMigratorMongo.spec.ts +192 -0
- package/src/db/fixedMigratorMongo.ts +425 -0
- package/src/db/fixedMigratorShared.ts +36 -0
- package/src/db/hotUpdaterSchema.ts +0 -1
- package/src/db/index.spec.ts +333 -1025
- package/src/db/mongoMigrationExecution.ts +23 -0
- package/src/db/node-sqlite.d.ts +25 -0
- package/src/db/releaseCatalog.ts +148 -0
- package/src/db/schema/mongodb.ts +20 -6
- package/src/db/schema/sql.ts +52 -11
- package/src/db/schema/sqlOperations.ts +5 -4
- package/src/db/schemaGenerators.ts +107 -23
- package/src/db/schemaReadiness.ts +2 -1
- package/src/db/sqlMigrationExecution.spec.ts +65 -0
- package/src/db/sqlMigrationExecution.ts +108 -0
- package/src/db/types.spec.ts +55 -0
- package/src/db/types.ts +129 -65
- package/src/db/updateArtifacts.spec.ts +359 -0
- package/src/db/updateArtifacts.ts +290 -126
- package/src/handler-standalone.integration.spec.ts +401 -364
- package/src/handler.spec.ts +137 -582
- package/src/handler.testFixtures.ts +30 -0
- package/src/handler.ts +218 -616
- package/src/handlerAuth.integration.spec.ts +33 -0
- package/src/handlerBundleRoutes.ts +259 -0
- package/src/handlerErrors.ts +7 -0
- package/src/handlerManagement.spec.ts +262 -0
- package/src/handlerParameters.ts +105 -0
- package/src/handlerReleaseCatalogRoutes.ts +154 -0
- package/src/handlerReleaseManagementRoutes.ts +213 -0
- package/src/handlerTypes.ts +96 -0
- package/src/handlerVersionRoutes.ts +12 -0
- package/src/index.ts +22 -2
- package/src/node.spec.ts +79 -10
- package/src/node.ts +20 -17
- package/src/releaseCatalogRoutes.integration.spec.ts +238 -0
- package/src/runtime.spec.ts +126 -959
- package/src/runtime.testFixtures.ts +71 -0
- package/src/schema/dsl-all-versions.spec.ts +26 -17
- package/src/schema/dsl.ts +41 -2
- package/src/schema/index.ts +3 -9
- package/src/schema/types.ts +9 -3
- package/src/schema/v1_0_0.spec.ts +146 -0
- package/src/schema/v1_0_0.ts +465 -0
- package/src/storageAccess.spec.ts +127 -32
- package/src/storageAccess.ts +106 -55
- package/src/types/index.ts +2 -1
- package/dist/db/bundleRows.cjs +0 -82
- package/dist/db/bundleRows.d.cts +0 -33
- package/dist/db/bundleRows.d.mts +0 -33
- package/dist/db/bundleRows.mjs +0 -79
- package/dist/db/pluginCore.cjs +0 -242
- package/dist/db/pluginCore.mjs +0 -241
- package/dist/db/schema/sqlMigrations.cjs +0 -74
- package/dist/db/schema/sqlMigrations.mjs +0 -73
- package/dist/db/schemaEnhancements.cjs +0 -20
- package/dist/db/schemaEnhancements.mjs +0 -19
- package/dist/route.cjs +0 -7
- package/dist/route.mjs +0 -7
- package/dist/schema/v0_21_0.cjs +0 -38
- package/dist/schema/v0_21_0.mjs +0 -37
- package/dist/schema/v0_29_0.cjs +0 -45
- package/dist/schema/v0_29_0.mjs +0 -44
- package/dist/schema/v0_31_0.cjs +0 -82
- package/dist/schema/v0_31_0.mjs +0 -80
- package/src/db/pluginCore.spec.ts +0 -1095
- package/src/db/pluginCore.ts +0 -475
- package/src/db/pluginUpdateCheck.bench.ts +0 -254
- package/src/db/schema/sqlMigrations.ts +0 -219
- package/src/db/schemaEnhancements.ts +0 -55
- package/src/route.ts +0 -7
- package/src/schema/v0_21_0.ts +0 -52
- package/src/schema/v0_29_0.ts +0 -62
- package/src/schema/v0_31_0.spec.ts +0 -73
- package/src/schema/v0_31_0.ts +0 -120
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../schema/types.mjs";
|
|
2
|
+
import { unsupportedSchemaUpgradeMessage } from "./fixedMigratorShared.mjs";
|
|
2
3
|
//#region src/db/schemaReadiness.ts
|
|
3
4
|
var HotUpdaterSchemaMigrationRequiredError = class extends Error {
|
|
4
5
|
constructor(adapterName, currentVersion) {
|
|
5
|
-
super(currentVersion === void 0 ? `Hot Updater database schema is not initialized for ${adapterName}. Run \`hot-updater db migrate\` before using this adapter.` :
|
|
6
|
+
super(currentVersion === void 0 ? `Hot Updater database schema is not initialized for ${adapterName}. Run \`hot-updater db migrate\` before using this adapter.` : unsupportedSchemaUpgradeMessage(currentVersion));
|
|
6
7
|
this.adapterName = adapterName;
|
|
7
8
|
this.currentVersion = currentVersion;
|
|
8
9
|
this.name = "HotUpdaterSchemaMigrationRequiredError";
|
|
@@ -14,7 +15,7 @@ const createSchemaReadinessChecker = (adapterName, createMigrator) => {
|
|
|
14
15
|
return async () => {
|
|
15
16
|
if (ready) return;
|
|
16
17
|
const version = await createMigrator().getVersion();
|
|
17
|
-
if (version !== "0.
|
|
18
|
+
if (version !== "1.0.0") throw new HotUpdaterSchemaMigrationRequiredError(adapterName, version);
|
|
18
19
|
ready = true;
|
|
19
20
|
};
|
|
20
21
|
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let kysely = require("kysely");
|
|
3
|
+
//#region src/db/sqlMigrationExecution.ts
|
|
4
|
+
var SqliteMigrationForeignKeyError = class extends Error {
|
|
5
|
+
name = "SqliteMigrationForeignKeyError";
|
|
6
|
+
constructor(violations) {
|
|
7
|
+
super(`SQLite migration produced ${violations} foreign key violation(s).`);
|
|
8
|
+
this.violations = violations;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const executeTransactionalStatements = async (db, statements) => {
|
|
12
|
+
await db.getExecutor().provideConnection(async (connection) => {
|
|
13
|
+
const execute = (statement) => connection.executeQuery(kysely.sql.raw(statement).compile(db));
|
|
14
|
+
await execute("begin");
|
|
15
|
+
try {
|
|
16
|
+
for (const statement of statements) await execute(statement);
|
|
17
|
+
await execute("commit");
|
|
18
|
+
} catch (error) {
|
|
19
|
+
await execute("rollback");
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
const executeSqliteStatements = async (db, statements) => {
|
|
25
|
+
await db.getExecutor().provideConnection(async (connection) => {
|
|
26
|
+
const execute = (statement) => connection.executeQuery(kysely.sql.raw(statement).compile(db));
|
|
27
|
+
const state = (await execute("pragma foreign_keys")).rows[0];
|
|
28
|
+
const foreignKeysWereEnabled = typeof state === "object" && state !== null && "foreign_keys" in state && state.foreign_keys === 1;
|
|
29
|
+
await execute("pragma foreign_keys = off");
|
|
30
|
+
try {
|
|
31
|
+
await execute("begin");
|
|
32
|
+
try {
|
|
33
|
+
for (const statement of statements) {
|
|
34
|
+
if (statement === "pragma foreign_keys = off" || statement === "pragma foreign_keys = on") continue;
|
|
35
|
+
if (statement === "pragma foreign_key_check") {
|
|
36
|
+
const result = await execute(statement);
|
|
37
|
+
if (result.rows.length > 0) throw new SqliteMigrationForeignKeyError(result.rows.length);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
await execute(statement);
|
|
41
|
+
}
|
|
42
|
+
await execute("commit");
|
|
43
|
+
} catch (error) {
|
|
44
|
+
await execute("rollback");
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
} finally {
|
|
48
|
+
await execute(foreignKeysWereEnabled ? "pragma foreign_keys = on" : "pragma foreign_keys = off");
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
const executeMysqlStatements = async (db, statements) => {
|
|
53
|
+
for (const statement of statements) await kysely.sql.raw(statement).execute(db);
|
|
54
|
+
};
|
|
55
|
+
const executeMigrationStatements = async ({ db, provider, statements }) => {
|
|
56
|
+
if (provider === "mysql") {
|
|
57
|
+
await executeMysqlStatements(db, statements);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (provider === "sqlite") {
|
|
61
|
+
await executeSqliteStatements(db, statements);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
await executeTransactionalStatements(db, statements);
|
|
65
|
+
};
|
|
66
|
+
//#endregion
|
|
67
|
+
exports.executeMigrationStatements = executeMigrationStatements;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { sql } from "kysely";
|
|
2
|
+
//#region src/db/sqlMigrationExecution.ts
|
|
3
|
+
var SqliteMigrationForeignKeyError = class extends Error {
|
|
4
|
+
name = "SqliteMigrationForeignKeyError";
|
|
5
|
+
constructor(violations) {
|
|
6
|
+
super(`SQLite migration produced ${violations} foreign key violation(s).`);
|
|
7
|
+
this.violations = violations;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
const executeTransactionalStatements = async (db, statements) => {
|
|
11
|
+
await db.getExecutor().provideConnection(async (connection) => {
|
|
12
|
+
const execute = (statement) => connection.executeQuery(sql.raw(statement).compile(db));
|
|
13
|
+
await execute("begin");
|
|
14
|
+
try {
|
|
15
|
+
for (const statement of statements) await execute(statement);
|
|
16
|
+
await execute("commit");
|
|
17
|
+
} catch (error) {
|
|
18
|
+
await execute("rollback");
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
const executeSqliteStatements = async (db, statements) => {
|
|
24
|
+
await db.getExecutor().provideConnection(async (connection) => {
|
|
25
|
+
const execute = (statement) => connection.executeQuery(sql.raw(statement).compile(db));
|
|
26
|
+
const state = (await execute("pragma foreign_keys")).rows[0];
|
|
27
|
+
const foreignKeysWereEnabled = typeof state === "object" && state !== null && "foreign_keys" in state && state.foreign_keys === 1;
|
|
28
|
+
await execute("pragma foreign_keys = off");
|
|
29
|
+
try {
|
|
30
|
+
await execute("begin");
|
|
31
|
+
try {
|
|
32
|
+
for (const statement of statements) {
|
|
33
|
+
if (statement === "pragma foreign_keys = off" || statement === "pragma foreign_keys = on") continue;
|
|
34
|
+
if (statement === "pragma foreign_key_check") {
|
|
35
|
+
const result = await execute(statement);
|
|
36
|
+
if (result.rows.length > 0) throw new SqliteMigrationForeignKeyError(result.rows.length);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
await execute(statement);
|
|
40
|
+
}
|
|
41
|
+
await execute("commit");
|
|
42
|
+
} catch (error) {
|
|
43
|
+
await execute("rollback");
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
} finally {
|
|
47
|
+
await execute(foreignKeysWereEnabled ? "pragma foreign_keys = on" : "pragma foreign_keys = off");
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
const executeMysqlStatements = async (db, statements) => {
|
|
52
|
+
for (const statement of statements) await sql.raw(statement).execute(db);
|
|
53
|
+
};
|
|
54
|
+
const executeMigrationStatements = async ({ db, provider, statements }) => {
|
|
55
|
+
if (provider === "mysql") {
|
|
56
|
+
await executeMysqlStatements(db, statements);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (provider === "sqlite") {
|
|
60
|
+
await executeSqliteStatements(db, statements);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
await executeTransactionalStatements(db, statements);
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { executeMigrationStatements };
|
package/dist/db/types.cjs
CHANGED
|
@@ -8,11 +8,8 @@ const sqlProviders = [
|
|
|
8
8
|
];
|
|
9
9
|
const noSqlProviders = ["mongodb"];
|
|
10
10
|
[...sqlProviders, ...noSqlProviders];
|
|
11
|
-
function
|
|
12
|
-
return typeof
|
|
13
|
-
}
|
|
14
|
-
function isDatabasePlugin(adapter) {
|
|
15
|
-
return typeof adapter === "object" && adapter !== null && "getBundleById" in adapter && "getBundles" in adapter && "getChannels" in adapter;
|
|
11
|
+
function isDatabasePlugin(plugin) {
|
|
12
|
+
return typeof plugin === "object" && plugin !== null && "name" in plugin && typeof plugin.name === "string" && "models" in plugin && typeof plugin.models === "object" && plugin.models !== null && "bundles" in plugin.models && typeof plugin.models.bundles === "object" && plugin.models.bundles !== null && "findById" in plugin.models.bundles && typeof plugin.models.bundles.findById === "function" && "findMany" in plugin.models.bundles && typeof plugin.models.bundles.findMany === "function" && "count" in plugin.models.bundles && typeof plugin.models.bundles.count === "function" && "bundlePatches" in plugin.models && typeof plugin.models.bundlePatches === "object" && plugin.models.bundlePatches !== null && "findByBundleIds" in plugin.models.bundlePatches && typeof plugin.models.bundlePatches.findByBundleIds === "function" && "channels" in plugin.models && typeof plugin.models.channels === "object" && plugin.models.channels !== null && "insert" in plugin.models.channels && typeof plugin.models.channels.insert === "function" && "list" in plugin.models.channels && typeof plugin.models.channels.list === "function" && "delete" in plugin.models.channels && typeof plugin.models.channels.delete === "function" && "analytics" in plugin.models && typeof plugin.models.analytics === "object" && plugin.models.analytics !== null && "append" in plugin.models.analytics && typeof plugin.models.analytics.append === "function" && "scan" in plugin.models.analytics && typeof plugin.models.analytics.scan === "function" && "apiKeys" in plugin.models && typeof plugin.models.apiKeys === "object" && plugin.models.apiKeys !== null && "create" in plugin.models.apiKeys && typeof plugin.models.apiKeys.create === "function" && "findByHash" in plugin.models.apiKeys && typeof plugin.models.apiKeys.findByHash === "function" && "list" in plugin.models.apiKeys && typeof plugin.models.apiKeys.list === "function" && "revoke" in plugin.models.apiKeys && typeof plugin.models.apiKeys.revoke === "function" && "commit" in plugin && typeof plugin.commit === "function" && (!("dispose" in plugin) || plugin.dispose === void 0 || typeof plugin.dispose === "function");
|
|
16
13
|
}
|
|
17
14
|
function getSQLProvider(provider) {
|
|
18
15
|
if (!provider) return;
|
|
@@ -21,4 +18,3 @@ function getSQLProvider(provider) {
|
|
|
21
18
|
//#endregion
|
|
22
19
|
exports.getSQLProvider = getSQLProvider;
|
|
23
20
|
exports.isDatabasePlugin = isDatabasePlugin;
|
|
24
|
-
exports.isDatabasePluginFactory = isDatabasePluginFactory;
|
package/dist/db/types.d.cts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { ReleaseCatalogRequest } from "./releaseCatalog.cjs";
|
|
1
2
|
import { PaginatedResult } from "../types/index.cjs";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
3
|
+
import * as _$_hot_updater_core0 from "@hot-updater/core";
|
|
4
|
+
import { ArtifactInfo, Bundle } from "@hot-updater/core";
|
|
5
|
+
import * as _$_hot_updater_plugin_core0 from "@hot-updater/plugin-core";
|
|
6
|
+
import { ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelRow, DatabaseCommit, DatabaseCommitResult, DatabasePlugin, ReleaseCatalogMutationPreflight, ReleaseCatalogMutationResult, ReleaseCatalogRebuildResult, ReleaseCatalogRow, ReleasePolicyPatch, ReleaseRow } from "@hot-updater/plugin-core";
|
|
4
7
|
|
|
5
8
|
//#region src/db/types.d.ts
|
|
6
|
-
type DatabasePluginFactory<TContext = unknown> = (() => DatabasePlugin<TContext>) & Partial<DatabaseAdapterCapabilities>;
|
|
7
9
|
declare const sqlProviders: readonly ["sqlite", "cockroachdb", "mysql", "postgresql", "mssql"];
|
|
8
10
|
declare const providers: readonly ["sqlite", "cockroachdb", "mysql", "postgresql", "mssql", "mongodb"];
|
|
9
11
|
type ORMProvider = (typeof providers)[number];
|
|
@@ -23,6 +25,9 @@ type MigrationOperation = {
|
|
|
23
25
|
type: string;
|
|
24
26
|
}>;
|
|
25
27
|
};
|
|
28
|
+
} | {
|
|
29
|
+
type: "custom";
|
|
30
|
+
description: string;
|
|
26
31
|
} | {
|
|
27
32
|
type: "custom";
|
|
28
33
|
sql: string;
|
|
@@ -60,18 +65,57 @@ interface DatabaseAdapterCapabilities {
|
|
|
60
65
|
createMigrator?: () => Migrator;
|
|
61
66
|
generateSchema?: SchemaGenerator;
|
|
62
67
|
}
|
|
63
|
-
type DatabaseAdapterWithCapabilities
|
|
64
|
-
type
|
|
65
|
-
interface DatabaseAPI
|
|
66
|
-
getBundleById(id: string
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
type DatabaseAdapterWithCapabilities = DatabasePlugin & DatabaseAdapterCapabilities;
|
|
69
|
+
type DatabasePlugin$1 = DatabaseAdapterWithCapabilities;
|
|
70
|
+
interface DatabaseAPI {
|
|
71
|
+
getBundleById(id: string): Promise<Bundle | null>;
|
|
72
|
+
getReleaseCatalog(input: ReleaseCatalogRequest): Promise<_$_hot_updater_core0.ReleaseCatalog | null>;
|
|
73
|
+
getArtifactInfo(targetBundleId: string, currentBundleId: string): Promise<ArtifactInfo | null>;
|
|
74
|
+
getReleaseById(id: string): Promise<ReleaseRow | null>;
|
|
75
|
+
getReleasesByScope(input: {
|
|
76
|
+
readonly scopeKey: string;
|
|
77
|
+
readonly afterReleaseId?: string;
|
|
78
|
+
readonly limit: number;
|
|
79
|
+
}): Promise<readonly ReleaseRow[]>;
|
|
80
|
+
getReleases(input: {
|
|
81
|
+
readonly afterReleaseId?: string;
|
|
82
|
+
readonly beforeReleaseId?: string;
|
|
83
|
+
readonly bundleId?: string;
|
|
84
|
+
readonly channelId?: string;
|
|
85
|
+
readonly enabled?: boolean;
|
|
86
|
+
readonly platform?: "ios" | "android";
|
|
87
|
+
readonly targetAppVersion?: string;
|
|
88
|
+
readonly limit: number;
|
|
89
|
+
}): Promise<readonly ReleaseRow[]>;
|
|
90
|
+
getReleaseCatalogByScopeKey(scopeKey: string): Promise<ReleaseCatalogRow | null>;
|
|
91
|
+
getReleaseCatalogs(input: {
|
|
92
|
+
readonly afterScopeKey?: string;
|
|
93
|
+
readonly limit: number;
|
|
94
|
+
}): Promise<readonly ReleaseCatalogRow[]>;
|
|
95
|
+
updateReleasePolicy(input: {
|
|
96
|
+
readonly expectedRevision?: number;
|
|
97
|
+
readonly patch: ReleasePolicyPatch;
|
|
98
|
+
readonly releaseId: string;
|
|
99
|
+
}): Promise<ReleaseCatalogMutationResult>;
|
|
100
|
+
preflightReleasePolicy(input: {
|
|
101
|
+
readonly expectedRevision?: number;
|
|
102
|
+
readonly patch: ReleasePolicyPatch;
|
|
103
|
+
readonly releaseId: string;
|
|
104
|
+
}): Promise<ReleaseCatalogMutationPreflight>;
|
|
105
|
+
deleteRelease(input: {
|
|
106
|
+
readonly expectedRevision?: number;
|
|
107
|
+
readonly releaseId: string;
|
|
108
|
+
}): Promise<ReleaseCatalogMutationResult>;
|
|
109
|
+
rebuildReleaseCatalog(scopeKey: string): Promise<ReleaseCatalogRebuildResult>;
|
|
110
|
+
commitDatabase(input: DatabaseCommit): Promise<DatabaseCommitResult>;
|
|
111
|
+
getChannels(): Promise<readonly ChannelRow[]>;
|
|
112
|
+
insertChannel(input: ChannelInsertInput): Promise<ChannelInsertResult>;
|
|
113
|
+
deleteChannel(input: ChannelDeleteInput): Promise<ChannelDeleteResult>;
|
|
114
|
+
getBundles(options: _$_hot_updater_plugin_core0.DatabaseBundleQueryOptions): Promise<PaginatedResult>;
|
|
115
|
+
insertBundle(bundle: Bundle): Promise<void>;
|
|
116
|
+
insertBundles(bundles: readonly Bundle[]): Promise<void>;
|
|
117
|
+
updateBundleById(bundleId: string, newBundle: Partial<Bundle>): Promise<void>;
|
|
118
|
+
deleteBundleById(bundleId: string): Promise<void>;
|
|
74
119
|
}
|
|
75
|
-
type StoragePluginFactory<TContext = unknown> = () => RuntimeStoragePlugin<TContext>;
|
|
76
120
|
//#endregion
|
|
77
|
-
export { DatabaseAPI,
|
|
121
|
+
export { DatabaseAPI, DatabaseAdapterWithCapabilities, DatabasePlugin$1 as DatabasePlugin, Migrator, ORMProvider, ORMSQLProvider, RelationMode, SchemaGenerator };
|
package/dist/db/types.d.mts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { ReleaseCatalogRequest } from "./releaseCatalog.mjs";
|
|
1
2
|
import { PaginatedResult } from "../types/index.mjs";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
3
|
+
import * as _$_hot_updater_plugin_core0 from "@hot-updater/plugin-core";
|
|
4
|
+
import { ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelRow, DatabaseCommit, DatabaseCommitResult, DatabasePlugin, ReleaseCatalogMutationPreflight, ReleaseCatalogMutationResult, ReleaseCatalogRebuildResult, ReleaseCatalogRow, ReleasePolicyPatch, ReleaseRow } from "@hot-updater/plugin-core";
|
|
5
|
+
import * as _$_hot_updater_core0 from "@hot-updater/core";
|
|
6
|
+
import { ArtifactInfo, Bundle as Bundle$1 } from "@hot-updater/core";
|
|
4
7
|
|
|
5
8
|
//#region src/db/types.d.ts
|
|
6
|
-
type DatabasePluginFactory<TContext = unknown> = (() => DatabasePlugin<TContext>) & Partial<DatabaseAdapterCapabilities>;
|
|
7
9
|
declare const sqlProviders: readonly ["sqlite", "cockroachdb", "mysql", "postgresql", "mssql"];
|
|
8
10
|
declare const providers: readonly ["sqlite", "cockroachdb", "mysql", "postgresql", "mssql", "mongodb"];
|
|
9
11
|
type ORMProvider = (typeof providers)[number];
|
|
@@ -23,6 +25,9 @@ type MigrationOperation = {
|
|
|
23
25
|
type: string;
|
|
24
26
|
}>;
|
|
25
27
|
};
|
|
28
|
+
} | {
|
|
29
|
+
type: "custom";
|
|
30
|
+
description: string;
|
|
26
31
|
} | {
|
|
27
32
|
type: "custom";
|
|
28
33
|
sql: string;
|
|
@@ -60,18 +65,57 @@ interface DatabaseAdapterCapabilities {
|
|
|
60
65
|
createMigrator?: () => Migrator;
|
|
61
66
|
generateSchema?: SchemaGenerator;
|
|
62
67
|
}
|
|
63
|
-
type DatabaseAdapterWithCapabilities
|
|
64
|
-
type
|
|
65
|
-
interface DatabaseAPI
|
|
66
|
-
getBundleById(id: string
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
type DatabaseAdapterWithCapabilities = DatabasePlugin & DatabaseAdapterCapabilities;
|
|
69
|
+
type DatabasePlugin$1 = DatabaseAdapterWithCapabilities;
|
|
70
|
+
interface DatabaseAPI {
|
|
71
|
+
getBundleById(id: string): Promise<Bundle$1 | null>;
|
|
72
|
+
getReleaseCatalog(input: ReleaseCatalogRequest): Promise<_$_hot_updater_core0.ReleaseCatalog | null>;
|
|
73
|
+
getArtifactInfo(targetBundleId: string, currentBundleId: string): Promise<ArtifactInfo | null>;
|
|
74
|
+
getReleaseById(id: string): Promise<ReleaseRow | null>;
|
|
75
|
+
getReleasesByScope(input: {
|
|
76
|
+
readonly scopeKey: string;
|
|
77
|
+
readonly afterReleaseId?: string;
|
|
78
|
+
readonly limit: number;
|
|
79
|
+
}): Promise<readonly ReleaseRow[]>;
|
|
80
|
+
getReleases(input: {
|
|
81
|
+
readonly afterReleaseId?: string;
|
|
82
|
+
readonly beforeReleaseId?: string;
|
|
83
|
+
readonly bundleId?: string;
|
|
84
|
+
readonly channelId?: string;
|
|
85
|
+
readonly enabled?: boolean;
|
|
86
|
+
readonly platform?: "ios" | "android";
|
|
87
|
+
readonly targetAppVersion?: string;
|
|
88
|
+
readonly limit: number;
|
|
89
|
+
}): Promise<readonly ReleaseRow[]>;
|
|
90
|
+
getReleaseCatalogByScopeKey(scopeKey: string): Promise<ReleaseCatalogRow | null>;
|
|
91
|
+
getReleaseCatalogs(input: {
|
|
92
|
+
readonly afterScopeKey?: string;
|
|
93
|
+
readonly limit: number;
|
|
94
|
+
}): Promise<readonly ReleaseCatalogRow[]>;
|
|
95
|
+
updateReleasePolicy(input: {
|
|
96
|
+
readonly expectedRevision?: number;
|
|
97
|
+
readonly patch: ReleasePolicyPatch;
|
|
98
|
+
readonly releaseId: string;
|
|
99
|
+
}): Promise<ReleaseCatalogMutationResult>;
|
|
100
|
+
preflightReleasePolicy(input: {
|
|
101
|
+
readonly expectedRevision?: number;
|
|
102
|
+
readonly patch: ReleasePolicyPatch;
|
|
103
|
+
readonly releaseId: string;
|
|
104
|
+
}): Promise<ReleaseCatalogMutationPreflight>;
|
|
105
|
+
deleteRelease(input: {
|
|
106
|
+
readonly expectedRevision?: number;
|
|
107
|
+
readonly releaseId: string;
|
|
108
|
+
}): Promise<ReleaseCatalogMutationResult>;
|
|
109
|
+
rebuildReleaseCatalog(scopeKey: string): Promise<ReleaseCatalogRebuildResult>;
|
|
110
|
+
commitDatabase(input: DatabaseCommit): Promise<DatabaseCommitResult>;
|
|
111
|
+
getChannels(): Promise<readonly ChannelRow[]>;
|
|
112
|
+
insertChannel(input: ChannelInsertInput): Promise<ChannelInsertResult>;
|
|
113
|
+
deleteChannel(input: ChannelDeleteInput): Promise<ChannelDeleteResult>;
|
|
114
|
+
getBundles(options: _$_hot_updater_plugin_core0.DatabaseBundleQueryOptions): Promise<PaginatedResult>;
|
|
115
|
+
insertBundle(bundle: Bundle$1): Promise<void>;
|
|
116
|
+
insertBundles(bundles: readonly Bundle$1[]): Promise<void>;
|
|
117
|
+
updateBundleById(bundleId: string, newBundle: Partial<Bundle$1>): Promise<void>;
|
|
118
|
+
deleteBundleById(bundleId: string): Promise<void>;
|
|
74
119
|
}
|
|
75
|
-
type StoragePluginFactory<TContext = unknown> = () => RuntimeStoragePlugin<TContext>;
|
|
76
120
|
//#endregion
|
|
77
|
-
export { DatabaseAPI,
|
|
121
|
+
export { DatabaseAPI, DatabaseAdapterWithCapabilities, DatabasePlugin$1 as DatabasePlugin, Migrator, ORMProvider, ORMSQLProvider, RelationMode, SchemaGenerator };
|
package/dist/db/types.mjs
CHANGED
|
@@ -8,15 +8,12 @@ const sqlProviders = [
|
|
|
8
8
|
];
|
|
9
9
|
const noSqlProviders = ["mongodb"];
|
|
10
10
|
[...sqlProviders, ...noSqlProviders];
|
|
11
|
-
function
|
|
12
|
-
return typeof
|
|
13
|
-
}
|
|
14
|
-
function isDatabasePlugin(adapter) {
|
|
15
|
-
return typeof adapter === "object" && adapter !== null && "getBundleById" in adapter && "getBundles" in adapter && "getChannels" in adapter;
|
|
11
|
+
function isDatabasePlugin(plugin) {
|
|
12
|
+
return typeof plugin === "object" && plugin !== null && "name" in plugin && typeof plugin.name === "string" && "models" in plugin && typeof plugin.models === "object" && plugin.models !== null && "bundles" in plugin.models && typeof plugin.models.bundles === "object" && plugin.models.bundles !== null && "findById" in plugin.models.bundles && typeof plugin.models.bundles.findById === "function" && "findMany" in plugin.models.bundles && typeof plugin.models.bundles.findMany === "function" && "count" in plugin.models.bundles && typeof plugin.models.bundles.count === "function" && "bundlePatches" in plugin.models && typeof plugin.models.bundlePatches === "object" && plugin.models.bundlePatches !== null && "findByBundleIds" in plugin.models.bundlePatches && typeof plugin.models.bundlePatches.findByBundleIds === "function" && "channels" in plugin.models && typeof plugin.models.channels === "object" && plugin.models.channels !== null && "insert" in plugin.models.channels && typeof plugin.models.channels.insert === "function" && "list" in plugin.models.channels && typeof plugin.models.channels.list === "function" && "delete" in plugin.models.channels && typeof plugin.models.channels.delete === "function" && "analytics" in plugin.models && typeof plugin.models.analytics === "object" && plugin.models.analytics !== null && "append" in plugin.models.analytics && typeof plugin.models.analytics.append === "function" && "scan" in plugin.models.analytics && typeof plugin.models.analytics.scan === "function" && "apiKeys" in plugin.models && typeof plugin.models.apiKeys === "object" && plugin.models.apiKeys !== null && "create" in plugin.models.apiKeys && typeof plugin.models.apiKeys.create === "function" && "findByHash" in plugin.models.apiKeys && typeof plugin.models.apiKeys.findByHash === "function" && "list" in plugin.models.apiKeys && typeof plugin.models.apiKeys.list === "function" && "revoke" in plugin.models.apiKeys && typeof plugin.models.apiKeys.revoke === "function" && "commit" in plugin && typeof plugin.commit === "function" && (!("dispose" in plugin) || plugin.dispose === void 0 || typeof plugin.dispose === "function");
|
|
16
13
|
}
|
|
17
14
|
function getSQLProvider(provider) {
|
|
18
15
|
if (!provider) return;
|
|
19
16
|
return sqlProviders.includes(provider) ? provider : void 0;
|
|
20
17
|
}
|
|
21
18
|
//#endregion
|
|
22
|
-
export { getSQLProvider, isDatabasePlugin
|
|
19
|
+
export { getSQLProvider, isDatabasePlugin };
|
|
@@ -3,6 +3,19 @@ let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
|
3
3
|
let _hot_updater_core = require("@hot-updater/core");
|
|
4
4
|
//#region src/db/updateArtifacts.ts
|
|
5
5
|
const HBC_ASSET_PATH_RE = /\.bundle$/;
|
|
6
|
+
const asByteSize = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
7
|
+
const sumByteSizes = (byteSizes) => {
|
|
8
|
+
let total = 0;
|
|
9
|
+
for (const byteSize of byteSizes) {
|
|
10
|
+
if (byteSize === null || total > Number.MAX_SAFE_INTEGER - byteSize) return null;
|
|
11
|
+
total += byteSize;
|
|
12
|
+
}
|
|
13
|
+
return total;
|
|
14
|
+
};
|
|
15
|
+
const shouldUseArchive = (targetBundle, downloadByteSize) => {
|
|
16
|
+
const archiveByteSize = asByteSize(targetBundle.archiveByteSize);
|
|
17
|
+
return archiveByteSize !== null && downloadByteSize !== null && downloadByteSize >= archiveByteSize;
|
|
18
|
+
};
|
|
6
19
|
const resolveUniqueHbcAssetPath = (manifest) => {
|
|
7
20
|
const candidates = Object.keys(manifest.assets).sort((left, right) => left.localeCompare(right)).filter((candidate) => HBC_ASSET_PATH_RE.test(candidate));
|
|
8
21
|
return candidates.length === 1 ? candidates[0] : null;
|
|
@@ -18,19 +31,8 @@ const isBundleManifest = (value) => {
|
|
|
18
31
|
return typeof manifestAsset.fileHash === "string" && (manifestAsset.signature === void 0 || typeof manifestAsset.signature === "string");
|
|
19
32
|
});
|
|
20
33
|
};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
let parsedValue = value;
|
|
24
|
-
if (typeof parsedValue === "string") try {
|
|
25
|
-
parsedValue = JSON.parse(parsedValue);
|
|
26
|
-
} catch {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
if (!parsedValue || typeof parsedValue !== "object" || Array.isArray(parsedValue)) return;
|
|
30
|
-
return (0, _hot_updater_core.stripBundleArtifactMetadata)(parsedValue);
|
|
31
|
-
};
|
|
32
|
-
async function fetchBundleManifest(storageUri, readStorageText, resolveFileUrl, context) {
|
|
33
|
-
const [storageText, fileUrl] = await Promise.all([readStorageText(storageUri, context), resolveFileUrl(storageUri, context)]);
|
|
34
|
+
async function fetchBundleManifest(storageUri, readStorageText) {
|
|
35
|
+
const storageText = await readStorageText(storageUri);
|
|
34
36
|
if (storageText === null) return null;
|
|
35
37
|
let payload;
|
|
36
38
|
try {
|
|
@@ -39,89 +41,141 @@ async function fetchBundleManifest(storageUri, readStorageText, resolveFileUrl,
|
|
|
39
41
|
return null;
|
|
40
42
|
}
|
|
41
43
|
if (!isBundleManifest(payload)) return null;
|
|
42
|
-
if (!fileUrl) return null;
|
|
43
44
|
return {
|
|
44
|
-
|
|
45
|
+
byteSize: asByteSize(new TextEncoder().encode(storageText).byteLength),
|
|
45
46
|
manifest: payload
|
|
46
47
|
};
|
|
47
48
|
}
|
|
48
|
-
|
|
49
|
-
const
|
|
49
|
+
function resolveHbcPatchPlan({ currentBundle, targetBundle, targetManifest }) {
|
|
50
|
+
const matchingPatch = currentBundle ? (0, _hot_updater_core.getBundlePatch)(targetBundle, currentBundle.id) : null;
|
|
51
|
+
const patchAssetPath = resolveUniqueHbcAssetPath(targetManifest);
|
|
52
|
+
if (!currentBundle || !matchingPatch || !patchAssetPath || !matchingPatch.patchStorageUri || !matchingPatch.patchFileHash || !matchingPatch.baseFileHash) return null;
|
|
53
|
+
return {
|
|
54
|
+
assetPath: patchAssetPath,
|
|
55
|
+
patch: {
|
|
56
|
+
baseBundleId: matchingPatch.baseBundleId,
|
|
57
|
+
baseFileHash: matchingPatch.baseFileHash,
|
|
58
|
+
byteSize: asByteSize(matchingPatch.byteSize),
|
|
59
|
+
patchFileHash: matchingPatch.patchFileHash,
|
|
60
|
+
storageUri: matchingPatch.patchStorageUri
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function createManifestArtifactPlan({ assetBaseStorageUri, currentManifest, currentBundle, targetBundle, targetManifest, targetManifestByteSize }) {
|
|
65
|
+
const patchCandidate = resolveHbcPatchPlan({
|
|
50
66
|
currentBundle,
|
|
51
|
-
resolveFileUrl,
|
|
52
67
|
targetBundle,
|
|
53
|
-
targetManifest
|
|
54
|
-
context
|
|
68
|
+
targetManifest
|
|
55
69
|
});
|
|
56
|
-
const
|
|
57
|
-
if ((currentManifest?.assets[assetPath])?.fileHash === asset.fileHash) return
|
|
70
|
+
const changedAssets = Object.entries(targetManifest.assets).flatMap(([assetPath, asset]) => {
|
|
71
|
+
if ((currentManifest?.assets[assetPath])?.fileHash === asset.fileHash) return [];
|
|
72
|
+
const downloadByteSize = asByteSize(asset.downloadByteSize);
|
|
58
73
|
const downloadPath = (0, _hot_updater_plugin_core.getManifestAssetDownloadPath)(assetPath);
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
74
|
+
const isTransformedDownload = downloadPath !== assetPath;
|
|
75
|
+
const hasValidDownloadFileHash = (0, _hot_updater_plugin_core.isContentAddressedAssetFileHash)(asset.downloadFileHash);
|
|
76
|
+
const file = {
|
|
77
|
+
byteSize: downloadByteSize !== null && (hasValidDownloadFileHash || !isTransformedDownload && asset.downloadFileHash === void 0) ? downloadByteSize : null,
|
|
78
|
+
storageUri: (0, _hot_updater_plugin_core.resolveManifestAssetStorageUri)({
|
|
79
|
+
assetBaseStorageUri,
|
|
80
|
+
assetPath: downloadPath,
|
|
81
|
+
downloadFileHash: asset.downloadFileHash,
|
|
82
|
+
fileHash: asset.fileHash
|
|
83
|
+
})
|
|
84
|
+
};
|
|
85
|
+
if (isTransformedDownload) file.compression = "br";
|
|
86
|
+
const patch = patchCandidate?.assetPath === assetPath ? patchCandidate.patch : null;
|
|
87
|
+
return [{
|
|
88
|
+
assetPath,
|
|
89
|
+
file,
|
|
90
|
+
fileHash: asset.fileHash,
|
|
91
|
+
patch
|
|
92
|
+
}];
|
|
93
|
+
});
|
|
94
|
+
const allPossibleByteSizesKnown = targetManifestByteSize !== null && changedAssets.every((asset) => asset.file.byteSize !== null && (asset.patch === null || asset.patch.byteSize !== null));
|
|
95
|
+
const primaryByteSizes = changedAssets.map((asset) => {
|
|
96
|
+
if (!asset.patch) return asset.file.byteSize;
|
|
97
|
+
if (asset.patch.byteSize === null || asset.file.byteSize === null) return null;
|
|
98
|
+
return Math.min(asset.patch.byteSize, asset.file.byteSize);
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
allPossibleByteSizesKnown,
|
|
102
|
+
changedAssets,
|
|
103
|
+
manifestByteSize: targetManifestByteSize,
|
|
104
|
+
minimumDownloadByteSize: allPossibleByteSizesKnown ? sumByteSizes([targetManifestByteSize, ...primaryByteSizes]) : null
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
async function resolveChangedAssets(plan, resolveFileUrl) {
|
|
108
|
+
const patchAsset = plan.changedAssets.find((asset) => asset.patch !== null);
|
|
109
|
+
let resolvedPatch = null;
|
|
110
|
+
if (patchAsset?.patch) {
|
|
111
|
+
const patchUrl = await resolveFileUrl(patchAsset.patch.storageUri);
|
|
112
|
+
if (patchUrl) resolvedPatch = {
|
|
113
|
+
assetPath: patchAsset.assetPath,
|
|
114
|
+
patch: {
|
|
115
|
+
algorithm: "bsdiff",
|
|
116
|
+
baseBundleId: patchAsset.patch.baseBundleId,
|
|
117
|
+
baseFileHash: patchAsset.patch.baseFileHash,
|
|
118
|
+
patchFileHash: patchAsset.patch.patchFileHash,
|
|
119
|
+
patchUrl
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const changedEntries = await Promise.all(plan.changedAssets.map(async (asset) => {
|
|
124
|
+
let patch = resolvedPatch?.assetPath === asset.assetPath ? resolvedPatch.patch : null;
|
|
66
125
|
let fileUrl = null;
|
|
67
126
|
try {
|
|
68
|
-
fileUrl = await resolveFileUrl(storageUri
|
|
127
|
+
fileUrl = await resolveFileUrl(asset.file.storageUri);
|
|
69
128
|
} catch (error) {
|
|
70
129
|
if (!patch) throw error;
|
|
71
130
|
}
|
|
72
|
-
if (
|
|
131
|
+
if (fileUrl && patch && asset.file.byteSize !== null && asset.patch !== null && asset.patch.byteSize !== null && asset.patch.byteSize >= asset.file.byteSize) patch = null;
|
|
132
|
+
if (!fileUrl && !patch) return null;
|
|
73
133
|
const changedAsset = { fileHash: asset.fileHash };
|
|
74
134
|
if (fileUrl) {
|
|
75
135
|
changedAsset.file = { url: fileUrl };
|
|
76
|
-
if (
|
|
136
|
+
if (asset.file.compression) changedAsset.file.compression = asset.file.compression;
|
|
77
137
|
}
|
|
78
138
|
if (patch) changedAsset.patch = patch;
|
|
79
|
-
return
|
|
139
|
+
return {
|
|
140
|
+
asset: [asset.assetPath, changedAsset],
|
|
141
|
+
primaryByteSize: patch ? asset.patch?.byteSize ?? null : asset.file.byteSize
|
|
142
|
+
};
|
|
80
143
|
}));
|
|
81
|
-
if (changedEntries.some((entry) => entry ===
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
async function resolveHbcPatchDescriptor({ currentBundle, resolveFileUrl, targetBundle, targetManifest, context }) {
|
|
85
|
-
const matchingPatch = targetBundle && currentBundle ? (0, _hot_updater_core.getBundlePatch)(targetBundle, currentBundle.id) : null;
|
|
86
|
-
const patchAssetPath = resolveUniqueHbcAssetPath(targetManifest);
|
|
87
|
-
if (!currentBundle || !matchingPatch || !patchAssetPath || !matchingPatch.patchStorageUri || !matchingPatch.patchFileHash || !matchingPatch.baseFileHash) return null;
|
|
88
|
-
const patchUrl = await resolveFileUrl(matchingPatch.patchStorageUri, context);
|
|
89
|
-
if (!patchUrl) return null;
|
|
144
|
+
if (changedEntries.some((entry) => entry === null)) return null;
|
|
145
|
+
const resolvedEntries = changedEntries.filter((entry) => entry !== null);
|
|
90
146
|
return {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
algorithm: "bsdiff",
|
|
94
|
-
baseBundleId: matchingPatch.baseBundleId,
|
|
95
|
-
baseFileHash: matchingPatch.baseFileHash,
|
|
96
|
-
patchFileHash: matchingPatch.patchFileHash,
|
|
97
|
-
patchUrl
|
|
98
|
-
}
|
|
147
|
+
changedAssets: Object.fromEntries(resolvedEntries.map((entry) => entry.asset)),
|
|
148
|
+
primaryByteSizes: resolvedEntries.map((entry) => entry.primaryByteSize)
|
|
99
149
|
};
|
|
100
150
|
}
|
|
101
|
-
async function resolveManifestArtifacts({ currentBundle, resolveFileUrl, readStorageText, targetBundle
|
|
151
|
+
async function resolveManifestArtifacts({ archiveUrlUsable, currentBundle, resolveFileUrl, readStorageText, targetBundle }) {
|
|
102
152
|
const manifestStorageUri = targetBundle ? (0, _hot_updater_core.getManifestStorageUri)(targetBundle) : null;
|
|
103
153
|
const manifestFileHash = targetBundle ? (0, _hot_updater_core.getManifestFileHash)(targetBundle) : null;
|
|
104
154
|
const assetBaseStorageUri = targetBundle ? (0, _hot_updater_core.getAssetBaseStorageUri)(targetBundle) : null;
|
|
105
|
-
if (!manifestStorageUri || !manifestFileHash || !assetBaseStorageUri) return null;
|
|
155
|
+
if (!targetBundle || !manifestStorageUri || !manifestFileHash || !assetBaseStorageUri) return null;
|
|
106
156
|
const currentManifestStorageUri = currentBundle ? (0, _hot_updater_core.getManifestStorageUri)(currentBundle) : null;
|
|
107
|
-
const [targetManifestResult, currentManifestResult] = await Promise.all([fetchBundleManifest(manifestStorageUri, readStorageText
|
|
157
|
+
const [targetManifestResult, currentManifestResult] = await Promise.all([fetchBundleManifest(manifestStorageUri, readStorageText), currentManifestStorageUri ? fetchBundleManifest(currentManifestStorageUri, readStorageText) : null]);
|
|
108
158
|
if (!targetManifestResult) return null;
|
|
109
|
-
const
|
|
159
|
+
const plan = createManifestArtifactPlan({
|
|
110
160
|
assetBaseStorageUri,
|
|
111
161
|
currentManifest: currentManifestResult?.manifest ?? null,
|
|
112
162
|
currentBundle,
|
|
113
|
-
resolveFileUrl,
|
|
114
163
|
targetBundle,
|
|
115
164
|
targetManifest: targetManifestResult.manifest,
|
|
116
|
-
|
|
165
|
+
targetManifestByteSize: targetManifestResult.byteSize
|
|
117
166
|
});
|
|
118
|
-
if (
|
|
167
|
+
if (archiveUrlUsable && plan.allPossibleByteSizesKnown && shouldUseArchive(targetBundle, plan.minimumDownloadByteSize)) return null;
|
|
168
|
+
const manifestUrl = await resolveFileUrl(manifestStorageUri);
|
|
169
|
+
if (!manifestUrl) return null;
|
|
170
|
+
const resolved = await resolveChangedAssets(plan, resolveFileUrl);
|
|
171
|
+
if (!resolved) return null;
|
|
172
|
+
const resolvedDownloadByteSize = sumByteSizes([plan.manifestByteSize, ...resolved.primaryByteSizes]);
|
|
173
|
+
if (archiveUrlUsable && shouldUseArchive(targetBundle, resolvedDownloadByteSize)) return null;
|
|
119
174
|
return {
|
|
120
|
-
changedAssets,
|
|
175
|
+
changedAssets: resolved.changedAssets,
|
|
121
176
|
manifestFileHash,
|
|
122
|
-
manifestUrl
|
|
177
|
+
manifestUrl
|
|
123
178
|
};
|
|
124
179
|
}
|
|
125
180
|
//#endregion
|
|
126
|
-
exports.parseBundleMetadata = parseBundleMetadata;
|
|
127
181
|
exports.resolveManifestArtifacts = resolveManifestArtifacts;
|