@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 CHANGED
@@ -1,11 +1,7 @@
1
- Copyright 2023 An Pham
1
+ Copyright 2024 Mile Square Park
2
2
 
3
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
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
- 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
6
 
7
- 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
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
@@ -1,7 +1,7 @@
1
- ### @e-mc/cloud
1
+ # @e-mc/cloud
2
2
 
3
- https://e-mc.readthedocs.io
3
+ PEP 402
4
4
 
5
- ### LICENSE
5
+ ## LICENSE
6
6
 
7
- BSD 3-Clause
7
+ MIT
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 grouped = file.localUri ? [file.localUri] : [];
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
- return [grouped, Array.from(individual)];
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
- if (instance.aborted) {
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 file.cloudStorage) {
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', file.cloudStorage);
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 && group.length > 1) {
305
- if (SERVICE_CLIENT.get(service)?.CLOUD_UPLOAD_FROMDISK) {
306
- fileGroup = group.slice(1).filter(value => this.isPath(value)).map(value => [value, path.extname(value), value]);
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
- else {
309
- fileGroup = [];
310
- for (let i = 1; i < group.length; ++i) {
311
- const value = group[i];
312
- try {
313
- if (fs.existsSync(value)) {
314
- fileGroup.push([typeof minStreamSize === 'number' ? await this.streamFile(value, { minStreamSize, cache: false, signal: instance.signal }) : fs.readFileSync(value), path.extname(value), value]);
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 (const localUri of group) {
325
- const exists = this.isPath(localUri);
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",
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": "BSD 3-Clause",
20
+ "license": "MIT",
21
21
  "homepage": "https://github.com/anpham6/e-mc#readme",
22
22
  "dependencies": {
23
- "@e-mc/core": "0.8.3",
24
- "@e-mc/db": "0.8.3",
25
- "@e-mc/types": "0.8.3",
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
- try {
46
- switch (typeof content) {
47
- case 'string':
48
- if (fs.existsSync(content)) {
49
- content = fs.readFileSync(content);
50
- }
51
- else if (path.isAbsolute(content)) {
52
- continue;
53
- }
54
- else {
55
- content = Buffer.from(content);
56
- }
57
- break;
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(content);
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 j = filename.indexOf('.');
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 = /^([\S\s]+?)_(\d+)$/.exec(basename = filename.substring(0, j));
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;