@lossless.org/objectstorage 10.7.1 → 11.0.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 CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "@git.zone/tsrust": {
2
+ "@git.zone/rsrepo": {
3
3
  "targetsByHost": {
4
4
  "linux": [
5
5
  "linux_amd64",
@@ -37,12 +37,17 @@
37
37
  ]
38
38
  }
39
39
  },
40
- "@git.zone/tstest": {
41
- "test": "test/",
42
- "concurrency": 1,
43
- "timeout": 300,
44
- "prepare": {
45
- "once": "tsrust --configured-targets"
40
+ "@git.zone/tsrepo": {
41
+ "test": {
42
+ "test": "test/",
43
+ "concurrency": 1,
44
+ "timeout": 300,
45
+ "prepare": {
46
+ "once": "rsrepo --configured-targets"
47
+ }
48
+ },
49
+ "docs": {
50
+ "legal": "\n## License and Legal Information\n\nThis repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](./license.md) file.\n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.\n\nUse of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District Court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
46
51
  }
47
52
  },
48
53
  "@git.zone/cli": {
@@ -108,9 +113,6 @@
108
113
  }
109
114
  }
110
115
  },
111
- "@git.zone/tsdoc": {
112
- "legal": "\n## License and Legal Information\n\nThis repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](./license.md) file.\n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.\n\nUse of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District Court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
113
- },
114
116
  "@ship.zone/szci": {
115
117
  "npmGlobalTools": []
116
118
  },
Binary file
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "format": "tsrust.build-provenance.v2",
3
- "binarySha256": "9841eb22a91b762d816707e1d1ad7958f1fe7bdb8f810bdc59c8eca4c71a4f23",
3
+ "binarySha256": "1980c7bbf44460d25e11566b17e4712b72f5404c112ff7a5afef9a35b162f32c",
4
4
  "buildInfo": {
5
5
  "projectName": "@lossless.org/objectstorage",
6
- "projectVersion": "10.7.1",
7
- "gitCommit": "375f3c1cdc3fb34abe9a71a7b335832430417f98",
6
+ "projectVersion": "11.0.0",
7
+ "gitCommit": "c81d8670c3a4eb21d8b926861ab0276aed7e1344",
8
8
  "gitDirty": false,
9
- "builtAt": "2026-10-14T17:51:00.129Z",
10
- "tsrustVersion": "4.5.1",
9
+ "builtAt": "2026-11-04T21:59:02.812Z",
10
+ "tsrustVersion": "1.1.1",
11
11
  "binary": "ruststorage",
12
12
  "target": "linux_amd64"
13
13
  }
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "format": "tsrust.build-provenance.v2",
3
- "binarySha256": "f6a034096bfe5f5d27a95772a12af4cb1ca81e0bea801d1038259a0d2c641bf8",
3
+ "binarySha256": "60d85f23387481dcfa616e86e731da9a8fdbac66c9786e26feaa955aec1e8f91",
4
4
  "buildInfo": {
5
5
  "projectName": "@lossless.org/objectstorage",
6
- "projectVersion": "10.7.1",
7
- "gitCommit": "375f3c1cdc3fb34abe9a71a7b335832430417f98",
6
+ "projectVersion": "11.0.0",
7
+ "gitCommit": "c81d8670c3a4eb21d8b926861ab0276aed7e1344",
8
8
  "gitDirty": false,
9
- "builtAt": "2026-10-14T17:51:01.751Z",
10
- "tsrustVersion": "4.5.1",
9
+ "builtAt": "2026-11-04T21:59:04.054Z",
10
+ "tsrustVersion": "1.1.1",
11
11
  "binary": "ruststorage",
12
12
  "target": "linux_amd64_musl"
13
13
  }
Binary file
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "format": "tsrust.build-provenance.v2",
3
- "binarySha256": "067d82cbb87353ae47c3df994618aff871767c773aac883aa92d441095431045",
3
+ "binarySha256": "7c067c7d454c697f2f1f2324a70e68d315fd5705584cb22e34e31d1728de7368",
4
4
  "buildInfo": {
5
5
  "projectName": "@lossless.org/objectstorage",
6
- "projectVersion": "10.7.1",
7
- "gitCommit": "375f3c1cdc3fb34abe9a71a7b335832430417f98",
6
+ "projectVersion": "11.0.0",
7
+ "gitCommit": "c81d8670c3a4eb21d8b926861ab0276aed7e1344",
8
8
  "gitDirty": false,
9
- "builtAt": "2026-10-14T17:51:00.918Z",
10
- "tsrustVersion": "4.5.1",
9
+ "builtAt": "2026-11-04T21:59:03.472Z",
10
+ "tsrustVersion": "1.1.1",
11
11
  "binary": "ruststorage",
12
12
  "target": "linux_arm64"
13
13
  }
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "format": "tsrust.build-provenance.v2",
3
- "binarySha256": "235a10fb515965f293520c649b298704a9be3abbad618765b8258b4911c6b767",
3
+ "binarySha256": "8978c9b56759428a25399843a2cdbc0f08c56aafc7c315189ba2605ff043a725",
4
4
  "buildInfo": {
5
5
  "projectName": "@lossless.org/objectstorage",
6
- "projectVersion": "10.7.1",
7
- "gitCommit": "375f3c1cdc3fb34abe9a71a7b335832430417f98",
6
+ "projectVersion": "11.0.0",
7
+ "gitCommit": "c81d8670c3a4eb21d8b926861ab0276aed7e1344",
8
8
  "gitDirty": false,
9
- "builtAt": "2026-10-14T17:51:02.424Z",
10
- "tsrustVersion": "4.5.1",
9
+ "builtAt": "2026-11-04T21:59:04.554Z",
10
+ "tsrustVersion": "1.1.1",
11
11
  "binary": "ruststorage",
12
12
  "target": "linux_arm64_musl"
13
13
  }
Binary file
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "format": "tsrust.build-provenance.v2",
3
- "binarySha256": "326b74e415950f73198706d35bdb1ecca48dd5a2344f015e80c5228c3a0fc87c",
3
+ "binarySha256": "7fafb5f1a17fabafae190aafe96e6337636c1cab40566715e5ac15af3caed951",
4
4
  "buildInfo": {
5
5
  "projectName": "@lossless.org/objectstorage",
6
- "projectVersion": "10.7.1",
7
- "gitCommit": "375f3c1cdc3fb34abe9a71a7b335832430417f98",
6
+ "projectVersion": "11.0.0",
7
+ "gitCommit": "c81d8670c3a4eb21d8b926861ab0276aed7e1344",
8
8
  "gitDirty": false,
9
- "builtAt": "2026-10-14T18:03:24.210Z",
10
- "tsrustVersion": "4.5.1",
9
+ "builtAt": "2026-11-04T22:26:30.568Z",
10
+ "tsrustVersion": "1.1.1",
11
11
  "binary": "ruststorage",
12
12
  "target": "macos_amd64"
13
13
  }
Binary file
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "format": "tsrust.build-provenance.v2",
3
- "binarySha256": "975efecbbd161d33b33e9ed59bd79da3748a2110efdd002ee7bbe255dd27b310",
3
+ "binarySha256": "b0b608cff5a23cfc2e9afb73539e904c0dcc22902cff02a7b178257431a278ca",
4
4
  "buildInfo": {
5
5
  "projectName": "@lossless.org/objectstorage",
6
- "projectVersion": "10.7.1",
7
- "gitCommit": "375f3c1cdc3fb34abe9a71a7b335832430417f98",
6
+ "projectVersion": "11.0.0",
7
+ "gitCommit": "c81d8670c3a4eb21d8b926861ab0276aed7e1344",
8
8
  "gitDirty": false,
9
- "builtAt": "2026-10-14T18:03:24.893Z",
10
- "tsrustVersion": "4.5.1",
9
+ "builtAt": "2026-11-04T22:26:31.267Z",
10
+ "tsrustVersion": "1.1.1",
11
11
  "binary": "ruststorage",
12
12
  "target": "macos_arm64"
13
13
  }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@lossless.org/objectstorage',
6
- version: '10.7.1',
6
+ version: '11.0.0',
7
7
  description: 'A Node.js TypeScript package to create a local S3-compatible storage server using mapped local directories for development and testing purposes.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSw2QkFBNkI7SUFDbkMsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLGtKQUFrSjtDQUNoSyxDQUFBIn0=
@@ -54,6 +54,11 @@ export interface ILimitsConfig {
54
54
  export interface IMultipartConfig {
55
55
  expirationDays?: number;
56
56
  cleanupIntervalMinutes?: number;
57
+ /**
58
+ * Open multipart uploads that the prefix credentials of one scope (bucket
59
+ * and prefix) may hold together (default 100). Counted in memory.
60
+ */
61
+ maxUploadsPerPrefixScope?: number;
57
62
  }
58
63
  /**
59
64
  * Server configuration
@@ -100,6 +105,11 @@ export interface IStorageConfig {
100
105
  export interface IErasureConfig {
101
106
  dataShards?: number;
102
107
  parityShards?: number;
108
+ /**
109
+ * Bytes per erasure-coded chunk, between 1 and 64 MiB (67,108,864 bytes);
110
+ * startup refuses a value outside that range, because every manifest
111
+ * refuses a larger chunk. Default 4,194,304 (4 MiB).
112
+ */
103
113
  chunkSizeBytes?: number;
104
114
  }
105
115
  /**
@@ -107,6 +117,13 @@ export interface IErasureConfig {
107
117
  */
108
118
  export interface IDriveConfig {
109
119
  paths: string[];
120
+ /**
121
+ * Accept drive roots that share a device (`st_dev`). Each drive root counts
122
+ * as one failure domain, so by default startup refuses two drive roots on
123
+ * one device. Set this only for dev and test clusters whose drive roots are
124
+ * directories on one filesystem. Default false.
125
+ */
126
+ allowSharedDevice?: boolean;
110
127
  }
111
128
  /**
112
129
  * Cluster configuration for distributed mode
@@ -120,6 +137,16 @@ export interface IClusterConfig {
120
137
  drives?: IDriveConfig;
121
138
  heartbeatIntervalMs?: number;
122
139
  heartbeatTimeoutMs?: number;
140
+ /**
141
+ * Longest a single GET may run, in milliseconds, from its start to its last
142
+ * byte, including the client's transfer time. A longer GET is aborted.
143
+ * Superseded and deleted object generations keep their shards for this
144
+ * deadline plus the smaller of the deadline and one hour, then cleanup frees
145
+ * them. Must be the same on every node: a mismatch can abort streams but
146
+ * never serves wrong bytes. Default 21,600,000 (6 hours); allowed from
147
+ * 60,000 (1 minute) to 604,800,000 (7 days).
148
+ */
149
+ getDeadlineMs?: number;
123
150
  }
124
151
  /**
125
152
  * Configuration as the engine receives it: every section resolved.
@@ -281,6 +308,32 @@ export interface IBucketTenantMetadata {
281
308
  region?: string;
282
309
  retention?: IBucketRetentionReceipt;
283
310
  }
311
+ export interface IPrefixCredentialInput {
312
+ bucketName: string;
313
+ /** Unreserved characters (RFC 3986) and `/`; ends with `/`, no leading `/`. */
314
+ prefix: string;
315
+ /** First node: lifetime in seconds, 1..43200. */
316
+ ttlSeconds?: number;
317
+ /** Fan-out to further nodes: the first node's expiresAt (epoch ms). */
318
+ expiresAt?: number;
319
+ /** Supply both together with expiresAt to install an existing credential on another node. */
320
+ accessKeyId?: string;
321
+ secretAccessKey?: string;
322
+ region?: string;
323
+ }
324
+ export interface IPrefixCredentialMetadata {
325
+ accessKeyId: string;
326
+ bucketName: string;
327
+ prefix: string;
328
+ region: string;
329
+ /** Epoch ms. */
330
+ createdAt: number;
331
+ /** Epoch ms; requests are refused from this instant and admitted ones end at it. */
332
+ expiresAt: number;
333
+ }
334
+ export interface IPrefixCredential extends IPrefixCredentialMetadata {
335
+ secretAccessKey: string;
336
+ }
284
337
  export interface IBucketRetentionPolicyInput {
285
338
  mode: 'compliance';
286
339
  policyId: string;
@@ -622,6 +675,10 @@ export interface IObjectStorageHealth {
622
675
  enabled: boolean;
623
676
  credentialCount: number;
624
677
  tenantCredentialCount: number;
678
+ prefixCredentialCount: number;
679
+ prefixCredentialTombstoneCount: number;
680
+ /** False when the prefix credential file is unreadable: every prefix credential is refused. */
681
+ prefixCredentialStoreAvailable: boolean;
625
682
  };
626
683
  bucketCount: number;
627
684
  objectCount: number;
@@ -641,6 +698,12 @@ export declare class ObjectStorageResourceFenceError extends Error {
641
698
  readonly code: TObjectStorageResourceFenceErrorCode;
642
699
  constructor(codeArg: TObjectStorageResourceFenceErrorCode, messageArg: string, causeArg?: unknown);
643
700
  }
701
+ export declare const objectStorageCredentialErrorCodes: readonly ['ECREDENTIAL_AUTH_DISABLED', 'ECREDENTIAL_INVALID_PREFIX', 'ECREDENTIAL_INVALID_TTL', 'ECREDENTIAL_INVALID_EXPIRY', 'ECREDENTIAL_INVALID_KEY', 'ECREDENTIAL_NO_SUCH_BUCKET', 'ECREDENTIAL_BUCKET_UNAVAILABLE', 'ECREDENTIAL_CONFLICT', 'ECREDENTIAL_REVOKED', 'ECREDENTIAL_NOT_PREFIX', 'ECREDENTIAL_LIMIT', 'ECREDENTIAL_PERSISTENCE', 'ECREDENTIAL_STORE_UNAVAILABLE'];
702
+ export type TObjectStorageCredentialErrorCode = (typeof objectStorageCredentialErrorCodes)[number];
703
+ export declare class ObjectStorageCredentialError extends Error {
704
+ readonly code: TObjectStorageCredentialErrorCode;
705
+ constructor(codeArg: TObjectStorageCredentialErrorCode, messageArg: string, causeArg?: unknown);
706
+ }
644
707
  export interface IObjectStorageMetrics {
645
708
  bucketCount: number;
646
709
  objectCount: number;
@@ -694,6 +757,8 @@ export interface IClusterRepairHealth {
694
757
  lastDurationMs?: number;
695
758
  shardsChecked?: number;
696
759
  shardsHealed?: number;
760
+ /** Pending shards (writes that failed at publication) the last scan left pending. */
761
+ shardsPending?: number;
697
762
  failed?: number;
698
763
  lastError?: string;
699
764
  }
@@ -713,6 +778,33 @@ export interface IClusterHealth {
713
778
  erasure?: IClusterErasureHealth;
714
779
  repairs?: IClusterRepairHealth;
715
780
  }
781
+ /**
782
+ * The result of one cluster healing scan, as `ObjectStorage.runHealingScan()`
783
+ * returns it. Times are milliseconds since the Unix epoch.
784
+ */
785
+ export interface IClusterHealingScanResult {
786
+ /** When the scan started; always after the request arrived. */
787
+ startedAt: number;
788
+ completedAt: number;
789
+ durationMs: number;
790
+ /** Shard placements checked at their drives (placements on offline nodes are not). */
791
+ shardsChecked: number;
792
+ /** Shards written: missing placements rebuilt and pending shards completed. */
793
+ shardsHealed: number;
794
+ /** Pending shards (writes that failed at publication) this scan left pending. */
795
+ shardsPending: number;
796
+ /** Failed checks, rebuilds, writes and manifest stores. */
797
+ failed: number;
798
+ }
799
+ export interface IRunHealingScanOptions {
800
+ /**
801
+ * How long to wait for the scan, in milliseconds. Defaults to the bridge's
802
+ * request timeout (300,000). The engine cannot cancel a scan: one that
803
+ * outlasts this keeps running, its result is discarded, and a later call
804
+ * joins the next scan that starts after it.
805
+ */
806
+ timeoutMs?: number;
807
+ }
716
808
  /**
717
809
  * Main ObjectStorage class - production-ready S3-compatible storage server
718
810
  */
@@ -757,6 +849,27 @@ export declare class ObjectStorage {
757
849
  getBucketTenantDescriptor(optionsArg: {
758
850
  bucketName: string;
759
851
  }): Promise<IBucketTenantDescriptor>;
852
+ /**
853
+ * Creates a credential confined to one key prefix of one bucket until its
854
+ * expiry. The first node takes `ttlSeconds`; further nodes of a fan-out take
855
+ * the first result's `accessKeyId`, `secretAccessKey` and `expiresAt`. The
856
+ * secret is returned only here and never kept by this instance.
857
+ */
858
+ createPrefixCredential(inputArg: IPrefixCredentialInput): Promise<IPrefixCredential>;
859
+ /**
860
+ * Revokes a prefix credential on this node. An unknown ID is recorded as
861
+ * revoked too, so a later create for it is refused; `revoked` is true only
862
+ * when a live credential was removed.
863
+ */
864
+ revokePrefixCredential(optionsArg: {
865
+ accessKeyId: string;
866
+ }): Promise<{
867
+ revoked: boolean;
868
+ }>;
869
+ /** Lists this node's live prefix credentials, without secrets. */
870
+ listPrefixCredentials(optionsArg?: {
871
+ bucketName?: string;
872
+ }): Promise<IPrefixCredentialMetadata[]>;
760
873
  getBucketRetentionCapability(): Promise<IBucketRetentionCapability>;
761
874
  getBucketRetentionReceipt(optionsArg: {
762
875
  bucketName: string;
@@ -789,6 +902,18 @@ export declare class ObjectStorage {
789
902
  */
790
903
  replaceCredentials(credentials: IStorageCredential[]): Promise<void>;
791
904
  getClusterHealth(): Promise<IClusterHealth>;
905
+ /**
906
+ * Runs a healing scan on this cluster node and resolves with its result.
907
+ * The scan covers the manifests this node coordinated. The request joins
908
+ * the next scan that starts after it arrives, never one already running,
909
+ * and requests that arrive together share one scan. It rejects in
910
+ * standalone mode, when the scan fails (for example without a majority of
911
+ * the cluster, or when a bucket's manifests cannot be listed), when 16
912
+ * requests already wait for a scan to start, and when the engine shuts down
913
+ * before the scan completes. The engine answers other management calls
914
+ * while the scan runs.
915
+ */
916
+ runHealingScan(optionsArg?: IRunHealingScanOptions): Promise<IClusterHealingScanResult>;
792
917
  getHealth(): Promise<IObjectStorageHealth>;
793
918
  getMetrics(): Promise<IObjectStorageMetrics>;
794
919
  /**