@e-mc/cloud 0.13.9 → 0.14.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 +8 -8
- package/index.js +128 -125
- package/package.json +4 -4
- package/types/index.d.ts +3 -2
- package/util.d.ts +12 -1
- package/util.js +42 -36
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @e-mc/cloud
|
|
2
2
|
|
|
3
|
-
* NodeJS
|
|
3
|
+
* NodeJS 20 (Minimum 18)
|
|
4
4
|
* ES2022
|
|
5
5
|
|
|
6
6
|
## General Usage
|
|
@@ -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.14.0/lib/index.d.ts)
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
import type { IFileManager, IHost, IScopeOrigin } from "./index";
|
|
@@ -180,12 +180,12 @@ const rows = await instance.getDatabaseRows({ service: "aws-v3", credential: "ma
|
|
|
180
180
|
|
|
181
181
|
## References
|
|
182
182
|
|
|
183
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
184
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
185
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
186
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
187
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
188
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
183
|
+
- https://www.unpkg.com/@e-mc/types@0.14.0/lib/asset.d.ts
|
|
184
|
+
- https://www.unpkg.com/@e-mc/types@0.14.0/lib/cloud.d.ts
|
|
185
|
+
- https://www.unpkg.com/@e-mc/types@0.14.0/lib/core.d.ts
|
|
186
|
+
- https://www.unpkg.com/@e-mc/types@0.14.0/lib/db.d.ts
|
|
187
|
+
- https://www.unpkg.com/@e-mc/types@0.14.0/lib/logger.d.ts
|
|
188
|
+
- https://www.unpkg.com/@e-mc/types@0.14.0/lib/settings.d.ts
|
|
189
189
|
|
|
190
190
|
## LICENSE
|
|
191
191
|
|
package/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
2
|
+
|
|
3
|
+
var _a;
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const fs = require('node:fs');
|
|
6
|
+
const { randomUUID } = require('node:crypto');
|
|
7
|
+
const { IMPORT_MAP, alignSize, coerceObject, createAbortError, errorMessage, errorValue, formatSize, ignoreFlag, isArray, isError, isErrorCode, isObject, isPlainObject, isString } = require('@e-mc/types');
|
|
8
|
+
const { ClientDb } = require('@e-mc/core');
|
|
7
9
|
const kCloud = Symbol.for('cloud:constructor');
|
|
8
10
|
const SERVICE_CLIENT = new Map();
|
|
9
11
|
const SERVICE_UPLOAD = Object.create(null);
|
|
@@ -12,19 +14,19 @@ function setUploadFilename(upload, filename) {
|
|
|
12
14
|
filename = Cloud.toPosix(filename.replace(/^\.*[\\/]+/, ''));
|
|
13
15
|
const index = filename.lastIndexOf('/');
|
|
14
16
|
if (index !== -1) {
|
|
15
|
-
const directory = filename.
|
|
17
|
+
const directory = filename.slice(0, index + 1);
|
|
16
18
|
upload.pathname = upload.pathname ? Cloud.joinPath(upload.pathname, directory) : directory;
|
|
17
|
-
filename = filename.
|
|
19
|
+
filename = filename.slice(index + 1);
|
|
18
20
|
}
|
|
19
21
|
return upload.filename = filename;
|
|
20
22
|
}
|
|
21
|
-
function
|
|
23
|
+
function fromSameBucket({ upload, service, bucket }, other) {
|
|
22
24
|
const endpoint = upload.endpoint;
|
|
23
25
|
return (service && other.service || endpoint && endpoint === other.upload.endpoint) && bucket === other.bucket;
|
|
24
26
|
}
|
|
25
27
|
function getFiles(file, data) {
|
|
26
28
|
const localUri = file.localUri;
|
|
27
|
-
const grouped = [localUri &&
|
|
29
|
+
const grouped = [localUri && ClientDb.isPath(localUri, true) ? localUri : ''];
|
|
28
30
|
if (data.all) {
|
|
29
31
|
if (file.descendants) {
|
|
30
32
|
grouped.push(...file.descendants);
|
|
@@ -43,19 +45,16 @@ function renameTrailing(map, item, folder, value) {
|
|
|
43
45
|
const location = folder + value;
|
|
44
46
|
map[location] ||= 1;
|
|
45
47
|
const index = value.indexOf('.');
|
|
46
|
-
item.filename = (index !== -1 ? value.
|
|
48
|
+
item.filename = (index !== -1 ? value.slice(0, index) : value) + '_' + map[location]++ + (index !== -1 ? value.slice(index) : '');
|
|
47
49
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const errorObject = (err, service, value) => err instanceof Error ? err : typeof err === 'string' ? new Error(err) : (0, types_1.errorMessage)(service, value);
|
|
52
|
-
const assignFilename = (value) => crypto.randomUUID() + (path.extname(value) || '');
|
|
53
|
-
class Cloud extends core_1.ClientDb {
|
|
50
|
+
const errorObject = (err, service, value) => isError(err) ? err : typeof err === 'string' ? new Error(err) : errorMessage(service, value);
|
|
51
|
+
const assignFilename = (value) => randomUUID() + (path.extname(value) || '');
|
|
52
|
+
class Cloud extends ClientDb {
|
|
54
53
|
static [kCloud] = true;
|
|
55
54
|
static STORE_RESULT_PARTITION_SIZE = 16;
|
|
56
55
|
static STORE_RESULT_PARTITION_MULT = 2;
|
|
57
|
-
static LOG_CLOUD_SUCCESS =
|
|
58
|
-
static LOG_CLOUD_FAIL =
|
|
56
|
+
static LOG_CLOUD_SUCCESS = ClientDb.LOG_STYLE_SUCCESS;
|
|
57
|
+
static LOG_CLOUD_FAIL = ClientDb.LOG_STYLE_FAIL;
|
|
59
58
|
static LOG_CLOUD_COMMAND = Object.freeze({ titleColor: 'blue' });
|
|
60
59
|
static LOG_CLOUD_WARN = Object.freeze({ titleColor: 'yellow' });
|
|
61
60
|
static LOG_CLOUD_UPLOAD = Object.freeze({ titleColor: 'green' });
|
|
@@ -87,11 +86,11 @@ class Cloud extends core_1.ClientDb {
|
|
|
87
86
|
}
|
|
88
87
|
static async finalize(instance) {
|
|
89
88
|
if (instance.aborted) {
|
|
90
|
-
return
|
|
89
|
+
return createAbortError(true);
|
|
91
90
|
}
|
|
92
|
-
|
|
91
|
+
_a.sanitizeAssets(this.assets);
|
|
93
92
|
const localStorage = new Map();
|
|
94
|
-
const bucketGroup =
|
|
93
|
+
const bucketGroup = randomUUID();
|
|
95
94
|
const state = { host: this, instance, bucketGroup, localStorage };
|
|
96
95
|
const bucketDelete = {};
|
|
97
96
|
const bucketPolicy = {};
|
|
@@ -100,17 +99,17 @@ class Cloud extends core_1.ClientDb {
|
|
|
100
99
|
const startTime = process.hrtime.bigint();
|
|
101
100
|
let tasks = [], downloadMap;
|
|
102
101
|
if (await instance.commit()) {
|
|
103
|
-
instance.writeTimeElapsed(instance.moduleName, "Transactions were committed", startTime,
|
|
102
|
+
instance.writeTimeElapsed(instance.moduleName, "Transactions were committed", startTime, _a.optionsLogMessage('SUCCESS'));
|
|
104
103
|
}
|
|
105
104
|
for (const { instance: document } of this.Document) {
|
|
106
105
|
document.cloudInit?.(state);
|
|
107
106
|
}
|
|
108
107
|
for (const item of this.assets) {
|
|
109
108
|
const cloudStorage = item.cloudStorage;
|
|
110
|
-
if (
|
|
109
|
+
if (isArray(cloudStorage) && !ignoreFlag(item)) {
|
|
111
110
|
if (item.invalid) {
|
|
112
111
|
for (const storage of cloudStorage) {
|
|
113
|
-
instance.formatMessage(64, storage.service, ["Upload failed", storage.bucket],
|
|
112
|
+
instance.formatMessage(64, storage.service, ["Upload failed", storage.bucket], errorValue("File not found", item.uri || item.filename || "Unknown"), _a.optionsLogMessage('WARN'));
|
|
114
113
|
}
|
|
115
114
|
continue;
|
|
116
115
|
}
|
|
@@ -137,7 +136,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
137
136
|
const service = bucketDelete[name] ||= {};
|
|
138
137
|
const items = service[bucket];
|
|
139
138
|
if (!items) {
|
|
140
|
-
let options =
|
|
139
|
+
let options = isObject(admin.emptyBucket) ? admin.emptyBucket : undefined;
|
|
141
140
|
if (typeof admin.recursive === 'boolean') {
|
|
142
141
|
(options ||= {}).recursive = admin.recursive;
|
|
143
142
|
}
|
|
@@ -165,7 +164,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
165
164
|
if (tasks.length > 0) {
|
|
166
165
|
await instance.allSettled(tasks, ["Compress files", instance.moduleName]);
|
|
167
166
|
if (instance.aborted) {
|
|
168
|
-
return
|
|
167
|
+
return createAbortError(true);
|
|
169
168
|
}
|
|
170
169
|
tasks = [];
|
|
171
170
|
}
|
|
@@ -181,20 +180,20 @@ class Cloud extends core_1.ClientDb {
|
|
|
181
180
|
if (tasks.length > 0) {
|
|
182
181
|
await instance.allSettled(tasks, ["Empty bucket", instance.moduleName]);
|
|
183
182
|
if (instance.aborted) {
|
|
184
|
-
return
|
|
183
|
+
return createAbortError(true);
|
|
185
184
|
}
|
|
186
185
|
tasks = [];
|
|
187
186
|
}
|
|
188
187
|
if (rawFiles.length > 0) {
|
|
189
188
|
const options = { preferBuffer: process.env.EMC_CLOUD_UPLOAD_BUFFER === 'true' };
|
|
190
189
|
for (const item of rawFiles) {
|
|
191
|
-
tasks.push(...
|
|
190
|
+
tasks.push(..._a.uploadAsset(state, item, options));
|
|
192
191
|
}
|
|
193
192
|
}
|
|
194
193
|
if (tasks.length > 0) {
|
|
195
194
|
await instance.allSettled(tasks, ["Upload raw assets", instance.moduleName]);
|
|
196
195
|
if (instance.aborted) {
|
|
197
|
-
return
|
|
196
|
+
return createAbortError(true);
|
|
198
197
|
}
|
|
199
198
|
tasks = [];
|
|
200
199
|
}
|
|
@@ -219,7 +218,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
219
218
|
if (tasks.length > 0) {
|
|
220
219
|
await instance.allSettled(tasks, ["Configure bucket", instance.moduleName]);
|
|
221
220
|
if (instance.aborted) {
|
|
222
|
-
return
|
|
221
|
+
return createAbortError(true);
|
|
223
222
|
}
|
|
224
223
|
tasks = [];
|
|
225
224
|
}
|
|
@@ -229,7 +228,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
229
228
|
document.writeFail(["Handled rejection", document.moduleName], err, { type: 64, startTime });
|
|
230
229
|
});
|
|
231
230
|
if (document.aborted) {
|
|
232
|
-
return
|
|
231
|
+
return createAbortError(true);
|
|
233
232
|
}
|
|
234
233
|
}
|
|
235
234
|
}
|
|
@@ -244,7 +243,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
244
243
|
}
|
|
245
244
|
for (const item of this.assets) {
|
|
246
245
|
const cloudStorage = item.cloudStorage;
|
|
247
|
-
if (
|
|
246
|
+
if (isArray(cloudStorage) && !ignoreFlag(item)) {
|
|
248
247
|
for (const data of cloudStorage) {
|
|
249
248
|
if (!instance.hasStorage('download', data)) {
|
|
250
249
|
continue;
|
|
@@ -258,8 +257,8 @@ class Cloud extends core_1.ClientDb {
|
|
|
258
257
|
let active = download.active, downloadUri;
|
|
259
258
|
if (pathname && path.isAbsolute(pathname)) {
|
|
260
259
|
downloadUri = path.join(pathname, filename);
|
|
261
|
-
if (!
|
|
262
|
-
instance.writeFail(["Unable to download file", filename],
|
|
260
|
+
if (!_a.isPath(downloadUri) && !this.canWrite(pathname)) {
|
|
261
|
+
instance.writeFail(["Unable to download file", filename], errorValue("Unsupported access", pathname), { type: 64, fatal: !!active, startTime });
|
|
263
262
|
continue;
|
|
264
263
|
}
|
|
265
264
|
}
|
|
@@ -267,14 +266,14 @@ class Cloud extends core_1.ClientDb {
|
|
|
267
266
|
downloadUri = pathname ? path.join(this.baseDirectory, pathname.replace(/^([A-Z]:)?[\\/]+/i, ''), filename) : path.join(data.admin?.preservePath && localUri ? path.dirname(localUri) : this.baseDirectory, filename);
|
|
268
267
|
}
|
|
269
268
|
const destDir = path.dirname(downloadUri);
|
|
270
|
-
if (
|
|
269
|
+
if (_a.isPath(downloadUri)) {
|
|
271
270
|
if (!active && !overwrite) {
|
|
272
271
|
continue;
|
|
273
272
|
}
|
|
274
273
|
active = true;
|
|
275
274
|
}
|
|
276
|
-
else if (!
|
|
277
|
-
instance.writeFail(["Unable to create directory", filename],
|
|
275
|
+
else if (!_a.createDir(destDir)) {
|
|
276
|
+
instance.writeFail(["Unable to create directory", filename], errorValue("Path is not a directory", destDir), { type: 64, fatal: !!active, startTime });
|
|
278
277
|
continue;
|
|
279
278
|
}
|
|
280
279
|
else if (active) {
|
|
@@ -294,7 +293,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
294
293
|
}
|
|
295
294
|
pending = new Set([downloadUri]);
|
|
296
295
|
download.admin = data.admin;
|
|
297
|
-
download.flags = SERVICE_CLIENT.get(service).CLOUD_DOWNLOAD_CHUNK &&
|
|
296
|
+
download.flags = SERVICE_CLIENT.get(service).CLOUD_DOWNLOAD_CHUNK && alignSize(download.chunkSize) > 0 ? 4 : 0;
|
|
298
297
|
const task = instance.downloadObject(service, instance.getCredential(data), data.bucket, download, async (value) => {
|
|
299
298
|
if (instance.aborted || !value) {
|
|
300
299
|
return;
|
|
@@ -318,11 +317,11 @@ class Cloud extends core_1.ClientDb {
|
|
|
318
317
|
this.addDownload(size = value.length);
|
|
319
318
|
}
|
|
320
319
|
this.add(destUri);
|
|
321
|
-
this.formatMessage(64, service, ["Download success",
|
|
320
|
+
this.formatMessage(64, service, ["Download success", formatSize(size)], destUri, _a.optionsLogMessage('DOWNLOAD'));
|
|
322
321
|
result ||= destUri;
|
|
323
322
|
}
|
|
324
323
|
catch (err) {
|
|
325
|
-
if (!copy &&
|
|
324
|
+
if (!copy && isErrorCode(err, 'EXDEV')) {
|
|
326
325
|
copy = true;
|
|
327
326
|
--i;
|
|
328
327
|
}
|
|
@@ -349,7 +348,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
349
348
|
}
|
|
350
349
|
static uploadAsset(state, file, contentType, ignoreProcess) {
|
|
351
350
|
let preferBuffer;
|
|
352
|
-
if (
|
|
351
|
+
if (isObject(contentType)) {
|
|
353
352
|
({ contentType, ignoreProcess, preferBuffer } = contentType);
|
|
354
353
|
}
|
|
355
354
|
else if (typeof contentType === 'boolean') {
|
|
@@ -375,7 +374,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
375
374
|
if (client.CLOUD_UPLOAD_STREAM && upload.minStreamSize !== -1) {
|
|
376
375
|
flags |= 2;
|
|
377
376
|
}
|
|
378
|
-
if (client.CLOUD_UPLOAD_CHUNK &&
|
|
377
|
+
if (client.CLOUD_UPLOAD_CHUNK && alignSize(upload.chunkSize) > 0) {
|
|
379
378
|
flags |= 4;
|
|
380
379
|
}
|
|
381
380
|
}
|
|
@@ -385,13 +384,13 @@ class Cloud extends core_1.ClientDb {
|
|
|
385
384
|
const task = new Promise(resolve => {
|
|
386
385
|
const { service, bucket = state.bucketGroup, admin } = storage;
|
|
387
386
|
const credential = instance.getCredential(storage, true);
|
|
388
|
-
const minStreamSize =
|
|
387
|
+
const minStreamSize = alignSize(upload.minStreamSize);
|
|
389
388
|
const uploading = [];
|
|
390
389
|
getFiles(file, upload).forEach(async (group, index) => {
|
|
391
390
|
let fileGroup;
|
|
392
391
|
if (index === 0) {
|
|
393
392
|
if (!group[0]) {
|
|
394
|
-
instance.writeFail("Unable to read file",
|
|
393
|
+
instance.writeFail("Unable to read file", errorValue("File not found", service), { type: 64, fatal: true });
|
|
395
394
|
return;
|
|
396
395
|
}
|
|
397
396
|
if (group.length > 1) {
|
|
@@ -419,7 +418,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
419
418
|
const localUri = group[i];
|
|
420
419
|
const exists = index === 0 || this.isPath(localUri, true);
|
|
421
420
|
if (!exists || !instance.canRead(localUri, { ownPermissionOnly: true })) {
|
|
422
|
-
instance.writeFail(["Unable to read file", path.basename(localUri)],
|
|
421
|
+
instance.writeFail(["Unable to read file", path.basename(localUri)], errorValue(!exists ? "File not found" : "Not permitted to read file", localUri), { type: 64, fatal: i === 0 && index === 0 });
|
|
423
422
|
continue;
|
|
424
423
|
}
|
|
425
424
|
let buffer, filename;
|
|
@@ -483,7 +482,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
483
482
|
const storage = [];
|
|
484
483
|
for (const item of assets) {
|
|
485
484
|
const cloudStorage = item.cloudStorage;
|
|
486
|
-
if (
|
|
485
|
+
if (isArray(cloudStorage) && !ignoreFlag(item)) {
|
|
487
486
|
for (const data of cloudStorage) {
|
|
488
487
|
const upload = data.upload;
|
|
489
488
|
if (upload) {
|
|
@@ -505,34 +504,32 @@ class Cloud extends core_1.ClientDb {
|
|
|
505
504
|
const current = storage[i];
|
|
506
505
|
for (const data of current.cloudStorage) {
|
|
507
506
|
const trailing = data.upload;
|
|
508
|
-
if (
|
|
509
|
-
continue;
|
|
510
|
-
}
|
|
511
|
-
renamed: {
|
|
507
|
+
if (trailing) {
|
|
512
508
|
const basename = trailing.filename;
|
|
513
509
|
const filename = basename || current.filename;
|
|
514
510
|
const trailingFolder = trailing.pathname || '';
|
|
515
511
|
const trailingName = this.joinPath(trailingFolder, filename);
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
512
|
+
renamed: {
|
|
513
|
+
for (let j = 0; j < length - 1; ++j) {
|
|
514
|
+
const previous = storage[j];
|
|
515
|
+
if (current !== previous) {
|
|
516
|
+
for (const other of previous.cloudStorage) {
|
|
517
|
+
const leading = other.upload;
|
|
518
|
+
if (leading && fromSameBucket(data, other)) {
|
|
519
|
+
const leadingFolder = leading.pathname || '';
|
|
520
|
+
if (basename && basename === leading.filename && leadingFolder === trailingFolder) {
|
|
521
|
+
renameTrailing(nameIndex, trailing, trailingFolder, basename);
|
|
522
|
+
break renamed;
|
|
523
|
+
}
|
|
524
|
+
const leadingName = this.joinPath(leadingFolder, leading.filename || previous.filename);
|
|
525
|
+
if (trailingName === leadingName) {
|
|
526
|
+
if (!trailing.overwrite || leading.overwrite) {
|
|
527
|
+
renameTrailing(nameIndex, trailing, trailingFolder, filename);
|
|
528
|
+
break renamed;
|
|
529
|
+
}
|
|
530
|
+
leading.filename = assignFilename(leading.filename || previous.filename);
|
|
531
|
+
}
|
|
534
532
|
}
|
|
535
|
-
leading.filename = assignFilename(leading.filename || previous.filename);
|
|
536
533
|
}
|
|
537
534
|
}
|
|
538
535
|
}
|
|
@@ -560,7 +557,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
560
557
|
}
|
|
561
558
|
async createBucket(service, credential, bucket, acl, options) {
|
|
562
559
|
if (this.aborted) {
|
|
563
|
-
return
|
|
560
|
+
return createAbortError(true);
|
|
564
561
|
}
|
|
565
562
|
const client = this.getClient(service);
|
|
566
563
|
try {
|
|
@@ -578,14 +575,14 @@ class Cloud extends core_1.ClientDb {
|
|
|
578
575
|
}
|
|
579
576
|
}
|
|
580
577
|
catch (err) {
|
|
581
|
-
this.formatMessage(64, service, ["Unable to create bucket", bucket], err,
|
|
578
|
+
this.formatMessage(64, service, ["Unable to create bucket", bucket], err, _a.optionsLogMessage('WARN'));
|
|
582
579
|
throw err;
|
|
583
580
|
}
|
|
584
|
-
throw
|
|
581
|
+
throw errorMessage(service, "Create bucket not supported");
|
|
585
582
|
}
|
|
586
583
|
async setBucketPolicy(service, credential, bucket, options) {
|
|
587
584
|
if (this.aborted) {
|
|
588
|
-
return
|
|
585
|
+
return createAbortError(true);
|
|
589
586
|
}
|
|
590
587
|
const handler = this.getClient(service).setBucketPolicy?.bind(this);
|
|
591
588
|
if (handler) {
|
|
@@ -593,15 +590,15 @@ class Cloud extends core_1.ClientDb {
|
|
|
593
590
|
return handler.call(this, credential, bucket, options);
|
|
594
591
|
}
|
|
595
592
|
catch (err) {
|
|
596
|
-
this.formatMessage(64, service, ["Unable to update bucket policy", bucket], err,
|
|
593
|
+
this.formatMessage(64, service, ["Unable to update bucket policy", bucket], err, _a.optionsLogMessage('WARN'));
|
|
597
594
|
throw err;
|
|
598
595
|
}
|
|
599
596
|
}
|
|
600
|
-
throw
|
|
597
|
+
throw errorMessage(service, "Bucket policy not supported");
|
|
601
598
|
}
|
|
602
599
|
async setBucketTagging(service, credential, bucket, options) {
|
|
603
600
|
if (this.aborted) {
|
|
604
|
-
return
|
|
601
|
+
return createAbortError(true);
|
|
605
602
|
}
|
|
606
603
|
const handler = this.getClient(service).setBucketTagging?.bind(this);
|
|
607
604
|
if (handler) {
|
|
@@ -609,15 +606,15 @@ class Cloud extends core_1.ClientDb {
|
|
|
609
606
|
return handler.call(this, credential, bucket, options);
|
|
610
607
|
}
|
|
611
608
|
catch (err) {
|
|
612
|
-
this.formatMessage(64, service, ["Unable to update bucket tagging", bucket], err,
|
|
609
|
+
this.formatMessage(64, service, ["Unable to update bucket tagging", bucket], err, _a.optionsLogMessage('WARN'));
|
|
613
610
|
throw err;
|
|
614
611
|
}
|
|
615
612
|
}
|
|
616
|
-
throw
|
|
613
|
+
throw errorMessage(service, "Bucket tagging not supported");
|
|
617
614
|
}
|
|
618
615
|
async setBucketWebsite(service, credential, bucket, options) {
|
|
619
616
|
if (this.aborted) {
|
|
620
|
-
return
|
|
617
|
+
return createAbortError(true);
|
|
621
618
|
}
|
|
622
619
|
const handler = this.getClient(service).setBucketWebsite?.bind(this);
|
|
623
620
|
if (handler) {
|
|
@@ -625,53 +622,53 @@ class Cloud extends core_1.ClientDb {
|
|
|
625
622
|
return handler.call(this, credential, bucket, options);
|
|
626
623
|
}
|
|
627
624
|
catch (err) {
|
|
628
|
-
this.formatMessage(64, service, ["Unable to configure bucket", bucket], err,
|
|
625
|
+
this.formatMessage(64, service, ["Unable to configure bucket", bucket], err, _a.optionsLogMessage('WARN'));
|
|
629
626
|
throw err;
|
|
630
627
|
}
|
|
631
628
|
}
|
|
632
|
-
throw
|
|
629
|
+
throw errorMessage(service, "Set bucket website not supported");
|
|
633
630
|
}
|
|
634
631
|
async deleteObjects(service, credential, bucket, options = true) {
|
|
635
632
|
if (this.aborted) {
|
|
636
|
-
return
|
|
633
|
+
return createAbortError(true);
|
|
637
634
|
}
|
|
638
635
|
const client = this.getClient(service);
|
|
639
636
|
const handlerV3 = client.deleteObjectsV3?.bind(this);
|
|
640
637
|
if (handlerV3) {
|
|
641
638
|
return handlerV3.call(this, credential, bucket, typeof options === 'boolean' ? { recursive: options } : options, service).catch((err) => {
|
|
642
|
-
errorResponse(
|
|
639
|
+
this.#errorResponse(service, bucket, err);
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
const handlerV1 = client.deleteObjects?.bind(this);
|
|
643
|
+
if (handlerV1) {
|
|
644
|
+
return handlerV1.call(this, credential, bucket, typeof options === 'boolean' ? { recursive: options } : options, service).catch((err) => {
|
|
645
|
+
this.#errorResponse(service, bucket, err);
|
|
643
646
|
});
|
|
644
647
|
}
|
|
645
|
-
const recursive =
|
|
648
|
+
const recursive = isObject(options) ? options.recursive : options;
|
|
646
649
|
const handlerV2 = client.deleteObjectsV2?.bind(this);
|
|
647
650
|
if (handlerV2) {
|
|
648
651
|
return handlerV2.call(this, credential, bucket, recursive ?? true, service).catch((err) => {
|
|
649
|
-
errorResponse(
|
|
652
|
+
this.#errorResponse(service, bucket, err);
|
|
650
653
|
});
|
|
651
654
|
}
|
|
652
|
-
|
|
653
|
-
if (handlerV1) {
|
|
654
|
-
return handlerV1.call(this, credential, bucket, service, undefined, recursive).catch((err) => {
|
|
655
|
-
errorResponse(this, service, bucket, err);
|
|
656
|
-
});
|
|
657
|
-
}
|
|
658
|
-
throw (0, types_1.errorMessage)(service, "Delete objects not supported");
|
|
655
|
+
throw errorMessage(service, "Delete objects not supported");
|
|
659
656
|
}
|
|
660
657
|
async copyObject(service, credential, bucketSource, keySource, bucket, key, options) {
|
|
661
658
|
if (this.aborted) {
|
|
662
|
-
return
|
|
659
|
+
return createAbortError(true);
|
|
663
660
|
}
|
|
664
661
|
const handler = this.getClient(service).copyObject?.bind(this);
|
|
665
662
|
if (handler) {
|
|
666
663
|
return handler.call(this, credential, bucketSource, keySource, bucket, key, options, service).catch((err) => {
|
|
667
|
-
errorResponse(
|
|
664
|
+
this.#errorResponse(service, bucket, err);
|
|
668
665
|
});
|
|
669
666
|
}
|
|
670
|
-
throw
|
|
667
|
+
throw errorMessage(service, "Copy object not supported");
|
|
671
668
|
}
|
|
672
669
|
async uploadObject(service, credential, bucket, upload, localUri, beforeResolve) {
|
|
673
670
|
if (this.aborted) {
|
|
674
|
-
return
|
|
671
|
+
return createAbortError(true);
|
|
675
672
|
}
|
|
676
673
|
try {
|
|
677
674
|
const handler = this.getUploadHandler(service, credential).bind(this);
|
|
@@ -681,7 +678,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
681
678
|
if (err) {
|
|
682
679
|
reject(errorObject(err, service, "Upload failed"));
|
|
683
680
|
}
|
|
684
|
-
else if (
|
|
681
|
+
else if (isString(value)) {
|
|
685
682
|
if (beforeResolve) {
|
|
686
683
|
await beforeResolve(value);
|
|
687
684
|
}
|
|
@@ -690,21 +687,21 @@ class Cloud extends core_1.ClientDb {
|
|
|
690
687
|
resolve(value);
|
|
691
688
|
}
|
|
692
689
|
else {
|
|
693
|
-
reject(
|
|
690
|
+
reject(errorMessage(service, "Upload failed"));
|
|
694
691
|
}
|
|
695
692
|
});
|
|
696
693
|
});
|
|
697
694
|
}
|
|
698
695
|
catch (err) {
|
|
699
|
-
this.formatMessage(64, service, ["Upload function not supported", bucket], localUri,
|
|
696
|
+
this.formatMessage(64, service, ["Upload function not supported", bucket], localUri, _a.optionsLogMessage('WARN'));
|
|
700
697
|
throw err;
|
|
701
698
|
}
|
|
702
699
|
}
|
|
703
700
|
async downloadObject(service, credential, bucket, download, beforeResolve) {
|
|
704
701
|
if (this.aborted) {
|
|
705
|
-
return
|
|
702
|
+
return createAbortError(true);
|
|
706
703
|
}
|
|
707
|
-
if ((service === 'gcp' || service === 'gcloud') &&
|
|
704
|
+
if ((service === 'gcp' || service === 'gcloud') && isPlainObject(credential)) {
|
|
708
705
|
credential.storageBucket ||= bucket;
|
|
709
706
|
}
|
|
710
707
|
try {
|
|
@@ -717,30 +714,30 @@ class Cloud extends core_1.ClientDb {
|
|
|
717
714
|
else if (value) {
|
|
718
715
|
if (beforeResolve) {
|
|
719
716
|
const output = await beforeResolve(value);
|
|
720
|
-
if (
|
|
717
|
+
if (isString(output)) {
|
|
721
718
|
value = output;
|
|
722
719
|
}
|
|
723
720
|
}
|
|
724
|
-
if (
|
|
721
|
+
if (isString(value) && path.isAbsolute(value)) {
|
|
725
722
|
this.addLog(4, 'downloadObject: ' + bucket, service, value);
|
|
726
723
|
this.downloaded.push(value);
|
|
727
724
|
}
|
|
728
725
|
resolve(value);
|
|
729
726
|
}
|
|
730
727
|
else {
|
|
731
|
-
reject(
|
|
728
|
+
reject(errorMessage(service, "Download failed"));
|
|
732
729
|
}
|
|
733
730
|
});
|
|
734
731
|
});
|
|
735
732
|
}
|
|
736
733
|
catch (err) {
|
|
737
|
-
this.formatMessage(64, service, ["Download function not supported", bucket],
|
|
734
|
+
this.formatMessage(64, service, ["Download function not supported", bucket], _a.joinPath(download.pathname, download.filename), _a.optionsLogMessage('WARN'));
|
|
738
735
|
throw err;
|
|
739
736
|
}
|
|
740
737
|
}
|
|
741
738
|
async getDatabaseRows(item, ignoreErrors, sessionKey) {
|
|
742
739
|
if (this.aborted) {
|
|
743
|
-
return
|
|
740
|
+
return createAbortError(true);
|
|
744
741
|
}
|
|
745
742
|
if (typeof ignoreErrors === 'string') {
|
|
746
743
|
sessionKey = ignoreErrors;
|
|
@@ -752,7 +749,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
752
749
|
if (client?.executeQuery) {
|
|
753
750
|
const credential = this.getCredential(item);
|
|
754
751
|
if (item.options && this.hasCoerce(service, 'options', credential)) {
|
|
755
|
-
|
|
752
|
+
coerceObject(item.options);
|
|
756
753
|
}
|
|
757
754
|
if (ignoreErrors) {
|
|
758
755
|
return client.executeQuery.call(this, credential, item, sessionKey);
|
|
@@ -761,17 +758,17 @@ class Cloud extends core_1.ClientDb {
|
|
|
761
758
|
return await client.executeQuery.call(this, credential, item, sessionKey);
|
|
762
759
|
}
|
|
763
760
|
catch (err) {
|
|
764
|
-
this.formatFail(64, service, "Unable to execute query", err,
|
|
761
|
+
this.formatFail(64, service, "Unable to execute query", err, _a.optionsLogMessage('FAIL'));
|
|
765
762
|
throw err;
|
|
766
763
|
}
|
|
767
764
|
}
|
|
768
|
-
throw
|
|
765
|
+
throw errorMessage(service, "Execute query not supported");
|
|
769
766
|
}
|
|
770
|
-
throw
|
|
767
|
+
throw errorMessage(service, "Invalid credentials");
|
|
771
768
|
}
|
|
772
769
|
async getDatabaseBatchRows(batch, ignoreErrors, sessionKey) {
|
|
773
770
|
if (this.aborted) {
|
|
774
|
-
return
|
|
771
|
+
return createAbortError(true);
|
|
775
772
|
}
|
|
776
773
|
if (typeof ignoreErrors === 'string') {
|
|
777
774
|
sessionKey = ignoreErrors;
|
|
@@ -786,7 +783,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
786
783
|
if (this.hasCoerce(service, 'options', credential)) {
|
|
787
784
|
for (const item of batch) {
|
|
788
785
|
if (item.options) {
|
|
789
|
-
|
|
786
|
+
coerceObject(item.options);
|
|
790
787
|
}
|
|
791
788
|
}
|
|
792
789
|
}
|
|
@@ -797,28 +794,28 @@ class Cloud extends core_1.ClientDb {
|
|
|
797
794
|
return await client.executeBatchQuery.call(this, credential, batch, sessionKey);
|
|
798
795
|
}
|
|
799
796
|
catch (err) {
|
|
800
|
-
this.formatFail(64, service, "Unable to execute query", err,
|
|
797
|
+
this.formatFail(64, service, "Unable to execute query", err, _a.optionsLogMessage('FAIL'));
|
|
801
798
|
throw err;
|
|
802
799
|
}
|
|
803
800
|
}
|
|
804
|
-
throw
|
|
801
|
+
throw errorMessage(service, "Execute query not supported");
|
|
805
802
|
}
|
|
806
|
-
throw
|
|
803
|
+
throw errorMessage(service, "Invalid credentials");
|
|
807
804
|
}
|
|
808
805
|
getCredential(item, unused) {
|
|
809
806
|
const service = item.service;
|
|
810
807
|
let credential = item.credential, stored = false;
|
|
811
808
|
if (typeof credential === 'string') {
|
|
812
809
|
const settings = this.getSettings(service);
|
|
813
|
-
if (
|
|
810
|
+
if (isPlainObject(settings)) {
|
|
814
811
|
credential = settings[credential];
|
|
815
812
|
stored = true;
|
|
816
813
|
}
|
|
817
814
|
}
|
|
818
|
-
if (
|
|
815
|
+
if (isPlainObject(credential)) {
|
|
819
816
|
item.credential = credential;
|
|
820
817
|
if (this.settingsOf(service, 'coerce', 'credential') === true) {
|
|
821
|
-
|
|
818
|
+
coerceObject(credential, stored);
|
|
822
819
|
}
|
|
823
820
|
return unused ? credential : { ...credential };
|
|
824
821
|
}
|
|
@@ -828,7 +825,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
828
825
|
return this.module[service];
|
|
829
826
|
}
|
|
830
827
|
getStorage(action, data) {
|
|
831
|
-
if (
|
|
828
|
+
if (isArray(data)) {
|
|
832
829
|
for (const item of data) {
|
|
833
830
|
const service = this.hasStorage(action, item);
|
|
834
831
|
if (service && service.active) {
|
|
@@ -863,7 +860,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
863
860
|
}
|
|
864
861
|
}
|
|
865
862
|
catch (err) {
|
|
866
|
-
this.formatFail(64, data.service, "Cloud provider not found", err,
|
|
863
|
+
this.formatFail(64, data.service, "Cloud provider not found", err, _a.optionsLogMessage('FAIL'));
|
|
867
864
|
}
|
|
868
865
|
return false;
|
|
869
866
|
}
|
|
@@ -876,7 +873,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
876
873
|
resolveService(service, folder) {
|
|
877
874
|
let result;
|
|
878
875
|
if (!service.startsWith('@')) {
|
|
879
|
-
result = this.settings.imports?.[service] ||
|
|
876
|
+
result = this.settings.imports?.[service] || IMPORT_MAP[service];
|
|
880
877
|
}
|
|
881
878
|
else {
|
|
882
879
|
folder ||= 'client';
|
|
@@ -885,11 +882,11 @@ class Cloud extends core_1.ClientDb {
|
|
|
885
882
|
}
|
|
886
883
|
settingsOf(service, name, component) {
|
|
887
884
|
const result = this.settings[service]?.[name];
|
|
888
|
-
return component ?
|
|
885
|
+
return component ? isObject(result) ? result[component] : undefined : result;
|
|
889
886
|
}
|
|
890
887
|
async commit() {
|
|
891
888
|
if (this.aborted) {
|
|
892
|
-
return
|
|
889
|
+
return createAbortError(true);
|
|
893
890
|
}
|
|
894
891
|
const items = this.pending.filter(item => !item.document).map(async (data) => {
|
|
895
892
|
data.ignoreCache ??= true;
|
|
@@ -909,9 +906,15 @@ class Cloud extends core_1.ClientDb {
|
|
|
909
906
|
return client;
|
|
910
907
|
}
|
|
911
908
|
}
|
|
912
|
-
catch {
|
|
909
|
+
catch (err) {
|
|
910
|
+
this.addLog(3, err, service);
|
|
913
911
|
}
|
|
914
|
-
throw service ?
|
|
912
|
+
throw service ? errorMessage(service, "Cloud provider not found") : errorValue("Cloud provider not found");
|
|
913
|
+
}
|
|
914
|
+
#errorResponse(service, bucket, err) {
|
|
915
|
+
this.formatMessage(64, service, ["Unable to empty bucket", bucket], err, _a.optionsLogMessage('WARN'));
|
|
915
916
|
}
|
|
916
917
|
}
|
|
918
|
+
_a = Cloud;
|
|
919
|
+
|
|
917
920
|
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.14.0",
|
|
4
4
|
"description": "Cloud constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"license": "BSD-3-Clause",
|
|
20
20
|
"homepage": "https://github.com/anpham6/e-mc#readme",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@e-mc/core": "0.
|
|
23
|
-
"@e-mc/db": "0.
|
|
24
|
-
"@e-mc/types": "0.
|
|
22
|
+
"@e-mc/core": "0.14.0",
|
|
23
|
+
"@e-mc/db": "0.14.0",
|
|
24
|
+
"@e-mc/types": "0.14.0",
|
|
25
25
|
"mime-types": "^3.0.2"
|
|
26
26
|
}
|
|
27
27
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -18,10 +18,11 @@ export interface ICloudServiceClient<T extends CloudDatabase = CloudDatabase, U
|
|
|
18
18
|
setBucketPolicy?(this: IModule, credential: U, bucket: string, options: unknown, service?: string, sdk?: string): Promise<boolean>;
|
|
19
19
|
setBucketTagging?(this: IModule, credential: U, bucket: string, options: unknown, service?: string, sdk?: string): Promise<boolean>;
|
|
20
20
|
setBucketWebsite?(this: IModule, credential: U, bucket: string, options: BucketWebsiteOptions, service?: string, sdk?: string): Promise<boolean>;
|
|
21
|
-
|
|
22
|
-
deleteObjects?(this: IModule, credential: U, bucket: string,
|
|
21
|
+
copyObject?(this: IModule, credential: U, bucketSource: string, keySource: string, bucket: string, key: string, options?: unknown, service?: string, sdk?: string): Promise<void>;
|
|
22
|
+
deleteObjects?(this: IModule, credential: U, bucket: string, options?: DeleteObjectsOptions, service?: string, sdk?: string): Promise<void>;
|
|
23
23
|
/** @deprecated */
|
|
24
24
|
deleteObjectsV2?(this: IModule, credential: U, bucket: string, recursive?: boolean, service?: string, sdk?: string): Promise<void>;
|
|
25
|
+
/** @deprecated */
|
|
25
26
|
deleteObjectsV3?(this: IModule, credential: U, bucket: string, options?: DeleteObjectsOptions, service?: string, sdk?: string): Promise<void>;
|
|
26
27
|
copyObject?(this: IModule, credential: U, bucketSource: string, keySource: string, bucket: string, key: string, options?: unknown, service?: string, sdk?: string): Promise<void>;
|
|
27
28
|
executeQuery?(this: ICloud, credential: V, data: T, sessionKey?: string): Promise<QueryResult>;
|
package/util.d.ts
CHANGED
|
@@ -5,8 +5,19 @@ import type { AuthValue } from '@e-mc/types/lib/http';
|
|
|
5
5
|
import type { Readable } from 'node:stream';
|
|
6
6
|
|
|
7
7
|
declare namespace util {
|
|
8
|
+
interface CreateKeyAndBodyOptions {
|
|
9
|
+
errorCallback?: FunctionReturn<void>;
|
|
10
|
+
descendantsGroup?: string[];
|
|
11
|
+
flags?: number;
|
|
12
|
+
chunkSize?: number;
|
|
13
|
+
mimeType?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
8
16
|
function readableAsBuffer(from: Readable): Promise<Buffer | null>;
|
|
9
|
-
function createKeyAndBody<T = Buffer>(filename: string, items: UploadContent[],
|
|
17
|
+
function createKeyAndBody<T = Buffer>(filename: string, items: UploadContent[], options: CreateKeyAndBodyOptions): [string[], T[], string[]];
|
|
18
|
+
function createKeyAndBody<T = Buffer>(filename: string, items: UploadContent[], errorCallback: FunctionReturn<void>, flags?: number): [string[], T[], string[]];
|
|
19
|
+
/** @deprecated options */
|
|
20
|
+
function createKeyAndBody<T = Buffer>(filename: string, items: UploadContent[], chunkSize?: number | string | FunctionReturn<void>, errorCallback?: FunctionReturn<void> | number, flags?: number, descendantsGroup?: string[]): [string[], T[], string[]];
|
|
10
21
|
function createErrorHandler(instance: IModule, service: string, bucket: string): (err: unknown) => void;
|
|
11
22
|
function generateFilename(filename: string): (i: number) => [string, boolean];
|
|
12
23
|
function getBasicAuth(auth: AuthValue): string;
|
package/util.js
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const path = require("node:path");
|
|
10
|
-
const fs = require("node:fs");
|
|
11
|
-
const stream = require("node:stream");
|
|
12
|
-
const mime = require("mime-types");
|
|
13
|
-
const types_1 = require("@e-mc/types");
|
|
14
|
-
const util_1 = require("@e-mc/db/util");
|
|
15
|
-
Object.defineProperty(exports, "getBasicAuth", { enumerable: true, get: function () { return util_1.getBasicAuth; } });
|
|
16
|
-
Object.defineProperty(exports, "hasBasicAuth", { enumerable: true, get: function () { return util_1.hasBasicAuth; } });
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const stream = require('node:stream');
|
|
6
|
+
const mime = require('mime-types');
|
|
7
|
+
const { errorMessage, incrementUUID, isObject, isPlainObject } = require('@e-mc/types');
|
|
8
|
+
const { getBasicAuth, hasBasicAuth } = require('@e-mc/db/util');
|
|
17
9
|
async function readableAsBuffer(from) {
|
|
18
10
|
return new Promise((resolve, reject) => {
|
|
19
11
|
let result = null;
|
|
20
|
-
from.on('data', chunk => {
|
|
12
|
+
from.on('data', (chunk) => {
|
|
21
13
|
if (!Buffer.isBuffer(chunk)) {
|
|
22
14
|
chunk = Buffer.from(chunk);
|
|
23
15
|
}
|
|
@@ -30,21 +22,26 @@ async function readableAsBuffer(from) {
|
|
|
30
22
|
.read();
|
|
31
23
|
});
|
|
32
24
|
}
|
|
33
|
-
function createKeyAndBody(filename, items, chunkSize = 0, errorCallback, flags = 0) {
|
|
25
|
+
function createKeyAndBody(filename, items, chunkSize = 0, errorCallback, flags = 0, descendantsGroup) {
|
|
34
26
|
let mimeType;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
errorCallback = chunkSize;
|
|
38
|
-
chunkSize = 0;
|
|
39
|
-
break;
|
|
40
|
-
case 'string':
|
|
41
|
-
mimeType = chunkSize;
|
|
42
|
-
chunkSize = 0;
|
|
43
|
-
break;
|
|
27
|
+
if (isPlainObject(chunkSize)) {
|
|
28
|
+
({ errorCallback, mimeType, descendantsGroup, chunkSize = 0, flags = 0 } = chunkSize);
|
|
44
29
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
else {
|
|
31
|
+
switch (typeof chunkSize) {
|
|
32
|
+
case 'function':
|
|
33
|
+
errorCallback = chunkSize;
|
|
34
|
+
chunkSize = 0;
|
|
35
|
+
break;
|
|
36
|
+
case 'string':
|
|
37
|
+
mimeType = chunkSize;
|
|
38
|
+
chunkSize = 0;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
if (typeof errorCallback === 'number') {
|
|
42
|
+
flags = errorCallback;
|
|
43
|
+
errorCallback = undefined;
|
|
44
|
+
}
|
|
48
45
|
}
|
|
49
46
|
const key = [];
|
|
50
47
|
const body = [];
|
|
@@ -105,9 +102,9 @@ function createKeyAndBody(filename, items, chunkSize = 0, errorCallback, flags =
|
|
|
105
102
|
}
|
|
106
103
|
if (target) {
|
|
107
104
|
const output = filename + ext;
|
|
108
|
-
key.push(
|
|
105
|
+
key.push(Array.isArray(descendantsGroup) && descendantsGroup.includes(ext) && localFile ? path.basename(localFile) : output);
|
|
109
106
|
body.push(target);
|
|
110
|
-
type.push(
|
|
107
|
+
type.push(type.length === 0 && mimeType ? mimeType : mime.lookup(output) || "application/octet-stream");
|
|
111
108
|
}
|
|
112
109
|
}
|
|
113
110
|
catch (err) {
|
|
@@ -134,20 +131,29 @@ function generateFilename(filename) {
|
|
|
134
131
|
const type = /\.[a-z0-9]+\.[a-z0-9]+$/i.exec(filename);
|
|
135
132
|
const j = type ? type.index : filename.lastIndexOf('.');
|
|
136
133
|
if (j !== -1) {
|
|
137
|
-
const match = /^(.+)_(\d+)$/.exec(basename = filename.
|
|
134
|
+
const match = /^(.+)_(\d+)$/.exec(basename = filename.slice(0, j));
|
|
138
135
|
if (match) {
|
|
139
136
|
basename = match[1];
|
|
140
137
|
i = parseInt(match[2]) + 1;
|
|
141
138
|
}
|
|
142
|
-
suffix = filename.
|
|
139
|
+
suffix = filename.slice(j);
|
|
143
140
|
}
|
|
144
141
|
}
|
|
145
|
-
return basename && suffix ? [basename + `_${i}` + suffix, true] : [
|
|
142
|
+
return basename && suffix ? [basename + `_${i}` + suffix, true] : [incrementUUID() + path.extname(filename), false];
|
|
146
143
|
};
|
|
147
144
|
}
|
|
148
145
|
function formatError(title, value, hint) {
|
|
149
|
-
if (
|
|
146
|
+
if (isObject(title)) {
|
|
150
147
|
title = title.service;
|
|
151
148
|
}
|
|
152
|
-
return
|
|
149
|
+
return errorMessage(typeof title === 'string' ? title : '', value, hint);
|
|
153
150
|
}
|
|
151
|
+
|
|
152
|
+
exports.createErrorHandler = createErrorHandler;
|
|
153
|
+
exports.createKeyAndBody = createKeyAndBody;
|
|
154
|
+
exports.formatError = formatError;
|
|
155
|
+
exports.generateFilename = generateFilename;
|
|
156
|
+
exports.getBasicAuth = getBasicAuth;
|
|
157
|
+
exports.hasBasicAuth = hasBasicAuth;
|
|
158
|
+
exports.intoArray = intoArray;
|
|
159
|
+
exports.readableAsBuffer = readableAsBuffer;
|