@simplysm/storage 13.0.96 → 13.0.97

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/package.json +2 -2
  2. package/README.md +0 -223
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/storage",
3
- "version": "13.0.96",
3
+ "version": "13.0.97",
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.1.0",
24
- "@simplysm/core-common": "13.0.96"
24
+ "@simplysm/core-common": "13.0.97"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/ssh2-sftp-client": "^9.0.6"
package/README.md DELETED
@@ -1,223 +0,0 @@
1
- # @simplysm/storage
2
-
3
- FTP, FTPS, SFTP 원격 스토리지 통합 라이브러리. 팩토리 패턴으로 프로토콜에 독립적인 파일 전송을 제공한다.
4
-
5
- ## 설치
6
-
7
- ```bash
8
- npm install @simplysm/storage
9
- ```
10
-
11
- **의존성:** `basic-ftp` (FTP/FTPS), `ssh2-sftp-client` (SFTP), `@simplysm/core-common`
12
-
13
- ## 빠른 시작
14
-
15
- ```typescript
16
- import { StorageFactory } from "@simplysm/storage";
17
-
18
- // 팩토리 패턴: 연결 → 작업 → 자동 종료
19
- await StorageFactory.connect("sftp", {
20
- host: "example.com",
21
- port: 22,
22
- user: "deploy",
23
- password: "secret",
24
- }, async (storage) => {
25
- await storage.put("/local/file.zip", "/remote/file.zip");
26
- await storage.uploadDir("/local/dist", "/remote/www");
27
- const files = await storage.list("/remote/www");
28
- const exists = await storage.exists("/remote/file.zip");
29
- });
30
- // 콜백 종료 시 연결 자동 해제 (예외 발생해도 보장)
31
- ```
32
-
33
- ## 타입 정의
34
-
35
- ### StorageProtocol
36
-
37
- ```typescript
38
- type StorageProtocol = "ftp" | "ftps" | "sftp";
39
- ```
40
-
41
- | 값 | 설명 | 내부 클라이언트 |
42
- |-----|------|----------------|
43
- | `"ftp"` | File Transfer Protocol | `FtpStorageClient(secure=false)` |
44
- | `"ftps"` | FTP over SSL/TLS | `FtpStorageClient(secure=true)` |
45
- | `"sftp"` | SSH File Transfer Protocol | `SftpStorageClient` |
46
-
47
- ### StorageConnConfig
48
-
49
- ```typescript
50
- interface StorageConnConfig {
51
- host: string;
52
- port?: number; // 미지정 시 프로토콜 기본값 사용
53
- user?: string;
54
- password?: string;
55
- }
56
- ```
57
-
58
- - **SFTP에서 `password` 미지정 시**: SSH 키 인증으로 전환
59
- 1. `~/.ssh/id_ed25519` 키 파일 자동 탐색
60
- 2. 키 파싱 실패 시 `SSH_AUTH_SOCK` 환경변수의 SSH 에이전트로 재시도
61
-
62
- ### FileInfo
63
-
64
- ```typescript
65
- interface FileInfo {
66
- name: string; // 파일/디렉토리 이름
67
- isFile: boolean; // true: 파일, false: 디렉토리
68
- }
69
- ```
70
-
71
- ### Bytes
72
-
73
- `@simplysm/core-common`에서 정의한 바이트 배열 타입 (`Uint8Array` 기반).
74
-
75
- ## API 레퍼런스
76
-
77
- ### StorageFactory
78
-
79
- 프로토콜에 독립적으로 스토리지 클라이언트를 생성하고 연결을 관리하는 팩토리 클래스.
80
-
81
- #### `StorageFactory.connect<R>(type, config, fn): Promise<R>`
82
-
83
- ```typescript
84
- static async connect<R>(
85
- type: StorageProtocol,
86
- config: StorageConnConfig,
87
- fn: (storage: StorageClient) => R | Promise<R>,
88
- ): Promise<R>
89
- ```
90
-
91
- - 연결 수립 → 콜백 실행 → 연결 종료를 자동 관리
92
- - 콜백에서 예외가 발생해도 `finally`에서 연결이 안전하게 종료됨
93
- - 콜백의 반환값을 그대로 반환 (제네릭 `R`)
94
-
95
- ```typescript
96
- // 반환값 활용 예시
97
- const fileList = await StorageFactory.connect("ftp", config, async (storage) => {
98
- return await storage.list("/data");
99
- });
100
- // fileList: FileInfo[]
101
- ```
102
-
103
- ### StorageClient (공통 인터페이스)
104
-
105
- `FtpStorageClient`와 `SftpStorageClient`가 구현하는 공통 인터페이스. `StorageFactory.connect` 콜백의 `storage` 파라미터 타입이다.
106
-
107
- | 메서드 | 시그니처 | 설명 |
108
- |--------|---------|------|
109
- | `connect` | `(config: StorageConnConfig) => Promise<void>` | 서버 연결. 이미 연결된 인스턴스에서 호출하면 에러 발생 |
110
- | `close` | `() => Promise<void>` | 연결 종료. 이미 종료된 상태에서 호출해도 안전함 |
111
- | `mkdir` | `(dirPath: string) => Promise<void>` | 디렉토리 생성 (부모 디렉토리 자동 생성) |
112
- | `rename` | `(fromPath: string, toPath: string) => Promise<void>` | 파일/디렉토리 이름 변경 |
113
- | `list` | `(dirPath: string) => Promise<FileInfo[]>` | 디렉토리 내 항목 목록 조회 |
114
- | `readFile` | `(filePath: string) => Promise<Bytes>` | 원격 파일을 바이트 배열로 읽기 |
115
- | `exists` | `(filePath: string) => Promise<boolean>` | 파일/디렉토리 존재 여부 확인 |
116
- | `put` | `(localPathOrBuffer: string \| Bytes, remotePath: string) => Promise<void>` | 로컬 파일 경로 또는 바이트 데이터를 원격 경로에 업로드 |
117
- | `uploadDir` | `(fromPath: string, toPath: string) => Promise<void>` | 로컬 디렉토리 전체를 원격 경로에 업로드 |
118
- | `remove` | `(filePath: string) => Promise<void>` | 원격 파일 삭제 |
119
-
120
- #### 메서드별 주의사항
121
-
122
- **`exists`**: 부모 디렉토리가 존재하지 않아도 `false` 반환. 네트워크 오류/권한 오류 등 모든 예외에 대해서도 `false` 반환.
123
- - FTP: `size()` 명령으로 파일 확인 (O(1)), 실패 시 부모 디렉토리 `list()`로 폴백
124
- - SFTP: `exists()` 내장 메서드 사용 (반환값 `false | 'd' | '-' | 'l'`)
125
-
126
- **`mkdir`**: 부모 디렉토리가 없으면 재귀적으로 생성한다.
127
-
128
- **`put`**: 첫 번째 인자로 로컬 파일 경로(string) 또는 바이트 데이터(Bytes)를 받는다.
129
- - SFTP는 파일 경로 전달 시 `fastPut` 사용 (병렬 전송으로 더 빠름)
130
-
131
- **`connect`**: 이미 연결된 인스턴스에서 중복 호출하면 `SdError` 발생. 반드시 `close()` 후 재연결해야 한다.
132
-
133
- ### FtpStorageClient
134
-
135
- FTP/FTPS 프로토콜 클라이언트. 내부적으로 `basic-ftp` 라이브러리를 사용한다.
136
-
137
- ```typescript
138
- import { FtpStorageClient } from "@simplysm/storage";
139
-
140
- const client = new FtpStorageClient(secure?: boolean);
141
- // secure=false: FTP (기본값)
142
- // secure=true: FTPS
143
- ```
144
-
145
- 직접 사용 시 반드시 `connect` → 작업 → `close` 순서를 지켜야 한다. `StorageFactory.connect` 사용을 권장한다.
146
-
147
- ### SftpStorageClient
148
-
149
- SFTP 프로토콜 클라이언트. 내부적으로 `ssh2-sftp-client` 라이브러리를 사용한다.
150
-
151
- ```typescript
152
- import { SftpStorageClient } from "@simplysm/storage";
153
-
154
- const client = new SftpStorageClient();
155
- ```
156
-
157
- **인증 방식 (자동 선택):**
158
- 1. `password`가 있으면 비밀번호 인증
159
- 2. `password`가 없으면 키 기반 인증:
160
- - `~/.ssh/id_ed25519` 키 파일 + SSH 에이전트(`SSH_AUTH_SOCK`) 시도
161
- - 키 파싱 실패 시 SSH 에이전트만으로 재시도
162
-
163
- ## 사용 예제
164
-
165
- ### 파일 업로드/다운로드
166
-
167
- ```typescript
168
- await StorageFactory.connect("sftp", config, async (storage) => {
169
- // 로컬 파일 업로드
170
- await storage.put("/local/path/file.txt", "/remote/path/file.txt");
171
-
172
- // 바이트 데이터 직접 업로드
173
- const data = new TextEncoder().encode("hello");
174
- await storage.put(data, "/remote/path/hello.txt");
175
-
176
- // 파일 읽기
177
- const content = await storage.readFile("/remote/path/file.txt");
178
- });
179
- ```
180
-
181
- ### 디렉토리 관리
182
-
183
- ```typescript
184
- await StorageFactory.connect("ftp", config, async (storage) => {
185
- // 디렉토리 생성 (중첩 경로 자동 생성)
186
- await storage.mkdir("/remote/a/b/c");
187
-
188
- // 디렉토리 전체 업로드
189
- await storage.uploadDir("/local/dist", "/remote/www");
190
-
191
- // 디렉토리 목록 조회
192
- const items = await storage.list("/remote/www");
193
- for (const item of items) {
194
- // item.name: 이름, item.isFile: 파일 여부
195
- }
196
- });
197
- ```
198
-
199
- ### 파일 존재 확인 및 삭제
200
-
201
- ```typescript
202
- await StorageFactory.connect("ftps", config, async (storage) => {
203
- if (await storage.exists("/remote/old-file.txt")) {
204
- await storage.remove("/remote/old-file.txt");
205
- }
206
-
207
- await storage.rename("/remote/temp.txt", "/remote/final.txt");
208
- });
209
- ```
210
-
211
- ### SSH 키 인증 (SFTP)
212
-
213
- ```typescript
214
- // password 미지정 시 자동으로 키 기반 인증
215
- await StorageFactory.connect("sftp", {
216
- host: "example.com",
217
- port: 22,
218
- user: "deploy",
219
- // password 생략 → ~/.ssh/id_ed25519 + SSH_AUTH_SOCK 사용
220
- }, async (storage) => {
221
- await storage.uploadDir("/local/build", "/var/www/html");
222
- });
223
- ```