@absolutejs/absolute 0.20.0-beta.81 → 0.20.0-beta.82

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.
@@ -20262,10 +20262,10 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20262
20262
  cacheControl: "public, max-age=31536000, immutable",
20263
20263
  contentType: "application/octet-stream",
20264
20264
  maxBytes: file.bytes,
20265
- metadata: { releaseId: manifest.releaseId, sha256: file.sha256 },
20265
+ metadata: { releaseid: manifest.releaseId, sha256: file.sha256 },
20266
20266
  signal: input.signal
20267
20267
  });
20268
- } else if (stored.size !== file.bytes || stored.metadata?.sha256 !== file.sha256 || stored.metadata?.releaseId !== manifest.releaseId)
20268
+ } else if (stored.size !== file.bytes || stored.metadata?.sha256 !== file.sha256 || (stored.metadata?.releaseid ?? stored.metadata?.releaseId) !== manifest.releaseId)
20269
20269
  throw new MobileUpdateRegistryError("Stored mobile update file identity changed");
20270
20270
  }
20271
20271
  const bytes = json(manifest);
@@ -20273,7 +20273,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20273
20273
  cacheControl: "public, max-age=31536000, immutable",
20274
20274
  contentType: "application/json",
20275
20275
  maxBytes: bytes.byteLength,
20276
- metadata: { releaseId: manifest.releaseId, sha256: digest(bytes) },
20276
+ metadata: { releaseid: manifest.releaseId, sha256: digest(bytes) },
20277
20277
  signal: input.signal
20278
20278
  });
20279
20279
  if (!await readManifest(manifest.appId, manifest.releaseId))
@@ -20346,7 +20346,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20346
20346
  ]);
20347
20347
  if (!bytes || !head)
20348
20348
  return null;
20349
- if (bytes.byteLength !== file.bytes || head.size !== file.bytes || head.metadata?.sha256 !== file.sha256 || head.metadata?.releaseId !== release.manifest.releaseId || digest(bytes) !== file.sha256)
20349
+ if (bytes.byteLength !== file.bytes || head.size !== file.bytes || head.metadata?.sha256 !== file.sha256 || (head.metadata?.releaseid ?? head.metadata?.releaseId) !== release.manifest.releaseId || digest(bytes) !== file.sha256)
20350
20350
  throw new MobileUpdateRegistryError("Stored mobile update file integrity failed");
20351
20351
  return { bytes, file };
20352
20352
  }
@@ -20705,10 +20705,27 @@ var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MOD
20705
20705
  const registry4 = loaded.default ?? loaded.registry;
20706
20706
  if (!isRegistry4(registry4))
20707
20707
  throw new TypeError("Mobile update registry must implement publication, promotion, rollback, resolution, and file reads.");
20708
+ const metadata = serverMetadata(loaded.absoluteMobileUpdateServer);
20709
+ const verifier = loaded.verifyAbsoluteMobileUpdateServer;
20710
+ if (metadata.storage === "durable" && typeof verifier !== "function")
20711
+ throw new TypeError("Mobile update registries marked durable must export verifyAbsoluteMobileUpdateServer(). Re-run `absolute mobile update provision --storage s3 --force` or provide an active durability check.");
20708
20712
  return {
20709
- metadata: serverMetadata(loaded.absoluteMobileUpdateServer),
20710
- registry: registry4
20713
+ metadata,
20714
+ registry: registry4,
20715
+ ...typeof verifier === "function" ? {
20716
+ verifyDurability: async () => {
20717
+ await verifier();
20718
+ }
20719
+ } : {}
20711
20720
  };
20721
+ }, verifyDurableModule = async (module) => {
20722
+ if (module.metadata.storage !== "durable")
20723
+ throw new TypeError("Mobile production updates require durable object storage. Re-run `absolute mobile update provision --storage s3 --force` or configure a durable adapter.");
20724
+ try {
20725
+ await module.verifyDurability?.();
20726
+ } catch (error) {
20727
+ throw new TypeError(`Durable mobile update storage verification failed for ${module.metadata.provider}. Check the bucket, endpoint, credentials, and read/write/delete permissions.`, { cause: error });
20728
+ }
20712
20729
  }, expoSigningOptions = (config) => {
20713
20730
  if (!config.updates?.expoCodeSigning)
20714
20731
  return;
@@ -20740,8 +20757,8 @@ var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MOD
20740
20757
  if (!updates || !server?.autoMount)
20741
20758
  return new Elysia4({ name: "absolutejs-mobile-updates-disabled" });
20742
20759
  const module = await loadAbsoluteMobileUpdateServerModule(projectRoot, server.registryModule);
20743
- if (options.production && module.metadata.storage !== "durable")
20744
- throw new TypeError("Mobile production updates require durable object storage. Re-run `absolute mobile update provision --storage s3 --force` or configure a durable adapter.");
20760
+ if (options.production)
20761
+ await verifyDurableModule(module);
20745
20762
  const manifest = new URL(updates.manifestUrl);
20746
20763
  if (!manifest.pathname.endsWith("/update.json"))
20747
20764
  throw new TypeError("Auto-mounted mobile update manifests must end in /update.json.");
@@ -20759,8 +20776,7 @@ var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MOD
20759
20776
  if (!config.updates)
20760
20777
  return;
20761
20778
  const module = await loadAbsoluteMobileUpdateServerModule(projectRoot, config.updateServer?.registryModule);
20762
- if (module.metadata.storage !== "durable")
20763
- throw new TypeError("Mobile production updates require durable object storage; the configured registry is local-only.");
20779
+ await verifyDurableModule(module);
20764
20780
  if (config.engine === "expo")
20765
20781
  expoSigningOptions(config);
20766
20782
  return module.metadata;
@@ -20787,7 +20803,8 @@ export default createMobileUpdateRegistry({
20787
20803
  store
20788
20804
  });
20789
20805
  `;
20790
- return `import { S3Client } from '@aws-sdk/client-s3';
20806
+ return `import { randomUUID } from 'node:crypto';
20807
+ import { DeleteObjectCommand, GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
20791
20808
  import { awsS3BlobStore } from '@absolutejs/blob/aws-s3';
20792
20809
  import { createMobileUpdateRegistry } from '@absolutejs/deploy/mobile-update';
20793
20810
 
@@ -20799,6 +20816,7 @@ const required = (name: string) => {
20799
20816
  return value;
20800
20817
  };
20801
20818
 
20819
+ const bucket = required('ABSOLUTE_MOBILE_UPDATE_S3_BUCKET');
20802
20820
  const client = new S3Client({
20803
20821
  region: process.env.ABSOLUTE_MOBILE_UPDATE_S3_REGION ?? 'auto',
20804
20822
  forcePathStyle: process.env.ABSOLUTE_MOBILE_UPDATE_S3_FORCE_PATH_STYLE === '1',
@@ -20806,10 +20824,22 @@ const client = new S3Client({
20806
20824
  ? { endpoint: process.env.ABSOLUTE_MOBILE_UPDATE_S3_ENDPOINT }
20807
20825
  : {})
20808
20826
  });
20809
- const store = awsS3BlobStore({
20810
- bucket: required('ABSOLUTE_MOBILE_UPDATE_S3_BUCKET'),
20811
- client
20812
- });
20827
+ const store = awsS3BlobStore({ bucket, client });
20828
+
20829
+ export const verifyAbsoluteMobileUpdateServer = async () => {
20830
+ const key = \`absolutejs/mobile-updates/_health/\${randomUUID()}\`;
20831
+ const expected = randomUUID();
20832
+ let stored = false;
20833
+ try {
20834
+ await client.send(new PutObjectCommand({ Bucket: bucket, Key: key, Body: expected }));
20835
+ stored = true;
20836
+ const response = await client.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
20837
+ if ((await response.Body?.transformToString()) !== expected)
20838
+ throw new Error('Durability probe read did not match its write.');
20839
+ } finally {
20840
+ if (stored) await client.send(new DeleteObjectCommand({ Bucket: bucket, Key: key }));
20841
+ }
20842
+ };
20813
20843
 
20814
20844
  export default createMobileUpdateRegistry({
20815
20845
  publicKeys: ${publicKeysSource(options.publicKeys)},
@@ -38954,5 +38984,5 @@ export {
38954
38984
  writeAbsoluteMobileUpdateRegistry
38955
38985
  };
38956
38986
 
38957
- //# debugId=E2398F592E2828EE64756E2164756E21
38987
+ //# debugId=A519D38D860E371564756E2164756E21
38958
38988
  //# sourceMappingURL=index.js.map