fsd-fs 0.14.1 → 0.15.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/LICENSE +21 -0
- package/README.md +66 -16
- package/index.d.ts +138 -0
- package/lib/index.js +1 -1
- package/package.json +8 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Liang Xingchen https://github.com/liangxingchen
|
|
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, destribute, 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,29 +1,79 @@
|
|
|
1
1
|
# fsd-fs
|
|
2
|
-
FSD 本地磁盘文件读写适配器。
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
const FSD = require('fsd');
|
|
6
|
-
const FSAdapter = require('fsd-fs');
|
|
3
|
+
FSD 本地文件系统适配器 - 提供对服务器磁盘文件的读写访问。
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/fsd-fs)
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
## 概述
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
`fsd-fs` 是 `fsd` 核心库的本地文件系统适配器,提供完整的文件和目录操作能力。
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
### 核心特性
|
|
15
12
|
|
|
13
|
+
- ✅ 完整的文件读写操作
|
|
14
|
+
- ✅ 目录管理(创建、删除、遍历)
|
|
15
|
+
- ✅ 流式读写(大文件处理)
|
|
16
|
+
- ✅ 分段上传(大文件优化)
|
|
17
|
+
- ✅ 递归目录列表
|
|
18
|
+
- ✅ Glob 模式匹配
|
|
19
|
+
- ✅ 文件权限控制
|
|
20
|
+
- ✅ 并发控制优化
|
|
21
|
+
|
|
22
|
+
## 安装
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install fsd-fs
|
|
16
26
|
```
|
|
17
27
|
|
|
18
|
-
|
|
28
|
+
## 配置
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import FSD from 'fsd';
|
|
32
|
+
import FSAdapter from 'fsd-fs';
|
|
33
|
+
|
|
34
|
+
// 创建适配器
|
|
35
|
+
const adapter = new FSAdapter({
|
|
36
|
+
root: '/app/uploads', // 必需:本地存储根路径
|
|
37
|
+
mode: 0o644, // 可选:创建文件权限(默认 0o644)
|
|
38
|
+
tmpdir: '/tmp/fsd-multipart', // 可选:临时目录(分段上传时使用,默认系统临时目录)
|
|
39
|
+
urlPrefix: 'https://cdn.example.com' // 可选:URL 前缀(生成访问链接时使用)
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// 创建 FSD 实例
|
|
43
|
+
const fsd = FSD({ adapter });
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 配置选项说明
|
|
47
|
+
|
|
48
|
+
| 选项 | 类型 | 必需 | 默认值 | 说明 |
|
|
49
|
+
|------|------|------|--------|------|
|
|
50
|
+
| `root` | string | 是 | - | 本地存储根路径,所有文件操作限制在此目录下 |
|
|
51
|
+
| `mode` | number | 否 | 0o644 | 创建文件时的权限模式(八进制) |
|
|
52
|
+
| `tmpdir` | string | 否 | os.tmpdir() | 分段上传时的临时文件存储目录 |
|
|
53
|
+
| `urlPrefix` | string | 否 | - | URL 前缀,用于生成访问链接,通常配合 CDN 或反向代理使用 |
|
|
54
|
+
|
|
55
|
+
### 文件权限模式
|
|
56
|
+
|
|
57
|
+
文件权限使用八进制表示法:
|
|
58
|
+
|
|
59
|
+
| 模式 | 说明 |
|
|
60
|
+
|------|------|
|
|
61
|
+
| 0o644 | rw-r--r-- (用户读写,组和其他只读) - 最常用 |
|
|
62
|
+
| 0o755 | rwxr-xr-x (用户读写执行,组和其他读执行) - 目录常用 |
|
|
63
|
+
| 0o600 | rw------- (仅用户可读写) - 敏感文件 |
|
|
64
|
+
| 0o666 | rw-rw-rw- (用户、组、其他都可读写) - 默认值 |
|
|
19
65
|
|
|
20
|
-
|
|
66
|
+
权限位说明:
|
|
67
|
+
- `4` = read (读)
|
|
68
|
+
- `2` = write (写)
|
|
69
|
+
- `1` = execute (执行)
|
|
70
|
+
- `0` = 无权限
|
|
21
71
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
| tmpdir | string | | 临时目录,用于分段上传时暂存文件,如不使用分段上传,可省略 |
|
|
27
|
-
| urlPrefix | string | | URL前缀,用于生成下载链接 |
|
|
72
|
+
示例 `0o644`:
|
|
73
|
+
- 用户: 4+2+0 = 6 (rw)
|
|
74
|
+
- 组: 4+0+0 = 4 (r--)
|
|
75
|
+
- 其他: 4+0+0 = 4 (r--)
|
|
28
76
|
|
|
77
|
+
## License
|
|
29
78
|
|
|
79
|
+
MIT
|
package/index.d.ts
CHANGED
|
@@ -1,10 +1,148 @@
|
|
|
1
1
|
import { Adapter } from 'fsd';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* FSAdapter 配置选项
|
|
5
|
+
*
|
|
6
|
+
* 本地文件系统适配器的初始化配置。
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const adapter = new FSAdapter({
|
|
11
|
+
* root: '/app/uploads',
|
|
12
|
+
* mode: 0o644,
|
|
13
|
+
* tmpdir: '/tmp/fsd-tmp',
|
|
14
|
+
* urlPrefix: 'https://cdn.example.com'
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
3
18
|
export interface FSAdapterOptions {
|
|
19
|
+
/**
|
|
20
|
+
* 本地存储根路径(必需)
|
|
21
|
+
*
|
|
22
|
+
* 所有文件操作都会在此根路径下进行。
|
|
23
|
+
* 此路径必须是绝对路径,并且适配器有读取/写入权限。
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Linux/Mac
|
|
28
|
+
* root: '/app/uploads'
|
|
29
|
+
*
|
|
30
|
+
* // Windows
|
|
31
|
+
* root: 'C:\\app\\uploads'
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* 确保此目录存在且有适当的读写权限。
|
|
36
|
+
*/
|
|
4
37
|
root: string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 创建文件的权限模式(可选)
|
|
41
|
+
*
|
|
42
|
+
* 默认值:`0o644` (rw-rw-rw-)
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* mode: 0o644, // rw-r--r-- (用户读写,组和其他只读)
|
|
47
|
+
* mode: 0o755, // rwxr-xr-x (用户读写执行,组和其他读执行)
|
|
48
|
+
* mode: 0o600, // rw------- (仅用户可读写)
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* 使用八进制表示法(0o 前缀)或十进制都可以。
|
|
53
|
+
*/
|
|
5
54
|
mode?: number;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* URL 前缀(可选)
|
|
58
|
+
*
|
|
59
|
+
* 用于生成访问链接时添加前缀。
|
|
60
|
+
* 通常配合 CDN 或反向代理使用。
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* urlPrefix: 'https://cdn.example.com',
|
|
65
|
+
* // file.createUrl() 返回: https://cdn.example.com/uploads/file.txt
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @remarks
|
|
69
|
+
* 尾部会自动去除 `/`,例如 `'https://cdn.com/'` 会被标准化为 `'https://cdn.com'`。
|
|
70
|
+
*/
|
|
6
71
|
urlPrefix?: string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 临时目录(可选)
|
|
75
|
+
*
|
|
76
|
+
* 用于分段上传时暂存分片文件。
|
|
77
|
+
* 如果不使用分段上传功能,可以省略此选项。
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* tmpdir: '/tmp/fsd-multipart',
|
|
82
|
+
* // 或使用系统默认临时目录
|
|
83
|
+
* tmpdir: os.tmpdir()
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* @remarks
|
|
87
|
+
* 默认值:系统临时目录(通过 `os.tmpdir()` 获取)。
|
|
88
|
+
* 确保临时目录有足够的磁盘空间用于存储分片文件。
|
|
89
|
+
*/
|
|
7
90
|
tmpdir?: string;
|
|
8
91
|
}
|
|
9
92
|
|
|
93
|
+
/**
|
|
94
|
+
* 本地文件系统适配器
|
|
95
|
+
*
|
|
96
|
+
* 提供对服务器本地磁盘文件的读写访问。
|
|
97
|
+
*
|
|
98
|
+
* @remarks
|
|
99
|
+
* ### 特性
|
|
100
|
+
* - 支持完整的文件和目录操作
|
|
101
|
+
* - 支持流式读写
|
|
102
|
+
* - 支持分段上传(大文件)
|
|
103
|
+
* - 支持递归目录列表
|
|
104
|
+
* - 使用 glob 模式匹配
|
|
105
|
+
*
|
|
106
|
+
* ### 权限要求
|
|
107
|
+
* - `root` 目录必须有读写权限
|
|
108
|
+
* - `tmpdir` 目录(用于分段上传)必须有读写权限
|
|
109
|
+
*
|
|
110
|
+
* ### 性能优化
|
|
111
|
+
* - 使用 `mapLimit` 限制并发操作,避免文件系统过载
|
|
112
|
+
* - 使用 `glob` 进行高效的目录遍历
|
|
113
|
+
*
|
|
114
|
+
* ### 分段上传机制
|
|
115
|
+
* 1. 调用 `initMultipartUpload()` 初始化任务
|
|
116
|
+
* 2. 每个分片写入到 `tmpdir` 下的临时文件
|
|
117
|
+
* 3. 调用 `completeMultipartUpload()` 时,所有临时文件会被顺序追加到目标文件
|
|
118
|
+
* 4. 完成后临时文件会被自动删除
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* import FSAdapter from 'fsd-fs';
|
|
123
|
+
* import FSD from 'fsd';
|
|
124
|
+
*
|
|
125
|
+
* // 创建适配器
|
|
126
|
+
* const adapter = new FSAdapter({
|
|
127
|
+
* root: '/app/uploads',
|
|
128
|
+
* mode: 0o644,
|
|
129
|
+
* tmpdir: '/tmp/fsd-tmp'
|
|
130
|
+
* });
|
|
131
|
+
*
|
|
132
|
+
* // 创建 FSD 实例
|
|
133
|
+
* const fsd = FSD({ adapter });
|
|
134
|
+
*
|
|
135
|
+
* // 基本操作
|
|
136
|
+
* await fsd('/test.txt').write('Hello, FS!');
|
|
137
|
+
* const content = await fsd('/test.txt').read('utf8');
|
|
138
|
+
*
|
|
139
|
+
* // 分段上传大文件
|
|
140
|
+
* const file = fsd('/large-file.dat');
|
|
141
|
+
* const tasks = await file.initMultipartUpload(3);
|
|
142
|
+
* for (let i = 0; i < tasks.length; i++) {
|
|
143
|
+
* await file.writePart(tasks[i], getDataForPart(i));
|
|
144
|
+
* }
|
|
145
|
+
* await file.completeMultipartUpload(['part://...', 'part://...', 'part://...']);
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
10
148
|
export default class FSAdapter extends Adapter<FSAdapterOptions> {}
|
package/lib/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fsd-fs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "File system adapter for fsd",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -9,12 +9,17 @@
|
|
|
9
9
|
"prepublish": "npm run build"
|
|
10
10
|
},
|
|
11
11
|
"repository": "https://github.com/liangxingchen/fsd/tree/master/packages/fsd-fs",
|
|
12
|
-
"author":
|
|
12
|
+
"author": {
|
|
13
|
+
"name": "Liang",
|
|
14
|
+
"email": "liang@miaomo.cn",
|
|
15
|
+
"url": "https://github.com/liangxingchen"
|
|
16
|
+
},
|
|
13
17
|
"license": "MIT",
|
|
14
18
|
"dependencies": {
|
|
15
19
|
"async": "*",
|
|
16
20
|
"debug": "^4.4.3",
|
|
17
21
|
"glob": "^10.5.0",
|
|
18
22
|
"is-stream": "^2.0.1"
|
|
19
|
-
}
|
|
23
|
+
},
|
|
24
|
+
"gitHead": "ea754919fb95b49deffd529b5c01c66da0dc08f9"
|
|
20
25
|
}
|