@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.
Files changed (255) hide show
  1. package/.smartconfig.json +37 -0
  2. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  3. package/dist_ts/00_commitinfo_data.js +9 -0
  4. package/dist_ts/classes.losslessorgclient.d.ts +32 -0
  5. package/dist_ts/classes.losslessorgclient.js +103 -0
  6. package/dist_ts/core/classes.error.d.ts +16 -0
  7. package/dist_ts/core/classes.error.js +29 -0
  8. package/dist_ts/core/classes.operation.d.ts +17 -0
  9. package/dist_ts/core/classes.operation.js +70 -0
  10. package/dist_ts/core/interfaces.d.ts +18 -0
  11. package/dist_ts/core/interfaces.js +2 -0
  12. package/dist_ts/index.d.ts +4 -0
  13. package/dist_ts/index.js +3 -0
  14. package/dist_ts/nosqldb/classes.atomicdelete.d.ts +26 -0
  15. package/dist_ts/nosqldb/classes.atomicdelete.js +44 -0
  16. package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +27 -0
  17. package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +86 -0
  18. package/dist_ts/nosqldb/classes.atomicupdate.d.ts +26 -0
  19. package/dist_ts/nosqldb/classes.atomicupdate.js +55 -0
  20. package/dist_ts/nosqldb/classes.bootstraprecord.d.ts +14 -0
  21. package/dist_ts/nosqldb/classes.bootstraprecord.js +80 -0
  22. package/dist_ts/nosqldb/classes.bsonassertion.d.ts +2 -0
  23. package/dist_ts/nosqldb/classes.bsonassertion.js +29 -0
  24. package/dist_ts/nosqldb/classes.bsonobjectid.d.ts +2 -0
  25. package/dist_ts/nosqldb/classes.bsonobjectid.js +50 -0
  26. package/dist_ts/nosqldb/classes.bsonsnapshot.d.ts +3 -0
  27. package/dist_ts/nosqldb/classes.bsonsnapshot.js +126 -0
  28. package/dist_ts/nosqldb/classes.cached-document.d.ts +27 -0
  29. package/dist_ts/nosqldb/classes.cached-document.js +112 -0
  30. package/dist_ts/nosqldb/classes.collection.d.ts +302 -0
  31. package/dist_ts/nosqldb/classes.collection.js +1568 -0
  32. package/dist_ts/nosqldb/classes.collectionfactory.d.ts +30 -0
  33. package/dist_ts/nosqldb/classes.collectionfactory.js +65 -0
  34. package/dist_ts/nosqldb/classes.collectionlifecycle.d.ts +4 -0
  35. package/dist_ts/nosqldb/classes.collectionlifecycle.js +15 -0
  36. package/dist_ts/nosqldb/classes.collectionpreparation.d.ts +34 -0
  37. package/dist_ts/nosqldb/classes.collectionpreparation.js +134 -0
  38. package/dist_ts/nosqldb/classes.collectiontopology.d.ts +47 -0
  39. package/dist_ts/nosqldb/classes.collectiontopology.js +388 -0
  40. package/dist_ts/nosqldb/classes.connection.d.ts +18 -0
  41. package/dist_ts/nosqldb/classes.connection.js +23 -0
  42. package/dist_ts/nosqldb/classes.convenience.d.ts +1 -0
  43. package/dist_ts/nosqldb/classes.convenience.js +5 -0
  44. package/dist_ts/nosqldb/classes.cursor.d.ts +15 -0
  45. package/dist_ts/nosqldb/classes.cursor.js +82 -0
  46. package/dist_ts/nosqldb/classes.cursoroperation.d.ts +7 -0
  47. package/dist_ts/nosqldb/classes.cursoroperation.js +36 -0
  48. package/dist_ts/nosqldb/classes.db.d.ts +98 -0
  49. package/dist_ts/nosqldb/classes.db.js +434 -0
  50. package/dist_ts/nosqldb/classes.distributedcoordinator.d.ts +52 -0
  51. package/dist_ts/nosqldb/classes.distributedcoordinator.js +314 -0
  52. package/dist_ts/nosqldb/classes.doc.d.ts +722 -0
  53. package/dist_ts/nosqldb/classes.doc.js +2976 -0
  54. package/dist_ts/nosqldb/classes.easystore.d.ts +42 -0
  55. package/dist_ts/nosqldb/classes.easystore.js +199 -0
  56. package/dist_ts/nosqldb/classes.exactpersistence.d.ts +141 -0
  57. package/dist_ts/nosqldb/classes.exactpersistence.js +1110 -0
  58. package/dist_ts/nosqldb/classes.lucene.adapter.d.ts +173 -0
  59. package/dist_ts/nosqldb/classes.lucene.adapter.js +623 -0
  60. package/dist_ts/nosqldb/classes.mongoadministration.d.ts +73 -0
  61. package/dist_ts/nosqldb/classes.mongoadministration.js +497 -0
  62. package/dist_ts/nosqldb/classes.namespaceinspection.d.ts +42 -0
  63. package/dist_ts/nosqldb/classes.namespaceinspection.js +138 -0
  64. package/dist_ts/nosqldb/classes.operationbudget.d.ts +22 -0
  65. package/dist_ts/nosqldb/classes.operationbudget.js +65 -0
  66. package/dist_ts/nosqldb/classes.ordinarypersistence.d.ts +18 -0
  67. package/dist_ts/nosqldb/classes.ordinarypersistence.js +71 -0
  68. package/dist_ts/nosqldb/classes.persistence.d.ts +14 -0
  69. package/dist_ts/nosqldb/classes.persistence.js +34 -0
  70. package/dist_ts/nosqldb/classes.session.d.ts +28 -0
  71. package/dist_ts/nosqldb/classes.session.js +246 -0
  72. package/dist_ts/nosqldb/classes.storedinspection.d.ts +44 -0
  73. package/dist_ts/nosqldb/classes.storedinspection.js +100 -0
  74. package/dist_ts/nosqldb/classes.testdatabase.d.ts +56 -0
  75. package/dist_ts/nosqldb/classes.testdatabase.js +250 -0
  76. package/dist_ts/nosqldb/classes.watcher.d.ts +37 -0
  77. package/dist_ts/nosqldb/classes.watcher.js +98 -0
  78. package/dist_ts/nosqldb/index.d.ts +27 -0
  79. package/dist_ts/nosqldb/index.js +18 -0
  80. package/dist_ts/nosqldb/logging.d.ts +2 -0
  81. package/dist_ts/nosqldb/logging.js +3 -0
  82. package/dist_ts/nosqldb/plugins.d.ts +17 -0
  83. package/dist_ts/nosqldb/plugins.js +20 -0
  84. package/dist_ts/nosqldb/shim.d.ts +1 -0
  85. package/dist_ts/nosqldb/shim.js +8 -0
  86. package/dist_ts/nosqldb/testsupport.d.ts +3 -0
  87. package/dist_ts/nosqldb/testsupport.js +3 -0
  88. package/dist_ts/objectstorage/classes.bucket.d.ts +227 -0
  89. package/dist_ts/objectstorage/classes.bucket.js +939 -0
  90. package/dist_ts/objectstorage/classes.connection.d.ts +21 -0
  91. package/dist_ts/objectstorage/classes.connection.js +27 -0
  92. package/dist_ts/objectstorage/classes.directory.d.ts +124 -0
  93. package/dist_ts/objectstorage/classes.directory.js +335 -0
  94. package/dist_ts/objectstorage/classes.exactpathpurgeerror.d.ts +5 -0
  95. package/dist_ts/objectstorage/classes.exactpathpurgeerror.js +18 -0
  96. package/dist_ts/objectstorage/classes.exactuploaderror.d.ts +5 -0
  97. package/dist_ts/objectstorage/classes.exactuploaderror.js +19 -0
  98. package/dist_ts/objectstorage/classes.file.d.ts +91 -0
  99. package/dist_ts/objectstorage/classes.file.js +255 -0
  100. package/dist_ts/objectstorage/classes.listcursor.d.ts +41 -0
  101. package/dist_ts/objectstorage/classes.listcursor.js +67 -0
  102. package/dist_ts/objectstorage/classes.metadata.d.ts +57 -0
  103. package/dist_ts/objectstorage/classes.metadata.js +113 -0
  104. package/dist_ts/objectstorage/classes.smartbucket.d.ts +57 -0
  105. package/dist_ts/objectstorage/classes.smartbucket.js +357 -0
  106. package/dist_ts/objectstorage/classes.trash.d.ts +11 -0
  107. package/dist_ts/objectstorage/classes.trash.js +22 -0
  108. package/dist_ts/objectstorage/classes.watcher.d.ts +79 -0
  109. package/dist_ts/objectstorage/classes.watcher.js +249 -0
  110. package/dist_ts/objectstorage/helpers.d.ts +25 -0
  111. package/dist_ts/objectstorage/helpers.js +215 -0
  112. package/dist_ts/objectstorage/index.d.ts +13 -0
  113. package/dist_ts/objectstorage/index.js +13 -0
  114. package/dist_ts/objectstorage/interfaces.d.ts +276 -0
  115. package/dist_ts/objectstorage/interfaces.js +2 -0
  116. package/dist_ts/objectstorage/internal.exactpathpurge.operations.d.ts +11 -0
  117. package/dist_ts/objectstorage/internal.exactpathpurge.operations.js +1069 -0
  118. package/dist_ts/objectstorage/internal.exactupload.capability.d.ts +40 -0
  119. package/dist_ts/objectstorage/internal.exactupload.capability.js +382 -0
  120. package/dist_ts/objectstorage/internal.exactupload.operations.d.ts +11 -0
  121. package/dist_ts/objectstorage/internal.exactupload.operations.js +1104 -0
  122. package/dist_ts/objectstorage/internal.multipart.planner.d.ts +8 -0
  123. package/dist_ts/objectstorage/internal.multipart.planner.js +63 -0
  124. package/dist_ts/objectstorage/internal.multipart.stream.d.ts +17 -0
  125. package/dist_ts/objectstorage/internal.multipart.stream.js +440 -0
  126. package/dist_ts/objectstorage/internal.multipart.types.d.ts +82 -0
  127. package/dist_ts/objectstorage/internal.multipart.types.js +2 -0
  128. package/dist_ts/objectstorage/plugins.d.ts +17 -0
  129. package/dist_ts/objectstorage/plugins.js +23 -0
  130. package/dist_ts/plugins.d.ts +4 -0
  131. package/dist_ts/plugins.js +5 -0
  132. package/dist_ts/sqldb/classes.clickhouseconnection.d.ts +39 -0
  133. package/dist_ts/sqldb/classes.clickhouseconnection.js +225 -0
  134. package/dist_ts/sqldb/classes.sqlconnection.d.ts +50 -0
  135. package/dist_ts/sqldb/classes.sqlconnection.js +376 -0
  136. package/dist_ts/sqldb/classes.sqltable.d.ts +29 -0
  137. package/dist_ts/sqldb/classes.sqltable.js +70 -0
  138. package/dist_ts/sqldb/clickhouse/classes.metricwriter.d.ts +27 -0
  139. package/dist_ts/sqldb/clickhouse/classes.metricwriter.js +89 -0
  140. package/dist_ts/sqldb/clickhouse/index.d.ts +9 -0
  141. package/dist_ts/sqldb/clickhouse/index.js +13 -0
  142. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.d.ts +88 -0
  143. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.js +304 -0
  144. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.d.ts +28 -0
  145. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.js +46 -0
  146. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.d.ts +43 -0
  147. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.js +155 -0
  148. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.d.ts +13 -0
  149. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.js +36 -0
  150. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.d.ts +49 -0
  151. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.js +106 -0
  152. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.d.ts +51 -0
  153. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.js +96 -0
  154. package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.d.ts +5 -0
  155. package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.js +6 -0
  156. package/dist_ts/sqldb/clickhouse/smartclickhouse.types.d.ts +53 -0
  157. package/dist_ts/sqldb/clickhouse/smartclickhouse.types.js +41 -0
  158. package/dist_ts/sqldb/index.d.ts +6 -0
  159. package/dist_ts/sqldb/index.js +6 -0
  160. package/dist_ts/sqldb/interfaces.d.ts +53 -0
  161. package/dist_ts/sqldb/interfaces.js +19 -0
  162. package/dist_ts/sqldb/internal.sqlpool.d.ts +51 -0
  163. package/dist_ts/sqldb/internal.sqlpool.js +214 -0
  164. package/dist_ts/sqldb/plugins.clickhouse.d.ts +4 -0
  165. package/dist_ts/sqldb/plugins.clickhouse.js +5 -0
  166. package/dist_ts/sqldb/plugins.mariadb.d.ts +4 -0
  167. package/dist_ts/sqldb/plugins.mariadb.js +5 -0
  168. package/docs/source/smartbucket/license.md +19 -0
  169. package/docs/source/smartclickhouse/license.md +19 -0
  170. package/license.md +21 -0
  171. package/package.json +101 -0
  172. package/readme.md +157 -0
  173. package/ts/00_commitinfo_data.ts +8 -0
  174. package/ts/classes.losslessorgclient.ts +104 -0
  175. package/ts/core/classes.error.ts +31 -0
  176. package/ts/core/classes.operation.ts +60 -0
  177. package/ts/core/interfaces.ts +24 -0
  178. package/ts/index.ts +4 -0
  179. package/ts/nosqldb/classes.atomicdelete.ts +81 -0
  180. package/ts/nosqldb/classes.atomicfindoneandupdate.ts +152 -0
  181. package/ts/nosqldb/classes.atomicupdate.ts +99 -0
  182. package/ts/nosqldb/classes.bootstraprecord.ts +107 -0
  183. package/ts/nosqldb/classes.bsonassertion.ts +25 -0
  184. package/ts/nosqldb/classes.bsonobjectid.ts +45 -0
  185. package/ts/nosqldb/classes.bsonsnapshot.ts +105 -0
  186. package/ts/nosqldb/classes.cached-document.ts +67 -0
  187. package/ts/nosqldb/classes.collection.ts +2399 -0
  188. package/ts/nosqldb/classes.collectionfactory.ts +87 -0
  189. package/ts/nosqldb/classes.collectionlifecycle.ts +24 -0
  190. package/ts/nosqldb/classes.collectionpreparation.ts +164 -0
  191. package/ts/nosqldb/classes.collectiontopology.ts +645 -0
  192. package/ts/nosqldb/classes.connection.ts +31 -0
  193. package/ts/nosqldb/classes.convenience.ts +5 -0
  194. package/ts/nosqldb/classes.cursor.ts +88 -0
  195. package/ts/nosqldb/classes.cursoroperation.ts +38 -0
  196. package/ts/nosqldb/classes.db.ts +637 -0
  197. package/ts/nosqldb/classes.distributedcoordinator.ts +305 -0
  198. package/ts/nosqldb/classes.doc.ts +4928 -0
  199. package/ts/nosqldb/classes.easystore.ts +154 -0
  200. package/ts/nosqldb/classes.exactpersistence.ts +1974 -0
  201. package/ts/nosqldb/classes.lucene.adapter.ts +780 -0
  202. package/ts/nosqldb/classes.mongoadministration.ts +867 -0
  203. package/ts/nosqldb/classes.namespaceinspection.ts +199 -0
  204. package/ts/nosqldb/classes.operationbudget.ts +75 -0
  205. package/ts/nosqldb/classes.ordinarypersistence.ts +84 -0
  206. package/ts/nosqldb/classes.persistence.ts +62 -0
  207. package/ts/nosqldb/classes.session.ts +389 -0
  208. package/ts/nosqldb/classes.storedinspection.ts +151 -0
  209. package/ts/nosqldb/classes.testdatabase.ts +272 -0
  210. package/ts/nosqldb/classes.watcher.ts +96 -0
  211. package/ts/nosqldb/index.ts +51 -0
  212. package/ts/nosqldb/logging.ts +3 -0
  213. package/ts/nosqldb/plugins.ts +37 -0
  214. package/ts/nosqldb/shim.ts +6 -0
  215. package/ts/nosqldb/testsupport.ts +13 -0
  216. package/ts/objectstorage/classes.bucket.ts +1114 -0
  217. package/ts/objectstorage/classes.connection.ts +36 -0
  218. package/ts/objectstorage/classes.directory.ts +425 -0
  219. package/ts/objectstorage/classes.exactpathpurgeerror.ts +24 -0
  220. package/ts/objectstorage/classes.exactuploaderror.ts +25 -0
  221. package/ts/objectstorage/classes.file.ts +303 -0
  222. package/ts/objectstorage/classes.listcursor.ts +89 -0
  223. package/ts/objectstorage/classes.metadata.ts +134 -0
  224. package/ts/objectstorage/classes.smartbucket.ts +445 -0
  225. package/ts/objectstorage/classes.trash.ts +30 -0
  226. package/ts/objectstorage/classes.watcher.ts +289 -0
  227. package/ts/objectstorage/helpers.ts +254 -0
  228. package/ts/objectstorage/index.ts +13 -0
  229. package/ts/objectstorage/interfaces.ts +389 -0
  230. package/ts/objectstorage/internal.exactpathpurge.operations.ts +1936 -0
  231. package/ts/objectstorage/internal.exactupload.capability.ts +580 -0
  232. package/ts/objectstorage/internal.exactupload.operations.ts +1715 -0
  233. package/ts/objectstorage/internal.multipart.planner.ts +90 -0
  234. package/ts/objectstorage/internal.multipart.stream.ts +606 -0
  235. package/ts/objectstorage/internal.multipart.types.ts +106 -0
  236. package/ts/objectstorage/plugins.ts +35 -0
  237. package/ts/plugins.ts +4 -0
  238. package/ts/sqldb/classes.clickhouseconnection.ts +189 -0
  239. package/ts/sqldb/classes.sqlconnection.ts +350 -0
  240. package/ts/sqldb/classes.sqltable.ts +70 -0
  241. package/ts/sqldb/clickhouse/classes.metricwriter.ts +72 -0
  242. package/ts/sqldb/clickhouse/index.ts +16 -0
  243. package/ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.ts +372 -0
  244. package/ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.ts +52 -0
  245. package/ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.ts +120 -0
  246. package/ts/sqldb/clickhouse/smartclickhouse.classes.resultset.ts +44 -0
  247. package/ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.ts +123 -0
  248. package/ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.ts +114 -0
  249. package/ts/sqldb/clickhouse/smartclickhouse.plugins.ts +5 -0
  250. package/ts/sqldb/clickhouse/smartclickhouse.types.ts +134 -0
  251. package/ts/sqldb/index.ts +6 -0
  252. package/ts/sqldb/interfaces.ts +61 -0
  253. package/ts/sqldb/internal.sqlpool.ts +179 -0
  254. package/ts/sqldb/plugins.clickhouse.ts +4 -0
  255. 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
+ }