@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.
- package/dist/firebase/functions/index.cjs +37 -1
- package/dist/index.cjs +36 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +36 -0
- package/package.json +7 -7
|
@@ -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.
|
|
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.
|
|
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.
|
|
41
|
-
"@hot-updater/protocol": "1.1.
|
|
42
|
-
"@hot-updater/plugin-core": "1.1.
|
|
43
|
-
"@hot-updater/server": "1.1.
|
|
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.
|
|
59
|
-
"@hot-updater/test-utils": "1.1.
|
|
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",
|