@naturalcycles/cloud-storage-lib 2.4.0 → 2.6.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 +5 -5
- package/dist/cloudStorage.js +9 -15
- package/dist/commonStorage.d.ts +8 -5
- package/dist/commonStorageBucket.d.ts +5 -5
- package/dist/commonStorageKeyValueDB.d.ts +5 -8
- package/dist/commonStorageKeyValueDB.js +2 -2
- package/dist/inMemoryCommonStorage.d.ts +6 -6
- package/dist/inMemoryCommonStorage.js +6 -5
- package/package.json +2 -2
- package/src/cloudStorage.ts +16 -25
- package/src/commonStorage.ts +8 -9
- package/src/commonStorageBucket.ts +5 -5
- package/src/commonStorageKeyValueDB.ts +6 -6
- package/src/inMemoryCommonStorage.ts +11 -15
package/dist/cloudStorage.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Storage, StorageOptions } from '@google-cloud/storage';
|
|
2
2
|
import type { LocalTimeInput } from '@naturalcycles/js-lib/datetime';
|
|
3
3
|
import type { CommonLogger } from '@naturalcycles/js-lib/log';
|
|
4
|
-
import
|
|
4
|
+
import { Pipeline, type WritableTyped } from '@naturalcycles/nodejs-lib/stream';
|
|
5
5
|
import type { CommonStorage, CommonStorageGetOptions, FileEntry } from './commonStorage.js';
|
|
6
6
|
import type { GCPServiceAccount } from './model.js';
|
|
7
7
|
export type { Storage, StorageOptions, };
|
|
@@ -47,16 +47,16 @@ export declare class CloudStorage implements CommonStorage {
|
|
|
47
47
|
deletePaths(bucketName: string, prefixes: string[]): Promise<void>;
|
|
48
48
|
fileExists(bucketName: string, filePath: string): Promise<boolean>;
|
|
49
49
|
getFileNames(bucketName: string, opt?: CommonStorageGetOptions): Promise<string[]>;
|
|
50
|
-
getFileNamesStream(bucketName: string, opt?: CommonStorageGetOptions):
|
|
51
|
-
getFilesStream(bucketName: string, opt?: CommonStorageGetOptions):
|
|
50
|
+
getFileNamesStream(bucketName: string, opt?: CommonStorageGetOptions): Pipeline<string>;
|
|
51
|
+
getFilesStream(bucketName: string, opt?: CommonStorageGetOptions): Pipeline<FileEntry>;
|
|
52
52
|
getFile(bucketName: string, filePath: string): Promise<Buffer | null>;
|
|
53
53
|
/**
|
|
54
54
|
* Returns a Readable that is NOT object mode,
|
|
55
55
|
* so you can e.g pipe it to fs.createWriteStream()
|
|
56
56
|
*/
|
|
57
|
-
getFileReadStream(bucketName: string, filePath: string):
|
|
57
|
+
getFileReadStream(bucketName: string, filePath: string): Pipeline<Uint8Array>;
|
|
58
58
|
saveFile(bucketName: string, filePath: string, content: Buffer): Promise<void>;
|
|
59
|
-
getFileWriteStream(bucketName: string, filePath: string):
|
|
59
|
+
getFileWriteStream(bucketName: string, filePath: string): WritableTyped<Uint8Array>;
|
|
60
60
|
uploadFile(localFilePath: string, bucketName: string, bucketFilePath: string): Promise<void>;
|
|
61
61
|
setFileVisibility(bucketName: string, filePath: string, isPublic: boolean): Promise<void>;
|
|
62
62
|
getFileVisibility(bucketName: string, filePath: string): Promise<boolean>;
|
package/dist/cloudStorage.js
CHANGED
|
@@ -4,6 +4,7 @@ import { _assert } from '@naturalcycles/js-lib/error/assert.js';
|
|
|
4
4
|
import { pMap } from '@naturalcycles/js-lib/promise/pMap.js';
|
|
5
5
|
import { _substringAfterLast } from '@naturalcycles/js-lib/string';
|
|
6
6
|
import { SKIP } from '@naturalcycles/js-lib/types';
|
|
7
|
+
import { Pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
7
8
|
const MAX_RECURSION_DEPTH = 10;
|
|
8
9
|
const BATCH_SIZE = 32;
|
|
9
10
|
/**
|
|
@@ -80,30 +81,23 @@ export class CloudStorage {
|
|
|
80
81
|
}
|
|
81
82
|
getFileNamesStream(bucketName, opt = {}) {
|
|
82
83
|
const { prefix, fullPaths = true } = opt;
|
|
83
|
-
return this.storage.bucket(bucketName).getFilesStream({
|
|
84
|
+
return Pipeline.from(this.storage.bucket(bucketName).getFilesStream({
|
|
84
85
|
prefix,
|
|
85
86
|
maxResults: opt.limit || undefined,
|
|
86
|
-
}).
|
|
87
|
-
const r = this.normalizeFilename(f.name, fullPaths);
|
|
88
|
-
if (r === SKIP)
|
|
89
|
-
return [];
|
|
90
|
-
return [r];
|
|
91
|
-
});
|
|
87
|
+
})).mapSync(f => this.normalizeFilename(f.name, fullPaths));
|
|
92
88
|
}
|
|
93
89
|
getFilesStream(bucketName, opt = {}) {
|
|
94
90
|
const { prefix, fullPaths = true } = opt;
|
|
95
|
-
return this.storage.bucket(bucketName).getFilesStream({
|
|
91
|
+
return Pipeline.from(this.storage.bucket(bucketName).getFilesStream({
|
|
96
92
|
prefix,
|
|
97
93
|
maxResults: opt.limit || undefined,
|
|
98
|
-
}).
|
|
94
|
+
})).map(async (f) => {
|
|
99
95
|
const filePath = this.normalizeFilename(f.name, fullPaths);
|
|
100
96
|
if (filePath === SKIP)
|
|
101
|
-
return
|
|
97
|
+
return SKIP;
|
|
102
98
|
const [content] = await f.download();
|
|
103
|
-
return
|
|
104
|
-
}, {
|
|
105
|
-
concurrency: 16,
|
|
106
|
-
});
|
|
99
|
+
return { filePath, content };
|
|
100
|
+
}, { concurrency: 16 });
|
|
107
101
|
}
|
|
108
102
|
async getFile(bucketName, filePath) {
|
|
109
103
|
const [buf] = await this.storage
|
|
@@ -122,7 +116,7 @@ export class CloudStorage {
|
|
|
122
116
|
* so you can e.g pipe it to fs.createWriteStream()
|
|
123
117
|
*/
|
|
124
118
|
getFileReadStream(bucketName, filePath) {
|
|
125
|
-
return this.storage.bucket(bucketName).file(filePath).createReadStream();
|
|
119
|
+
return Pipeline.from(this.storage.bucket(bucketName).file(filePath).createReadStream());
|
|
126
120
|
}
|
|
127
121
|
async saveFile(bucketName, filePath, content) {
|
|
128
122
|
await this.storage.bucket(bucketName).file(filePath).save(content);
|
package/dist/commonStorage.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LocalTimeInput } from '@naturalcycles/js-lib/datetime';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Pipeline, WritableTyped } from '@naturalcycles/nodejs-lib/stream';
|
|
3
3
|
export interface FileEntry {
|
|
4
4
|
filePath: string;
|
|
5
5
|
content: Buffer;
|
|
@@ -69,10 +69,13 @@ export interface CommonStorage {
|
|
|
69
69
|
* return all files from sub-directories too!
|
|
70
70
|
*/
|
|
71
71
|
getFileNames: (bucketName: string, opt?: CommonStorageGetOptions) => Promise<string[]>;
|
|
72
|
-
getFileNamesStream: (bucketName: string, opt?: CommonStorageGetOptions) =>
|
|
73
|
-
getFilesStream: (bucketName: string, opt?: CommonStorageGetOptions) =>
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
getFileNamesStream: (bucketName: string, opt?: CommonStorageGetOptions) => Pipeline<string>;
|
|
73
|
+
getFilesStream: (bucketName: string, opt?: CommonStorageGetOptions) => Pipeline<FileEntry>;
|
|
74
|
+
/**
|
|
75
|
+
* Returns a Pipeline with binary output, objectMode=false.
|
|
76
|
+
*/
|
|
77
|
+
getFileReadStream: (bucketName: string, filePath: string) => Pipeline<Uint8Array>;
|
|
78
|
+
getFileWriteStream: (bucketName: string, filePath: string) => WritableTyped<Uint8Array>;
|
|
76
79
|
/**
|
|
77
80
|
* Upload local file to the bucket (by streaming it).
|
|
78
81
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { Writable } from 'node:stream';
|
|
2
|
+
import type { Pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
3
3
|
import type { CommonStorage, CommonStorageGetOptions, FileEntry } from './commonStorage.js';
|
|
4
4
|
export interface CommonStorageBucketCfg {
|
|
5
5
|
storage: CommonStorage;
|
|
@@ -56,9 +56,9 @@ export declare class CommonStorageBucket {
|
|
|
56
56
|
* return all files from sub-directories too!
|
|
57
57
|
*/
|
|
58
58
|
getFileNames(opt?: CommonStorageGetOptions): Promise<string[]>;
|
|
59
|
-
getFileNamesStream(opt?: CommonStorageGetOptions):
|
|
60
|
-
getFilesStream(opt?: CommonStorageGetOptions):
|
|
61
|
-
getFileReadStream(filePath: string):
|
|
59
|
+
getFileNamesStream(opt?: CommonStorageGetOptions): Pipeline<string>;
|
|
60
|
+
getFilesStream(opt?: CommonStorageGetOptions): Pipeline<FileEntry>;
|
|
61
|
+
getFileReadStream(filePath: string): Pipeline<Uint8Array>;
|
|
62
62
|
getFileWriteStream(filePath: string): Writable;
|
|
63
63
|
setFileVisibility(filePath: string, isPublic: boolean): Promise<void>;
|
|
64
64
|
getFileVisibility(filePath: string): Promise<boolean>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CommonDBCreateOptions } from '@naturalcycles/db-lib';
|
|
2
2
|
import type { CommonKeyValueDB, IncrementTuple, KeyValueDBTuple } from '@naturalcycles/db-lib/kv';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
4
4
|
import type { CommonStorage } from './commonStorage.js';
|
|
5
5
|
export interface CommonStorageKeyValueDBCfg {
|
|
6
6
|
storage: CommonStorage;
|
|
@@ -17,10 +17,7 @@ export interface CommonStorageKeyValueDBCfg {
|
|
|
17
17
|
export declare class CommonStorageKeyValueDB implements CommonKeyValueDB {
|
|
18
18
|
cfg: CommonStorageKeyValueDBCfg;
|
|
19
19
|
constructor(cfg: CommonStorageKeyValueDBCfg);
|
|
20
|
-
support:
|
|
21
|
-
increment: boolean;
|
|
22
|
-
count?: boolean;
|
|
23
|
-
};
|
|
20
|
+
support: any;
|
|
24
21
|
ping(): Promise<void>;
|
|
25
22
|
createTable(_table: string, _opt?: CommonDBCreateOptions): Promise<void>;
|
|
26
23
|
/**
|
|
@@ -30,9 +27,9 @@ export declare class CommonStorageKeyValueDB implements CommonKeyValueDB {
|
|
|
30
27
|
deleteByIds(table: string, ids: string[]): Promise<void>;
|
|
31
28
|
getByIds(table: string, ids: string[]): Promise<KeyValueDBTuple[]>;
|
|
32
29
|
saveBatch(table: string, entries: KeyValueDBTuple[]): Promise<void>;
|
|
33
|
-
streamIds(table: string, limit?: number):
|
|
34
|
-
streamValues(table: string, limit?: number):
|
|
35
|
-
streamEntries(table: string, limit?: number):
|
|
30
|
+
streamIds(table: string, limit?: number): Pipeline<string>;
|
|
31
|
+
streamValues(table: string, limit?: number): Pipeline<Buffer>;
|
|
32
|
+
streamEntries(table: string, limit?: number): Pipeline<KeyValueDBTuple>;
|
|
36
33
|
count(table: string): Promise<number>;
|
|
37
34
|
incrementBatch(_table: string, _entries: IncrementTuple[]): Promise<IncrementTuple[]>;
|
|
38
35
|
}
|
|
@@ -69,13 +69,13 @@ export class CommonStorageKeyValueDB {
|
|
|
69
69
|
}
|
|
70
70
|
streamValues(table, limit) {
|
|
71
71
|
const { bucketName, prefix } = this.getBucketAndPrefix(table);
|
|
72
|
-
return this.cfg.storage.getFilesStream(bucketName, { prefix, limit }).
|
|
72
|
+
return this.cfg.storage.getFilesStream(bucketName, { prefix, limit }).mapSync(f => f.content);
|
|
73
73
|
}
|
|
74
74
|
streamEntries(table, limit) {
|
|
75
75
|
const { bucketName, prefix } = this.getBucketAndPrefix(table);
|
|
76
76
|
return this.cfg.storage
|
|
77
77
|
.getFilesStream(bucketName, { prefix, limit, fullPaths: false })
|
|
78
|
-
.
|
|
78
|
+
.mapSync(f => [f.filePath, f.content]);
|
|
79
79
|
}
|
|
80
80
|
async count(table) {
|
|
81
81
|
const { bucketName, prefix } = this.getBucketAndPrefix(table);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LocalTimeInput } from '@naturalcycles/js-lib/datetime';
|
|
2
2
|
import type { StringMap } from '@naturalcycles/js-lib/types';
|
|
3
|
-
import {
|
|
3
|
+
import { Pipeline, type WritableTyped } from '@naturalcycles/nodejs-lib/stream';
|
|
4
4
|
import type { CommonStorage, CommonStorageGetOptions, FileEntry } from './commonStorage.js';
|
|
5
5
|
export declare class InMemoryCommonStorage implements CommonStorage {
|
|
6
6
|
/**
|
|
@@ -10,7 +10,7 @@ export declare class InMemoryCommonStorage implements CommonStorage {
|
|
|
10
10
|
publicMap: StringMap<StringMap<boolean>>;
|
|
11
11
|
ping(): Promise<void>;
|
|
12
12
|
getBucketNames(): Promise<string[]>;
|
|
13
|
-
getBucketNamesStream():
|
|
13
|
+
getBucketNamesStream(): Pipeline<string>;
|
|
14
14
|
fileExists(bucketName: string, filePath: string): Promise<boolean>;
|
|
15
15
|
getFile(bucketName: string, filePath: string): Promise<Buffer | null>;
|
|
16
16
|
saveFile(bucketName: string, filePath: string, content: Buffer): Promise<void>;
|
|
@@ -18,10 +18,10 @@ export declare class InMemoryCommonStorage implements CommonStorage {
|
|
|
18
18
|
deletePaths(bucketName: string, prefixes: string[]): Promise<void>;
|
|
19
19
|
deleteFiles(bucketName: string, filePaths: string[]): Promise<void>;
|
|
20
20
|
getFileNames(bucketName: string, opt?: CommonStorageGetOptions): Promise<string[]>;
|
|
21
|
-
getFileNamesStream(bucketName: string, opt?: CommonStorageGetOptions):
|
|
22
|
-
getFilesStream(bucketName: string, opt?: CommonStorageGetOptions):
|
|
23
|
-
getFileReadStream(bucketName: string, filePath: string):
|
|
24
|
-
getFileWriteStream(_bucketName: string, _filePath: string):
|
|
21
|
+
getFileNamesStream(bucketName: string, opt?: CommonStorageGetOptions): Pipeline<string>;
|
|
22
|
+
getFilesStream(bucketName: string, opt?: CommonStorageGetOptions): Pipeline<FileEntry>;
|
|
23
|
+
getFileReadStream(bucketName: string, filePath: string): Pipeline<Uint8Array>;
|
|
24
|
+
getFileWriteStream(_bucketName: string, _filePath: string): WritableTyped<Uint8Array>;
|
|
25
25
|
uploadFile(localFilePath: string, bucketName: string, bucketFilePath: string): Promise<void>;
|
|
26
26
|
setFileVisibility(bucketName: string, filePath: string, isPublic: boolean): Promise<void>;
|
|
27
27
|
getFileVisibility(bucketName: string, filePath: string): Promise<boolean>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
1
2
|
import { _isTruthy } from '@naturalcycles/js-lib';
|
|
2
3
|
import { localTime } from '@naturalcycles/js-lib/datetime/localTime.js';
|
|
3
4
|
import { _assert } from '@naturalcycles/js-lib/error/assert.js';
|
|
@@ -5,7 +6,7 @@ import { _substringAfterLast } from '@naturalcycles/js-lib/string';
|
|
|
5
6
|
import { _stringMapEntries } from '@naturalcycles/js-lib/types';
|
|
6
7
|
import { md5 } from '@naturalcycles/nodejs-lib';
|
|
7
8
|
import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
|
|
8
|
-
import {
|
|
9
|
+
import { Pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
9
10
|
export class InMemoryCommonStorage {
|
|
10
11
|
/**
|
|
11
12
|
* data[bucketName][filePath] = Buffer
|
|
@@ -17,7 +18,7 @@ export class InMemoryCommonStorage {
|
|
|
17
18
|
return Object.keys(this.data);
|
|
18
19
|
}
|
|
19
20
|
getBucketNamesStream() {
|
|
20
|
-
return
|
|
21
|
+
return Pipeline.fromArray(Object.keys(this.data));
|
|
21
22
|
}
|
|
22
23
|
async fileExists(bucketName, filePath) {
|
|
23
24
|
return !!this.data[bucketName]?.[filePath];
|
|
@@ -52,14 +53,14 @@ export class InMemoryCommonStorage {
|
|
|
52
53
|
}
|
|
53
54
|
getFileNamesStream(bucketName, opt = {}) {
|
|
54
55
|
const { prefix = '', fullPaths = true } = opt;
|
|
55
|
-
return
|
|
56
|
+
return Pipeline.fromArray(Object.keys(this.data[bucketName] || {})
|
|
56
57
|
.filter(filePath => filePath.startsWith(prefix))
|
|
57
58
|
.slice(0, opt.limit)
|
|
58
59
|
.map(n => (fullPaths ? n : _substringAfterLast(n, '/'))));
|
|
59
60
|
}
|
|
60
61
|
getFilesStream(bucketName, opt = {}) {
|
|
61
62
|
const { prefix = '', fullPaths = true } = opt;
|
|
62
|
-
return
|
|
63
|
+
return Pipeline.fromArray(_stringMapEntries(this.data[bucketName] || {})
|
|
63
64
|
.map(([filePath, content]) => ({
|
|
64
65
|
filePath,
|
|
65
66
|
content,
|
|
@@ -69,7 +70,7 @@ export class InMemoryCommonStorage {
|
|
|
69
70
|
.map(f => (fullPaths ? f : { ...f, filePath: _substringAfterLast(f.filePath, '/') })));
|
|
70
71
|
}
|
|
71
72
|
getFileReadStream(bucketName, filePath) {
|
|
72
|
-
return
|
|
73
|
+
return Pipeline.from(Readable.from(this.data[bucketName][filePath]));
|
|
73
74
|
}
|
|
74
75
|
getFileWriteStream(_bucketName, _filePath) {
|
|
75
76
|
throw new Error('Method not implemented.');
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@types/node": "^24",
|
|
13
13
|
"firebase-admin": "^13",
|
|
14
|
-
"@naturalcycles/dev-lib": "19.
|
|
14
|
+
"@naturalcycles/dev-lib": "19.37.0"
|
|
15
15
|
},
|
|
16
16
|
"exports": {
|
|
17
17
|
".": "./dist/index.js"
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"engines": {
|
|
38
38
|
"node": ">=22.12.0"
|
|
39
39
|
},
|
|
40
|
-
"version": "2.
|
|
40
|
+
"version": "2.6.0",
|
|
41
41
|
"description": "CommonStorage implementation based on Google Cloud Storage",
|
|
42
42
|
"author": "Natural Cycles Team",
|
|
43
43
|
"license": "MIT",
|
package/src/cloudStorage.ts
CHANGED
|
@@ -8,11 +8,7 @@ import { pMap } from '@naturalcycles/js-lib/promise/pMap.js'
|
|
|
8
8
|
import { _substringAfterLast } from '@naturalcycles/js-lib/string'
|
|
9
9
|
import type { UnixTimestampMillis } from '@naturalcycles/js-lib/types'
|
|
10
10
|
import { SKIP } from '@naturalcycles/js-lib/types'
|
|
11
|
-
import type
|
|
12
|
-
ReadableBinary,
|
|
13
|
-
ReadableTyped,
|
|
14
|
-
WritableBinary,
|
|
15
|
-
} from '@naturalcycles/nodejs-lib/stream'
|
|
11
|
+
import { Pipeline, type WritableTyped } from '@naturalcycles/nodejs-lib/stream'
|
|
16
12
|
import type { CommonStorage, CommonStorageGetOptions, FileEntry } from './commonStorage.js'
|
|
17
13
|
import type { GCPServiceAccount } from './model.js'
|
|
18
14
|
|
|
@@ -40,6 +36,7 @@ export interface CloudStorageCfg {
|
|
|
40
36
|
*/
|
|
41
37
|
logger?: CommonLogger
|
|
42
38
|
|
|
39
|
+
// todo: refactor to logLevel
|
|
43
40
|
/**
|
|
44
41
|
* Pass true for extra debugging
|
|
45
42
|
*/
|
|
@@ -142,40 +139,34 @@ export class CloudStorage implements CommonStorage {
|
|
|
142
139
|
return files.map(f => _substringAfterLast(f.name, '/')).filter(Boolean)
|
|
143
140
|
}
|
|
144
141
|
|
|
145
|
-
getFileNamesStream(bucketName: string, opt: CommonStorageGetOptions = {}):
|
|
142
|
+
getFileNamesStream(bucketName: string, opt: CommonStorageGetOptions = {}): Pipeline<string> {
|
|
146
143
|
const { prefix, fullPaths = true } = opt
|
|
147
144
|
|
|
148
|
-
return (
|
|
145
|
+
return Pipeline.from<File>(
|
|
149
146
|
this.storage.bucket(bucketName).getFilesStream({
|
|
150
147
|
prefix,
|
|
151
148
|
maxResults: opt.limit || undefined,
|
|
152
|
-
})
|
|
153
|
-
).
|
|
154
|
-
const r = this.normalizeFilename(f.name, fullPaths)
|
|
155
|
-
if (r === SKIP) return []
|
|
156
|
-
return [r]
|
|
157
|
-
})
|
|
149
|
+
}),
|
|
150
|
+
).mapSync(f => this.normalizeFilename(f.name, fullPaths))
|
|
158
151
|
}
|
|
159
152
|
|
|
160
|
-
getFilesStream(bucketName: string, opt: CommonStorageGetOptions = {}):
|
|
153
|
+
getFilesStream(bucketName: string, opt: CommonStorageGetOptions = {}): Pipeline<FileEntry> {
|
|
161
154
|
const { prefix, fullPaths = true } = opt
|
|
162
155
|
|
|
163
|
-
return (
|
|
156
|
+
return Pipeline.from<File>(
|
|
164
157
|
this.storage.bucket(bucketName).getFilesStream({
|
|
165
158
|
prefix,
|
|
166
159
|
maxResults: opt.limit || undefined,
|
|
167
|
-
})
|
|
168
|
-
).
|
|
160
|
+
}),
|
|
161
|
+
).map(
|
|
169
162
|
async f => {
|
|
170
163
|
const filePath = this.normalizeFilename(f.name, fullPaths)
|
|
171
|
-
if (filePath === SKIP) return
|
|
164
|
+
if (filePath === SKIP) return SKIP
|
|
172
165
|
|
|
173
166
|
const [content] = await f.download()
|
|
174
|
-
return
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
concurrency: 16,
|
|
167
|
+
return { filePath, content } satisfies FileEntry
|
|
178
168
|
},
|
|
169
|
+
{ concurrency: 16 },
|
|
179
170
|
)
|
|
180
171
|
}
|
|
181
172
|
|
|
@@ -196,15 +187,15 @@ export class CloudStorage implements CommonStorage {
|
|
|
196
187
|
* Returns a Readable that is NOT object mode,
|
|
197
188
|
* so you can e.g pipe it to fs.createWriteStream()
|
|
198
189
|
*/
|
|
199
|
-
getFileReadStream(bucketName: string, filePath: string):
|
|
200
|
-
return this.storage.bucket(bucketName).file(filePath).createReadStream()
|
|
190
|
+
getFileReadStream(bucketName: string, filePath: string): Pipeline<Uint8Array> {
|
|
191
|
+
return Pipeline.from(this.storage.bucket(bucketName).file(filePath).createReadStream())
|
|
201
192
|
}
|
|
202
193
|
|
|
203
194
|
async saveFile(bucketName: string, filePath: string, content: Buffer): Promise<void> {
|
|
204
195
|
await this.storage.bucket(bucketName).file(filePath).save(content)
|
|
205
196
|
}
|
|
206
197
|
|
|
207
|
-
getFileWriteStream(bucketName: string, filePath: string):
|
|
198
|
+
getFileWriteStream(bucketName: string, filePath: string): WritableTyped<Uint8Array> {
|
|
208
199
|
return this.storage.bucket(bucketName).file(filePath).createWriteStream()
|
|
209
200
|
}
|
|
210
201
|
|
package/src/commonStorage.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import type { LocalTimeInput } from '@naturalcycles/js-lib/datetime'
|
|
2
|
-
import type {
|
|
3
|
-
ReadableBinary,
|
|
4
|
-
ReadableTyped,
|
|
5
|
-
WritableBinary,
|
|
6
|
-
} from '@naturalcycles/nodejs-lib/stream'
|
|
2
|
+
import type { Pipeline, WritableTyped } from '@naturalcycles/nodejs-lib/stream'
|
|
7
3
|
|
|
8
4
|
export interface FileEntry {
|
|
9
5
|
filePath: string
|
|
@@ -90,13 +86,16 @@ export interface CommonStorage {
|
|
|
90
86
|
*/
|
|
91
87
|
getFileNames: (bucketName: string, opt?: CommonStorageGetOptions) => Promise<string[]>
|
|
92
88
|
|
|
93
|
-
getFileNamesStream: (bucketName: string, opt?: CommonStorageGetOptions) =>
|
|
89
|
+
getFileNamesStream: (bucketName: string, opt?: CommonStorageGetOptions) => Pipeline<string>
|
|
94
90
|
|
|
95
|
-
getFilesStream: (bucketName: string, opt?: CommonStorageGetOptions) =>
|
|
91
|
+
getFilesStream: (bucketName: string, opt?: CommonStorageGetOptions) => Pipeline<FileEntry>
|
|
96
92
|
|
|
97
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Returns a Pipeline with binary output, objectMode=false.
|
|
95
|
+
*/
|
|
96
|
+
getFileReadStream: (bucketName: string, filePath: string) => Pipeline<Uint8Array>
|
|
98
97
|
|
|
99
|
-
getFileWriteStream: (bucketName: string, filePath: string) =>
|
|
98
|
+
getFileWriteStream: (bucketName: string, filePath: string) => WritableTyped<Uint8Array>
|
|
100
99
|
|
|
101
100
|
/**
|
|
102
101
|
* Upload local file to the bucket (by streaming it).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Writable } from 'node:stream'
|
|
2
2
|
import { AppError } from '@naturalcycles/js-lib/error/error.util.js'
|
|
3
3
|
import { pMap } from '@naturalcycles/js-lib/promise/pMap.js'
|
|
4
|
-
import type {
|
|
4
|
+
import type { Pipeline } from '@naturalcycles/nodejs-lib/stream'
|
|
5
5
|
import type { CommonStorage, CommonStorageGetOptions, FileEntry } from './commonStorage.js'
|
|
6
6
|
|
|
7
7
|
export interface CommonStorageBucketCfg {
|
|
@@ -160,15 +160,15 @@ export class CommonStorageBucket {
|
|
|
160
160
|
return await this.cfg.storage.getFileNames(this.cfg.bucketName, opt)
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
getFileNamesStream(opt?: CommonStorageGetOptions):
|
|
163
|
+
getFileNamesStream(opt?: CommonStorageGetOptions): Pipeline<string> {
|
|
164
164
|
return this.cfg.storage.getFileNamesStream(this.cfg.bucketName, opt)
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
getFilesStream(opt?: CommonStorageGetOptions):
|
|
167
|
+
getFilesStream(opt?: CommonStorageGetOptions): Pipeline<FileEntry> {
|
|
168
168
|
return this.cfg.storage.getFilesStream(this.cfg.bucketName, opt)
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
getFileReadStream(filePath: string):
|
|
171
|
+
getFileReadStream(filePath: string): Pipeline<Uint8Array> {
|
|
172
172
|
return this.cfg.storage.getFileReadStream(this.cfg.bucketName, filePath)
|
|
173
173
|
}
|
|
174
174
|
|
|
@@ -4,7 +4,7 @@ import { commonKeyValueDBFullSupport } from '@naturalcycles/db-lib/kv'
|
|
|
4
4
|
import { AppError } from '@naturalcycles/js-lib/error/error.util.js'
|
|
5
5
|
import { pMap } from '@naturalcycles/js-lib/promise/pMap.js'
|
|
6
6
|
import type { StringMap } from '@naturalcycles/js-lib/types'
|
|
7
|
-
import type {
|
|
7
|
+
import type { Pipeline } from '@naturalcycles/nodejs-lib/stream'
|
|
8
8
|
import type { CommonStorage } from './commonStorage.js'
|
|
9
9
|
|
|
10
10
|
export interface CommonStorageKeyValueDBCfg {
|
|
@@ -84,24 +84,24 @@ export class CommonStorageKeyValueDB implements CommonKeyValueDB {
|
|
|
84
84
|
})
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
streamIds(table: string, limit?: number):
|
|
87
|
+
streamIds(table: string, limit?: number): Pipeline<string> {
|
|
88
88
|
const { bucketName, prefix } = this.getBucketAndPrefix(table)
|
|
89
89
|
|
|
90
90
|
return this.cfg.storage.getFileNamesStream(bucketName, { prefix, limit, fullPaths: false })
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
streamValues(table: string, limit?: number):
|
|
93
|
+
streamValues(table: string, limit?: number): Pipeline<Buffer> {
|
|
94
94
|
const { bucketName, prefix } = this.getBucketAndPrefix(table)
|
|
95
95
|
|
|
96
|
-
return this.cfg.storage.getFilesStream(bucketName, { prefix, limit }).
|
|
96
|
+
return this.cfg.storage.getFilesStream(bucketName, { prefix, limit }).mapSync(f => f.content)
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
streamEntries(table: string, limit?: number):
|
|
99
|
+
streamEntries(table: string, limit?: number): Pipeline<KeyValueDBTuple> {
|
|
100
100
|
const { bucketName, prefix } = this.getBucketAndPrefix(table)
|
|
101
101
|
|
|
102
102
|
return this.cfg.storage
|
|
103
103
|
.getFilesStream(bucketName, { prefix, limit, fullPaths: false })
|
|
104
|
-
.
|
|
104
|
+
.mapSync(f => [f.filePath, f.content])
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
async count(table: string): Promise<number> {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Readable } from 'node:stream'
|
|
1
2
|
import { _isTruthy } from '@naturalcycles/js-lib'
|
|
2
3
|
import type { LocalTimeInput } from '@naturalcycles/js-lib/datetime'
|
|
3
4
|
import { localTime } from '@naturalcycles/js-lib/datetime/localTime.js'
|
|
@@ -7,12 +8,7 @@ import type { StringMap } from '@naturalcycles/js-lib/types'
|
|
|
7
8
|
import { _stringMapEntries } from '@naturalcycles/js-lib/types'
|
|
8
9
|
import { md5 } from '@naturalcycles/nodejs-lib'
|
|
9
10
|
import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
|
|
10
|
-
import {
|
|
11
|
-
type ReadableBinary,
|
|
12
|
-
readableFrom,
|
|
13
|
-
type ReadableTyped,
|
|
14
|
-
type WritableBinary,
|
|
15
|
-
} from '@naturalcycles/nodejs-lib/stream'
|
|
11
|
+
import { Pipeline, type WritableTyped } from '@naturalcycles/nodejs-lib/stream'
|
|
16
12
|
import type { CommonStorage, CommonStorageGetOptions, FileEntry } from './commonStorage.js'
|
|
17
13
|
|
|
18
14
|
export class InMemoryCommonStorage implements CommonStorage {
|
|
@@ -29,8 +25,8 @@ export class InMemoryCommonStorage implements CommonStorage {
|
|
|
29
25
|
return Object.keys(this.data)
|
|
30
26
|
}
|
|
31
27
|
|
|
32
|
-
getBucketNamesStream():
|
|
33
|
-
return
|
|
28
|
+
getBucketNamesStream(): Pipeline<string> {
|
|
29
|
+
return Pipeline.fromArray(Object.keys(this.data))
|
|
34
30
|
}
|
|
35
31
|
|
|
36
32
|
async fileExists(bucketName: string, filePath: string): Promise<boolean> {
|
|
@@ -70,10 +66,10 @@ export class InMemoryCommonStorage implements CommonStorage {
|
|
|
70
66
|
.map(f => (fullPaths ? f : _substringAfterLast(f, '/')))
|
|
71
67
|
}
|
|
72
68
|
|
|
73
|
-
getFileNamesStream(bucketName: string, opt: CommonStorageGetOptions = {}):
|
|
69
|
+
getFileNamesStream(bucketName: string, opt: CommonStorageGetOptions = {}): Pipeline<string> {
|
|
74
70
|
const { prefix = '', fullPaths = true } = opt
|
|
75
71
|
|
|
76
|
-
return
|
|
72
|
+
return Pipeline.fromArray(
|
|
77
73
|
Object.keys(this.data[bucketName] || {})
|
|
78
74
|
.filter(filePath => filePath.startsWith(prefix))
|
|
79
75
|
.slice(0, opt.limit)
|
|
@@ -81,10 +77,10 @@ export class InMemoryCommonStorage implements CommonStorage {
|
|
|
81
77
|
)
|
|
82
78
|
}
|
|
83
79
|
|
|
84
|
-
getFilesStream(bucketName: string, opt: CommonStorageGetOptions = {}):
|
|
80
|
+
getFilesStream(bucketName: string, opt: CommonStorageGetOptions = {}): Pipeline<FileEntry> {
|
|
85
81
|
const { prefix = '', fullPaths = true } = opt
|
|
86
82
|
|
|
87
|
-
return
|
|
83
|
+
return Pipeline.fromArray(
|
|
88
84
|
_stringMapEntries(this.data[bucketName] || {})
|
|
89
85
|
.map(([filePath, content]) => ({
|
|
90
86
|
filePath,
|
|
@@ -96,11 +92,11 @@ export class InMemoryCommonStorage implements CommonStorage {
|
|
|
96
92
|
)
|
|
97
93
|
}
|
|
98
94
|
|
|
99
|
-
getFileReadStream(bucketName: string, filePath: string):
|
|
100
|
-
return
|
|
95
|
+
getFileReadStream(bucketName: string, filePath: string): Pipeline<Uint8Array> {
|
|
96
|
+
return Pipeline.from(Readable.from(this.data[bucketName]![filePath]!))
|
|
101
97
|
}
|
|
102
98
|
|
|
103
|
-
getFileWriteStream(_bucketName: string, _filePath: string):
|
|
99
|
+
getFileWriteStream(_bucketName: string, _filePath: string): WritableTyped<Uint8Array> {
|
|
104
100
|
throw new Error('Method not implemented.')
|
|
105
101
|
}
|
|
106
102
|
|