@zero-transfer/sdk 0.3.1 → 0.4.2

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.mts CHANGED
@@ -3,6 +3,7 @@ import { SecureVersion, PeerCertificate } from 'node:tls';
3
3
  import { Readable } from 'node:stream';
4
4
  import { Buffer as Buffer$1 } from 'node:buffer';
5
5
  import { Socket } from 'node:net';
6
+ import { KeyObject } from 'node:crypto';
6
7
 
7
8
  /**
8
9
  * Structured logging contracts and helpers for ZeroTransfer.
@@ -834,7 +835,41 @@ interface TransferEngineOptions {
834
835
  /** Clock used for receipts and progress events. Defaults to `new Date()`. */
835
836
  now?: () => Date;
836
837
  }
837
- /** Executes transfer jobs and produces audit-friendly receipts. */
838
+ /**
839
+ * Executes transfer jobs and produces audit-friendly receipts.
840
+ *
841
+ * The engine is the lowest-level entry point in the transfer stack: it owns
842
+ * retry policy, attempt history, abort propagation, progress event
843
+ * normalization, and receipt construction. Most callers reach the engine
844
+ * indirectly through {@link runRoute}, {@link uploadFile}, {@link downloadFile},
845
+ * {@link copyBetween}, or {@link TransferQueue}; instantiate it directly when
846
+ * you need full control over execution semantics.
847
+ *
848
+ * @example Execute a single job with a custom executor
849
+ * ```ts
850
+ * import { TransferEngine, type TransferExecutor, type TransferJob } from "@zero-transfer/sdk";
851
+ *
852
+ * const engine = new TransferEngine();
853
+ *
854
+ * const executor: TransferExecutor = async ({ job, signal, onProgress }) => {
855
+ * onProgress?.({ jobId: job.id, bytesTransferred: 0 });
856
+ * // … perform the bytes here, honoring `signal` …
857
+ * return { jobId: job.id, bytesTransferred: 1234, completedAt: new Date() };
858
+ * };
859
+ *
860
+ * const job: TransferJob = {
861
+ * id: "manual-1",
862
+ * operation: "upload",
863
+ * source: { profile: localProfile, path: "./data.bin" },
864
+ * destination: { profile: s3Profile, path: "/data/data.bin" },
865
+ * };
866
+ *
867
+ * const receipt = await engine.execute(job, executor, {
868
+ * retry: { maxAttempts: 3, baseDelayMs: 250 },
869
+ * });
870
+ * console.log(receipt.attempts.length); // 1 on success
871
+ * ```
872
+ */
838
873
  declare class TransferEngine {
839
874
  private readonly now;
840
875
  /**
@@ -1417,9 +1452,41 @@ interface RunRouteOptions {
1417
1452
  /**
1418
1453
  * Executes an MFT route as a single transfer through the supplied client.
1419
1454
  *
1455
+ * Connects the source and destination profiles, runs the route's transfer
1456
+ * through the engine, and returns the resulting receipt. The friendly helpers
1457
+ * {@link uploadFile}, {@link downloadFile}, and {@link copyBetween} synthesize
1458
+ * routes and delegate to this function, so behaviour around retry, abort,
1459
+ * progress, timeout, and bandwidth limits is identical.
1460
+ *
1420
1461
  * @param options - Client, route, and optional engine/abort/retry hooks.
1421
1462
  * @returns Receipt produced by the underlying transfer engine.
1422
1463
  * @throws {@link ConfigurationError} When the route is disabled.
1464
+ *
1465
+ * @example Run a pre-built route with progress + retry
1466
+ * ```ts
1467
+ * import { createTransferClient, runRoute, type MftRoute } from "@zero-transfer/sdk";
1468
+ *
1469
+ * const route: MftRoute = {
1470
+ * id: "nightly-export",
1471
+ * operation: "copy",
1472
+ * source: {
1473
+ * path: "/exports/daily.csv",
1474
+ * profile: { host: "sftp.example.com", provider: "sftp", username: "etl" },
1475
+ * },
1476
+ * destination: {
1477
+ * path: "warehouse/daily.csv",
1478
+ * profile: { host: "warehouse", provider: "s3", s3: { region: "us-east-1" } },
1479
+ * },
1480
+ * };
1481
+ *
1482
+ * const receipt = await runRoute({
1483
+ * client,
1484
+ * route,
1485
+ * onProgress: (e) => console.log(`${e.bytesTransferred}/${e.totalBytes ?? "?"}`),
1486
+ * retry: { maxAttempts: 3, baseDelayMs: 500 },
1487
+ * });
1488
+ * console.log(`Job ${receipt.jobId} moved ${receipt.bytesTransferred} bytes…`);
1489
+ * ```
1423
1490
  */
1424
1491
  declare function runRoute(options: RunRouteOptions): Promise<TransferReceipt>;
1425
1492
 
@@ -1593,8 +1660,20 @@ interface ClientDiagnostics {
1593
1660
  /**
1594
1661
  * Returns a redaction-safe snapshot of the providers registered with a client.
1595
1662
  *
1663
+ * Use this when rendering a setup screen, generating a support bundle, or
1664
+ * asserting in tests that the expected provider factories were registered.
1665
+ *
1596
1666
  * @param client - Transfer client to inspect.
1597
1667
  * @returns Provider id and capability snapshot tuples.
1668
+ *
1669
+ * @example List registered providers
1670
+ * ```ts
1671
+ * import { summarizeClientDiagnostics } from "@zero-transfer/sdk";
1672
+ *
1673
+ * for (const { id, capabilities } of summarizeClientDiagnostics(client).providers) {
1674
+ * console.log(`${id}: streaming=${capabilities.readStream} resume=${capabilities.resumeDownload}`);
1675
+ * }
1676
+ * ```
1598
1677
  */
1599
1678
  declare function summarizeClientDiagnostics(client: TransferClient): ClientDiagnostics;
1600
1679
  /** Per-step duration measurements collected by {@link runConnectionDiagnostics}. */
@@ -1647,28 +1726,116 @@ interface RunConnectionDiagnosticsOptions {
1647
1726
  /**
1648
1727
  * Connects to a profile, captures capability and listing samples, and returns a redaction-safe report.
1649
1728
  *
1729
+ * Useful for connectivity "ping" pages, smoke tests, and bug reports. Secrets
1730
+ * in the profile are redacted via {@link redactConnectionProfile} before being
1731
+ * returned. The session is always disconnected before the function returns,
1732
+ * including when probes throw.
1733
+ *
1650
1734
  * @param options - Diagnostic probe options.
1651
1735
  * @returns Diagnostic report including timings and any captured error.
1736
+ *
1737
+ * @example Probe an SFTP connection
1738
+ * ```ts
1739
+ * import { runConnectionDiagnostics } from "@zero-transfer/sdk";
1740
+ *
1741
+ * const report = await runConnectionDiagnostics({
1742
+ * client,
1743
+ * profile: {
1744
+ * host: "sftp.example.com",
1745
+ * provider: "sftp",
1746
+ * username: "deploy",
1747
+ * ssh: { privateKey: { path: "./keys/id_ed25519" } },
1748
+ * },
1749
+ * listPath: "/uploads",
1750
+ * });
1751
+ *
1752
+ * if (!report.ok) {
1753
+ * console.error("connection failed:", report.error);
1754
+ * } else {
1755
+ * console.log(`connect=${report.timings.connectMs}ms list=${report.timings.listMs}ms`);
1756
+ * console.log(report.sample); // up to 5 entries from /uploads
1757
+ * }
1758
+ * ```
1652
1759
  */
1653
1760
  declare function runConnectionDiagnostics(options: RunConnectionDiagnosticsOptions): Promise<ConnectionDiagnosticsResult>;
1654
1761
 
1762
+ /** Options for {@link createPooledTransferClient}. */
1763
+ interface ConnectionPoolOptions {
1764
+ /**
1765
+ * Maximum number of *idle* sessions retained per pool key.
1766
+ *
1767
+ * Active leases are not counted against this limit — the cap only applies
1768
+ * to sessions waiting in the pool. When more than `maxIdlePerKey` sessions
1769
+ * become idle simultaneously, the oldest ones are disconnected. Defaults
1770
+ * to `4`.
1771
+ */
1772
+ maxIdlePerKey?: number;
1773
+ /**
1774
+ * How long an idle session may sit unused before it is automatically
1775
+ * disconnected. Defaults to `60_000` ms. Set to `0` to disable the timer
1776
+ * (idle sessions persist until `drainPool()` is called).
1777
+ */
1778
+ idleTimeoutMs?: number;
1779
+ /**
1780
+ * Custom pool key derivation. Receives the resolved
1781
+ * {@link ConnectionProfile} (after TransferClient validation) and must
1782
+ * return a string. Sessions with matching keys are pooled together; never
1783
+ * include secrets in the key.
1784
+ *
1785
+ * The default derives the key from `provider`, `host`, `port`, and
1786
+ * `username`.
1787
+ */
1788
+ keyOf?: (profile: ConnectionProfile) => string;
1789
+ }
1790
+ /**
1791
+ * Pool-aware {@link TransferClient} returned by
1792
+ * {@link createPooledTransferClient}.
1793
+ */
1794
+ interface PooledTransferClient {
1795
+ /** Opens (or leases) a pooled provider session. */
1796
+ connect(profile: ConnectionProfile): Promise<TransferSession>;
1797
+ /** Inspects the registered providers (delegated to the underlying client). */
1798
+ hasProvider(providerId: ProviderId): boolean;
1799
+ /** Returns the registered capability snapshots (delegated). */
1800
+ getCapabilities(): CapabilitySet[];
1801
+ /** Returns a specific capability snapshot (delegated). */
1802
+ getCapabilities(providerId: ProviderId): CapabilitySet;
1803
+ /**
1804
+ * Disconnects every idle session and prevents further pooling. After
1805
+ * `drainPool()` resolves, subsequent `connect()` calls still work but
1806
+ * always create fresh sessions (and never return them to the pool).
1807
+ */
1808
+ drainPool(): Promise<void>;
1809
+ /** Returns the number of idle sessions currently held in the pool. */
1810
+ poolSize(): number;
1811
+ }
1812
+ /**
1813
+ * Wraps a {@link TransferClient} with connection pooling.
1814
+ *
1815
+ * @param inner - Underlying client used to create real provider sessions.
1816
+ * @param options - Pool sizing, eviction, and key-derivation overrides.
1817
+ * @returns A {@link PooledTransferClient} that reuses idle sessions.
1818
+ */
1819
+ declare function createPooledTransferClient(inner: TransferClient, options?: ConnectionPoolOptions): PooledTransferClient;
1820
+
1655
1821
  /**
1656
1822
  * Built-in provider capability matrix.
1657
1823
  *
1658
1824
  * Aggregates the {@link CapabilitySet} advertised by every shipped provider
1659
1825
  * factory so applications, docs, and diagnostics can compare features across
1660
1826
  * providers without instantiating each one. The S3 entry is captured twice —
1661
- * once with multipart upload disabled (default) and once with multipart
1662
- * upload enabled because that flag flips `resumeUpload`.
1827
+ * once with the new multipart-by-default configuration and once with
1828
+ * `multipart.enabled: false` for the legacy single-shot variant — because
1829
+ * that flag flips `resumeUpload`.
1663
1830
  *
1664
1831
  * @module providers/capabilityMatrix
1665
1832
  */
1666
1833
 
1667
1834
  /** Identifier for an entry in {@link getBuiltinCapabilityMatrix}. */
1668
- type BuiltinProviderMatrixId = ProviderId | "s3:multipart";
1835
+ type BuiltinProviderMatrixId = ProviderId | "s3:single-shot";
1669
1836
  /** Single entry in the built-in capability matrix. */
1670
1837
  interface BuiltinCapabilityMatrixEntry {
1671
- /** Stable matrix identifier (provider id, or `s3:multipart` for the multipart variant). */
1838
+ /** Stable matrix identifier (provider id, or `s3:single-shot` for the legacy variant). */
1672
1839
  id: BuiltinProviderMatrixId;
1673
1840
  /** Human-readable label, suitable for documentation tables. */
1674
1841
  label: string;
@@ -1741,7 +1908,31 @@ interface DropboxProviderOptions {
1741
1908
  *
1742
1909
  * The bearer token is resolved per-connection from `profile.password`. The
1743
1910
  * `profile.host` field is unused; Dropbox connections are identified solely by
1744
- * their token.
1911
+ * their token. Uploads go to `/2/files/upload` (single-shot); resumable upload
1912
+ * sessions are not yet supported.
1913
+ *
1914
+ * @param options - Optional API base URL overrides and fetch implementation.
1915
+ * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
1916
+ *
1917
+ * @example Upload a backup to Dropbox
1918
+ * ```ts
1919
+ * import { createDropboxProviderFactory, createTransferClient, uploadFile } from "@zero-transfer/sdk";
1920
+ *
1921
+ * const client = createTransferClient({ providers: [createDropboxProviderFactory()] });
1922
+ *
1923
+ * await uploadFile({
1924
+ * client,
1925
+ * localPath: "./backups/db.dump",
1926
+ * destination: {
1927
+ * path: "/Backups/2026-04-28/db.dump",
1928
+ * profile: {
1929
+ * host: "",
1930
+ * provider: "dropbox",
1931
+ * password: { env: "DROPBOX_ACCESS_TOKEN" },
1932
+ * },
1933
+ * },
1934
+ * });
1935
+ * ```
1745
1936
  */
1746
1937
  declare function createDropboxProviderFactory(options?: DropboxProviderOptions): ProviderFactory;
1747
1938
 
@@ -1768,7 +1959,34 @@ interface GoogleDriveProviderOptions {
1768
1959
  * Creates a Google Drive provider factory.
1769
1960
  *
1770
1961
  * The bearer token is resolved per-connection from `profile.password`
1771
- * (typically an OAuth 2 access token). `profile.host` is unused.
1962
+ * (typically an OAuth 2 access token). `profile.host` is unused. Set
1963
+ * `rootFolderId` to scope the provider to a shared-drive subtree instead
1964
+ * of the authenticated user's My Drive root.
1965
+ *
1966
+ * @param options - Optional `rootFolderId`, `fetch`, and default headers.
1967
+ * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
1968
+ *
1969
+ * @example Upload to a shared drive folder
1970
+ * ```ts
1971
+ * import { createGoogleDriveProviderFactory, createTransferClient, uploadFile } from "@zero-transfer/sdk";
1972
+ *
1973
+ * const client = createTransferClient({
1974
+ * providers: [createGoogleDriveProviderFactory({ rootFolderId: "0AB1cDeFG2HiJk" })],
1975
+ * });
1976
+ *
1977
+ * await uploadFile({
1978
+ * client,
1979
+ * localPath: "./contracts/2026-Q2.pdf",
1980
+ * destination: {
1981
+ * path: "/Contracts/2026-Q2.pdf",
1982
+ * profile: {
1983
+ * host: "",
1984
+ * provider: "google-drive",
1985
+ * password: { env: "GOOGLE_OAUTH_ACCESS_TOKEN" },
1986
+ * },
1987
+ * },
1988
+ * });
1989
+ * ```
1772
1990
  */
1773
1991
  declare function createGoogleDriveProviderFactory(options?: GoogleDriveProviderOptions): ProviderFactory;
1774
1992
 
@@ -1791,7 +2009,40 @@ interface OneDriveProviderOptions {
1791
2009
  * Creates a OneDrive/SharePoint provider factory backed by Microsoft Graph.
1792
2010
  *
1793
2011
  * The bearer token is resolved per-connection from `profile.password`.
1794
- * `profile.host` is unused.
2012
+ * `profile.host` is unused. To target a SharePoint site or specific drive,
2013
+ * override `driveBaseUrl` with `https://graph.microsoft.com/v1.0/drives/{driveId}`.
2014
+ *
2015
+ * @param options - Optional `driveBaseUrl`, `fetch`, and default headers.
2016
+ * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2017
+ *
2018
+ * @example Upload to the authenticated user's OneDrive
2019
+ * ```ts
2020
+ * import { createOneDriveProviderFactory, createTransferClient, uploadFile } from "@zero-transfer/sdk";
2021
+ *
2022
+ * const client = createTransferClient({
2023
+ * providers: [createOneDriveProviderFactory()],
2024
+ * });
2025
+ *
2026
+ * await uploadFile({
2027
+ * client,
2028
+ * localPath: "./report.xlsx",
2029
+ * destination: {
2030
+ * path: "/Reports/Q2/report.xlsx",
2031
+ * profile: {
2032
+ * host: "",
2033
+ * provider: "one-drive",
2034
+ * password: { env: "GRAPH_ACCESS_TOKEN" },
2035
+ * },
2036
+ * },
2037
+ * });
2038
+ * ```
2039
+ *
2040
+ * @example Target a specific SharePoint drive
2041
+ * ```ts
2042
+ * createOneDriveProviderFactory({
2043
+ * driveBaseUrl: "https://graph.microsoft.com/v1.0/drives/b!abc123",
2044
+ * });
2045
+ * ```
1795
2046
  */
1796
2047
  declare function createOneDriveProviderFactory(options?: OneDriveProviderOptions): ProviderFactory;
1797
2048
 
@@ -1818,7 +2069,48 @@ interface AzureBlobProviderOptions {
1818
2069
  /** Default headers applied before bearer auth on every request. */
1819
2070
  defaultHeaders?: Record<string, string>;
1820
2071
  }
1821
- /** Creates an Azure Blob Storage provider factory. */
2072
+ /**
2073
+ * Creates an Azure Blob Storage provider factory.
2074
+ *
2075
+ * The container is fixed at factory construction time. Authenticate per-connection
2076
+ * with either a SAS token (configured at factory level via {@link AzureBlobProviderOptions.sasToken})
2077
+ * or an AAD bearer token resolved from `profile.password`. Override `endpoint` for
2078
+ * sovereign clouds or local Azurite testing.
2079
+ *
2080
+ * @param options - Container plus optional endpoint, SAS token, fetch override.
2081
+ * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2082
+ *
2083
+ * @example AAD-bearer upload
2084
+ * ```ts
2085
+ * import { createAzureBlobProviderFactory, createTransferClient, uploadFile } from "@zero-transfer/sdk";
2086
+ *
2087
+ * const client = createTransferClient({
2088
+ * providers: [createAzureBlobProviderFactory({ container: "snapshots" })],
2089
+ * });
2090
+ *
2091
+ * await uploadFile({
2092
+ * client,
2093
+ * localPath: "./snapshots/2026-04-28.tar.zst",
2094
+ * destination: {
2095
+ * path: "/2026/04/28/snapshot.tar.zst",
2096
+ * profile: {
2097
+ * host: "mystorageacct",
2098
+ * provider: "azure-blob",
2099
+ * password: { env: "AZURE_AAD_TOKEN" },
2100
+ * },
2101
+ * },
2102
+ * });
2103
+ * ```
2104
+ *
2105
+ * @example SAS-token + Azurite emulator
2106
+ * ```ts
2107
+ * createAzureBlobProviderFactory({
2108
+ * container: "devstoreaccount1",
2109
+ * endpoint: "http://127.0.0.1:10000/devstoreaccount1",
2110
+ * sasToken: "sv=2024-11-04&ss=b&srt=co&sp=rwdlac&se=...",
2111
+ * });
2112
+ * ```
2113
+ */
1822
2114
  declare function createAzureBlobProviderFactory(options: AzureBlobProviderOptions): ProviderFactory;
1823
2115
 
1824
2116
  /** Options accepted by {@link createGcsProviderFactory}. */
@@ -1836,7 +2128,39 @@ interface GcsProviderOptions {
1836
2128
  /** Default headers applied before bearer auth on every request. */
1837
2129
  defaultHeaders?: Record<string, string>;
1838
2130
  }
1839
- /** Creates a Google Cloud Storage provider factory. */
2131
+ /**
2132
+ * Creates a Google Cloud Storage provider factory.
2133
+ *
2134
+ * Authentication is per-connection: pass a Google OAuth 2 access token via
2135
+ * `profile.password`. `profile.host` is unused — the bucket is fixed at
2136
+ * factory construction time so a single client can target multiple buckets
2137
+ * by registering separate factories.
2138
+ *
2139
+ * @param options - Bucket plus optional fetch/transport overrides.
2140
+ * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2141
+ *
2142
+ * @example Bearer-token upload
2143
+ * ```ts
2144
+ * import { createGcsProviderFactory, createTransferClient, uploadFile } from "@zero-transfer/sdk";
2145
+ *
2146
+ * const client = createTransferClient({
2147
+ * providers: [createGcsProviderFactory({ bucket: "my-bucket" })],
2148
+ * });
2149
+ *
2150
+ * await uploadFile({
2151
+ * client,
2152
+ * localPath: "./build/app.tar.gz",
2153
+ * destination: {
2154
+ * path: "releases/2026.04/app.tar.gz",
2155
+ * profile: {
2156
+ * host: "my-bucket",
2157
+ * provider: "gcs",
2158
+ * password: { env: "GCP_OAUTH_ACCESS_TOKEN" },
2159
+ * },
2160
+ * },
2161
+ * });
2162
+ * ```
2163
+ */
1840
2164
  declare function createGcsProviderFactory(options: GcsProviderOptions): ProviderFactory;
1841
2165
 
1842
2166
  /** Fixture entry used to seed a memory provider instance. */
@@ -1854,8 +2178,29 @@ interface MemoryProviderOptions {
1854
2178
  /**
1855
2179
  * Creates a provider factory backed by deterministic in-memory fixture entries.
1856
2180
  *
2181
+ * Useful for tests and examples where you want a real `TransferSession` without
2182
+ * touching disk or the network. Entries are pre-seeded; mutations made through
2183
+ * the session are visible to subsequent operations on the same provider.
2184
+ *
1857
2185
  * @param options - Optional fixture entries to expose through the memory provider.
1858
2186
  * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2187
+ *
2188
+ * @example Seed entries and read them back
2189
+ * ```ts
2190
+ * import { createMemoryProviderFactory, createTransferClient } from "@zero-transfer/sdk";
2191
+ *
2192
+ * const client = createTransferClient({
2193
+ * providers: [createMemoryProviderFactory({
2194
+ * entries: [
2195
+ * { path: "/fixtures/hello.txt", content: "hello world" },
2196
+ * { path: "/fixtures/data.bin", content: new Uint8Array([1, 2, 3]) },
2197
+ * ],
2198
+ * })],
2199
+ * });
2200
+ *
2201
+ * const session = await client.connect({ host: "fixtures", provider: "memory" });
2202
+ * console.log(await session.fs.list("/fixtures"));
2203
+ * ```
1859
2204
  */
1860
2205
  declare function createMemoryProviderFactory(options?: MemoryProviderOptions): ProviderFactory;
1861
2206
 
@@ -1875,8 +2220,45 @@ interface HttpProviderOptions {
1875
2220
  /**
1876
2221
  * Creates a provider factory backed by HTTP(S) GET/HEAD.
1877
2222
  *
1878
- * @param options - Optional provider configuration.
2223
+ * Read-only by design use it to fetch artifacts from public URLs, signed
2224
+ * URLs, or HTTP-only artifact servers. Range-based resume is supported when
2225
+ * the server advertises `Accept-Ranges: bytes`. To upload to an HTTP endpoint,
2226
+ * use the WebDAV provider, the S3 provider, or a cloud-specific provider.
2227
+ *
2228
+ * @param options - Optional id, base path, secure flag, fetch override.
1879
2229
  * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2230
+ *
2231
+ * @example Download a public artifact
2232
+ * ```ts
2233
+ * import { createHttpProviderFactory, createTransferClient, downloadFile } from "@zero-transfer/sdk";
2234
+ *
2235
+ * const client = createTransferClient({ providers: [createHttpProviderFactory()] });
2236
+ *
2237
+ * await downloadFile({
2238
+ * client,
2239
+ * localPath: "./tmp/release.tar.gz",
2240
+ * source: {
2241
+ * path: "/releases/v1.0.0/release.tar.gz",
2242
+ * profile: { host: "downloads.example.com", provider: "http" },
2243
+ * },
2244
+ * });
2245
+ * ```
2246
+ *
2247
+ * @example Bearer-token-protected endpoint
2248
+ * ```ts
2249
+ * await downloadFile({
2250
+ * client,
2251
+ * localPath: "./reports/today.json",
2252
+ * source: {
2253
+ * path: "/reports/today.json",
2254
+ * profile: {
2255
+ * host: "api.example.com",
2256
+ * provider: "http",
2257
+ * password: { env: "REPORTS_TOKEN" },
2258
+ * },
2259
+ * },
2260
+ * });
2261
+ * ```
1880
2262
  */
1881
2263
  declare function createHttpProviderFactory(options?: HttpProviderOptions): ProviderFactory;
1882
2264
 
@@ -1892,12 +2274,61 @@ interface WebDavProviderOptions {
1892
2274
  fetch?: HttpFetch;
1893
2275
  /** Default headers applied to every request. */
1894
2276
  defaultHeaders?: Record<string, string>;
2277
+ /**
2278
+ * Streaming policy for `PUT` request bodies.
2279
+ *
2280
+ * - `"when-known-size"` (default) — stream when the caller declares
2281
+ * `request.totalBytes` (an explicit `Content-Length` is sent so all
2282
+ * WebDAV servers accept the upload); otherwise buffer the entire body in
2283
+ * memory before sending. This is the safe default that does not require
2284
+ * the server to accept HTTP/1.1 chunked transfer-encoding.
2285
+ * - `"always"` — always stream the body, even when the size is unknown
2286
+ * (the runtime will use chunked transfer-encoding). Some legacy WebDAV
2287
+ * servers reject `Transfer-Encoding: chunked` and will respond `411
2288
+ * Length Required` or `501 Not Implemented`; only enable this for
2289
+ * servers known to accept chunked uploads (modern Apache/nginx, IIS
2290
+ * with chunked transfer enabled, Nextcloud, ownCloud, sabre/dav).
2291
+ * - `"never"` — always buffer (legacy behaviour pre-0.4.0). Use for
2292
+ * maximum compatibility at the cost of memory.
2293
+ */
2294
+ uploadStreaming?: "when-known-size" | "always" | "never";
1895
2295
  }
1896
2296
  /**
1897
2297
  * Creates a WebDAV provider factory.
1898
2298
  *
1899
- * @param options - Optional provider configuration.
2299
+ * Talks to any RFC 4918 server: Nextcloud, ownCloud, sabre/dav, Apache `mod_dav`,
2300
+ * IIS WebDAV, etc. PROPFIND drives directory listings, GET supports byte-range
2301
+ * resume on download, and PUT handles uploads. Server-side `COPY` is exposed via
2302
+ * the capability set. Authentication is per-connection from `profile.password`.
2303
+ *
2304
+ * @param options - Optional id, base path, secure flag, fetch, streaming policy.
1900
2305
  * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2306
+ *
2307
+ * @example Upload to Nextcloud
2308
+ * ```ts
2309
+ * import { createTransferClient, createWebDavProviderFactory, uploadFile } from "@zero-transfer/sdk";
2310
+ *
2311
+ * const client = createTransferClient({
2312
+ * providers: [createWebDavProviderFactory({
2313
+ * secure: true,
2314
+ * basePath: "/remote.php/dav/files/alice",
2315
+ * })],
2316
+ * });
2317
+ *
2318
+ * await uploadFile({
2319
+ * client,
2320
+ * localPath: "./contracts/2026.pdf",
2321
+ * destination: {
2322
+ * path: "/Documents/Contracts/2026.pdf",
2323
+ * profile: {
2324
+ * host: "cloud.example.com",
2325
+ * provider: "webdav",
2326
+ * username: "alice",
2327
+ * password: { env: "NEXTCLOUD_APP_PASSWORD" },
2328
+ * },
2329
+ * },
2330
+ * });
2331
+ * ```
1901
2332
  */
1902
2333
  declare function createWebDavProviderFactory(options?: WebDavProviderOptions): ProviderFactory;
1903
2334
 
@@ -1926,7 +2357,14 @@ interface S3ProviderOptions {
1926
2357
  }
1927
2358
  /** Multipart upload tuning for the S3 provider. */
1928
2359
  interface S3MultipartOptions {
1929
- /** Enable multipart upload. Defaults to `false`. */
2360
+ /**
2361
+ * Enable multipart upload. **Defaults to `true`** so large objects stream
2362
+ * in fixed-size parts instead of being buffered in memory before a single
2363
+ * `PUT`. Payloads at or below {@link S3MultipartOptions.thresholdBytes}
2364
+ * still fall back to a single-shot `PUT` automatically. Set to `false` to
2365
+ * force the legacy single-shot behaviour (e.g. when targeting an
2366
+ * S3-compatible endpoint that does not support `CreateMultipartUpload`).
2367
+ */
1930
2368
  enabled?: boolean;
1931
2369
  /** Object size threshold in bytes above which multipart is used. Defaults to 8 MiB. */
1932
2370
  thresholdBytes?: number;
@@ -1972,6 +2410,41 @@ interface S3MultipartResumeStore {
1972
2410
  }
1973
2411
  /** Creates an in-memory {@link S3MultipartResumeStore}. */
1974
2412
  declare function createMemoryS3MultipartResumeStore(): S3MultipartResumeStore;
2413
+ /** Options for {@link createFileSystemS3MultipartResumeStore}. */
2414
+ interface FileSystemS3MultipartResumeStoreOptions {
2415
+ /**
2416
+ * Directory under which checkpoint JSON files are written. Created
2417
+ * recursively if it does not exist. Each upload occupies a single file
2418
+ * named after a SHA-256 hash of the resume key, so the directory is safe
2419
+ * to share across many concurrent uploads.
2420
+ */
2421
+ directory: string;
2422
+ }
2423
+ /**
2424
+ * File-system backed {@link S3MultipartResumeStore} that survives process
2425
+ * restarts. Each in-flight multipart upload is checkpointed to a single
2426
+ * JSON file in `options.directory` after every part. On retry the upload
2427
+ * reuses the stored `uploadId` and skips parts that S3 has already
2428
+ * accepted.
2429
+ *
2430
+ * The implementation writes atomically (`<file>.tmp` then `rename`) so a
2431
+ * crash mid-write cannot leave a corrupt checkpoint.
2432
+ *
2433
+ * @example
2434
+ * ```ts
2435
+ * import { createFileSystemS3MultipartResumeStore, createS3ProviderFactory }
2436
+ * from "@zero-transfer/sdk";
2437
+ *
2438
+ * const resumeStore = createFileSystemS3MultipartResumeStore({
2439
+ * directory: "./.zt-s3-resume",
2440
+ * });
2441
+ *
2442
+ * const factory = createS3ProviderFactory({
2443
+ * multipart: { enabled: true, resumeStore },
2444
+ * });
2445
+ * ```
2446
+ */
2447
+ declare function createFileSystemS3MultipartResumeStore(options: FileSystemS3MultipartResumeStoreOptions): S3MultipartResumeStore;
1975
2448
  /**
1976
2449
  * Creates an S3-compatible provider factory.
1977
2450
  *
@@ -2583,286 +3056,40 @@ declare function redactValue(value: unknown): unknown;
2583
3056
  */
2584
3057
  declare function redactObject(input: Record<string, unknown>): Record<string, unknown>;
2585
3058
 
3059
+ /** Algorithm lists exchanged during SSH KEXINIT negotiation. */
3060
+ interface SshAlgorithmPreferences {
3061
+ compressionClientToServer: readonly string[];
3062
+ compressionServerToClient: readonly string[];
3063
+ encryptionClientToServer: readonly string[];
3064
+ encryptionServerToClient: readonly string[];
3065
+ kexAlgorithms: readonly string[];
3066
+ languagesClientToServer: readonly string[];
3067
+ languagesServerToClient: readonly string[];
3068
+ macClientToServer: readonly string[];
3069
+ macServerToClient: readonly string[];
3070
+ serverHostKeyAlgorithms: readonly string[];
3071
+ }
3072
+ /** Selected algorithms after intersecting client preferences with server capabilities. */
3073
+ interface NegotiatedSshAlgorithms {
3074
+ compressionClientToServer: string;
3075
+ compressionServerToClient: string;
3076
+ encryptionClientToServer: string;
3077
+ encryptionServerToClient: string;
3078
+ kexAlgorithm: string;
3079
+ languageClientToServer?: string;
3080
+ languageServerToClient?: string;
3081
+ macClientToServer: string;
3082
+ macServerToClient: string;
3083
+ serverHostKeyAlgorithm: string;
3084
+ }
2586
3085
  /**
2587
- * FTPS control-channel TLS mode.
2588
- *
2589
- * `explicit` connects on a plain FTP control socket and upgrades with `AUTH TLS`;
2590
- * `implicit` starts TLS immediately, typically on port 990.
3086
+ * Baseline algorithm order for the initial native SSH transport implementation.
2591
3087
  */
2592
- type FtpsMode = "explicit" | "implicit";
3088
+ declare const DEFAULT_SSH_ALGORITHM_PREFERENCES: Readonly<SshAlgorithmPreferences>;
2593
3089
  /**
2594
- * FTPS data-channel protection level requested after TLS negotiation.
2595
- *
2596
- * `private` sends `PROT P` and wraps passive data sockets in TLS. `clear` sends
2597
- * `PROT C`, keeping the control channel encrypted while leaving data sockets plain.
2598
- */
2599
- type FtpsDataProtection = "clear" | "private";
2600
- /**
2601
- * Host selection strategy for PASV data endpoints.
2602
- *
2603
- * `control` connects data sockets back to the control connection host, which avoids
2604
- * broken private or unroutable PASV addresses from NATed servers. `advertised` uses
2605
- * the host supplied by the server's PASV response for deployments that require it.
2606
- */
2607
- type FtpPassiveHostStrategy = "advertised" | "control";
2608
- /** Options used to create the classic FTP provider factory. */
2609
- interface FtpProviderOptions {
2610
- /** Default control port used when a connection profile omits `port`. */
2611
- defaultPort?: number;
2612
- /** PASV host selection strategy. Defaults to `control` for NAT-friendly compatibility. */
2613
- passiveHostStrategy?: FtpPassiveHostStrategy;
2614
- }
2615
- /** Options used to create the FTPS provider factory. */
2616
- interface FtpsProviderOptions extends FtpProviderOptions {
2617
- /** TLS mode used for the control connection. Defaults to explicit FTPS on port 21. */
2618
- mode?: FtpsMode;
2619
- /** Data channel protection requested through PROT. Defaults to private/encrypted data. */
2620
- dataProtection?: FtpsDataProtection;
2621
- }
2622
- /**
2623
- * Creates a provider factory for classic FTP connections.
2624
- *
2625
- * @param options - Optional provider defaults.
2626
- * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2627
- *
2628
- * @example Plain FTP (cleartext — prefer FTPS or SFTP whenever possible)
2629
- * ```ts
2630
- * import { createFtpProviderFactory, createTransferClient } from "@zero-transfer/sdk";
2631
- *
2632
- * const client = createTransferClient({ providers: [createFtpProviderFactory()] });
2633
- *
2634
- * const session = await client.connect({
2635
- * host: "ftp.example.com",
2636
- * provider: "ftp",
2637
- * username: "deploy",
2638
- * password: { env: "FTP_PASSWORD" },
2639
- * });
2640
- * ```
2641
- */
2642
- declare function createFtpProviderFactory(options?: FtpProviderOptions): ProviderFactory;
2643
- /**
2644
- * Creates a provider factory for explicit or implicit FTPS connections.
2645
- *
2646
- * The factory resolves TLS material from each connection profile, upgrades explicit
2647
- * sessions with `AUTH TLS`, and applies the configured `PROT` data-channel policy.
2648
- *
2649
- * @param options - Optional provider defaults.
2650
- * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2651
- *
2652
- * @example FTPS with public-CA TLS (no extra TLS material needed)
2653
- * ```ts
2654
- * import { createFtpsProviderFactory, createTransferClient } from "@zero-transfer/sdk";
2655
- *
2656
- * const client = createTransferClient({ providers: [createFtpsProviderFactory()] });
2657
- *
2658
- * const session = await client.connect({
2659
- * host: "ftps.example.com",
2660
- * provider: "ftps",
2661
- * username: "deploy",
2662
- * password: { env: "FTPS_PASSWORD" },
2663
- * tls: { minVersion: "TLSv1.2" },
2664
- * });
2665
- * ```
2666
- *
2667
- * @example FTPS with private CA + certificate pinning (defence-in-depth)
2668
- * ```ts
2669
- * await client.connect({
2670
- * host: "ftps.internal.example",
2671
- * provider: "ftps",
2672
- * username: "audit",
2673
- * tls: {
2674
- * ca: { path: "./certs/ca-bundle.pem" },
2675
- * cert: { path: "./certs/client.crt" },
2676
- * key: { path: "./certs/client.key" },
2677
- * // Optional but recommended:
2678
- * pinnedFingerprint256: "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99",
2679
- * },
2680
- * });
2681
- * ```
2682
- */
2683
- declare function createFtpsProviderFactory(options?: FtpsProviderOptions): ProviderFactory;
2684
-
2685
- /** FTP response status family derived from the first digit of the reply code. */
2686
- type FtpResponseStatus = "preliminary" | "completion" | "intermediate" | "transientFailure" | "permanentFailure";
2687
- /**
2688
- * Complete parsed FTP response.
2689
- */
2690
- interface FtpResponse {
2691
- /** Numeric three-digit FTP reply code. */
2692
- code: number;
2693
- /** Response message with multi-line content joined by newlines. */
2694
- message: string;
2695
- /** Individual message lines without the reply-code prefix. */
2696
- lines: string[];
2697
- /** Raw response lines joined by newlines. */
2698
- raw: string;
2699
- /** Classified response status family. */
2700
- status: FtpResponseStatus;
2701
- /** Whether the response is a 1xx preliminary reply. */
2702
- preliminary: boolean;
2703
- /** Whether the response is a 2xx completion reply. */
2704
- completion: boolean;
2705
- /** Whether the response is a 3xx intermediate reply. */
2706
- intermediate: boolean;
2707
- /** Whether the response is a 4xx transient failure reply. */
2708
- transientFailure: boolean;
2709
- /** Whether the response is a 5xx permanent failure reply. */
2710
- permanentFailure: boolean;
2711
- }
2712
- /**
2713
- * Stateful parser for socket-delivered FTP response text.
3090
+ * Intersects client and server algorithm lists using SSH's client-priority selection model.
2714
3091
  */
2715
- declare class FtpResponseParser {
2716
- private buffer;
2717
- private pendingResponse;
2718
- /**
2719
- * Adds incoming socket data and returns any complete responses.
2720
- *
2721
- * @param chunk - Buffer or string chunk from the FTP control connection.
2722
- * @returns Zero or more complete parsed responses.
2723
- * @throws {@link ParseError} When a malformed standalone response line is received.
2724
- */
2725
- push(chunk: Buffer | string): FtpResponse[];
2726
- /**
2727
- * Clears buffered text and any incomplete multi-line response state.
2728
- *
2729
- * @returns Nothing.
2730
- */
2731
- reset(): void;
2732
- /**
2733
- * Checks whether the parser is holding buffered or incomplete response data.
2734
- *
2735
- * @returns `true` when there is unconsumed text or an open multi-line response.
2736
- */
2737
- hasPendingResponse(): boolean;
2738
- /**
2739
- * Consumes one line of FTP response text.
2740
- *
2741
- * @param rawLine - Line without a trailing CRLF delimiter.
2742
- * @returns A complete response when the line finishes one, otherwise `undefined`.
2743
- * @throws {@link ParseError} When a malformed standalone line is encountered.
2744
- */
2745
- private consumeLine;
2746
- }
2747
- /**
2748
- * Parses an exact set of response lines into one complete FTP response.
2749
- *
2750
- * @param lines - Raw response lines without trailing newline delimiters.
2751
- * @returns A single complete parsed FTP response.
2752
- * @throws {@link ParseError} When the lines do not contain exactly one complete response.
2753
- */
2754
- declare function parseFtpResponseLines(lines: string[]): FtpResponse;
2755
-
2756
- /**
2757
- * FTP FEAT response parser.
2758
- *
2759
- * This module extracts advertised server capabilities and MLST facts from a parsed
2760
- * FTP response, raw response string, or pre-split response lines.
2761
- *
2762
- * @module providers/classic/ftp/FtpFeatureParser
2763
- */
2764
-
2765
- /**
2766
- * Normalized server features returned by an FTP FEAT command.
2767
- */
2768
- interface FtpFeatures {
2769
- /** Raw normalized feature lines. */
2770
- raw: string[];
2771
- /** Uppercase feature names for fast lookup. */
2772
- names: Set<string>;
2773
- /** MLST facts advertised by the server, preserving required-fact markers. */
2774
- mlstFacts: string[];
2775
- /**
2776
- * Checks whether a named feature is advertised.
2777
- *
2778
- * @param featureName - Feature name to search for, case-insensitively.
2779
- * @returns `true` when the feature appears in the FEAT response.
2780
- */
2781
- supports(featureName: string): boolean;
2782
- }
2783
- /**
2784
- * Parses FTP FEAT output into a normalized feature set.
2785
- *
2786
- * @param input - Parsed FTP response, raw string, or individual response lines.
2787
- * @returns Normalized feature names, raw feature lines, and MLST fact names.
2788
- */
2789
- declare function parseFtpFeatures(input: FtpResponse | string | string[]): FtpFeatures;
2790
-
2791
- /**
2792
- * Parses an MLSD directory listing into normalized remote entries.
2793
- *
2794
- * @param input - Raw MLSD response body.
2795
- * @param directory - Parent remote directory used to build entry paths.
2796
- * @returns Remote entries excluding the `.` and `..` pseudo entries.
2797
- * @throws {@link ParseError} When any listing line is malformed.
2798
- */
2799
- declare function parseMlsdList(input: string, directory?: string): RemoteEntry[];
2800
- /**
2801
- * Parses a Unix-style FTP `LIST` response into normalized remote entries.
2802
- *
2803
- * This parser covers the common `ls -l` shape returned by classic FTP daemons and
2804
- * is used as a compatibility fallback when a server does not support MLSD.
2805
- *
2806
- * @param input - Raw LIST response body.
2807
- * @param directory - Parent remote directory used to build entry paths.
2808
- * @param now - Reference date used when LIST entries include time but omit year.
2809
- * @returns Remote entries excluding `.` and `..` pseudo entries.
2810
- * @throws {@link ParseError} When any non-summary listing line is malformed.
2811
- */
2812
- declare function parseUnixList(input: string, directory?: string, now?: Date): RemoteEntry[];
2813
- /**
2814
- * Parses one Unix-style FTP `LIST` line.
2815
- *
2816
- * @param line - Raw listing line in an `ls -l` compatible format.
2817
- * @param directory - Parent remote directory used to build the entry path.
2818
- * @param now - Reference date used when the line omits a year.
2819
- * @returns Normalized remote entry with raw LIST metadata retained.
2820
- * @throws {@link ParseError} When the line is not a supported Unix LIST entry.
2821
- */
2822
- declare function parseUnixListLine(line: string, directory?: string, now?: Date): RemoteEntry;
2823
- /**
2824
- * Parses a single MLSD or MLST fact line.
2825
- *
2826
- * @param line - Raw fact line in `fact=value; name` format.
2827
- * @param directory - Parent remote directory used to build the entry path.
2828
- * @returns A normalized remote entry with parsed facts in `raw` metadata.
2829
- * @throws {@link ParseError} When the line does not contain facts and a name.
2830
- */
2831
- declare function parseMlsdLine(line: string, directory?: string): RemoteEntry;
2832
- /**
2833
- * Parses the UTC timestamp format used by MLST/MLSD `modify` facts.
2834
- *
2835
- * @param input - Timestamp text such as `20260427010203.123`.
2836
- * @returns A UTC Date when the timestamp is valid, otherwise `undefined`.
2837
- */
2838
- declare function parseMlstTimestamp(input: string | undefined): Date | undefined;
2839
-
2840
- /** Algorithm lists exchanged during SSH KEXINIT negotiation. */
2841
- interface SshAlgorithmPreferences {
2842
- compressionClientToServer: readonly string[];
2843
- compressionServerToClient: readonly string[];
2844
- encryptionClientToServer: readonly string[];
2845
- encryptionServerToClient: readonly string[];
2846
- kexAlgorithms: readonly string[];
2847
- languagesClientToServer: readonly string[];
2848
- languagesServerToClient: readonly string[];
2849
- macClientToServer: readonly string[];
2850
- macServerToClient: readonly string[];
2851
- serverHostKeyAlgorithms: readonly string[];
2852
- }
2853
- /** Selected algorithms after intersecting client preferences with server capabilities. */
2854
- interface NegotiatedSshAlgorithms {
2855
- compressionClientToServer: string;
2856
- compressionServerToClient: string;
2857
- encryptionClientToServer: string;
2858
- encryptionServerToClient: string;
2859
- kexAlgorithm: string;
2860
- languageClientToServer?: string;
2861
- languageServerToClient?: string;
2862
- macClientToServer: string;
2863
- macServerToClient: string;
2864
- serverHostKeyAlgorithm: string;
2865
- }
3092
+ declare function negotiateSshAlgorithms(client: SshAlgorithmPreferences, server: SshAlgorithmPreferences): NegotiatedSshAlgorithms;
2866
3093
 
2867
3094
  /** Parsed SSH identification components from the RFC 4253 banner line. */
2868
3095
  interface SshIdentification {
@@ -2927,6 +3154,62 @@ interface SshTransportHandshakeResult {
2927
3154
  */
2928
3155
  inboundPacketCount: number;
2929
3156
  }
3157
+ /**
3158
+ * Client-side SSH handshake coordinator for version exchange and KEXINIT negotiation.
3159
+ */
3160
+ declare class SshTransportHandshake {
3161
+ private readonly options;
3162
+ private readonly clientAlgorithms;
3163
+ private readonly clientIdentificationLine;
3164
+ private readonly clientKexInitPayload;
3165
+ private readonly identificationLines;
3166
+ private readonly packetFramer;
3167
+ private readonly pendingIdentification;
3168
+ private phase;
3169
+ private inboundPacketCount;
3170
+ private outboundPacketCount;
3171
+ private pendingCurve25519;
3172
+ private pendingKeyExchange;
3173
+ private serverIdentification;
3174
+ constructor(options?: {
3175
+ algorithms?: SshAlgorithmPreferences;
3176
+ clientComments?: string;
3177
+ clientSoftwareVersion?: string;
3178
+ kexCookie?: Uint8Array;
3179
+ /**
3180
+ * Verifies the server's host key after the signature check passes.
3181
+ * Receives the SSH wire-format host key blob and its SHA-256 digest.
3182
+ * Throwing rejects the handshake; resolving accepts it.
3183
+ *
3184
+ * If omitted, the host key is accepted as long as its signature over the
3185
+ * exchange hash verifies. Callers SHOULD supply this hook in production
3186
+ * to enforce known_hosts or pinned-fingerprint policies.
3187
+ */
3188
+ verifyHostKey?: (input: {
3189
+ hostKeyBlob: Buffer$1;
3190
+ hostKeySha256: Buffer$1;
3191
+ algorithmName: string;
3192
+ }) => void | Promise<void>;
3193
+ });
3194
+ /** Creates the first outbound bytes (client identification line). */
3195
+ createInitialClientBytes(): Buffer$1;
3196
+ /**
3197
+ * Feeds raw server bytes into the handshake state machine.
3198
+ */
3199
+ pushServerBytes(chunk: Uint8Array): {
3200
+ outbound: Buffer$1[];
3201
+ result?: SshTransportHandshakeResult;
3202
+ };
3203
+ getServerBannerLines(): readonly string[];
3204
+ isComplete(): boolean;
3205
+ /**
3206
+ * Returns any bytes received after the last complete handshake packet and clears the buffer.
3207
+ * Call this once after `pushServerBytes` returns a result to drain bytes that belong to the
3208
+ * post-NEWKEYS encrypted phase but arrived in the same TCP segment as NEWKEYS.
3209
+ */
3210
+ takeRemainingBytes(): Buffer$1;
3211
+ private pushServerBytesWithPhase;
3212
+ }
2930
3213
 
2931
3214
  /** Standard SSH disconnect reason codes (RFC 4253 §11.1). */
2932
3215
  declare const SshDisconnectReason: {
@@ -3048,6 +3331,78 @@ declare class SshTransportConnection {
3048
3331
  private sendKeepalivePing;
3049
3332
  }
3050
3333
 
3334
+ interface SshPasswordCredential {
3335
+ type: "password";
3336
+ username: string;
3337
+ password: string;
3338
+ }
3339
+ interface SshPublickeyCredential {
3340
+ type: "publickey";
3341
+ username: string;
3342
+ algorithmName: string;
3343
+ /** Raw public key blob in SSH wire format (e.g. the bytes returned by ssh-keygen -e -f key.pub). */
3344
+ publicKeyBlob: Uint8Array;
3345
+ /**
3346
+ * Signs the challenge data. The data is already the complete sign-data per RFC 4252 §7.
3347
+ * Should return the signature blob (without algorithm prefix; caller adds wrapping).
3348
+ */
3349
+ sign: (data: Uint8Array) => Promise<Uint8Array> | Uint8Array;
3350
+ }
3351
+ interface SshKeyboardInteractiveCredential {
3352
+ type: "keyboard-interactive";
3353
+ username: string;
3354
+ /**
3355
+ * Called for each INFO_REQUEST round. Return one string per prompt in order.
3356
+ */
3357
+ respond: (name: string, instruction: string, prompts: Array<{
3358
+ echo: boolean;
3359
+ prompt: string;
3360
+ }>) => Promise<string[]> | string[];
3361
+ }
3362
+ type SshCredential = SshPasswordCredential | SshPublickeyCredential | SshKeyboardInteractiveCredential;
3363
+ interface SshAuthOptions {
3364
+ credential: SshCredential;
3365
+ /** SSH session id (exchange hash) from key exchange — required for publickey signing. */
3366
+ sessionId: Uint8Array;
3367
+ /** Maximum number of USERAUTH_FAILURE retries before giving up. Defaults to 4. */
3368
+ maxAttempts?: number;
3369
+ }
3370
+ interface SshAuthResult {
3371
+ /** Banner lines received from the server during authentication. */
3372
+ bannerLines: string[];
3373
+ /** Auth method that succeeded. */
3374
+ method: string;
3375
+ }
3376
+ /**
3377
+ * Runs SSH user authentication over an encrypted transport connection.
3378
+ *
3379
+ * Call this after `SshTransportConnection.connect()` completes.
3380
+ * Returns a generator of inbound payloads for the upper (connection) layer to consume.
3381
+ * Resolves with an `SshAuthResult` on success; throws `AuthenticationError` on failure.
3382
+ */
3383
+ declare class SshAuthSession {
3384
+ private readonly transport;
3385
+ constructor(transport: SshTransportConnection);
3386
+ authenticate(options: SshAuthOptions): Promise<SshAuthResult>;
3387
+ private runKeyboardInteractiveRounds;
3388
+ private pendingPayload;
3389
+ private nextPayload;
3390
+ private nextPayloadSkippingBanners;
3391
+ }
3392
+
3393
+ interface BuildPublickeyCredentialOptions {
3394
+ /** Username to authenticate as. */
3395
+ username: string;
3396
+ /** Decoded private key (OpenSSH or PKCS8 PEM accepted by `crypto.createPrivateKey`). */
3397
+ privateKey: KeyObject;
3398
+ /**
3399
+ * For RSA keys, the SSH signature algorithm. Defaults to `rsa-sha2-512`.
3400
+ * Ignored for Ed25519 keys.
3401
+ */
3402
+ rsaSignatureAlgorithm?: "rsa-sha2-256" | "rsa-sha2-512";
3403
+ }
3404
+ declare function buildPublickeyCredential(options: BuildPublickeyCredentialOptions): SshPublickeyCredential;
3405
+
3051
3406
  /**
3052
3407
  * SSH session channel (RFC 4254 §6).
3053
3408
  *
@@ -3073,74 +3428,435 @@ interface SshSessionChannelOptions {
3073
3428
  * A single SSH session channel.
3074
3429
  * Not safe to share across concurrent callers; each SftpSession should own one.
3075
3430
  */
3076
- declare class SshSessionChannel {
3077
- private readonly transport;
3078
- private phase;
3079
- /** Remote channel id assigned by the server in OPEN_CONFIRMATION. */
3080
- private remoteChannelId;
3081
- /** Bytes the remote side can still receive before we must stop sending. */
3082
- private remoteWindowRemaining;
3083
- /** Maximum packet data size the remote accepts. */
3084
- private remoteMaxPacketSize;
3085
- /** Local window: bytes we can still accept from remote. */
3086
- private localWindowConsumed;
3087
- private localWindowSize;
3088
- /** Queue of inbound data for the `receiveData()` generator. */
3089
- private readonly inboundQueue;
3090
- private waitingConsumer;
3091
- /** Queue of outbound data waiting for remote window space. */
3092
- private readonly outboundQueue;
3093
- /**
3094
- * FIFO of waiters blocked on remote window credit. Each WINDOW_ADJUST wakes
3095
- * exactly one waiter; concurrent senders must not lose wakeups.
3096
- */
3097
- private readonly outboundDrainedWaiters;
3098
- /** Serializes sendData() calls so byte order on the wire matches call order. */
3099
- private sendChain;
3100
- private readonly localChannelId;
3101
- constructor(transport: SshTransportConnection, options?: SshSessionChannelOptions);
3102
- /**
3103
- * Opens the channel and requests a subsystem.
3104
- * Resolves once the server confirms both CHANNEL_OPEN and the subsystem request.
3105
- */
3106
- openSubsystem(subsystemName: string): Promise<void>;
3431
+ declare class SshSessionChannel {
3432
+ private readonly transport;
3433
+ private phase;
3434
+ /** Remote channel id assigned by the server in OPEN_CONFIRMATION. */
3435
+ private remoteChannelId;
3436
+ /** Bytes the remote side can still receive before we must stop sending. */
3437
+ private remoteWindowRemaining;
3438
+ /** Maximum packet data size the remote accepts. */
3439
+ private remoteMaxPacketSize;
3440
+ /** Local window: bytes we can still accept from remote. */
3441
+ private localWindowConsumed;
3442
+ private localWindowSize;
3443
+ /** Queue of inbound data for the `receiveData()` generator. */
3444
+ private readonly inboundQueue;
3445
+ private waitingConsumer;
3446
+ /** Queue of outbound data waiting for remote window space. */
3447
+ private readonly outboundQueue;
3448
+ /**
3449
+ * FIFO of waiters blocked on remote window credit. Each WINDOW_ADJUST wakes
3450
+ * exactly one waiter; concurrent senders must not lose wakeups.
3451
+ */
3452
+ private readonly outboundDrainedWaiters;
3453
+ /** Serializes sendData() calls so byte order on the wire matches call order. */
3454
+ private sendChain;
3455
+ private readonly localChannelId;
3456
+ constructor(transport: SshTransportConnection, options?: SshSessionChannelOptions);
3457
+ /**
3458
+ * Opens the channel and requests a subsystem.
3459
+ * Resolves once the server confirms both CHANNEL_OPEN and the subsystem request.
3460
+ */
3461
+ openSubsystem(subsystemName: string): Promise<void>;
3462
+ /**
3463
+ * Opens the channel and executes a command.
3464
+ */
3465
+ openExec(command: string): Promise<void>;
3466
+ private openChannel;
3467
+ private requestSubsystem;
3468
+ private requestExec;
3469
+ private awaitChannelRequestReply;
3470
+ /**
3471
+ * Sends data on the channel. Respects the remote window; if there is no space,
3472
+ * splits the data and queues the remainder for when WINDOW_ADJUST arrives.
3473
+ *
3474
+ * Concurrent calls are serialized so wire byte order matches call order.
3475
+ */
3476
+ sendData(data: Uint8Array): Promise<void>;
3477
+ private sendDataLocked;
3478
+ /**
3479
+ * Async generator that yields raw data buffers from the channel.
3480
+ * Returns (done) when the channel receives EOF or CLOSE.
3481
+ */
3482
+ receiveData(): AsyncGenerator<Buffer$1, void, undefined>;
3483
+ /**
3484
+ * Sends EOF and CLOSE. Should be called when the client is done sending.
3485
+ */
3486
+ close(): void;
3487
+ /**
3488
+ * Feed an inbound transport payload to this channel.
3489
+ * Called by the channel multiplexer (`SshConnectionManager`).
3490
+ */
3491
+ dispatch(payload: Buffer$1): void;
3492
+ dispatchError(error: Error): void;
3493
+ private consumeLocalWindow;
3494
+ private enqueueInbound;
3495
+ private dequeueInbound;
3496
+ /** Pull the next payload from the transport (used during channel setup only). */
3497
+ private nextPayload;
3498
+ }
3499
+
3500
+ /**
3501
+ * SSH connection protocol manager (RFC 4254).
3502
+ *
3503
+ * Drives the transport-level `receivePayloads()` generator and dispatches each
3504
+ * payload to the right `SshSessionChannel` by recipient channel id.
3505
+ *
3506
+ * Lifecycle:
3507
+ * 1. Create after auth succeeds.
3508
+ * 2. Call `openSubsystemChannel("sftp")` or `openExecChannel(cmd)` to get a channel.
3509
+ * 3. Drive the pump: `start()` returns a Promise that resolves when the transport
3510
+ * closes cleanly or rejects on a fatal error.
3511
+ */
3512
+
3513
+ declare class SshConnectionManager {
3514
+ private readonly transport;
3515
+ private readonly channels;
3516
+ private nextLocalId;
3517
+ private pumpPromise;
3518
+ private pumpResolve;
3519
+ private pumpReject;
3520
+ /** Payloads that arrived before any channel registered (buffered for the first channel). */
3521
+ private readonly pendingSetupPayloads;
3522
+ private setupPayloadConsumer;
3523
+ constructor(transport: SshTransportConnection);
3524
+ /**
3525
+ * Delivers the next connection-layer payload to callers during channel setup.
3526
+ * Called by `SshSessionChannel` during `openChannel()` / `requestSubsystem()`.
3527
+ *
3528
+ * Channel setup happens sequentially before `start()` begins pumping, so we
3529
+ * pull directly from the transport iterator here.
3530
+ */
3531
+ nextSetupPayload(): Promise<Buffer$1>;
3532
+ /**
3533
+ * Opens a session channel and starts the SFTP subsystem on it.
3534
+ * Must be called before `start()`.
3535
+ */
3536
+ openSubsystemChannel(subsystemName: string): Promise<SshSessionChannel>;
3537
+ /**
3538
+ * Opens a session channel and runs the given command on it.
3539
+ * Must be called before `start()`.
3540
+ */
3541
+ openExecChannel(command: string): Promise<SshSessionChannel>;
3542
+ /**
3543
+ * Starts the main dispatch loop. Returns a Promise that resolves when the
3544
+ * connection closes cleanly, or rejects on a fatal transport error.
3545
+ *
3546
+ * Call this after all channels have been opened and the application is ready
3547
+ * to receive data.
3548
+ */
3549
+ start(): Promise<void>;
3550
+ /**
3551
+ * Runs channel setup (open + request) with a dedicated payload pump that
3552
+ * pulls from the transport iterator and dispatches non-channel-setup messages
3553
+ * to `pendingSetupPayloads` for later processing.
3554
+ */
3555
+ private runChannelSetup;
3556
+ private pump;
3557
+ private dispatch;
3558
+ private terminateChannels;
3559
+ }
3560
+
3561
+ /**
3562
+ * Stateful SSH primitive decoder that reads sequential values from a packet payload.
3563
+ */
3564
+ declare class SshDataReader {
3565
+ private readonly source;
3566
+ private offset;
3567
+ constructor(source: Uint8Array);
3568
+ get remaining(): number;
3569
+ hasMore(): boolean;
3570
+ readByte(): number;
3571
+ readBoolean(): boolean;
3572
+ readBytes(length: number): Buffer$1;
3573
+ readUint32(): number;
3574
+ readUint64(): bigint;
3575
+ readString(): Buffer$1;
3576
+ readUtf8String(): string;
3577
+ readNameList(): string[];
3578
+ /**
3579
+ * Reads an SSH `mpint` value (RFC 4251 §5): a length-prefixed two's-complement
3580
+ * big-endian integer. Returns the raw magnitude bytes (non-negative integers
3581
+ * may have a leading 0x00 byte preserved by the caller as needed).
3582
+ */
3583
+ readMpint(): Buffer$1;
3584
+ assertFinished(): void;
3585
+ private ensureAvailable;
3586
+ }
3587
+
3588
+ /**
3589
+ * Minimal SSH primitive encoder for transport and authentication packets.
3590
+ */
3591
+ declare class SshDataWriter {
3592
+ private readonly chunks;
3593
+ private length;
3594
+ writeByte(value: number): this;
3595
+ writeBoolean(value: boolean): this;
3596
+ writeBytes(value: Uint8Array): this;
3597
+ writeUint32(value: number): this;
3598
+ writeUint64(value: bigint): this;
3599
+ writeString(value: string | Uint8Array, encoding?: BufferEncoding): this;
3600
+ writeMpint(value: Uint8Array): this;
3601
+ writeNameList(values: readonly string[]): this;
3602
+ toBuffer(): Buffer$1;
3603
+ private push;
3604
+ private assertByte;
3605
+ }
3606
+
3607
+ /**
3608
+ * FTPS control-channel TLS mode.
3609
+ *
3610
+ * `explicit` connects on a plain FTP control socket and upgrades with `AUTH TLS`;
3611
+ * `implicit` starts TLS immediately, typically on port 990.
3612
+ */
3613
+ type FtpsMode = "explicit" | "implicit";
3614
+ /**
3615
+ * FTPS data-channel protection level requested after TLS negotiation.
3616
+ *
3617
+ * `private` sends `PROT P` and wraps passive data sockets in TLS. `clear` sends
3618
+ * `PROT C`, keeping the control channel encrypted while leaving data sockets plain.
3619
+ */
3620
+ type FtpsDataProtection = "clear" | "private";
3621
+ /**
3622
+ * Host selection strategy for PASV data endpoints.
3623
+ *
3624
+ * `control` connects data sockets back to the control connection host, which avoids
3625
+ * broken private or unroutable PASV addresses from NATed servers. `advertised` uses
3626
+ * the host supplied by the server's PASV response for deployments that require it.
3627
+ */
3628
+ type FtpPassiveHostStrategy = "advertised" | "control";
3629
+ /** Options used to create the classic FTP provider factory. */
3630
+ interface FtpProviderOptions {
3631
+ /** Default control port used when a connection profile omits `port`. */
3632
+ defaultPort?: number;
3633
+ /** PASV host selection strategy. Defaults to `control` for NAT-friendly compatibility. */
3634
+ passiveHostStrategy?: FtpPassiveHostStrategy;
3635
+ }
3636
+ /** Options used to create the FTPS provider factory. */
3637
+ interface FtpsProviderOptions extends FtpProviderOptions {
3638
+ /** TLS mode used for the control connection. Defaults to explicit FTPS on port 21. */
3639
+ mode?: FtpsMode;
3640
+ /** Data channel protection requested through PROT. Defaults to private/encrypted data. */
3641
+ dataProtection?: FtpsDataProtection;
3642
+ }
3643
+ /**
3644
+ * Creates a provider factory for classic FTP connections.
3645
+ *
3646
+ * @param options - Optional provider defaults.
3647
+ * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
3648
+ *
3649
+ * @example Plain FTP (cleartext — prefer FTPS or SFTP whenever possible)
3650
+ * ```ts
3651
+ * import { createFtpProviderFactory, createTransferClient } from "@zero-transfer/sdk";
3652
+ *
3653
+ * const client = createTransferClient({ providers: [createFtpProviderFactory()] });
3654
+ *
3655
+ * const session = await client.connect({
3656
+ * host: "ftp.example.com",
3657
+ * provider: "ftp",
3658
+ * username: "deploy",
3659
+ * password: { env: "FTP_PASSWORD" },
3660
+ * });
3661
+ * ```
3662
+ */
3663
+ declare function createFtpProviderFactory(options?: FtpProviderOptions): ProviderFactory;
3664
+ /**
3665
+ * Creates a provider factory for explicit or implicit FTPS connections.
3666
+ *
3667
+ * The factory resolves TLS material from each connection profile, upgrades explicit
3668
+ * sessions with `AUTH TLS`, and applies the configured `PROT` data-channel policy.
3669
+ *
3670
+ * @param options - Optional provider defaults.
3671
+ * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
3672
+ *
3673
+ * @example FTPS with public-CA TLS (no extra TLS material needed)
3674
+ * ```ts
3675
+ * import { createFtpsProviderFactory, createTransferClient } from "@zero-transfer/sdk";
3676
+ *
3677
+ * const client = createTransferClient({ providers: [createFtpsProviderFactory()] });
3678
+ *
3679
+ * const session = await client.connect({
3680
+ * host: "ftps.example.com",
3681
+ * provider: "ftps",
3682
+ * username: "deploy",
3683
+ * password: { env: "FTPS_PASSWORD" },
3684
+ * tls: { minVersion: "TLSv1.2" },
3685
+ * });
3686
+ * ```
3687
+ *
3688
+ * @example FTPS with private CA + certificate pinning (defence-in-depth)
3689
+ * ```ts
3690
+ * await client.connect({
3691
+ * host: "ftps.internal.example",
3692
+ * provider: "ftps",
3693
+ * username: "audit",
3694
+ * tls: {
3695
+ * ca: { path: "./certs/ca-bundle.pem" },
3696
+ * cert: { path: "./certs/client.crt" },
3697
+ * key: { path: "./certs/client.key" },
3698
+ * // Optional but recommended:
3699
+ * pinnedFingerprint256: "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99",
3700
+ * },
3701
+ * });
3702
+ * ```
3703
+ */
3704
+ declare function createFtpsProviderFactory(options?: FtpsProviderOptions): ProviderFactory;
3705
+
3706
+ /** FTP response status family derived from the first digit of the reply code. */
3707
+ type FtpResponseStatus = "preliminary" | "completion" | "intermediate" | "transientFailure" | "permanentFailure";
3708
+ /**
3709
+ * Complete parsed FTP response.
3710
+ */
3711
+ interface FtpResponse {
3712
+ /** Numeric three-digit FTP reply code. */
3713
+ code: number;
3714
+ /** Response message with multi-line content joined by newlines. */
3715
+ message: string;
3716
+ /** Individual message lines without the reply-code prefix. */
3717
+ lines: string[];
3718
+ /** Raw response lines joined by newlines. */
3719
+ raw: string;
3720
+ /** Classified response status family. */
3721
+ status: FtpResponseStatus;
3722
+ /** Whether the response is a 1xx preliminary reply. */
3723
+ preliminary: boolean;
3724
+ /** Whether the response is a 2xx completion reply. */
3725
+ completion: boolean;
3726
+ /** Whether the response is a 3xx intermediate reply. */
3727
+ intermediate: boolean;
3728
+ /** Whether the response is a 4xx transient failure reply. */
3729
+ transientFailure: boolean;
3730
+ /** Whether the response is a 5xx permanent failure reply. */
3731
+ permanentFailure: boolean;
3732
+ }
3733
+ /**
3734
+ * Stateful parser for socket-delivered FTP response text.
3735
+ */
3736
+ declare class FtpResponseParser {
3737
+ private buffer;
3738
+ private pendingResponse;
3107
3739
  /**
3108
- * Opens the channel and executes a command.
3740
+ * Adds incoming socket data and returns any complete responses.
3741
+ *
3742
+ * @param chunk - Buffer or string chunk from the FTP control connection.
3743
+ * @returns Zero or more complete parsed responses.
3744
+ * @throws {@link ParseError} When a malformed standalone response line is received.
3109
3745
  */
3110
- openExec(command: string): Promise<void>;
3111
- private openChannel;
3112
- private requestSubsystem;
3113
- private requestExec;
3114
- private awaitChannelRequestReply;
3746
+ push(chunk: Buffer | string): FtpResponse[];
3115
3747
  /**
3116
- * Sends data on the channel. Respects the remote window; if there is no space,
3117
- * splits the data and queues the remainder for when WINDOW_ADJUST arrives.
3748
+ * Clears buffered text and any incomplete multi-line response state.
3118
3749
  *
3119
- * Concurrent calls are serialized so wire byte order matches call order.
3750
+ * @returns Nothing.
3120
3751
  */
3121
- sendData(data: Uint8Array): Promise<void>;
3122
- private sendDataLocked;
3752
+ reset(): void;
3123
3753
  /**
3124
- * Async generator that yields raw data buffers from the channel.
3125
- * Returns (done) when the channel receives EOF or CLOSE.
3754
+ * Checks whether the parser is holding buffered or incomplete response data.
3755
+ *
3756
+ * @returns `true` when there is unconsumed text or an open multi-line response.
3126
3757
  */
3127
- receiveData(): AsyncGenerator<Buffer$1, void, undefined>;
3758
+ hasPendingResponse(): boolean;
3128
3759
  /**
3129
- * Sends EOF and CLOSE. Should be called when the client is done sending.
3760
+ * Consumes one line of FTP response text.
3761
+ *
3762
+ * @param rawLine - Line without a trailing CRLF delimiter.
3763
+ * @returns A complete response when the line finishes one, otherwise `undefined`.
3764
+ * @throws {@link ParseError} When a malformed standalone line is encountered.
3130
3765
  */
3131
- close(): void;
3766
+ private consumeLine;
3767
+ }
3768
+ /**
3769
+ * Parses an exact set of response lines into one complete FTP response.
3770
+ *
3771
+ * @param lines - Raw response lines without trailing newline delimiters.
3772
+ * @returns A single complete parsed FTP response.
3773
+ * @throws {@link ParseError} When the lines do not contain exactly one complete response.
3774
+ */
3775
+ declare function parseFtpResponseLines(lines: string[]): FtpResponse;
3776
+
3777
+ /**
3778
+ * FTP FEAT response parser.
3779
+ *
3780
+ * This module extracts advertised server capabilities and MLST facts from a parsed
3781
+ * FTP response, raw response string, or pre-split response lines.
3782
+ *
3783
+ * @module providers/classic/ftp/FtpFeatureParser
3784
+ */
3785
+
3786
+ /**
3787
+ * Normalized server features returned by an FTP FEAT command.
3788
+ */
3789
+ interface FtpFeatures {
3790
+ /** Raw normalized feature lines. */
3791
+ raw: string[];
3792
+ /** Uppercase feature names for fast lookup. */
3793
+ names: Set<string>;
3794
+ /** MLST facts advertised by the server, preserving required-fact markers. */
3795
+ mlstFacts: string[];
3132
3796
  /**
3133
- * Feed an inbound transport payload to this channel.
3134
- * Called by the channel multiplexer (`SshConnectionManager`).
3797
+ * Checks whether a named feature is advertised.
3798
+ *
3799
+ * @param featureName - Feature name to search for, case-insensitively.
3800
+ * @returns `true` when the feature appears in the FEAT response.
3135
3801
  */
3136
- dispatch(payload: Buffer$1): void;
3137
- dispatchError(error: Error): void;
3138
- private consumeLocalWindow;
3139
- private enqueueInbound;
3140
- private dequeueInbound;
3141
- /** Pull the next payload from the transport (used during channel setup only). */
3142
- private nextPayload;
3802
+ supports(featureName: string): boolean;
3143
3803
  }
3804
+ /**
3805
+ * Parses FTP FEAT output into a normalized feature set.
3806
+ *
3807
+ * @param input - Parsed FTP response, raw string, or individual response lines.
3808
+ * @returns Normalized feature names, raw feature lines, and MLST fact names.
3809
+ */
3810
+ declare function parseFtpFeatures(input: FtpResponse | string | string[]): FtpFeatures;
3811
+
3812
+ /**
3813
+ * Parses an MLSD directory listing into normalized remote entries.
3814
+ *
3815
+ * @param input - Raw MLSD response body.
3816
+ * @param directory - Parent remote directory used to build entry paths.
3817
+ * @returns Remote entries excluding the `.` and `..` pseudo entries.
3818
+ * @throws {@link ParseError} When any listing line is malformed.
3819
+ */
3820
+ declare function parseMlsdList(input: string, directory?: string): RemoteEntry[];
3821
+ /**
3822
+ * Parses a Unix-style FTP `LIST` response into normalized remote entries.
3823
+ *
3824
+ * This parser covers the common `ls -l` shape returned by classic FTP daemons and
3825
+ * is used as a compatibility fallback when a server does not support MLSD.
3826
+ *
3827
+ * @param input - Raw LIST response body.
3828
+ * @param directory - Parent remote directory used to build entry paths.
3829
+ * @param now - Reference date used when LIST entries include time but omit year.
3830
+ * @returns Remote entries excluding `.` and `..` pseudo entries.
3831
+ * @throws {@link ParseError} When any non-summary listing line is malformed.
3832
+ */
3833
+ declare function parseUnixList(input: string, directory?: string, now?: Date): RemoteEntry[];
3834
+ /**
3835
+ * Parses one Unix-style FTP `LIST` line.
3836
+ *
3837
+ * @param line - Raw listing line in an `ls -l` compatible format.
3838
+ * @param directory - Parent remote directory used to build the entry path.
3839
+ * @param now - Reference date used when the line omits a year.
3840
+ * @returns Normalized remote entry with raw LIST metadata retained.
3841
+ * @throws {@link ParseError} When the line is not a supported Unix LIST entry.
3842
+ */
3843
+ declare function parseUnixListLine(line: string, directory?: string, now?: Date): RemoteEntry;
3844
+ /**
3845
+ * Parses a single MLSD or MLST fact line.
3846
+ *
3847
+ * @param line - Raw fact line in `fact=value; name` format.
3848
+ * @param directory - Parent remote directory used to build the entry path.
3849
+ * @returns A normalized remote entry with parsed facts in `raw` metadata.
3850
+ * @throws {@link ParseError} When the line does not contain facts and a name.
3851
+ */
3852
+ declare function parseMlsdLine(line: string, directory?: string): RemoteEntry;
3853
+ /**
3854
+ * Parses the UTC timestamp format used by MLST/MLSD `modify` facts.
3855
+ *
3856
+ * @param input - Timestamp text such as `20260427010203.123`.
3857
+ * @returns A UTC Date when the timestamp is valid, otherwise `undefined`.
3858
+ */
3859
+ declare function parseMlstTimestamp(input: string | undefined): Date | undefined;
3144
3860
 
3145
3861
  /**
3146
3862
  * SFTP v3 file attribute encoding and decoding (draft-ietf-secsh-filexfer-02 §5).
@@ -3311,6 +4027,15 @@ interface NativeSftpProviderOptions {
3311
4027
  * traffic. Disabled when omitted or `0`.
3312
4028
  */
3313
4029
  keepaliveIntervalMs?: number;
4030
+ /**
4031
+ * Maximum concurrent file-transfer operations the engine should schedule
4032
+ * against a single SFTP session. Each in-flight read/write occupies an
4033
+ * outstanding SFTP request slot multiplexed over the same SSH channel; the
4034
+ * default of `8` keeps memory bounded on commodity servers, but high-RTT
4035
+ * links and modern OpenSSH builds can comfortably handle 16\u201364. Must be
4036
+ * a positive integer.
4037
+ */
4038
+ maxConcurrency?: number;
3314
4039
  }
3315
4040
  /**
3316
4041
  * Low-level handles exposed by a native SFTP session for diagnostics and
@@ -3594,9 +4319,47 @@ interface TransferPlanSummary {
3594
4319
  /** Counts grouped by action. */
3595
4320
  actions: Record<string, number>;
3596
4321
  }
3597
- /** Creates a transfer plan from dry-run planning input. */
4322
+ /**
4323
+ * Creates a transfer plan from dry-run planning input.
4324
+ *
4325
+ * Plans are immutable, structured descriptions of intended work. Pair with
4326
+ * {@link createSyncPlan} or {@link createAtomicDeployPlan} for end-to-end
4327
+ * planning, or build steps by hand when you need full control. Pass the plan
4328
+ * to {@link createTransferJobsFromPlan} to materialize executable jobs.
4329
+ *
4330
+ * @example Build a plan with two upload steps and inspect it
4331
+ * ```ts
4332
+ * import { createTransferPlan, summarizeTransferPlan } from "@zero-transfer/sdk";
4333
+ *
4334
+ * const plan = createTransferPlan({
4335
+ * id: "manual-batch",
4336
+ * steps: [
4337
+ * { action: "upload", source: "./a.bin", destination: "/lake/a.bin", expectedBytes: 1024 },
4338
+ * { action: "upload", source: "./b.bin", destination: "/lake/b.bin", expectedBytes: 2048 },
4339
+ * ],
4340
+ * });
4341
+ *
4342
+ * console.table(summarizeTransferPlan(plan));
4343
+ * ```
4344
+ */
3598
4345
  declare function createTransferPlan(input: TransferPlanInput): TransferPlan;
3599
- /** Summarizes a transfer plan for diagnostics, previews, and tests. */
4346
+ /**
4347
+ * Summarizes a transfer plan for diagnostics, previews, and tests.
4348
+ *
4349
+ * Returns aggregate counts (total / executable / skipped / destructive),
4350
+ * total expected bytes, and a per-action histogram. Useful for printing a
4351
+ * one-line plan summary before executing or for asserting plan shape in
4352
+ * tests.
4353
+ *
4354
+ * @example Print a plan preview
4355
+ * ```ts
4356
+ * import { summarizeTransferPlan } from "@zero-transfer/sdk";
4357
+ *
4358
+ * const summary = summarizeTransferPlan(plan);
4359
+ * console.log(`${summary.executableSteps} steps, ${summary.totalExpectedBytes} bytes total`);
4360
+ * console.log("Actions:", summary.actions);
4361
+ * ```
4362
+ */
3600
4363
  declare function summarizeTransferPlan(plan: TransferPlan): TransferPlanSummary;
3601
4364
  /** Converts executable plan steps into transfer jobs while preserving order. */
3602
4365
  declare function createTransferJobsFromPlan(plan: TransferPlan): TransferJob[];
@@ -3673,7 +4436,41 @@ interface TransferQueueSummary {
3673
4436
  /** Failed queue items in queue order. */
3674
4437
  failures: TransferQueueItem[];
3675
4438
  }
3676
- /** Minimal transfer queue with concurrency, pause/resume, cancellation, and drain summaries. */
4439
+ /**
4440
+ * Minimal transfer queue with concurrency, pause/resume, cancellation, and drain summaries.
4441
+ *
4442
+ * Wrap a {@link TransferEngine} with a queue when you need to run many transfers
4443
+ * concurrently with bounded parallelism, observe per-job progress, or drive
4444
+ * a UI from a single source of truth. Items are FIFO; failures and successes
4445
+ * are surfaced via observers and in the final {@link TransferQueueSummary}.
4446
+ *
4447
+ * @example Run a batch of uploads with concurrency=4
4448
+ * ```ts
4449
+ * import {
4450
+ * TransferQueue,
4451
+ * createProviderTransferExecutor,
4452
+ * } from "@zero-transfer/sdk";
4453
+ *
4454
+ * const queue = new TransferQueue({
4455
+ * concurrency: 4,
4456
+ * executor: createProviderTransferExecutor({ client }),
4457
+ * onProgress: (e) => console.log(`${e.jobId}: ${e.bytesTransferred}`),
4458
+ * onError: (item, err) => console.error(`${item.job.id} failed`, err),
4459
+ * });
4460
+ *
4461
+ * for (const file of files) {
4462
+ * queue.enqueue({
4463
+ * id: file.name,
4464
+ * operation: "upload",
4465
+ * source: { profile: localProfile, path: file.path },
4466
+ * destination: { profile: s3Profile, path: `/lake/${file.name}` },
4467
+ * });
4468
+ * }
4469
+ *
4470
+ * const summary = await queue.drain();
4471
+ * console.log(`Completed ${summary.completed} / ${summary.total}`);
4472
+ * ```
4473
+ */
3677
4474
  declare class TransferQueue {
3678
4475
  private readonly engine;
3679
4476
  private readonly items;
@@ -3953,6 +4750,26 @@ interface DiffRemoteTreesOptions {
3953
4750
  * @param destinationPath - Destination-side root path being compared.
3954
4751
  * @param options - Optional comparison controls.
3955
4752
  * @returns Diff result containing entries and a summary.
4753
+ *
4754
+ * @example Diff two SFTP subtrees and feed the result into createSyncPlan
4755
+ * ```ts
4756
+ * import { createSyncPlan, diffRemoteTrees } from "@zero-transfer/sdk";
4757
+ *
4758
+ * const diff = await diffRemoteTrees(
4759
+ * srcSession.fs, "/exports",
4760
+ * dstSession.fs, "/exports",
4761
+ * { compareUniqueId: true },
4762
+ * );
4763
+ *
4764
+ * console.log(diff.summary); // { added, removed, changed, unchanged }
4765
+ *
4766
+ * const plan = createSyncPlan({
4767
+ * id: "exports-sync",
4768
+ * diff,
4769
+ * source: { provider: "sftp", rootPath: "/exports" },
4770
+ * destination: { provider: "sftp", rootPath: "/exports" },
4771
+ * });
4772
+ * ```
3956
4773
  */
3957
4774
  declare function diffRemoteTrees(source: RemoteFileSystem, sourcePath: string, destination: RemoteFileSystem, destinationPath: string, options?: DiffRemoteTreesOptions): Promise<RemoteTreeDiff>;
3958
4775
 
@@ -4024,6 +4841,31 @@ interface CreateSyncPlanOptions {
4024
4841
  * @param options - Inputs and policies that shape the plan.
4025
4842
  * @returns Transfer plan ready for `createTransferJobsFromPlan` or queue execution.
4026
4843
  * @throws {@link ConfigurationError} When `conflictPolicy: "error"` encounters a conflict.
4844
+ *
4845
+ * @example Mirror SFTP → S3 with deletes
4846
+ * ```ts
4847
+ * import {
4848
+ * createSyncPlan,
4849
+ * diffRemoteTrees,
4850
+ * summarizeTransferPlan,
4851
+ * } from "@zero-transfer/sdk";
4852
+ *
4853
+ * const diff = await diffRemoteTrees(
4854
+ * srcSession.fs, "/dist",
4855
+ * dstSession.fs, "/releases/current",
4856
+ * );
4857
+ *
4858
+ * const plan = createSyncPlan({
4859
+ * id: "release-mirror",
4860
+ * diff,
4861
+ * source: { provider: "sftp", rootPath: "/dist" },
4862
+ * destination: { provider: "s3", rootPath: "/releases/current" },
4863
+ * deletePolicy: "mirror",
4864
+ * conflictPolicy: "overwrite",
4865
+ * });
4866
+ *
4867
+ * console.table(summarizeTransferPlan(plan));
4868
+ * ```
4027
4869
  */
4028
4870
  declare function createSyncPlan(options: CreateSyncPlanOptions): TransferPlan;
4029
4871
 
@@ -4139,9 +4981,39 @@ interface CreateAtomicDeployPlanOptions {
4139
4981
  /**
4140
4982
  * Builds an {@link AtomicDeployPlan} that stages a release, swaps it live, and prunes old releases.
4141
4983
  *
4984
+ * The plan describes a blue/green-style deploy:
4985
+ * 1. Upload to a timestamped staging directory under `<destination>/.releases/`.
4986
+ * 2. Atomically swap the `current` symlink/rename to point at the new release.
4987
+ * 3. Optionally prune old releases beyond `retain`.
4988
+ *
4989
+ * No I/O is performed — the host executes the plan steps. Pair with
4990
+ * {@link createTransferPlan} or {@link createTransferJobsFromPlan} to execute.
4991
+ *
4142
4992
  * @param options - Inputs and policies that shape the deploy.
4143
4993
  * @returns Structured deploy plan ready for execution by the calling host.
4144
4994
  * @throws {@link ConfigurationError} When `retain` is less than `1` or the destination root is empty.
4995
+ *
4996
+ * @example Plan a release with rollback path
4997
+ * ```ts
4998
+ * import { createAtomicDeployPlan } from "@zero-transfer/sdk";
4999
+ *
5000
+ * const plan = createAtomicDeployPlan({
5001
+ * id: "web-2026-04-28",
5002
+ * source: { rootPath: "./dist" },
5003
+ * destination: {
5004
+ * profile: { host: "web1.example.com", provider: "sftp", username: "deploy" },
5005
+ * rootPath: "/srv/www",
5006
+ * },
5007
+ * retain: 5,
5008
+ * existingReleases: [
5009
+ * "/srv/www/.releases/2026-04-21T00-00-00Z",
5010
+ * "/srv/www/.releases/2026-04-14T00-00-00Z",
5011
+ * ],
5012
+ * });
5013
+ *
5014
+ * console.log(plan.swap); // staging → current rename
5015
+ * console.log(plan.prune); // releases scheduled for removal
5016
+ * ```
4145
5017
  */
4146
5018
  declare function createAtomicDeployPlan(options: CreateAtomicDeployPlanOptions): AtomicDeployPlan;
4147
5019
 
@@ -4641,9 +5513,33 @@ interface CreateWebhookAuditLogOptions {
4641
5513
  *
4642
5514
  * Entries whose `type` is not in `target.types` are silently dropped. `list()`
4643
5515
  * always returns an empty array because webhook deliveries are not buffered.
5516
+ * Payloads are HMAC-signed with `target.secret` (when provided) so receivers
5517
+ * can verify authenticity before acting on them.
4644
5518
  *
4645
5519
  * @param options - Webhook target plus optional retry/observer hooks.
4646
5520
  * @returns An audit log that delivers each `record` call to the webhook.
5521
+ *
5522
+ * @example Compose a webhook log with an in-memory log for local replay
5523
+ * ```ts
5524
+ * import {
5525
+ * InMemoryAuditLog,
5526
+ * composeAuditLogs,
5527
+ * createWebhookAuditLog,
5528
+ * } from "@zero-transfer/sdk";
5529
+ *
5530
+ * const memory = new InMemoryAuditLog();
5531
+ * const webhook = createWebhookAuditLog({
5532
+ * target: {
5533
+ * url: "https://hooks.example.com/zt",
5534
+ * secret: { env: "ZT_WEBHOOK_SECRET" },
5535
+ * types: ["transfer.success", "transfer.failure"],
5536
+ * },
5537
+ * onDelivery: ({ result }) => console.log("delivered", result.statusCode),
5538
+ * });
5539
+ *
5540
+ * const audit = composeAuditLogs(memory, webhook);
5541
+ * await audit.record({ type: "transfer.success", receipt });
5542
+ * ```
4647
5543
  */
4648
5544
  declare function createWebhookAuditLog(options: CreateWebhookAuditLogOptions): MftAuditLog;
4649
5545
 
@@ -4798,7 +5694,48 @@ interface MftSchedulerOptions {
4798
5694
  /** Timer/clock injection used by tests. */
4799
5695
  timer?: ScheduleTimerHooks;
4800
5696
  }
4801
- /** Runs routes on configured schedules. */
5697
+ /**
5698
+ * Runs routes on configured schedules.
5699
+ *
5700
+ * Subscribes to a {@link ScheduleRegistry}, computes the next fire time for
5701
+ * each schedule (cron or interval), and dispatches the matching route through
5702
+ * a runner of your choice (`runRoute` by default, or a wrapped runner for
5703
+ * approvals / rate limiting / circuit breaking). Observers fire on each cycle
5704
+ * for telemetry. Tests can inject a deterministic timer via `timer`.
5705
+ *
5706
+ * @example Wire a cron schedule with audit + approval
5707
+ * ```ts
5708
+ * import {
5709
+ * ApprovalRegistry,
5710
+ * InMemoryAuditLog,
5711
+ * MftScheduler,
5712
+ * RouteRegistry,
5713
+ * ScheduleRegistry,
5714
+ * createApprovalGate,
5715
+ * runRoute,
5716
+ * } from "@zero-transfer/sdk";
5717
+ *
5718
+ * const audit = new InMemoryAuditLog();
5719
+ * const approvals = new ApprovalRegistry();
5720
+ *
5721
+ * const scheduler = new MftScheduler({
5722
+ * client,
5723
+ * routes: new RouteRegistry([route]),
5724
+ * schedules: new ScheduleRegistry([
5725
+ * { id: "nightly", routeId: route.id, cron: "0 2 * * *" },
5726
+ * ]),
5727
+ * runner: createApprovalGate({
5728
+ * registry: approvals,
5729
+ * approvalId: ({ route }) => `release:${route.id}`,
5730
+ * runner: ({ client: c, route: r, signal }) => runRoute({ client: c, route: r, signal }),
5731
+ * }),
5732
+ * onResult: ({ receipt }) => audit.record({ type: "transfer.success", receipt }),
5733
+ * onError: ({ error }) => audit.record({ type: "transfer.failure", error }),
5734
+ * });
5735
+ *
5736
+ * scheduler.start();
5737
+ * ```
5738
+ */
4802
5739
  declare class MftScheduler {
4803
5740
  private readonly options;
4804
5741
  private readonly now;
@@ -4942,10 +5879,33 @@ interface CreateApprovalGateOptions {
4942
5879
  *
4943
5880
  * The returned runner creates an approval request, waits for resolution, and
4944
5881
  * dispatches the underlying runner only when the request is approved. Rejection
4945
- * surfaces an {@link ApprovalRejectedError}.
5882
+ * surfaces an {@link ApprovalRejectedError}. Pair with {@link MftScheduler} to
5883
+ * implement two-person rules and human-in-the-loop release flows.
4946
5884
  *
4947
5885
  * @param options - Registry, downstream runner, approval-id derivation, hooks.
4948
5886
  * @returns A {@link ScheduleRouteRunner} that gates execution behind approval.
5887
+ *
5888
+ * @example Two-person rule on a release route
5889
+ * ```ts
5890
+ * import {
5891
+ * ApprovalRegistry,
5892
+ * createApprovalGate,
5893
+ * runRoute,
5894
+ * } from "@zero-transfer/sdk";
5895
+ *
5896
+ * const approvals = new ApprovalRegistry();
5897
+ *
5898
+ * const gatedRunner = createApprovalGate({
5899
+ * registry: approvals,
5900
+ * approvalId: ({ route }) => `release:${route.id}:${Date.now()}`,
5901
+ * onRequested: (req) => notifyOnCallChannel(req),
5902
+ * runner: ({ client, route, signal }) => runRoute({ client, route, signal }),
5903
+ * });
5904
+ *
5905
+ * // Elsewhere, an authorized operator approves or rejects:
5906
+ * approvals.approve(approvalId, { actor: "alice@example.com" });
5907
+ * // approvals.reject(approvalId, { actor: "bob@example.com", reason: "hold release" });
5908
+ * ```
4949
5909
  */
4950
5910
  declare function createApprovalGate(options: CreateApprovalGateOptions): ScheduleRouteRunner;
4951
5911
 
@@ -5020,4 +5980,4 @@ declare function joinRemotePath(...segments: string[]): string;
5020
5980
  */
5021
5981
  declare function basenameRemotePath(input: string): string;
5022
5982
 
5023
- export { AbortError, type AgeRetentionPolicy, ApprovalRegistry, ApprovalRejectedError, type ApprovalRequest, type ApprovalStatus, type AtomicDeployActivateOperation, type AtomicDeployActivateStep, type AtomicDeployPlan, type AtomicDeployPruneStep, type AtomicDeployStrategy, type AuthenticationCapability, AuthenticationError, AuthorizationError, type AzureBlobProviderOptions, type BandwidthSleep, type BandwidthThrottle, type BandwidthThrottleOptions, type Base64EnvSecretSource, type BuiltInProviderId, type BuiltinCapabilityMatrixEntry, type BuiltinProviderMatrixId, CLASSIC_PROVIDER_IDS, type CapabilitySet, type ChecksumCapability, type ClassicProviderId, type ClientDiagnostics, type CompareRemoteManifestsOptions, ConfigurationError, type ConnectionDiagnosticTimings, type ConnectionDiagnosticsResult, ConnectionError, type ConnectionProfile, type ConventionEndpoint, type CopyBetweenOptions, type CountRetentionPolicy, type CreateApprovalGateOptions, type CreateAtomicDeployPlanOptions, type CreateInboxRouteOptions, type CreateOutboxRouteOptions, type CreateRemoteBrowserOptions, type CreateRemoteManifestOptions, type CreateSyncPlanOptions, type CreateWebhookAuditLogOptions, type CronExpression, type CronField, type CronScheduleTrigger, DEFAULT_FAILED_SUBDIR, DEFAULT_PROCESSED_SUBDIR, type DiffRemoteTreesOptions, type DispatchWebhookOptions, type DispatchWebhookResult, type DownloadFileOptions, type DropboxProviderOptions, type EnvSecretSource, type EvaluateRetentionOptions, type FileSecretSource, type FileZillaSite, type FriendlyTransferOptions, type FtpFeatures, type FtpPassiveHostStrategy, type FtpProviderOptions, type FtpReplyErrorInput, type FtpResponse, FtpResponseParser, type FtpResponseStatus, type FtpsDataProtection, type FtpsMode, type FtpsProviderOptions, type GcsProviderOptions, type GoogleDriveProviderOptions, type HttpFetch, type HttpProviderOptions, type ImportFileZillaSitesResult, type ImportOpenSshConfigOptions, type ImportOpenSshConfigResult, type ImportWinScpSessionsResult, InMemoryAuditLog, type IntervalScheduleTrigger, type JsonlWriter, type KnownHostsEntry, type KnownHostsMarker, type ListOptions, type LocalProviderOptions, type LogLevel, type LogRecord, type LogRecordInput, type LoggerMethod, type MemoryProviderEntry, type MemoryProviderOptions, type MetadataCapability, type MftAuditEntry, type MftAuditEntryType, type MftAuditLog, type MftInboxConvention, type MftOutboxConvention, type MftRoute, type MftRouteEndpoint, type MftRouteFilter, type MftRouteOperation, type MftSchedule, type MftScheduleTrigger, MftScheduler, type MftSchedulerOptions, type MkdirOptions, type NativeSftpProviderOptions, type NativeSftpRawSession, type OAuthAccessToken, type OAuthRefreshCallback, type OAuthTokenSecretSourceOptions, type OneDriveProviderOptions, type OpenSshConfigEntry, ParseError, PathAlreadyExistsError, PathNotFoundError, PermissionDeniedError, type ProgressEventInput, ProtocolError, type AuthenticationCapability as ProviderAuthenticationCapability, type CapabilitySet as ProviderCapabilities, type ChecksumCapability as ProviderChecksumCapability, type ProviderFactory, type ProviderId, type MetadataCapability as ProviderMetadataCapability, ProviderRegistry, type ProviderSelection, type ProviderTransferEndpointRole, type ProviderTransferExecutorOptions, type ProviderTransferOperations, type ProviderTransferReadRequest, type ProviderTransferReadResult, type ProviderTransferRequest, type ProviderTransferSessionResolver, type ProviderTransferSessionResolverInput, type ProviderTransferWriteRequest, type ProviderTransferWriteResult, REDACTED, REMOTE_MANIFEST_FORMAT_VERSION, type RemoteBreadcrumb, type RemoteBrowser, type RemoteBrowserFilter, type RemoteBrowserSnapshot, type RemoteEntry, type RemoteEntrySortKey, type RemoteEntrySortOrder, type RemoteEntryType, type RemoteFileAdapter, type RemoteFileEndpoint, type RemoteFileSystem, type RemoteManifest, type RemoteManifestEntry, type RemotePermissions, type RemoteProtocol, type RemoteStat, type RemoteTreeDiff, type RemoteTreeDiffEntry, type RemoteTreeDiffReason, type RemoteTreeDiffStatus, type RemoteTreeDiffSummary, type RemoteTreeEntry, type RemoteTreeFilter, type RemoveOptions, type RenameOptions, type ResolveSecretOptions, type ResolvedConnectionProfile, type ResolvedOpenSshHost, type ResolvedSshProfile, type ResolvedTlsProfile, type RetentionEvaluation, type RetentionPolicy, type RmdirOptions, RouteRegistry, type RunConnectionDiagnosticsOptions, type RunRouteOptions, type S3MultipartCheckpoint, type S3MultipartOptions, type S3MultipartPart, type S3MultipartResumeKey, type S3MultipartResumeStore, type S3ProviderOptions, ScheduleRegistry, type ScheduleRouteRunner, type ScheduleTimerHooks, type SecretProvider, type SecretSource, type SecretValue, type NativeSftpProviderOptions as SftpProviderOptions, type NativeSftpRawSession as SftpRawSession, type SpecializedErrorDetails, type SshAgentSource, type SshAlgorithms, type SshKeyboardInteractiveChallenge, type SshKeyboardInteractiveHandler, type SshKeyboardInteractivePrompt, type SshKnownHostsSource, type SshProfile, type SshSocketFactory, type SshSocketFactoryContext, type StatOptions, type SyncConflictPolicy, type SyncDeletePolicy, type SyncDirection, type SyncEndpointInput, TimeoutError, type TlsProfile, type TlsSecretSource, type TransferAttempt, type TransferAttemptError, type TransferBandwidthLimit, type TransferByteRange, TransferClient, type TransferClientOptions, type TransferDataChunk, type TransferDataSource, type TransferEndpoint, TransferEngine, type TransferEngineExecuteOptions, type TransferEngineOptions, TransferError, type TransferExecutionContext, type TransferExecutionResult, type TransferExecutor, type TransferJob, type TransferOperation, type TransferPlan, type TransferPlanAction, type TransferPlanInput, type TransferPlanStep, type TransferPlanSummary, type TransferProgressEvent, type TransferProvider, TransferQueue, type TransferQueueExecutorResolver, type TransferQueueItem, type TransferQueueItemStatus, type TransferQueueOptions, type TransferQueueRunOptions, type TransferQueueSummary, type TransferReceipt, type TransferResult, type TransferResultInput, type TransferRetryDecisionInput, type TransferRetryPolicy, type TransferSession, type TransferTimeoutPolicy, type TransferVerificationResult, UnsupportedFeatureError, type UploadFileOptions, type ValueSecretSource, VerificationError, type WalkRemoteTreeOptions, type WebDavProviderOptions, type WebhookRetryPolicy, type WebhookSignature, type WebhookTarget, type WinScpSession, ZeroTransfer, type ZeroTransferCapabilities, ZeroTransferError, type ZeroTransferErrorDetails, type ZeroTransferLogger, type ZeroTransferOptions, assertSafeFtpArgument, basenameRemotePath, buildRemoteBreadcrumbs, compareRemoteManifests, composeAuditLogs, copyBetween, createApprovalGate, createAtomicDeployPlan, createAzureBlobProviderFactory, createBandwidthThrottle, createDropboxProviderFactory, createFtpProviderFactory, createFtpsProviderFactory, createGcsProviderFactory, createGoogleDriveProviderFactory, createHttpProviderFactory, createInboxRoute, createJsonlAuditLog, createLocalProviderFactory, createMemoryProviderFactory, createMemoryS3MultipartResumeStore, createNativeSftpProviderFactory, createOAuthTokenSecretSource, createOneDriveProviderFactory, createOutboxRoute, createProgressEvent, createProviderTransferExecutor, createRemoteBrowser, createRemoteManifest, createS3ProviderFactory, createNativeSftpProviderFactory as createSftpProviderFactory, createSyncPlan, createTransferClient, createTransferJobsFromPlan, createTransferPlan, createTransferResult, createWebDavProviderFactory, createWebhookAuditLog, diffRemoteTrees, dispatchWebhook, downloadFile, emitLog, errorFromFtpReply, evaluateRetention, filterRemoteEntries, formatCapabilityMatrixMarkdown, freezeReceipt, getBuiltinCapabilityMatrix, importFileZillaSites, importOpenSshConfig, importWinScpSessions, inboxFailedPath, inboxProcessedPath, isClassicProviderId, isSensitiveKey, joinRemotePath, matchKnownHosts, matchKnownHostsEntry, nextCronFireAt, nextScheduleFireAt, noopLogger, normalizeRemotePath, parentRemotePath, parseCronExpression, parseFtpFeatures, parseFtpResponseLines, parseKnownHosts, parseMlsdLine, parseMlsdList, parseMlstTimestamp, parseOpenSshConfig, parseRemoteManifest, parseUnixList, parseUnixListLine, redactCommand, redactConnectionProfile, redactObject, redactSecretSource, redactValue, resolveConnectionProfileSecrets, resolveOpenSshHost, resolveProviderId, resolveSecret, runConnectionDiagnostics, runRoute, serializeRemoteManifest, signWebhookPayload, sortRemoteEntries, summarizeClientDiagnostics, summarizeError, summarizeTransferPlan, throttleByteIterable, uploadFile, validateConnectionProfile, validateSchedule, walkRemoteTree };
5983
+ export { AbortError, type AgeRetentionPolicy, ApprovalRegistry, ApprovalRejectedError, type ApprovalRequest, type ApprovalStatus, type AtomicDeployActivateOperation, type AtomicDeployActivateStep, type AtomicDeployPlan, type AtomicDeployPruneStep, type AtomicDeployStrategy, type AuthenticationCapability, AuthenticationError, AuthorizationError, type AzureBlobProviderOptions, type BandwidthSleep, type BandwidthThrottle, type BandwidthThrottleOptions, type Base64EnvSecretSource, type BuiltInProviderId, type BuiltinCapabilityMatrixEntry, type BuiltinProviderMatrixId, CLASSIC_PROVIDER_IDS, type CapabilitySet, type ChecksumCapability, type ClassicProviderId, type ClientDiagnostics, type CompareRemoteManifestsOptions, ConfigurationError, type ConnectionDiagnosticTimings, type ConnectionDiagnosticsResult, ConnectionError, type ConnectionPoolOptions, type ConnectionProfile, type ConventionEndpoint, type CopyBetweenOptions, type CountRetentionPolicy, type CreateApprovalGateOptions, type CreateAtomicDeployPlanOptions, type CreateInboxRouteOptions, type CreateOutboxRouteOptions, type CreateRemoteBrowserOptions, type CreateRemoteManifestOptions, type CreateSyncPlanOptions, type CreateWebhookAuditLogOptions, type CronExpression, type CronField, type CronScheduleTrigger, DEFAULT_FAILED_SUBDIR, DEFAULT_PROCESSED_SUBDIR, DEFAULT_SSH_ALGORITHM_PREFERENCES, type DiffRemoteTreesOptions, type DispatchWebhookOptions, type DispatchWebhookResult, type DownloadFileOptions, type DropboxProviderOptions, type EnvSecretSource, type EvaluateRetentionOptions, type FileSecretSource, type FileSystemS3MultipartResumeStoreOptions, type FileZillaSite, type FriendlyTransferOptions, type FtpFeatures, type FtpPassiveHostStrategy, type FtpProviderOptions, type FtpReplyErrorInput, type FtpResponse, FtpResponseParser, type FtpResponseStatus, type FtpsDataProtection, type FtpsMode, type FtpsProviderOptions, type GcsProviderOptions, type GoogleDriveProviderOptions, type HttpFetch, type HttpProviderOptions, type ImportFileZillaSitesResult, type ImportOpenSshConfigOptions, type ImportOpenSshConfigResult, type ImportWinScpSessionsResult, InMemoryAuditLog, type IntervalScheduleTrigger, type JsonlWriter, type KnownHostsEntry, type KnownHostsMarker, type ListOptions, type LocalProviderOptions, type LogLevel, type LogRecord, type LogRecordInput, type LoggerMethod, type MemoryProviderEntry, type MemoryProviderOptions, type MetadataCapability, type MftAuditEntry, type MftAuditEntryType, type MftAuditLog, type MftInboxConvention, type MftOutboxConvention, type MftRoute, type MftRouteEndpoint, type MftRouteFilter, type MftRouteOperation, type MftSchedule, type MftScheduleTrigger, MftScheduler, type MftSchedulerOptions, type MkdirOptions, type NativeSftpProviderOptions, type NativeSftpRawSession, type NegotiatedSshAlgorithms, type OAuthAccessToken, type OAuthRefreshCallback, type OAuthTokenSecretSourceOptions, type OneDriveProviderOptions, type OpenSshConfigEntry, ParseError, PathAlreadyExistsError, PathNotFoundError, PermissionDeniedError, type PooledTransferClient, type ProgressEventInput, ProtocolError, type AuthenticationCapability as ProviderAuthenticationCapability, type CapabilitySet as ProviderCapabilities, type ChecksumCapability as ProviderChecksumCapability, type ProviderFactory, type ProviderId, type MetadataCapability as ProviderMetadataCapability, ProviderRegistry, type ProviderSelection, type ProviderTransferEndpointRole, type ProviderTransferExecutorOptions, type ProviderTransferOperations, type ProviderTransferReadRequest, type ProviderTransferReadResult, type ProviderTransferRequest, type ProviderTransferSessionResolver, type ProviderTransferSessionResolverInput, type ProviderTransferWriteRequest, type ProviderTransferWriteResult, REDACTED, REMOTE_MANIFEST_FORMAT_VERSION, type RemoteBreadcrumb, type RemoteBrowser, type RemoteBrowserFilter, type RemoteBrowserSnapshot, type RemoteEntry, type RemoteEntrySortKey, type RemoteEntrySortOrder, type RemoteEntryType, type RemoteFileAdapter, type RemoteFileEndpoint, type RemoteFileSystem, type RemoteManifest, type RemoteManifestEntry, type RemotePermissions, type RemoteProtocol, type RemoteStat, type RemoteTreeDiff, type RemoteTreeDiffEntry, type RemoteTreeDiffReason, type RemoteTreeDiffStatus, type RemoteTreeDiffSummary, type RemoteTreeEntry, type RemoteTreeFilter, type RemoveOptions, type RenameOptions, type ResolveSecretOptions, type ResolvedConnectionProfile, type ResolvedOpenSshHost, type ResolvedSshProfile, type ResolvedTlsProfile, type RetentionEvaluation, type RetentionPolicy, type RmdirOptions, RouteRegistry, type RunConnectionDiagnosticsOptions, type RunRouteOptions, type S3MultipartCheckpoint, type S3MultipartOptions, type S3MultipartPart, type S3MultipartResumeKey, type S3MultipartResumeStore, type S3ProviderOptions, ScheduleRegistry, type ScheduleRouteRunner, type ScheduleTimerHooks, type SecretProvider, type SecretSource, type SecretValue, type NativeSftpProviderOptions as SftpProviderOptions, type NativeSftpRawSession as SftpRawSession, type SpecializedErrorDetails, type SshAgentSource, type SshAlgorithmPreferences, type SshAlgorithms, SshAuthSession, SshConnectionManager, SshDataReader, SshDataWriter, SshDisconnectReason, type SshKeyboardInteractiveChallenge, type SshKeyboardInteractiveCredential, type SshKeyboardInteractiveHandler, type SshKeyboardInteractivePrompt, type SshKnownHostsSource, type SshPasswordCredential, type SshProfile, type SshPublickeyCredential, SshSessionChannel, type SshSocketFactory, type SshSocketFactoryContext, SshTransportConnection, type SshTransportConnectionOptions, SshTransportHandshake, type SshTransportHandshakeResult, type StatOptions, type SyncConflictPolicy, type SyncDeletePolicy, type SyncDirection, type SyncEndpointInput, TimeoutError, type TlsProfile, type TlsSecretSource, type TransferAttempt, type TransferAttemptError, type TransferBandwidthLimit, type TransferByteRange, TransferClient, type TransferClientOptions, type TransferDataChunk, type TransferDataSource, type TransferEndpoint, TransferEngine, type TransferEngineExecuteOptions, type TransferEngineOptions, TransferError, type TransferExecutionContext, type TransferExecutionResult, type TransferExecutor, type TransferJob, type TransferOperation, type TransferPlan, type TransferPlanAction, type TransferPlanInput, type TransferPlanStep, type TransferPlanSummary, type TransferProgressEvent, type TransferProvider, TransferQueue, type TransferQueueExecutorResolver, type TransferQueueItem, type TransferQueueItemStatus, type TransferQueueOptions, type TransferQueueRunOptions, type TransferQueueSummary, type TransferReceipt, type TransferResult, type TransferResultInput, type TransferRetryDecisionInput, type TransferRetryPolicy, type TransferSession, type TransferTimeoutPolicy, type TransferVerificationResult, UnsupportedFeatureError, type UploadFileOptions, type ValueSecretSource, VerificationError, type WalkRemoteTreeOptions, type WebDavProviderOptions, type WebhookRetryPolicy, type WebhookSignature, type WebhookTarget, type WinScpSession, ZeroTransfer, type ZeroTransferCapabilities, ZeroTransferError, type ZeroTransferErrorDetails, type ZeroTransferLogger, type ZeroTransferOptions, assertSafeFtpArgument, basenameRemotePath, buildPublickeyCredential, buildRemoteBreadcrumbs, compareRemoteManifests, composeAuditLogs, copyBetween, createApprovalGate, createAtomicDeployPlan, createAzureBlobProviderFactory, createBandwidthThrottle, createDropboxProviderFactory, createFileSystemS3MultipartResumeStore, createFtpProviderFactory, createFtpsProviderFactory, createGcsProviderFactory, createGoogleDriveProviderFactory, createHttpProviderFactory, createInboxRoute, createJsonlAuditLog, createLocalProviderFactory, createMemoryProviderFactory, createMemoryS3MultipartResumeStore, createNativeSftpProviderFactory, createOAuthTokenSecretSource, createOneDriveProviderFactory, createOutboxRoute, createPooledTransferClient, createProgressEvent, createProviderTransferExecutor, createRemoteBrowser, createRemoteManifest, createS3ProviderFactory, createNativeSftpProviderFactory as createSftpProviderFactory, createSyncPlan, createTransferClient, createTransferJobsFromPlan, createTransferPlan, createTransferResult, createWebDavProviderFactory, createWebhookAuditLog, diffRemoteTrees, dispatchWebhook, downloadFile, emitLog, errorFromFtpReply, evaluateRetention, filterRemoteEntries, formatCapabilityMatrixMarkdown, freezeReceipt, getBuiltinCapabilityMatrix, importFileZillaSites, importOpenSshConfig, importWinScpSessions, inboxFailedPath, inboxProcessedPath, isClassicProviderId, isSensitiveKey, joinRemotePath, matchKnownHosts, matchKnownHostsEntry, negotiateSshAlgorithms, nextCronFireAt, nextScheduleFireAt, noopLogger, normalizeRemotePath, parentRemotePath, parseCronExpression, parseFtpFeatures, parseFtpResponseLines, parseKnownHosts, parseMlsdLine, parseMlsdList, parseMlstTimestamp, parseOpenSshConfig, parseRemoteManifest, parseUnixList, parseUnixListLine, redactCommand, redactConnectionProfile, redactObject, redactSecretSource, redactValue, resolveConnectionProfileSecrets, resolveOpenSshHost, resolveProviderId, resolveSecret, runConnectionDiagnostics, runRoute, serializeRemoteManifest, signWebhookPayload, sortRemoteEntries, summarizeClientDiagnostics, summarizeError, summarizeTransferPlan, throttleByteIterable, uploadFile, validateConnectionProfile, validateSchedule, walkRemoteTree };