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 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
- ```js
5
- const FSD = require('fsd');
6
- const FSAdapter = require('fsd-fs');
3
+ FSD 本地文件系统适配器 - 提供对服务器磁盘文件的读写访问。
7
4
 
8
- const adapter = new FSAdapter(config);
5
+ [![npm version](https://badge.fury.io/js/fsd-fs.svg)](https://www.npmjs.com/package/fsd-fs)
9
6
 
10
- const fsd = FSD({ adapter: adapter });
7
+ ## 概述
11
8
 
12
- let file = fsd('/test.txt');
9
+ `fsd-fs` `fsd` 核心库的本地文件系统适配器,提供完整的文件和目录操作能力。
13
10
 
14
- let content = await fsd.read();
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
- FSD 文档: https://github.com/liangxingchen/fsd
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
- | root | string | Yes | 本地存储根路径,例如 '/app/uploads' |
25
- | mode | number | | 创建的文件权限,默认 `0o666` |
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
@@ -25,7 +25,7 @@ class FSAdapter {
25
25
  this._options = Object.assign({
26
26
  urlPrefix: '',
27
27
  root: '/',
28
- mode: 0o666,
28
+ mode: 0o644,
29
29
  tmpdir: os_1.default.tmpdir()
30
30
  }, options);
31
31
  let { urlPrefix } = this._options;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fsd-fs",
3
- "version": "0.14.1",
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": "Liang <liang@miaomo.cc> (https://github.com/liangxingchen)",
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
  }