@hot-updater/aws 0.29.1 → 0.29.3

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.
@@ -7181,6 +7181,11 @@ const regionLocationMap = {
7181
7181
  };
7182
7182
  //#endregion
7183
7183
  //#region iac/s3.ts
7184
+ function normalizeBucketRegion(region) {
7185
+ if (region == null) return "us-east-1";
7186
+ if (region === "EU") return "eu-west-1";
7187
+ return region;
7188
+ }
7184
7189
  var S3Manager = class {
7185
7190
  credentials;
7186
7191
  constructor(credentials) {
@@ -7193,10 +7198,10 @@ var S3Manager = class {
7193
7198
  });
7194
7199
  const buckets = (await s3Client.listBuckets({})).Buckets ?? [];
7195
7200
  return await Promise.all(buckets.filter((bucket) => bucket.Name).map(async (bucket) => {
7196
- const { LocationConstraint: region } = await s3Client.getBucketLocation({ Bucket: bucket.Name });
7201
+ const { LocationConstraint } = await s3Client.getBucketLocation({ Bucket: bucket.Name });
7197
7202
  return {
7198
7203
  name: bucket.Name,
7199
- region
7204
+ region: normalizeBucketRegion(LocationConstraint)
7200
7205
  };
7201
7206
  }));
7202
7207
  }
@@ -7175,6 +7175,11 @@ const regionLocationMap = {
7175
7175
  };
7176
7176
  //#endregion
7177
7177
  //#region iac/s3.ts
7178
+ function normalizeBucketRegion(region) {
7179
+ if (region == null) return "us-east-1";
7180
+ if (region === "EU") return "eu-west-1";
7181
+ return region;
7182
+ }
7178
7183
  var S3Manager = class {
7179
7184
  credentials;
7180
7185
  constructor(credentials) {
@@ -7187,10 +7192,10 @@ var S3Manager = class {
7187
7192
  });
7188
7193
  const buckets = (await s3Client.listBuckets({})).Buckets ?? [];
7189
7194
  return await Promise.all(buckets.filter((bucket) => bucket.Name).map(async (bucket) => {
7190
- const { LocationConstraint: region } = await s3Client.getBucketLocation({ Bucket: bucket.Name });
7195
+ const { LocationConstraint } = await s3Client.getBucketLocation({ Bucket: bucket.Name });
7191
7196
  return {
7192
7197
  name: bucket.Name,
7193
- region
7198
+ region: normalizeBucketRegion(LocationConstraint)
7194
7199
  };
7195
7200
  }));
7196
7201
  }
@@ -36,7 +36,7 @@ let path = require("path");
36
36
  path = __toESM(path);
37
37
  let _aws_sdk_client_ssm = require("@aws-sdk/client-ssm");
38
38
  let _aws_sdk_cloudfront_signer = require("@aws-sdk/cloudfront-signer");
39
- //#region ../../packages/core/dist/rollout.mjs
39
+ //#region ../../packages/core/dist/index.mjs
40
40
  const NUMERIC_COHORT_SIZE = 1e3;
41
41
  const DEFAULT_ROLLOUT_COHORT_COUNT = NUMERIC_COHORT_SIZE;
42
42
  function parseNumericCohortValue(cohort) {
@@ -126,8 +126,6 @@ function isCohortEligibleForUpdate(bundleId, cohort, rolloutCohortCount, targetC
126
126
  if (normalizedRolloutCount >= 1e3) return true;
127
127
  return getNumericCohortRolloutPosition(bundleId, numericCohort) < normalizedRolloutCount;
128
128
  }
129
- //#endregion
130
- //#region ../../packages/core/dist/uuid.mjs
131
129
  const NIL_UUID = "00000000-0000-0000-0000-000000000000";
132
130
  //#endregion
133
131
  //#region ../plugin-core/dist/calculatePagination.mjs
@@ -1612,12 +1610,12 @@ function mergeBundleUpdate(baseBundle, patch) {
1612
1610
  */
1613
1611
  function createDatabasePlugin(options) {
1614
1612
  return (config, hooks) => {
1613
+ let cachedMethods = null;
1614
+ const getMethods = () => {
1615
+ if (!cachedMethods) cachedMethods = options.factory(config);
1616
+ return cachedMethods;
1617
+ };
1615
1618
  return () => {
1616
- let cachedMethods = null;
1617
- const getMethods = () => {
1618
- if (!cachedMethods) cachedMethods = options.factory(config);
1619
- return cachedMethods;
1620
- };
1621
1619
  const changedMap = /* @__PURE__ */ new Map();
1622
1620
  const markChanged = (operation, data) => {
1623
1621
  changedMap.set(data.id, {
@@ -1648,8 +1646,8 @@ function createDatabasePlugin(options) {
1648
1646
  const params = { changedSets: Array.from(changedMap.values()) };
1649
1647
  if (context === void 0) await methods.commitBundle(params);
1650
1648
  else await methods.commitBundle(params, context);
1651
- await hooks?.onDatabaseUpdated?.();
1652
1649
  changedMap.clear();
1650
+ await hooks?.onDatabaseUpdated?.();
1653
1651
  },
1654
1652
  async updateBundle(targetBundleId, newBundle, context) {
1655
1653
  const pendingChange = changedMap.get(targetBundleId);
@@ -3076,6 +3074,11 @@ function getSemverNormalizedVersions(version) {
3076
3074
  if (coerced.minor === 0 && coerced.patch === 0) versions.add(`${coerced.major}`);
3077
3075
  return Array.from(versions);
3078
3076
  }
3077
+ function resolveStorageTarget({ targetAppVersion, fingerprintHash }) {
3078
+ const target = normalizeTargetAppVersion(targetAppVersion) ?? fingerprintHash;
3079
+ if (!target) throw new Error("target not found");
3080
+ return target;
3081
+ }
3079
3082
  /**
3080
3083
  * Creates a blob storage-based database plugin with lazy initialization.
3081
3084
  *
@@ -3211,8 +3214,7 @@ const createBlobDatabasePlugin = ({ name, factory }) => {
3211
3214
  if (data.targetAppVersion !== void 0) isTargetAppVersionChanged = true;
3212
3215
  if (operation === "update" && data.channel !== void 0) isChannelChanged = true;
3213
3216
  if (operation === "insert") {
3214
- const target = normalizeTargetAppVersion(data.targetAppVersion) ?? data.fingerprintHash;
3215
- if (!target) throw new Error("target not found");
3217
+ const target = resolveStorageTarget(data);
3216
3218
  const key = `${data.channel}/${data.platform}/${target}/update.json`;
3217
3219
  const bundleWithKey = {
3218
3220
  ...data,
@@ -3241,20 +3243,16 @@ const createBlobDatabasePlugin = ({ name, factory }) => {
3241
3243
  if (!bundle) bundle = bundlesMap.get(data.id);
3242
3244
  if (!bundle) throw new Error("targetBundleId not found");
3243
3245
  if (operation === "update") {
3244
- const newChannel = data.channel !== void 0 ? data.channel : bundle.channel;
3245
- const newPlatform = data.platform !== void 0 ? data.platform : bundle.platform;
3246
- const target = data.fingerprintHash ?? bundle.fingerprintHash ?? normalizeTargetAppVersion(data.targetAppVersion) ?? normalizeTargetAppVersion(bundle.targetAppVersion);
3247
- if (!target) throw new Error("target not found");
3248
- const newKey = `${newChannel}/${newPlatform}/${target}/update.json`;
3246
+ const updatedBundle = {
3247
+ ...bundle,
3248
+ ...data
3249
+ };
3250
+ const newKey = `${updatedBundle.channel}/${updatedBundle.platform}/${resolveStorageTarget(updatedBundle)}/update.json`;
3249
3251
  if (newKey !== bundle._updateJsonKey) {
3250
3252
  const oldKey = bundle._updateJsonKey;
3251
3253
  removalsByKey[oldKey] = removalsByKey[oldKey] || [];
3252
3254
  removalsByKey[oldKey].push(bundle.id);
3253
3255
  changedBundlesByKey[newKey] = changedBundlesByKey[newKey] || [];
3254
- const updatedBundle = {
3255
- ...bundle,
3256
- ...data
3257
- };
3258
3256
  updatedBundle._oldUpdateJsonKey = oldKey;
3259
3257
  updatedBundle._updateJsonKey = newKey;
3260
3258
  bundlesMap.set(data.id, updatedBundle);
@@ -3274,10 +3272,6 @@ const createBlobDatabasePlugin = ({ name, factory }) => {
3274
3272
  continue;
3275
3273
  }
3276
3274
  const currentKey = bundle._updateJsonKey;
3277
- const updatedBundle = {
3278
- ...bundle,
3279
- ...data
3280
- };
3281
3275
  bundlesMap.set(data.id, updatedBundle);
3282
3276
  pendingBundlesMap.set(data.id, updatedBundle);
3283
3277
  changedBundlesByKey[currentKey] = changedBundlesByKey[currentKey] || [];
@@ -3458,9 +3452,17 @@ const INIT_BUNDLE_ROLLBACK_UPDATE_INFO = {
3458
3452
  storageUri: null,
3459
3453
  fileHash: null
3460
3454
  };
3461
- function createPluginDatabaseCore(plugin, resolveFileUrl) {
3455
+ function createPluginDatabaseCore(getPlugin, resolveFileUrl, options) {
3456
+ const runWithMutationPlugin = async (operation) => {
3457
+ const plugin = options?.createMutationPlugin?.() ?? getPlugin();
3458
+ try {
3459
+ return await operation(plugin);
3460
+ } finally {
3461
+ if (options?.createMutationPlugin) await options.cleanupMutationPlugin?.(plugin);
3462
+ }
3463
+ };
3462
3464
  const getSortedBundlePage = async (options, context) => {
3463
- const result = await plugin.getBundles({
3465
+ const result = await getPlugin().getBundles({
3464
3466
  ...options,
3465
3467
  orderBy: options.orderBy ?? DESC_ORDER
3466
3468
  }, context);
@@ -3514,7 +3516,7 @@ function createPluginDatabaseCore(plugin, resolveFileUrl) {
3514
3516
  return {
3515
3517
  api: {
3516
3518
  async getBundleById(id, context) {
3517
- return plugin.getBundleById(id, context);
3519
+ return getPlugin().getBundleById(id, context);
3518
3520
  },
3519
3521
  async getUpdateInfo(args, context) {
3520
3522
  const channel = args.channel ?? "production";
@@ -3555,27 +3557,33 @@ function createPluginDatabaseCore(plugin, resolveFileUrl) {
3555
3557
  };
3556
3558
  },
3557
3559
  async getChannels(context) {
3558
- return plugin.getChannels(context);
3560
+ return getPlugin().getChannels(context);
3559
3561
  },
3560
3562
  async getBundles(options, context) {
3561
- return plugin.getBundles(options, context);
3563
+ return getPlugin().getBundles(options, context);
3562
3564
  },
3563
3565
  async insertBundle(bundle, context) {
3564
- await plugin.appendBundle(bundle, context);
3565
- await plugin.commitBundle(context);
3566
+ await runWithMutationPlugin(async (plugin) => {
3567
+ await plugin.appendBundle(bundle, context);
3568
+ await plugin.commitBundle(context);
3569
+ });
3566
3570
  },
3567
3571
  async updateBundleById(bundleId, newBundle, context) {
3568
- await plugin.updateBundle(bundleId, newBundle, context);
3569
- await plugin.commitBundle(context);
3572
+ await runWithMutationPlugin(async (plugin) => {
3573
+ await plugin.updateBundle(bundleId, newBundle, context);
3574
+ await plugin.commitBundle(context);
3575
+ });
3570
3576
  },
3571
3577
  async deleteBundleById(bundleId, context) {
3572
- const bundle = await plugin.getBundleById(bundleId, context);
3573
- if (!bundle) return;
3574
- await plugin.deleteBundle(bundle, context);
3575
- await plugin.commitBundle(context);
3578
+ await runWithMutationPlugin(async (plugin) => {
3579
+ const bundle = await plugin.getBundleById(bundleId, context);
3580
+ if (!bundle) return;
3581
+ await plugin.deleteBundle(bundle, context);
3582
+ await plugin.commitBundle(context);
3583
+ });
3576
3584
  }
3577
3585
  },
3578
- adapterName: plugin.name,
3586
+ adapterName: getPlugin().name,
3579
3587
  createMigrator: () => {
3580
3588
  throw new Error("createMigrator is only available for Kysely/Prisma/Drizzle database adapters.");
3581
3589
  },
@@ -3752,7 +3760,7 @@ const handleGetBundles = async (_params, request, api, context) => {
3752
3760
  limit,
3753
3761
  offset
3754
3762
  }, context);
3755
- return new Response(JSON.stringify(result.data), {
3763
+ return new Response(JSON.stringify(result), {
3756
3764
  status: 200,
3757
3765
  headers: { "Content-Type": "application/json" }
3758
3766
  });
@@ -3785,8 +3793,8 @@ const handleDeleteBundle = async (params, _request, api, context) => {
3785
3793
  });
3786
3794
  };
3787
3795
  const handleGetChannels = async (_params, _request, api, context) => {
3788
- const channels = await api.getChannels(context);
3789
- return new Response(JSON.stringify({ channels }), {
3796
+ const response = { data: { channels: await api.getChannels(context) } };
3797
+ return new Response(JSON.stringify(response), {
3790
3798
  status: 200,
3791
3799
  headers: { "Content-Type": "application/json" }
3792
3800
  });
@@ -3867,6 +3875,7 @@ const normalizeBasePath = (basePath) => {
3867
3875
  //#endregion
3868
3876
  //#region ../../packages/server/src/runtime.ts
3869
3877
  function createHotUpdater(options) {
3878
+ const database = options.database;
3870
3879
  const basePath = normalizeBasePath(options.basePath ?? "/api");
3871
3880
  const storagePlugins = (options.storages ?? options.storagePlugins ?? []).map((plugin) => typeof plugin === "function" ? plugin() : plugin);
3872
3881
  const resolveStoragePluginUrl = async (storageUri, context) => {
@@ -3879,8 +3888,9 @@ function createHotUpdater(options) {
3879
3888
  if (!fileUrl) throw new Error("Storage plugin returned empty fileUrl");
3880
3889
  return fileUrl;
3881
3890
  };
3882
- if (!isDatabasePluginFactory(options.database) && !isDatabasePlugin(options.database)) throw new Error("@hot-updater/server/runtime only supports database plugins.");
3883
- const core = createPluginDatabaseCore(isDatabasePluginFactory(options.database) ? options.database() : options.database, resolveStoragePluginUrl);
3891
+ if (!isDatabasePluginFactory(database) && !isDatabasePlugin(database)) throw new Error("@hot-updater/server/runtime only supports database plugins.");
3892
+ const plugin = isDatabasePluginFactory(database) ? database() : database;
3893
+ const core = createPluginDatabaseCore(() => plugin, resolveStoragePluginUrl, isDatabasePluginFactory(database) ? { createMutationPlugin: () => database() } : void 0);
3884
3894
  const api = {
3885
3895
  ...core.api,
3886
3896
  handler: createHandler(core.api, {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hot-updater/aws",
3
3
  "type": "module",
4
- "version": "0.29.1",
4
+ "version": "0.29.3",
5
5
  "description": "React Native OTA solution for self-hosted",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.mjs",
@@ -42,10 +42,10 @@
42
42
  "es-toolkit": "^1.32.0",
43
43
  "execa": "9.5.2",
44
44
  "mime": "^4.0.4",
45
- "@hot-updater/core": "0.29.1",
46
- "@hot-updater/js": "0.29.1",
47
- "@hot-updater/mock": "0.29.1",
48
- "@hot-updater/test-utils": "0.29.1"
45
+ "@hot-updater/core": "0.29.3",
46
+ "@hot-updater/js": "0.29.3",
47
+ "@hot-updater/mock": "0.29.3",
48
+ "@hot-updater/test-utils": "0.29.3"
49
49
  },
50
50
  "dependencies": {
51
51
  "@aws-sdk/client-cloudfront": "3.1008.0",
@@ -60,9 +60,9 @@
60
60
  "@aws-sdk/lib-storage": "3.1008.0",
61
61
  "hono": "4.12.9",
62
62
  "aws-lambda": "1.0.7",
63
- "@hot-updater/server": "0.29.1",
64
- "@hot-updater/cli-tools": "0.29.1",
65
- "@hot-updater/plugin-core": "0.29.1"
63
+ "@hot-updater/cli-tools": "0.29.3",
64
+ "@hot-updater/plugin-core": "0.29.3",
65
+ "@hot-updater/server": "0.29.3"
66
66
  },
67
67
  "scripts": {
68
68
  "build": "tsdown",