@e-mc/cloud 0.8.3 → 0.8.5
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/LICENSE +4 -8
- package/README.md +4 -4
- package/index.js +41 -31
- package/package.json +5 -5
- package/util.js +22 -23
package/LICENSE
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
Copyright
|
|
1
|
+
Copyright 2024 Mile Square Park
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
-
|
|
11
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -23,17 +23,19 @@ function hasSameBucket({ upload, service, bucket }, other) {
|
|
|
23
23
|
return (service && other.service || endpoint && endpoint === other.upload.endpoint) && bucket === other.bucket;
|
|
24
24
|
}
|
|
25
25
|
function getFiles(file, data) {
|
|
26
|
-
const
|
|
26
|
+
const localUri = file.localUri;
|
|
27
|
+
const grouped = [localUri && core_1.ClientDb.isPath(localUri, true) ? localUri : ''];
|
|
27
28
|
if (data.all) {
|
|
28
|
-
const individual = new Set();
|
|
29
|
-
if (!file.cloudUrl) {
|
|
30
|
-
file.transforms?.forEach(value => individual.add(value));
|
|
31
|
-
}
|
|
32
|
-
file.torrentFiles?.forEach(value => individual.add(value));
|
|
33
29
|
if (file.descendants) {
|
|
34
30
|
grouped.push(...file.descendants);
|
|
35
31
|
}
|
|
36
|
-
|
|
32
|
+
const individual = !file.cloudUrl && file.transforms || [];
|
|
33
|
+
if (file.torrentFiles) {
|
|
34
|
+
individual.push(...file.torrentFiles);
|
|
35
|
+
}
|
|
36
|
+
if (individual.length) {
|
|
37
|
+
return [grouped, Array.from(new Set(individual))];
|
|
38
|
+
}
|
|
37
39
|
}
|
|
38
40
|
return [grouped];
|
|
39
41
|
}
|
|
@@ -161,7 +163,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
161
163
|
}
|
|
162
164
|
}
|
|
163
165
|
for (const [item, data] of localStorage) {
|
|
164
|
-
getFiles(item, data).forEach(group => group.forEach(value => this.deleteFile(value, { emptyDir: true })));
|
|
166
|
+
getFiles(item, data).forEach(group => group.forEach(value => value && this.deleteFile(value, { emptyDir: true })));
|
|
165
167
|
}
|
|
166
168
|
for (const item of this.assets) {
|
|
167
169
|
const cloudStorage = item.cloudStorage;
|
|
@@ -172,12 +174,11 @@ class Cloud extends core_1.ClientDb {
|
|
|
172
174
|
}
|
|
173
175
|
const download = data.download;
|
|
174
176
|
const { pathname, filename, waitStatus, overwrite } = download;
|
|
175
|
-
let active = download.active;
|
|
176
177
|
if (!filename) {
|
|
177
178
|
continue;
|
|
178
179
|
}
|
|
179
180
|
const localUri = item.localUri;
|
|
180
|
-
let downloadUri;
|
|
181
|
+
let active = download.active, downloadUri;
|
|
181
182
|
if (pathname && path.isAbsolute(pathname)) {
|
|
182
183
|
downloadUri = path.join(pathname, filename);
|
|
183
184
|
if (!Cloud.isPath(downloadUri) && !this.canWrite(pathname)) {
|
|
@@ -196,6 +197,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
196
197
|
active = true;
|
|
197
198
|
}
|
|
198
199
|
else if (!Cloud.createDir(destDir)) {
|
|
200
|
+
instance.writeFail(["Unable to create directory" /* ERR_MESSAGE.CREATE_DIRECTORY */, filename], (0, types_1.errorValue)("Path is not a directory" /* ERR_MESSAGE.NOT_DIRECTORY */, destDir), { type: 64 /* LOG_TYPE.CLOUD */, fatal: !!active, startTime });
|
|
199
201
|
continue;
|
|
200
202
|
}
|
|
201
203
|
else if (active) {
|
|
@@ -269,16 +271,17 @@ class Cloud extends core_1.ClientDb {
|
|
|
269
271
|
contentType = file.mimeType;
|
|
270
272
|
}
|
|
271
273
|
const { host, instance } = state;
|
|
272
|
-
|
|
274
|
+
const cloudStorage = file.cloudStorage;
|
|
275
|
+
if (instance.aborted || !Array.isArray(cloudStorage)) {
|
|
273
276
|
return [];
|
|
274
277
|
}
|
|
275
278
|
const tasks = [];
|
|
276
|
-
for (const storage of
|
|
279
|
+
for (const storage of cloudStorage) {
|
|
277
280
|
if (!instance.hasStorage('upload', storage)) {
|
|
278
281
|
continue;
|
|
279
282
|
}
|
|
280
283
|
const upload = storage.upload;
|
|
281
|
-
const active = storage === instance.getStorage('upload',
|
|
284
|
+
const active = storage === instance.getStorage('upload', cloudStorage);
|
|
282
285
|
if (active && upload.localStorage === false) {
|
|
283
286
|
state.localStorage.set(file, upload);
|
|
284
287
|
}
|
|
@@ -301,30 +304,37 @@ class Cloud extends core_1.ClientDb {
|
|
|
301
304
|
const uploading = [];
|
|
302
305
|
getFiles(file, upload).forEach(async (group, index) => {
|
|
303
306
|
let fileGroup;
|
|
304
|
-
if (index === 0
|
|
305
|
-
if (
|
|
306
|
-
|
|
307
|
+
if (index === 0) {
|
|
308
|
+
if (!group[0]) {
|
|
309
|
+
instance.writeFail("Unable to read file" /* ERR_MESSAGE.READ_FILE */, (0, types_1.errorValue)("File not found" /* ERR_MESSAGE.NOTFOUND_FILE */, service), { type: 64 /* LOG_TYPE.CLOUD */, fatal: true });
|
|
310
|
+
return;
|
|
307
311
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
312
|
+
if (group.length > 1) {
|
|
313
|
+
if (SERVICE_CLIENT.get(service)?.CLOUD_UPLOAD_FROMDISK) {
|
|
314
|
+
fileGroup = group.slice(1).filter(value => this.isPath(value, true)).map(value => [value, path.extname(value), value]);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
fileGroup = [];
|
|
318
|
+
for (let i = 1; i < group.length; ++i) {
|
|
319
|
+
const value = group[i];
|
|
320
|
+
if (this.isPath(value, true)) {
|
|
321
|
+
try {
|
|
322
|
+
fileGroup.push([typeof minStreamSize === 'number' ? await this.streamFile(value, { minStreamSize, cache: false, signal: instance.signal }) : fs.readFileSync(value), path.extname(value), value]);
|
|
323
|
+
}
|
|
324
|
+
catch (err) {
|
|
325
|
+
instance.writeFail(["Unable to read file" /* ERR_MESSAGE.READ_FILE */, path.basename(value)], err, { type: 32 /* LOG_TYPE.FILE */, fatal: false });
|
|
326
|
+
}
|
|
315
327
|
}
|
|
316
328
|
}
|
|
317
|
-
catch (err) {
|
|
318
|
-
instance.writeFail(["Unable to read file" /* ERR_MESSAGE.READ_FILE */, path.basename(value)], err, { type: 32 /* LOG_TYPE.FILE */, fatal: false });
|
|
319
|
-
}
|
|
320
329
|
}
|
|
330
|
+
group = [group[0]];
|
|
321
331
|
}
|
|
322
|
-
group = [group[0]];
|
|
323
332
|
}
|
|
324
|
-
for (
|
|
325
|
-
const
|
|
333
|
+
for (let i = 0; i < group.length; ++i) {
|
|
334
|
+
const localUri = group[i];
|
|
335
|
+
const exists = index === 0 || this.isPath(localUri, true);
|
|
326
336
|
if (!exists || !instance.canRead(localUri, { ownPermissionOnly: true })) {
|
|
327
|
-
instance.writeFail(["Unable to read file" /* ERR_MESSAGE.READ_FILE */, path.basename(localUri)], (0, types_1.errorValue)(exists ? "Not permitted to read file" /* ERR_MESSAGE.UNSUPPORTED_READ */ : "File not found" /* ERR_MESSAGE.NOTFOUND_FILE */, localUri), { type: 64 /* LOG_TYPE.CLOUD */, fatal: index === 0 });
|
|
337
|
+
instance.writeFail(["Unable to read file" /* ERR_MESSAGE.READ_FILE */, path.basename(localUri)], (0, types_1.errorValue)(exists ? "Not permitted to read file" /* ERR_MESSAGE.UNSUPPORTED_READ */ : "File not found" /* ERR_MESSAGE.NOTFOUND_FILE */, localUri), { type: 64 /* LOG_TYPE.CLOUD */, fatal: i === 0 && index === 0 });
|
|
328
338
|
continue;
|
|
329
339
|
}
|
|
330
340
|
let buffer, filename;
|
|
@@ -348,7 +358,7 @@ class Cloud extends core_1.ClientDb {
|
|
|
348
358
|
options.contentType = contentType;
|
|
349
359
|
}
|
|
350
360
|
uploading.push(instance.uploadObject(service, { ...credential }, bucket, options, localUri, callback)
|
|
351
|
-
.catch(err => instance.writeFail(["Upload failed" /* ERR_CLOUD.UPLOAD_FAIL */, path.basename(localUri)], err, { type: 64 /* LOG_TYPE.CLOUD */, fatal: index === 0 })));
|
|
361
|
+
.catch(err => instance.writeFail(["Upload failed" /* ERR_CLOUD.UPLOAD_FAIL */, path.basename(localUri)], err, { type: 64 /* LOG_TYPE.CLOUD */, fatal: i === 0 && index === 0 })));
|
|
352
362
|
}
|
|
353
363
|
});
|
|
354
364
|
instance.allSettled(uploading, [`Upload file "${contentType || "Unknown" /* ERR_MESSAGE.UNKNOWN */}"`, storage.service + ': ' + path.basename(file.localUri)]).then(() => resolve());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/cloud",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"description": "Cloud constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
"squared-functions"
|
|
18
18
|
],
|
|
19
19
|
"author": "An Pham <anpham6@gmail.com>",
|
|
20
|
-
"license": "
|
|
20
|
+
"license": "MIT",
|
|
21
21
|
"homepage": "https://github.com/anpham6/e-mc#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/core": "0.8.
|
|
24
|
-
"@e-mc/db": "0.8.
|
|
25
|
-
"@e-mc/types": "0.8.
|
|
23
|
+
"@e-mc/core": "0.8.5",
|
|
24
|
+
"@e-mc/db": "0.8.5",
|
|
25
|
+
"@e-mc/types": "0.8.5",
|
|
26
26
|
"mime-types": "^2.1.35"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/util.js
CHANGED
|
@@ -42,32 +42,30 @@ function createKeyAndBody(filename, items, mimeType, errorCallback) {
|
|
|
42
42
|
const body = [];
|
|
43
43
|
const type = [];
|
|
44
44
|
for (let [content, ext, localFile] of items) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
case 'object':
|
|
59
|
-
break;
|
|
60
|
-
default:
|
|
61
|
-
continue;
|
|
45
|
+
let buffer;
|
|
46
|
+
if (typeof content === 'string') {
|
|
47
|
+
try {
|
|
48
|
+
if (content === localFile || fs.existsSync(content)) {
|
|
49
|
+
buffer = fs.readFileSync(content);
|
|
50
|
+
localFile = content;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
buffer = Buffer.from(content);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
errorCallback?.(err);
|
|
62
58
|
}
|
|
59
|
+
}
|
|
60
|
+
else if (Buffer.isBuffer(content)) {
|
|
61
|
+
buffer = content;
|
|
62
|
+
}
|
|
63
|
+
if (buffer) {
|
|
63
64
|
const output = filename + ext;
|
|
64
65
|
key.push(ext === '.map' && localFile ? path.basename(localFile) : output);
|
|
65
|
-
body.push(
|
|
66
|
+
body.push(buffer);
|
|
66
67
|
type.push(ext !== '.map' && mime.lookup(output) || mimeType || 'application/octet-stream');
|
|
67
68
|
}
|
|
68
|
-
catch (err) {
|
|
69
|
-
errorCallback?.(err);
|
|
70
|
-
}
|
|
71
69
|
}
|
|
72
70
|
return [key, body, type];
|
|
73
71
|
}
|
|
@@ -76,9 +74,10 @@ function generateFilename(filename) {
|
|
|
76
74
|
let basename, suffix;
|
|
77
75
|
return (i) => {
|
|
78
76
|
if (i === 1) {
|
|
79
|
-
const
|
|
77
|
+
const type = /\.[a-z0-9]+\.[a-z0-9]+$/i.exec(filename);
|
|
78
|
+
const j = type ? type.index : filename.lastIndexOf('.');
|
|
80
79
|
if (j !== -1) {
|
|
81
|
-
const match = /^(
|
|
80
|
+
const match = /^(.+)_(\d+)$/.exec(basename = filename.substring(0, j));
|
|
82
81
|
if (match) {
|
|
83
82
|
basename = match[1];
|
|
84
83
|
i = parseInt(match[2]) + 1;
|