@naturalcycles/cloud-storage-lib 1.9.0 → 1.9.1
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.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.CloudStorage = exports.Storage = void 0;
|
|
|
4
4
|
const storage_1 = require("@google-cloud/storage");
|
|
5
5
|
Object.defineProperty(exports, "Storage", { enumerable: true, get: function () { return storage_1.Storage; } });
|
|
6
6
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
7
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
8
7
|
/**
|
|
9
8
|
* CloudStorage implementation of CommonStorage API.
|
|
10
9
|
*
|
|
@@ -68,29 +67,28 @@ class CloudStorage {
|
|
|
68
67
|
}
|
|
69
68
|
getFileNamesStream(bucketName, opt = {}) {
|
|
70
69
|
const { prefix, fullPaths = true } = opt;
|
|
71
|
-
return this.storage
|
|
72
|
-
.bucket(bucketName)
|
|
73
|
-
.getFilesStream({
|
|
70
|
+
return this.storage.bucket(bucketName).getFilesStream({
|
|
74
71
|
prefix,
|
|
75
72
|
maxResults: opt.limit || undefined,
|
|
76
|
-
})
|
|
77
|
-
|
|
73
|
+
}).flatMap(f => {
|
|
74
|
+
const r = this.normalizeFilename(f.name, fullPaths);
|
|
75
|
+
if (r === js_lib_1.SKIP)
|
|
76
|
+
return [];
|
|
77
|
+
return [r];
|
|
78
|
+
});
|
|
78
79
|
}
|
|
79
80
|
getFilesStream(bucketName, opt = {}) {
|
|
80
81
|
const { prefix, fullPaths = true } = opt;
|
|
81
|
-
return this.storage
|
|
82
|
-
.bucket(bucketName)
|
|
83
|
-
.getFilesStream({
|
|
82
|
+
return this.storage.bucket(bucketName).getFilesStream({
|
|
84
83
|
prefix,
|
|
85
84
|
maxResults: opt.limit || undefined,
|
|
86
|
-
})
|
|
87
|
-
.pipe((0, nodejs_lib_1.transformMap)(async (f) => {
|
|
85
|
+
}).flatMap(async (f) => {
|
|
88
86
|
const filePath = this.normalizeFilename(f.name, fullPaths);
|
|
89
87
|
if (filePath === js_lib_1.SKIP)
|
|
90
|
-
return
|
|
88
|
+
return [];
|
|
91
89
|
const [content] = await f.download();
|
|
92
|
-
return { filePath, content };
|
|
93
|
-
})
|
|
90
|
+
return [{ filePath, content }];
|
|
91
|
+
});
|
|
94
92
|
}
|
|
95
93
|
async getFile(bucketName, filePath) {
|
|
96
94
|
const [buf] = await this.storage
|
|
@@ -144,16 +142,16 @@ class CloudStorage {
|
|
|
144
142
|
async movePath(fromBucket, fromPrefix, toPrefix, toBucket) {
|
|
145
143
|
(0, js_lib_1._assert)(fromPrefix.endsWith('/'), 'fromPrefix should end with `/`');
|
|
146
144
|
(0, js_lib_1._assert)(toPrefix.endsWith('/'), 'toPrefix should end with `/`');
|
|
147
|
-
await
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
145
|
+
await this.storage
|
|
146
|
+
.bucket(fromBucket)
|
|
147
|
+
.getFilesStream({
|
|
148
|
+
prefix: fromPrefix,
|
|
149
|
+
})
|
|
150
|
+
.forEach(async (file) => {
|
|
151
|
+
const { name } = file;
|
|
152
|
+
const newName = toPrefix + name.slice(fromPrefix.length);
|
|
153
|
+
await file.move(this.storage.bucket(toBucket || fromBucket).file(newName));
|
|
154
|
+
});
|
|
157
155
|
}
|
|
158
156
|
async combine(bucketName, filePaths, toPath, toBucket) {
|
|
159
157
|
// todo: if (filePaths.length > 32) - use recursive algorithm
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CommonStorageKeyValueDB = void 0;
|
|
4
4
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
6
5
|
/**
|
|
7
6
|
* CommonKeyValueDB, backed up by a CommonStorage implementation.
|
|
8
7
|
*
|
|
@@ -66,18 +65,13 @@ class CommonStorageKeyValueDB {
|
|
|
66
65
|
}
|
|
67
66
|
streamValues(table, limit) {
|
|
68
67
|
const { bucketName, prefix } = this.getBucketAndPrefix(table);
|
|
69
|
-
return this.cfg.storage
|
|
70
|
-
.getFilesStream(bucketName, { prefix, limit })
|
|
71
|
-
.pipe((0, nodejs_lib_1.transformMapSimple)(f => f.content));
|
|
68
|
+
return this.cfg.storage.getFilesStream(bucketName, { prefix, limit }).map(f => f.content);
|
|
72
69
|
}
|
|
73
70
|
streamEntries(table, limit) {
|
|
74
71
|
const { bucketName, prefix } = this.getBucketAndPrefix(table);
|
|
75
72
|
return this.cfg.storage
|
|
76
73
|
.getFilesStream(bucketName, { prefix, limit, fullPaths: false })
|
|
77
|
-
.
|
|
78
|
-
filePath,
|
|
79
|
-
content,
|
|
80
|
-
]));
|
|
74
|
+
.map(f => [f.filePath, f.content]);
|
|
81
75
|
}
|
|
82
76
|
async count(table) {
|
|
83
77
|
const { bucketName, prefix } = this.getBucketAndPrefix(table);
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runCommonStorageTest = void 0;
|
|
4
4
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
6
5
|
const TEST_FOLDER = 'test/subdir';
|
|
7
6
|
const TEST_ITEMS = (0, js_lib_1._range)(10).map(n => ({
|
|
8
7
|
id: `id_${n + 1}`,
|
|
@@ -56,7 +55,9 @@ function runCommonStorageTest(storage, bucketName) {
|
|
|
56
55
|
expect(fileNames).toEqual([]);
|
|
57
56
|
});
|
|
58
57
|
test(`streamFileNames on ${TEST_FOLDER} should return empty`, async () => {
|
|
59
|
-
const fileNames = await
|
|
58
|
+
const fileNames = await storage
|
|
59
|
+
.getFileNamesStream(bucketName, { prefix: TEST_FOLDER })
|
|
60
|
+
.toArray();
|
|
60
61
|
expect(fileNames).toEqual([]);
|
|
61
62
|
});
|
|
62
63
|
test(`exists should return empty array`, async () => {
|
|
@@ -76,7 +77,9 @@ function runCommonStorageTest(storage, bucketName) {
|
|
|
76
77
|
expect(fileNamesShort.sort()).toEqual(TEST_FILES.map(f => (0, js_lib_1._substringAfterLast)(f.filePath, '/')).sort());
|
|
77
78
|
const fileNames = await storage.getFileNames(bucketName, { prefix: TEST_FOLDER });
|
|
78
79
|
expect(fileNames.sort()).toEqual(TEST_FILES.map(f => f.filePath).sort());
|
|
79
|
-
const streamedFileNames = await
|
|
80
|
+
const streamedFileNames = await storage
|
|
81
|
+
.getFileNamesStream(bucketName, { prefix: TEST_FOLDER })
|
|
82
|
+
.toArray();
|
|
80
83
|
expect(streamedFileNames.sort()).toEqual(TEST_FILES.map(f => f.filePath).sort());
|
|
81
84
|
const filesMap = {};
|
|
82
85
|
await (0, js_lib_1.pMap)(fileNames, async (filePath) => {
|
package/package.json
CHANGED
package/src/cloudStorage.ts
CHANGED
|
@@ -8,13 +8,7 @@ import {
|
|
|
8
8
|
pMap,
|
|
9
9
|
SKIP,
|
|
10
10
|
} from '@naturalcycles/js-lib'
|
|
11
|
-
import {
|
|
12
|
-
_pipeline,
|
|
13
|
-
ReadableTyped,
|
|
14
|
-
transformMap,
|
|
15
|
-
transformMapSync,
|
|
16
|
-
writableForEach,
|
|
17
|
-
} from '@naturalcycles/nodejs-lib'
|
|
11
|
+
import { ReadableTyped } from '@naturalcycles/nodejs-lib'
|
|
18
12
|
import { CommonStorage, CommonStorageGetOptions, FileEntry } from './commonStorage'
|
|
19
13
|
import { GCPServiceAccount } from './model'
|
|
20
14
|
|
|
@@ -114,33 +108,33 @@ export class CloudStorage implements CommonStorage {
|
|
|
114
108
|
getFileNamesStream(bucketName: string, opt: CommonStorageGetOptions = {}): ReadableTyped<string> {
|
|
115
109
|
const { prefix, fullPaths = true } = opt
|
|
116
110
|
|
|
117
|
-
return
|
|
118
|
-
.bucket(bucketName)
|
|
119
|
-
.getFilesStream({
|
|
111
|
+
return (
|
|
112
|
+
this.storage.bucket(bucketName).getFilesStream({
|
|
120
113
|
prefix,
|
|
121
114
|
maxResults: opt.limit || undefined,
|
|
122
|
-
})
|
|
123
|
-
|
|
115
|
+
}) as ReadableTyped<File>
|
|
116
|
+
).flatMap(f => {
|
|
117
|
+
const r = this.normalizeFilename(f.name, fullPaths)
|
|
118
|
+
if (r === SKIP) return []
|
|
119
|
+
return [r]
|
|
120
|
+
})
|
|
124
121
|
}
|
|
125
122
|
|
|
126
123
|
getFilesStream(bucketName: string, opt: CommonStorageGetOptions = {}): ReadableTyped<FileEntry> {
|
|
127
124
|
const { prefix, fullPaths = true } = opt
|
|
128
125
|
|
|
129
|
-
return
|
|
130
|
-
.bucket(bucketName)
|
|
131
|
-
.getFilesStream({
|
|
126
|
+
return (
|
|
127
|
+
this.storage.bucket(bucketName).getFilesStream({
|
|
132
128
|
prefix,
|
|
133
129
|
maxResults: opt.limit || undefined,
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}),
|
|
143
|
-
)
|
|
130
|
+
}) as ReadableTyped<File>
|
|
131
|
+
).flatMap(async f => {
|
|
132
|
+
const filePath = this.normalizeFilename(f.name, fullPaths)
|
|
133
|
+
if (filePath === SKIP) return []
|
|
134
|
+
|
|
135
|
+
const [content] = await f.download()
|
|
136
|
+
return [{ filePath, content }] as FileEntry[]
|
|
137
|
+
})
|
|
144
138
|
}
|
|
145
139
|
|
|
146
140
|
async getFile(bucketName: string, filePath: string): Promise<Buffer | null> {
|
|
@@ -224,16 +218,16 @@ export class CloudStorage implements CommonStorage {
|
|
|
224
218
|
_assert(fromPrefix.endsWith('/'), 'fromPrefix should end with `/`')
|
|
225
219
|
_assert(toPrefix.endsWith('/'), 'toPrefix should end with `/`')
|
|
226
220
|
|
|
227
|
-
await
|
|
228
|
-
|
|
221
|
+
await this.storage
|
|
222
|
+
.bucket(fromBucket)
|
|
223
|
+
.getFilesStream({
|
|
229
224
|
prefix: fromPrefix,
|
|
230
|
-
})
|
|
231
|
-
|
|
225
|
+
})
|
|
226
|
+
.forEach(async file => {
|
|
232
227
|
const { name } = file
|
|
233
228
|
const newName = toPrefix + name.slice(fromPrefix.length)
|
|
234
229
|
await file.move(this.storage.bucket(toBucket || fromBucket).file(newName))
|
|
235
|
-
})
|
|
236
|
-
])
|
|
230
|
+
})
|
|
237
231
|
}
|
|
238
232
|
|
|
239
233
|
async combine(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CommonDBCreateOptions, CommonKeyValueDB, KeyValueDBTuple } from '@naturalcycles/db-lib'
|
|
2
2
|
import { pMap, StringMap } from '@naturalcycles/js-lib'
|
|
3
|
-
import { ReadableTyped
|
|
4
|
-
import { CommonStorage
|
|
3
|
+
import { ReadableTyped } from '@naturalcycles/nodejs-lib'
|
|
4
|
+
import { CommonStorage } from './commonStorage'
|
|
5
5
|
|
|
6
6
|
export interface CommonStorageKeyValueDBCfg {
|
|
7
7
|
storage: CommonStorage
|
|
@@ -84,9 +84,7 @@ export class CommonStorageKeyValueDB implements CommonKeyValueDB {
|
|
|
84
84
|
streamValues(table: string, limit?: number): ReadableTyped<Buffer> {
|
|
85
85
|
const { bucketName, prefix } = this.getBucketAndPrefix(table)
|
|
86
86
|
|
|
87
|
-
return this.cfg.storage
|
|
88
|
-
.getFilesStream(bucketName, { prefix, limit })
|
|
89
|
-
.pipe(transformMapSimple<FileEntry, Buffer>(f => f.content))
|
|
87
|
+
return this.cfg.storage.getFilesStream(bucketName, { prefix, limit }).map(f => f.content)
|
|
90
88
|
}
|
|
91
89
|
|
|
92
90
|
streamEntries(table: string, limit?: number): ReadableTyped<KeyValueDBTuple> {
|
|
@@ -94,12 +92,7 @@ export class CommonStorageKeyValueDB implements CommonKeyValueDB {
|
|
|
94
92
|
|
|
95
93
|
return this.cfg.storage
|
|
96
94
|
.getFilesStream(bucketName, { prefix, limit, fullPaths: false })
|
|
97
|
-
.
|
|
98
|
-
transformMapSimple<FileEntry, KeyValueDBTuple>(({ filePath, content }) => [
|
|
99
|
-
filePath,
|
|
100
|
-
content,
|
|
101
|
-
]),
|
|
102
|
-
)
|
|
95
|
+
.map(f => [f.filePath, f.content] satisfies KeyValueDBTuple)
|
|
103
96
|
}
|
|
104
97
|
|
|
105
98
|
async count(table: string): Promise<number> {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { _range, _substringAfterLast, pMap, StringMap } from '@naturalcycles/js-lib'
|
|
2
|
-
import { readableToArray } from '@naturalcycles/nodejs-lib'
|
|
3
2
|
import { CommonStorage, FileEntry } from '../commonStorage'
|
|
4
3
|
|
|
5
4
|
const TEST_FOLDER = 'test/subdir'
|
|
@@ -69,9 +68,9 @@ export function runCommonStorageTest(storage: CommonStorage, bucketName: string)
|
|
|
69
68
|
})
|
|
70
69
|
|
|
71
70
|
test(`streamFileNames on ${TEST_FOLDER} should return empty`, async () => {
|
|
72
|
-
const fileNames = await
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
const fileNames = await storage
|
|
72
|
+
.getFileNamesStream(bucketName, { prefix: TEST_FOLDER })
|
|
73
|
+
.toArray()
|
|
75
74
|
expect(fileNames).toEqual([])
|
|
76
75
|
})
|
|
77
76
|
|
|
@@ -99,9 +98,9 @@ export function runCommonStorageTest(storage: CommonStorage, bucketName: string)
|
|
|
99
98
|
const fileNames = await storage.getFileNames(bucketName, { prefix: TEST_FOLDER })
|
|
100
99
|
expect(fileNames.sort()).toEqual(TEST_FILES.map(f => f.filePath).sort())
|
|
101
100
|
|
|
102
|
-
const streamedFileNames = await
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
const streamedFileNames = await storage
|
|
102
|
+
.getFileNamesStream(bucketName, { prefix: TEST_FOLDER })
|
|
103
|
+
.toArray()
|
|
105
104
|
expect(streamedFileNames.sort()).toEqual(TEST_FILES.map(f => f.filePath).sort())
|
|
106
105
|
|
|
107
106
|
const filesMap: StringMap<Buffer> = {}
|