@simplysm/storage 13.0.71 → 13.0.74

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.
Files changed (2) hide show
  1. package/README.md +246 -15
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -2,33 +2,264 @@
2
2
 
3
3
  Simplysm Package - Storage Module (node)
4
4
 
5
+ Provides FTP, FTPS, and SFTP storage clients with a unified interface, plus a factory for connection management.
6
+
5
7
  ## Installation
6
8
 
9
+ ```bash
7
10
  pnpm add @simplysm/storage
11
+ ```
8
12
 
9
- ## Source Index
13
+ ## Main Modules
10
14
 
11
15
  ### Types
12
16
 
13
- | Source | Exports | Description | Test |
14
- |--------|---------|-------------|------|
15
- | `src/types/storage-conn-config.ts` | `StorageConnConfig` | Connection config interface (host, port, user, pass) | - |
16
- | `src/types/storage.ts` | `FileInfo`, `Storage` | Storage interface and file entry type | - |
17
- | `src/types/storage-type.ts` | `StorageType` | Union type for supported protocols: ftp, ftps, sftp | - |
17
+ #### `StorageConnConfig`
18
+
19
+ Connection configuration shared by all storage clients.
20
+
21
+ ```ts
22
+ import { StorageConnConfig } from "@simplysm/storage";
23
+
24
+ const config: StorageConnConfig = {
25
+ host: "storage.example.com",
26
+ port: 22, // optional — defaults to the protocol default
27
+ user: "admin", // optional
28
+ pass: "secret", // optional
29
+ };
30
+ ```
31
+
32
+ | Property | Type | Required | Description |
33
+ | -------- | -------- | -------- | ---------------------------------------- |
34
+ | `host` | `string` | yes | Hostname or IP address of the server |
35
+ | `port` | `number` | no | Port number (defaults to protocol default) |
36
+ | `user` | `string` | no | Username for authentication |
37
+ | `pass` | `string` | no | Password for authentication |
38
+
39
+ ---
40
+
41
+ #### `FileInfo`
42
+
43
+ Describes a single entry returned by `readdir`.
44
+
45
+ ```ts
46
+ import { FileInfo } from "@simplysm/storage";
47
+
48
+ // Example entry
49
+ const entry: FileInfo = { name: "report.pdf", isFile: true };
50
+ ```
51
+
52
+ | Property | Type | Description |
53
+ | -------- | --------- | -------------------------------------------- |
54
+ | `name` | `string` | File or directory name (not the full path) |
55
+ | `isFile` | `boolean` | `true` if it is a file, `false` if directory |
56
+
57
+ ---
58
+
59
+ #### `Storage`
60
+
61
+ The unified storage interface implemented by all client classes. Use this type when writing code that is protocol-agnostic.
62
+
63
+ ```ts
64
+ import { Storage } from "@simplysm/storage";
65
+
66
+ async function uploadFile(storage: Storage, localPath: string, remotePath: string) {
67
+ await storage.put(localPath, remotePath);
68
+ }
69
+ ```
70
+
71
+ | Method | Returns | Description |
72
+ | ------------------------------------------------------------- | --------------------- | ------------------------------------------------------------- |
73
+ | `connect(config: StorageConnConfig)` | `Promise<void>` | Open a connection to the server |
74
+ | `mkdir(dirPath: string)` | `Promise<void>` | Create a directory (including parents) |
75
+ | `rename(fromPath: string, toPath: string)` | `Promise<void>` | Rename or move a remote path |
76
+ | `readdir(dirPath: string)` | `Promise<FileInfo[]>` | List entries in a directory |
77
+ | `readFile(filePath: string)` | `Promise<Bytes>` | Download a file as raw bytes |
78
+ | `exists(filePath: string)` | `Promise<boolean>` | Check whether a path exists |
79
+ | `put(localPathOrBuffer: string \| Bytes, storageFilePath: string)` | `Promise<void>` | Upload a local file path or byte buffer to the remote path |
80
+ | `uploadDir(fromPath: string, toPath: string)` | `Promise<void>` | Upload an entire local directory to a remote path |
81
+ | `remove(filePath: string)` | `Promise<void>` | Delete a remote file |
82
+ | `close()` | `Promise<void>` | Close the connection |
83
+
84
+ ---
85
+
86
+ #### `StorageType`
87
+
88
+ Union type that identifies the storage protocol.
89
+
90
+ ```ts
91
+ import { StorageType } from "@simplysm/storage";
92
+
93
+ const type: StorageType = "sftp"; // "ftp" | "ftps" | "sftp"
94
+ ```
95
+
96
+ | Value | Protocol |
97
+ | -------- | ------------------------------- |
98
+ | `"ftp"` | Plain FTP |
99
+ | `"ftps"` | FTP with TLS/SSL (explicit) |
100
+ | `"sftp"` | SSH File Transfer Protocol |
101
+
102
+ ---
18
103
 
19
104
  ### Clients
20
105
 
21
- | Source | Exports | Description | Test |
22
- |--------|---------|-------------|------|
23
- | `src/clients/ftp-storage-client.ts` | `FtpStorageClient` | Storage client for FTP/FTPS protocol | `ftp-storage-client.spec.ts` |
24
- | `src/clients/sftp-storage-client.ts` | `SftpStorageClient` | Storage client for SFTP protocol with SSH key support | `sftp-storage-client.spec.ts` |
106
+ #### `FtpStorageClient`
107
+
108
+ Storage client for FTP and FTPS. Implements `Storage`.
109
+
110
+ The constructor accepts a `secure` boolean that selects FTPS when `true` (default `false`).
111
+ Using `StorageFactory.connect` is recommended over direct instantiation.
112
+
113
+ ```ts
114
+ import { FtpStorageClient } from "@simplysm/storage";
115
+
116
+ // Plain FTP
117
+ const client = new FtpStorageClient();
118
+
119
+ // FTPS
120
+ const secureClient = new FtpStorageClient(true);
121
+
122
+ await client.connect({ host: "ftp.example.com", user: "user", pass: "pass" });
123
+
124
+ try {
125
+ const entries = await client.readdir("/uploads");
126
+ console.log(entries);
127
+
128
+ await client.put("/local/file.txt", "/uploads/file.txt");
129
+ const exists = await client.exists("/uploads/file.txt");
130
+ console.log(exists); // true
131
+ } finally {
132
+ await client.close();
133
+ }
134
+ ```
135
+
136
+ **Constructor**
137
+
138
+ ```ts
139
+ new FtpStorageClient(secure?: boolean)
140
+ ```
141
+
142
+ | Parameter | Type | Default | Description |
143
+ | --------- | --------- | ------- | ---------------------------------------- |
144
+ | `secure` | `boolean` | `false` | `true` to use FTPS (TLS), `false` for FTP |
145
+
146
+ **Methods** — all defined by the `Storage` interface.
147
+
148
+ | Method | Notes |
149
+ | -------------- | --------------------------------------------------------------------------------------------------- |
150
+ | `connect` | Throws if already connected. Use `StorageFactory.connect` to avoid manual lifecycle management. |
151
+ | `mkdir` | Creates parent directories automatically. |
152
+ | `rename` | Renames or moves a remote path. |
153
+ | `readdir` | Returns a list of `FileInfo` entries for the given directory. |
154
+ | `readFile` | Downloads and returns file content as `Bytes`. |
155
+ | `exists` | Uses `size()` for files (O(1)) and `list()` for directories. Returns `false` on any error. |
156
+ | `put` | Accepts a local file path string or a `Bytes` buffer. |
157
+ | `uploadDir` | Recursively uploads a local directory. |
158
+ | `remove` | Deletes a remote file. |
159
+ | `close` | Safe to call when already closed. Can reconnect on the same instance after closing. |
160
+
161
+ ---
162
+
163
+ #### `SftpStorageClient`
164
+
165
+ Storage client for SFTP (SSH File Transfer Protocol). Implements `Storage`.
166
+
167
+ When `pass` is omitted from the config, authentication falls back to SSH agent and the key file at `~/.ssh/id_ed25519`.
168
+ Using `StorageFactory.connect` is recommended over direct instantiation.
169
+
170
+ ```ts
171
+ import { SftpStorageClient } from "@simplysm/storage";
172
+
173
+ const client = new SftpStorageClient();
174
+
175
+ // Password authentication
176
+ await client.connect({ host: "sftp.example.com", port: 22, user: "user", pass: "pass" });
177
+
178
+ // Key-based authentication (omit pass)
179
+ await client.connect({ host: "sftp.example.com", user: "user" });
180
+
181
+ try {
182
+ await client.mkdir("/uploads/2024");
183
+ await client.put("/local/report.csv", "/uploads/2024/report.csv");
184
+ const entries = await client.readdir("/uploads/2024");
185
+ console.log(entries);
186
+ } finally {
187
+ await client.close();
188
+ }
189
+ ```
190
+
191
+ **Constructor**
192
+
193
+ ```ts
194
+ new SftpStorageClient()
195
+ ```
196
+
197
+ No constructor parameters.
198
+
199
+ **Methods** — all defined by the `Storage` interface.
200
+
201
+ | Method | Notes |
202
+ | -------------- | ------------------------------------------------------------------------------------------------------- |
203
+ | `connect` | Throws if already connected. When `pass` is absent, authenticates via SSH agent / `~/.ssh/id_ed25519`. |
204
+ | `mkdir` | Creates parent directories automatically. |
205
+ | `rename` | Renames or moves a remote path. |
206
+ | `readdir` | Returns a list of `FileInfo` entries for the given directory. |
207
+ | `readFile` | Downloads and returns file content as `Bytes`. |
208
+ | `exists` | Returns `false` even when the parent directory does not exist, or on any error. |
209
+ | `put` | Accepts a local file path string (uses `fastPut`) or a `Bytes` buffer. |
210
+ | `uploadDir` | Recursively uploads a local directory. |
211
+ | `remove` | Deletes a remote file. |
212
+ | `close` | Safe to call when already closed. Can reconnect on the same instance after closing. |
213
+
214
+ ---
25
215
 
26
216
  ### Factory
27
217
 
28
- | Source | Exports | Description | Test |
29
- |--------|---------|-------------|------|
30
- | `src/storage-factory.ts` | `StorageFactory` | Factory that creates and auto-closes storage connections | `storage-factory.spec.ts` |
218
+ #### `StorageFactory`
219
+
220
+ Creates and manages storage client connections. Preferred over constructing clients directly.
221
+
222
+ **`StorageFactory.connect`** (static)
223
+
224
+ Connects to storage, executes the callback, and closes the connection automatically — even if the callback throws.
225
+
226
+ ```ts
227
+ import { StorageFactory } from "@simplysm/storage";
228
+
229
+ const result = await StorageFactory.connect(
230
+ "sftp",
231
+ { host: "sftp.example.com", user: "deploy", pass: "secret" },
232
+ async (storage) => {
233
+ await storage.mkdir("/var/www/releases/v2");
234
+ await storage.uploadDir("/local/build", "/var/www/releases/v2");
235
+ return await storage.readdir("/var/www/releases/v2");
236
+ },
237
+ );
238
+
239
+ console.log(result); // FileInfo[]
240
+ ```
241
+
242
+ ```ts
243
+ static connect<R>(
244
+ type: StorageType,
245
+ config: StorageConnConfig,
246
+ fn: (storage: Storage) => R | Promise<R>,
247
+ ): Promise<R>
248
+ ```
249
+
250
+ | Parameter | Type | Description |
251
+ | --------- | --------------------------------- | ---------------------------------------------------- |
252
+ | `type` | `StorageType` | Protocol: `"ftp"`, `"ftps"`, or `"sftp"` |
253
+ | `config` | `StorageConnConfig` | Connection parameters (host, port, user, pass) |
254
+ | `fn` | `(storage: Storage) => R \| Promise<R>` | Callback that receives the connected client |
255
+
256
+ Returns a `Promise<R>` that resolves to the value returned by `fn`.
31
257
 
32
- ## License
258
+ ## Types
33
259
 
34
- Apache-2.0
260
+ | Name | Kind | Description |
261
+ | ------------------- | ----------- | --------------------------------------------------- |
262
+ | `StorageConnConfig` | `interface` | Connection configuration (host, port, user, pass) |
263
+ | `FileInfo` | `interface` | File/directory entry returned by `readdir` |
264
+ | `Storage` | `interface` | Unified interface implemented by all storage clients |
265
+ | `StorageType` | `type` | Protocol discriminant: `"ftp" \| "ftps" \| "sftp"` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/storage",
3
- "version": "13.0.71",
3
+ "version": "13.0.74",
4
4
  "description": "Simplysm Package - Storage Module (node)",
5
5
  "author": "simplysm",
6
6
  "license": "Apache-2.0",
@@ -21,7 +21,7 @@
21
21
  "dependencies": {
22
22
  "basic-ftp": "^5.2.0",
23
23
  "ssh2-sftp-client": "^12.0.1",
24
- "@simplysm/core-common": "13.0.71"
24
+ "@simplysm/core-common": "13.0.74"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/ssh2-sftp-client": "^9.0.6"