@hot-updater/aws 1.0.0-rc.46 → 1.0.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.
@@ -7800,7 +7800,7 @@ var DynamoDBTableSchemaError = class extends Error {
7800
7800
  tableName;
7801
7801
  name = "DynamoDBTableSchemaError";
7802
7802
  constructor(tableName) {
7803
- super(`DynamoDB table "${tableName}" does not match the Hot Updater schema: a pk and sk key and no secondary index. A table from before 1.0 keeps its update index; delete it and rerun init to create it again.`);
7803
+ super(`DynamoDB table "${tableName}" does not match the Hot Updater schema: a pk and sk key and no secondary index. Delete the table and rerun init to create it again.`);
7804
7804
  this.tableName = tableName;
7805
7805
  }
7806
7806
  };
@@ -7795,7 +7795,7 @@ var DynamoDBTableSchemaError = class extends Error {
7795
7795
  tableName;
7796
7796
  name = "DynamoDBTableSchemaError";
7797
7797
  constructor(tableName) {
7798
- super(`DynamoDB table "${tableName}" does not match the Hot Updater schema: a pk and sk key and no secondary index. A table from before 1.0 keeps its update index; delete it and rerun init to create it again.`);
7798
+ super(`DynamoDB table "${tableName}" does not match the Hot Updater schema: a pk and sk key and no secondary index. Delete the table and rerun init to create it again.`);
7799
7799
  this.tableName = tableName;
7800
7800
  }
7801
7801
  };
@@ -1154,29 +1154,23 @@ function validateReleases(releases, strategy) {
1154
1154
  if (seenIds.has(release.id)) throw new ReleaseCatalogCompilationError("INVALID_RELEASE", `Duplicate Release ID: ${release.id}`);
1155
1155
  seenIds.add(release.id);
1156
1156
  if (release.strategy !== strategy) throw new ReleaseCatalogCompilationError("INVALID_RELEASE", `Release ${release.id} has the wrong strategy`);
1157
- if (release.kind === "BUNDLE" && release.bundleId === null || release.kind === "EMBEDDED" && release.bundleId !== null) throw new ReleaseCatalogCompilationError("INVALID_RELEASE", `Release ${release.id} has an invalid kind/Bundle combination`);
1157
+ if (release.bundleId === null) throw new ReleaseCatalogCompilationError("INVALID_RELEASE", `Release ${release.id} has no Bundle`);
1158
1158
  if (release.targetCohorts.length > 100) throw new ReleaseCatalogCompilationError("TARGET_COHORT_LIMIT", `Release ${release.id} exceeds 100 target cohorts`);
1159
1159
  if (strategy === "APP_VERSION" && (release.targetAppVersion === null || release.fingerprintHash !== null)) throw new ReleaseCatalogCompilationError("INVALID_RELEASE", `Release ${release.id} has an invalid app-version target`);
1160
1160
  if (strategy === "FINGERPRINT" && (release.fingerprintHash === null || release.targetAppVersion !== null)) throw new ReleaseCatalogCompilationError("INVALID_RELEASE", `Release ${release.id} has an invalid fingerprint target`);
1161
1161
  }
1162
- return enabled.filter((release) => release.kind === "BUNDLE");
1162
+ return enabled;
1163
1163
  }
1164
1164
  function collectFrontierReleaseIds(releases) {
1165
1165
  if (releases.every((release) => normalizeRolloutCohortCount(release.rolloutCohortCount) >= 1e3)) {
1166
1166
  const retained = /* @__PURE__ */ new Set();
1167
1167
  const bundleIds = /* @__PURE__ */ new Set();
1168
- let embedded = false;
1169
1168
  for (const release of releases) {
1170
- if (release.kind === "EMBEDDED") {
1171
- if (!embedded) {
1172
- embedded = true;
1173
- retained.add(release.id);
1174
- }
1175
- } else if (release.bundleId !== null && bundleIds.size < 11 && !bundleIds.has(release.bundleId)) {
1169
+ if (release.bundleId !== null && !bundleIds.has(release.bundleId)) {
1176
1170
  bundleIds.add(release.bundleId);
1177
1171
  retained.add(release.id);
1178
1172
  }
1179
- if (embedded && bundleIds.size >= 11) break;
1173
+ if (bundleIds.size >= 11) break;
1180
1174
  }
1181
1175
  return retained;
1182
1176
  }
@@ -1193,7 +1187,6 @@ function collectFrontierReleaseIds(releases) {
1193
1187
  normalized,
1194
1188
  numeric: normalized === void 0 ? null : getNumericCohortValue(normalized),
1195
1189
  bundleIds: /* @__PURE__ */ new Set(),
1196
- embedded: false,
1197
1190
  complete: false
1198
1191
  };
1199
1192
  });
@@ -1218,16 +1211,11 @@ function collectFrontierReleaseIds(releases) {
1218
1211
  for (const index of eligibleStateIndexes) {
1219
1212
  const state = cohortStates[index];
1220
1213
  if (state.complete) continue;
1221
- if (release.kind === "EMBEDDED") {
1222
- if (!state.embedded) {
1223
- state.embedded = true;
1224
- retained.add(release.id);
1225
- }
1226
- } else if (release.bundleId !== null && state.bundleIds.size < 11 && !state.bundleIds.has(release.bundleId)) {
1214
+ if (release.bundleId !== null && !state.bundleIds.has(release.bundleId)) {
1227
1215
  state.bundleIds.add(release.bundleId);
1228
1216
  retained.add(release.id);
1229
1217
  }
1230
- if (state.embedded && state.bundleIds.size >= 11) {
1218
+ if (state.bundleIds.size >= 11) {
1231
1219
  state.complete = true;
1232
1220
  incompleteStateCount -= 1;
1233
1221
  }
@@ -1412,12 +1400,11 @@ function projectCompiledCatalog(catalog, appVersion) {
1412
1400
  }
1413
1401
  function projectCompiledRollbackCatalog(catalog, appVersion) {
1414
1402
  let indexes;
1415
- if (catalog.strategy === "FINGERPRINT") indexes = catalog.rollbackReleaseIndexes ?? catalog.releaseIndexes;
1403
+ if (catalog.strategy === "FINGERPRINT") indexes = catalog.rollbackReleaseIndexes;
1416
1404
  else {
1417
1405
  const canonicalVersion = appVersion && canonicalizeAppVersion(appVersion);
1418
1406
  if (!canonicalVersion) return [];
1419
- const segment = catalog.segments.find((candidate) => versionInSegment(canonicalVersion, candidate));
1420
- indexes = segment?.rollbackReleaseIndexes ?? segment?.releaseIndexes ?? [];
1407
+ indexes = catalog.segments.find((segment) => versionInSegment(canonicalVersion, segment))?.rollbackReleaseIndexes ?? [];
1421
1408
  }
1422
1409
  return indexes.map((index) => catalog.releaseDescriptors[index]);
1423
1410
  }
@@ -1939,7 +1926,7 @@ const SETTINGS_TABLE = {
1939
1926
  const ENGINE_SCHEMA_KEY = "schema.engine";
1940
1927
  const CORE_SCHEMA_KEY = "schema.core";
1941
1928
  const stored = ({ key, expected, found }) => `"${key}" is ${found === null ? "missing" : `"${found}"`}; expected "${expected}"`;
1942
- const settingMessage = (adapterName, { key, expected, found }) => `Hot Updater schema setting "${key}" for ${adapterName} is ${found === null ? "missing" : `"${found}"`}; expected "${expected}". ${key === "schema.engine" ? "Create a new empty database and run `hot-updater db migrate`; databases from before the storage engine are not converted." : "Run `hot-updater db migrate`."}`;
1929
+ const settingMessage = (adapterName, { key, expected, found }) => `Hot Updater schema setting "${key}" for ${adapterName} is ${found === null ? "missing" : `"${found}"`}; expected "${expected}". Run \`hot-updater db migrate\`.`;
1943
1930
  /** The plugin a `schema.<id>` setting belongs to; undefined for core's and the engine's. */
1944
1931
  const pluginOf = ({ key }) => key.startsWith("schema.") && key !== "schema.engine" && key !== CORE_SCHEMA_KEY ? key.slice(7) : void 0;
1945
1932
  const listed = (items) => items.length < 2 ? items.join("") : `${items.slice(0, -1).join(", ")} and ${items.at(-1)}`;
@@ -2057,26 +2044,13 @@ const METER = Symbol.for("@hot-updater/plugin-core/read-meter");
2057
2044
  const readMeterOf = (database) => typeof database === "object" && database !== null ? database[METER] : void 0;
2058
2045
  //#endregion
2059
2046
  //#region ../plugin-core/dist/engine/db/schemaSettings.mjs
2060
- /** Refuses a database with `schema.core` but no `schema.engine`: it predates the engine. */
2061
- const assertEngineDatabase = (adapterName, stored) => {
2062
- if (stored.get("schema.core") && !stored.get("schema.engine")) throw new HotUpdaterSchemaMigrationRequiredError(adapterName, String(stored.get("schema.core").value), {
2063
- key: ENGINE_SCHEMA_KEY,
2064
- expected: "1",
2065
- found: null
2066
- });
2067
- };
2068
2047
  const storedSettings = async (adapter, keys) => {
2069
2048
  const rows = await readSettings(adapter, keys);
2070
2049
  return new Map(keys.map((key, position) => [key, rows[position] ?? null]));
2071
2050
  };
2072
- /** Writes the settings rows after every table exists, refusing a pre-engine database. */
2051
+ /** Writes the settings rows after every table exists. */
2073
2052
  const writeSchemaSettings = async (adapter, adapterName, settings) => {
2074
- const stored = await storedSettings(adapter, [.../* @__PURE__ */ new Set([
2075
- "schema.core",
2076
- ENGINE_SCHEMA_KEY,
2077
- ...Object.keys(settings)
2078
- ])]);
2079
- assertEngineDatabase(adapterName, stored);
2053
+ const stored = await storedSettings(adapter, Object.keys(settings));
2080
2054
  const ops = Object.entries(settings).flatMap(([key, value]) => {
2081
2055
  const row = stored.get(key);
2082
2056
  if (row === null || row === void 0) return [{
@@ -2099,19 +2073,11 @@ const writeSchemaSettings = async (adapter, adapterName, settings) => {
2099
2073
  }];
2100
2074
  });
2101
2075
  if (ops.length === 0) return;
2102
- if (!(await adapter.write(ops)).ok) throw new Error("The schema settings changed during the migration; run it again.");
2076
+ if (!(await adapter.write(ops)).ok) throw new Error(`${adapterName}: the schema settings changed during the migration; run it again.`);
2103
2077
  };
2104
- /**
2105
- * Creates or updates every table, then writes the settings rows last. A
2106
- * pre-engine database is refused before any table changes.
2107
- */
2078
+ /** Creates or updates every table, then writes the settings rows last. */
2108
2079
  const migrateSchema = async (adapter, adapterName, tables, settings) => {
2109
2080
  if (adapter.migrations === void 0) throw new Error(`${adapterName} creates its tables with its own tooling; write only the settings rows.`);
2110
- const stored = await storedSettings(adapter, ["schema.core", ENGINE_SCHEMA_KEY]).catch((error) => {
2111
- if (!isMissingSchemaError(error)) throw error;
2112
- return /* @__PURE__ */ new Map();
2113
- });
2114
- assertEngineDatabase(adapterName, stored);
2115
2081
  await adapter.migrations.apply([...tables, SETTINGS_TABLE]);
2116
2082
  await writeSchemaSettings(adapter, adapterName, settings);
2117
2083
  };
@@ -2403,15 +2369,14 @@ const storedSchemaVersion = (stored) => {
2403
2369
  const version = stored?.get("schema.core") ?? stored?.get("version");
2404
2370
  return typeof version === "string" ? version : void 0;
2405
2371
  };
2406
- /** A v0 or pre-engine database is recreated, never converted. */
2407
- const refusePreEngineDatabase = (adapterName, stored) => {
2408
- const version = storedSchemaVersion(stored);
2409
- if (version === void 0 || stored.has("schema.engine")) return;
2410
- throw new HotUpdaterSchemaMigrationRequiredError(adapterName, version, stored.has("schema.core") ? {
2411
- key: ENGINE_SCHEMA_KEY,
2412
- expected: "1",
2413
- found: null
2414
- } : void 0);
2372
+ /**
2373
+ * A v0 database, whose settings hold `version` and no `schema.engine`, is
2374
+ * recreated, never converted.
2375
+ */
2376
+ const refuseV0Database = (adapterName, stored) => {
2377
+ const version = stored.get("version");
2378
+ if (typeof version !== "string" || stored.has("schema.engine")) return;
2379
+ throw new HotUpdaterSchemaMigrationRequiredError(adapterName, version);
2415
2380
  };
2416
2381
  //#endregion
2417
2382
  //#region ../plugin-core/dist/engine/database/cursor.mjs
@@ -3474,13 +3439,13 @@ const resolveSchema = (modules) => {
3474
3439
  * `hot-updater db migrate` for a store whose adapter creates its own tables
3475
3440
  * (MongoDB and the key-value stores): the tables and indexes, then the
3476
3441
  * settings rows, applied when a setting is missing or different, and refused
3477
- * on a database from before the engine.
3442
+ * on a v0 database.
3478
3443
  */
3479
3444
  const createEngineMigrator = (options) => {
3480
3445
  const getVersion = async () => storedSchemaVersion(await options.readSettings());
3481
3446
  const makeResult = async (migrate = {}) => {
3482
3447
  const stored = await options.readSettings();
3483
- refusePreEngineDatabase(options.adapterName, stored);
3448
+ refuseV0Database(options.adapterName, stored);
3484
3449
  if (Object.entries(options.settings).every(([key, value]) => stored.get(key) === value)) return getEmptyMigrationResult();
3485
3450
  return {
3486
3451
  operations: [...options.schema.tables.map((table) => ({
@@ -4585,7 +4550,7 @@ const createKvAdapter = ({ store, tablePrefix = "" }) => {
4585
4550
  };
4586
4551
  //#endregion
4587
4552
  //#region ../../packages/server/dist/version.mjs
4588
- const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.46";
4553
+ const HOT_UPDATER_SERVER_VERSION = "1.0.0";
4589
4554
  //#endregion
4590
4555
  //#region ../../packages/server/dist/handlerVersionRoutes.mjs
4591
4556
  /**
@@ -5274,7 +5239,7 @@ const baseBundleIdsOf = (row, range, bundleId, limit) => {
5274
5239
  for (const { descriptor, index } of newestFirst) {
5275
5240
  if (ids.length >= limit) break;
5276
5241
  const id = descriptor.bundleId;
5277
- if (serving.has(index) && descriptor.kind === "BUNDLE" && id !== null && id < bundleId && !ids.includes(id)) ids.push(id);
5242
+ if (serving.has(index) && id !== null && id < bundleId && !ids.includes(id)) ids.push(id);
5278
5243
  }
5279
5244
  return ids;
5280
5245
  };
@@ -6040,7 +6005,7 @@ const createCoreOperations = (db, { now = Date.now } = {}) => {
6040
6005
  }),
6041
6006
  promoteRelease: (input) => withChannels(async () => {
6042
6007
  const checkSource = (source) => {
6043
- if (source.kind !== "BUNDLE" || source.bundle_id === null) throw new ReleaseManagementError("TARGET_RELEASE_INVALID", "Only a Bundle Release can be promoted.");
6008
+ if (source.bundle_id === null) throw new ReleaseManagementError("TARGET_RELEASE_INVALID", "Only a Bundle Release can be promoted.");
6044
6009
  };
6045
6010
  checkSource((await db.transaction((tx) => loadTarget(tx, input))).release);
6046
6011
  const targetChannel = input.targetChannel.trim();
@@ -6239,7 +6204,6 @@ const fail = (message) => {
6239
6204
  const isRecord$6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
6240
6205
  const checkPlugin = (value, at) => {
6241
6206
  if (!isRecord$6(value)) return fail(`${at} is not a plugin.`);
6242
- if ("kind" in value) fail(`${at} has a kind; core is built in and is never passed as a plugin.`);
6243
6207
  const unknown = Object.keys(value).find((key) => !PLUGIN_KEYS.has(key));
6244
6208
  if (unknown !== void 0) fail(`${at} has an unknown key "${unknown}".`);
6245
6209
  const plugin = value;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hot-updater/aws",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.46",
4
+ "version": "1.0.0",
5
5
  "description": "React Native OTA solution for self-hosted",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.mjs",
@@ -45,9 +45,9 @@
45
45
  "es-toolkit": "^1.32.0",
46
46
  "execa": "9.5.2",
47
47
  "mime": "^4.0.4",
48
- "@hot-updater/protocol": "1.0.0-rc.46",
49
- "@hot-updater/test-utils": "1.0.0-rc.46",
50
- "@hot-updater/mock": "1.0.0-rc.46"
48
+ "@hot-updater/protocol": "1.0.0",
49
+ "@hot-updater/test-utils": "1.0.0",
50
+ "@hot-updater/mock": "1.0.0"
51
51
  },
52
52
  "dependencies": {
53
53
  "@aws-sdk/client-cloudfront": "3.1066.0",
@@ -63,9 +63,9 @@
63
63
  "@aws-sdk/lib-dynamodb": "3.1066.0",
64
64
  "@aws-sdk/s3-request-presigner": "3.1066.0",
65
65
  "hono": "4.12.34",
66
- "@hot-updater/cli-tools": "1.0.0-rc.46",
67
- "@hot-updater/plugin-core": "1.0.0-rc.46",
68
- "@hot-updater/server": "1.0.0-rc.46"
66
+ "@hot-updater/plugin-core": "1.0.0",
67
+ "@hot-updater/server": "1.0.0",
68
+ "@hot-updater/cli-tools": "1.0.0"
69
69
  },
70
70
  "scripts": {
71
71
  "build": "tsdown",