@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @e-mc/cloud
2
2
 
3
- * NodeJS 18.20 LTS
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.13.9/lib/index.d.ts)
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.13.9/lib/asset.d.ts
184
- - https://www.unpkg.com/@e-mc/types@0.13.9/lib/cloud.d.ts
185
- - https://www.unpkg.com/@e-mc/types@0.13.9/lib/core.d.ts
186
- - https://www.unpkg.com/@e-mc/types@0.13.9/lib/db.d.ts
187
- - https://www.unpkg.com/@e-mc/types@0.13.9/lib/logger.d.ts
188
- - https://www.unpkg.com/@e-mc/types@0.13.9/lib/settings.d.ts
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
- const path = require("node:path");
3
- const fs = require("node:fs");
4
- const crypto = require("node:crypto");
5
- const types_1 = require("@e-mc/types");
6
- const core_1 = require("@e-mc/core");
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.substring(0, index + 1);
17
+ const directory = filename.slice(0, index + 1);
16
18
  upload.pathname = upload.pathname ? Cloud.joinPath(upload.pathname, directory) : directory;
17
- filename = filename.substring(index + 1);
19
+ filename = filename.slice(index + 1);
18
20
  }
19
21
  return upload.filename = filename;
20
22
  }
21
- function hasSameBucket({ upload, service, bucket }, other) {
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 && core_1.ClientDb.isPath(localUri, true) ? 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.substring(0, index) : value) + '_' + map[location]++ + (index !== -1 ? value.substring(index) : '');
48
+ item.filename = (index !== -1 ? value.slice(0, index) : value) + '_' + map[location]++ + (index !== -1 ? value.slice(index) : '');
47
49
  }
48
- function errorResponse(instance, service, bucket, err) {
49
- instance.formatMessage(64, service, ["Unable to empty bucket", bucket], err, Cloud.optionsLogMessage('WARN'));
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 = core_1.ClientDb.LOG_STYLE_SUCCESS;
58
- static LOG_CLOUD_FAIL = core_1.ClientDb.LOG_STYLE_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 (0, types_1.createAbortError)(true);
89
+ return createAbortError(true);
91
90
  }
92
- Cloud.sanitizeAssets(this.assets);
91
+ _a.sanitizeAssets(this.assets);
93
92
  const localStorage = new Map();
94
- const bucketGroup = crypto.randomUUID();
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, Cloud.optionsLogMessage('SUCCESS'));
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 ((0, types_1.isArray)(cloudStorage) && !(0, types_1.ignoreFlag)(item)) {
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], (0, types_1.errorValue)("File not found", item.uri || item.filename || "Unknown"), Cloud.optionsLogMessage('WARN'));
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 = (0, types_1.isObject)(admin.emptyBucket) ? admin.emptyBucket : undefined;
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 (0, types_1.createAbortError)(true);
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 (0, types_1.createAbortError)(true);
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(...Cloud.uploadAsset(state, item, options));
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 (0, types_1.createAbortError)(true);
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 (0, types_1.createAbortError)(true);
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 (0, types_1.createAbortError)(true);
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 ((0, types_1.isArray)(cloudStorage) && !(0, types_1.ignoreFlag)(item)) {
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 (!Cloud.isPath(downloadUri) && !this.canWrite(pathname)) {
262
- instance.writeFail(["Unable to download file", filename], (0, types_1.errorValue)("Unsupported access", pathname), { type: 64, fatal: !!active, startTime });
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 (Cloud.isPath(downloadUri)) {
269
+ if (_a.isPath(downloadUri)) {
271
270
  if (!active && !overwrite) {
272
271
  continue;
273
272
  }
274
273
  active = true;
275
274
  }
276
- else if (!Cloud.createDir(destDir)) {
277
- instance.writeFail(["Unable to create directory", filename], (0, types_1.errorValue)("Path is not a directory", destDir), { type: 64, fatal: !!active, startTime });
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 && (0, types_1.alignSize)(download.chunkSize) > 0 ? 4 : 0;
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", (0, types_1.formatSize)(size)], destUri, Cloud.optionsLogMessage('DOWNLOAD'));
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 && (0, types_1.isErrorCode)(err, 'EXDEV')) {
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 ((0, types_1.isObject)(contentType)) {
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 && (0, types_1.alignSize)(upload.chunkSize) > 0) {
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 = (0, types_1.alignSize)(upload.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", (0, types_1.errorValue)("File not found", service), { type: 64, fatal: true });
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)], (0, types_1.errorValue)(!exists ? "File not found" : "Not permitted to read file", localUri), { type: 64, fatal: i === 0 && index === 0 });
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 ((0, types_1.isArray)(cloudStorage) && !(0, types_1.ignoreFlag)(item)) {
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 (!trailing) {
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
- for (let j = 0; j < length - 1; ++j) {
517
- const previous = storage[j];
518
- if (current === previous) {
519
- continue;
520
- }
521
- for (const other of previous.cloudStorage) {
522
- const leading = other.upload;
523
- if (leading && hasSameBucket(data, other)) {
524
- const leadingFolder = leading.pathname || '';
525
- if (basename && basename === leading.filename && leadingFolder === trailingFolder) {
526
- renameTrailing(nameIndex, trailing, trailingFolder, basename);
527
- break renamed;
528
- }
529
- const leadingName = this.joinPath(leadingFolder, leading.filename || previous.filename);
530
- if (trailingName === leadingName) {
531
- if (!trailing.overwrite || leading.overwrite) {
532
- renameTrailing(nameIndex, trailing, trailingFolder, filename);
533
- break renamed;
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 (0, types_1.createAbortError)(true);
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, Cloud.optionsLogMessage('WARN'));
578
+ this.formatMessage(64, service, ["Unable to create bucket", bucket], err, _a.optionsLogMessage('WARN'));
582
579
  throw err;
583
580
  }
584
- throw (0, types_1.errorMessage)(service, "Create bucket not supported");
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 (0, types_1.createAbortError)(true);
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, Cloud.optionsLogMessage('WARN'));
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 (0, types_1.errorMessage)(service, "Bucket policy not supported");
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 (0, types_1.createAbortError)(true);
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, Cloud.optionsLogMessage('WARN'));
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 (0, types_1.errorMessage)(service, "Bucket tagging not supported");
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 (0, types_1.createAbortError)(true);
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, Cloud.optionsLogMessage('WARN'));
625
+ this.formatMessage(64, service, ["Unable to configure bucket", bucket], err, _a.optionsLogMessage('WARN'));
629
626
  throw err;
630
627
  }
631
628
  }
632
- throw (0, types_1.errorMessage)(service, "Set bucket website not supported");
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 (0, types_1.createAbortError)(true);
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(this, service, bucket, err);
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 = (0, types_1.isObject)(options) ? options.recursive : options;
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(this, service, bucket, err);
652
+ this.#errorResponse(service, bucket, err);
650
653
  });
651
654
  }
652
- const handlerV1 = client.deleteObjects?.bind(this);
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 (0, types_1.createAbortError)(true);
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(this, service, bucket, err);
664
+ this.#errorResponse(service, bucket, err);
668
665
  });
669
666
  }
670
- throw (0, types_1.errorMessage)(service, "Copy object not supported");
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 (0, types_1.createAbortError)(true);
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 ((0, types_1.isString)(value)) {
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((0, types_1.errorMessage)(service, "Upload failed"));
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, Cloud.optionsLogMessage('WARN'));
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 (0, types_1.createAbortError)(true);
702
+ return createAbortError(true);
706
703
  }
707
- if ((service === 'gcp' || service === 'gcloud') && (0, types_1.isPlainObject)(credential)) {
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 ((0, types_1.isString)(output)) {
717
+ if (isString(output)) {
721
718
  value = output;
722
719
  }
723
720
  }
724
- if ((0, types_1.isString)(value) && path.isAbsolute(value)) {
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((0, types_1.errorMessage)(service, "Download failed"));
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], Cloud.joinPath(download.pathname, download.filename), Cloud.optionsLogMessage('WARN'));
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 (0, types_1.createAbortError)(true);
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
- (0, types_1.coerceObject)(item.options);
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, Cloud.optionsLogMessage('FAIL'));
761
+ this.formatFail(64, service, "Unable to execute query", err, _a.optionsLogMessage('FAIL'));
765
762
  throw err;
766
763
  }
767
764
  }
768
- throw (0, types_1.errorMessage)(service, "Execute query not supported");
765
+ throw errorMessage(service, "Execute query not supported");
769
766
  }
770
- throw (0, types_1.errorMessage)(service, "Invalid credentials");
767
+ throw errorMessage(service, "Invalid credentials");
771
768
  }
772
769
  async getDatabaseBatchRows(batch, ignoreErrors, sessionKey) {
773
770
  if (this.aborted) {
774
- return (0, types_1.createAbortError)(true);
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
- (0, types_1.coerceObject)(item.options);
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, Cloud.optionsLogMessage('FAIL'));
797
+ this.formatFail(64, service, "Unable to execute query", err, _a.optionsLogMessage('FAIL'));
801
798
  throw err;
802
799
  }
803
800
  }
804
- throw (0, types_1.errorMessage)(service, "Execute query not supported");
801
+ throw errorMessage(service, "Execute query not supported");
805
802
  }
806
- throw (0, types_1.errorMessage)(service, "Invalid credentials");
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 ((0, types_1.isPlainObject)(settings)) {
810
+ if (isPlainObject(settings)) {
814
811
  credential = settings[credential];
815
812
  stored = true;
816
813
  }
817
814
  }
818
- if ((0, types_1.isPlainObject)(credential)) {
815
+ if (isPlainObject(credential)) {
819
816
  item.credential = credential;
820
817
  if (this.settingsOf(service, 'coerce', 'credential') === true) {
821
- (0, types_1.coerceObject)(credential, stored);
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 ((0, types_1.isArray)(data)) {
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, Cloud.optionsLogMessage('FAIL'));
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] || types_1.IMPORT_MAP[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 ? (0, types_1.isObject)(result) ? result[component] : undefined : result;
885
+ return component ? isObject(result) ? result[component] : undefined : result;
889
886
  }
890
887
  async commit() {
891
888
  if (this.aborted) {
892
- return (0, types_1.createAbortError)(true);
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 ? (0, types_1.errorMessage)(service, "Cloud provider not found") : (0, types_1.errorValue)("Cloud provider not found");
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.13.9",
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.13.9",
23
- "@e-mc/db": "0.13.9",
24
- "@e-mc/types": "0.13.9",
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
- /** @deprecated */
22
- deleteObjects?(this: IModule, credential: U, bucket: string, service?: string, sdk?: string, recursive?: boolean): Promise<void>;
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[], chunkSize?: number | string | FunctionType<void>, errorCallback?: FunctionType<void> | number, flags?: number): [string[], T[], string[]];
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
- exports.hasBasicAuth = exports.getBasicAuth = void 0;
3
- exports.readableAsBuffer = readableAsBuffer;
4
- exports.createKeyAndBody = createKeyAndBody;
5
- exports.createErrorHandler = createErrorHandler;
6
- exports.intoArray = intoArray;
7
- exports.generateFilename = generateFilename;
8
- exports.formatError = formatError;
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
- switch (typeof chunkSize) {
36
- case 'function':
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
- if (typeof errorCallback === 'number') {
46
- flags = errorCallback;
47
- errorCallback = undefined;
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(ext === '.map' && localFile ? path.basename(localFile) : output);
105
+ key.push(Array.isArray(descendantsGroup) && descendantsGroup.includes(ext) && localFile ? path.basename(localFile) : output);
109
106
  body.push(target);
110
- type.push(ext !== '.map' && mime.lookup(output) || mimeType || "application/octet-stream");
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.substring(0, j));
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.substring(j);
139
+ suffix = filename.slice(j);
143
140
  }
144
141
  }
145
- return basename && suffix ? [basename + `_${i}` + suffix, true] : [(0, types_1.incrementUUID)() + path.extname(filename), false];
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 ((0, types_1.isObject)(title)) {
146
+ if (isObject(title)) {
150
147
  title = title.service;
151
148
  }
152
- return (0, types_1.errorMessage)(typeof title === 'string' ? title : '', value, hint);
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;