@filebox/core 1.0.10 → 1.0.12

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/README.md CHANGED
@@ -1,599 +1,49 @@
1
- # @filebox/core - FileBox核心模块
1
+ # @filebox/core
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@filebox/core.svg)](https://www.npmjs.com/package/@filebox/core)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
-
6
- FileBox 是一个强大的虚拟文件系统抽象层,用于统一管理多个异构存储后端。它提供了一致的 API 来操作不同的存储服务(如云盘、本地存储、HTTP文件系统等),支持挂载、缓存、加密等高级特性。
7
-
8
- ## 特性
9
-
10
- - 🔌 **多存储后端支持** - 通过插件系统支持各种存储服务
11
- - 🗂️ **虚拟文件系统** - 统一的文件系统抽象,像操作本地文件一样操作云盘
12
- - ⚡ **智能缓存** - 内置多种缓存策略(LRU、LFU等),支持依赖追踪
13
- - 🔐 **文件加密** - 支持文件名和内容加密
14
- - 🎯 **路径解析** - 强大的路径处理工具集
15
- - 📊 **文件元数据** - 完整的文件统计信息(Stat)
16
- - 🔄 **事件系统** - 支持生命周期钩子和自定义事件
17
- - 🚀 **高性能** - 支持直接模式和递归模式两种访问策略
18
- - 🌐 **跨平台** - 支持浏览器和 Node.js 环境
3
+ FileBox 的虚拟文件系统核心包,用来把不同存储驱动挂载到统一的路径空间里,并通过同一套 API 读写文件。
19
4
 
20
5
  ## 安装
21
6
 
22
7
  ```bash
23
- npm install @filebox/core
24
- # 或
25
8
  pnpm add @filebox/core
26
- # 或
27
- yarn add @filebox/core
28
- ```
29
-
30
- ## 快速开始
31
-
32
- ### 基础用法
33
-
34
- ```typescript
35
- import { FileBox, FileSystem } from '@filebox/core'
36
-
37
- // 创建 FileBox 实例
38
- const fs = new FileBox({
39
- events: {
40
- beforeMount: (path, options) => console.log('挂载前:', path),
41
- afterMount: (path, volume) => console.log('挂载后:', path),
42
- },
43
- })
44
-
45
- // 挂载存储后端
46
- const volume = await fs.mount({
47
- name: '/my-drive',
48
- provider: 'custom-provider',
49
- auth: {
50
- token: 'your-token',
51
- },
52
- rootPath: '/',
53
- })
54
-
55
- // 列出文件
56
- const { data, total } = await fs.list('/my-drive')
57
- console.log('文件列表:', data)
58
-
59
- // 读取文件
60
- const content = await fs.readFile('/my-drive/file.txt')
61
-
62
- // 创建目录
63
- await fs.mkdir('/my-drive/new-folder')
64
-
65
- // 上传文件
66
- await fs.upload('/my-drive/new-folder', file)
67
-
68
- // 删除文件
69
- await fs.remove('/my-drive/file.txt')
70
- ```
71
-
72
- ### 使用缓存策略
73
-
74
- ```typescript
75
- import { FileBox, Cache } from '@filebox/core'
76
- import { LRUStrategy } from '@filebox/core'
77
-
78
- // 创建带缓存的 FileBox 实例
79
- const fs = new FileBox({
80
- cacheStrategy: new LRUStrategy({
81
- maxSize: 1000,
82
- ttl: 1000 * 60 * 30, // 30分钟
83
- }),
84
- })
85
-
86
- // 挂载时指定 TTL
87
- const volume = await fs.mount({
88
- name: '/cached-drive',
89
- provider: 'custom-provider',
90
- ttl: 1, // 启用缓存
91
- auth: { token: 'token' },
92
- })
93
- ```
94
-
95
- ### 自定义文件系统驱动
96
-
97
- ```typescript
98
- import { FileSystem } from '@filebox/core'
99
-
100
- class MyFileSystem extends FileSystem<YourDataType> {
101
- constructor(config) {
102
- super(config)
103
- }
104
-
105
- // 实现必需的抽象方法
106
- getName(data: YourDataType): string {
107
- return data.name
108
- }
109
-
110
- getId(data: YourDataType): string | number {
111
- return data.id
112
- }
113
-
114
- getSize(data: YourDataType): number {
115
- return data.size
116
- }
117
-
118
- getMTime(data: YourDataType): number {
119
- return data.modifiedTime
120
- }
121
-
122
- getExt(data: YourDataType): string {
123
- return data.extension
124
- }
125
-
126
- isFile(data: YourDataType): boolean {
127
- return data.type === 'file'
128
- }
129
-
130
- getRecursiveKey(target: YourDataType): string | number {
131
- return target.id
132
- }
133
-
134
- async fetchList(id: string | number): Promise<YourDataType[]> {
135
- // 从远程 API 获取文件列表
136
- const response = await fetch(`/api/files/${id}`)
137
- return response.json()
138
- }
139
-
140
- // 可选:实现额外的方法
141
- async mkdir(stat: Stat, name: string) {
142
- // 实现创建目录逻辑
143
- }
144
-
145
- async remove(stat: Stat) {
146
- // 实现删除逻辑
147
- }
148
-
149
- async upload(stat: Stat, file: any) {
150
- // 实现上传逻辑
151
- }
152
- }
153
-
154
- // 注册驱动
155
- FileBox.use({
156
- name: 'my-provider',
157
- package: MyFileSystem,
158
- })
159
- ```
160
-
161
- ## 核心概念
162
-
163
- ### 1. FileBox - 虚拟文件系统
164
-
165
- FileBox 是主要的文件系统管理器,负责:
166
-
167
- - 挂载和管理多个存储卷(Volume)
168
- - 路由文件操作到正确的存储后端
169
- - 提供统一的文件操作 API
170
- - 触发生命周期事件
171
-
172
- ### 2. Volume - 存储卷
173
-
174
- Volume 代表一个挂载的存储后端,分为两种类型:
175
-
176
- - **`Volume`** - 可读写的存储卷
177
- - **`ReadOnlyVolume`** - 只读的存储卷
178
-
179
- 每个 Volume 都有自己的:
180
-
181
- - 挂载路径(mountPath)
182
- - 根路径(rootPath)
183
- - 文件系统实例(FileSystem)
184
-
185
- ### 3. FileSystem - 文件系统抽象
186
-
187
- FileSystem 是存储后端的抽象基类,提供:
188
-
189
- - **两种访问模式**:
190
- - `Mode.indirect` - 递归模式,通过父子关系遍历(默认)
191
- - `Mode.direct` - 直接模式,直接通过路径访问
192
- - **缓存支持** - 自动缓存文件列表
193
- - **格式化** - 将原始数据转换为统一的 Stat 对象
194
-
195
- ### 4. Stat - 文件元数据
196
-
197
- Stat 表示文件或目录的元数据:
198
-
199
- ```typescript
200
- interface IStat {
201
- id: string | number // 文件 ID
202
- name: string // 文件名
203
- size: any // 格式化的大小(如 "1.5 MB")
204
- byte: number | null // 字节大小
205
- thumbnail: string | null // 缩略图 URL
206
- atime?: string | null // 访问时间
207
- ctime?: string | null // 创建时间
208
- mtime: string | null // 修改时间
209
- type: string | null // 文件类型/扩展名
210
- hash?: {
211
- // 文件哈希
212
- md5?: string
213
- sha1?: string
214
- sha256?: string
215
- }
216
- }
217
- ```
218
-
219
- ### 5. Cache - 缓存系统
220
-
221
- FileBox 提供了强大的缓存系统:
222
-
223
- **缓存策略**:
224
-
225
- - `LRUStrategy` - 最近最少使用
226
- - `LFUStrategy` - 最不经常使用
227
- - `FIFOStrategy` - 先进先出
228
- - `TTLStrategy` - 基于时间的过期
229
-
230
- **依赖追踪**:
231
- 缓存系统会自动追踪文件之间的依赖关系,当某个文件变更时,会自动失效相关的缓存。
232
-
233
- ```typescript
234
- // 文件操作会自动更新缓存
235
- await fs.mkdir('/my-drive/folder') // 自动失效父目录缓存
236
- await fs.remove('/my-drive/file') // 自动失效父目录和文件缓存
237
- await fs.rename('/my-drive/old', 'new') // 自动更新缓存
238
9
  ```
239
10
 
240
- ### 6. Path - 路径工具
241
-
242
- 提供了完整的路径处理工具集:
243
-
244
- ```typescript
245
- import { path } from '@filebox/core'
246
-
247
- // 基础操作
248
- path.join('/foo', 'bar', 'baz') // => '/foo/bar/baz'
249
- path.normalize('/foo//bar/../baz') // => '/foo/baz'
250
- path.basename('/foo/bar.txt') // => 'bar.txt'
251
- path.dirname('/foo/bar.txt') // => '/foo'
252
- path.extname('/foo/bar.txt') // => '.txt'
253
-
254
- // 高级操作
255
- path.split('/drive/foo/bar') // => ['drive', '/foo/bar']
256
- path.reverseSplist('/foo/bar/baz') // => ['/foo/bar', 'baz']
257
- path.toArray('/foo/bar/baz') // => ['foo', 'bar', 'baz']
258
- ```
11
+ ## 使用
259
12
 
260
- ### 7. Plugin - 插件系统
13
+ ```ts
14
+ import FileBox from "@filebox/core";
15
+ import WebDAVDriver from "./drivers/webdav";
261
16
 
262
- 插件系统用于注册和管理文件系统驱动:
263
-
264
- ```typescript
265
- // 注册插件
266
17
  FileBox.use({
267
- name: 'my-driver',
268
- package: MyFileSystem,
269
- install() {
270
- console.log('插件已安装')
271
- },
272
- uninstall() {
273
- console.log('插件已卸载')
274
- },
275
- })
276
-
277
- // 获取插件
278
- const driver = Plugin.get('my-driver')
279
-
280
- // 列出所有插件
281
- const drivers = Plugin.list()
282
-
283
- // 卸载插件
284
- Plugin.uninstall('my-driver')
285
- ```
286
-
287
- ## API 文档
288
-
289
- ### FileBox 类
18
+ name: "webdav",
19
+ package: WebDAVDriver,
20
+ });
290
21
 
291
- #### 构造函数
22
+ const filebox = new FileBox();
292
23
 
293
- ```typescript
294
- new FileBox(options?: {
295
- events?: Record<string, EventCallback | EventCallback[]>
296
- plugins?: Array<any>
297
- cacheStrategy?: ICacheStrategy
298
- })
299
- ```
300
-
301
- #### 静态方法
302
-
303
- - **`use(module: any): typeof FileBox`** - 注册插件
304
-
305
- #### 实例方法
306
-
307
- ##### 挂载和卸载
308
-
309
- - **`mount(options: MountOptions): Promise<Volume>`** - 挂载存储后端
310
- - **`mountRaw(options: MountOptions): void`** - 挂载只读存储
311
- - **`unmount(volume: Volume): Promise<void>`** - 卸载存储卷
312
- - **`getVolume(name?: string): Volume | Map<string, Volume>`** - 获取存储卷
313
-
314
- ##### 文件操作
315
-
316
- - **`stat(path: string): Promise<Stat>`** - 获取文件信息
317
- - **`list(path: string, options?): Promise<{data: Stat[], total: number}>`** - 列出目录内容
318
- - **`readFile(path: string): Promise<any>`** - 读取文件内容
319
- - **`mkdir(path: string, options?): Promise<Stat>`** - 创建目录
320
- - **`rename(path: string, newName: string): Promise<Stat>`** - 重命名
321
- - **`remove(path: string): Promise<any>`** - 删除文件/目录
322
- - **`upload(path: string, file: any, progress?): Promise<Stat>`** - 上传文件
323
- - **`download(path: string, options?): Promise<string[]>`** - 获取下载链接
324
- - **`copy(src: string, dest: string, options?): Promise<any>`** - 复制文件
325
- - **`move(src: string, dest: string, options?): Promise<any>`** - 移动文件
326
- - **`bulkRemove(options: {paths: string[]}): Promise<any[]>`** - 批量删除
327
-
328
- ##### 缓存管理
329
-
330
- - **`setCache(strategy: ICacheStrategy): void`** - 设置全局缓存策略
331
- - **`getCache(): ICacheStrategy | undefined`** - 获取缓存策略
332
-
333
- ### FileSystem 类
334
-
335
- #### 必须实现的抽象方法
336
-
337
- ```typescript
338
- abstract getName(data: T): string
339
- abstract getId(data: T): string | number
340
- abstract getSize(data: T): string | number | null
341
- abstract getMTime(data: T): string | number
342
- abstract getExt(data: T): string
343
- abstract isFile(data: T): boolean
344
- abstract getRecursiveKey(target: T): string | number
345
- abstract fetchList(keyOrPath: string | number, options?): Promise<any>
346
- ```
347
-
348
- #### 可选实现的方法
349
-
350
- ```typescript
351
- getThumbnail?(data: T): string
352
- getATime?(data: T): string | number | null
353
- getCTime?(data: T): string | number
354
- getHash?(data: T): any
355
- getQuota?(data: T): any
356
- isEmpty?(data: T): boolean
357
-
358
- mkdir?(stat: Stat, name: string): Promise<any>
359
- remove?(stat: Stat): Promise<any>
360
- rename?(stat: Stat, name: string): Promise<any>
361
- copy?(source: Stat, target: Stat): Promise<any>
362
- move?(source: Stat, target: Stat): Promise<any>
363
- upload?(stat: Stat, file: any): Promise<any>
364
- rapidupload?(stat: Stat, file: any): Promise<any>
365
- share?(stat: Stat, obj: any): Promise<any>
366
- save?(stat: Stat, obj: any): Promise<any>
367
- link?(stat: Stat): Promise<any>
368
- ```
369
-
370
- ### Volume 类
371
-
372
- #### 只读方法
373
-
374
- - **`stat(path: string | Stat): Promise<Stat>`** - 获取文件信息
375
- - **`list(path: string | Stat, options?): Promise<{data: Stat[], total: number}>`** - 列出目录
376
- - **`readFile(path: string): Promise<any>`** - 读取文件
377
- - **`hasMethod(method: string): boolean`** - 检查是否支持某个方法
378
- - **`refresh(path: string): Promise<void>`** - 刷新缓存
379
-
380
- #### 读写方法(仅 Volume)
381
-
382
- - **`mkdir(path: string | Stat, options?): Promise<Stat>`** - 创建目录
383
- - **`rename(path: string, newName: string): Promise<Stat>`** - 重命名
384
- - **`remove(path: string, options?): Promise<any>`** - 删除
385
- - **`upload(path: string, file: any, progress?): Promise<Stat>`** - 上传
386
- - **`download(path: string, options?): Promise<string[]>`** - 下载
387
- - **`copy(src: string, dest: string, options?): Promise<any>`** - 复制
388
- - **`move(src: string, dest: string, options?): Promise<any>`** - 移动
389
- - **`bulkRemove(paths: string[], options?): Promise<any[]>`** - 批量删除
390
- - **`bulkCopy(src: string[], dest: string, options?): Promise<any[]>`** - 批量复制
391
- - **`share(options, path?): Promise<any>`** - 分享文件
392
- - **`save(option, dest?): Promise<any>`** - 保存文件
393
- - **`search(data: any): Promise<Stat[]>`** - 搜索文件
394
-
395
- ## 事件系统
396
-
397
- FileBox 支持以下生命周期事件:
398
-
399
- ```typescript
400
- const fs = new FileBox({
401
- events: {
402
- // 挂载事件
403
- beforeMount: (path, options) => {},
404
- afterMount: (path, volume) => {},
405
-
406
- // 文件操作事件
407
- beforeList: (path, options) => {},
408
- afterList: (path, result) => {},
409
- beforeStat: (path) => {},
410
- afterStat: (path, stat) => {},
411
- beforeReadFile: (path) => {},
412
- afterReadFile: (path, content) => {},
413
- beforeMkdir: (path, options) => {},
414
- afterMkdir: (path, result) => {},
415
- beforeRename: (path, newName) => {},
416
- afterRename: (path, newName, result) => {},
417
- beforeRemove: (path) => {},
418
- afterRemove: (path, result) => {},
419
- beforeUpload: (path, file) => {},
420
- afterUpload: (path, result) => {},
421
- beforeDownload: (path, options) => {},
422
- afterDownload: (path, result) => {},
423
- beforeCopy: (src, dest, options) => {},
424
- afterCopy: (src, dest, result) => {},
425
- beforeMove: (src, dest, options) => {},
426
- afterMove: (src, dest, result) => {},
427
- beforeBulkRemove: (paths, options) => {},
428
- afterBulkRemove: (paths, result) => {},
429
-
430
- // 认证事件
431
- authChange: (path, options) => {},
432
- },
433
- })
434
- ```
435
-
436
- ## 过滤和分页
437
-
438
- ### 文件过滤
439
-
440
- ```typescript
441
- const { data, total, filter } = await fs.list('/my-drive', {
442
- filter: {
443
- name: '.*\\.txt$', // 正则表达式匹配文件名
444
- size: '${size} > 1024', // 文件大小条件
445
- type: 'txt,md', // 文件类型
446
- mode: 'strict', // 匹配模式: 'normal' 或 'strict'
447
- },
448
- })
449
- ```
450
-
451
- ### 分页和排序
452
-
453
- ```typescript
454
- const result = await fs.list('/my-drive', {
455
- pagination: {
456
- page: 1,
457
- pageSize: 20,
458
- },
459
- sort: {
460
- field: 'name',
461
- order: 'asc',
24
+ await filebox.mount({
25
+ name: "/dav",
26
+ provider: "webdav",
27
+ rootPath: "/",
28
+ auth: {
29
+ url: "https://example.com/dav/",
30
+ username: "user",
31
+ password: "password",
462
32
  },
463
- })
464
- ```
465
-
466
- ## 加密支持
467
-
468
- FileBox 提供了文件加密功能:
469
-
470
- ```typescript
471
- import { crypt } from '@filebox/core'
472
-
473
- // 加密文件名
474
- const encrypted = crypt.encryptName('secret.txt', 'password')
475
-
476
- // 解密文件名
477
- const decrypted = crypt.decryptName(encrypted, 'password')
478
-
479
- // 文件内容加密/解密
480
- // 详见 src/crypt 模块
481
- ```
482
-
483
- ## 类型定义
484
-
485
- ```typescript
486
- // 挂载选项
487
- interface MountOptions {
488
- name: string // 挂载路径
489
- provider: string // 驱动名称
490
- auth?: any // 认证信息
491
- rootPath?: string // 根路径
492
- ttl?: number // 缓存时间(秒)
493
- readOnly?: boolean // 是否只读
494
- userConfig?: any // 用户配置
495
- }
496
-
497
- // 列表选项
498
- interface ListOptions {
499
- pagination?: {
500
- page: number
501
- pageSize: number
502
- }
503
- sort?: {
504
- field: string
505
- order: 'asc' | 'desc'
506
- }
507
- filter?: {
508
- name?: string
509
- size?: string
510
- type?: string
511
- mode?: 'normal' | 'strict'
512
- }
513
- }
514
- ```
515
-
516
- ## 构建格式
517
-
518
- 该包提供三种构建格式:
519
-
520
- - **ESM** (`dist/index.mjs`) - ES Modules
521
- - **CJS** (`dist/index.cjs`) - CommonJS
522
- - **UMD** (`dist/index.browser.js`) - 浏览器 Universal Module Definition
523
-
524
- ## 依赖
525
-
526
- - `bytes` - 字节格式化
527
- - `dayjs` - 日期处理
528
- - `debug` - 调试日志
529
- - `lru-cache` - LRU 缓存
530
- - `mime-types` - MIME 类型处理
531
- - `mitt` - 事件总线
532
- - `pako` - 压缩/解压
533
- - `path-browserify` - 浏览器路径处理
534
-
535
- ## 开发
33
+ });
536
34
 
537
- ```bash
538
- # 安装依赖
539
- pnpm install
540
-
541
- # 构建
542
- pnpm run build
543
-
544
- # 监听模式
545
- pnpm run watch
546
-
547
- # 测试
548
- pnpm test
35
+ const list = await filebox.list("/dav");
36
+ const stat = await filebox.stat("/dav/readme.txt");
549
37
  ```
550
38
 
551
- ## 发布
552
-
553
- 该包使用语义化版本控制。发布前会自动构建 dist 目录。
554
-
555
- ```bash
556
- # 发布补丁版本 (1.0.0 -> 1.0.1)
557
- npm run publish:patch
558
-
559
- # 发布次版本 (1.0.0 -> 1.1.0)
560
- npm run publish:minor
561
-
562
- # 发布主版本 (1.0.0 -> 2.0.0)
563
- npm run publish:major
564
- ```
565
-
566
- **注意事项:**
567
-
568
- - 只有 `dist` 目录和 `LICENSE` 会被发布到 npm,README.md 和源码不会被包含
569
- - 发布前会自动执行 `prepublishOnly` 钩子进行构建
570
- - 确保已登录 npm: `npm login`
571
- - 确保有发布权限: `npm whoami`
572
- - **作为 scoped package (@filebox/core),发布命令已自动添加 `--access public` 参数发布为公开包**
573
- - **需要启用双因素认证(2FA)** 或使用带有 bypass 2fa 权限的 access token
574
-
575
- ```bash
576
- # 启用 2FA
577
- npm profile enable-2fa auth-and-writes
578
-
579
- # 或使用 automation token (推荐用于 CI/CD)
580
- npm token create --type=automation
581
- ```
582
-
583
- ## 许可证
584
-
585
- MIT License - 详见 [LICENSE](./LICENSE) 文件
586
-
587
- ## 相关包
588
-
589
- - `@filebox/drivers` - 官方驱动集合
590
- - `@filebox/backend` - FileBox 后端服务
591
- - `@filebox/ui` - 文件管理器 UI 组件
592
-
593
- ## 贡献
39
+ 常用 API:
594
40
 
595
- 欢迎提交 Issue 和 Pull Request!
41
+ - `mount(options)`:挂载一个驱动到指定路径。
42
+ - `unmount(path)`:卸载已挂载的路径。
43
+ - `list(path)`:读取目录。
44
+ - `stat(path)`:读取文件或目录信息。
45
+ - `mkdir(path, name)`、`upload(path, file)`、`remove(path)`、`rename(path, name)`:常见文件操作。
596
46
 
597
- ## 作者
47
+ ## License
598
48
 
599
- ppnow <ppnows@gmail.com>
49
+ MIT