@hot-updater/firebase 1.1.3 → 1.1.5

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.
@@ -4525,7 +4525,7 @@ const createKvAdapter = ({ store, tablePrefix = "" }) => {
4525
4525
  };
4526
4526
  //#endregion
4527
4527
  //#region ../../packages/server/dist/version.mjs
4528
- const HOT_UPDATER_SERVER_VERSION = "1.1.3";
4528
+ const HOT_UPDATER_SERVER_VERSION = "1.1.5";
4529
4529
  //#endregion
4530
4530
  //#region ../../packages/server/dist/handlerVersionRoutes.mjs
4531
4531
  /**
@@ -11628,10 +11628,13 @@ const firebaseDatabase = (config) => createEngineDatabase({
11628
11628
  //#region src/firebaseStorage.ts
11629
11629
  /** Signed URLs kept per adapter, enough for a few Bundles' assets. */
11630
11630
  const MAX_CACHED_SIGNED_URLS = 1e4;
11631
+ /** Objects deleted at once: Cloud Storage deletes one object a request. */
11632
+ const DELETE_CONCURRENCY = 16;
11631
11633
  const firebaseStorage = (config) => {
11632
11634
  const app = (0, firebase_admin_app.getApps)().length ? (0, firebase_admin_app.getApp)() : (0, firebase_admin_app.initializeApp)(config);
11633
11635
  const bucket = (0, firebase_admin_storage.getStorage)(app).bucket(config.storageBucket);
11634
11636
  const getStorageKey = createStorageKeyBuilder(config.basePath);
11637
+ const basePrefix = getStorageKey() ? `${getStorageKey()}/` : "";
11635
11638
  /**
11636
11639
  * Signed URLs by object. Without a private key, as in Cloud Functions, each
11637
11640
  * signature is an IAM signBlob request, and an update check returns a URL
@@ -11720,6 +11723,39 @@ const firebaseStorage = (config) => {
11720
11723
  const { key } = parseAndValidate(storageUri);
11721
11724
  await bucket.file(key).delete({ ignoreNotFound: true });
11722
11725
  return { deleted: true };
11726
+ },
11727
+ async listObjects(prefix) {
11728
+ const folder = getStorageKey(prefix ?? "");
11729
+ const [files] = await bucket.getFiles({
11730
+ autoPaginate: true,
11731
+ prefix: folder ? `${folder}/` : ""
11732
+ });
11733
+ const objects = [];
11734
+ for (const file of files) {
11735
+ if (!file.name.startsWith(basePrefix)) continue;
11736
+ let storageUri;
11737
+ try {
11738
+ storageUri = createStorageUri({
11739
+ bucket: config.storageBucket,
11740
+ key: file.name,
11741
+ protocol: "gs"
11742
+ });
11743
+ } catch {
11744
+ continue;
11745
+ }
11746
+ const { size, updated } = file.metadata;
11747
+ objects.push({
11748
+ key: file.name.slice(basePrefix.length),
11749
+ ...updated ? { lastModifiedAt: new Date(updated) } : {},
11750
+ size: Number(size ?? 0),
11751
+ storageUri
11752
+ });
11753
+ }
11754
+ return objects;
11755
+ },
11756
+ async deleteObjects(relativeKeys) {
11757
+ const keys = relativeKeys.map((key) => getStorageKey(key));
11758
+ for (let offset = 0; offset < keys.length; offset += DELETE_CONCURRENCY) await Promise.all(keys.slice(offset, offset + DELETE_CONCURRENCY).map((key) => bucket.file(key).delete({ ignoreNotFound: true })));
11723
11759
  }
11724
11760
  });
11725
11761
  };
package/dist/index.cjs CHANGED
@@ -193,10 +193,13 @@ const firebaseDatabase = (config) => (0, _hot_updater_plugin_core.createEngineDa
193
193
  //#region src/firebaseStorage.ts
194
194
  /** Signed URLs kept per adapter, enough for a few Bundles' assets. */
195
195
  const MAX_CACHED_SIGNED_URLS = 1e4;
196
+ /** Objects deleted at once: Cloud Storage deletes one object a request. */
197
+ const DELETE_CONCURRENCY = 16;
196
198
  const firebaseStorage = (config) => {
197
199
  const app = (0, firebase_admin_app.getApps)().length ? (0, firebase_admin_app.getApp)() : (0, firebase_admin_app.initializeApp)(config);
198
200
  const bucket = (0, firebase_admin_storage.getStorage)(app).bucket(config.storageBucket);
199
201
  const getStorageKey = (0, _hot_updater_plugin_core.createStorageKeyBuilder)(config.basePath);
202
+ const basePrefix = getStorageKey() ? `${getStorageKey()}/` : "";
200
203
  /**
201
204
  * Signed URLs by object. Without a private key, as in Cloud Functions, each
202
205
  * signature is an IAM signBlob request, and an update check returns a URL
@@ -285,6 +288,39 @@ const firebaseStorage = (config) => {
285
288
  const { key } = parseAndValidate(storageUri);
286
289
  await bucket.file(key).delete({ ignoreNotFound: true });
287
290
  return { deleted: true };
291
+ },
292
+ async listObjects(prefix) {
293
+ const folder = getStorageKey(prefix ?? "");
294
+ const [files] = await bucket.getFiles({
295
+ autoPaginate: true,
296
+ prefix: folder ? `${folder}/` : ""
297
+ });
298
+ const objects = [];
299
+ for (const file of files) {
300
+ if (!file.name.startsWith(basePrefix)) continue;
301
+ let storageUri;
302
+ try {
303
+ storageUri = (0, _hot_updater_plugin_core.createStorageUri)({
304
+ bucket: config.storageBucket,
305
+ key: file.name,
306
+ protocol: "gs"
307
+ });
308
+ } catch {
309
+ continue;
310
+ }
311
+ const { size, updated } = file.metadata;
312
+ objects.push({
313
+ key: file.name.slice(basePrefix.length),
314
+ ...updated ? { lastModifiedAt: new Date(updated) } : {},
315
+ size: Number(size ?? 0),
316
+ storageUri
317
+ });
318
+ }
319
+ return objects;
320
+ },
321
+ async deleteObjects(relativeKeys) {
322
+ const keys = relativeKeys.map((key) => getStorageKey(key));
323
+ for (let offset = 0; offset < keys.length; offset += DELETE_CONCURRENCY) await Promise.all(keys.slice(offset, offset + DELETE_CONCURRENCY).map((key) => bucket.file(key).delete({ ignoreNotFound: true })));
288
324
  }
289
325
  });
290
326
  };
package/dist/index.d.cts CHANGED
@@ -37,6 +37,6 @@ interface FirebaseStorageConfig extends AppOptions {
37
37
  /** Firebase signed URL lifetime in seconds. @default 3600 */
38
38
  signedUrlExpiresIn?: number;
39
39
  }
40
- declare const firebaseStorage: (config: FirebaseStorageConfig) => StorageAdapterWith<"put" | "get" | "getDownloadUrl" | "exists" | "delete">;
40
+ declare const firebaseStorage: (config: FirebaseStorageConfig) => StorageAdapterWith<"put" | "get" | "getDownloadUrl" | "exists" | "delete" | "listObjects" | "deleteObjects">;
41
41
  //#endregion
42
42
  export { FirebaseDatabaseConfig, FirebaseStorageConfig, firebaseDatabase, firebaseStorage, migrateFirebaseDatabase };
package/dist/index.d.mts CHANGED
@@ -37,6 +37,6 @@ interface FirebaseStorageConfig extends AppOptions {
37
37
  /** Firebase signed URL lifetime in seconds. @default 3600 */
38
38
  signedUrlExpiresIn?: number;
39
39
  }
40
- declare const firebaseStorage: (config: FirebaseStorageConfig) => StorageAdapterWith<"put" | "get" | "getDownloadUrl" | "exists" | "delete">;
40
+ declare const firebaseStorage: (config: FirebaseStorageConfig) => StorageAdapterWith<"put" | "get" | "getDownloadUrl" | "exists" | "delete" | "listObjects" | "deleteObjects">;
41
41
  //#endregion
42
42
  export { FirebaseDatabaseConfig, FirebaseStorageConfig, firebaseDatabase, firebaseStorage, migrateFirebaseDatabase };
package/dist/index.mjs CHANGED
@@ -192,10 +192,13 @@ const firebaseDatabase = (config) => createEngineDatabase({
192
192
  //#region src/firebaseStorage.ts
193
193
  /** Signed URLs kept per adapter, enough for a few Bundles' assets. */
194
194
  const MAX_CACHED_SIGNED_URLS = 1e4;
195
+ /** Objects deleted at once: Cloud Storage deletes one object a request. */
196
+ const DELETE_CONCURRENCY = 16;
195
197
  const firebaseStorage = (config) => {
196
198
  const app = getApps().length ? getApp() : initializeApp(config);
197
199
  const bucket = getStorage(app).bucket(config.storageBucket);
198
200
  const getStorageKey = createStorageKeyBuilder(config.basePath);
201
+ const basePrefix = getStorageKey() ? `${getStorageKey()}/` : "";
199
202
  /**
200
203
  * Signed URLs by object. Without a private key, as in Cloud Functions, each
201
204
  * signature is an IAM signBlob request, and an update check returns a URL
@@ -284,6 +287,39 @@ const firebaseStorage = (config) => {
284
287
  const { key } = parseAndValidate(storageUri);
285
288
  await bucket.file(key).delete({ ignoreNotFound: true });
286
289
  return { deleted: true };
290
+ },
291
+ async listObjects(prefix) {
292
+ const folder = getStorageKey(prefix ?? "");
293
+ const [files] = await bucket.getFiles({
294
+ autoPaginate: true,
295
+ prefix: folder ? `${folder}/` : ""
296
+ });
297
+ const objects = [];
298
+ for (const file of files) {
299
+ if (!file.name.startsWith(basePrefix)) continue;
300
+ let storageUri;
301
+ try {
302
+ storageUri = createStorageUri({
303
+ bucket: config.storageBucket,
304
+ key: file.name,
305
+ protocol: "gs"
306
+ });
307
+ } catch {
308
+ continue;
309
+ }
310
+ const { size, updated } = file.metadata;
311
+ objects.push({
312
+ key: file.name.slice(basePrefix.length),
313
+ ...updated ? { lastModifiedAt: new Date(updated) } : {},
314
+ size: Number(size ?? 0),
315
+ storageUri
316
+ });
317
+ }
318
+ return objects;
319
+ },
320
+ async deleteObjects(relativeKeys) {
321
+ const keys = relativeKeys.map((key) => getStorageKey(key));
322
+ for (let offset = 0; offset < keys.length; offset += DELETE_CONCURRENCY) await Promise.all(keys.slice(offset, offset + DELETE_CONCURRENCY).map((key) => bucket.file(key).delete({ ignoreNotFound: true })));
287
323
  }
288
324
  });
289
325
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hot-updater/firebase",
3
3
  "type": "module",
4
- "version": "1.1.3",
4
+ "version": "1.1.5",
5
5
  "description": "React Native OTA solution for self-hosted",
6
6
  "main": "dist/index.cjs",
7
7
  "types": "dist/index.d.cts",
@@ -37,10 +37,10 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "hono": "4.12.34",
40
- "@hot-updater/cli-tools": "1.1.3",
41
- "@hot-updater/protocol": "1.1.3",
42
- "@hot-updater/plugin-core": "1.1.3",
43
- "@hot-updater/server": "1.1.3"
40
+ "@hot-updater/cli-tools": "1.1.5",
41
+ "@hot-updater/protocol": "1.1.5",
42
+ "@hot-updater/plugin-core": "1.1.5",
43
+ "@hot-updater/server": "1.1.5"
44
44
  },
45
45
  "publishConfig": {
46
46
  "access": "public"
@@ -55,8 +55,8 @@
55
55
  "firebase-tools": "15.29.0",
56
56
  "fkill": "^9.0.0",
57
57
  "mime": "^4.0.4",
58
- "@hot-updater/mock": "1.1.3",
59
- "@hot-updater/test-utils": "1.1.3"
58
+ "@hot-updater/mock": "1.1.5",
59
+ "@hot-updater/test-utils": "1.1.5"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "firebase-admin": ">=11.10.0",