@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/LICENSE +21 -21
- package/README.md +182 -213
- package/assets/zero-transfer-logo.svg +201 -201
- package/dist/index.cjs +12 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +309 -4
- package/dist/index.d.ts +309 -4
- package/dist/index.mjs +11 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -4
- package/CHANGELOG.md +0 -177
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Tony Wiedman
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tony Wiedman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,158 +1,110 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="assets/zero-transfer-logo.svg" alt="ZeroTransfer file transfer SDK for Node.js" width="720">
|
|
2
|
+
<img src="https://tonywied17.github.io/zero-transfer/assets/zero-transfer-logo.svg" alt="ZeroTransfer file transfer SDK for Node.js" width="720">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<h1 align="center">ZeroTransfer</h1>
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
[](https://nodejs.org)
|
|
12
|
-
|
|
13
|
-
ZeroTransfer is a unified TypeScript-first Node.js SDK for moving files across classic protocols, web transfer endpoints, object storage, cloud drives, and future MFT-style workflows. The project is being rebuilt from the original FTP-first implementation into a safer, typed, observable transfer platform with parser-first tests, npmjs-only publishing, and generated API documentation in mind.
|
|
14
|
-
|
|
15
|
-
## Status
|
|
16
|
-
|
|
17
|
-
This repository is in the ZeroTransfer alpha foundation phase. The old CommonJS package surface has been removed so the project can move forward around the TypeScript `src/` foundation and generated `dist/` output.
|
|
18
|
-
|
|
19
|
-
The current foundation includes:
|
|
20
|
-
|
|
21
|
-
- TypeScript source, declarations, and dual ESM/CJS package output.
|
|
22
|
-
- Vitest coverage gates at 90% across statements, branches, functions, and lines.
|
|
23
|
-
- ESLint, Prettier, typecheck, build, package dry-run, and CI scripts.
|
|
24
|
-
- Typed error classes, safe remote argument validation, structured logging redaction helpers, FTP parser tests, and an initial classic FTP provider contract slice.
|
|
25
|
-
- Provider-neutral core contracts, provider registry, `TransferClient`, `createTransferClient()`, provider capability discovery, deterministic memory and local providers with read/write transfer operations, an MLST/MLSD/EPSV/PASV-based FTP provider with streaming read/write transfer operations, profile secret utilities, transfer plans, transfer queue primitives, and the initial transfer engine.
|
|
26
|
-
- Verbose JSDoc across the public TypeScript API for future generated documentation.
|
|
27
|
-
- Initial GitHub Actions scaffolding for CI, CodeQL, and npmjs release provenance.
|
|
28
|
-
|
|
29
|
-
## Installation
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
npm install @zero-transfer/sdk
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Intended API Direction
|
|
36
|
-
|
|
37
|
-
```ts
|
|
38
|
-
import { ZeroTransfer } from "@zero-transfer/sdk";
|
|
39
|
-
|
|
40
|
-
const client = await ZeroTransfer.connect({
|
|
41
|
-
provider: "ftps",
|
|
42
|
-
host: "ftp.example.com",
|
|
43
|
-
username: "deploy",
|
|
44
|
-
password: { env: "FTP_PASSWORD" },
|
|
45
|
-
secure: true,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const entries = await client.list("/releases");
|
|
49
|
-
const artifact = await client.stat("/releases/app.zip");
|
|
50
|
-
await client.disconnect();
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
`ZeroTransfer` is the facade for new provider-neutral code. Protocol-specific behavior lives behind providers and adapters rather than a protocol-named client class.
|
|
54
|
-
|
|
55
|
-
The first provider-neutral core path is also available for provider registration and capability discovery:
|
|
56
|
-
|
|
57
|
-
```ts
|
|
58
|
-
import { createTransferClient } from "@zero-transfer/sdk";
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>One TypeScript SDK for moving files across every storage system you actually use.</strong><br/>
|
|
9
|
+
FTP · FTPS · SFTP · HTTP(S) · WebDAV · S3-compatible · Azure Blob · GCS · Google Drive · Dropbox · OneDrive · Local
|
|
10
|
+
</p>
|
|
59
11
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/@zero-transfer/sdk"><img src="https://img.shields.io/npm/v/@zero-transfer/sdk.svg?style=for-the-badge&labelColor=0d1117&color=00b4d8&logo=npm&logoColor=white&label=%40zero-transfer%2Fsdk" alt="npm version"></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/@zero-transfer/sdk"><img src="https://img.shields.io/npm/dm/@zero-transfer/sdk.svg?style=for-the-badge&labelColor=0d1117&color=00b4d8&logo=npm&logoColor=white" alt="npm downloads"></a>
|
|
15
|
+
<a href="https://github.com/tonywied17/zero-transfer/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/tonywied17/zero-transfer/ci.yml?branch=main&style=for-the-badge&labelColor=0d1117&logo=githubactions&logoColor=white&label=CI" alt="CI"></a>
|
|
16
|
+
<a href="https://github.com/tonywied17/zero-transfer/actions/workflows/ci.yml"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Ftonywied17.github.io%2Fzero-transfer%2Fbadges%2Ftests.json&style=for-the-badge&labelColor=0d1117&logo=vitest&logoColor=white" alt="Tests"></a>
|
|
17
|
+
<a href="https://github.com/tonywied17/zero-transfer/actions/workflows/ci.yml"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Ftonywied17.github.io%2Fzero-transfer%2Fbadges%2Fcoverage.json&style=for-the-badge&labelColor=0d1117&logo=vitest&logoColor=white" alt="Coverage"></a>
|
|
18
|
+
<a href="https://tonywied17.github.io/zero-transfer/"><img src="https://img.shields.io/badge/docs-typedoc-00b4d8?style=for-the-badge&labelColor=0d1117&logo=readthedocs&logoColor=white" alt="Docs"></a>
|
|
19
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-00b4d8?style=for-the-badge&labelColor=0d1117" alt="License"></a>
|
|
20
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D20-339933?style=for-the-badge&labelColor=0d1117&logo=nodedotjs&logoColor=white" alt="Node.js"></a>
|
|
21
|
+
</p>
|
|
63
22
|
|
|
64
|
-
|
|
23
|
+
ZeroTransfer is a unified, TypeScript-first file transfer SDK for Node.js. One typed API speaks to every backend you actually deploy against — classic protocols, web endpoints, object storage, cloud drives, and local disks — with streaming, resume, verification, dry-run plans, MFT-style scheduling, audit logs, and webhook delivery built in.
|
|
65
24
|
|
|
66
25
|
```ts
|
|
67
|
-
import {
|
|
26
|
+
import { createS3ProviderFactory, createTransferClient, uploadFile } from "@zero-transfer/sdk";
|
|
68
27
|
|
|
69
28
|
const client = createTransferClient({
|
|
70
|
-
providers: [
|
|
29
|
+
providers: [createS3ProviderFactory({ region: "us-east-1" })],
|
|
71
30
|
});
|
|
72
31
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
32
|
+
// One call, any provider you registered above.
|
|
33
|
+
await uploadFile({
|
|
34
|
+
client,
|
|
35
|
+
localPath: "./dist/app.tar.gz",
|
|
36
|
+
destination: {
|
|
37
|
+
path: "/lake/bronze/app.tar.gz",
|
|
38
|
+
profile: {
|
|
39
|
+
provider: "s3",
|
|
40
|
+
host: "data-lake-bronze",
|
|
41
|
+
username: { env: "AWS_ACCESS_KEY_ID" },
|
|
42
|
+
password: { env: "AWS_SECRET_ACCESS_KEY" },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
78
45
|
});
|
|
79
|
-
|
|
80
|
-
const releases = await session.fs.list("/releases");
|
|
81
|
-
const artifact = await session.fs.stat("/releases/app.zip");
|
|
82
|
-
await session.disconnect();
|
|
83
46
|
```
|
|
84
47
|
|
|
85
|
-
|
|
48
|
+
---
|
|
86
49
|
|
|
87
|
-
|
|
88
|
-
import { createFtpsProviderFactory, createTransferClient } from "@zero-transfer/sdk";
|
|
50
|
+
## Why ZeroTransfer
|
|
89
51
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
52
|
+
- **One API, every provider.** Replace bespoke FTP, SFTP, S3, and cloud-drive code with a single `TransferClient` and provider-neutral sessions.
|
|
53
|
+
- **TypeScript-first.** Strict types, exact optional properties, exhaustive capability discovery, and typed errors for every protocol failure mode.
|
|
54
|
+
- **Streaming + resume.** Backpressure via `stream.pipeline`, byte-range downloads, multipart uploads, and cross-process resume stores for object storage.
|
|
55
|
+
- **Dry-run-first sync.** Diff remote trees, generate `TransferPlan`s, and review every step before any byte moves.
|
|
56
|
+
- **MFT batteries.** Routes, cron + interval schedules, audit logs, HMAC-signed webhooks, retention policies, and approval gates that block on human sign-off.
|
|
57
|
+
- **Security by default.** Profile redaction in every log, host-key pinning, certificate fingerprint pinning, OAuth refresh, and SecretSource adapters for vaults / env / files / commands.
|
|
58
|
+
- **Observable.** Structured logger, redaction-safe diagnostics, immutable transfer receipts, and per-attempt history for compliance.
|
|
93
59
|
|
|
94
|
-
|
|
95
|
-
provider: "ftps",
|
|
96
|
-
host: "ftp.example.com",
|
|
97
|
-
username: { env: "FTP_USERNAME" },
|
|
98
|
-
password: { env: "FTP_PASSWORD" },
|
|
99
|
-
tls: {
|
|
100
|
-
ca: { path: "./certs/private-ca.pem" },
|
|
101
|
-
servername: "ftp.example.com",
|
|
102
|
-
},
|
|
103
|
-
});
|
|
60
|
+
## Install
|
|
104
61
|
|
|
105
|
-
|
|
106
|
-
|
|
62
|
+
```bash
|
|
63
|
+
# Batteries-included SDK (every provider):
|
|
64
|
+
npm install @zero-transfer/sdk
|
|
65
|
+
|
|
66
|
+
# Or pick a scoped slice (today these re-export the full SDK; future releases will narrow):
|
|
67
|
+
npm install @zero-transfer/sftp
|
|
68
|
+
npm install @zero-transfer/s3
|
|
69
|
+
npm install @zero-transfer/mft
|
|
107
70
|
```
|
|
108
71
|
|
|
109
|
-
|
|
72
|
+
Requires Node.js **>=20**.
|
|
110
73
|
|
|
111
|
-
|
|
112
|
-
import { createMemoryProviderFactory, createTransferClient } from "@zero-transfer/sdk";
|
|
74
|
+
## Scoped packages
|
|
113
75
|
|
|
114
|
-
|
|
115
|
-
providers: [
|
|
116
|
-
createMemoryProviderFactory({
|
|
117
|
-
entries: [{ path: "/fixtures/report.csv", type: "file", size: 24 }],
|
|
118
|
-
}),
|
|
119
|
-
],
|
|
120
|
-
});
|
|
76
|
+
ZeroTransfer publishes 13 scoped packages under the [`@zero-transfer`](https://www.npmjs.com/org/zero-transfer) npm organization. [`@zero-transfer/sdk`](https://www.npmjs.com/package/@zero-transfer/sdk) is the batteries-included distribution; the other 12 are **narrowly scoped** packages that re-export only the symbols listed in their [scope page](docs/scopes/README.md). Pick one to keep your dependency tree tight, or install the SDK if you want every provider in one go.
|
|
121
77
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
78
|
+
| Package | Summary | Docs |
|
|
79
|
+
| ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- | ----------------------------------------- |
|
|
80
|
+
| [`@zero-transfer/sdk`](https://www.npmjs.com/package/@zero-transfer/sdk) | Batteries-included distribution. Every provider, every helper. | [API reference](docs/api-md/README.md) |
|
|
81
|
+
| [`@zero-transfer/core`](https://www.npmjs.com/package/@zero-transfer/core) | Provider-neutral contracts, transfer engine, queue, profiles, errors. | [Scope page](docs/scopes/core.md) |
|
|
82
|
+
| [`@zero-transfer/classic`](https://www.npmjs.com/package/@zero-transfer/classic) | FTP + FTPS + SFTP in one install. | [Scope page](docs/scopes/classic.md) |
|
|
83
|
+
| [`@zero-transfer/ftp`](https://www.npmjs.com/package/@zero-transfer/ftp) | Classic FTP with EPSV/PASV streaming and REST resume. | [Scope page](docs/scopes/ftp.md) |
|
|
84
|
+
| [`@zero-transfer/ftps`](https://www.npmjs.com/package/@zero-transfer/ftps) | Explicit + implicit FTPS with full TLS profile support. | [Scope page](docs/scopes/ftps.md) |
|
|
85
|
+
| [`@zero-transfer/sftp`](https://www.npmjs.com/package/@zero-transfer/sftp) | SFTP with SSH key auth, known_hosts, and jump-host support. | [Scope page](docs/scopes/sftp.md) |
|
|
86
|
+
| [`@zero-transfer/http`](https://www.npmjs.com/package/@zero-transfer/http) | HTTP(S) and signed-URL provider with ranged downloads. | [Scope page](docs/scopes/http.md) |
|
|
87
|
+
| [`@zero-transfer/webdav`](https://www.npmjs.com/package/@zero-transfer/webdav) | WebDAV with PROPFIND listings and ranged downloads. | [Scope page](docs/scopes/webdav.md) |
|
|
88
|
+
| [`@zero-transfer/s3`](https://www.npmjs.com/package/@zero-transfer/s3) | S3-compatible storage with SigV4, multipart upload, and cross-process resume. | [Scope page](docs/scopes/s3.md) |
|
|
89
|
+
| [`@zero-transfer/google-drive`](https://www.npmjs.com/package/@zero-transfer/google-drive) | Google Drive with OAuth, folder paths, md5 checksums. | [Scope page](docs/scopes/google-drive.md) |
|
|
90
|
+
| [`@zero-transfer/dropbox`](https://www.npmjs.com/package/@zero-transfer/dropbox) | Dropbox with content-hash verification. | [Scope page](docs/scopes/dropbox.md) |
|
|
91
|
+
| [`@zero-transfer/azure-blob`](https://www.npmjs.com/package/@zero-transfer/azure-blob) | Azure Blob Storage with SAS or AAD bearer auth. | [Scope page](docs/scopes/azure-blob.md) |
|
|
92
|
+
| [`@zero-transfer/mft`](https://www.npmjs.com/package/@zero-transfer/mft) | Routes, schedules, audit logs, webhooks, approval gates. | [Scope page](docs/scopes/mft.md) |
|
|
93
|
+
|
|
94
|
+
The full per-scope index lives at [`docs/scopes/`](docs/scopes/README.md).
|
|
127
95
|
|
|
128
|
-
|
|
96
|
+
## Quick start
|
|
129
97
|
|
|
130
|
-
|
|
98
|
+
### 1. Connect a provider-neutral client
|
|
131
99
|
|
|
132
100
|
```ts
|
|
133
|
-
import {
|
|
101
|
+
import { createSftpProviderFactory, createTransferClient } from "@zero-transfer/sdk";
|
|
134
102
|
|
|
135
103
|
const client = createTransferClient({
|
|
136
|
-
providers: [
|
|
104
|
+
providers: [createSftpProviderFactory()],
|
|
137
105
|
});
|
|
138
106
|
|
|
139
|
-
const session = await client.connect({
|
|
140
|
-
const files = await session.fs.list("/");
|
|
141
|
-
await session.disconnect();
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
The local provider also exposes provider transfer reads/writes under `session.transfers` for local-only workflow tests and early transfer-engine coverage.
|
|
145
|
-
|
|
146
|
-
Profile helpers are also available for validating connection profiles, resolving deferred secret sources, and redacting diagnostics:
|
|
147
|
-
|
|
148
|
-
```ts
|
|
149
|
-
import {
|
|
150
|
-
redactConnectionProfile,
|
|
151
|
-
resolveConnectionProfileSecrets,
|
|
152
|
-
validateConnectionProfile,
|
|
153
|
-
} from "@zero-transfer/sdk";
|
|
154
|
-
|
|
155
|
-
const profile = validateConnectionProfile({
|
|
107
|
+
const session = await client.connect({
|
|
156
108
|
provider: "sftp",
|
|
157
109
|
host: "files.example.com",
|
|
158
110
|
username: { env: "ZT_USER" },
|
|
@@ -163,123 +115,140 @@ const profile = validateConnectionProfile({
|
|
|
163
115
|
},
|
|
164
116
|
});
|
|
165
117
|
|
|
166
|
-
const
|
|
167
|
-
|
|
118
|
+
const releases = await session.fs.list("/releases");
|
|
119
|
+
await session.disconnect();
|
|
168
120
|
```
|
|
169
121
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
The first transfer-engine foundation is available for adapters and higher-level workflows that need abort-aware execution, progress callbacks, retry hooks, timeout policy, bandwidth-limit handoff, verification details, and audit receipts around a concrete transfer operation:
|
|
122
|
+
### 2. Move a file with one call
|
|
173
123
|
|
|
174
124
|
```ts
|
|
175
|
-
import {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
totalBytes: 1024,
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
const receipt = await engine.execute(
|
|
187
|
-
job,
|
|
188
|
-
(context) => {
|
|
189
|
-
context.reportProgress(1024);
|
|
190
|
-
return {
|
|
191
|
-
bytesTransferred: 1024,
|
|
192
|
-
verification: { method: "checksum", verified: true },
|
|
193
|
-
};
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
bandwidthLimit: { bytesPerSecond: 1024 * 1024 },
|
|
197
|
-
retry: { maxAttempts: 2 },
|
|
198
|
-
timeout: { timeoutMs: 30_000 },
|
|
199
|
-
},
|
|
200
|
-
);
|
|
125
|
+
import { uploadFile } from "@zero-transfer/sdk";
|
|
126
|
+
|
|
127
|
+
await uploadFile({
|
|
128
|
+
client,
|
|
129
|
+
localPath: "./dist/app.tar.gz",
|
|
130
|
+
destination: { path: "/releases/2026.04.28/app.tar.gz", profile: sftpProfile },
|
|
131
|
+
onProgress: (event) => console.log(`${event.bytesTransferred}/${event.totalBytes ?? "?"}`),
|
|
132
|
+
});
|
|
201
133
|
```
|
|
202
134
|
|
|
203
|
-
|
|
135
|
+
### 3. Plan a sync without touching bytes
|
|
204
136
|
|
|
205
137
|
```ts
|
|
206
|
-
import {
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
138
|
+
import { createSyncPlan, diffRemoteTrees, summarizeTransferPlan } from "@zero-transfer/sdk";
|
|
139
|
+
|
|
140
|
+
const diff = await diffRemoteTrees(srcSession.fs, "/dist", dstSession.fs, "/releases/current");
|
|
141
|
+
const plan = createSyncPlan({
|
|
142
|
+
id: "release-sync",
|
|
143
|
+
diff,
|
|
144
|
+
source: { provider: "sftp", rootPath: "/dist" },
|
|
145
|
+
destination: { provider: "s3", rootPath: "/releases/current" },
|
|
146
|
+
deletePolicy: "mirror",
|
|
214
147
|
});
|
|
148
|
+
console.table(summarizeTransferPlan(plan));
|
|
215
149
|
```
|
|
216
150
|
|
|
217
|
-
|
|
151
|
+
### 4. Schedule it as an MFT route with audit + approval
|
|
218
152
|
|
|
219
153
|
```ts
|
|
220
|
-
import {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
source: { provider: "local", path: "./dist/app.zip" },
|
|
229
|
-
destination: { provider: "memory", path: "/releases/app.zip" },
|
|
230
|
-
expectedBytes: 1024,
|
|
231
|
-
},
|
|
232
|
-
],
|
|
233
|
-
});
|
|
154
|
+
import {
|
|
155
|
+
ApprovalRegistry,
|
|
156
|
+
MftScheduler,
|
|
157
|
+
RouteRegistry,
|
|
158
|
+
ScheduleRegistry,
|
|
159
|
+
createApprovalGate,
|
|
160
|
+
runRoute,
|
|
161
|
+
} from "@zero-transfer/sdk";
|
|
234
162
|
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
163
|
+
const approvals = new ApprovalRegistry();
|
|
164
|
+
const scheduler = new MftScheduler({
|
|
165
|
+
client,
|
|
166
|
+
routes: new RouteRegistry([route]),
|
|
167
|
+
schedules: scheduleRegistry,
|
|
168
|
+
runner: createApprovalGate({
|
|
169
|
+
approvalId: ({ route }) => `release:${route.id}:${Date.now()}`,
|
|
170
|
+
registry: approvals,
|
|
171
|
+
runner: ({ client: c, route: r, signal }) => runRoute({ client: c, route: r, signal }),
|
|
172
|
+
}),
|
|
173
|
+
onResult: ({ receipt }) => console.log(`Released ${receipt.jobId}`),
|
|
242
174
|
});
|
|
243
175
|
|
|
244
|
-
|
|
245
|
-
queue.add(plannedJob);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const summary = await queue.run();
|
|
176
|
+
scheduler.start();
|
|
249
177
|
```
|
|
250
178
|
|
|
251
|
-
##
|
|
179
|
+
## Capability matrix
|
|
180
|
+
|
|
181
|
+
Every provider advertises its own [`CapabilitySet`](docs/api-md/interfaces/CapabilitySet.md). The full programmatic matrix is exposed via [`getBuiltinCapabilityMatrix()`](docs/api-md/functions/getBuiltinCapabilityMatrix.md) and renders to Markdown via [`formatCapabilityMatrixMarkdown()`](docs/api-md/functions/formatCapabilityMatrixMarkdown.md).
|
|
182
|
+
|
|
183
|
+
| Provider | Streaming | Resume | Server-side copy | Multipart upload | Checksum exposed |
|
|
184
|
+
| ------------- | :-------: | :------------------------------: | :--------------: | :--------------: | :----------------------: |
|
|
185
|
+
| FTP | ✅ | ⬆/⬇ via REST | — | — | — |
|
|
186
|
+
| FTPS | ✅ | ⬆/⬇ via REST | — | — | — |
|
|
187
|
+
| SFTP | ✅ | ⬆/⬇ | rename | — | — |
|
|
188
|
+
| HTTP(S) | ✅ (read) | ⬇ via Range | — | — | ETag |
|
|
189
|
+
| WebDAV | ✅ | ⬇ via Range | COPY | — | ETag |
|
|
190
|
+
| S3-compatible | ✅ | ⬆ via multipart resume / ⬇ Range | CopyObject | ✅ | SHA-256 / md5 |
|
|
191
|
+
| Azure Blob | ✅ | ⬇ via Range | — | (planned) | md5 |
|
|
192
|
+
| GCS | ✅ | ⬇ via Range | — | (planned) | crc32c / md5 |
|
|
193
|
+
| Google Drive | ✅ | ⬇ via Range | — | — | md5 |
|
|
194
|
+
| Dropbox | ✅ | ⬇ via Range | — | — | content_hash |
|
|
195
|
+
| OneDrive | ✅ | ⬇ via Range | — | (planned) | sha256 / sha1 / quickXor |
|
|
196
|
+
| Local | ✅ | ⬆/⬇ | — | — | — |
|
|
197
|
+
| Memory | ✅ | ⬆/⬇ | — | — | — |
|
|
198
|
+
|
|
199
|
+
## Examples
|
|
200
|
+
|
|
201
|
+
Real-world examples live in [`examples/`](https://github.com/tonywied17/zero-transfer/tree/main/examples). Run them with `tsx examples/<file>`.
|
|
202
|
+
|
|
203
|
+
| Example | What it shows |
|
|
204
|
+
| --------------------------------------------------------------------------- | ----------------------------------------------------------------- |
|
|
205
|
+
| [`local-copy-file.ts`](examples/local-copy-file.ts) | Zero-config local-to-local copy via `copyBetween`. |
|
|
206
|
+
| [`ftp-basic.ts`](examples/ftp-basic.ts) | Plain FTP upload + download round-trip with username/password. |
|
|
207
|
+
| [`ftps-basic.ts`](examples/ftps-basic.ts) | FTPS with username/password over a public-CA endpoint. |
|
|
208
|
+
| [`ftps-client-certificate.ts`](examples/ftps-client-certificate.ts) | FTPS hardened: mTLS + private CA bundle + fingerprint pinning. |
|
|
209
|
+
| [`sftp-basic.ts`](examples/sftp-basic.ts) | Minimal SFTP with username/password (no host-key pinning). |
|
|
210
|
+
| [`sftp-private-key.ts`](examples/sftp-private-key.ts) | SFTP hardened: private-key auth + pinned host-key SHA-256. |
|
|
211
|
+
| [`s3-compatible-upload.ts`](examples/s3-compatible-upload.ts) | S3 multipart upload with cross-process resume store. |
|
|
212
|
+
| [`webdav-sync.ts`](examples/webdav-sync.ts) | WebDAV diff + sync plan with deterministic ordering. |
|
|
213
|
+
| [`signed-url-download.ts`](examples/signed-url-download.ts) | HTTPS signed-URL download with progress reporting. |
|
|
214
|
+
| [`transfer-queue.ts`](examples/transfer-queue.ts) | Concurrent transfers with `TransferQueue` + executor. |
|
|
215
|
+
| [`dry-run-sync.ts`](examples/dry-run-sync.ts) | Plan a sync, print a summary, never touch bytes. |
|
|
216
|
+
| [`mft-route.ts`](examples/mft-route.ts) | SFTP→S3 cron-scheduled MFT route with audit hooks. |
|
|
217
|
+
| [`profile-from-env.ts`](examples/profile-from-env.ts) | Build a `ConnectionProfile` from env / file / base64-env secrets. |
|
|
218
|
+
| [`diagnose-connection.ts`](examples/diagnose-connection.ts) | Provider summary + redaction-safe connection probe. |
|
|
219
|
+
| [`approval-gated-route.ts`](examples/approval-gated-route.ts) | Two-person rule: scheduled route blocks until approval lands. |
|
|
220
|
+
| [`multi-cloud-orchestration.ts`](examples/multi-cloud-orchestration.ts) | Fan-out SFTP → S3 + Azure + Local with webhook audit. |
|
|
221
|
+
| [`atomic-deploy-with-rollback.ts`](examples/atomic-deploy-with-rollback.ts) | Blue/green-style deploy plan with rollback path. |
|
|
222
|
+
|
|
223
|
+
## Documentation
|
|
224
|
+
|
|
225
|
+
- [Full API reference (HTML)](https://tonywied17.github.io/zero-transfer/) — TypeDoc HTML site, deployed from `main` on every push.
|
|
226
|
+
- [Full API reference (Markdown)](docs/api-md/README.md) — every public symbol with parameter / property / type tables.
|
|
227
|
+
- [Per-scope pages](docs/scopes/README.md) — one page per `@zero-transfer/*` package.
|
|
228
|
+
- [Examples directory](https://github.com/tonywied17/zero-transfer/tree/main/examples) — runnable real-world flows.
|
|
229
|
+
|
|
230
|
+
Regenerate everything locally:
|
|
252
231
|
|
|
253
232
|
```bash
|
|
254
|
-
npm
|
|
255
|
-
npm run lint
|
|
256
|
-
npm run format:check
|
|
257
|
-
npm run typecheck
|
|
258
|
-
npm run test:coverage
|
|
259
|
-
npm run build
|
|
260
|
-
npm run pack:dry
|
|
233
|
+
npm run docs:all # HTML + Markdown api refs + per-scope pages + per-package READMEs
|
|
261
234
|
```
|
|
262
235
|
|
|
263
|
-
|
|
236
|
+
## Project status
|
|
237
|
+
|
|
238
|
+
ZeroTransfer is in **alpha** under the `alpha` npm dist-tag. The provider-neutral foundation, transfer engine, queue, sync planner, atomic deploy planner, MFT layer, friendly client surface, and diagnostics module are stable. Phase work in progress: resumable upload sessions for Azure / GCS / OneDrive, broader real-server compatibility coverage, and the push to higher coverage targets.
|
|
264
239
|
|
|
265
|
-
|
|
266
|
-
container. With Docker running locally, use:
|
|
240
|
+
## Contributing
|
|
267
241
|
|
|
268
242
|
```bash
|
|
269
|
-
|
|
243
|
+
git clone https://github.com/tonywied17/zero-transfer.git
|
|
244
|
+
cd zero-transfer
|
|
245
|
+
npm install
|
|
246
|
+
npm run ci # lint, format check, typecheck, tests with coverage, build, pack dry-run
|
|
247
|
+
npm run test:watch # iterate
|
|
270
248
|
```
|
|
271
249
|
|
|
272
|
-
|
|
273
|
-
metadata and transfer round-trip coverage, and tears the container down afterward.
|
|
274
|
-
|
|
275
|
-
## Publishing
|
|
276
|
-
|
|
277
|
-
ZeroTransfer publishes only to the public npm registry as `@zero-transfer/sdk`.
|
|
278
|
-
|
|
279
|
-
The `zero-transfer` npm organization owns the package scope. The first package is the batteries-included SDK at `@zero-transfer/sdk`; future monorepo packages can split provider-neutral contracts into `@zero-transfer/core` and adapters such as `@zero-transfer/ftp`, `@zero-transfer/sftp`, and `@zero-transfer/s3` when the contracts prove out.
|
|
280
|
-
|
|
281
|
-
Publishing is configured for npm provenance through GitHub Actions. For token-based test publishing, add the npm automation token as a repository secret named `NPM_TOKEN`; never commit npm tokens or place them in local config files. There is no GitHub Packages release target.
|
|
250
|
+
Issues and PRs welcome. Provider integration tests are gated behind opt-in env vars — see [`test/integration/`](https://github.com/tonywied17/zero-transfer/tree/main/test/integration) for the full list.
|
|
282
251
|
|
|
283
252
|
## License
|
|
284
253
|
|
|
285
|
-
MIT
|
|
254
|
+
MIT © [Tony Wiedman](https://github.com/tonywied17)
|