@cfxlabsinc/b2b-services
    Preparing search index...

    A minimal SFTP client for pushing generated files to a counterparty.

    Deliberately not a connection pool: every call opens a connection, transfers, and closes it. The callers are Temporal activities that run monthly, so a pooled connection would spend its whole life idle and would fail in whatever way the far side's idle timeout chose, at a moment unrelated to the upload.

    Built on ssh2 rather than a promise wrapper so hostVerifier — the only thing standing between this and a trust-on-first-use MITM — is configured directly here rather than through a layer that could default it away.

    Index
    instance: (...args: []) => SftpClient = ...

    Dart's drop: the sftp namespace, read at the first connection and kept.

    • Stream a whole file, or null when it does not exist; err NOT_A_FILE for a directory, or a refused connection.

      The connection outlives this call and closes with the stream, so the caller must consume or destroy body.

      Parameters

      • path: string

      Returns Promise<
          | { error: SftpError
          | SftpNotAFileError; ok: false }
          | { ok: true; value: { body: Readable; size: number } | null },
      >

    • A directory's absolute path and its entries, or null when it does not exist. directory may be relative; unset or "" is the login's home. err when the connection is refused (see SftpError).

      Parameters

      • directory: string | undefined

      Returns Promise<
          | { error: SftpError; ok: false }
          | { ok: true; value: { entries: SftpEntry[]; path: string } | null },
      >

    • The first maxBytes of a file and its full size, so the caller knows whether it saw all of it. null when the file does not exist; err NOT_A_FILE for a directory, or a refused connection.

      Parameters

      • __namedParameters: { maxBytes: number; path: string }

      Returns Promise<
          | { ok: true; value: { bytes: Buffer; size: number }
          | null }
          | { error: SftpError | SftpNotAFileError; ok: false },
      >

    • Upload one file, atomically from the reader's point of view.

      Writes to <remotePath>.part and renames on success. A counterparty polling the drop directory would otherwise be free to pick up a file that is still being written and reconcile against a truncated month; the rename is what makes the file appear whole or not at all.

      Idempotent, so an activity retry can re-send files an earlier attempt already delivered: identical bytes (size, then SHA-256) are left alone, different bytes replace the file. Replacing unlinks before the rename because SFTP rename refuses an existing target, as does MOVEit by default.

      err HOST_KEY_MISMATCH or AUTH_REJECTED when the connection is refused; any other failure throws.

      Parameters

      • __namedParameters: { body: Readable; remotePath: string }

      Returns Promise<
          { ok: true; value: SftpUploadOutcome }
          | { error: SftpError; ok: false },
      >