@e-mc/cloud 0.9.7 → 0.10.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/README.md +11 -11
- package/index.d.ts +5 -5
- package/index.js +142 -135
- package/package.json +4 -4
- package/util.d.ts +1 -0
- package/util.js +13 -20
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
## Interface
|
|
11
11
|
|
|
12
|
-
* [View Source](https://www.unpkg.com/@e-mc/types@0.
|
|
12
|
+
* [View Source](https://www.unpkg.com/@e-mc/types@0.10.0/lib/index.d.ts)
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
import type { IHost, IScopeOrigin } from "./index";
|
|
@@ -57,10 +57,10 @@ interface CloudConstructor extends ClientDbConstructor<IHost> {
|
|
|
57
57
|
LOG_CLOUD_DOWNLOAD: LogMessageOptions;
|
|
58
58
|
LOG_CLOUD_DELETE: LogMessageOptions;
|
|
59
59
|
LOG_CLOUD_DELAYED: LogMessageOptions;
|
|
60
|
-
finalize(this: IHost, instance: ICloud): Promise<
|
|
61
|
-
uploadAsset(state: IScopeOrigin<IFileManager, ICloud>, file: ExternalAsset, options: UploadAssetOptions): Promise<
|
|
62
|
-
uploadAsset(state: IScopeOrigin<IFileManager, ICloud>, file: ExternalAsset, ignoreProcess: boolean): Promise<
|
|
63
|
-
uploadAsset(state: IScopeOrigin<IFileManager, ICloud>, file: ExternalAsset, contentType?: string, ignoreProcess?: boolean): Promise<
|
|
60
|
+
finalize(this: IHost, instance: ICloud): Promise<void>;
|
|
61
|
+
uploadAsset(state: IScopeOrigin<IFileManager, ICloud>, file: ExternalAsset, options: UploadAssetOptions): Promise<void>[];
|
|
62
|
+
uploadAsset(state: IScopeOrigin<IFileManager, ICloud>, file: ExternalAsset, ignoreProcess: boolean): Promise<void>[];
|
|
63
|
+
uploadAsset(state: IScopeOrigin<IFileManager, ICloud>, file: ExternalAsset, contentType?: string, ignoreProcess?: boolean): Promise<void>[];
|
|
64
64
|
sanitizeAssets(assets: ExternalAsset[]): ExternalAsset[];
|
|
65
65
|
readonly prototype: ICloud;
|
|
66
66
|
new(module?: CloudModule, database?: CloudDatabase[], ...args: unknown[]): ICloud;
|
|
@@ -174,12 +174,12 @@ const rows = await instance.getDatabaseRows({ service: "aws-v3", credential: "ma
|
|
|
174
174
|
|
|
175
175
|
## References
|
|
176
176
|
|
|
177
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
178
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
179
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
180
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
181
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
182
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
177
|
+
- https://www.unpkg.com/@e-mc/types@0.10.0/lib/asset.d.ts
|
|
178
|
+
- https://www.unpkg.com/@e-mc/types@0.10.0/lib/cloud.d.ts
|
|
179
|
+
- https://www.unpkg.com/@e-mc/types@0.10.0/lib/core.d.ts
|
|
180
|
+
- https://www.unpkg.com/@e-mc/types@0.10.0/lib/db.d.ts
|
|
181
|
+
- https://www.unpkg.com/@e-mc/types@0.10.0/lib/logger.d.ts
|
|
182
|
+
- https://www.unpkg.com/@e-mc/types@0.10.0/lib/settings.d.ts
|
|
183
183
|
|
|
184
184
|
## LICENSE
|
|
185
185
|
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { CloudConstructor, IFileManager } from '../types/lib';
|
|
2
|
-
import type { CloudAsset } from '../types/lib/cloud';
|
|
3
|
-
|
|
4
|
-
declare const Cloud: CloudConstructor<IFileManager<CloudAsset>>;
|
|
5
|
-
|
|
1
|
+
import type { CloudConstructor, IFileManager } from '../types/lib';
|
|
2
|
+
import type { CloudAsset } from '../types/lib/cloud';
|
|
3
|
+
|
|
4
|
+
declare const Cloud: CloudConstructor<IFileManager<CloudAsset>>;
|
|
5
|
+
|
|
6
6
|
export = Cloud;
|
package/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const fs = require("fs");
|
|
4
|
-
const
|
|
4
|
+
const crypto = require("crypto");
|
|
5
5
|
const core_1 = require("@e-mc/core");
|
|
6
|
-
const
|
|
6
|
+
const types_1 = require("@e-mc/types");
|
|
7
7
|
const SERVICE_CLIENT = new Map();
|
|
8
8
|
const SERVICE_UPLOAD = {};
|
|
9
9
|
const SERVICE_DOWNLOAD = {};
|
|
@@ -32,14 +32,34 @@ function getFiles(file, data) {
|
|
|
32
32
|
if (file.torrentFiles) {
|
|
33
33
|
individual.push(...file.torrentFiles);
|
|
34
34
|
}
|
|
35
|
-
if (individual.length) {
|
|
35
|
+
if (individual.length > 0) {
|
|
36
36
|
return [grouped, Array.from(new Set(individual))];
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
return [grouped];
|
|
40
40
|
}
|
|
41
|
+
function createUploadCallback(state, file, active) {
|
|
42
|
+
return async (value) => {
|
|
43
|
+
if ((0, types_1.isString)(value)) {
|
|
44
|
+
for (const { instance: document } of state.host.Document) {
|
|
45
|
+
if (document.cloudUpload && await document.cloudUpload(state, file, value, active)) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function renameTrailing(map, item, folder, value) {
|
|
53
|
+
const location = folder + value;
|
|
54
|
+
map[location] || (map[location] = 1);
|
|
55
|
+
const index = value.indexOf('.');
|
|
56
|
+
item.filename = (index !== -1 ? value.substring(0, index) : value) + '_' + map[location]++ + (index !== -1 ? value.substring(index) : '');
|
|
57
|
+
}
|
|
58
|
+
function errorResponse(instance, service, bucket, err) {
|
|
59
|
+
instance.formatMessage(64, service, ["Unable to empty bucket", bucket], err, { ...Cloud.LOG_CLOUD_WARN });
|
|
60
|
+
}
|
|
41
61
|
const errorObject = (err, service, value) => err instanceof Error ? err : typeof err === 'string' ? new Error(err) : (0, types_1.errorMessage)(service, value);
|
|
42
|
-
const assignFilename = (value) =>
|
|
62
|
+
const assignFilename = (value) => crypto.randomUUID() + (path.extname(value) || '');
|
|
43
63
|
class Cloud extends core_1.ClientDb {
|
|
44
64
|
constructor() {
|
|
45
65
|
super(...arguments);
|
|
@@ -54,7 +74,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
54
74
|
}
|
|
55
75
|
Cloud.sanitizeAssets(this.assets);
|
|
56
76
|
const localStorage = new Map();
|
|
57
|
-
const bucketGroup =
|
|
77
|
+
const bucketGroup = crypto.randomUUID();
|
|
58
78
|
const state = { host: this, instance, bucketGroup, localStorage };
|
|
59
79
|
const bucketDelete = {};
|
|
60
80
|
const bucketPolicy = {};
|
|
@@ -72,7 +92,9 @@ class Cloud extends core_1.ClientDb {
|
|
|
72
92
|
const cloudStorage = item.cloudStorage;
|
|
73
93
|
if ((0, types_1.isArray)(cloudStorage) && !(0, types_1.ignoreFlag)(item.flags)) {
|
|
74
94
|
if (item.invalid) {
|
|
75
|
-
cloudStorage.forEach(storage =>
|
|
95
|
+
cloudStorage.forEach(storage => {
|
|
96
|
+
instance.formatMessage(64, storage.service, ["Upload failed", storage.bucket], (0, types_1.errorValue)("File not found", item.uri || item.filename || "Unknown"), { ...Cloud.LOG_CLOUD_WARN });
|
|
97
|
+
});
|
|
76
98
|
continue;
|
|
77
99
|
}
|
|
78
100
|
resume: {
|
|
@@ -119,8 +141,8 @@ class Cloud extends core_1.ClientDb {
|
|
|
119
141
|
}
|
|
120
142
|
}
|
|
121
143
|
}
|
|
122
|
-
if (tasks.length) {
|
|
123
|
-
await instance.allSettled(tasks, [
|
|
144
|
+
if (tasks.length > 0) {
|
|
145
|
+
await instance.allSettled(tasks, ["Compress files", instance.moduleName]);
|
|
124
146
|
if (instance.aborted) {
|
|
125
147
|
return (0, types_1.createAbortError)(true);
|
|
126
148
|
}
|
|
@@ -130,22 +152,26 @@ class Cloud extends core_1.ClientDb {
|
|
|
130
152
|
const map = bucketDelete[service];
|
|
131
153
|
for (const bucket in map) {
|
|
132
154
|
const [credential, recursive] = map[bucket];
|
|
133
|
-
tasks.push(instance.deleteObjects(service, credential, bucket, recursive).catch((err) =>
|
|
155
|
+
tasks.push(instance.deleteObjects(service, credential, bucket, recursive).catch((err) => {
|
|
156
|
+
instance.writeFail(["Unable to empty bucket", service + ': ' + bucket], err, { type: 64, startTime });
|
|
157
|
+
}));
|
|
134
158
|
}
|
|
135
159
|
}
|
|
136
|
-
if (tasks.length) {
|
|
137
|
-
await instance.allSettled(tasks, [
|
|
160
|
+
if (tasks.length > 0) {
|
|
161
|
+
await instance.allSettled(tasks, ["Empty bucket", instance.moduleName]);
|
|
138
162
|
if (instance.aborted) {
|
|
139
163
|
return (0, types_1.createAbortError)(true);
|
|
140
164
|
}
|
|
141
165
|
tasks = [];
|
|
142
166
|
}
|
|
143
|
-
if (rawFiles.length) {
|
|
167
|
+
if (rawFiles.length > 0) {
|
|
144
168
|
const options = { preferBuffer: process.env.EMC_CLOUD_UPLOAD_BUFFER === 'true' };
|
|
145
|
-
rawFiles.forEach(item =>
|
|
169
|
+
rawFiles.forEach(item => {
|
|
170
|
+
tasks.push(...Cloud.uploadAsset(state, item, options));
|
|
171
|
+
});
|
|
146
172
|
}
|
|
147
|
-
if (tasks.length) {
|
|
148
|
-
await instance.allSettled(tasks, [
|
|
173
|
+
if (tasks.length > 0) {
|
|
174
|
+
await instance.allSettled(tasks, ["Upload raw assets", instance.moduleName]);
|
|
149
175
|
if (instance.aborted) {
|
|
150
176
|
return (0, types_1.createAbortError)(true);
|
|
151
177
|
}
|
|
@@ -155,18 +181,22 @@ class Cloud extends core_1.ClientDb {
|
|
|
155
181
|
const map = bucketPolicy[service];
|
|
156
182
|
for (const bucket in map) {
|
|
157
183
|
const [credential, options] = map[bucket];
|
|
158
|
-
tasks.push(instance.setBucketPolicy(service, credential, bucket, options).catch((err) =>
|
|
184
|
+
tasks.push(instance.setBucketPolicy(service, credential, bucket, options).catch((err) => {
|
|
185
|
+
instance.writeFail(["Unable to update bucket policy", service + ': ' + bucket], err, { type: 64, startTime });
|
|
186
|
+
}));
|
|
159
187
|
}
|
|
160
188
|
}
|
|
161
189
|
for (const service in bucketTagging) {
|
|
162
190
|
const map = bucketTagging[service];
|
|
163
191
|
for (const bucket in map) {
|
|
164
192
|
const [credential, options] = map[bucket];
|
|
165
|
-
tasks.push(instance.setBucketTagging(service, credential, bucket, options).catch((err) =>
|
|
193
|
+
tasks.push(instance.setBucketTagging(service, credential, bucket, options).catch((err) => {
|
|
194
|
+
instance.writeFail(["Unable to update bucket tagging", service + ': ' + bucket], err, { type: 64, startTime });
|
|
195
|
+
}));
|
|
166
196
|
}
|
|
167
197
|
}
|
|
168
|
-
if (tasks.length) {
|
|
169
|
-
await instance.allSettled(tasks, [
|
|
198
|
+
if (tasks.length > 0) {
|
|
199
|
+
await instance.allSettled(tasks, ["Configure bucket", instance.moduleName]);
|
|
170
200
|
if (instance.aborted) {
|
|
171
201
|
return (0, types_1.createAbortError)(true);
|
|
172
202
|
}
|
|
@@ -174,14 +204,22 @@ class Cloud extends core_1.ClientDb {
|
|
|
174
204
|
}
|
|
175
205
|
for (const { instance: document } of this.Document) {
|
|
176
206
|
if (document.cloudFinalize) {
|
|
177
|
-
await document.cloudFinalize(state).catch((err) =>
|
|
207
|
+
await document.cloudFinalize(state).catch((err) => {
|
|
208
|
+
document.writeFail(["Handled rejection", document.moduleName], err, { type: 64, startTime });
|
|
209
|
+
});
|
|
178
210
|
if (document.aborted) {
|
|
179
211
|
return (0, types_1.createAbortError)(true);
|
|
180
212
|
}
|
|
181
213
|
}
|
|
182
214
|
}
|
|
183
215
|
for (const [item, data] of localStorage) {
|
|
184
|
-
getFiles(item, data).forEach(group =>
|
|
216
|
+
getFiles(item, data).forEach(group => {
|
|
217
|
+
group.forEach(value => {
|
|
218
|
+
if (value) {
|
|
219
|
+
this.deleteFile(value, { emptyDir: true });
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
});
|
|
185
223
|
}
|
|
186
224
|
for (const item of this.assets) {
|
|
187
225
|
const cloudStorage = item.cloudStorage;
|
|
@@ -274,7 +312,9 @@ class Cloud extends core_1.ClientDb {
|
|
|
274
312
|
}
|
|
275
313
|
return result;
|
|
276
314
|
})
|
|
277
|
-
.catch((err) =>
|
|
315
|
+
.catch((err) => {
|
|
316
|
+
instance.writeFail(["Download failed", path.basename(downloadUri)], err, { type: 64, startTime });
|
|
317
|
+
});
|
|
278
318
|
if (active || waitStatus || this.incremental === "staging") {
|
|
279
319
|
tasks.push(task);
|
|
280
320
|
}
|
|
@@ -282,8 +322,8 @@ class Cloud extends core_1.ClientDb {
|
|
|
282
322
|
}
|
|
283
323
|
}
|
|
284
324
|
}
|
|
285
|
-
if (tasks.length) {
|
|
286
|
-
|
|
325
|
+
if (tasks.length > 0) {
|
|
326
|
+
await instance.allSettled(tasks, ["Download objects", instance.moduleName]);
|
|
287
327
|
}
|
|
288
328
|
}
|
|
289
329
|
static uploadAsset(state, file, contentType, ignoreProcess) {
|
|
@@ -321,15 +361,6 @@ class Cloud extends core_1.ClientDb {
|
|
|
321
361
|
if (active && upload.localStorage === false) {
|
|
322
362
|
state.localStorage.set(file, upload);
|
|
323
363
|
}
|
|
324
|
-
const callback = async (value) => {
|
|
325
|
-
if ((0, types_1.isString)(value) && !ignoreProcess) {
|
|
326
|
-
for (const { instance: document } of host.Document) {
|
|
327
|
-
if (document.cloudUpload && await document.cloudUpload(state, file, value, active)) {
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
364
|
const task = new Promise(resolve => {
|
|
334
365
|
const { service, bucket = state.bucketGroup, admin } = storage;
|
|
335
366
|
const credential = instance.getCredential(storage, true);
|
|
@@ -398,18 +429,19 @@ class Cloud extends core_1.ClientDb {
|
|
|
398
429
|
}
|
|
399
430
|
}
|
|
400
431
|
}
|
|
401
|
-
else {
|
|
402
|
-
contentType = this.lookupMime(path.basename(localUri)) || file.mimeType;
|
|
403
|
-
}
|
|
404
432
|
const options = { ...upload, buffer, filename, fileGroup, admin, flags };
|
|
405
433
|
if (index > 0 || !options.contentType) {
|
|
406
|
-
options.contentType = contentType;
|
|
434
|
+
options.contentType = index === 0 && contentType || this.lookupMime(path.basename(localUri)) || "application/octet-stream";
|
|
407
435
|
}
|
|
408
|
-
uploading.push(instance.uploadObject(service, { ...credential }, bucket, options, localUri,
|
|
409
|
-
.catch((err) =>
|
|
436
|
+
uploading.push(instance.uploadObject(service, { ...credential }, bucket, options, localUri, !ignoreProcess ? createUploadCallback(state, file, active) : undefined)
|
|
437
|
+
.catch((err) => {
|
|
438
|
+
instance.writeFail(["Upload failed", path.basename(localUri)], err, { type: 64, fatal: i === 0 && index === 0 });
|
|
439
|
+
}));
|
|
410
440
|
}
|
|
411
441
|
});
|
|
412
|
-
instance.allSettled(uploading, [`Upload file "${contentType || "Unknown"}"`, storage.service + ': ' + path.basename(file.localUri)]).then(() =>
|
|
442
|
+
void instance.allSettled(uploading, [`Upload file "${contentType || "Unknown"}"`, storage.service + ': ' + path.basename(file.localUri)]).then(() => {
|
|
443
|
+
resolve();
|
|
444
|
+
});
|
|
413
445
|
});
|
|
414
446
|
if (active) {
|
|
415
447
|
tasks.push(task);
|
|
@@ -460,20 +492,14 @@ class Cloud extends core_1.ClientDb {
|
|
|
460
492
|
const leading = other.upload;
|
|
461
493
|
if (leading && hasSameBucket(data, other)) {
|
|
462
494
|
const leadingFolder = leading.pathname || '';
|
|
463
|
-
const renameTrailing = (value) => {
|
|
464
|
-
const location = trailingFolder + value;
|
|
465
|
-
nameIndex[location] || (nameIndex[location] = 1);
|
|
466
|
-
const index = value.indexOf('.');
|
|
467
|
-
trailing.filename = (index !== -1 ? value.substring(0, index) : value) + '_' + nameIndex[location]++ + (index !== -1 ? value.substring(index) : '');
|
|
468
|
-
};
|
|
469
495
|
if (basename && basename === leading.filename && leadingFolder === trailingFolder) {
|
|
470
|
-
renameTrailing(basename);
|
|
496
|
+
renameTrailing(nameIndex, trailing, trailingFolder, basename);
|
|
471
497
|
break renamed;
|
|
472
498
|
}
|
|
473
499
|
const leadingName = this.joinPath(leadingFolder, leading.filename || previous.filename);
|
|
474
500
|
if (trailingName === leadingName) {
|
|
475
501
|
if (!trailing.overwrite || leading.overwrite) {
|
|
476
|
-
renameTrailing(filename);
|
|
502
|
+
renameTrailing(nameIndex, trailing, trailingFolder, filename);
|
|
477
503
|
break renamed;
|
|
478
504
|
}
|
|
479
505
|
leading.filename = assignFilename(leading.filename || previous.filename);
|
|
@@ -499,115 +525,93 @@ class Cloud extends core_1.ClientDb {
|
|
|
499
525
|
if (this.aborted) {
|
|
500
526
|
return (0, types_1.createAbortError)(true);
|
|
501
527
|
}
|
|
528
|
+
const client = this.getClient(service);
|
|
502
529
|
try {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
if (
|
|
506
|
-
|
|
507
|
-
if (handler) {
|
|
508
|
-
return handler.call(this, credential, bucket, publicRead);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
else {
|
|
512
|
-
const handler = client.createBucketV2?.bind(this);
|
|
513
|
-
if (handler) {
|
|
514
|
-
return handler.call(this, credential, bucket, publicRead, options);
|
|
515
|
-
}
|
|
530
|
+
if (publicRead === undefined || typeof publicRead === 'boolean') {
|
|
531
|
+
const handler = client.createBucket?.bind(this);
|
|
532
|
+
if (handler) {
|
|
533
|
+
return handler.call(this, credential, bucket, publicRead);
|
|
516
534
|
}
|
|
517
|
-
return Promise.reject((0, types_1.errorMessage)(service, "Create bucket not supported"));
|
|
518
535
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
536
|
+
else {
|
|
537
|
+
const handler = client.createBucketV2?.bind(this);
|
|
538
|
+
if (handler) {
|
|
539
|
+
return handler.call(this, credential, bucket, publicRead, options);
|
|
540
|
+
}
|
|
522
541
|
}
|
|
523
542
|
}
|
|
524
543
|
catch (err) {
|
|
525
|
-
|
|
544
|
+
this.formatMessage(64, service, ["Unable to create bucket", bucket], err, { ...Cloud.LOG_CLOUD_WARN });
|
|
545
|
+
throw err;
|
|
526
546
|
}
|
|
547
|
+
throw (0, types_1.errorMessage)(service, "Create bucket not supported");
|
|
527
548
|
}
|
|
528
549
|
async setBucketPolicy(service, credential, bucket, options) {
|
|
529
550
|
if (this.aborted) {
|
|
530
551
|
return (0, types_1.createAbortError)(true);
|
|
531
552
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
return Promise.reject(err);
|
|
541
|
-
}
|
|
553
|
+
const handler = this.getClient(service).setBucketPolicy?.bind(this);
|
|
554
|
+
if (handler) {
|
|
555
|
+
try {
|
|
556
|
+
return handler.call(this, credential, bucket, options);
|
|
557
|
+
}
|
|
558
|
+
catch (err) {
|
|
559
|
+
this.formatMessage(64, service, ["Unable to update bucket policy", bucket], err, { ...Cloud.LOG_CLOUD_WARN });
|
|
560
|
+
throw err;
|
|
542
561
|
}
|
|
543
|
-
return Promise.reject((0, types_1.errorMessage)(service, "Bucket policy not supported"));
|
|
544
|
-
}
|
|
545
|
-
catch (err) {
|
|
546
|
-
return Promise.reject(err);
|
|
547
562
|
}
|
|
563
|
+
throw (0, types_1.errorMessage)(service, "Bucket policy not supported");
|
|
548
564
|
}
|
|
549
565
|
async setBucketTagging(service, credential, bucket, options) {
|
|
550
566
|
if (this.aborted) {
|
|
551
567
|
return (0, types_1.createAbortError)(true);
|
|
552
568
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
return Promise.reject(err);
|
|
562
|
-
}
|
|
569
|
+
const handler = this.getClient(service).setBucketTagging?.bind(this);
|
|
570
|
+
if (handler) {
|
|
571
|
+
try {
|
|
572
|
+
return handler.call(this, credential, bucket, options);
|
|
573
|
+
}
|
|
574
|
+
catch (err) {
|
|
575
|
+
this.formatMessage(64, service, ["Unable to update bucket tagging", bucket], err, { ...Cloud.LOG_CLOUD_WARN });
|
|
576
|
+
throw err;
|
|
563
577
|
}
|
|
564
|
-
return Promise.reject((0, types_1.errorMessage)(service, "Bucket tagging not supported"));
|
|
565
|
-
}
|
|
566
|
-
catch (err) {
|
|
567
|
-
return Promise.reject(err);
|
|
568
578
|
}
|
|
579
|
+
throw (0, types_1.errorMessage)(service, "Bucket tagging not supported");
|
|
569
580
|
}
|
|
570
581
|
async setBucketWebsite(service, credential, bucket, options) {
|
|
571
582
|
if (this.aborted) {
|
|
572
583
|
return (0, types_1.createAbortError)(true);
|
|
573
584
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
return Promise.reject(err);
|
|
583
|
-
}
|
|
585
|
+
const handler = this.getClient(service).setBucketWebsite?.bind(this);
|
|
586
|
+
if (handler) {
|
|
587
|
+
try {
|
|
588
|
+
return handler.call(this, credential, bucket, options);
|
|
589
|
+
}
|
|
590
|
+
catch (err) {
|
|
591
|
+
this.formatMessage(64, service, ["Unable to configure bucket", bucket], err, { ...Cloud.LOG_CLOUD_WARN });
|
|
592
|
+
throw err;
|
|
584
593
|
}
|
|
585
|
-
return Promise.reject((0, types_1.errorMessage)(service, "Set bucket website not supported"));
|
|
586
|
-
}
|
|
587
|
-
catch (err) {
|
|
588
|
-
return Promise.reject(err);
|
|
589
594
|
}
|
|
595
|
+
throw (0, types_1.errorMessage)(service, "Set bucket website not supported");
|
|
590
596
|
}
|
|
591
597
|
async deleteObjects(service, credential, bucket, recursive = true) {
|
|
592
598
|
if (this.aborted) {
|
|
593
599
|
return (0, types_1.createAbortError)(true);
|
|
594
600
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
}
|
|
602
|
-
const handlerV1 = client.deleteObjects?.bind(this);
|
|
603
|
-
if (handlerV1) {
|
|
604
|
-
return handlerV1.call(this, credential, bucket, service, undefined, recursive).catch((err) => errorResponse(err));
|
|
605
|
-
}
|
|
606
|
-
return Promise.reject((0, types_1.errorMessage)(service, "Delete objects not supported"));
|
|
601
|
+
const client = this.getClient(service);
|
|
602
|
+
const handlerV2 = client.deleteObjectsV2?.bind(this);
|
|
603
|
+
if (handlerV2) {
|
|
604
|
+
return handlerV2.call(this, credential, bucket, recursive, service).catch((err) => {
|
|
605
|
+
errorResponse(this, service, bucket, err);
|
|
606
|
+
});
|
|
607
607
|
}
|
|
608
|
-
|
|
609
|
-
|
|
608
|
+
const handlerV1 = client.deleteObjects?.bind(this);
|
|
609
|
+
if (handlerV1) {
|
|
610
|
+
return handlerV1.call(this, credential, bucket, service, undefined, recursive).catch((err) => {
|
|
611
|
+
errorResponse(this, service, bucket, err);
|
|
612
|
+
});
|
|
610
613
|
}
|
|
614
|
+
throw (0, types_1.errorMessage)(service, "Delete objects not supported");
|
|
611
615
|
}
|
|
612
616
|
async uploadObject(service, credential, bucket, upload, localUri, beforeResolve) {
|
|
613
617
|
if (this.aborted) {
|
|
@@ -619,7 +623,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
619
623
|
}
|
|
620
624
|
catch (err) {
|
|
621
625
|
this.formatMessage(64, service, ["Upload function not supported", bucket], localUri, { ...Cloud.LOG_CLOUD_WARN });
|
|
622
|
-
|
|
626
|
+
throw err;
|
|
623
627
|
}
|
|
624
628
|
return new Promise((resolve, reject) => {
|
|
625
629
|
const flags = upload.flags || 0;
|
|
@@ -631,7 +635,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
631
635
|
if (beforeResolve) {
|
|
632
636
|
await beforeResolve(value);
|
|
633
637
|
}
|
|
634
|
-
this.addLog(types_1.STATUS_TYPE.INFO,
|
|
638
|
+
this.addLog(types_1.STATUS_TYPE.INFO, 'uploadObject: ' + bucket, service, value);
|
|
635
639
|
resolve(value);
|
|
636
640
|
}
|
|
637
641
|
else {
|
|
@@ -653,7 +657,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
653
657
|
}
|
|
654
658
|
catch (err) {
|
|
655
659
|
this.formatMessage(64, service, ["Download function not supported", bucket], Cloud.joinPath(download.pathname, download.filename), { ...Cloud.LOG_CLOUD_WARN });
|
|
656
|
-
|
|
660
|
+
throw err;
|
|
657
661
|
}
|
|
658
662
|
return new Promise((resolve, reject) => {
|
|
659
663
|
handler({ bucket, download }, async (err, value) => {
|
|
@@ -668,7 +672,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
668
672
|
}
|
|
669
673
|
}
|
|
670
674
|
if (typeof value === 'string' && path.isAbsolute(value)) {
|
|
671
|
-
this.addLog(types_1.STATUS_TYPE.INFO,
|
|
675
|
+
this.addLog(types_1.STATUS_TYPE.INFO, 'downloadObject: ' + bucket, service, value);
|
|
672
676
|
this.downloaded.push(value);
|
|
673
677
|
}
|
|
674
678
|
resolve(value);
|
|
@@ -703,12 +707,12 @@ class Cloud extends core_1.ClientDb {
|
|
|
703
707
|
}
|
|
704
708
|
catch (err) {
|
|
705
709
|
this.formatFail(64, service, "Unable to execute query", err, { ...Cloud.LOG_CLOUD_FAIL });
|
|
706
|
-
|
|
710
|
+
throw err;
|
|
707
711
|
}
|
|
708
712
|
}
|
|
709
|
-
|
|
713
|
+
throw (0, types_1.errorMessage)(service, "Execute query not supported");
|
|
710
714
|
}
|
|
711
|
-
|
|
715
|
+
throw (0, types_1.errorMessage)(service, "Invalid credentials");
|
|
712
716
|
}
|
|
713
717
|
async getDatabaseBatchRows(batch, ignoreErrors, sessionKey) {
|
|
714
718
|
if (this.aborted) {
|
|
@@ -725,7 +729,11 @@ class Cloud extends core_1.ClientDb {
|
|
|
725
729
|
if (client?.executeBatchQuery) {
|
|
726
730
|
const credential = this.getCredential(data);
|
|
727
731
|
if (this.hasCoerce(service, 'options', credential)) {
|
|
728
|
-
batch.forEach(item =>
|
|
732
|
+
batch.forEach(item => {
|
|
733
|
+
if (item.options) {
|
|
734
|
+
(0, types_1.coerceObject)(item.options);
|
|
735
|
+
}
|
|
736
|
+
});
|
|
729
737
|
}
|
|
730
738
|
if (ignoreErrors) {
|
|
731
739
|
return client.executeBatchQuery.call(this, credential, batch, sessionKey);
|
|
@@ -735,12 +743,12 @@ class Cloud extends core_1.ClientDb {
|
|
|
735
743
|
}
|
|
736
744
|
catch (err) {
|
|
737
745
|
this.formatFail(64, service, "Unable to execute query", err, { ...Cloud.LOG_CLOUD_FAIL });
|
|
738
|
-
|
|
746
|
+
throw err;
|
|
739
747
|
}
|
|
740
748
|
}
|
|
741
|
-
|
|
749
|
+
throw (0, types_1.errorMessage)(service, "Execute query not supported");
|
|
742
750
|
}
|
|
743
|
-
|
|
751
|
+
throw (0, types_1.errorMessage)(service, "Invalid credentials");
|
|
744
752
|
}
|
|
745
753
|
getCredential(item, unused) {
|
|
746
754
|
const service = item.service;
|
|
@@ -813,7 +821,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
813
821
|
resolveService(service, folder) {
|
|
814
822
|
let result;
|
|
815
823
|
if (!service.startsWith('@')) {
|
|
816
|
-
result = this.settings.imports?.[service] ||
|
|
824
|
+
result = this.settings.imports?.[service] || types_1.IMPORT_MAP[service];
|
|
817
825
|
}
|
|
818
826
|
else {
|
|
819
827
|
folder || (folder = 'client');
|
|
@@ -860,5 +868,4 @@ Cloud.LOG_CLOUD_UPLOAD = Object.freeze({ titleColor: 'green' });
|
|
|
860
868
|
Cloud.LOG_CLOUD_DOWNLOAD = Object.freeze({ titleColor: 'cyan' });
|
|
861
869
|
Cloud.LOG_CLOUD_DELETE = Object.freeze({ titleColor: 'grey' });
|
|
862
870
|
Cloud.LOG_CLOUD_DELAYED = Object.freeze({ titleColor: 'grey' });
|
|
863
|
-
|
|
864
871
|
module.exports = Cloud;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/cloud",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Cloud constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"license": "BSD 3-Clause",
|
|
21
21
|
"homepage": "https://github.com/anpham6/e-mc#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/core": "0.
|
|
24
|
-
"@e-mc/db": "0.
|
|
25
|
-
"@e-mc/types": "0.
|
|
23
|
+
"@e-mc/core": "0.10.0",
|
|
24
|
+
"@e-mc/db": "0.10.0",
|
|
25
|
+
"@e-mc/types": "0.10.0",
|
|
26
26
|
"mime-types": "^2.1.35"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/util.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { AuthValue } from '../types/lib/http';
|
|
|
4
4
|
import type { Readable } from 'stream';
|
|
5
5
|
|
|
6
6
|
declare namespace util {
|
|
7
|
+
/** @deprecated Types.IMPORT_MAP */
|
|
7
8
|
const IMPORTS: Record<string, string | undefined>;
|
|
8
9
|
function readableAsBuffer(from: Readable): Promise<Buffer | null>;
|
|
9
10
|
function createKeyAndBody<T = Buffer>(filename: string, items: UploadContent[], chunkSize?: number | string | FunctionType<void>, errorCallback?: FunctionType<void> | number, flags?: number): [string[], T[], string[]];
|
package/util.js
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
exports.hasBasicAuth = exports.getBasicAuth = exports.
|
|
2
|
+
exports.hasBasicAuth = exports.getBasicAuth = exports.IMPORTS = void 0;
|
|
3
|
+
exports.readableAsBuffer = readableAsBuffer;
|
|
4
|
+
exports.createKeyAndBody = createKeyAndBody;
|
|
5
|
+
exports.generateFilename = generateFilename;
|
|
6
|
+
exports.formatError = formatError;
|
|
3
7
|
const path = require("path");
|
|
4
8
|
const fs = require("fs");
|
|
5
9
|
const stream = require("stream");
|
|
6
10
|
const mime = require("mime-types");
|
|
7
11
|
const types_1 = require("@e-mc/types");
|
|
12
|
+
Object.defineProperty(exports, "IMPORTS", { enumerable: true, get: function () { return types_1.IMPORT_MAP; } });
|
|
8
13
|
const util_1 = require("@e-mc/db/util");
|
|
9
14
|
Object.defineProperty(exports, "getBasicAuth", { enumerable: true, get: function () { return util_1.getBasicAuth; } });
|
|
10
15
|
Object.defineProperty(exports, "hasBasicAuth", { enumerable: true, get: function () { return util_1.hasBasicAuth; } });
|
|
11
|
-
exports.IMPORTS = {
|
|
12
|
-
"atlas": "@pi-r/atlas",
|
|
13
|
-
"aws": "@pi-r/aws",
|
|
14
|
-
"aws-v3": "@pi-r/aws-v3",
|
|
15
|
-
"az": "@pi-r/azure",
|
|
16
|
-
"azure": "@pi-r/azure",
|
|
17
|
-
"gcloud": "@pi-r/gcp",
|
|
18
|
-
"gcp": "@pi-r/gcp",
|
|
19
|
-
"ibm": "@pi-r/ibm",
|
|
20
|
-
"minio": "@pi-r/minio",
|
|
21
|
-
"oci": "@pi-r/oci"
|
|
22
|
-
};
|
|
23
16
|
async function readableAsBuffer(from) {
|
|
24
17
|
return new Promise((resolve, reject) => {
|
|
25
18
|
let result = null;
|
|
@@ -29,12 +22,15 @@ async function readableAsBuffer(from) {
|
|
|
29
22
|
}
|
|
30
23
|
result = result ? Buffer.concat([result, chunk]) : chunk;
|
|
31
24
|
})
|
|
32
|
-
.on('end', () =>
|
|
33
|
-
|
|
25
|
+
.on('end', () => {
|
|
26
|
+
resolve(result);
|
|
27
|
+
})
|
|
28
|
+
.on('error', err => {
|
|
29
|
+
reject(err);
|
|
30
|
+
})
|
|
34
31
|
.read();
|
|
35
32
|
});
|
|
36
33
|
}
|
|
37
|
-
exports.readableAsBuffer = readableAsBuffer;
|
|
38
34
|
function createKeyAndBody(filename, items, chunkSize = 0, errorCallback, flags = 0) {
|
|
39
35
|
let mimeType;
|
|
40
36
|
switch (typeof chunkSize) {
|
|
@@ -112,7 +108,7 @@ function createKeyAndBody(filename, items, chunkSize = 0, errorCallback, flags =
|
|
|
112
108
|
const output = filename + ext;
|
|
113
109
|
key.push(ext === '.map' && localFile ? path.basename(localFile) : output);
|
|
114
110
|
body.push(target);
|
|
115
|
-
type.push(ext !== '.map' && mime.lookup(output) || mimeType ||
|
|
111
|
+
type.push(ext !== '.map' && mime.lookup(output) || mimeType || "application/octet-stream");
|
|
116
112
|
}
|
|
117
113
|
}
|
|
118
114
|
catch (err) {
|
|
@@ -121,7 +117,6 @@ function createKeyAndBody(filename, items, chunkSize = 0, errorCallback, flags =
|
|
|
121
117
|
}
|
|
122
118
|
return [key, body, type];
|
|
123
119
|
}
|
|
124
|
-
exports.createKeyAndBody = createKeyAndBody;
|
|
125
120
|
function generateFilename(filename) {
|
|
126
121
|
let basename, suffix;
|
|
127
122
|
return (i) => {
|
|
@@ -140,11 +135,9 @@ function generateFilename(filename) {
|
|
|
140
135
|
return basename && suffix ? [basename + `_${i}` + suffix, true] : [(0, types_1.incrementUUID)() + path.extname(filename), false];
|
|
141
136
|
};
|
|
142
137
|
}
|
|
143
|
-
exports.generateFilename = generateFilename;
|
|
144
138
|
function formatError(title, value, hint) {
|
|
145
139
|
if ((0, types_1.isObject)(title)) {
|
|
146
140
|
title = title.service;
|
|
147
141
|
}
|
|
148
142
|
return (0, types_1.errorMessage)(typeof title === 'string' ? title : '', value, hint);
|
|
149
143
|
}
|
|
150
|
-
exports.formatError = formatError;
|