@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.
@@ -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[]>;
@@ -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
- constructor(cfg) {
9
- this.cfg = cfg;
10
- this.storage = new storage_1.Storage({
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,
@@ -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
- const fileNames = await storage.getFileNames(bucketName);
51
- expect(fileNames).toEqual([]);
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('streamFileNames on root should return empty', async () => {
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.3.0",
38
+ "version": "1.4.0",
38
39
  "description": "",
39
40
  "author": "Natural Cycles Team",
40
41
  "license": "MIT"
@@ -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 { Bucket, File, Storage } from '@google-cloud/storage'
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
- constructor(public cfg: CloudStorageCfg) {
24
- this.storage = new Storage({
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
- // async createBucket(bucketName: string): Promise<void> {
38
- // const bucket = await this.storage.createBucket(bucketName)
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,
@@ -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
- 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
- })
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
- const fileNames = await storage.getFileNames(bucketName)
63
- expect(fileNames).toEqual([])
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('streamFileNames on root should return empty', async () => {
72
- const fileNames = await readableToArray(storage.getFileNamesStream(bucketName))
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