scp-next 1.0.18 → 1.0.20

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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.19
4
+
5
+ - Refined README structure for clearer installation, quick start, basic usage, advanced usage,
6
+ library options, and configuration guidance.
7
+ - Improved password-first examples while keeping security warnings and safer authentication
8
+ recommendations visible.
9
+ - Clarified SSH agent usage, `SSH_AUTH_SOCK`, timeout behavior, and configuration-file
10
+ recommendations.
11
+ - Expanded GitHub Pages documentation with CLI, library, and configuration options.
12
+ - Moved release notes under `docs/release-notes/` for cleaner documentation organization.
13
+
3
14
  ## 1.0.14
4
15
 
5
16
  - Production-ready `scp-next` TypeScript CLI and library.
package/README.md CHANGED
@@ -19,14 +19,6 @@
19
19
  It uses SFTP internally through `ssh2-sftp-client` instead of implementing SCP or SFTP protocols manually.
20
20
  Developer documentation is available at [GitHub Pages](https://chengchuu.github.io/scp-next/).
21
21
 
22
- ## Contents
23
-
24
- - [Installation](#installation)
25
- - [Quick Start](#quick-start)
26
- - [Basic Usage](#basic-usage)
27
- - [Library Usage](#library-usage)
28
- - [Advanced Usage](#advanced-usage)
29
-
30
22
  ## Features
31
23
 
32
24
  - Upload and download files or directories recursively.
@@ -35,6 +27,19 @@ Developer documentation is available at [GitHub Pages](https://chengchuu.github.
35
27
  - JSON configuration files, named profiles, and configured jobs.
36
28
  - Reusable transfer client.
37
29
 
30
+ ## Contents
31
+
32
+ - [Installation](#installation)
33
+ - [Quick Start](#quick-start)
34
+ - [CLI Usage](#cli-usage)
35
+ - [CLI Options](#cli-options)
36
+ - [Library Usage](#library-usage)
37
+ - [Library Options](#library-options)
38
+ - [Advanced Usage](#advanced-usage)
39
+ - [Configuration File Options](#configuration-file-options)
40
+ - [Environment Variables](#environment-variables)
41
+ - [User Guides](#user-guides)
42
+
38
43
  ## Installation
39
44
 
40
45
  CLI:
@@ -77,7 +82,7 @@ Downloading: /var/log/example.log 1.0 MB / 1.0 MB (100%)
77
82
  ```
78
83
 
79
84
  Password arguments are convenient, but they may be exposed through shell history and process listings.
80
- Prefer `SCP_NEXT_PASSWORD`, SSH agents, or protected private-key files for shared or production environments.
85
+ Prefer `SCP_NEXT_PASSWORD` environment variable in shared or production environments. For key authentication, use a protected private-key file.
81
86
 
82
87
  Use the library:
83
88
 
@@ -95,7 +100,7 @@ await upload({
95
100
  });
96
101
  ```
97
102
 
98
- ## Basic Usage
103
+ ## CLI Usage
99
104
 
100
105
  ### CLI Syntax
101
106
 
@@ -186,7 +191,7 @@ scp-next run download-logs --config ./scp-next.config.json
186
191
  | `--host <host>` | SSH server host. |
187
192
  | `--port <port>` | SSH server port. Defaults to `22`. |
188
193
  | `--username <username>` | SSH username. |
189
- | `--password <password>` | SSH password. Prefer environment variables, SSH agents, or key files. |
194
+ | `--password <password>` | SSH password. |
190
195
  | `--private-key <privateKey>` | Private-key content. Redacted from logs and errors. |
191
196
  | `--private-key-file <privateKeyFile>` | Private-key file path. Supports `~` expansion. |
192
197
  | `--passphrase <passphrase>` | Passphrase for an encrypted private key. |
@@ -197,12 +202,14 @@ scp-next run download-logs --config ./scp-next.config.json
197
202
  | `--create-directories` | Create missing destination directories. Enabled by default. |
198
203
  | `--no-create-directories` | Disable automatic destination directory creation. |
199
204
  | `--dry-run` | Resolve and validate the operation without connecting or transferring. |
200
- | `--timeout <milliseconds>` | Connection and operation timeout in milliseconds. |
205
+ | `--timeout <milliseconds>` | SSH connection ready timeout in milliseconds. |
201
206
  | `--verbose` | Print non-sensitive diagnostic details. |
202
207
  | `--quiet` | Disable progress and non-error output. |
203
208
  | `--help` | Show command help. |
204
209
  | `--version` | Show the package version. |
205
210
 
211
+ `--timeout` maps to the SSH `readyTimeout`, so it controls how long to wait for the connection handshake. It does not currently limit per-file or total transfer duration.
212
+
206
213
  ## Library Usage
207
214
 
208
215
  ### ESM Upload
@@ -284,6 +291,29 @@ await upload({
284
291
  });
285
292
  ```
286
293
 
294
+ ### Library Options
295
+
296
+ | Field | Used by | Description |
297
+ | ------------------- | --------------- | ------------------------------------------------------------ |
298
+ | `host` | server | SSH server host. |
299
+ | `port` | server | SSH server port. Defaults to `22`. |
300
+ | `username` | server | SSH username. |
301
+ | `password` | server | SSH password. |
302
+ | `privateKey` | server | Private-key content as a string or Buffer. |
303
+ | `privateKeyFile` | server | Private-key file path. |
304
+ | `passphrase` | server | Passphrase for an encrypted private key. |
305
+ | `agent` | server | SSH agent socket path. |
306
+ | `hostFingerprint` | server | Expected server host-key SHA-256 fingerprint. |
307
+ | `knownHostsFile` | server | Known-hosts file for host verification. |
308
+ | `localPath` | upload/download | Local source for upload or local destination for download. |
309
+ | `remotePath` | upload/download | Remote destination for upload or remote source for download. |
310
+ | `recursive` | transfer | Transfer directories recursively. Defaults to `false`. |
311
+ | `overwrite` | transfer | Allow replacing existing files. |
312
+ | `createDirectories` | transfer | Create missing destination directories. Defaults to `true`. |
313
+ | `dryRun` | transfer | Validate and plan without modifying local or remote files. |
314
+ | `timeout` | server/transfer | SSH connection ready timeout in milliseconds. |
315
+ | `onProgress` | transfer | Progress callback for file and directory transfers. |
316
+
287
317
  ## Advanced Usage
288
318
 
289
319
  ### Configuration Files
@@ -329,15 +359,15 @@ Example:
329
359
 
330
360
  Do not commit configuration files containing real passwords. Prefer `SCP_NEXT_PASSWORD` or another protected secret source for shared repositories and deployment environments.
331
361
 
332
- Configuration file options:
362
+ ### Configuration File Options
333
363
 
334
- | Key | Description |
335
- | ---------------- | ------------------------------------------------------------------- |
336
- | `server` | SSH connection options such as `host`, `port`, and `username`. |
337
- | `transfer` | Transfer defaults such as `recursive`, `overwrite`, and `timeout`. |
338
- | `defaultProfile` | Profile name used when `--profile` or `SCP_NEXT_PROFILE` is absent. |
339
- | `profiles` | Named server connection profiles. |
340
- | `jobs` | Reusable upload or download jobs for `scp-next run <job>`. |
364
+ | Key | Description |
365
+ | ---------------- | -------------------------------------------------------------------- |
366
+ | `server` | SSH connection options such as `host`, `port`, and `username`. |
367
+ | `transfer` | Transfer defaults such as `recursive`, `overwrite`, and directories. |
368
+ | `defaultProfile` | Profile name used when `--profile` or `SCP_NEXT_PROFILE` is absent. |
369
+ | `profiles` | Named server connection profiles. |
370
+ | `jobs` | Reusable upload or download jobs for `scp-next run <job>`. |
341
371
 
342
372
  Root-level server options such as `host`, `username`, `privateKeyFile`, `knownHostsFile`,
343
373
  and `hostFingerprint` are also supported for simple configuration files, but `server` keeps connection values grouped and easier to read.
@@ -420,6 +450,7 @@ SCP_NEXT_PRIVATE_KEY_FILE
420
450
  SCP_NEXT_PASSPHRASE
421
451
  SCP_NEXT_TIMEOUT
422
452
  SCP_NEXT_PROFILE
453
+ SSH_AUTH_SOCK
423
454
  ```
424
455
 
425
456
  Bash:
@@ -464,6 +495,32 @@ Supported methods:
464
495
  - Private-key passphrase
465
496
  - SSH agent authentication through `agent` or `SSH_AUTH_SOCK`
466
497
 
498
+ SSH agent CLI example:
499
+
500
+ ```bash
501
+ ssh-add ~/.ssh/id_ed25519
502
+
503
+ export SCP_NEXT_HOST="your-host"
504
+ export SCP_NEXT_USERNAME="your-username"
505
+
506
+ scp-next upload ./dist /var/www/example --recursive
507
+ ```
508
+
509
+ Library example:
510
+
511
+ ```ts
512
+ import { upload } from "scp-next";
513
+
514
+ await upload({
515
+ host: process.env.SCP_NEXT_HOST,
516
+ username: process.env.SCP_NEXT_USERNAME,
517
+ agent: process.env.SSH_AUTH_SOCK,
518
+ localPath: "./dist",
519
+ remotePath: "/var/www/example",
520
+ recursive: true
521
+ });
522
+ ```
523
+
467
524
  ### Host Verification
468
525
 
469
526
  `hostFingerprint` compares the server host key SHA-256 fingerprint. `knownHostsFile` supports plain OpenSSH `known_hosts` entries for exact host names. When neither is supplied, `scp-next` reads `~/.ssh/known_hosts`. Hashed host names and every OpenSSH marker variant are not currently parsed.
@@ -534,6 +591,11 @@ copy(options: CopyOptions): Promise<void>
534
591
  Upload and download APIs use explicit `localPath` and `remotePath` names.
535
592
  The optional generic `copy()` API accepts typed local/remote endpoint objects.
536
593
 
594
+ ## User Guides
595
+
596
+ - [English](https://github.com/chengchuu/scp-next/blob/main/docs/release-notes/introducing-scp-next-v1.0.19-en.md)
597
+ - [简体中文](https://github.com/chengchuu/scp-next/blob/main/docs/release-notes/introducing-scp-next-v1.0.19-zh.md)
598
+
537
599
  ## Development
538
600
 
539
601
  ```bash
@@ -0,0 +1,183 @@
1
+ # Introducing scp-next v1.0.14
2
+
3
+ `scp-next` is an SCP-style CLI and TypeScript library for secure file transfers over SSH.
4
+ It keeps familiar `upload <source> <destination>` and `download <source> <destination>`
5
+ commands while using SFTP internally through `ssh2-sftp-client`.
6
+
7
+ Version 1.0.14 focuses on production polish: clearer documentation, safer daily defaults,
8
+ better path behavior, and a cleaner project footprint.
9
+
10
+ ## Highlights
11
+
12
+ - Upload and download files or directories recursively.
13
+ - Use the CLI with clear `<source> <destination>` operands.
14
+ - Use the library from ESM `import` or CommonJS `require`.
15
+ - Configure transfers with JSON files, named profiles, jobs, and environment variables.
16
+ - Reuse a transfer client across multiple operations.
17
+ - Create missing destination directories by default.
18
+ - Disable destination directory creation with `--no-create-directories`.
19
+ - Preview operations with `--dry-run`.
20
+ - Keep secrets redacted from logs and errors.
21
+
22
+ ## Install
23
+
24
+ CLI:
25
+
26
+ ```bash
27
+ npm install --global scp-next
28
+ ```
29
+
30
+ Library:
31
+
32
+ ```bash
33
+ npm install scp-next
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ Upload with password authentication:
39
+
40
+ ```bash
41
+ scp-next upload ./dist /var/www/example \
42
+ --host your-host \
43
+ --username your-username \
44
+ --password your-password \
45
+ --recursive
46
+ ```
47
+
48
+ Password arguments are convenient, but they may be exposed through shell history and process
49
+ listings. Prefer environment variables, SSH agents, or protected private-key files for shared
50
+ or production environments.
51
+
52
+ Download with password authentication:
53
+
54
+ ```bash
55
+ scp-next download /var/log/example.log ./logs/example.log \
56
+ --host your-host \
57
+ --username your-username \
58
+ --password your-password
59
+ ```
60
+
61
+ ## Library Usage
62
+
63
+ ESM upload:
64
+
65
+ ```ts
66
+ import { upload } from "scp-next";
67
+
68
+ await upload({
69
+ host: process.env.SCP_NEXT_HOST,
70
+ username: process.env.SCP_NEXT_USERNAME,
71
+ password: process.env.SCP_NEXT_PASSWORD,
72
+ localPath: "./dist",
73
+ remotePath: "/var/www/example",
74
+ recursive: true,
75
+ overwrite: true
76
+ });
77
+ ```
78
+
79
+ Reusable client:
80
+
81
+ ```ts
82
+ import { createClient } from "scp-next";
83
+
84
+ const client = createClient({
85
+ host: process.env.SCP_NEXT_HOST,
86
+ username: process.env.SCP_NEXT_USERNAME,
87
+ password: process.env.SCP_NEXT_PASSWORD
88
+ });
89
+
90
+ try {
91
+ await client.connect();
92
+ await client.upload("./dist", "/var/www/example", { recursive: true });
93
+ await client.download("/var/log/example.log", "./logs/example.log");
94
+ } finally {
95
+ await client.close();
96
+ }
97
+ ```
98
+
99
+ ## Configuration Files
100
+
101
+ The CLI searches for:
102
+
103
+ ```text
104
+ scp-next.config.json
105
+ .scp-nextrc
106
+ .scp-nextrc.json
107
+ ```
108
+
109
+ You can also pass an explicit path:
110
+
111
+ ```bash
112
+ scp-next upload ./dist /var/www/example \
113
+ --config ./scp-next.config.json \
114
+ --profile production
115
+ ```
116
+
117
+ Example:
118
+
119
+ ```json
120
+ {
121
+ "profiles": {
122
+ "production": {
123
+ "host": "your-host",
124
+ "username": "your-username",
125
+ "privateKeyFile": "~/.ssh/id_ed25519"
126
+ }
127
+ },
128
+ "jobs": {
129
+ "deploy": {
130
+ "operation": "upload",
131
+ "profile": "production",
132
+ "source": "./dist",
133
+ "destination": "/var/www/example",
134
+ "recursive": true,
135
+ "overwrite": true
136
+ }
137
+ }
138
+ }
139
+ ```
140
+
141
+ Run the configured job:
142
+
143
+ ```bash
144
+ scp-next run deploy
145
+ ```
146
+
147
+ ## What's New in v1.0.14
148
+
149
+ - Added GitHub Pages developer documentation.
150
+ - Expanded README sections for quick start, basic usage, library usage, and advanced usage.
151
+ - Added complete CLI, library, and configuration option references to the docs site.
152
+ - Improved SCP-style destination behavior for file and directory transfers.
153
+ - Made missing destination directory creation the default behavior.
154
+ - Added `--no-create-directories` as the explicit opt-out.
155
+ - Improved host verification guidance and typical-fix messaging.
156
+ - Improved Git Bash remote path restoration for Windows users.
157
+ - Reduced noisy duplicate progress output.
158
+ - Removed unused legacy tooling and Docker configuration files.
159
+
160
+ ## Security Notes
161
+
162
+ `scp-next` is designed for security-conscious transfer workflows:
163
+
164
+ - Normal transfers use SFTP and do not execute remote shell commands.
165
+ - Passwords, passphrases, private-key contents, and tokens are redacted from logs and errors.
166
+ - Host verification uses `hostFingerprint`, `knownHostsFile`, or `~/.ssh/known_hosts`.
167
+ - Local paths use OS-aware path behavior, while remote paths preserve POSIX `/` separators.
168
+ - Credentials are never persisted automatically.
169
+
170
+ ## Transfer Terminology
171
+
172
+ The CLI uses standard `<source> <destination>` order:
173
+
174
+ ```text
175
+ Operation Source Destination
176
+ Upload Local Remote
177
+ Download Remote Local
178
+ ```
179
+
180
+ The TypeScript API uses `localPath` and `remotePath` so application code stays explicit.
181
+
182
+ `scp-next` v1.0.14 is ready for command-line transfers, deployment scripts, and Node.js
183
+ applications that need SSH file transfer without custom protocol implementation.
@@ -0,0 +1,347 @@
1
+ # Introducing scp-next v1.0.19: An SSH File Transfer Tool for Node.js Developers
2
+
3
+ ![scp-next](http://blog.mazey.net/wp-content/uploads/2026/07/scp-next-SF-s7x3.jpg)
4
+
5
+ Learn how to install `scp-next` from npm, use the CLI for uploads and downloads, configure reusable jobs, handle credentials safely, call the library API, and onboard a new engineer quickly.
6
+
7
+ - [Introduction](#introduction)
8
+ - [Who Should Use It](#who-should-use-it)
9
+ - [Installation](#installation)
10
+ - [Understand Transfer Direction First](#understand-transfer-direction-first)
11
+ - [CLI Quick Start](#cli-quick-start)
12
+ - [Recommended Credential Patterns](#recommended-credential-patterns)
13
+ - [Common CLI Options](#common-cli-options)
14
+ - [Configuration Files](#configuration-files)
15
+ - [Library API Usage](#library-api-usage)
16
+ - [Host Verification](#host-verification)
17
+ - [New Engineer Checklist](#new-engineer-checklist)
18
+
19
+ ## Introduction
20
+
21
+ `scp-next` is an SCP-style npm package. It provides both a command-line tool and a library for secure file transfers over SSH. Although the package name includes SCP, normal transfers use SFTP internally through `ssh2-sftp-client`, so regular transfers do not execute remote shell commands.
22
+
23
+ ## Who Should Use It
24
+
25
+ Use `scp-next` when you need file transfers in deployment scripts, CI workflows, or Node.js applications. Common use cases include:
26
+
27
+ - Uploading local build output to a server.
28
+ - Downloading logs or generated artifacts from a server.
29
+ - Managing different server environments with configuration files.
30
+ - Reusing one transfer client across multiple operations in application code.
31
+
32
+ `scp-next` requires Node.js 18.18.0 or later.
33
+
34
+ ## Installation
35
+
36
+ Install it globally when you want to call the `scp-next` command directly.
37
+
38
+ ```bash
39
+ npm install --global scp-next
40
+ ```
41
+
42
+ Install it as a project dependency when you want to import the API from Node.js code.
43
+
44
+ ```bash
45
+ npm install scp-next
46
+ ```
47
+
48
+ If a project only needs the CLI in scripts, you can also install it locally and call it with `npx scp-next` or through npm scripts.
49
+
50
+ ## Understand Transfer Direction First
51
+
52
+ The CLI always uses two positional operands: `<source> <destination>`.
53
+
54
+ ```text
55
+ scp-next upload <source> <destination> [options]
56
+ scp-next download <source> <destination> [options]
57
+ scp-next run <job> [source] [destination] [options]
58
+ ```
59
+
60
+ The direction rules are:
61
+
62
+ | Operation | Source | Destination |
63
+ | --------- | ------ | ----------- |
64
+ | Upload | Local | Remote |
65
+ | Download | Remote | Local |
66
+
67
+ The programmatic API does not use `<source>` and `<destination>`. Upload and download options use `localPath` and `remotePath`, which keeps local and remote paths explicit in application code.
68
+
69
+ ## CLI Quick Start
70
+
71
+ Upload a local directory to a remote server.
72
+
73
+ ```bash
74
+ scp-next upload ./dist /var/www/example \
75
+ --host your-host \
76
+ --username your-username \
77
+ --password your-password \
78
+ --recursive
79
+ ```
80
+
81
+ Download a remote file to a local path.
82
+
83
+ ```bash
84
+ scp-next download /var/log/example.log ./logs/example.log \
85
+ --host your-host \
86
+ --username your-username \
87
+ --password your-password
88
+ ```
89
+
90
+ If the destination directory does not exist, `scp-next` creates it by default. This matches familiar `cp` and `scp` behavior for day-to-day use. Use `--no-create-directories` to disable automatic destination directory creation.
91
+
92
+ Preview an upload plan without connecting to the server.
93
+
94
+ ```bash
95
+ scp-next upload ./dist /var/www/example \
96
+ --host your-host \
97
+ --username your-username \
98
+ --password your-password \
99
+ --recursive \
100
+ --dry-run
101
+ ```
102
+
103
+ `--dry-run` resolves configuration and validates local paths. It does not connect to the remote server, and it does not modify local or remote files.
104
+
105
+ ## Recommended Credential Patterns
106
+
107
+ Password arguments are convenient for local trials.
108
+
109
+ ```bash
110
+ scp-next upload ./dist /var/www/example \
111
+ --host your-host \
112
+ --username your-username \
113
+ --password your-password \
114
+ --recursive
115
+ ```
116
+
117
+ For shared or production environments, prefer environment variables. This lowers the risk of exposing passwords through shell history or process listings.
118
+
119
+ ```bash
120
+ export SCP_NEXT_HOST="your-host"
121
+ export SCP_NEXT_USERNAME="your-username"
122
+ export SCP_NEXT_PASSWORD="your-password"
123
+
124
+ scp-next upload ./dist /var/www/example --recursive
125
+ ```
126
+
127
+ You can also use a protected private-key file.
128
+
129
+ ```bash
130
+ scp-next upload ./dist /var/www/example \
131
+ --host your-host \
132
+ --username your-username \
133
+ --private-key-file ~/.ssh/id_ed25519 \
134
+ --recursive
135
+ ```
136
+
137
+ If your environment already uses SSH agent authentication, add the key first and let `scp-next` use `SSH_AUTH_SOCK`.
138
+
139
+ ```bash
140
+ ssh-add ~/.ssh/id_ed25519
141
+
142
+ export SCP_NEXT_HOST="your-host"
143
+ export SCP_NEXT_USERNAME="your-username"
144
+
145
+ scp-next upload ./dist /var/www/example --recursive
146
+ ```
147
+
148
+ ## Common CLI Options
149
+
150
+ | Option | Description |
151
+ | ------------------------------------- | ---------------------------------------------------------------------- |
152
+ | `--host <host>` | SSH server host. |
153
+ | `--port <port>` | SSH server port. Defaults to `22`. |
154
+ | `--username <username>` | SSH username. |
155
+ | `--password <password>` | SSH password. |
156
+ | `--private-key-file <privateKeyFile>` | Private-key file path. Supports `~` expansion. |
157
+ | `--passphrase <passphrase>` | Passphrase for an encrypted private key. |
158
+ | `--config <path>` | Explicit configuration file path. |
159
+ | `--profile <name>` | Named server profile from the configuration file. |
160
+ | `--recursive` | Transfer directories recursively. Defaults to `false`. |
161
+ | `--overwrite` | Allow replacing existing destination files. |
162
+ | `--create-directories` | Create missing destination directories. Enabled by default. |
163
+ | `--no-create-directories` | Disable automatic destination directory creation. |
164
+ | `--dry-run` | Resolve and validate the operation without connecting or transferring. |
165
+ | `--timeout <milliseconds>` | SSH connection ready timeout in milliseconds. |
166
+ | `--quiet` | Disable progress and non-error output. |
167
+ | `--verbose` | Print non-sensitive diagnostic details. |
168
+
169
+ `--timeout` maps to the SSH `readyTimeout`. It controls how long to wait for the connection handshake, not the duration of each file transfer or the whole transfer run.
170
+
171
+ ## Configuration Files
172
+
173
+ The CLI automatically searches for these configuration files.
174
+
175
+ ```text
176
+ scp-next.config.json
177
+ .scp-nextrc
178
+ .scp-nextrc.json
179
+ ```
180
+
181
+ You can also pass an explicit path.
182
+
183
+ ```bash
184
+ scp-next upload ./dist /var/www/example \
185
+ --config ./scp-next.config.json \
186
+ --profile production
187
+ ```
188
+
189
+ The example below defines a server profile and two reusable jobs.
190
+
191
+ ```json
192
+ {
193
+ "profiles": {
194
+ "production": {
195
+ "host": "your-host",
196
+ "username": "your-username",
197
+ "privateKeyFile": "~/.ssh/id_ed25519"
198
+ }
199
+ },
200
+ "jobs": {
201
+ "deploy": {
202
+ "operation": "upload",
203
+ "profile": "production",
204
+ "source": "./dist",
205
+ "destination": "/var/www/example",
206
+ "recursive": true,
207
+ "overwrite": true
208
+ },
209
+ "download-logs": {
210
+ "operation": "download",
211
+ "profile": "production",
212
+ "source": "/var/log/example",
213
+ "destination": "./logs",
214
+ "recursive": true
215
+ }
216
+ }
217
+ }
218
+ ```
219
+
220
+ Run the configured upload job.
221
+
222
+ ```bash
223
+ scp-next run deploy
224
+ ```
225
+
226
+ Run the configured download job.
227
+
228
+ ```bash
229
+ scp-next run download-logs
230
+ ```
231
+
232
+ The `run` command also supports temporary path overrides.
233
+
234
+ ```bash
235
+ scp-next run deploy ./dist-canary /var/www/canary
236
+ ```
237
+
238
+ Configuration precedence, from highest to lowest, is:
239
+
240
+ 1. Explicit CLI options
241
+ 2. Positional CLI operands
242
+ 3. Environment variables
243
+ 4. Selected configuration profile
244
+ 5. Root-level configuration values
245
+ 6. Configured job values
246
+ 7. Internal defaults
247
+
248
+ Do not commit configuration files that contain real passwords to public repositories. For shared repositories and deployment environments, prefer `SCP_NEXT_PASSWORD`, SSH agent authentication, or protected key files.
249
+
250
+ ## Library API Usage
251
+
252
+ ESM projects can import `upload` directly.
253
+
254
+ ```ts
255
+ import { upload } from "scp-next";
256
+
257
+ await upload({
258
+ host: process.env.SCP_NEXT_HOST,
259
+ username: process.env.SCP_NEXT_USERNAME,
260
+ password: process.env.SCP_NEXT_PASSWORD,
261
+ localPath: "./dist",
262
+ remotePath: "/var/www/example",
263
+ recursive: true,
264
+ overwrite: true
265
+ });
266
+ ```
267
+
268
+ CommonJS projects can use `require`.
269
+
270
+ ```js
271
+ const { download } = require("scp-next");
272
+
273
+ async function main() {
274
+ await download({
275
+ host: process.env.SCP_NEXT_HOST,
276
+ username: process.env.SCP_NEXT_USERNAME,
277
+ password: process.env.SCP_NEXT_PASSWORD,
278
+ remotePath: "/var/log/example.log",
279
+ localPath: "./logs/example.log"
280
+ });
281
+ }
282
+
283
+ main().catch((error) => {
284
+ console.error(error.message);
285
+ process.exitCode = 1;
286
+ });
287
+ ```
288
+
289
+ Create a reusable client when you need multiple operations in one connection lifecycle.
290
+
291
+ ```ts
292
+ import { createClient } from "scp-next";
293
+
294
+ const client = createClient({
295
+ host: process.env.SCP_NEXT_HOST,
296
+ username: process.env.SCP_NEXT_USERNAME,
297
+ password: process.env.SCP_NEXT_PASSWORD
298
+ });
299
+
300
+ try {
301
+ await client.connect();
302
+ await client.upload("./dist", "/var/www/example", { recursive: true });
303
+ await client.download("/var/log/example.log", "./logs/example.log");
304
+ } finally {
305
+ await client.close();
306
+ }
307
+ ```
308
+
309
+ Primary exports include:
310
+
311
+ ```ts
312
+ upload(options: UploadOptions): Promise<void>;
313
+ download(options: DownloadOptions): Promise<void>;
314
+ createClient(options: ScpServerOptions): ScpNextClient;
315
+ copy(options: CopyOptions): Promise<void>;
316
+ ```
317
+
318
+ Public errors include stable `code` values, readable `message` values, and redacted non-sensitive context. Common error types include `ConfigurationError`, `AuthenticationError`, `ConnectionError`, `TransferError`, and `HostVerificationError`.
319
+
320
+ ## Host Verification
321
+
322
+ `scp-next` supports host verification with `hostFingerprint` or `knownHostsFile`. When neither is supplied, it reads `~/.ssh/known_hosts`.
323
+
324
+ For CI or deployment environments without an available known-hosts file, configure `hostFingerprint`. If `scp-next` cannot establish host verification, it fails closed.
325
+
326
+ ## New Engineer Checklist
327
+
328
+ Use this order when onboarding a project that already uses `scp-next`.
329
+
330
+ 1. Confirm that Node.js is 18.18.0 or later.
331
+ 2. Install the CLI with `npm install --global scp-next`.
332
+ 3. Run `scp-next upload ... --dry-run` to validate options and paths.
333
+ 4. Move server details into environment variables or a configuration file.
334
+ 5. Use `scp-next run <job>` for recurring upload or download workflows.
335
+ 6. Use `upload`, `download`, or `createClient` from Node.js code when the project needs library integration.
336
+
337
+ After these pieces are clear, `scp-next` is ready for deployment scripts, log downloads, and Node.js file transfer workflows.
338
+
339
+ **Copyright Notice**
340
+
341
+ This is an original article. The author reserves all rights. Please keep the full content when reposting, and include a hyperlink to the author.
342
+
343
+ Author: [Cheng](https://github.com/chengchuu)
344
+
345
+ <!-- ID: introducing-scp-next-v1.0.19-en -->
346
+
347
+ (End)
@@ -0,0 +1,324 @@
1
+ # scp-next v1.0.19 项目介绍: 面向 Node.js 开发者的 SSH 文件传输工具
2
+
3
+ ![scp-next](http://blog.mazey.net/wp-content/uploads/2026/07/scp-next-SF-s7x3.jpg)
4
+
5
+ 介绍 scp-next v1.0.19 的 npm 安装、CLI 上传下载、配置文件、凭据安全、库 API 和新人使用流程。
6
+
7
+ - [前言](#前言)
8
+ - [适合谁使用](#适合谁使用)
9
+ - [安装方式](#安装方式)
10
+ - [先理解传输方向](#先理解传输方向)
11
+ - [命令行快速开始](#命令行快速开始)
12
+ - [推荐的凭据写法](#推荐的凭据写法)
13
+ - [常用命令选项](#常用命令选项)
14
+ - [配置文件用法](#配置文件用法)
15
+ - [库 API 用法](#库-api-用法)
16
+ - [主机验证](#主机验证)
17
+ - [新人接手清单](#新人接手清单)
18
+
19
+ ## 前言
20
+
21
+ `scp-next` 是一个 SCP 风格的 npm 包。他同时提供命令行工具和库,用于通过 SSH 安全传输文件。虽然包名包含 SCP,实际使用 SFTP,不会为普通传输执行远程 Shell 命令。
22
+
23
+ ## 适合谁使用
24
+
25
+ 如果你需要在部署脚本、CI 流程或 Node.js 应用中传输文件,`scp-next` 可以减少重复封装。常见场景如下:
26
+
27
+ - 将本地构建产物上传到服务器。
28
+ - 从服务器下载日志或产物。
29
+ - 用配置文件管理不同服务器环境。
30
+ - 在应用代码中复用同一个传输客户端。
31
+
32
+ ## 安装方式
33
+
34
+ 全局安装后,可以直接使用 `scp-next` 命令。
35
+
36
+ ```bash
37
+ npm install --global scp-next
38
+ ```
39
+
40
+ 作为项目依赖安装后,可以在 Node.js 代码中导入 API。
41
+
42
+ ```bash
43
+ npm install scp-next
44
+ ```
45
+
46
+ 如果一个项目只在脚本里调用命令行工具,也可以把他安装到项目依赖中,再通过 `npx scp-next` 或 npm scripts 调用。
47
+
48
+ ## 先理解传输方向
49
+
50
+ 命令行统一使用 `<source> <destination>` 两个位置参数。
51
+
52
+ ```plain
53
+ scp-next upload <source> <destination> [options]
54
+ scp-next download <source> <destination> [options]
55
+ scp-next run <job> [source] [destination] [options]
56
+ ```
57
+
58
+ 方向规则如下:
59
+
60
+ | Operation | Source | Destination |
61
+ | --------- | ------ | ----------- |
62
+ | Upload | Local | Remote |
63
+ | Download | Remote | Local |
64
+
65
+ ## 命令行快速开始
66
+
67
+ 上传本地目录到远程服务器。
68
+
69
+ ```bash
70
+ scp-next upload ./dist /var/www/example \
71
+ --host your-host \
72
+ --username your-username \
73
+ --password your-password \
74
+ --recursive
75
+ ```
76
+
77
+ 下载远程文件到本地目录。如果目标目录不存在,`scp-next` 默认会创建目录。这符合日常 `cp` 和 `scp` 风格的使用习惯。可以用 `--no-create-directories` 关闭该行为。
78
+
79
+ ```bash
80
+ scp-next download /var/log/example.log ./logs/example.log \
81
+ --host your-host \
82
+ --username your-username \
83
+ --password your-password
84
+ ```
85
+
86
+ 先预览上传计划,而不连接服务器。`--dry-run` 会解析配置并检查本地路径。他不会连接远程服务器,也不会修改本地或远程文件。
87
+
88
+ ```bash
89
+ scp-next upload ./dist /var/www/example \
90
+ --host your-host \
91
+ --username your-username \
92
+ --password your-password \
93
+ --recursive \
94
+ --dry-run
95
+ ```
96
+
97
+ ## 推荐的凭据写法
98
+
99
+ 命令行密码参数适合本地快速试用。
100
+
101
+ ```bash
102
+ scp-next upload ./dist /var/www/example \
103
+ --host your-host \
104
+ --username your-username \
105
+ --password your-password \
106
+ --recursive
107
+ ```
108
+
109
+ 共享环境和生产环境建议使用环境变量。这样可以降低密码进入 Shell 历史记录或进程列表的风险。
110
+
111
+ ```bash
112
+ export SCP_NEXT_HOST="your-host"
113
+ export SCP_NEXT_USERNAME="your-username"
114
+ export SCP_NEXT_PASSWORD="your-password"
115
+
116
+ scp-next upload ./dist /var/www/example --recursive
117
+ ```
118
+
119
+ 也可以使用受保护的私钥文件。
120
+
121
+ ```bash
122
+ scp-next upload ./dist /var/www/example \
123
+ --host your-host \
124
+ --username your-username \
125
+ --private-key-file ~/.ssh/id_ed25519 \
126
+ --recursive
127
+ ```
128
+
129
+ ## 常用命令选项
130
+
131
+ | 选项 | 作用 |
132
+ | ------------------------------------- | ------------------------------- |
133
+ | `--host <host>` | SSH 服务器地址。 |
134
+ | `--port <port>` | SSH 服务器端口,默认值为 `22`。 |
135
+ | `--username <username>` | SSH 用户名。 |
136
+ | `--password <password>` | SSH 密码。 |
137
+ | `--private-key-file <privateKeyFile>` | 私钥文件路径,支持 `~`。 |
138
+ | `--passphrase <passphrase>` | 加密私钥的口令。 |
139
+ | `--config <path>` | 指定配置文件路径。 |
140
+ | `--profile <name>` | 选择配置文件中的服务器配置。 |
141
+ | `--recursive` | 递归传输目录,默认关闭。 |
142
+ | `--overwrite` | 允许覆盖已有目标文件。 |
143
+ | `--create-directories` | 创建缺失的目标目录,默认开启。 |
144
+ | `--no-create-directories` | 关闭目标目录自动创建。 |
145
+ | `--dry-run` | 只解析和验证,不执行传输。 |
146
+ | `--timeout <milliseconds>` | SSH 握手超时时间,单位为毫秒。 |
147
+ | `--quiet` | 关闭进度和非错误输出。 |
148
+ | `--verbose` | 输出不含敏感信息的诊断内容。 |
149
+
150
+ ## 配置文件用法
151
+
152
+ CLI 会自动查找以下配置文件。
153
+
154
+ ```plain
155
+ scp-next.config.json
156
+ .scp-nextrc
157
+ .scp-nextrc.json
158
+ ```
159
+
160
+ 也可以显式指定路径。
161
+
162
+ ```bash
163
+ scp-next upload ./dist /var/www/example \
164
+ --config ./scp-next.config.json \
165
+ --profile production
166
+ ```
167
+
168
+ 下面是一个包含服务器配置和任务的示例。
169
+
170
+ ```json
171
+ {
172
+ "profiles": {
173
+ "production": {
174
+ "host": "your-host",
175
+ "username": "your-username",
176
+ "privateKeyFile": "~/.ssh/id_ed25519"
177
+ }
178
+ },
179
+ "jobs": {
180
+ "deploy": {
181
+ "operation": "upload",
182
+ "profile": "production",
183
+ "source": "./dist",
184
+ "destination": "/var/www/example",
185
+ "recursive": true,
186
+ "overwrite": true
187
+ },
188
+ "download-logs": {
189
+ "operation": "download",
190
+ "profile": "production",
191
+ "source": "/var/log/example",
192
+ "destination": "./logs",
193
+ "recursive": true
194
+ }
195
+ }
196
+ }
197
+ ```
198
+
199
+ 运行配置好的上传任务。
200
+
201
+ ```bash
202
+ scp-next run deploy
203
+ ```
204
+
205
+ 运行配置好的下载任务。
206
+
207
+ ```bash
208
+ scp-next run download-logs
209
+ ```
210
+
211
+ `run` 命令也支持临时覆盖路径。
212
+
213
+ ```bash
214
+ scp-next run deploy ./dist-canary /var/www/canary
215
+ ```
216
+
217
+ 配置优先级从高到低如下。
218
+
219
+ 1. 显式 CLI 选项
220
+ 2. 位置参数
221
+ 3. 环境变量
222
+ 4. 选中的配置 profile
223
+ 5. 根级配置值
224
+ 6. 配置的 job 值
225
+ 7. 内部默认值
226
+
227
+ 不要把包含真实密码的配置文件提交到 Public 仓库。共享仓库和部署环境应优先使用 `SCP_NEXT_PASSWORD` 或受保护的密钥文件。
228
+
229
+ ## 库 API 用法
230
+
231
+ ESM 项目可以直接导入 `upload`。
232
+
233
+ ```ts
234
+ import { upload } from "scp-next";
235
+
236
+ await upload({
237
+ host: process.env.SCP_NEXT_HOST,
238
+ username: process.env.SCP_NEXT_USERNAME,
239
+ password: process.env.SCP_NEXT_PASSWORD,
240
+ localPath: "./dist",
241
+ remotePath: "/var/www/example",
242
+ recursive: true,
243
+ overwrite: true
244
+ });
245
+ ```
246
+
247
+ CommonJS 项目可以使用 `require`。
248
+
249
+ ```js
250
+ const { download } = require("scp-next");
251
+
252
+ async function main() {
253
+ await download({
254
+ host: process.env.SCP_NEXT_HOST,
255
+ username: process.env.SCP_NEXT_USERNAME,
256
+ password: process.env.SCP_NEXT_PASSWORD,
257
+ remotePath: "/var/log/example.log",
258
+ localPath: "./logs/example.log"
259
+ });
260
+ }
261
+
262
+ main().catch((error) => {
263
+ console.error(error.message);
264
+ process.exitCode = 1;
265
+ });
266
+ ```
267
+
268
+ 如果一次连接内要执行多个操作,可以创建可复用客户端。
269
+
270
+ ```ts
271
+ import { createClient } from "scp-next";
272
+
273
+ const client = createClient({
274
+ host: process.env.SCP_NEXT_HOST,
275
+ username: process.env.SCP_NEXT_USERNAME,
276
+ password: process.env.SCP_NEXT_PASSWORD
277
+ });
278
+
279
+ try {
280
+ await client.connect();
281
+ await client.upload("./dist", "/var/www/example", { recursive: true });
282
+ await client.download("/var/log/example.log", "./logs/example.log");
283
+ } finally {
284
+ await client.close();
285
+ }
286
+ ```
287
+
288
+ 主要导出如下。
289
+
290
+ ```ts
291
+ upload(options);
292
+ download(options);
293
+ createClient(options);
294
+ copy(options);
295
+ ```
296
+
297
+ 错误类型包含稳定的 `code`、可读的 `message` 和经过脱敏的上下文。常见错误包括 `ConfigurationError`、`AuthenticationError`、`ConnectionError`、`TransferError` 和 `HostVerificationError`。
298
+
299
+ ## 主机验证
300
+
301
+ `scp-next` 支持通过 `hostFingerprint` 或 `knownHostsFile` 验证主机。如果没有显式配置,他会读取 `~/.ssh/known_hosts`。
302
+
303
+ 在 CI 或部署环境中,如果没有可用的 known-hosts 文件,建议配置 `hostFingerprint`。如果无法建立主机验证,`scp-next` 会失败退出。
304
+
305
+ ## 新人接手清单
306
+
307
+ 接手项目时,可以按以下顺序验证。
308
+
309
+ 1. 确认 Node.js 版本不低于 18.18.0。
310
+ 2. 使用 `npm install --global scp-next` 安装 CLI。
311
+ 3. 用 `scp-next upload ... --dry-run` 验证参数和路径。
312
+
313
+ 掌握这几项后,就可以把 `scp-next` 用于日常部署脚本、日志下载任务和 Node.js 文件传输流程。
314
+
315
+ **版权声明**
316
+
317
+ 本文为原创文章,作者保留版权。转载请保留本文完整内容,并以超链接形式注明作者及原文出处。
318
+
319
+ 作者: [除除](https://github.com/chengchuu)
320
+ 原文: <https://blog.mazey.net/6454.html>
321
+
322
+ <!-- ID: introducing-scp-next-v1.0.19-zh -->
323
+
324
+ (完)
@@ -0,0 +1,186 @@
1
+ # Introducing scp-next v1.0.2
2
+
3
+ `scp-next` is an SCP-style command-line tool and TypeScript library for secure file transfers
4
+ over SSH. It keeps the familiar upload/download workflow while using SFTP internally through
5
+ `ssh2-sftp-client`, avoiding custom protocol code and normal remote shell execution.
6
+
7
+ ## Why scp-next
8
+
9
+ File transfer tools often start simple and become harder to manage once deployments need
10
+ profiles, dry runs, recursive directories, secret handling, and reusable application code.
11
+ `scp-next` is built for that middle ground: easy to run from a terminal, but structured enough
12
+ to use safely in scripts, CI, and Node.js applications.
13
+
14
+ ## Highlights
15
+
16
+ - Upload and download files or directories recursively.
17
+ - Use clear CLI operands: `<source> <destination>`.
18
+ - Import the library from ESM or CommonJS projects.
19
+ - Configure servers with JSON files, named profiles, jobs, or environment variables.
20
+ - Preview operations with dry-run mode before connecting.
21
+ - Track transfer progress when supported by the SFTP client.
22
+ - Control overwrites, timeouts, and destination directory creation.
23
+ - Redact passwords, passphrases, and private-key contents from logs and errors.
24
+ - Reuse a transfer client across multiple upload and download operations.
25
+
26
+ ## Install
27
+
28
+ Global CLI installation:
29
+
30
+ ```bash
31
+ npm install --global scp-next
32
+ ```
33
+
34
+ Library installation:
35
+
36
+ ```bash
37
+ npm install scp-next
38
+ ```
39
+
40
+ ## CLI Usage
41
+
42
+ Uploads treat `source` as local and `destination` as remote:
43
+
44
+ ```bash
45
+ scp-next upload ./dist /var/www/example \
46
+ --host example.com \
47
+ --username deploy \
48
+ --private-key-file ~/.ssh/id_ed25519 \
49
+ --recursive \
50
+ --create-directories
51
+ ```
52
+
53
+ Downloads treat `source` as remote and `destination` as local:
54
+
55
+ ```bash
56
+ scp-next download /var/log/example.log ./logs/example.log \
57
+ --host example.com \
58
+ --username deploy \
59
+ --private-key-file ~/.ssh/id_ed25519 \
60
+ --create-directories
61
+ ```
62
+
63
+ Run a configured job:
64
+
65
+ ```bash
66
+ scp-next run deploy
67
+ ```
68
+
69
+ ## Library Usage
70
+
71
+ ESM:
72
+
73
+ ```ts
74
+ import { upload } from "scp-next";
75
+
76
+ await upload({
77
+ host: process.env.SCP_NEXT_HOST,
78
+ username: process.env.SCP_NEXT_USERNAME,
79
+ privateKeyFile: process.env.SCP_NEXT_PRIVATE_KEY_FILE,
80
+ localPath: "./dist",
81
+ remotePath: "/var/www/example",
82
+ recursive: true,
83
+ overwrite: true
84
+ });
85
+ ```
86
+
87
+ CommonJS:
88
+
89
+ ```js
90
+ const { download } = require("scp-next");
91
+
92
+ await download({
93
+ host: process.env.SCP_NEXT_HOST,
94
+ username: process.env.SCP_NEXT_USERNAME,
95
+ privateKeyFile: process.env.SCP_NEXT_PRIVATE_KEY_FILE,
96
+ remotePath: "/var/log/example.log",
97
+ localPath: "./logs/example.log"
98
+ });
99
+ ```
100
+
101
+ Reusable client:
102
+
103
+ ```ts
104
+ import { createClient } from "scp-next";
105
+
106
+ const client = createClient({
107
+ host: process.env.SCP_NEXT_HOST,
108
+ username: process.env.SCP_NEXT_USERNAME,
109
+ privateKeyFile: process.env.SCP_NEXT_PRIVATE_KEY_FILE
110
+ });
111
+
112
+ try {
113
+ await client.connect();
114
+ await client.upload("./dist", "/var/www/example", { recursive: true });
115
+ await client.download("/var/log/example.log", "./logs/example.log");
116
+ } finally {
117
+ await client.close();
118
+ }
119
+ ```
120
+
121
+ ## Configuration
122
+
123
+ `scp-next` supports `scp-next.config.json`, `.scp-nextrc`, `.scp-nextrc.json`, or an explicit
124
+ `--config` path.
125
+
126
+ ```json
127
+ {
128
+ "profiles": {
129
+ "production": {
130
+ "host": "production.example.com",
131
+ "username": "deploy",
132
+ "privateKeyFile": "~/.ssh/id_ed25519"
133
+ }
134
+ },
135
+ "jobs": {
136
+ "deploy": {
137
+ "operation": "upload",
138
+ "profile": "production",
139
+ "source": "./dist",
140
+ "destination": "/var/www/example",
141
+ "recursive": true,
142
+ "overwrite": true,
143
+ "createDirectories": true
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ ## Security Notes
150
+
151
+ `scp-next` is designed to make safer defaults and patterns easy:
152
+
153
+ - Prefer environment variables, SSH agents, or protected private-key files over CLI password
154
+ arguments.
155
+ - Passwords, passphrases, and private-key contents are redacted from logs and error context.
156
+ - Host verification uses `hostFingerprint`, `knownHostsFile`, or `~/.ssh/known_hosts`.
157
+ - Remote paths are handled with POSIX rules, while local paths use the current operating
158
+ system's path behavior.
159
+ - Normal transfers use SFTP and do not execute remote shell commands.
160
+
161
+ ## Transfer Terminology
162
+
163
+ The CLI uses the standard `<source> <destination>` order:
164
+
165
+ ```text
166
+ Operation Source Destination
167
+ Upload Local Remote
168
+ Download Remote Local
169
+ ```
170
+
171
+ The TypeScript API uses explicit `localPath` and `remotePath` names for upload and download
172
+ calls, so application code does not need to infer path locality from transfer direction.
173
+
174
+ ## What's Included in v1.0.2
175
+
176
+ - CLI commands for upload, download, and configured jobs.
177
+ - ESM, CommonJS, and TypeScript declaration outputs.
178
+ - Recursive directory transfers.
179
+ - Dry-run support.
180
+ - Configuration files, profiles, jobs, and environment variables.
181
+ - Typed errors and validation for common configuration, filesystem, connection, and transfer
182
+ failures.
183
+ - Mockable transport architecture for tests and future integration coverage.
184
+
185
+ `scp-next` v1.0.2 is ready for CLI workflows, deployment scripts, and Node.js applications that
186
+ need secure SSH file transfers without hand-rolled protocol logic.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scp-next",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "A SCP CLI and library for secure SSH file transfers using SFTP.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",