@lossless.org/client 0.1.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/.smartconfig.json +37 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.losslessorgclient.d.ts +32 -0
- package/dist_ts/classes.losslessorgclient.js +103 -0
- package/dist_ts/core/classes.error.d.ts +16 -0
- package/dist_ts/core/classes.error.js +29 -0
- package/dist_ts/core/classes.operation.d.ts +17 -0
- package/dist_ts/core/classes.operation.js +70 -0
- package/dist_ts/core/interfaces.d.ts +18 -0
- package/dist_ts/core/interfaces.js +2 -0
- package/dist_ts/index.d.ts +4 -0
- package/dist_ts/index.js +3 -0
- package/dist_ts/nosqldb/classes.atomicdelete.d.ts +26 -0
- package/dist_ts/nosqldb/classes.atomicdelete.js +44 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +27 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +86 -0
- package/dist_ts/nosqldb/classes.atomicupdate.d.ts +26 -0
- package/dist_ts/nosqldb/classes.atomicupdate.js +55 -0
- package/dist_ts/nosqldb/classes.bootstraprecord.d.ts +14 -0
- package/dist_ts/nosqldb/classes.bootstraprecord.js +80 -0
- package/dist_ts/nosqldb/classes.bsonassertion.d.ts +2 -0
- package/dist_ts/nosqldb/classes.bsonassertion.js +29 -0
- package/dist_ts/nosqldb/classes.bsonobjectid.d.ts +2 -0
- package/dist_ts/nosqldb/classes.bsonobjectid.js +50 -0
- package/dist_ts/nosqldb/classes.bsonsnapshot.d.ts +3 -0
- package/dist_ts/nosqldb/classes.bsonsnapshot.js +126 -0
- package/dist_ts/nosqldb/classes.cached-document.d.ts +27 -0
- package/dist_ts/nosqldb/classes.cached-document.js +112 -0
- package/dist_ts/nosqldb/classes.collection.d.ts +302 -0
- package/dist_ts/nosqldb/classes.collection.js +1568 -0
- package/dist_ts/nosqldb/classes.collectionfactory.d.ts +30 -0
- package/dist_ts/nosqldb/classes.collectionfactory.js +65 -0
- package/dist_ts/nosqldb/classes.collectionlifecycle.d.ts +4 -0
- package/dist_ts/nosqldb/classes.collectionlifecycle.js +15 -0
- package/dist_ts/nosqldb/classes.collectionpreparation.d.ts +34 -0
- package/dist_ts/nosqldb/classes.collectionpreparation.js +134 -0
- package/dist_ts/nosqldb/classes.collectiontopology.d.ts +47 -0
- package/dist_ts/nosqldb/classes.collectiontopology.js +388 -0
- package/dist_ts/nosqldb/classes.connection.d.ts +18 -0
- package/dist_ts/nosqldb/classes.connection.js +23 -0
- package/dist_ts/nosqldb/classes.convenience.d.ts +1 -0
- package/dist_ts/nosqldb/classes.convenience.js +5 -0
- package/dist_ts/nosqldb/classes.cursor.d.ts +15 -0
- package/dist_ts/nosqldb/classes.cursor.js +82 -0
- package/dist_ts/nosqldb/classes.cursoroperation.d.ts +7 -0
- package/dist_ts/nosqldb/classes.cursoroperation.js +36 -0
- package/dist_ts/nosqldb/classes.db.d.ts +98 -0
- package/dist_ts/nosqldb/classes.db.js +434 -0
- package/dist_ts/nosqldb/classes.distributedcoordinator.d.ts +52 -0
- package/dist_ts/nosqldb/classes.distributedcoordinator.js +314 -0
- package/dist_ts/nosqldb/classes.doc.d.ts +722 -0
- package/dist_ts/nosqldb/classes.doc.js +2976 -0
- package/dist_ts/nosqldb/classes.easystore.d.ts +42 -0
- package/dist_ts/nosqldb/classes.easystore.js +199 -0
- package/dist_ts/nosqldb/classes.exactpersistence.d.ts +141 -0
- package/dist_ts/nosqldb/classes.exactpersistence.js +1110 -0
- package/dist_ts/nosqldb/classes.lucene.adapter.d.ts +173 -0
- package/dist_ts/nosqldb/classes.lucene.adapter.js +623 -0
- package/dist_ts/nosqldb/classes.mongoadministration.d.ts +73 -0
- package/dist_ts/nosqldb/classes.mongoadministration.js +497 -0
- package/dist_ts/nosqldb/classes.namespaceinspection.d.ts +42 -0
- package/dist_ts/nosqldb/classes.namespaceinspection.js +138 -0
- package/dist_ts/nosqldb/classes.operationbudget.d.ts +22 -0
- package/dist_ts/nosqldb/classes.operationbudget.js +65 -0
- package/dist_ts/nosqldb/classes.ordinarypersistence.d.ts +18 -0
- package/dist_ts/nosqldb/classes.ordinarypersistence.js +71 -0
- package/dist_ts/nosqldb/classes.persistence.d.ts +14 -0
- package/dist_ts/nosqldb/classes.persistence.js +34 -0
- package/dist_ts/nosqldb/classes.session.d.ts +28 -0
- package/dist_ts/nosqldb/classes.session.js +246 -0
- package/dist_ts/nosqldb/classes.storedinspection.d.ts +44 -0
- package/dist_ts/nosqldb/classes.storedinspection.js +100 -0
- package/dist_ts/nosqldb/classes.testdatabase.d.ts +56 -0
- package/dist_ts/nosqldb/classes.testdatabase.js +250 -0
- package/dist_ts/nosqldb/classes.watcher.d.ts +37 -0
- package/dist_ts/nosqldb/classes.watcher.js +98 -0
- package/dist_ts/nosqldb/index.d.ts +27 -0
- package/dist_ts/nosqldb/index.js +18 -0
- package/dist_ts/nosqldb/logging.d.ts +2 -0
- package/dist_ts/nosqldb/logging.js +3 -0
- package/dist_ts/nosqldb/plugins.d.ts +17 -0
- package/dist_ts/nosqldb/plugins.js +20 -0
- package/dist_ts/nosqldb/shim.d.ts +1 -0
- package/dist_ts/nosqldb/shim.js +8 -0
- package/dist_ts/nosqldb/testsupport.d.ts +3 -0
- package/dist_ts/nosqldb/testsupport.js +3 -0
- package/dist_ts/objectstorage/classes.bucket.d.ts +227 -0
- package/dist_ts/objectstorage/classes.bucket.js +939 -0
- package/dist_ts/objectstorage/classes.connection.d.ts +21 -0
- package/dist_ts/objectstorage/classes.connection.js +27 -0
- package/dist_ts/objectstorage/classes.directory.d.ts +124 -0
- package/dist_ts/objectstorage/classes.directory.js +335 -0
- package/dist_ts/objectstorage/classes.exactpathpurgeerror.d.ts +5 -0
- package/dist_ts/objectstorage/classes.exactpathpurgeerror.js +18 -0
- package/dist_ts/objectstorage/classes.exactuploaderror.d.ts +5 -0
- package/dist_ts/objectstorage/classes.exactuploaderror.js +19 -0
- package/dist_ts/objectstorage/classes.file.d.ts +91 -0
- package/dist_ts/objectstorage/classes.file.js +255 -0
- package/dist_ts/objectstorage/classes.listcursor.d.ts +41 -0
- package/dist_ts/objectstorage/classes.listcursor.js +67 -0
- package/dist_ts/objectstorage/classes.metadata.d.ts +57 -0
- package/dist_ts/objectstorage/classes.metadata.js +113 -0
- package/dist_ts/objectstorage/classes.smartbucket.d.ts +57 -0
- package/dist_ts/objectstorage/classes.smartbucket.js +357 -0
- package/dist_ts/objectstorage/classes.trash.d.ts +11 -0
- package/dist_ts/objectstorage/classes.trash.js +22 -0
- package/dist_ts/objectstorage/classes.watcher.d.ts +79 -0
- package/dist_ts/objectstorage/classes.watcher.js +249 -0
- package/dist_ts/objectstorage/helpers.d.ts +25 -0
- package/dist_ts/objectstorage/helpers.js +215 -0
- package/dist_ts/objectstorage/index.d.ts +13 -0
- package/dist_ts/objectstorage/index.js +13 -0
- package/dist_ts/objectstorage/interfaces.d.ts +276 -0
- package/dist_ts/objectstorage/interfaces.js +2 -0
- package/dist_ts/objectstorage/internal.exactpathpurge.operations.d.ts +11 -0
- package/dist_ts/objectstorage/internal.exactpathpurge.operations.js +1069 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.d.ts +40 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.js +382 -0
- package/dist_ts/objectstorage/internal.exactupload.operations.d.ts +11 -0
- package/dist_ts/objectstorage/internal.exactupload.operations.js +1104 -0
- package/dist_ts/objectstorage/internal.multipart.planner.d.ts +8 -0
- package/dist_ts/objectstorage/internal.multipart.planner.js +63 -0
- package/dist_ts/objectstorage/internal.multipart.stream.d.ts +17 -0
- package/dist_ts/objectstorage/internal.multipart.stream.js +440 -0
- package/dist_ts/objectstorage/internal.multipart.types.d.ts +82 -0
- package/dist_ts/objectstorage/internal.multipart.types.js +2 -0
- package/dist_ts/objectstorage/plugins.d.ts +17 -0
- package/dist_ts/objectstorage/plugins.js +23 -0
- package/dist_ts/plugins.d.ts +4 -0
- package/dist_ts/plugins.js +5 -0
- package/dist_ts/sqldb/classes.clickhouseconnection.d.ts +39 -0
- package/dist_ts/sqldb/classes.clickhouseconnection.js +225 -0
- package/dist_ts/sqldb/classes.sqlconnection.d.ts +50 -0
- package/dist_ts/sqldb/classes.sqlconnection.js +376 -0
- package/dist_ts/sqldb/classes.sqltable.d.ts +29 -0
- package/dist_ts/sqldb/classes.sqltable.js +70 -0
- package/dist_ts/sqldb/clickhouse/classes.metricwriter.d.ts +27 -0
- package/dist_ts/sqldb/clickhouse/classes.metricwriter.js +89 -0
- package/dist_ts/sqldb/clickhouse/index.d.ts +9 -0
- package/dist_ts/sqldb/clickhouse/index.js +13 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.d.ts +88 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.js +304 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.d.ts +28 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.js +46 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.d.ts +43 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.js +155 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.d.ts +13 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.js +36 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.d.ts +49 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.js +106 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.d.ts +51 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.js +96 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.d.ts +5 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.js +6 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.types.d.ts +53 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.types.js +41 -0
- package/dist_ts/sqldb/index.d.ts +6 -0
- package/dist_ts/sqldb/index.js +6 -0
- package/dist_ts/sqldb/interfaces.d.ts +53 -0
- package/dist_ts/sqldb/interfaces.js +19 -0
- package/dist_ts/sqldb/internal.sqlpool.d.ts +51 -0
- package/dist_ts/sqldb/internal.sqlpool.js +214 -0
- package/dist_ts/sqldb/plugins.clickhouse.d.ts +4 -0
- package/dist_ts/sqldb/plugins.clickhouse.js +5 -0
- package/dist_ts/sqldb/plugins.mariadb.d.ts +4 -0
- package/dist_ts/sqldb/plugins.mariadb.js +5 -0
- package/docs/source/smartbucket/license.md +19 -0
- package/docs/source/smartclickhouse/license.md +19 -0
- package/license.md +21 -0
- package/package.json +101 -0
- package/readme.md +157 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/classes.losslessorgclient.ts +104 -0
- package/ts/core/classes.error.ts +31 -0
- package/ts/core/classes.operation.ts +60 -0
- package/ts/core/interfaces.ts +24 -0
- package/ts/index.ts +4 -0
- package/ts/nosqldb/classes.atomicdelete.ts +81 -0
- package/ts/nosqldb/classes.atomicfindoneandupdate.ts +152 -0
- package/ts/nosqldb/classes.atomicupdate.ts +99 -0
- package/ts/nosqldb/classes.bootstraprecord.ts +107 -0
- package/ts/nosqldb/classes.bsonassertion.ts +25 -0
- package/ts/nosqldb/classes.bsonobjectid.ts +45 -0
- package/ts/nosqldb/classes.bsonsnapshot.ts +105 -0
- package/ts/nosqldb/classes.cached-document.ts +67 -0
- package/ts/nosqldb/classes.collection.ts +2399 -0
- package/ts/nosqldb/classes.collectionfactory.ts +87 -0
- package/ts/nosqldb/classes.collectionlifecycle.ts +24 -0
- package/ts/nosqldb/classes.collectionpreparation.ts +164 -0
- package/ts/nosqldb/classes.collectiontopology.ts +645 -0
- package/ts/nosqldb/classes.connection.ts +31 -0
- package/ts/nosqldb/classes.convenience.ts +5 -0
- package/ts/nosqldb/classes.cursor.ts +88 -0
- package/ts/nosqldb/classes.cursoroperation.ts +38 -0
- package/ts/nosqldb/classes.db.ts +637 -0
- package/ts/nosqldb/classes.distributedcoordinator.ts +305 -0
- package/ts/nosqldb/classes.doc.ts +4928 -0
- package/ts/nosqldb/classes.easystore.ts +154 -0
- package/ts/nosqldb/classes.exactpersistence.ts +1974 -0
- package/ts/nosqldb/classes.lucene.adapter.ts +780 -0
- package/ts/nosqldb/classes.mongoadministration.ts +867 -0
- package/ts/nosqldb/classes.namespaceinspection.ts +199 -0
- package/ts/nosqldb/classes.operationbudget.ts +75 -0
- package/ts/nosqldb/classes.ordinarypersistence.ts +84 -0
- package/ts/nosqldb/classes.persistence.ts +62 -0
- package/ts/nosqldb/classes.session.ts +389 -0
- package/ts/nosqldb/classes.storedinspection.ts +151 -0
- package/ts/nosqldb/classes.testdatabase.ts +272 -0
- package/ts/nosqldb/classes.watcher.ts +96 -0
- package/ts/nosqldb/index.ts +51 -0
- package/ts/nosqldb/logging.ts +3 -0
- package/ts/nosqldb/plugins.ts +37 -0
- package/ts/nosqldb/shim.ts +6 -0
- package/ts/nosqldb/testsupport.ts +13 -0
- package/ts/objectstorage/classes.bucket.ts +1114 -0
- package/ts/objectstorage/classes.connection.ts +36 -0
- package/ts/objectstorage/classes.directory.ts +425 -0
- package/ts/objectstorage/classes.exactpathpurgeerror.ts +24 -0
- package/ts/objectstorage/classes.exactuploaderror.ts +25 -0
- package/ts/objectstorage/classes.file.ts +303 -0
- package/ts/objectstorage/classes.listcursor.ts +89 -0
- package/ts/objectstorage/classes.metadata.ts +134 -0
- package/ts/objectstorage/classes.smartbucket.ts +445 -0
- package/ts/objectstorage/classes.trash.ts +30 -0
- package/ts/objectstorage/classes.watcher.ts +289 -0
- package/ts/objectstorage/helpers.ts +254 -0
- package/ts/objectstorage/index.ts +13 -0
- package/ts/objectstorage/interfaces.ts +389 -0
- package/ts/objectstorage/internal.exactpathpurge.operations.ts +1936 -0
- package/ts/objectstorage/internal.exactupload.capability.ts +580 -0
- package/ts/objectstorage/internal.exactupload.operations.ts +1715 -0
- package/ts/objectstorage/internal.multipart.planner.ts +90 -0
- package/ts/objectstorage/internal.multipart.stream.ts +606 -0
- package/ts/objectstorage/internal.multipart.types.ts +106 -0
- package/ts/objectstorage/plugins.ts +35 -0
- package/ts/plugins.ts +4 -0
- package/ts/sqldb/classes.clickhouseconnection.ts +189 -0
- package/ts/sqldb/classes.sqlconnection.ts +350 -0
- package/ts/sqldb/classes.sqltable.ts +70 -0
- package/ts/sqldb/clickhouse/classes.metricwriter.ts +72 -0
- package/ts/sqldb/clickhouse/index.ts +16 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.ts +372 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.ts +52 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.ts +120 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.resultset.ts +44 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.ts +123 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.ts +114 -0
- package/ts/sqldb/clickhouse/smartclickhouse.plugins.ts +5 -0
- package/ts/sqldb/clickhouse/smartclickhouse.types.ts +134 -0
- package/ts/sqldb/index.ts +6 -0
- package/ts/sqldb/interfaces.ts +61 -0
- package/ts/sqldb/internal.sqlpool.ts +179 -0
- package/ts/sqldb/plugins.clickhouse.ts +4 -0
- package/ts/sqldb/plugins.mariadb.ts +4 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SmartBucket } from './classes.smartbucket.js';
|
|
2
|
+
import type { ICapabilities, IOperationOptions, IReadiness } from '../core/interfaces.js';
|
|
3
|
+
|
|
4
|
+
export interface IObjectStorageConnectionOptions {
|
|
5
|
+
backend: 'objectstorage' | 's3';
|
|
6
|
+
endpoint: string;
|
|
7
|
+
region?: string;
|
|
8
|
+
credentials: { accessKeyId: string; secretAccessKey: string };
|
|
9
|
+
forcePathStyle?: boolean;
|
|
10
|
+
/** Existing bucket used by the read-only readiness probe; no bucket is created automatically. */
|
|
11
|
+
readinessBucket?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class ObjectStorageConnection extends SmartBucket {
|
|
15
|
+
public readonly backend: 'objectstorage' | 's3';
|
|
16
|
+
public readonly capabilities: ICapabilities;
|
|
17
|
+
constructor(public readonly options: IObjectStorageConnectionOptions) {
|
|
18
|
+
const endpoint = new URL(options.endpoint);
|
|
19
|
+
if (!['http:', 'https:'].includes(endpoint.protocol) || endpoint.username || endpoint.password ||
|
|
20
|
+
endpoint.pathname !== '/' || endpoint.search || endpoint.hash) {
|
|
21
|
+
throw new TypeError('Object storage requires an HTTP(S) origin with separate credentials.');
|
|
22
|
+
}
|
|
23
|
+
super({ endpoint: endpoint.hostname, port: Number(endpoint.port || (endpoint.protocol === 'https:' ? 443 : 80)),
|
|
24
|
+
useSsl: endpoint.protocol === 'https:', accessKey: options.credentials.accessKeyId,
|
|
25
|
+
accessSecret: options.credentials.secretAccessKey, region: options.region ?? 'us-east-1' },
|
|
26
|
+
{ forcePathStyle: options.forcePathStyle });
|
|
27
|
+
this.backend = options.backend;
|
|
28
|
+
this.capabilities = Object.freeze({ backend: this.backend, transactions: 'unsupported', changeStreams: 'unsupported',
|
|
29
|
+
objectMetrics: 'unsupported', diskResidentScans: 'unknown' });
|
|
30
|
+
}
|
|
31
|
+
public async ready(options: IOperationOptions = {}): Promise<IReadiness> {
|
|
32
|
+
if (!this.options.readinessBucket) return { ready: false, reason: 'readiness_bucket_required' };
|
|
33
|
+
const result = await this.checkReadiness(this.options.readinessBucket, options);
|
|
34
|
+
return result.ready ? { ready: true } : { ready: false, reason: result.reason };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
// classes.directory.ts
|
|
2
|
+
|
|
3
|
+
import * as plugins from './plugins.js';
|
|
4
|
+
import { Bucket } from './classes.bucket.js';
|
|
5
|
+
import { File } from './classes.file.js';
|
|
6
|
+
import * as helpers from './helpers.js';
|
|
7
|
+
import type { IDirectoryFastPutStreamOptions } from './interfaces.js';
|
|
8
|
+
|
|
9
|
+
export class Directory {
|
|
10
|
+
public bucketRef: Bucket;
|
|
11
|
+
public parentDirectoryRef: Directory;
|
|
12
|
+
public name: string;
|
|
13
|
+
|
|
14
|
+
public tree!: string[];
|
|
15
|
+
public files!: string[];
|
|
16
|
+
public folders!: string[];
|
|
17
|
+
|
|
18
|
+
constructor(bucketRefArg: Bucket, parentDirectory: Directory, name: string) {
|
|
19
|
+
this.bucketRef = bucketRefArg;
|
|
20
|
+
this.parentDirectoryRef = parentDirectory;
|
|
21
|
+
this.name = name;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* returns an array of parent directories
|
|
26
|
+
*/
|
|
27
|
+
public getParentDirectories(): Directory[] {
|
|
28
|
+
let parentDirectories: Directory[] = [];
|
|
29
|
+
if (this.parentDirectoryRef) {
|
|
30
|
+
parentDirectories.push(this.parentDirectoryRef);
|
|
31
|
+
parentDirectories = parentDirectories.concat(this.parentDirectoryRef.getParentDirectories());
|
|
32
|
+
}
|
|
33
|
+
return parentDirectories;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* returns the directory level
|
|
38
|
+
*/
|
|
39
|
+
public getDirectoryLevel(): number {
|
|
40
|
+
return this.getParentDirectories().length;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* updates the base path
|
|
45
|
+
*/
|
|
46
|
+
public getBasePath(): string {
|
|
47
|
+
const parentDirectories = this.getParentDirectories();
|
|
48
|
+
let basePath = '';
|
|
49
|
+
for (const parentDir of parentDirectories) {
|
|
50
|
+
if (!parentDir.name && !basePath) {
|
|
51
|
+
basePath = this.name + '/';
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (parentDir.name && !basePath) {
|
|
55
|
+
basePath = parentDir.name + '/' + this.name + '/';
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (parentDir.name && basePath) {
|
|
59
|
+
basePath = parentDir.name + '/' + basePath;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return basePath;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* gets a file by name
|
|
68
|
+
*/
|
|
69
|
+
public async getFile(optionsArg: {
|
|
70
|
+
path: string;
|
|
71
|
+
createWithContents?: string | Buffer;
|
|
72
|
+
getFromTrash?: boolean;
|
|
73
|
+
}): Promise<File> {
|
|
74
|
+
const pathDescriptor = {
|
|
75
|
+
directory: this,
|
|
76
|
+
path: optionsArg.path,
|
|
77
|
+
};
|
|
78
|
+
const exists = await this.bucketRef.fastExists({
|
|
79
|
+
path: await helpers.reducePathDescriptorToPath(pathDescriptor),
|
|
80
|
+
});
|
|
81
|
+
if (!exists && optionsArg.getFromTrash) {
|
|
82
|
+
const trash = await this.bucketRef.getTrash();
|
|
83
|
+
const trashedFile = await trash.getTrashedFileByOriginalName(pathDescriptor);
|
|
84
|
+
return trashedFile;
|
|
85
|
+
}
|
|
86
|
+
if (!exists && !optionsArg.createWithContents) {
|
|
87
|
+
throw new Error(`File not found at path '${optionsArg.path}'`);
|
|
88
|
+
}
|
|
89
|
+
if (!exists && optionsArg.createWithContents) {
|
|
90
|
+
await File.create({
|
|
91
|
+
directory: this,
|
|
92
|
+
name: optionsArg.path,
|
|
93
|
+
contents: optionsArg.createWithContents,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return new File({
|
|
97
|
+
directoryRefArg: this,
|
|
98
|
+
fileName: optionsArg.path,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Check if a file exists in this directory
|
|
105
|
+
*/
|
|
106
|
+
public async fileExists(optionsArg: { path: string }): Promise<boolean> {
|
|
107
|
+
const pathDescriptor = {
|
|
108
|
+
directory: this,
|
|
109
|
+
path: optionsArg.path,
|
|
110
|
+
};
|
|
111
|
+
return this.bucketRef.fastExists({
|
|
112
|
+
path: await helpers.reducePathDescriptorToPath(pathDescriptor),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Check if a subdirectory exists
|
|
118
|
+
*/
|
|
119
|
+
public async directoryExists(dirNameArg: string): Promise<boolean> {
|
|
120
|
+
const directories = await this.listDirectories();
|
|
121
|
+
return directories.some(dir => dir.name === dirNameArg);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Collects all ListObjectsV2 pages for a prefix.
|
|
126
|
+
*/
|
|
127
|
+
private async listObjectsV2AllPages(prefix: string, delimiter?: string) {
|
|
128
|
+
const allContents: plugins.s3._Object[] = [];
|
|
129
|
+
const allCommonPrefixes: plugins.s3.CommonPrefix[] = [];
|
|
130
|
+
let continuationToken: string | undefined;
|
|
131
|
+
|
|
132
|
+
do {
|
|
133
|
+
const command = new plugins.s3.ListObjectsV2Command({
|
|
134
|
+
Bucket: this.bucketRef.name,
|
|
135
|
+
Prefix: prefix,
|
|
136
|
+
Delimiter: delimiter,
|
|
137
|
+
ContinuationToken: continuationToken,
|
|
138
|
+
});
|
|
139
|
+
const response = await this.bucketRef.smartbucketRef.storageClient.send(command);
|
|
140
|
+
|
|
141
|
+
if (response.Contents) {
|
|
142
|
+
allContents.push(...response.Contents);
|
|
143
|
+
}
|
|
144
|
+
if (response.CommonPrefixes) {
|
|
145
|
+
allCommonPrefixes.push(...response.CommonPrefixes);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
continuationToken = response.IsTruncated ? response.NextContinuationToken : undefined;
|
|
149
|
+
} while (continuationToken);
|
|
150
|
+
|
|
151
|
+
return { contents: allContents, commonPrefixes: allCommonPrefixes };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* lists all files
|
|
156
|
+
*/
|
|
157
|
+
public async listFiles(): Promise<File[]> {
|
|
158
|
+
const { contents } = await this.listObjectsV2AllPages(this.getBasePath(), '/');
|
|
159
|
+
const fileArray: File[] = [];
|
|
160
|
+
|
|
161
|
+
contents.forEach((item) => {
|
|
162
|
+
if (item.Key && !item.Key.endsWith('/')) {
|
|
163
|
+
const subtractedPath = item.Key.replace(this.getBasePath(), '');
|
|
164
|
+
if (!subtractedPath.includes('/')) {
|
|
165
|
+
fileArray.push(
|
|
166
|
+
new File({
|
|
167
|
+
directoryRefArg: this,
|
|
168
|
+
fileName: subtractedPath,
|
|
169
|
+
})
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return fileArray;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* lists all folders
|
|
180
|
+
*/
|
|
181
|
+
public async listDirectories(): Promise<Directory[]> {
|
|
182
|
+
try {
|
|
183
|
+
const { commonPrefixes } = await this.listObjectsV2AllPages(this.getBasePath(), '/');
|
|
184
|
+
const directoryArray: Directory[] = [];
|
|
185
|
+
|
|
186
|
+
if (commonPrefixes) {
|
|
187
|
+
commonPrefixes.forEach((item) => {
|
|
188
|
+
if (item.Prefix) {
|
|
189
|
+
const subtractedPath = item.Prefix.replace(this.getBasePath(), '');
|
|
190
|
+
if (subtractedPath.endsWith('/')) {
|
|
191
|
+
const dirName = subtractedPath.slice(0, -1);
|
|
192
|
+
// Ensure the directory name is not empty (which would indicate the base directory itself)
|
|
193
|
+
if (dirName) {
|
|
194
|
+
directoryArray.push(new Directory(this.bucketRef, this, dirName));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return directoryArray;
|
|
202
|
+
} catch (error) {
|
|
203
|
+
console.error('Error listing directories:', error);
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* gets an array that has all objects with a certain prefix
|
|
210
|
+
*/
|
|
211
|
+
public async getTreeArray() {
|
|
212
|
+
const command = new plugins.s3.ListObjectsV2Command({
|
|
213
|
+
Bucket: this.bucketRef.name,
|
|
214
|
+
Prefix: this.getBasePath(),
|
|
215
|
+
Delimiter: '/',
|
|
216
|
+
});
|
|
217
|
+
const response = await this.bucketRef.smartbucketRef.storageClient.send(command);
|
|
218
|
+
return response.Contents;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* gets a sub directory by name
|
|
223
|
+
*/
|
|
224
|
+
public async getSubDirectoryByName(dirNameArg: string, optionsArg: {
|
|
225
|
+
/**
|
|
226
|
+
* in object storage a directory does not exist if it is empty
|
|
227
|
+
* this option returns a directory even if it is empty
|
|
228
|
+
*/
|
|
229
|
+
getEmptyDirectory?: boolean;
|
|
230
|
+
/**
|
|
231
|
+
* in object storage a directory does not exist if it is empty
|
|
232
|
+
* this option creates a directory even if it is empty using a initializer file
|
|
233
|
+
*/
|
|
234
|
+
createWithInitializerFile?: boolean;
|
|
235
|
+
/**
|
|
236
|
+
* if the path is a file path, it will be treated as a file and the parent directory will be returned
|
|
237
|
+
*/
|
|
238
|
+
couldBeFilePath?: boolean;
|
|
239
|
+
} = {}): Promise<Directory> {
|
|
240
|
+
|
|
241
|
+
const dirNameArray = dirNameArg.split('/').filter(str => str.trim() !== "");
|
|
242
|
+
|
|
243
|
+
optionsArg = {
|
|
244
|
+
getEmptyDirectory: false,
|
|
245
|
+
createWithInitializerFile: false,
|
|
246
|
+
...optionsArg,
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
const getDirectory = async (directoryArg: Directory, dirNameToSearch: string, isFinalDirectory: boolean) => {
|
|
251
|
+
const directories = await directoryArg.listDirectories();
|
|
252
|
+
let returnDirectory = directories.find((directory) => {
|
|
253
|
+
return directory.name === dirNameToSearch;
|
|
254
|
+
});
|
|
255
|
+
if (returnDirectory) {
|
|
256
|
+
return returnDirectory;
|
|
257
|
+
}
|
|
258
|
+
if (optionsArg.getEmptyDirectory || optionsArg.createWithInitializerFile) {
|
|
259
|
+
returnDirectory = new Directory(this.bucketRef, directoryArg, dirNameToSearch);
|
|
260
|
+
}
|
|
261
|
+
if (isFinalDirectory && optionsArg.createWithInitializerFile) {
|
|
262
|
+
returnDirectory?.createEmptyFile('00init.txt');
|
|
263
|
+
}
|
|
264
|
+
return returnDirectory || null;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
if (optionsArg.couldBeFilePath) {
|
|
268
|
+
const baseDirectory = await this.bucketRef.getBaseDirectory();
|
|
269
|
+
const existingFile = await baseDirectory.getFile({
|
|
270
|
+
path: dirNameArg,
|
|
271
|
+
});
|
|
272
|
+
if (existingFile) {
|
|
273
|
+
const adjustedPath = dirNameArg.substring(0, dirNameArg.lastIndexOf('/'));
|
|
274
|
+
return this.getSubDirectoryByName(adjustedPath);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
let wantedDirectory: Directory | null = null;
|
|
279
|
+
let counter = 0;
|
|
280
|
+
for (const dirNameToSearch of dirNameArray) {
|
|
281
|
+
counter++;
|
|
282
|
+
const directoryToSearchIn = wantedDirectory ? wantedDirectory : this;
|
|
283
|
+
wantedDirectory = await getDirectory(directoryToSearchIn, dirNameToSearch, counter === dirNameArray.length);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (!wantedDirectory) {
|
|
287
|
+
throw new Error(`Directory not found at path '${dirNameArg}'`);
|
|
288
|
+
}
|
|
289
|
+
return wantedDirectory;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* moves the directory
|
|
295
|
+
*/
|
|
296
|
+
public async move() {
|
|
297
|
+
// TODO
|
|
298
|
+
throw new Error('Moving a directory is not yet implemented');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* creates an empty file within this directory
|
|
303
|
+
* @param relativePathArg
|
|
304
|
+
*/
|
|
305
|
+
public async createEmptyFile(relativePathArg: string) {
|
|
306
|
+
const emptyFile = await File.create({
|
|
307
|
+
directory: this,
|
|
308
|
+
name: relativePathArg,
|
|
309
|
+
contents: '',
|
|
310
|
+
});
|
|
311
|
+
return emptyFile;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// file operations
|
|
315
|
+
public async fastPut(optionsArg: { path: string; contents: string | Buffer }) {
|
|
316
|
+
const path = plugins.path.join(this.getBasePath(), optionsArg.path);
|
|
317
|
+
await this.bucketRef.fastPut({
|
|
318
|
+
path,
|
|
319
|
+
contents: optionsArg.contents,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
public async fastGet(optionsArg: { path: string }) {
|
|
324
|
+
const path = plugins.path.join(this.getBasePath(), optionsArg.path);
|
|
325
|
+
const result = await this.bucketRef.fastGet({
|
|
326
|
+
path,
|
|
327
|
+
});
|
|
328
|
+
return result;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
public fastGetStream(
|
|
332
|
+
optionsArg: {
|
|
333
|
+
path: string;
|
|
334
|
+
signal?: AbortSignal;
|
|
335
|
+
},
|
|
336
|
+
typeArg: 'webstream'
|
|
337
|
+
): Promise<ReadableStream>;
|
|
338
|
+
public async fastGetStream(
|
|
339
|
+
optionsArg: {
|
|
340
|
+
path: string;
|
|
341
|
+
signal?: AbortSignal;
|
|
342
|
+
},
|
|
343
|
+
typeArg: 'nodestream'
|
|
344
|
+
): Promise<plugins.stream.Readable>;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* fastGetStream
|
|
348
|
+
* @param optionsArg
|
|
349
|
+
* @returns
|
|
350
|
+
*/
|
|
351
|
+
public async fastGetStream(
|
|
352
|
+
optionsArg: { path: string; signal?: AbortSignal },
|
|
353
|
+
typeArg: 'webstream' | 'nodestream'
|
|
354
|
+
): Promise<ReadableStream | plugins.stream.Readable> {
|
|
355
|
+
const path = plugins.path.join(this.getBasePath(), optionsArg.path);
|
|
356
|
+
const result = await this.bucketRef.fastGetStream(
|
|
357
|
+
{
|
|
358
|
+
path,
|
|
359
|
+
signal: optionsArg.signal,
|
|
360
|
+
},
|
|
361
|
+
typeArg as any
|
|
362
|
+
);
|
|
363
|
+
return result;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* fast put stream
|
|
368
|
+
*/
|
|
369
|
+
public async fastPutStream(
|
|
370
|
+
optionsArg: IDirectoryFastPutStreamOptions,
|
|
371
|
+
): Promise<void> {
|
|
372
|
+
const path = plugins.path.join(this.getBasePath(), optionsArg.path);
|
|
373
|
+
await this.bucketRef.fastPutStream({
|
|
374
|
+
path,
|
|
375
|
+
readableStream: optionsArg.stream,
|
|
376
|
+
contentLength: optionsArg.contentLength,
|
|
377
|
+
signal: optionsArg.signal,
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* removes a file within the directory
|
|
383
|
+
* uses file class to make sure effects for metadata etc. are handled correctly
|
|
384
|
+
* @param optionsArg
|
|
385
|
+
*/
|
|
386
|
+
public async fastRemove(optionsArg: {
|
|
387
|
+
path: string
|
|
388
|
+
/**
|
|
389
|
+
* wether the file should be placed into trash. Default is false.
|
|
390
|
+
*/
|
|
391
|
+
mode?: 'permanent' | 'trash';
|
|
392
|
+
}) {
|
|
393
|
+
const file = await this.getFile({
|
|
394
|
+
path: optionsArg.path,
|
|
395
|
+
});
|
|
396
|
+
await file.delete({
|
|
397
|
+
mode: optionsArg.mode ? optionsArg.mode : 'permanent',
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* deletes the directory with all its contents
|
|
403
|
+
*/
|
|
404
|
+
public async delete(optionsArg: {
|
|
405
|
+
mode?: 'permanent' | 'trash';
|
|
406
|
+
}) {
|
|
407
|
+
const deleteDirectory = async (directoryArg: Directory) => {
|
|
408
|
+
const childDirectories = await directoryArg.listDirectories();
|
|
409
|
+
if (childDirectories.length === 0) {
|
|
410
|
+
console.log('Directory empty! Path complete!');
|
|
411
|
+
} else {
|
|
412
|
+
for (const childDir of childDirectories) {
|
|
413
|
+
await deleteDirectory(childDir);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const files = await directoryArg.listFiles();
|
|
417
|
+
for (const file of files) {
|
|
418
|
+
await file.delete({
|
|
419
|
+
mode: optionsArg.mode ? optionsArg.mode : 'permanent',
|
|
420
|
+
})
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
await deleteDirectory(this);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IExactPathPurgeFailureState,
|
|
3
|
+
TExactPathPurgeFailurePhase,
|
|
4
|
+
} from './interfaces.js';
|
|
5
|
+
|
|
6
|
+
const phaseMessages: Record<TExactPathPurgeFailurePhase, string> = {
|
|
7
|
+
capability: 'The exact-path purge capability is invalid or stale.',
|
|
8
|
+
inventory: 'The exact path could not be inventoried safely.',
|
|
9
|
+
consistency: 'The exact path changed before purge mutation.',
|
|
10
|
+
delete: 'The exact path could not be deleted safely.',
|
|
11
|
+
verification: 'The exact-path purge could not be verified.',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export class ExactPathPurgeError extends Error {
|
|
15
|
+
public readonly state: IExactPathPurgeFailureState;
|
|
16
|
+
|
|
17
|
+
constructor(stateArg: IExactPathPurgeFailureState, causeArg: unknown) {
|
|
18
|
+
super(phaseMessages[stateArg.phase], {
|
|
19
|
+
cause: causeArg,
|
|
20
|
+
});
|
|
21
|
+
this.name = 'ExactPathPurgeError';
|
|
22
|
+
this.state = stateArg;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IExactUploadFailureState,
|
|
3
|
+
TExactUploadFailurePhase,
|
|
4
|
+
} from './interfaces.js';
|
|
5
|
+
|
|
6
|
+
const phaseMessages: Record<TExactUploadFailurePhase, string> = {
|
|
7
|
+
capability: 'The exact upload capability is invalid or stale.',
|
|
8
|
+
source: 'The exact upload source could not be consumed.',
|
|
9
|
+
'put-zero': 'The conditional zero-byte object upload failed.',
|
|
10
|
+
'create-multipart': 'The multipart upload could not be created.',
|
|
11
|
+
'upload-part': 'A multipart upload part failed.',
|
|
12
|
+
'complete-multipart': 'The conditional multipart completion failed.',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class ExactUploadError extends Error {
|
|
16
|
+
public readonly state: IExactUploadFailureState;
|
|
17
|
+
|
|
18
|
+
constructor(stateArg: IExactUploadFailureState, causeArg: unknown) {
|
|
19
|
+
super(phaseMessages[stateArg.phase], {
|
|
20
|
+
cause: causeArg,
|
|
21
|
+
});
|
|
22
|
+
this.name = 'ExactUploadError';
|
|
23
|
+
this.state = stateArg;
|
|
24
|
+
}
|
|
25
|
+
}
|