disk 0.8.14 → 0.8.16

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/dist/index.d.ts CHANGED
@@ -1553,6 +1553,171 @@ interface ListObjectsResult {
1553
1553
  /** The prefix the listing was filtered by, echoed back by the server. */
1554
1554
  prefix?: string;
1555
1555
  }
1556
+ /** A part to list in {@link Disk.completeMultipartUpload}. */
1557
+ interface UploadPart {
1558
+ /** 1-based part number (1..=10000), strictly increasing across the list. */
1559
+ partNumber: number;
1560
+ /** Entity tag returned by {@link Disk.uploadPart} for this part. */
1561
+ etag: string;
1562
+ }
1563
+ /** Handle to an in-progress multipart upload, returned by {@link Disk.createMultipartUpload}. */
1564
+ interface MultipartUpload {
1565
+ /** Server-assigned upload id; pass to uploadPart/complete/abort/listParts. */
1566
+ uploadId: string;
1567
+ /** The object key this upload targets. */
1568
+ key: string;
1569
+ /** The bucket (disk id) the upload lives in. */
1570
+ bucket: string;
1571
+ }
1572
+ /** The assembled object, returned by {@link Disk.completeMultipartUpload}. */
1573
+ interface CompletedMultipartUpload {
1574
+ /** Multipart entity tag — S3's `md5(concat(partMd5s))-N` form. */
1575
+ etag?: string;
1576
+ /** Resource path of the completed object. */
1577
+ location?: string;
1578
+ /** The bucket (disk id). */
1579
+ bucket?: string;
1580
+ /** The object key. */
1581
+ key?: string;
1582
+ }
1583
+ /** One part in a {@link Disk.listParts} listing. */
1584
+ interface PartInfo {
1585
+ /** 1-based part number. */
1586
+ partNumber: number;
1587
+ /** Entity tag the server assigned to this part. */
1588
+ etag?: string;
1589
+ /** Size in bytes. */
1590
+ size: number;
1591
+ /** Time the part was uploaded, if reported. */
1592
+ lastModified?: Date;
1593
+ }
1594
+ interface ListPartsOptions {
1595
+ /** Cap parts returned in one page (server clamps to 1000). */
1596
+ maxParts?: number;
1597
+ /** Return parts after this part number (for pagination). */
1598
+ partNumberMarker?: number;
1599
+ }
1600
+ interface PartListing {
1601
+ /** The bucket (disk id), echoed by the server. */
1602
+ bucket?: string;
1603
+ /** The object key, echoed by the server. */
1604
+ key?: string;
1605
+ /** The upload id, echoed by the server. */
1606
+ uploadId?: string;
1607
+ /** Parts in this page, ascending by part number. */
1608
+ parts: PartInfo[];
1609
+ /** True if more parts exist beyond this page. */
1610
+ isTruncated: boolean;
1611
+ /** The part-number marker this page started after. */
1612
+ partNumberMarker: number;
1613
+ /** Pass back as `partNumberMarker` to fetch the next page. */
1614
+ nextPartNumberMarker?: number;
1615
+ /** Max parts the server was asked to return. */
1616
+ maxParts: number;
1617
+ }
1618
+ /** One in-progress upload in a {@link Disk.listMultipartUploads} listing. */
1619
+ interface MultipartUploadSummary {
1620
+ /** The object key the upload targets. */
1621
+ key: string;
1622
+ /** The upload id. */
1623
+ uploadId: string;
1624
+ /** When the upload was initiated, if reported. */
1625
+ initiated?: Date;
1626
+ }
1627
+ interface ListMultipartUploadsOptions {
1628
+ /** Only list uploads whose key begins with this prefix. */
1629
+ prefix?: string;
1630
+ /** Roll keys up to this delimiter into `commonPrefixes` (S3 supports "/"). */
1631
+ delimiter?: string;
1632
+ /** Resume listing keys after this one (with `uploadIdMarker`). */
1633
+ keyMarker?: string;
1634
+ /** Resume listing uploads after this upload id (requires `keyMarker`). */
1635
+ uploadIdMarker?: string;
1636
+ /** Cap uploads returned in one page (server clamps to 1000). */
1637
+ maxUploads?: number;
1638
+ }
1639
+ interface MultipartUploadListing {
1640
+ /** The bucket (disk id), echoed by the server. */
1641
+ bucket?: string;
1642
+ /** In-progress uploads in this page. */
1643
+ uploads: MultipartUploadSummary[];
1644
+ /** Key prefixes rolled up by `delimiter` (empty if no delimiter). */
1645
+ commonPrefixes: string[];
1646
+ /** True if more uploads exist beyond this page. */
1647
+ isTruncated: boolean;
1648
+ /** The key marker this page started after, echoed back. */
1649
+ keyMarker?: string;
1650
+ /** The upload-id marker this page started after, echoed back. */
1651
+ uploadIdMarker?: string;
1652
+ /** Pass back as `keyMarker` (with `nextUploadIdMarker`) for the next page. */
1653
+ nextKeyMarker?: string;
1654
+ /** Pass back as `uploadIdMarker` (with `nextKeyMarker`) for the next page. */
1655
+ nextUploadIdMarker?: string;
1656
+ /** The prefix the listing was filtered by, echoed back. */
1657
+ prefix?: string;
1658
+ /** The delimiter used, echoed back. */
1659
+ delimiter?: string;
1660
+ /** Max uploads the server was asked to return. */
1661
+ maxUploads?: number;
1662
+ }
1663
+ interface DeleteObjectsOptions {
1664
+ /**
1665
+ * Quiet mode: the server omits the per-key success list and returns only
1666
+ * failures, so the result's `deleted` array is empty. Cuts response size on
1667
+ * large batches. Defaults to false.
1668
+ */
1669
+ quiet?: boolean;
1670
+ }
1671
+ /** A single per-key failure within a {@link Disk.deleteObjects} batch. */
1672
+ interface DeleteObjectsError {
1673
+ /** The key that failed to delete. */
1674
+ key: string;
1675
+ /** S3 error code (e.g. "AccessDenied", "OperationAborted"), if provided. */
1676
+ code?: string;
1677
+ /** Human-readable failure detail, if provided. */
1678
+ message?: string;
1679
+ }
1680
+ interface DeleteObjectsResult {
1681
+ /** Keys the server confirmed deleted (empty in quiet mode). */
1682
+ deleted: string[];
1683
+ /** Per-key failures; empty when every key was deleted. */
1684
+ errors: DeleteObjectsError[];
1685
+ }
1686
+ interface PutObjectOptions {
1687
+ /** MIME type to store the object with. Default "application/octet-stream". */
1688
+ contentType?: string;
1689
+ /**
1690
+ * Bodies larger than this take the multipart path; bodies at or below it take
1691
+ * a single PutObject. Defaults to `partSize` (16 MiB), so by default the
1692
+ * switch happens at the part size. Set it lower (e.g. 5 MiB) to start using
1693
+ * multipart sooner, or to `Infinity` to force a single PutObject.
1694
+ */
1695
+ multipartThreshold?: number;
1696
+ /**
1697
+ * Bytes per part on the multipart path. Clamped to a minimum of 5 MiB (the S3
1698
+ * floor for every part but the last). Default 16 MiB.
1699
+ */
1700
+ partSize?: number;
1701
+ /** Max parts uploaded in parallel on the multipart path. Default 4. */
1702
+ concurrency?: number;
1703
+ }
1704
+ /**
1705
+ * The S3 transport function {@link DiskMultipart} uses, supplied by the owning
1706
+ * {@link Disk} so the namespace shares the disk's credential and endpoint.
1707
+ * @internal
1708
+ */
1709
+ type S3RequestFn = (method: "GET" | "PUT" | "DELETE" | "HEAD" | "POST", key: string, opts?: {
1710
+ body?: string | Uint8Array | ArrayBuffer;
1711
+ contentType?: string;
1712
+ query?: Record<string, string | number>;
1713
+ retry?: boolean;
1714
+ }) => Promise<{
1715
+ ok: boolean;
1716
+ status: number;
1717
+ statusText: string;
1718
+ headers: Headers;
1719
+ body: Uint8Array;
1720
+ }>;
1556
1721
  declare class Disk {
1557
1722
  readonly id: string;
1558
1723
  readonly name: string;
@@ -1576,6 +1741,8 @@ declare class Disk {
1576
1741
  private readonly _archilRegion;
1577
1742
  /** Base URL for the S3-compatible API (port 9000 ingress). Empty if unset. */
1578
1743
  private readonly _s3BaseUrl;
1744
+ /** Lazily-constructed multipart namespace (see {@link multipart}). @internal */
1745
+ private _multipart?;
1579
1746
  /** @internal */
1580
1747
  constructor(data: DiskResponse, client: ApiClient, archilRegion: string, s3BaseUrl?: string);
1581
1748
  toJSON(): DiskResponse;
@@ -1638,15 +1805,52 @@ declare class Disk {
1638
1805
  /** Whether an object exists on the disk (a HeadObject that maps 404 → false). */
1639
1806
  objectExists(key: string): Promise<boolean>;
1640
1807
  /**
1641
- * Write an object to the disk using the S3-compatible PutObject API. Faster
1642
- * than exec for large files no container overhead, no command-length limits.
1643
- * Returns the entity tag the server assigned.
1808
+ * Write an object to the disk via the S3-compatible API. Handles any size:
1809
+ * bodies at or below `multipartThreshold` (defaults to `partSize`, i.e.
1810
+ * 16 MiB) go through a single PutObject request; larger bodies are uploaded as
1811
+ * a multipart upload — split into `partSize` parts, uploaded with bounded
1812
+ * `concurrency` (default 4), and assembled. A failed part aborts the upload so
1813
+ * nothing is left half-staged. For manual control over the multipart
1814
+ * lifecycle, use the {@link multipart} namespace.
1815
+ *
1816
+ * Faster than exec for large files — no container overhead, no command-length
1817
+ * limits. Returns the entity tag the server assigned (a multipart upload's tag
1818
+ * is S3's `md5(concat(partMd5s))-N` form rather than a plain MD5).
1644
1819
  *
1645
- * @param key Path on the disk (e.g. "reports/2026-01/data.json")
1646
- * @param body Contents as a string, Uint8Array/Buffer, or ArrayBuffer
1647
- * @param contentType MIME type (default: "application/octet-stream")
1820
+ * @param key Path on the disk (e.g. "reports/2026-01/data.json")
1821
+ * @param body Contents as a string, Uint8Array/Buffer, or ArrayBuffer
1822
+ * @param options Either a content-type string, or {@link PutObjectOptions}
1823
+ * (`contentType`, `multipartThreshold`, `partSize`,
1824
+ * `concurrency`). Content type defaults to
1825
+ * "application/octet-stream".
1648
1826
  */
1649
- putObject(key: string, body: string | Uint8Array | ArrayBuffer, contentType?: string): Promise<PutObjectResult>;
1827
+ putObject(key: string, body: string | Uint8Array | ArrayBuffer, options?: string | PutObjectOptions): Promise<PutObjectResult>;
1828
+ /**
1829
+ * Upload a large body through the multipart lifecycle: split into `partSize`
1830
+ * parts, upload them with bounded concurrency, then complete — aborting the
1831
+ * upload if any part fails so nothing is left half-staged. @internal
1832
+ */
1833
+ private _putMultipart;
1834
+ /**
1835
+ * Append bytes to an object via the S3-compatible PutObject append extension
1836
+ * (`?append=true`). If the object already exists the bytes are appended to it;
1837
+ * if it doesn't, it is created. Returns the entity tag of the full object
1838
+ * after the append.
1839
+ *
1840
+ * Each call may append at most 1 MiB — the server rejects a larger body with
1841
+ * `EntityTooLarge`. To grow an object past that, append in chunks (or use
1842
+ * {@link putObject} for a one-shot large write).
1843
+ *
1844
+ * Unlike most operations this is NOT auto-retried on a transient error:
1845
+ * append isn't idempotent, so retrying a succeeded-but-unacknowledged append
1846
+ * would duplicate the bytes. On a transient failure, re-append yourself only
1847
+ * after confirming the object's size.
1848
+ *
1849
+ * @param key Path on the disk (e.g. "logs/app.log")
1850
+ * @param body Bytes to append (string, Uint8Array/Buffer, or ArrayBuffer)
1851
+ * @param contentType MIME type, applied only when the object is newly created.
1852
+ */
1853
+ appendObject(key: string, body: string | Uint8Array | ArrayBuffer, contentType?: string): Promise<PutObjectResult>;
1650
1854
  /**
1651
1855
  * Delete an object from the disk via the S3-compatible DeleteObject API.
1652
1856
  * Idempotent: deleting a key that doesn't exist resolves successfully, per
@@ -1683,6 +1887,29 @@ declare class Disk {
1683
1887
  listObjectsPages(prefix?: string, opts?: ListObjectsOptions): AsyncGenerator<ListObjectsResult>;
1684
1888
  /** Fetch a single ListObjectsV2 page. @internal */
1685
1889
  private _listObjectsPage;
1890
+ /**
1891
+ * Delete up to many objects in a single S3-compatible DeleteObjects request.
1892
+ * Unlike {@link deleteObject}, failures are reported per key rather than
1893
+ * thrown: the result's `deleted` lists the keys that were removed and
1894
+ * `errors` lists the ones that weren't (with the server's code/message). A
1895
+ * key that didn't exist still counts as deleted, per S3 semantics.
1896
+ *
1897
+ * The server caps a single request at 1000 keys; this method transparently
1898
+ * splits larger inputs into 1000-key batches and merges the results.
1899
+ *
1900
+ * @param keys Object keys to delete.
1901
+ * @param opts `quiet` suppresses the per-key success list server-side.
1902
+ */
1903
+ deleteObjects(keys: string[], opts?: DeleteObjectsOptions): Promise<DeleteObjectsResult>;
1904
+ /**
1905
+ * The advanced, opt-in multipart-upload API. Drive the raw lifecycle
1906
+ * yourself — `create` → `uploadPart` → `complete` (or `abort`), plus
1907
+ * `listParts` / `listUploads`. Most callers don't need this: {@link putObject}
1908
+ * runs the whole lifecycle automatically for large bodies. Reach for it only
1909
+ * when you need manual control (e.g. uploading parts from separate processes),
1910
+ * and note you then own part-size, memory, and concurrency management.
1911
+ */
1912
+ get multipart(): DiskMultipart;
1686
1913
  /**
1687
1914
  * Send a single request to the disk's S3-compatible endpoint. This reuses the
1688
1915
  * control-plane client purely for its credential and transport — the same
@@ -1705,6 +1932,89 @@ declare class Disk {
1705
1932
  */
1706
1933
  mount(opts?: MountOptions): Promise<unknown>;
1707
1934
  }
1935
+ /**
1936
+ * The advanced, opt-in multipart-upload namespace, reached via {@link Disk.multipart}.
1937
+ * Drives the raw S3 multipart lifecycle — `create` → `uploadPart` → `complete`
1938
+ * (or `abort`), plus `listParts` / `listUploads`. Prefer {@link Disk.putObject},
1939
+ * which runs this lifecycle automatically for large bodies; use this only when
1940
+ * you need manual control, in which case you own part-size, memory, and
1941
+ * concurrency management.
1942
+ */
1943
+ declare class DiskMultipart {
1944
+ private readonly diskId;
1945
+ private readonly s3Request;
1946
+ /** @internal */
1947
+ constructor(diskId: string, s3Request: S3RequestFn);
1948
+ /**
1949
+ * Start a multipart upload (CreateMultipartUpload) and return its `uploadId`.
1950
+ *
1951
+ * @param key Path on the disk the finished object will live at.
1952
+ * @param contentType MIME type to store the object with.
1953
+ */
1954
+ create(key: string, contentType?: string): Promise<MultipartUpload>;
1955
+ /**
1956
+ * Upload one part (UploadPart) and return its entity tag, which you must
1957
+ * collect (with its part number) and pass to {@link complete}. Every part
1958
+ * except the last must be at least 5 MiB.
1959
+ *
1960
+ * @param key The upload's object key.
1961
+ * @param uploadId The id from {@link create}.
1962
+ * @param partNumber 1-based part number (1..=10000).
1963
+ * @param body Part contents as a string, Uint8Array/Buffer, or ArrayBuffer.
1964
+ */
1965
+ uploadPart(key: string, uploadId: string, partNumber: number, body: string | Uint8Array | ArrayBuffer): Promise<UploadPart>;
1966
+ /**
1967
+ * Finish a multipart upload (CompleteMultipartUpload), assembling the listed
1968
+ * parts into one object. Parts are sorted by part number before submission
1969
+ * (the server requires strictly-increasing order).
1970
+ *
1971
+ * Unlike the other operations this is NOT auto-retried on a transient error:
1972
+ * the gateway isn't idempotent for completion, so a retry after a
1973
+ * successful-but-unacknowledged complete would return a spurious NoSuchUpload.
1974
+ * On a transient failure, re-drive completion yourself only after confirming
1975
+ * the object isn't already present.
1976
+ *
1977
+ * @param key The upload's object key.
1978
+ * @param uploadId The id from {@link create}.
1979
+ * @param parts The `{ partNumber, etag }` pairs from {@link uploadPart}.
1980
+ */
1981
+ complete(key: string, uploadId: string, parts: UploadPart[]): Promise<CompletedMultipartUpload>;
1982
+ /**
1983
+ * Abort a multipart upload (AbortMultipartUpload), discarding every staged
1984
+ * part. Idempotent against an upload that's already gone (404 / NoSuchUpload
1985
+ * resolves successfully).
1986
+ *
1987
+ * @param key The upload's object key.
1988
+ * @param uploadId The id from {@link create}.
1989
+ */
1990
+ abort(key: string, uploadId: string): Promise<void>;
1991
+ /**
1992
+ * List the parts already uploaded for an in-progress upload (ListParts).
1993
+ * Returns a single page; follow `nextPartNumberMarker` (when `isTruncated`)
1994
+ * to page through the rest.
1995
+ *
1996
+ * @param key The upload's object key.
1997
+ * @param uploadId The id from {@link create}.
1998
+ * @param opts `maxParts` / `partNumberMarker` pagination controls.
1999
+ */
2000
+ listParts(key: string, uploadId: string, opts?: ListPartsOptions): Promise<PartListing>;
2001
+ /**
2002
+ * List in-progress multipart uploads on the disk (ListMultipartUploads).
2003
+ * Returns a single page; follow `nextKeyMarker` / `nextUploadIdMarker` (when
2004
+ * `isTruncated`) for the rest.
2005
+ *
2006
+ * @param opts Prefix/delimiter filter and pagination markers.
2007
+ */
2008
+ listUploads(opts?: ListMultipartUploadsOptions): Promise<MultipartUploadListing>;
2009
+ }
2010
+ /**
2011
+ * Choose the part size for a `totalBytes` multipart upload. Returns
2012
+ * `requestedPartSize` unless splitting at that size would exceed the server's
2013
+ * 10,000-part cap, in which case it grows the part size (rounded up to a whole
2014
+ * MiB) so the body fits in ≤ 10,000 parts — mirroring boto3's chunk-size
2015
+ * adjustment. Parts only ever get larger, so they stay above the 5 MiB floor.
2016
+ */
2017
+ declare function effectiveUploadPartSize(totalBytes: number, requestedPartSize: number): number;
1708
2018
 
1709
2019
  interface ListDisksOptions {
1710
2020
  limit?: number;
@@ -1877,4 +2187,4 @@ declare function deleteApiKey(id: string): Promise<void>;
1877
2187
  */
1878
2188
  declare function exec(opts: ExecOptions): Promise<ExecDiskResult>;
1879
2189
 
1880
- export { type ApiTokenResponse, Archil, ArchilApiError, ArchilError, type ArchilOptions, ArchilS3Error, type AuthorizedUser, type AwsStsUser, type AzureBlobMount, type ConnectedClient, type CreateApiTokenRequest, type CreateDiskRequest, type CreateDiskResult, Disk, type DiskMetrics, type DiskResponse, type DiskStatus, type DiskUser, Disks, type ExecMount, type ExecMountSpec, type ExecOptions, type ExecRequest, type ExecResult, type GCSMount, type GrepMatch, type GrepOptions, type GrepResult, type GrepStoppedReason, type ListDisksOptions, type ListObjectsOptions, type ListObjectsResult, type ListTokensOptions, type MountConfig, type MountConfigResponse, type MountOptions, type MountResponse, type ObjectMetadata, type PutObjectResult, type R2Mount, type S3CompatibleMount, type S3Mount, type S3Object, type ShareUrlOptions, type ShareUrlResult, type TokenUser, Tokens, USER_AGENT, VERSION, configure, createApiKey, createDisk, deleteApiKey, exec, getDisk, listApiKeys, listDisks };
2190
+ export { type ApiTokenResponse, Archil, ArchilApiError, ArchilError, type ArchilOptions, ArchilS3Error, type AuthorizedUser, type AwsStsUser, type AzureBlobMount, type CompletedMultipartUpload, type ConnectedClient, type CreateApiTokenRequest, type CreateDiskRequest, type CreateDiskResult, type DeleteObjectsError, type DeleteObjectsOptions, type DeleteObjectsResult, Disk, type DiskMetrics, DiskMultipart, type DiskResponse, type DiskStatus, type DiskUser, Disks, type ExecMount, type ExecMountSpec, type ExecOptions, type ExecRequest, type ExecResult, type GCSMount, type GrepMatch, type GrepOptions, type GrepResult, type GrepStoppedReason, type ListDisksOptions, type ListMultipartUploadsOptions, type ListObjectsOptions, type ListObjectsResult, type ListPartsOptions, type ListTokensOptions, type MountConfig, type MountConfigResponse, type MountOptions, type MountResponse, type MultipartUpload, type MultipartUploadListing, type MultipartUploadSummary, type ObjectMetadata, type PartInfo, type PartListing, type PutObjectOptions, type PutObjectResult, type R2Mount, type S3CompatibleMount, type S3Mount, type S3Object, type ShareUrlOptions, type ShareUrlResult, type TokenUser, Tokens, USER_AGENT, type UploadPart, VERSION, configure, createApiKey, createDisk, deleteApiKey, effectiveUploadPartSize, exec, getDisk, listApiKeys, listDisks };