@zero-transfer/sdk 0.1.0-alpha.0
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/CHANGELOG.md +177 -0
- package/LICENSE +21 -0
- package/README.md +285 -0
- package/assets/zero-transfer-logo.svg +201 -0
- package/dist/index.cjs +11812 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +4186 -0
- package/dist/index.d.ts +4186 -0
- package/dist/index.mjs +11650 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +94 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.0-alpha.0] - 2026-04-27
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Prepared the package to publish under the `zero-transfer` npm organization as `@zero-transfer/sdk`.
|
|
8
|
+
- Updated repository metadata and documentation for the `tonywied17/zero-transfer` GitHub repository.
|
|
9
|
+
- Refreshed the animated ZeroTransfer logo and package tagline around a unified file-transfer SDK identity.
|
|
10
|
+
- Renamed package foundation from legacy FTP-first naming to `@zero-transfer/sdk`.
|
|
11
|
+
- Switched the package entry point to the new TypeScript `src/` rebuild output.
|
|
12
|
+
- Removed the old CommonJS FTP implementation after the TypeScript foundation became the package surface.
|
|
13
|
+
- Switched project licensing from ISC to MIT.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- TypeScript, build, lint, format, typecheck, test, coverage, and package dry-run scripts.
|
|
18
|
+
- Initial parser-first test harness with 90% coverage gates.
|
|
19
|
+
- Verbose JSDoc comments for the TypeScript API foundation.
|
|
20
|
+
- Animated ZeroTransfer SVG logo assets for the repository README and package.
|
|
21
|
+
- npmjs-only publishing metadata with provenance enabled.
|
|
22
|
+
- CI, release, CodeQL, Dependabot, and integration-server scaffolding.
|
|
23
|
+
|
|
24
|
+
## [2.3.0] - 2026-02-02
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- `uploadFile(localPath, remotePath, ensureDir)` - Upload local files from disk
|
|
29
|
+
- `downloadFile(remotePath, localPath)` - Download files directly to disk
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- **Simplified `ensureDir()` API** - now auto-detects file paths (by extension) and creates parent directory
|
|
34
|
+
- No more confusing `ensureDir(path, true, true)` - just `ensureDir(path)` works for both files and directories
|
|
35
|
+
- Example: `ensureDir('/path/file.txt')` automatically creates `/path/` directory
|
|
36
|
+
|
|
37
|
+
## [2.2.0] - 2026-02-02
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- **CRITICAL: Fixed 30-second timeout on all data transfers** - upload, download, list, downloadStream now complete instantly
|
|
42
|
+
- Commands with data connections no longer wait for 226 completion response, dramatically improving speed
|
|
43
|
+
- Download speed improved from 0.03 MB/s to 2.47 MB/s (80x faster!)
|
|
44
|
+
- Recursive directory deletion now blazing fast (sub-second instead of minutes)
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- `removeDir(path, recursive)` - Remove directories with optional recursive deletion
|
|
49
|
+
- `chmod(path, mode)` - Change file permissions (Unix/Linux servers)
|
|
50
|
+
- `listDetailed(path)` - Get parsed directory listings with permissions, owner, size, etc.
|
|
51
|
+
- `site(command)` - Execute server-specific SITE commands
|
|
52
|
+
|
|
53
|
+
### Improved
|
|
54
|
+
|
|
55
|
+
- `listDetailed()` now filters out `.` and `..` entries automatically
|
|
56
|
+
- Better handling of unknown file types in recursive operations
|
|
57
|
+
|
|
58
|
+
## [2.1.0] - 2026-02-02
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
|
|
62
|
+
- `stat()` method returns detailed file/directory information: `{ exists, size, isFile, isDirectory }`
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- **Simplified performance system** - removed over-engineered preset configuration
|
|
67
|
+
- TCP optimizations (TCP_NODELAY, keep-alive) now applied by default at socket creation
|
|
68
|
+
- `createOptimizedSocket()` replaces repeated `optimizeSocket()` calls for cleaner code
|
|
69
|
+
- Updated `exists()` to use new `stat()` method internally
|
|
70
|
+
|
|
71
|
+
### Removed
|
|
72
|
+
|
|
73
|
+
- Performance presets (LOW_LATENCY, HIGH_THROUGHPUT, BALANCED) - unnecessary complexity
|
|
74
|
+
- `performancePreset` and `performance` constructor options
|
|
75
|
+
- `getOptimalChunkSize()` function - Node.js doesn't expose socket buffer controls
|
|
76
|
+
|
|
77
|
+
## [2.0.0] - 2026-02-02
|
|
78
|
+
|
|
79
|
+
### Breaking Changes
|
|
80
|
+
|
|
81
|
+
- Removed `ensureParentDir()` - use `ensureDir(path, true, true)` instead
|
|
82
|
+
- Removed `uploadFile()` - use `upload(data, path, true)` instead
|
|
83
|
+
|
|
84
|
+
### Added
|
|
85
|
+
|
|
86
|
+
- **Performance optimization system** with TCP tuning (inspired by HFT practices)
|
|
87
|
+
- `downloadStream()` method for memory-efficient large file transfers
|
|
88
|
+
- `isConnected()` method to check connection and authentication status
|
|
89
|
+
- Parameter validation for `connect()`, `upload()`, and `download()`
|
|
90
|
+
- Connection state validation before upload/download operations
|
|
91
|
+
- Better error messages with file path context
|
|
92
|
+
- Data socket cleanup in connection close
|
|
93
|
+
- New `lib/performance.js` module for TCP optimization utilities
|
|
94
|
+
|
|
95
|
+
### Improved
|
|
96
|
+
|
|
97
|
+
- **40-50% faster downloads** for small files with LOW_LATENCY preset
|
|
98
|
+
- **`exists()` now properly detects directories** (previously only detected files)
|
|
99
|
+
- All timeouts now respect `client.timeout` configuration (no more hardcoded values)
|
|
100
|
+
- Error messages include file paths for better debugging
|
|
101
|
+
- Connection cleanup includes data socket termination
|
|
102
|
+
- Code quality: added missing semicolons and consistent formatting
|
|
103
|
+
- All data connections now apply performance optimizations
|
|
104
|
+
|
|
105
|
+
### Changed
|
|
106
|
+
|
|
107
|
+
- `upload()` now accepts optional `ensureDir` boolean parameter (default: false)
|
|
108
|
+
- `ensureDir()` now accepts optional `isFilePath` boolean parameter (default: false)
|
|
109
|
+
- Consolidated API reduces method count while maintaining functionality
|
|
110
|
+
- TCP sockets now optimized on connection for better performance
|
|
111
|
+
|
|
112
|
+
## [1.2.1] - 2026-02-02
|
|
113
|
+
|
|
114
|
+
### Changed
|
|
115
|
+
|
|
116
|
+
- Improved README documentation
|
|
117
|
+
- Better examples for `ensureDir()`, `ensureParentDir()`, and `uploadFile()`
|
|
118
|
+
- Added architecture section explaining modular structure
|
|
119
|
+
- Enhanced feature list highlighting directory management capabilities
|
|
120
|
+
- Reorganized API documentation for better clarity
|
|
121
|
+
|
|
122
|
+
## [1.2.0] - 2026-02-02
|
|
123
|
+
|
|
124
|
+
### Changed
|
|
125
|
+
|
|
126
|
+
- **Major refactoring**: Improved separation of concerns
|
|
127
|
+
- `index.js` now serves as simple entry point
|
|
128
|
+
- Implementation moved to organized `lib/` structure:
|
|
129
|
+
- `lib/FTPClient.js` - Main class definition
|
|
130
|
+
- `lib/connection.js` - Connection and authentication logic
|
|
131
|
+
- `lib/commands.js` - All FTP command implementations
|
|
132
|
+
- `lib/utils.js` - Helper functions
|
|
133
|
+
- Better code maintainability and readability
|
|
134
|
+
- No breaking changes - API remains identical
|
|
135
|
+
|
|
136
|
+
## [1.1.0] - 2026-02-02
|
|
137
|
+
|
|
138
|
+
### Added
|
|
139
|
+
|
|
140
|
+
- `ensureDir(dirPath, recursive)` - Ensure directory exists, creating parent directories if needed
|
|
141
|
+
- `ensureParentDir(filePath)` - Ensure parent directory exists for a file path
|
|
142
|
+
- `uploadFile(data, remotePath, ensureDir)` - Upload with automatic directory creation
|
|
143
|
+
- Utility library (`lib/utils.js`) for better code organization
|
|
144
|
+
- Helper functions for FTP command parsing and path manipulation
|
|
145
|
+
|
|
146
|
+
### Changed
|
|
147
|
+
|
|
148
|
+
- Refactored internal code structure for better maintainability
|
|
149
|
+
- Improved path normalization across all directory operations
|
|
150
|
+
- Better error handling for directory creation
|
|
151
|
+
|
|
152
|
+
### Improved
|
|
153
|
+
|
|
154
|
+
- Cleaner API for common operations
|
|
155
|
+
- Reduced boilerplate code needed for directory handling
|
|
156
|
+
- More consistent error messages
|
|
157
|
+
|
|
158
|
+
## [1.0.1] - 2026-02-02
|
|
159
|
+
|
|
160
|
+
### Fixed
|
|
161
|
+
|
|
162
|
+
- Updated repository URLs to correct GitHub location
|
|
163
|
+
|
|
164
|
+
## [1.0.0] - 2026-02-02
|
|
165
|
+
|
|
166
|
+
### Initial Release
|
|
167
|
+
|
|
168
|
+
- Zero dependencies FTP client using native Node.js TCP sockets
|
|
169
|
+
- Promise-based API with async/await support
|
|
170
|
+
- Passive mode (PASV) for data transfers
|
|
171
|
+
- Debug logging with configurable options
|
|
172
|
+
- Connection keep-alive and timeout configuration
|
|
173
|
+
- Upload/download files with Buffer support
|
|
174
|
+
- Directory operations (list, cd, mkdir, pwd)
|
|
175
|
+
- File operations (delete, rename, size, exists, modifiedTime)
|
|
176
|
+
- Connection statistics tracking
|
|
177
|
+
- Event-based architecture
|
package/LICENSE
ADDED
|
@@ -0,0 +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.
|
package/README.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/zero-transfer-logo.svg" alt="ZeroTransfer file transfer SDK for Node.js" width="720">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# ZeroTransfer
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@zero-transfer/sdk)
|
|
8
|
+
[](https://www.npmjs.com/package/@zero-transfer/sdk)
|
|
9
|
+
[](https://github.com/tonywied17/zero-transfer/actions/workflows/ci.yml)
|
|
10
|
+
[](https://opensource.org/licenses/MIT)
|
|
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";
|
|
59
|
+
|
|
60
|
+
const client = createTransferClient();
|
|
61
|
+
const capabilities = client.getCapabilities();
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Provider factories can be registered with `createTransferClient({ providers: [...] })`. Classic network providers are being added incrementally; the FTP provider supports login, `fs.stat()` through MLST, `fs.list()` through EPSV/PASV MLSD, streaming provider transfer reads/writes through EPSV/PASV `RETR`/`STOR` with REST offsets, and profile `timeoutMs` enforcement across control replies and passive transfers. The first FTPS slice supports explicit `AUTH TLS`, `PBSZ 0`, encrypted `PROT P` data channels, and TLS profile fields for CA bundles, client certificates, keys, PFX/P12 bundles, passphrases, SNI, TLS versions, and certificate validation controls. The SFTP provider supports password, private-key, agent, and keyboard-interactive authentication, SSH transport algorithm overrides, custom socket factories for proxy and tunnel integrations, provider transfer streams, and profile-level host-key verification with known_hosts content or pinned SHA-256 host-key fingerprints.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { createFtpProviderFactory, createTransferClient } from "@zero-transfer/sdk";
|
|
68
|
+
|
|
69
|
+
const client = createTransferClient({
|
|
70
|
+
providers: [createFtpProviderFactory()],
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const session = await client.connect({
|
|
74
|
+
provider: "ftp",
|
|
75
|
+
host: "ftp.example.com",
|
|
76
|
+
username: { env: "FTP_USERNAME" },
|
|
77
|
+
password: { env: "FTP_PASSWORD" },
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const releases = await session.fs.list("/releases");
|
|
81
|
+
const artifact = await session.fs.stat("/releases/app.zip");
|
|
82
|
+
await session.disconnect();
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Explicit FTPS can use the same provider-neutral session API with TLS settings on the connection profile:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { createFtpsProviderFactory, createTransferClient } from "@zero-transfer/sdk";
|
|
89
|
+
|
|
90
|
+
const client = createTransferClient({
|
|
91
|
+
providers: [createFtpsProviderFactory()],
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const session = await client.connect({
|
|
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
|
+
});
|
|
104
|
+
|
|
105
|
+
const releases = await session.fs.list("/releases");
|
|
106
|
+
await session.disconnect();
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
For deterministic contract and unit tests, the SDK exports a fixture-backed memory provider factory:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { createMemoryProviderFactory, createTransferClient } from "@zero-transfer/sdk";
|
|
113
|
+
|
|
114
|
+
const client = createTransferClient({
|
|
115
|
+
providers: [
|
|
116
|
+
createMemoryProviderFactory({
|
|
117
|
+
entries: [{ path: "/fixtures/report.csv", type: "file", size: 24 }],
|
|
118
|
+
}),
|
|
119
|
+
],
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const session = await client.connect({ provider: "memory", host: "memory.local" });
|
|
123
|
+
const entries = await session.fs.list("/fixtures");
|
|
124
|
+
const report = await session.fs.stat("/fixtures/report.csv");
|
|
125
|
+
await session.disconnect();
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The memory provider is intentionally test-focused: it supports connection lifecycle, capability discovery, `fs.list()`, `fs.stat()`, typed missing-path errors, and deterministic in-memory transfer reads/writes over fixture state.
|
|
129
|
+
|
|
130
|
+
The local provider exposes a configured local root as `/` for local-only tests and early provider contract coverage:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { createLocalProviderFactory, createTransferClient } from "@zero-transfer/sdk";
|
|
134
|
+
|
|
135
|
+
const client = createTransferClient({
|
|
136
|
+
providers: [createLocalProviderFactory({ rootPath: process.cwd() })],
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const session = await client.connect({ provider: "local", host: "local" });
|
|
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({
|
|
156
|
+
provider: "sftp",
|
|
157
|
+
host: "files.example.com",
|
|
158
|
+
username: { env: "ZT_USER" },
|
|
159
|
+
password: { env: "ZT_PASSWORD" },
|
|
160
|
+
ssh: {
|
|
161
|
+
knownHosts: { path: "./known_hosts" },
|
|
162
|
+
pinnedHostKeySha256: "SHA256:base64-encoded-host-key-digest",
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const resolved = await resolveConnectionProfileSecrets(profile);
|
|
167
|
+
const safeForLogs = redactConnectionProfile(profile);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Protocol adapters are intentionally being added incrementally. Early releases focus on the package foundation, deterministic tests, parser correctness, typed errors, logging, provider contracts, and transfer-service primitives while FTP is hardened, FTPS/SFTP support is ported in focused slices, and broader provider families are added.
|
|
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:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import { TransferEngine, type TransferJob } from "@zero-transfer/sdk";
|
|
176
|
+
|
|
177
|
+
const engine = new TransferEngine();
|
|
178
|
+
const job: TransferJob = {
|
|
179
|
+
id: "upload-1",
|
|
180
|
+
operation: "upload",
|
|
181
|
+
source: { provider: "local", path: "./dist/app.zip" },
|
|
182
|
+
destination: { provider: "memory", path: "/releases/app.zip" },
|
|
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
|
+
);
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Provider sessions that can stream content expose `session.transfers.read()` and `session.transfers.write()`. The memory, local, and initial FTP providers implement that surface now, and the SDK exports `createProviderTransferExecutor()` to bridge provider operations into `TransferEngine` without hard-coding a concrete FTP, SFTP, or cloud implementation:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { createProviderTransferExecutor } from "@zero-transfer/sdk";
|
|
207
|
+
|
|
208
|
+
const executor = createProviderTransferExecutor({
|
|
209
|
+
resolveSession: ({ endpoint }) => connectedSessions.get(endpoint.provider ?? ""),
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const receipt = await engine.execute(job, executor, {
|
|
213
|
+
retry: { maxAttempts: 2 },
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Dry-run transfer plans can be converted into executable jobs and drained through a minimal queue with concurrency, pause/resume, cancellation, progress, retries, receipts, and per-job failure tracking:
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
import { TransferQueue, createTransferJobsFromPlan, createTransferPlan } from "@zero-transfer/sdk";
|
|
221
|
+
|
|
222
|
+
const plan = createTransferPlan({
|
|
223
|
+
id: "release-plan",
|
|
224
|
+
steps: [
|
|
225
|
+
{
|
|
226
|
+
id: "upload-app",
|
|
227
|
+
action: "upload",
|
|
228
|
+
source: { provider: "local", path: "./dist/app.zip" },
|
|
229
|
+
destination: { provider: "memory", path: "/releases/app.zip" },
|
|
230
|
+
expectedBytes: 1024,
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const queue = new TransferQueue({
|
|
236
|
+
concurrency: 2,
|
|
237
|
+
executor: (context) => {
|
|
238
|
+
const bytesTransferred = context.job.totalBytes ?? 0;
|
|
239
|
+
context.reportProgress(bytesTransferred);
|
|
240
|
+
return { bytesTransferred, verified: true };
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
for (const plannedJob of createTransferJobsFromPlan(plan)) {
|
|
245
|
+
queue.add(plannedJob);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const summary = await queue.run();
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Development
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
npm install
|
|
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
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Use `npm run ci` to run the same local quality gate used by the CI workflow.
|
|
264
|
+
|
|
265
|
+
Docker-backed FTP integration coverage is opt-in because it pulls and runs a real `pure-ftpd`
|
|
266
|
+
container. With Docker running locally, use:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
npm run test:integration:ftp
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The script starts the FTP service from `test/servers/docker-compose.yml`, runs the provider
|
|
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.
|
|
282
|
+
|
|
283
|
+
## License
|
|
284
|
+
|
|
285
|
+
MIT License
|