@naturalcycles/cloud-storage-lib 1.3.0 → 1.4.0
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/cloudStorage.d.ts +6 -4
- package/dist/cloudStorage.js +10 -16
- package/dist/commonStorage.d.ts +0 -5
- package/dist/testing/commonStorageTest.js +17 -16
- package/package.json +2 -1
- package/src/cloudStorage.ts +11 -22
- package/src/commonStorage.ts +0 -7
- package/src/testing/commonStorageTest.ts +19 -17
package/dist/cloudStorage.d.ts
CHANGED
|
@@ -17,12 +17,14 @@ export interface CloudStorageCfg {
|
|
|
17
17
|
credentials: GCPServiceAccount;
|
|
18
18
|
}
|
|
19
19
|
export declare class CloudStorage implements CommonStorage {
|
|
20
|
-
cfg: CloudStorageCfg;
|
|
21
|
-
constructor(cfg: CloudStorageCfg);
|
|
22
20
|
storage: Storage;
|
|
21
|
+
/**
|
|
22
|
+
* Passing the pre-created Storage allows to instantiate it from both
|
|
23
|
+
* GCP Storage and FirebaseStorage.
|
|
24
|
+
*/
|
|
25
|
+
constructor(storage: Storage);
|
|
26
|
+
static createFromGCPServiceAccount(cfg: CloudStorageCfg): CloudStorage;
|
|
23
27
|
ping(bucketName?: string): Promise<void>;
|
|
24
|
-
getBucketNames(opt?: CommonStorageGetOptions): Promise<string[]>;
|
|
25
|
-
getBucketNamesStream(): ReadableTyped<string>;
|
|
26
28
|
deletePath(bucketName: string, prefix: string): Promise<void>;
|
|
27
29
|
fileExists(bucketName: string, filePath: string): Promise<boolean>;
|
|
28
30
|
getFileNames(bucketName: string, opt?: CommonStorageGetOptions): Promise<string[]>;
|
package/dist/cloudStorage.js
CHANGED
|
@@ -5,9 +5,15 @@ const js_lib_1 = require("@naturalcycles/js-lib");
|
|
|
5
5
|
const storage_1 = require("@google-cloud/storage");
|
|
6
6
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
7
7
|
class CloudStorage {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Passing the pre-created Storage allows to instantiate it from both
|
|
10
|
+
* GCP Storage and FirebaseStorage.
|
|
11
|
+
*/
|
|
12
|
+
constructor(storage) {
|
|
13
|
+
this.storage = storage;
|
|
14
|
+
}
|
|
15
|
+
static createFromGCPServiceAccount(cfg) {
|
|
16
|
+
const storage = new storage_1.Storage({
|
|
11
17
|
credentials: cfg.credentials,
|
|
12
18
|
// Explicitly passing it here to fix this error:
|
|
13
19
|
// Error: Unable to detect a Project Id in the current environment.
|
|
@@ -16,23 +22,11 @@ class CloudStorage {
|
|
|
16
22
|
// at /root/repo/node_modules/google-auth-library/build/src/auth/googleauth.js:95:31
|
|
17
23
|
projectId: cfg.credentials.project_id,
|
|
18
24
|
});
|
|
25
|
+
return new CloudStorage(storage);
|
|
19
26
|
}
|
|
20
|
-
// async createBucket(bucketName: string): Promise<void> {
|
|
21
|
-
// const bucket = await this.storage.createBucket(bucketName)
|
|
22
|
-
// console.log(bucket) // debugging
|
|
23
|
-
// }
|
|
24
27
|
async ping(bucketName) {
|
|
25
28
|
await this.storage.bucket(bucketName || 'non-existing-for-sure').exists();
|
|
26
29
|
}
|
|
27
|
-
async getBucketNames(opt = {}) {
|
|
28
|
-
const [buckets] = await this.storage.getBuckets({
|
|
29
|
-
maxResults: opt.limit,
|
|
30
|
-
});
|
|
31
|
-
return buckets.map(b => b.name);
|
|
32
|
-
}
|
|
33
|
-
getBucketNamesStream() {
|
|
34
|
-
return this.storage.getBucketsStream().pipe((0, nodejs_lib_1.transformMapSimple)(b => b.name));
|
|
35
|
-
}
|
|
36
30
|
async deletePath(bucketName, prefix) {
|
|
37
31
|
await this.storage.bucket(bucketName).deleteFiles({
|
|
38
32
|
prefix,
|
package/dist/commonStorage.d.ts
CHANGED
|
@@ -40,11 +40,6 @@ export interface CommonStorage {
|
|
|
40
40
|
* Pass `bucketName` in case you only have permissions to operate on that bucket.
|
|
41
41
|
*/
|
|
42
42
|
ping(bucketName?: string): Promise<void>;
|
|
43
|
-
/**
|
|
44
|
-
* Often needs a special permission.
|
|
45
|
-
*/
|
|
46
|
-
getBucketNames(opt?: CommonStorageGetOptions): Promise<string[]>;
|
|
47
|
-
getBucketNamesStream(): ReadableTyped<string>;
|
|
48
43
|
/**
|
|
49
44
|
* Creates a new bucket by given name.
|
|
50
45
|
* todo: check what to do if it already exists
|
|
@@ -33,29 +33,30 @@ function runCommonStorageTest(storage, bucketName) {
|
|
|
33
33
|
// await storage.createBucket(bucketName)
|
|
34
34
|
// })
|
|
35
35
|
test('ping', async () => {
|
|
36
|
-
await storage.ping();
|
|
37
|
-
});
|
|
38
|
-
test('listBuckets', async () => {
|
|
39
|
-
const buckets = await storage.getBucketNames();
|
|
40
|
-
console.log(buckets);
|
|
41
|
-
});
|
|
42
|
-
test('streamBuckets', async () => {
|
|
43
|
-
const buckets = await (0, nodejs_lib_1.readableToArray)(storage.getBucketNamesStream());
|
|
44
|
-
console.log(buckets);
|
|
36
|
+
await storage.ping(bucketName);
|
|
45
37
|
});
|
|
38
|
+
// test('listBuckets', async () => {
|
|
39
|
+
// const buckets = await storage.getBucketNames()
|
|
40
|
+
// console.log(buckets)
|
|
41
|
+
// })
|
|
42
|
+
//
|
|
43
|
+
// test('streamBuckets', async () => {
|
|
44
|
+
// const buckets = await readableToArray(storage.getBucketNamesStream())
|
|
45
|
+
// console.log(buckets)
|
|
46
|
+
// })
|
|
46
47
|
test('prepare: clear bucket', async () => {
|
|
47
48
|
await (0, js_lib_1.pMap)(TEST_FILES.map(f => f.filePath), async (filePath) => await storage.deletePath(bucketName, filePath));
|
|
48
49
|
});
|
|
49
|
-
test('listFileNames on root should return empty', async () => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
})
|
|
50
|
+
// test('listFileNames on root should return empty', async () => {
|
|
51
|
+
// const fileNames = await storage.getFileNames(bucketName)
|
|
52
|
+
// expect(fileNames).toEqual([])
|
|
53
|
+
// })
|
|
53
54
|
test(`listFileNames on ${TEST_FOLDER} should return empty`, async () => {
|
|
54
55
|
const fileNames = await storage.getFileNames(bucketName, { prefix: TEST_FOLDER });
|
|
55
56
|
expect(fileNames).toEqual([]);
|
|
56
57
|
});
|
|
57
|
-
test(
|
|
58
|
-
const fileNames = await (0, nodejs_lib_1.readableToArray)(storage.getFileNamesStream(bucketName));
|
|
58
|
+
test(`streamFileNames on ${TEST_FOLDER} should return empty`, async () => {
|
|
59
|
+
const fileNames = await (0, nodejs_lib_1.readableToArray)(storage.getFileNamesStream(bucketName, { prefix: TEST_FOLDER }));
|
|
59
60
|
expect(fileNames).toEqual([]);
|
|
60
61
|
});
|
|
61
62
|
test(`exists should return empty array`, async () => {
|
|
@@ -88,7 +89,7 @@ function runCommonStorageTest(storage, bucketName) {
|
|
|
88
89
|
});
|
|
89
90
|
});
|
|
90
91
|
test('cleanup', async () => {
|
|
91
|
-
await storage.deletePath(bucketName,
|
|
92
|
+
await storage.deletePath(bucketName, TEST_FOLDER);
|
|
92
93
|
});
|
|
93
94
|
// Cannot update access control for an object when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access
|
|
94
95
|
/*
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@naturalcycles/dev-lib": "^12.1.3",
|
|
14
14
|
"@types/node": "^17.0.5",
|
|
15
|
+
"firebase-admin": "^10.0.1",
|
|
15
16
|
"jest": "^27.1.0"
|
|
16
17
|
},
|
|
17
18
|
"files": [
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
"engines": {
|
|
35
36
|
"node": ">=14.16.0"
|
|
36
37
|
},
|
|
37
|
-
"version": "1.
|
|
38
|
+
"version": "1.4.0",
|
|
38
39
|
"description": "",
|
|
39
40
|
"author": "Natural Cycles Team",
|
|
40
41
|
"license": "MIT"
|
package/src/cloudStorage.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Buffer from 'buffer'
|
|
2
2
|
import { Readable, Writable } from 'stream'
|
|
3
3
|
import { _substringAfterLast } from '@naturalcycles/js-lib'
|
|
4
|
-
import {
|
|
4
|
+
import { File, Storage } from '@google-cloud/storage'
|
|
5
5
|
import { ReadableTyped, transformMap, transformMapSimple } from '@naturalcycles/nodejs-lib'
|
|
6
6
|
import { CommonStorage, CommonStorageGetOptions, FileEntry } from './commonStorage'
|
|
7
7
|
import { GCPServiceAccount } from './model'
|
|
@@ -20,8 +20,14 @@ export interface CloudStorageCfg {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export class CloudStorage implements CommonStorage {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Passing the pre-created Storage allows to instantiate it from both
|
|
25
|
+
* GCP Storage and FirebaseStorage.
|
|
26
|
+
*/
|
|
27
|
+
constructor(public storage: Storage) {}
|
|
28
|
+
|
|
29
|
+
static createFromGCPServiceAccount(cfg: CloudStorageCfg): CloudStorage {
|
|
30
|
+
const storage = new Storage({
|
|
25
31
|
credentials: cfg.credentials,
|
|
26
32
|
// Explicitly passing it here to fix this error:
|
|
27
33
|
// Error: Unable to detect a Project Id in the current environment.
|
|
@@ -30,31 +36,14 @@ export class CloudStorage implements CommonStorage {
|
|
|
30
36
|
// at /root/repo/node_modules/google-auth-library/build/src/auth/googleauth.js:95:31
|
|
31
37
|
projectId: cfg.credentials.project_id,
|
|
32
38
|
})
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
storage: Storage
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// console.log(bucket) // debugging
|
|
40
|
-
// }
|
|
40
|
+
return new CloudStorage(storage)
|
|
41
|
+
}
|
|
41
42
|
|
|
42
43
|
async ping(bucketName?: string): Promise<void> {
|
|
43
44
|
await this.storage.bucket(bucketName || 'non-existing-for-sure').exists()
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
async getBucketNames(opt: CommonStorageGetOptions = {}): Promise<string[]> {
|
|
47
|
-
const [buckets] = await this.storage.getBuckets({
|
|
48
|
-
maxResults: opt.limit,
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
return buckets.map(b => b.name)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
getBucketNamesStream(): ReadableTyped<string> {
|
|
55
|
-
return this.storage.getBucketsStream().pipe(transformMapSimple<Bucket, string>(b => b.name))
|
|
56
|
-
}
|
|
57
|
-
|
|
58
47
|
async deletePath(bucketName: string, prefix: string): Promise<void> {
|
|
59
48
|
await this.storage.bucket(bucketName).deleteFiles({
|
|
60
49
|
prefix,
|
package/src/commonStorage.ts
CHANGED
|
@@ -47,13 +47,6 @@ export interface CommonStorage {
|
|
|
47
47
|
*/
|
|
48
48
|
ping(bucketName?: string): Promise<void>
|
|
49
49
|
|
|
50
|
-
/**
|
|
51
|
-
* Often needs a special permission.
|
|
52
|
-
*/
|
|
53
|
-
getBucketNames(opt?: CommonStorageGetOptions): Promise<string[]>
|
|
54
|
-
|
|
55
|
-
getBucketNamesStream(): ReadableTyped<string>
|
|
56
|
-
|
|
57
50
|
/**
|
|
58
51
|
* Creates a new bucket by given name.
|
|
59
52
|
* todo: check what to do if it already exists
|
|
@@ -38,18 +38,18 @@ export function runCommonStorageTest(storage: CommonStorage, bucketName: string)
|
|
|
38
38
|
// })
|
|
39
39
|
|
|
40
40
|
test('ping', async () => {
|
|
41
|
-
await storage.ping()
|
|
41
|
+
await storage.ping(bucketName)
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
-
test('listBuckets', async () => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('streamBuckets', async () => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
})
|
|
44
|
+
// test('listBuckets', async () => {
|
|
45
|
+
// const buckets = await storage.getBucketNames()
|
|
46
|
+
// console.log(buckets)
|
|
47
|
+
// })
|
|
48
|
+
//
|
|
49
|
+
// test('streamBuckets', async () => {
|
|
50
|
+
// const buckets = await readableToArray(storage.getBucketNamesStream())
|
|
51
|
+
// console.log(buckets)
|
|
52
|
+
// })
|
|
53
53
|
|
|
54
54
|
test('prepare: clear bucket', async () => {
|
|
55
55
|
await pMap(
|
|
@@ -58,18 +58,20 @@ export function runCommonStorageTest(storage: CommonStorage, bucketName: string)
|
|
|
58
58
|
)
|
|
59
59
|
})
|
|
60
60
|
|
|
61
|
-
test('listFileNames on root should return empty', async () => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
})
|
|
61
|
+
// test('listFileNames on root should return empty', async () => {
|
|
62
|
+
// const fileNames = await storage.getFileNames(bucketName)
|
|
63
|
+
// expect(fileNames).toEqual([])
|
|
64
|
+
// })
|
|
65
65
|
|
|
66
66
|
test(`listFileNames on ${TEST_FOLDER} should return empty`, async () => {
|
|
67
67
|
const fileNames = await storage.getFileNames(bucketName, { prefix: TEST_FOLDER })
|
|
68
68
|
expect(fileNames).toEqual([])
|
|
69
69
|
})
|
|
70
70
|
|
|
71
|
-
test(
|
|
72
|
-
const fileNames = await readableToArray(
|
|
71
|
+
test(`streamFileNames on ${TEST_FOLDER} should return empty`, async () => {
|
|
72
|
+
const fileNames = await readableToArray(
|
|
73
|
+
storage.getFileNamesStream(bucketName, { prefix: TEST_FOLDER }),
|
|
74
|
+
)
|
|
73
75
|
expect(fileNames).toEqual([])
|
|
74
76
|
})
|
|
75
77
|
|
|
@@ -117,7 +119,7 @@ export function runCommonStorageTest(storage: CommonStorage, bucketName: string)
|
|
|
117
119
|
})
|
|
118
120
|
|
|
119
121
|
test('cleanup', async () => {
|
|
120
|
-
await storage.deletePath(bucketName,
|
|
122
|
+
await storage.deletePath(bucketName, TEST_FOLDER)
|
|
121
123
|
})
|
|
122
124
|
|
|
123
125
|
// Cannot update access control for an object when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access
|