@hot-updater/aws 1.0.0-rc.45 → 1.0.0-rc.47

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
  };
@@ -241,6 +241,13 @@ const isDatabaseJsonValue = (value) => {
241
241
  const isDatabaseJsonObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && isDatabaseJsonValue(value);
242
242
  const isDatabaseMetadataObject = (value) => isDatabaseJsonObject(value) && (!Object.hasOwn(value, "app_version") || typeof value["app_version"] === "string");
243
243
  //#endregion
244
+ //#region ../plugin-core/dist/databaseMetadata.mjs
245
+ const bundleMetadataToRow = (metadata) => {
246
+ if (metadata === void 0) return {};
247
+ if (!isDatabaseMetadataObject(metadata)) throw new DatabaseAdapterInputError("invalid-data");
248
+ return metadata;
249
+ };
250
+ //#endregion
244
251
  //#region ../../packages/protocol/dist/index.mjs
245
252
  const LETTER_DASH_NUMBER$2 = "[a-zA-Z0-9-]";
246
253
  const NUMERIC_IDENTIFIER$2 = String.raw`0|[1-9]\d*`;
@@ -354,7 +361,6 @@ function canonicalizeAppVersion(appVersion) {
354
361
  const version = coerce$1(appVersion);
355
362
  return version ? normalizeFull(version) : null;
356
363
  }
357
- const stripBundleArtifactMetadata = (metadata) => metadata;
358
364
  const getManifestStorageUri = (bundle) => bundle.manifestStorageUri;
359
365
  const getManifestFileHash = (bundle) => bundle.manifestFileHash;
360
366
  const getAssetBaseStorageUri = (bundle) => bundle.assetBaseStorageUri;
@@ -601,14 +607,6 @@ const NIL_UUID = "00000000-0000-0000-0000-000000000000";
601
607
  const UUID_V7_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
602
608
  const isUUIDv7 = (value) => typeof value === "string" && UUID_V7_PATTERN.test(value);
603
609
  //#endregion
604
- //#region ../plugin-core/dist/databaseMetadata.mjs
605
- const bundleMetadataToRow = (metadata) => {
606
- const value = stripBundleArtifactMetadata(metadata);
607
- if (value === void 0) return {};
608
- if (!isDatabaseMetadataObject(value)) throw new DatabaseAdapterInputError("invalid-data");
609
- return value;
610
- };
611
- //#endregion
612
610
  //#region ../plugin-core/dist/databaseRows.mjs
613
611
  const releaseRowToRelease = (row) => ({
614
612
  id: row.id,
@@ -666,7 +664,7 @@ const rowToBundle = (row, patchRows = []) => {
666
664
  id: row.id,
667
665
  platform: row.platform,
668
666
  gitCommitHash: row.git_commit_hash,
669
- metadata: stripBundleArtifactMetadata(row.metadata),
667
+ metadata: row.metadata,
670
668
  manifestStorageUri: row.manifest_storage_uri,
671
669
  manifestFileHash: row.manifest_file_hash,
672
670
  assetBaseStorageUri: row.asset_base_storage_uri,
@@ -674,6 +672,35 @@ const rowToBundle = (row, patchRows = []) => {
674
672
  };
675
673
  };
676
674
  //#endregion
675
+ //#region ../plugin-core/dist/uuidv7.mjs
676
+ const extractTimestampFromUUIDv7 = (uuid) => {
677
+ if (!isUUIDv7(uuid)) throw new TypeError("Expected a canonical lowercase UUIDv7");
678
+ const timestampHex = uuid.split("-").join("").slice(0, 12);
679
+ return Number.parseInt(timestampHex, 16);
680
+ };
681
+ function createUUIDv7FromTimestampHex(timestampHex) {
682
+ const randomBytes = /* @__PURE__ */ new Uint8Array(10);
683
+ crypto.getRandomValues(randomBytes);
684
+ const randomHex = Array.from(randomBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
685
+ const randA = randomHex.slice(0, 3);
686
+ const randBHex = randomHex.slice(3, 19);
687
+ const versionAndRandA = `7${randA}`;
688
+ const variantAndFirstRandB = (128 | parseInt(randBHex.slice(0, 2), 16) & 63).toString(16).padStart(2, "0");
689
+ return [
690
+ timestampHex.slice(0, 8),
691
+ timestampHex.slice(8, 12),
692
+ versionAndRandA,
693
+ variantAndFirstRandB + randBHex.slice(2, 4),
694
+ randBHex.slice(4, 16)
695
+ ].join("-");
696
+ }
697
+ const createUUIDv7 = () => createUUIDv7FromTimestampHex(Date.now().toString(16).padStart(12, "0"));
698
+ const createUUIDv7After = (floor, nowMs = Date.now()) => {
699
+ const timestamp = Math.max(nowMs, floor === null ? 0 : extractTimestampFromUUIDv7(floor) + 1);
700
+ if (!Number.isSafeInteger(timestamp) || timestamp < 0 || timestamp >= 2 ** 48) throw new RangeError("UUIDv7 timestamp is out of range");
701
+ return createUUIDv7FromTimestampHex(timestamp.toString(16).padStart(12, "0"));
702
+ };
703
+ //#endregion
677
704
  //#region ../plugin-core/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.mjs
678
705
  const LETTER_DASH_NUMBER$1 = "[a-zA-Z0-9-]";
679
706
  const NUMERIC_IDENTIFIER$1 = String.raw`0|[1-9]\d*`;
@@ -1020,42 +1047,6 @@ function coerce(value, options = {}) {
1020
1047
  return tryParse(`${major}.${match[3] || "0"}.${match[4] || "0"}${options.includePrerelease && match[5] ? `-${match[5]}` : ""}${options.includePrerelease && match[6] ? `+${match[6]}` : ""}`, options);
1021
1048
  }
1022
1049
  //#endregion
1023
- //#region ../plugin-core/dist/semverSatisfies.mjs
1024
- const semverSatisfies = (targetAppVersion, currentVersion) => {
1025
- const currentCoerce = coerce(currentVersion);
1026
- if (!currentCoerce) return false;
1027
- return satisfies(currentCoerce, targetAppVersion);
1028
- };
1029
- //#endregion
1030
- //#region ../plugin-core/dist/uuidv7.mjs
1031
- const extractTimestampFromUUIDv7 = (uuid) => {
1032
- if (!isUUIDv7(uuid)) throw new TypeError("Expected a canonical lowercase UUIDv7");
1033
- const timestampHex = uuid.split("-").join("").slice(0, 12);
1034
- return Number.parseInt(timestampHex, 16);
1035
- };
1036
- function createUUIDv7FromTimestampHex(timestampHex) {
1037
- const randomBytes = /* @__PURE__ */ new Uint8Array(10);
1038
- crypto.getRandomValues(randomBytes);
1039
- const randomHex = Array.from(randomBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
1040
- const randA = randomHex.slice(0, 3);
1041
- const randBHex = randomHex.slice(3, 19);
1042
- const versionAndRandA = `7${randA}`;
1043
- const variantAndFirstRandB = (128 | parseInt(randBHex.slice(0, 2), 16) & 63).toString(16).padStart(2, "0");
1044
- return [
1045
- timestampHex.slice(0, 8),
1046
- timestampHex.slice(8, 12),
1047
- versionAndRandA,
1048
- variantAndFirstRandB + randBHex.slice(2, 4),
1049
- randBHex.slice(4, 16)
1050
- ].join("-");
1051
- }
1052
- const createUUIDv7 = () => createUUIDv7FromTimestampHex(Date.now().toString(16).padStart(12, "0"));
1053
- const createUUIDv7After = (floor, nowMs = Date.now()) => {
1054
- const timestamp = Math.max(nowMs, floor === null ? 0 : extractTimestampFromUUIDv7(floor) + 1);
1055
- if (!Number.isSafeInteger(timestamp) || timestamp < 0 || timestamp >= 2 ** 48) throw new RangeError("UUIDv7 timestamp is out of range");
1056
- return createUUIDv7FromTimestampHex(timestamp.toString(16).padStart(12, "0"));
1057
- };
1058
- //#endregion
1059
1050
  //#region ../plugin-core/dist/releaseCatalogCompiler.mjs
1060
1051
  var ReleaseCatalogCompilationError = class extends Error {
1061
1052
  code;
@@ -1163,29 +1154,23 @@ function validateReleases(releases, strategy) {
1163
1154
  if (seenIds.has(release.id)) throw new ReleaseCatalogCompilationError("INVALID_RELEASE", `Duplicate Release ID: ${release.id}`);
1164
1155
  seenIds.add(release.id);
1165
1156
  if (release.strategy !== strategy) throw new ReleaseCatalogCompilationError("INVALID_RELEASE", `Release ${release.id} has the wrong strategy`);
1166
- 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`);
1167
1158
  if (release.targetCohorts.length > 100) throw new ReleaseCatalogCompilationError("TARGET_COHORT_LIMIT", `Release ${release.id} exceeds 100 target cohorts`);
1168
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`);
1169
1160
  if (strategy === "FINGERPRINT" && (release.fingerprintHash === null || release.targetAppVersion !== null)) throw new ReleaseCatalogCompilationError("INVALID_RELEASE", `Release ${release.id} has an invalid fingerprint target`);
1170
1161
  }
1171
- return enabled.filter((release) => release.kind === "BUNDLE");
1162
+ return enabled;
1172
1163
  }
1173
1164
  function collectFrontierReleaseIds(releases) {
1174
1165
  if (releases.every((release) => normalizeRolloutCohortCount(release.rolloutCohortCount) >= 1e3)) {
1175
1166
  const retained = /* @__PURE__ */ new Set();
1176
1167
  const bundleIds = /* @__PURE__ */ new Set();
1177
- let embedded = false;
1178
1168
  for (const release of releases) {
1179
- if (release.kind === "EMBEDDED") {
1180
- if (!embedded) {
1181
- embedded = true;
1182
- retained.add(release.id);
1183
- }
1184
- } else if (release.bundleId !== null && bundleIds.size < 11 && !bundleIds.has(release.bundleId)) {
1169
+ if (release.bundleId !== null && !bundleIds.has(release.bundleId)) {
1185
1170
  bundleIds.add(release.bundleId);
1186
1171
  retained.add(release.id);
1187
1172
  }
1188
- if (embedded && bundleIds.size >= 11) break;
1173
+ if (bundleIds.size >= 11) break;
1189
1174
  }
1190
1175
  return retained;
1191
1176
  }
@@ -1202,7 +1187,6 @@ function collectFrontierReleaseIds(releases) {
1202
1187
  normalized,
1203
1188
  numeric: normalized === void 0 ? null : getNumericCohortValue(normalized),
1204
1189
  bundleIds: /* @__PURE__ */ new Set(),
1205
- embedded: false,
1206
1190
  complete: false
1207
1191
  };
1208
1192
  });
@@ -1227,16 +1211,11 @@ function collectFrontierReleaseIds(releases) {
1227
1211
  for (const index of eligibleStateIndexes) {
1228
1212
  const state = cohortStates[index];
1229
1213
  if (state.complete) continue;
1230
- if (release.kind === "EMBEDDED") {
1231
- if (!state.embedded) {
1232
- state.embedded = true;
1233
- retained.add(release.id);
1234
- }
1235
- } else if (release.bundleId !== null && state.bundleIds.size < 11 && !state.bundleIds.has(release.bundleId)) {
1214
+ if (release.bundleId !== null && !state.bundleIds.has(release.bundleId)) {
1236
1215
  state.bundleIds.add(release.bundleId);
1237
1216
  retained.add(release.id);
1238
1217
  }
1239
- if (state.embedded && state.bundleIds.size >= 11) {
1218
+ if (state.bundleIds.size >= 11) {
1240
1219
  state.complete = true;
1241
1220
  incompleteStateCount -= 1;
1242
1221
  }
@@ -1421,12 +1400,11 @@ function projectCompiledCatalog(catalog, appVersion) {
1421
1400
  }
1422
1401
  function projectCompiledRollbackCatalog(catalog, appVersion) {
1423
1402
  let indexes;
1424
- if (catalog.strategy === "FINGERPRINT") indexes = catalog.rollbackReleaseIndexes ?? catalog.releaseIndexes;
1403
+ if (catalog.strategy === "FINGERPRINT") indexes = catalog.rollbackReleaseIndexes;
1425
1404
  else {
1426
1405
  const canonicalVersion = appVersion && canonicalizeAppVersion(appVersion);
1427
1406
  if (!canonicalVersion) return [];
1428
- const segment = catalog.segments.find((candidate) => versionInSegment(canonicalVersion, candidate));
1429
- indexes = segment?.rollbackReleaseIndexes ?? segment?.releaseIndexes ?? [];
1407
+ indexes = catalog.segments.find((segment) => versionInSegment(canonicalVersion, segment))?.rollbackReleaseIndexes ?? [];
1430
1408
  }
1431
1409
  return indexes.map((index) => catalog.releaseDescriptors[index]);
1432
1410
  }
@@ -1451,6 +1429,13 @@ var ReleaseCatalogMutationError = class extends Error {
1451
1429
  }
1452
1430
  };
1453
1431
  //#endregion
1432
+ //#region ../plugin-core/dist/semverSatisfies.mjs
1433
+ const semverSatisfies = (targetAppVersion, currentVersion) => {
1434
+ const currentCoerce = coerce(currentVersion);
1435
+ if (!currentCoerce) return false;
1436
+ return satisfies(currentCoerce, targetAppVersion);
1437
+ };
1438
+ //#endregion
1454
1439
  //#region ../plugin-core/dist/serverPlugin/definePlugin.mjs
1455
1440
  /** Declares a plugin; Hot Updater's own plugins and third-party ones use the same contract. */
1456
1441
  const definePlugin = (plugin) => plugin;
@@ -1941,7 +1926,7 @@ const SETTINGS_TABLE = {
1941
1926
  const ENGINE_SCHEMA_KEY = "schema.engine";
1942
1927
  const CORE_SCHEMA_KEY = "schema.core";
1943
1928
  const stored = ({ key, expected, found }) => `"${key}" is ${found === null ? "missing" : `"${found}"`}; expected "${expected}"`;
1944
- 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\`.`;
1945
1930
  /** The plugin a `schema.<id>` setting belongs to; undefined for core's and the engine's. */
1946
1931
  const pluginOf = ({ key }) => key.startsWith("schema.") && key !== "schema.engine" && key !== CORE_SCHEMA_KEY ? key.slice(7) : void 0;
1947
1932
  const listed = (items) => items.length < 2 ? items.join("") : `${items.slice(0, -1).join(", ")} and ${items.at(-1)}`;
@@ -2059,26 +2044,13 @@ const METER = Symbol.for("@hot-updater/plugin-core/read-meter");
2059
2044
  const readMeterOf = (database) => typeof database === "object" && database !== null ? database[METER] : void 0;
2060
2045
  //#endregion
2061
2046
  //#region ../plugin-core/dist/engine/db/schemaSettings.mjs
2062
- /** Refuses a database with `schema.core` but no `schema.engine`: it predates the engine. */
2063
- const assertEngineDatabase = (adapterName, stored) => {
2064
- if (stored.get("schema.core") && !stored.get("schema.engine")) throw new HotUpdaterSchemaMigrationRequiredError(adapterName, String(stored.get("schema.core").value), {
2065
- key: ENGINE_SCHEMA_KEY,
2066
- expected: "1",
2067
- found: null
2068
- });
2069
- };
2070
2047
  const storedSettings = async (adapter, keys) => {
2071
2048
  const rows = await readSettings(adapter, keys);
2072
2049
  return new Map(keys.map((key, position) => [key, rows[position] ?? null]));
2073
2050
  };
2074
- /** Writes the settings rows after every table exists, refusing a pre-engine database. */
2051
+ /** Writes the settings rows after every table exists. */
2075
2052
  const writeSchemaSettings = async (adapter, adapterName, settings) => {
2076
- const stored = await storedSettings(adapter, [.../* @__PURE__ */ new Set([
2077
- "schema.core",
2078
- ENGINE_SCHEMA_KEY,
2079
- ...Object.keys(settings)
2080
- ])]);
2081
- assertEngineDatabase(adapterName, stored);
2053
+ const stored = await storedSettings(adapter, Object.keys(settings));
2082
2054
  const ops = Object.entries(settings).flatMap(([key, value]) => {
2083
2055
  const row = stored.get(key);
2084
2056
  if (row === null || row === void 0) return [{
@@ -2101,19 +2073,11 @@ const writeSchemaSettings = async (adapter, adapterName, settings) => {
2101
2073
  }];
2102
2074
  });
2103
2075
  if (ops.length === 0) return;
2104
- 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.`);
2105
2077
  };
2106
- /**
2107
- * Creates or updates every table, then writes the settings rows last. A
2108
- * pre-engine database is refused before any table changes.
2109
- */
2078
+ /** Creates or updates every table, then writes the settings rows last. */
2110
2079
  const migrateSchema = async (adapter, adapterName, tables, settings) => {
2111
2080
  if (adapter.migrations === void 0) throw new Error(`${adapterName} creates its tables with its own tooling; write only the settings rows.`);
2112
- const stored = await storedSettings(adapter, ["schema.core", ENGINE_SCHEMA_KEY]).catch((error) => {
2113
- if (!isMissingSchemaError(error)) throw error;
2114
- return /* @__PURE__ */ new Map();
2115
- });
2116
- assertEngineDatabase(adapterName, stored);
2117
2081
  await adapter.migrations.apply([...tables, SETTINGS_TABLE]);
2118
2082
  await writeSchemaSettings(adapter, adapterName, settings);
2119
2083
  };
@@ -2398,9 +2362,6 @@ const getEmptyMigrationResult = () => ({
2398
2362
  execute: async () => {},
2399
2363
  getSQL: () => ""
2400
2364
  });
2401
- const assertSupportedMigrationMode = (options) => {
2402
- if (options.mode === "from-database") throw new Error("Hot Updater migrations support only mode: 'from-schema'.");
2403
- };
2404
2365
  //#endregion
2405
2366
  //#region ../plugin-core/dist/engine/db/settingsMigrator.mjs
2406
2367
  /** `schema.core`, or a v0 database's `version`. */
@@ -2408,15 +2369,14 @@ const storedSchemaVersion = (stored) => {
2408
2369
  const version = stored?.get("schema.core") ?? stored?.get("version");
2409
2370
  return typeof version === "string" ? version : void 0;
2410
2371
  };
2411
- /** A v0 or pre-engine database is recreated, never converted. */
2412
- const refusePreEngineDatabase = (adapterName, stored) => {
2413
- const version = storedSchemaVersion(stored);
2414
- if (version === void 0 || stored.has("schema.engine")) return;
2415
- throw new HotUpdaterSchemaMigrationRequiredError(adapterName, version, stored.has("schema.core") ? {
2416
- key: ENGINE_SCHEMA_KEY,
2417
- expected: "1",
2418
- found: null
2419
- } : 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);
2420
2380
  };
2421
2381
  //#endregion
2422
2382
  //#region ../plugin-core/dist/engine/database/cursor.mjs
@@ -3479,14 +3439,13 @@ const resolveSchema = (modules) => {
3479
3439
  * `hot-updater db migrate` for a store whose adapter creates its own tables
3480
3440
  * (MongoDB and the key-value stores): the tables and indexes, then the
3481
3441
  * settings rows, applied when a setting is missing or different, and refused
3482
- * on a database from before the engine.
3442
+ * on a v0 database.
3483
3443
  */
3484
3444
  const createEngineMigrator = (options) => {
3485
3445
  const getVersion = async () => storedSchemaVersion(await options.readSettings());
3486
3446
  const makeResult = async (migrate = {}) => {
3487
- assertSupportedMigrationMode(migrate);
3488
3447
  const stored = await options.readSettings();
3489
- refusePreEngineDatabase(options.adapterName, stored);
3448
+ refuseV0Database(options.adapterName, stored);
3490
3449
  if (Object.entries(options.settings).every(([key, value]) => stored.get(key) === value)) return getEmptyMigrationResult();
3491
3450
  return {
3492
3451
  operations: [...options.schema.tables.map((table) => ({
@@ -4591,7 +4550,7 @@ const createKvAdapter = ({ store, tablePrefix = "" }) => {
4591
4550
  };
4592
4551
  //#endregion
4593
4552
  //#region ../../packages/server/dist/version.mjs
4594
- const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.45";
4553
+ const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.47";
4595
4554
  //#endregion
4596
4555
  //#region ../../packages/server/dist/handlerVersionRoutes.mjs
4597
4556
  /**
@@ -5280,7 +5239,7 @@ const baseBundleIdsOf = (row, range, bundleId, limit) => {
5280
5239
  for (const { descriptor, index } of newestFirst) {
5281
5240
  if (ids.length >= limit) break;
5282
5241
  const id = descriptor.bundleId;
5283
- 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);
5284
5243
  }
5285
5244
  return ids;
5286
5245
  };
@@ -6046,7 +6005,7 @@ const createCoreOperations = (db, { now = Date.now } = {}) => {
6046
6005
  }),
6047
6006
  promoteRelease: (input) => withChannels(async () => {
6048
6007
  const checkSource = (source) => {
6049
- 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.");
6050
6009
  };
6051
6010
  checkSource((await db.transaction((tx) => loadTarget(tx, input))).release);
6052
6011
  const targetChannel = input.targetChannel.trim();
@@ -6245,7 +6204,6 @@ const fail = (message) => {
6245
6204
  const isRecord$6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
6246
6205
  const checkPlugin = (value, at) => {
6247
6206
  if (!isRecord$6(value)) return fail(`${at} is not a plugin.`);
6248
- if ("kind" in value) fail(`${at} has a kind; core is built in and is never passed as a plugin.`);
6249
6207
  const unknown = Object.keys(value).find((key) => !PLUGIN_KEYS.has(key));
6250
6208
  if (unknown !== void 0) fail(`${at} has an unknown key "${unknown}".`);
6251
6209
  const plugin = value;
@@ -7137,7 +7095,7 @@ const databaseOf = (value) => {
7137
7095
  if (isAdapter(value.adapter)) return value;
7138
7096
  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(...).");
7139
7097
  }
7140
- throw new HotUpdaterConfigError("database must be a Hot Updater 1.0 database, such as kyselyAdapter(...) or postgres(...). Upgrade the provider package that created it.");
7098
+ throw new HotUpdaterConfigError("database must be a Hot Updater database adapter, such as kyselyAdapter(...) or postgres(...).");
7141
7099
  };
7142
7100
  /** The configured storage, when it is a storage adapter. */
7143
7101
  const storageOf = (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.45",
4
+ "version": "1.0.0-rc.47",
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.45",
49
- "@hot-updater/mock": "1.0.0-rc.45",
50
- "@hot-updater/test-utils": "1.0.0-rc.45"
48
+ "@hot-updater/protocol": "1.0.0-rc.47",
49
+ "@hot-updater/mock": "1.0.0-rc.47",
50
+ "@hot-updater/test-utils": "1.0.0-rc.47"
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.45",
67
- "@hot-updater/plugin-core": "1.0.0-rc.45",
68
- "@hot-updater/server": "1.0.0-rc.45"
66
+ "@hot-updater/plugin-core": "1.0.0-rc.47",
67
+ "@hot-updater/server": "1.0.0-rc.47",
68
+ "@hot-updater/cli-tools": "1.0.0-rc.47"
69
69
  },
70
70
  "scripts": {
71
71
  "build": "tsdown",