@zero-transfer/sdk 0.4.0 → 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
@@ -835,7 +835,41 @@ interface TransferEngineOptions {
835
835
  /** Clock used for receipts and progress events. Defaults to `new Date()`. */
836
836
  now?: () => Date;
837
837
  }
838
- /** 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
+ */
839
873
  declare class TransferEngine {
840
874
  private readonly now;
841
875
  /**
@@ -1418,9 +1452,41 @@ interface RunRouteOptions {
1418
1452
  /**
1419
1453
  * Executes an MFT route as a single transfer through the supplied client.
1420
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
+ *
1421
1461
  * @param options - Client, route, and optional engine/abort/retry hooks.
1422
1462
  * @returns Receipt produced by the underlying transfer engine.
1423
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
+ * ```
1424
1490
  */
1425
1491
  declare function runRoute(options: RunRouteOptions): Promise<TransferReceipt>;
1426
1492
 
@@ -1594,8 +1660,20 @@ interface ClientDiagnostics {
1594
1660
  /**
1595
1661
  * Returns a redaction-safe snapshot of the providers registered with a client.
1596
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
+ *
1597
1666
  * @param client - Transfer client to inspect.
1598
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
+ * ```
1599
1677
  */
1600
1678
  declare function summarizeClientDiagnostics(client: TransferClient): ClientDiagnostics;
1601
1679
  /** Per-step duration measurements collected by {@link runConnectionDiagnostics}. */
@@ -1648,8 +1726,36 @@ interface RunConnectionDiagnosticsOptions {
1648
1726
  /**
1649
1727
  * Connects to a profile, captures capability and listing samples, and returns a redaction-safe report.
1650
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
+ *
1651
1734
  * @param options - Diagnostic probe options.
1652
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
+ * ```
1653
1759
  */
1654
1760
  declare function runConnectionDiagnostics(options: RunConnectionDiagnosticsOptions): Promise<ConnectionDiagnosticsResult>;
1655
1761
 
@@ -1802,7 +1908,31 @@ interface DropboxProviderOptions {
1802
1908
  *
1803
1909
  * The bearer token is resolved per-connection from `profile.password`. The
1804
1910
  * `profile.host` field is unused; Dropbox connections are identified solely by
1805
- * 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
+ * ```
1806
1936
  */
1807
1937
  declare function createDropboxProviderFactory(options?: DropboxProviderOptions): ProviderFactory;
1808
1938
 
@@ -1829,7 +1959,34 @@ interface GoogleDriveProviderOptions {
1829
1959
  * Creates a Google Drive provider factory.
1830
1960
  *
1831
1961
  * The bearer token is resolved per-connection from `profile.password`
1832
- * (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
+ * ```
1833
1990
  */
1834
1991
  declare function createGoogleDriveProviderFactory(options?: GoogleDriveProviderOptions): ProviderFactory;
1835
1992
 
@@ -1852,7 +2009,40 @@ interface OneDriveProviderOptions {
1852
2009
  * Creates a OneDrive/SharePoint provider factory backed by Microsoft Graph.
1853
2010
  *
1854
2011
  * The bearer token is resolved per-connection from `profile.password`.
1855
- * `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
+ * ```
1856
2046
  */
1857
2047
  declare function createOneDriveProviderFactory(options?: OneDriveProviderOptions): ProviderFactory;
1858
2048
 
@@ -1879,7 +2069,48 @@ interface AzureBlobProviderOptions {
1879
2069
  /** Default headers applied before bearer auth on every request. */
1880
2070
  defaultHeaders?: Record<string, string>;
1881
2071
  }
1882
- /** 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
+ */
1883
2114
  declare function createAzureBlobProviderFactory(options: AzureBlobProviderOptions): ProviderFactory;
1884
2115
 
1885
2116
  /** Options accepted by {@link createGcsProviderFactory}. */
@@ -1897,7 +2128,39 @@ interface GcsProviderOptions {
1897
2128
  /** Default headers applied before bearer auth on every request. */
1898
2129
  defaultHeaders?: Record<string, string>;
1899
2130
  }
1900
- /** 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
+ */
1901
2164
  declare function createGcsProviderFactory(options: GcsProviderOptions): ProviderFactory;
1902
2165
 
1903
2166
  /** Fixture entry used to seed a memory provider instance. */
@@ -1915,8 +2178,29 @@ interface MemoryProviderOptions {
1915
2178
  /**
1916
2179
  * Creates a provider factory backed by deterministic in-memory fixture entries.
1917
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
+ *
1918
2185
  * @param options - Optional fixture entries to expose through the memory provider.
1919
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
+ * ```
1920
2204
  */
1921
2205
  declare function createMemoryProviderFactory(options?: MemoryProviderOptions): ProviderFactory;
1922
2206
 
@@ -1936,8 +2220,45 @@ interface HttpProviderOptions {
1936
2220
  /**
1937
2221
  * Creates a provider factory backed by HTTP(S) GET/HEAD.
1938
2222
  *
1939
- * @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.
1940
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
+ * ```
1941
2262
  */
1942
2263
  declare function createHttpProviderFactory(options?: HttpProviderOptions): ProviderFactory;
1943
2264
 
@@ -1975,8 +2296,39 @@ interface WebDavProviderOptions {
1975
2296
  /**
1976
2297
  * Creates a WebDAV provider factory.
1977
2298
  *
1978
- * @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.
1979
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
+ * ```
1980
2332
  */
1981
2333
  declare function createWebDavProviderFactory(options?: WebDavProviderOptions): ProviderFactory;
1982
2334
 
@@ -3967,9 +4319,47 @@ interface TransferPlanSummary {
3967
4319
  /** Counts grouped by action. */
3968
4320
  actions: Record<string, number>;
3969
4321
  }
3970
- /** 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
+ */
3971
4345
  declare function createTransferPlan(input: TransferPlanInput): TransferPlan;
3972
- /** 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
+ */
3973
4363
  declare function summarizeTransferPlan(plan: TransferPlan): TransferPlanSummary;
3974
4364
  /** Converts executable plan steps into transfer jobs while preserving order. */
3975
4365
  declare function createTransferJobsFromPlan(plan: TransferPlan): TransferJob[];
@@ -4046,7 +4436,41 @@ interface TransferQueueSummary {
4046
4436
  /** Failed queue items in queue order. */
4047
4437
  failures: TransferQueueItem[];
4048
4438
  }
4049
- /** 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
+ */
4050
4474
  declare class TransferQueue {
4051
4475
  private readonly engine;
4052
4476
  private readonly items;
@@ -4326,6 +4750,26 @@ interface DiffRemoteTreesOptions {
4326
4750
  * @param destinationPath - Destination-side root path being compared.
4327
4751
  * @param options - Optional comparison controls.
4328
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
+ * ```
4329
4773
  */
4330
4774
  declare function diffRemoteTrees(source: RemoteFileSystem, sourcePath: string, destination: RemoteFileSystem, destinationPath: string, options?: DiffRemoteTreesOptions): Promise<RemoteTreeDiff>;
4331
4775
 
@@ -4397,6 +4841,31 @@ interface CreateSyncPlanOptions {
4397
4841
  * @param options - Inputs and policies that shape the plan.
4398
4842
  * @returns Transfer plan ready for `createTransferJobsFromPlan` or queue execution.
4399
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
+ * ```
4400
4869
  */
4401
4870
  declare function createSyncPlan(options: CreateSyncPlanOptions): TransferPlan;
4402
4871
 
@@ -4512,9 +4981,39 @@ interface CreateAtomicDeployPlanOptions {
4512
4981
  /**
4513
4982
  * Builds an {@link AtomicDeployPlan} that stages a release, swaps it live, and prunes old releases.
4514
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
+ *
4515
4992
  * @param options - Inputs and policies that shape the deploy.
4516
4993
  * @returns Structured deploy plan ready for execution by the calling host.
4517
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
+ * ```
4518
5017
  */
4519
5018
  declare function createAtomicDeployPlan(options: CreateAtomicDeployPlanOptions): AtomicDeployPlan;
4520
5019
 
@@ -5014,9 +5513,33 @@ interface CreateWebhookAuditLogOptions {
5014
5513
  *
5015
5514
  * Entries whose `type` is not in `target.types` are silently dropped. `list()`
5016
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.
5017
5518
  *
5018
5519
  * @param options - Webhook target plus optional retry/observer hooks.
5019
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
+ * ```
5020
5543
  */
5021
5544
  declare function createWebhookAuditLog(options: CreateWebhookAuditLogOptions): MftAuditLog;
5022
5545
 
@@ -5171,7 +5694,48 @@ interface MftSchedulerOptions {
5171
5694
  /** Timer/clock injection used by tests. */
5172
5695
  timer?: ScheduleTimerHooks;
5173
5696
  }
5174
- /** 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
+ */
5175
5739
  declare class MftScheduler {
5176
5740
  private readonly options;
5177
5741
  private readonly now;
@@ -5315,10 +5879,33 @@ interface CreateApprovalGateOptions {
5315
5879
  *
5316
5880
  * The returned runner creates an approval request, waits for resolution, and
5317
5881
  * dispatches the underlying runner only when the request is approved. Rejection
5318
- * 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.
5319
5884
  *
5320
5885
  * @param options - Registry, downstream runner, approval-id derivation, hooks.
5321
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
+ * ```
5322
5909
  */
5323
5910
  declare function createApprovalGate(options: CreateApprovalGateOptions): ScheduleRouteRunner;
5324
5911