@zero-transfer/sdk 0.1.0-alpha.0 → 0.1.1

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
@@ -375,7 +375,17 @@ interface TlsProfile {
375
375
  minVersion?: SecureVersion;
376
376
  /** Maximum TLS protocol version accepted by the client. */
377
377
  maxVersion?: SecureVersion;
378
- /** Expected server certificate SHA-256 fingerprint or fingerprints, using hex with optional colons. */
378
+ /**
379
+ * Optional. Expected server certificate SHA-256 fingerprint(s) for **certificate pinning**, in
380
+ * hex form with or without colons. When present, the TLS handshake additionally requires the
381
+ * leaf certificate's SHA-256 fingerprint to match one of these values.
382
+ *
383
+ * Not required for normal CA-trusted endpoints — public CAs and `ca` bundles already gate
384
+ * trust via `rejectUnauthorized`. Pinning is **recommended for production** when you control
385
+ * the server and want defence-in-depth against rogue certificates issued by trusted CAs.
386
+ *
387
+ * @example "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"
388
+ */
379
389
  pinnedFingerprint256?: string | readonly string[];
380
390
  /** Optional custom server identity checker for private PKI or certificate pinning. */
381
391
  checkServerIdentity?: (host: string, cert: PeerCertificate) => Error | undefined;
@@ -395,9 +405,25 @@ interface SshProfile {
395
405
  privateKey?: SecretSource;
396
406
  /** Passphrase used to decrypt an encrypted private key. */
397
407
  passphrase?: SecretSource;
398
- /** OpenSSH known_hosts content used for strict SFTP host-key verification. */
408
+ /**
409
+ * Optional. OpenSSH `known_hosts` content used for **strict SFTP host-key verification**.
410
+ * Mutually exclusive with provider-level `hostHash`/`hostVerifier` options.
411
+ *
412
+ * Not required for the connection to succeed, but **strongly recommended for production**:
413
+ * without `knownHosts` (and without {@link SshProfile.pinnedHostKeySha256 | pinnedHostKeySha256}),
414
+ * the SSH session accepts any host key the server presents, leaving you exposed to MITM.
415
+ */
399
416
  knownHosts?: SshKnownHostsSource;
400
- /** Expected SSH host-key SHA-256 fingerprint or fingerprints, using OpenSSH `SHA256:` form, base64, or hex. */
417
+ /**
418
+ * Optional. SSH host-key SHA-256 fingerprint(s) the remote must present, in OpenSSH
419
+ * `SHA256:<base64>` form, raw base64, or hex.
420
+ *
421
+ * Use this as a lighter-weight alternative to a full `known_hosts` file when you only need
422
+ * to pin a single host. Like `knownHosts`, it is **optional but recommended for production**;
423
+ * leaving both unset disables host-key verification entirely.
424
+ *
425
+ * @example "SHA256:abc123basesixfourpinFromKnownHosts="
426
+ */
401
427
  pinnedHostKeySha256?: string | readonly string[];
402
428
  /** Runtime callback that answers SSH keyboard-interactive authentication prompts. */
403
429
  keyboardInteractive?: SshKeyboardInteractiveHandler;
@@ -406,6 +432,46 @@ interface SshProfile {
406
432
  }
407
433
  /**
408
434
  * Connection settings accepted by facade and adapter implementations.
435
+ *
436
+ * Every `ConnectionProfile` has a `host` and a `provider` (or `protocol`).
437
+ * Authentication and transport-specific material is layered on via the
438
+ * optional `ssh`, `tls`, `oauth`, and provider-specific blocks (e.g. `s3`,
439
+ * `azure`, `dropbox`).
440
+ *
441
+ * @example SFTP with public-key auth
442
+ * ```ts
443
+ * const profile: ConnectionProfile = {
444
+ * host: "sftp.example.com",
445
+ * provider: "sftp",
446
+ * username: "deploy",
447
+ * ssh: {
448
+ * privateKey: { path: "./keys/id_ed25519" },
449
+ * pinnedHostKeySha256: "SHA256:abc123basesixfourpinFromKnownHosts=",
450
+ * },
451
+ * };
452
+ * ```
453
+ *
454
+ * @example FTPS with username/password and public-CA TLS
455
+ * ```ts
456
+ * const profile: ConnectionProfile = {
457
+ * host: "ftps.example.com",
458
+ * provider: "ftps",
459
+ * username: "deploy",
460
+ * password: { env: "FTPS_PASSWORD" },
461
+ * tls: { minVersion: "TLSv1.2" },
462
+ * };
463
+ * ```
464
+ *
465
+ * @example S3-compatible
466
+ * ```ts
467
+ * const profile: ConnectionProfile = {
468
+ * host: "my-bucket",
469
+ * provider: "s3",
470
+ * username: process.env.AWS_ACCESS_KEY_ID,
471
+ * password: { env: "AWS_SECRET_ACCESS_KEY" },
472
+ * s3: { region: "us-east-1" },
473
+ * };
474
+ * ```
409
475
  */
410
476
  interface ConnectionProfile {
411
477
  /** Provider to use for this connection. Prefer this over the compatibility protocol field. */
@@ -982,8 +1048,50 @@ declare class TransferClient {
982
1048
  /**
983
1049
  * Creates a provider-neutral transfer client.
984
1050
  *
1051
+ * The returned client owns a registry of provider factories and produces
1052
+ * `TransferSession` instances on demand via {@link TransferClient.connect}.
1053
+ * Registering only the providers you actually use keeps bundle size small
1054
+ * (each factory pulls in its own SDK dependencies).
1055
+ *
985
1056
  * @param options - Optional registry, provider factories, and logger.
986
1057
  * @returns A disconnected {@link TransferClient} instance.
1058
+ *
1059
+ * @example Multi-provider client
1060
+ * ```ts
1061
+ * import {
1062
+ * createS3ProviderFactory,
1063
+ * createSftpProviderFactory,
1064
+ * createTransferClient,
1065
+ * } from "@zero-transfer/sdk";
1066
+ *
1067
+ * const client = createTransferClient({
1068
+ * providers: [createSftpProviderFactory(), createS3ProviderFactory()],
1069
+ * });
1070
+ *
1071
+ * const session = await client.connect({
1072
+ * host: "sftp.example.com",
1073
+ * provider: "sftp",
1074
+ * username: "deploy",
1075
+ * ssh: { privateKey: { path: "./keys/id_ed25519" } },
1076
+ * });
1077
+ * try {
1078
+ * const list = await session.fs.list("/uploads");
1079
+ * console.log(list);
1080
+ * } finally {
1081
+ * await session.disconnect();
1082
+ * }
1083
+ * ```
1084
+ *
1085
+ * @example Friendly one-shot helpers
1086
+ * ```ts
1087
+ * import { uploadFile } from "@zero-transfer/sdk";
1088
+ *
1089
+ * await uploadFile({
1090
+ * client,
1091
+ * destination: { path: "/uploads/report.csv", profile },
1092
+ * localPath: "./out/report.csv",
1093
+ * });
1094
+ * ```
987
1095
  */
988
1096
  declare function createTransferClient(options?: TransferClientOptions): TransferClient;
989
1097
 
@@ -1280,8 +1388,37 @@ interface UploadFileOptions extends FriendlyTransferOptions {
1280
1388
  /**
1281
1389
  * Uploads a single local file to a remote endpoint.
1282
1390
  *
1391
+ * The remote provider is resolved from `destination.profile.provider`, so any
1392
+ * provider factory you registered with {@link createTransferClient} can be used
1393
+ * as the destination.
1394
+ *
1283
1395
  * @param options - Friendly upload options.
1284
1396
  * @returns Receipt produced by the underlying transfer engine.
1397
+ *
1398
+ * @example Upload to SFTP with public-key auth
1399
+ * ```ts
1400
+ * import {
1401
+ * createSftpProviderFactory,
1402
+ * createTransferClient,
1403
+ * uploadFile,
1404
+ * } from "@zero-transfer/sdk";
1405
+ *
1406
+ * const client = createTransferClient({ providers: [createSftpProviderFactory()] });
1407
+ *
1408
+ * await uploadFile({
1409
+ * client,
1410
+ * destination: {
1411
+ * path: "/uploads/report.csv",
1412
+ * profile: {
1413
+ * host: "sftp.example.com",
1414
+ * provider: "sftp",
1415
+ * username: "deploy",
1416
+ * ssh: { privateKey: { path: "./keys/id_ed25519" } },
1417
+ * },
1418
+ * },
1419
+ * localPath: "./out/report.csv",
1420
+ * });
1421
+ * ```
1285
1422
  */
1286
1423
  declare function uploadFile(options: UploadFileOptions): Promise<TransferReceipt>;
1287
1424
  /** Options for {@link downloadFile}. */
@@ -1296,8 +1433,35 @@ interface DownloadFileOptions extends FriendlyTransferOptions {
1296
1433
  /**
1297
1434
  * Downloads a single remote file to a local path.
1298
1435
  *
1436
+ * The remote provider is resolved from `source.profile.provider`. The local
1437
+ * destination path is created (including parent directories) on demand.
1438
+ *
1299
1439
  * @param options - Friendly download options.
1300
1440
  * @returns Receipt produced by the underlying transfer engine.
1441
+ *
1442
+ * @example Download from S3
1443
+ * ```ts
1444
+ * import {
1445
+ * createS3ProviderFactory,
1446
+ * createTransferClient,
1447
+ * downloadFile,
1448
+ * } from "@zero-transfer/sdk";
1449
+ *
1450
+ * const client = createTransferClient({ providers: [createS3ProviderFactory()] });
1451
+ *
1452
+ * await downloadFile({
1453
+ * client,
1454
+ * localPath: "./tmp/snapshot.tar.gz",
1455
+ * source: {
1456
+ * path: "snapshots/2026-04-28/snapshot.tar.gz",
1457
+ * profile: {
1458
+ * host: "snapshots", // S3 bucket
1459
+ * provider: "s3",
1460
+ * s3: { region: "us-east-1" },
1461
+ * },
1462
+ * },
1463
+ * });
1464
+ * ```
1301
1465
  */
1302
1466
  declare function downloadFile(options: DownloadFileOptions): Promise<TransferReceipt>;
1303
1467
  /** Options for {@link copyBetween}. */
@@ -1312,8 +1476,38 @@ interface CopyBetweenOptions extends FriendlyTransferOptions {
1312
1476
  /**
1313
1477
  * Copies a file between two remote endpoints in a single call.
1314
1478
  *
1479
+ * Both source and destination providers must be registered with the
1480
+ * {@link TransferClient}. Streams are piped end-to-end without staging the file
1481
+ * on the local disk.
1482
+ *
1315
1483
  * @param options - Friendly copy options.
1316
1484
  * @returns Receipt produced by the underlying transfer engine.
1485
+ *
1486
+ * @example Copy from SFTP to S3
1487
+ * ```ts
1488
+ * import {
1489
+ * copyBetween,
1490
+ * createS3ProviderFactory,
1491
+ * createSftpProviderFactory,
1492
+ * createTransferClient,
1493
+ * } from "@zero-transfer/sdk";
1494
+ *
1495
+ * const client = createTransferClient({
1496
+ * providers: [createSftpProviderFactory(), createS3ProviderFactory()],
1497
+ * });
1498
+ *
1499
+ * await copyBetween({
1500
+ * client,
1501
+ * source: {
1502
+ * path: "/exports/daily.csv",
1503
+ * profile: { host: "sftp.example.com", provider: "sftp", username: "etl" },
1504
+ * },
1505
+ * destination: {
1506
+ * path: "warehouse/daily.csv",
1507
+ * profile: { host: "warehouse", provider: "s3", s3: { region: "us-east-1" } },
1508
+ * },
1509
+ * });
1510
+ * ```
1317
1511
  */
1318
1512
  declare function copyBetween(options: CopyBetweenOptions): Promise<TransferReceipt>;
1319
1513
 
@@ -1444,8 +1638,24 @@ interface LocalProviderOptions {
1444
1638
  /**
1445
1639
  * Creates a provider factory backed by the local filesystem.
1446
1640
  *
1641
+ * Useful for copying files between two remote endpoints via a local staging
1642
+ * area, or as the destination for `downloadFile`. The friendly `uploadFile`
1643
+ * helper registers a local provider implicitly.
1644
+ *
1447
1645
  * @param options - Optional local root path exposed through provider sessions.
1448
1646
  * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
1647
+ *
1648
+ * @example Use a fixed root directory
1649
+ * ```ts
1650
+ * import { createLocalProviderFactory, createTransferClient } from "@zero-transfer/sdk";
1651
+ *
1652
+ * const client = createTransferClient({
1653
+ * providers: [createLocalProviderFactory({ rootPath: "/var/lib/zt-staging" })],
1654
+ * });
1655
+ *
1656
+ * const session = await client.connect({ host: "staging", provider: "local" });
1657
+ * const list = await session.fs.list("/");
1658
+ * ```
1449
1659
  */
1450
1660
  declare function createLocalProviderFactory(options?: LocalProviderOptions): ProviderFactory;
1451
1661
 
@@ -1692,7 +1902,7 @@ interface S3MultipartPart {
1692
1902
  * Persistence contract for resuming partial multipart uploads across
1693
1903
  * processes or retries. Implementations may be synchronous or asynchronous;
1694
1904
  * `clear` is invoked once the multipart upload completes successfully (or is
1695
- * explicitly aborted via {@link abortS3MultipartUpload}).
1905
+ * explicitly aborted).
1696
1906
  */
1697
1907
  interface S3MultipartResumeStore {
1698
1908
  load(key: S3MultipartResumeKey): Promise<S3MultipartCheckpoint | undefined> | S3MultipartCheckpoint | undefined;
@@ -1707,6 +1917,34 @@ declare function createMemoryS3MultipartResumeStore(): S3MultipartResumeStore;
1707
1917
  * Credentials must be supplied via the connection profile: `username` is the
1708
1918
  * access key id and `password` is the secret access key. `profile.host` may
1709
1919
  * be set to the bucket name (taking precedence over `options.bucket`).
1920
+ *
1921
+ * Works with AWS S3 and any S3-compatible API (MinIO, Cloudflare R2,
1922
+ * Backblaze B2, DigitalOcean Spaces, Wasabi, etc.) via `options.endpoint`.
1923
+ *
1924
+ * @example AWS S3
1925
+ * ```ts
1926
+ * import { createS3ProviderFactory, createTransferClient } from "@zero-transfer/sdk";
1927
+ *
1928
+ * const client = createTransferClient({ providers: [createS3ProviderFactory()] });
1929
+ *
1930
+ * const session = await client.connect({
1931
+ * host: "my-bucket",
1932
+ * provider: "s3",
1933
+ * username: process.env.AWS_ACCESS_KEY_ID,
1934
+ * password: { env: "AWS_SECRET_ACCESS_KEY" },
1935
+ * s3: { region: "us-east-1" },
1936
+ * });
1937
+ * ```
1938
+ *
1939
+ * @example MinIO / R2 / S3-compatible endpoint
1940
+ * ```ts
1941
+ * const client = createTransferClient({
1942
+ * providers: [createS3ProviderFactory({
1943
+ * endpoint: "https://minio.internal:9000",
1944
+ * pathStyle: true,
1945
+ * })],
1946
+ * });
1947
+ * ```
1710
1948
  */
1711
1949
  declare function createS3ProviderFactory(options?: S3ProviderOptions): ProviderFactory;
1712
1950
 
@@ -2325,6 +2563,20 @@ interface FtpsProviderOptions extends FtpProviderOptions {
2325
2563
  *
2326
2564
  * @param options - Optional provider defaults.
2327
2565
  * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2566
+ *
2567
+ * @example Plain FTP (cleartext — prefer FTPS or SFTP whenever possible)
2568
+ * ```ts
2569
+ * import { createFtpProviderFactory, createTransferClient } from "@zero-transfer/sdk";
2570
+ *
2571
+ * const client = createTransferClient({ providers: [createFtpProviderFactory()] });
2572
+ *
2573
+ * const session = await client.connect({
2574
+ * host: "ftp.example.com",
2575
+ * provider: "ftp",
2576
+ * username: "deploy",
2577
+ * password: { env: "FTP_PASSWORD" },
2578
+ * });
2579
+ * ```
2328
2580
  */
2329
2581
  declare function createFtpProviderFactory(options?: FtpProviderOptions): ProviderFactory;
2330
2582
  /**
@@ -2335,6 +2587,37 @@ declare function createFtpProviderFactory(options?: FtpProviderOptions): Provide
2335
2587
  *
2336
2588
  * @param options - Optional provider defaults.
2337
2589
  * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2590
+ *
2591
+ * @example FTPS with public-CA TLS (no extra TLS material needed)
2592
+ * ```ts
2593
+ * import { createFtpsProviderFactory, createTransferClient } from "@zero-transfer/sdk";
2594
+ *
2595
+ * const client = createTransferClient({ providers: [createFtpsProviderFactory()] });
2596
+ *
2597
+ * const session = await client.connect({
2598
+ * host: "ftps.example.com",
2599
+ * provider: "ftps",
2600
+ * username: "deploy",
2601
+ * password: { env: "FTPS_PASSWORD" },
2602
+ * tls: { minVersion: "TLSv1.2" },
2603
+ * });
2604
+ * ```
2605
+ *
2606
+ * @example FTPS with private CA + certificate pinning (defence-in-depth)
2607
+ * ```ts
2608
+ * await client.connect({
2609
+ * host: "ftps.internal.example",
2610
+ * provider: "ftps",
2611
+ * username: "audit",
2612
+ * tls: {
2613
+ * ca: { path: "./certs/ca-bundle.pem" },
2614
+ * cert: { path: "./certs/client.crt" },
2615
+ * key: { path: "./certs/client.key" },
2616
+ * // Optional but recommended:
2617
+ * 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",
2618
+ * },
2619
+ * });
2620
+ * ```
2338
2621
  */
2339
2622
  declare function createFtpsProviderFactory(options?: FtpsProviderOptions): ProviderFactory;
2340
2623
 
@@ -2514,6 +2797,28 @@ interface SftpRawSession {
2514
2797
  *
2515
2798
  * @param options - Optional ssh2 host-key verifier and timeout defaults.
2516
2799
  * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.
2800
+ *
2801
+ * @example Register and use
2802
+ * ```ts
2803
+ * import { createSftpProviderFactory, createTransferClient } from "@zero-transfer/sdk";
2804
+ *
2805
+ * const client = createTransferClient({ providers: [createSftpProviderFactory()] });
2806
+ *
2807
+ * const session = await client.connect({
2808
+ * host: "sftp.example.com",
2809
+ * provider: "sftp",
2810
+ * username: "deploy",
2811
+ * ssh: {
2812
+ * privateKey: { path: "./keys/id_ed25519" },
2813
+ * // Optional but recommended for production:
2814
+ * pinnedHostKeySha256: "SHA256:abc123basesixfourpinFromKnownHosts=",
2815
+ * },
2816
+ * });
2817
+ * ```
2818
+ *
2819
+ * Host-key verification (`ssh.knownHosts` and/or `ssh.pinnedHostKeySha256`) is
2820
+ * optional; without either, the client trusts whatever host key the server
2821
+ * presents. Use one for any non-lab deployment.
2517
2822
  */
2518
2823
  declare function createSftpProviderFactory(options?: SftpProviderOptions): ProviderFactory;
2519
2824