@aigne/afs 1.0.0 → 1.1.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/CHANGELOG.md +16 -0
- package/lib/cjs/afs.d.ts +16 -2
- package/lib/cjs/afs.js +35 -12
- package/lib/cjs/history/index.d.ts +8 -2
- package/lib/cjs/history/index.js +5 -3
- package/lib/cjs/type.d.ts +11 -2
- package/lib/dts/afs.d.ts +16 -2
- package/lib/dts/history/index.d.ts +8 -2
- package/lib/dts/type.d.ts +11 -2
- package/lib/esm/afs.d.ts +16 -2
- package/lib/esm/afs.js +35 -12
- package/lib/esm/history/index.d.ts +8 -2
- package/lib/esm/history/index.js +5 -3
- package/lib/esm/type.d.ts +11 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.0](https://github.com/AIGNE-io/aigne-framework/compare/afs-v1.1.0-beta...afs-v1.1.0) (2025-10-19)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Dependencies
|
|
7
|
+
|
|
8
|
+
* The following workspace dependencies were updated
|
|
9
|
+
* dependencies
|
|
10
|
+
* @aigne/sqlite bumped to 0.4.3
|
|
11
|
+
|
|
12
|
+
## [1.1.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/afs-v1.0.0...afs-v1.1.0-beta) (2025-10-11)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **afs:** add module system fs for afs ([#594](https://github.com/AIGNE-io/aigne-framework/issues/594)) ([83c7b65](https://github.com/AIGNE-io/aigne-framework/commit/83c7b6555d21c606a5005eb05f6686882fb8ffa3))
|
|
18
|
+
|
|
3
19
|
## 1.0.0 (2025-10-07)
|
|
4
20
|
|
|
5
21
|
|
package/lib/cjs/afs.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { AFSStorage } from "./storage/type.js";
|
|
|
4
4
|
import type { AFSEntry, AFSListOptions, AFSModule, AFSRoot, AFSRootEvents, AFSSearchOptions, AFSWriteEntryPayload } from "./type.js";
|
|
5
5
|
export interface AFSOptions {
|
|
6
6
|
storage?: SharedAFSStorage | SharedAFSStorageOptions;
|
|
7
|
+
modules?: AFSModule[];
|
|
7
8
|
}
|
|
8
9
|
export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
9
10
|
moduleId: string;
|
|
@@ -13,14 +14,27 @@ export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
|
13
14
|
storage(module: AFSModule): AFSStorage;
|
|
14
15
|
private modules;
|
|
15
16
|
use(module: AFSModule): this;
|
|
17
|
+
listModules(): Promise<{
|
|
18
|
+
moduleId: string;
|
|
19
|
+
path: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
}[]>;
|
|
16
22
|
list(path: string, options?: AFSListOptions): Promise<{
|
|
17
23
|
list: AFSEntry[];
|
|
24
|
+
message?: string;
|
|
18
25
|
}>;
|
|
19
26
|
private findModules;
|
|
20
27
|
private isSubpath;
|
|
21
|
-
read(path: string): Promise<
|
|
22
|
-
|
|
28
|
+
read(path: string): Promise<{
|
|
29
|
+
result?: AFSEntry;
|
|
30
|
+
message?: string;
|
|
31
|
+
}>;
|
|
32
|
+
write(path: string, content: AFSWriteEntryPayload): Promise<{
|
|
33
|
+
result: AFSEntry;
|
|
34
|
+
message?: string;
|
|
35
|
+
}>;
|
|
23
36
|
search(path: string, query: string, options?: AFSSearchOptions): Promise<{
|
|
24
37
|
list: AFSEntry[];
|
|
38
|
+
message?: string;
|
|
25
39
|
}>;
|
|
26
40
|
}
|
package/lib/cjs/afs.js
CHANGED
|
@@ -16,6 +16,9 @@ class AFS extends strict_event_emitter_1.Emitter {
|
|
|
16
16
|
? options.storage
|
|
17
17
|
: new index_js_2.SharedAFSStorage(options?.storage);
|
|
18
18
|
this.use(new index_js_1.AFSHistory());
|
|
19
|
+
for (const module of options?.modules ?? []) {
|
|
20
|
+
this.use(module);
|
|
21
|
+
}
|
|
19
22
|
}
|
|
20
23
|
_storage;
|
|
21
24
|
storage(module) {
|
|
@@ -27,11 +30,19 @@ class AFS extends strict_event_emitter_1.Emitter {
|
|
|
27
30
|
module.onMount?.(this);
|
|
28
31
|
return this;
|
|
29
32
|
}
|
|
33
|
+
async listModules() {
|
|
34
|
+
return Array.from(this.modules.entries()).map(([path, module]) => ({
|
|
35
|
+
moduleId: module.moduleId,
|
|
36
|
+
path,
|
|
37
|
+
description: module.description,
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
30
40
|
async list(path, options) {
|
|
31
41
|
const maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
32
42
|
if (!(maxDepth >= 0))
|
|
33
43
|
throw new Error(`Invalid maxDepth: ${maxDepth}`);
|
|
34
44
|
const results = [];
|
|
45
|
+
const messages = [];
|
|
35
46
|
const modules = this.findModules(path);
|
|
36
47
|
for (const { module, subpath, mountPath } of modules) {
|
|
37
48
|
if (!module.list)
|
|
@@ -40,17 +51,19 @@ class AFS extends strict_event_emitter_1.Emitter {
|
|
|
40
51
|
const newMaxDepth = maxDepth - mountPath.split("/").filter(Boolean).length;
|
|
41
52
|
if (newMaxDepth < 0)
|
|
42
53
|
continue;
|
|
43
|
-
const { list } = await module.list(subpath, { ...options, maxDepth: newMaxDepth });
|
|
54
|
+
const { list, message } = await module.list(subpath, { ...options, maxDepth: newMaxDepth });
|
|
44
55
|
results.push(...list.map((entry) => ({
|
|
45
56
|
...entry,
|
|
46
57
|
path: (0, ufo_1.joinURL)(mountPath, entry.path),
|
|
47
58
|
})));
|
|
59
|
+
if (message)
|
|
60
|
+
messages.push(message);
|
|
48
61
|
}
|
|
49
62
|
catch (error) {
|
|
50
63
|
console.error(`Error listing from module at ${mountPath}`, error);
|
|
51
64
|
}
|
|
52
65
|
}
|
|
53
|
-
return { list: results };
|
|
66
|
+
return { list: results, message: messages.join("; ") };
|
|
54
67
|
}
|
|
55
68
|
findModules(fullPath) {
|
|
56
69
|
const modules = [];
|
|
@@ -76,51 +89,61 @@ class AFS extends strict_event_emitter_1.Emitter {
|
|
|
76
89
|
else if (mp.startsWith(fp)) {
|
|
77
90
|
return {
|
|
78
91
|
matchedDepth: fullPathSegments.length,
|
|
79
|
-
subpath:
|
|
92
|
+
subpath: "/",
|
|
80
93
|
};
|
|
81
94
|
}
|
|
82
95
|
}
|
|
83
96
|
async read(path) {
|
|
84
97
|
const modules = this.findModules(path);
|
|
85
98
|
for (const { module, mountPath, subpath } of modules) {
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
99
|
+
const res = await module.read?.(subpath);
|
|
100
|
+
if (res?.result) {
|
|
88
101
|
return {
|
|
89
|
-
...
|
|
90
|
-
|
|
102
|
+
...res,
|
|
103
|
+
result: {
|
|
104
|
+
...res.result,
|
|
105
|
+
path: (0, ufo_1.joinURL)(mountPath, res.result.path),
|
|
106
|
+
},
|
|
91
107
|
};
|
|
92
108
|
}
|
|
93
109
|
}
|
|
110
|
+
return { result: undefined, message: "File not found" };
|
|
94
111
|
}
|
|
95
112
|
async write(path, content) {
|
|
96
113
|
const module = this.findModules(path)[0];
|
|
97
114
|
if (!module?.module.write)
|
|
98
115
|
throw new Error(`No module found for path: ${path}`);
|
|
99
|
-
const
|
|
116
|
+
const res = await module.module.write(module.subpath, content);
|
|
100
117
|
return {
|
|
101
|
-
...
|
|
102
|
-
|
|
118
|
+
...res,
|
|
119
|
+
result: {
|
|
120
|
+
...res.result,
|
|
121
|
+
path: (0, ufo_1.joinURL)(module.mountPath, res.result.path),
|
|
122
|
+
},
|
|
103
123
|
};
|
|
104
124
|
}
|
|
105
125
|
async search(path, query, options) {
|
|
106
126
|
const results = [];
|
|
127
|
+
const messages = [];
|
|
107
128
|
for (const { module, mountPath, subpath } of this.findModules(path)) {
|
|
108
129
|
if (mountPath.startsWith(path)) {
|
|
109
130
|
if (!module.search)
|
|
110
131
|
continue;
|
|
111
132
|
try {
|
|
112
|
-
const { list } = await module.search(subpath, query, options);
|
|
133
|
+
const { list, message } = await module.search(subpath, query, options);
|
|
113
134
|
results.push(...list.map((entry) => ({
|
|
114
135
|
...entry,
|
|
115
136
|
path: (0, ufo_1.joinURL)(mountPath, entry.path),
|
|
116
137
|
})));
|
|
138
|
+
if (message)
|
|
139
|
+
messages.push(message);
|
|
117
140
|
}
|
|
118
141
|
catch (error) {
|
|
119
142
|
console.error(`Error searching in module at ${mountPath}`, error);
|
|
120
143
|
}
|
|
121
144
|
}
|
|
122
145
|
}
|
|
123
|
-
return { list: results };
|
|
146
|
+
return { list: results, message: messages.join("; ") };
|
|
124
147
|
}
|
|
125
148
|
}
|
|
126
149
|
exports.AFS = AFS;
|
|
@@ -9,6 +9,12 @@ export declare class AFSHistory implements AFSModule {
|
|
|
9
9
|
list(path: string, options?: AFSListOptions): Promise<{
|
|
10
10
|
list: AFSEntry[];
|
|
11
11
|
}>;
|
|
12
|
-
read(path: string): Promise<
|
|
13
|
-
|
|
12
|
+
read(path: string): Promise<{
|
|
13
|
+
result: AFSEntry | undefined;
|
|
14
|
+
message?: string;
|
|
15
|
+
}>;
|
|
16
|
+
write(path: string, content: AFSWriteEntryPayload): Promise<{
|
|
17
|
+
result: AFSEntry;
|
|
18
|
+
message?: string;
|
|
19
|
+
}>;
|
|
14
20
|
}
|
package/lib/cjs/history/index.js
CHANGED
|
@@ -33,13 +33,15 @@ class AFSHistory {
|
|
|
33
33
|
async list(path, options) {
|
|
34
34
|
if (path !== "/")
|
|
35
35
|
return { list: [] };
|
|
36
|
-
return this.afs.storage(this).list(options);
|
|
36
|
+
return await this.afs.storage(this).list(options);
|
|
37
37
|
}
|
|
38
38
|
async read(path) {
|
|
39
|
-
|
|
39
|
+
const result = await this.afs.storage(this).read(path);
|
|
40
|
+
return { result };
|
|
40
41
|
}
|
|
41
42
|
async write(path, content) {
|
|
42
|
-
|
|
43
|
+
const result = await this.afs.storage(this).create({ ...content, path });
|
|
44
|
+
return { result };
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
exports.AFSHistory = AFSHistory;
|
package/lib/cjs/type.d.ts
CHANGED
|
@@ -18,14 +18,23 @@ export interface AFSWriteEntryPayload extends Omit<AFSEntry, "id" | "path"> {
|
|
|
18
18
|
export interface AFSModule {
|
|
19
19
|
readonly moduleId: string;
|
|
20
20
|
readonly path: string;
|
|
21
|
+
readonly description?: string;
|
|
21
22
|
onMount?(root: AFSRoot): void;
|
|
22
23
|
list?(path: string, options?: AFSListOptions): Promise<{
|
|
23
24
|
list: AFSEntry[];
|
|
25
|
+
message?: string;
|
|
26
|
+
}>;
|
|
27
|
+
read?(path: string): Promise<{
|
|
28
|
+
result?: AFSEntry;
|
|
29
|
+
message?: string;
|
|
30
|
+
}>;
|
|
31
|
+
write?(path: string, content: AFSWriteEntryPayload): Promise<{
|
|
32
|
+
result: AFSEntry;
|
|
33
|
+
message?: string;
|
|
24
34
|
}>;
|
|
25
|
-
read?(path: string): Promise<AFSEntry | undefined>;
|
|
26
|
-
write?(path: string, content: AFSWriteEntryPayload): Promise<AFSEntry>;
|
|
27
35
|
search?(path: string, query: string, options?: AFSSearchOptions): Promise<{
|
|
28
36
|
list: AFSEntry[];
|
|
37
|
+
message?: string;
|
|
29
38
|
}>;
|
|
30
39
|
}
|
|
31
40
|
export type AFSRootEvents = {
|
package/lib/dts/afs.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { AFSStorage } from "./storage/type.js";
|
|
|
4
4
|
import type { AFSEntry, AFSListOptions, AFSModule, AFSRoot, AFSRootEvents, AFSSearchOptions, AFSWriteEntryPayload } from "./type.js";
|
|
5
5
|
export interface AFSOptions {
|
|
6
6
|
storage?: SharedAFSStorage | SharedAFSStorageOptions;
|
|
7
|
+
modules?: AFSModule[];
|
|
7
8
|
}
|
|
8
9
|
export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
9
10
|
moduleId: string;
|
|
@@ -13,14 +14,27 @@ export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
|
13
14
|
storage(module: AFSModule): AFSStorage;
|
|
14
15
|
private modules;
|
|
15
16
|
use(module: AFSModule): this;
|
|
17
|
+
listModules(): Promise<{
|
|
18
|
+
moduleId: string;
|
|
19
|
+
path: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
}[]>;
|
|
16
22
|
list(path: string, options?: AFSListOptions): Promise<{
|
|
17
23
|
list: AFSEntry[];
|
|
24
|
+
message?: string;
|
|
18
25
|
}>;
|
|
19
26
|
private findModules;
|
|
20
27
|
private isSubpath;
|
|
21
|
-
read(path: string): Promise<
|
|
22
|
-
|
|
28
|
+
read(path: string): Promise<{
|
|
29
|
+
result?: AFSEntry;
|
|
30
|
+
message?: string;
|
|
31
|
+
}>;
|
|
32
|
+
write(path: string, content: AFSWriteEntryPayload): Promise<{
|
|
33
|
+
result: AFSEntry;
|
|
34
|
+
message?: string;
|
|
35
|
+
}>;
|
|
23
36
|
search(path: string, query: string, options?: AFSSearchOptions): Promise<{
|
|
24
37
|
list: AFSEntry[];
|
|
38
|
+
message?: string;
|
|
25
39
|
}>;
|
|
26
40
|
}
|
|
@@ -9,6 +9,12 @@ export declare class AFSHistory implements AFSModule {
|
|
|
9
9
|
list(path: string, options?: AFSListOptions): Promise<{
|
|
10
10
|
list: AFSEntry[];
|
|
11
11
|
}>;
|
|
12
|
-
read(path: string): Promise<
|
|
13
|
-
|
|
12
|
+
read(path: string): Promise<{
|
|
13
|
+
result: AFSEntry | undefined;
|
|
14
|
+
message?: string;
|
|
15
|
+
}>;
|
|
16
|
+
write(path: string, content: AFSWriteEntryPayload): Promise<{
|
|
17
|
+
result: AFSEntry;
|
|
18
|
+
message?: string;
|
|
19
|
+
}>;
|
|
14
20
|
}
|
package/lib/dts/type.d.ts
CHANGED
|
@@ -18,14 +18,23 @@ export interface AFSWriteEntryPayload extends Omit<AFSEntry, "id" | "path"> {
|
|
|
18
18
|
export interface AFSModule {
|
|
19
19
|
readonly moduleId: string;
|
|
20
20
|
readonly path: string;
|
|
21
|
+
readonly description?: string;
|
|
21
22
|
onMount?(root: AFSRoot): void;
|
|
22
23
|
list?(path: string, options?: AFSListOptions): Promise<{
|
|
23
24
|
list: AFSEntry[];
|
|
25
|
+
message?: string;
|
|
26
|
+
}>;
|
|
27
|
+
read?(path: string): Promise<{
|
|
28
|
+
result?: AFSEntry;
|
|
29
|
+
message?: string;
|
|
30
|
+
}>;
|
|
31
|
+
write?(path: string, content: AFSWriteEntryPayload): Promise<{
|
|
32
|
+
result: AFSEntry;
|
|
33
|
+
message?: string;
|
|
24
34
|
}>;
|
|
25
|
-
read?(path: string): Promise<AFSEntry | undefined>;
|
|
26
|
-
write?(path: string, content: AFSWriteEntryPayload): Promise<AFSEntry>;
|
|
27
35
|
search?(path: string, query: string, options?: AFSSearchOptions): Promise<{
|
|
28
36
|
list: AFSEntry[];
|
|
37
|
+
message?: string;
|
|
29
38
|
}>;
|
|
30
39
|
}
|
|
31
40
|
export type AFSRootEvents = {
|
package/lib/esm/afs.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { AFSStorage } from "./storage/type.js";
|
|
|
4
4
|
import type { AFSEntry, AFSListOptions, AFSModule, AFSRoot, AFSRootEvents, AFSSearchOptions, AFSWriteEntryPayload } from "./type.js";
|
|
5
5
|
export interface AFSOptions {
|
|
6
6
|
storage?: SharedAFSStorage | SharedAFSStorageOptions;
|
|
7
|
+
modules?: AFSModule[];
|
|
7
8
|
}
|
|
8
9
|
export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
9
10
|
moduleId: string;
|
|
@@ -13,14 +14,27 @@ export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
|
13
14
|
storage(module: AFSModule): AFSStorage;
|
|
14
15
|
private modules;
|
|
15
16
|
use(module: AFSModule): this;
|
|
17
|
+
listModules(): Promise<{
|
|
18
|
+
moduleId: string;
|
|
19
|
+
path: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
}[]>;
|
|
16
22
|
list(path: string, options?: AFSListOptions): Promise<{
|
|
17
23
|
list: AFSEntry[];
|
|
24
|
+
message?: string;
|
|
18
25
|
}>;
|
|
19
26
|
private findModules;
|
|
20
27
|
private isSubpath;
|
|
21
|
-
read(path: string): Promise<
|
|
22
|
-
|
|
28
|
+
read(path: string): Promise<{
|
|
29
|
+
result?: AFSEntry;
|
|
30
|
+
message?: string;
|
|
31
|
+
}>;
|
|
32
|
+
write(path: string, content: AFSWriteEntryPayload): Promise<{
|
|
33
|
+
result: AFSEntry;
|
|
34
|
+
message?: string;
|
|
35
|
+
}>;
|
|
23
36
|
search(path: string, query: string, options?: AFSSearchOptions): Promise<{
|
|
24
37
|
list: AFSEntry[];
|
|
38
|
+
message?: string;
|
|
25
39
|
}>;
|
|
26
40
|
}
|
package/lib/esm/afs.js
CHANGED
|
@@ -13,6 +13,9 @@ export class AFS extends Emitter {
|
|
|
13
13
|
? options.storage
|
|
14
14
|
: new SharedAFSStorage(options?.storage);
|
|
15
15
|
this.use(new AFSHistory());
|
|
16
|
+
for (const module of options?.modules ?? []) {
|
|
17
|
+
this.use(module);
|
|
18
|
+
}
|
|
16
19
|
}
|
|
17
20
|
_storage;
|
|
18
21
|
storage(module) {
|
|
@@ -24,11 +27,19 @@ export class AFS extends Emitter {
|
|
|
24
27
|
module.onMount?.(this);
|
|
25
28
|
return this;
|
|
26
29
|
}
|
|
30
|
+
async listModules() {
|
|
31
|
+
return Array.from(this.modules.entries()).map(([path, module]) => ({
|
|
32
|
+
moduleId: module.moduleId,
|
|
33
|
+
path,
|
|
34
|
+
description: module.description,
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
27
37
|
async list(path, options) {
|
|
28
38
|
const maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
29
39
|
if (!(maxDepth >= 0))
|
|
30
40
|
throw new Error(`Invalid maxDepth: ${maxDepth}`);
|
|
31
41
|
const results = [];
|
|
42
|
+
const messages = [];
|
|
32
43
|
const modules = this.findModules(path);
|
|
33
44
|
for (const { module, subpath, mountPath } of modules) {
|
|
34
45
|
if (!module.list)
|
|
@@ -37,17 +48,19 @@ export class AFS extends Emitter {
|
|
|
37
48
|
const newMaxDepth = maxDepth - mountPath.split("/").filter(Boolean).length;
|
|
38
49
|
if (newMaxDepth < 0)
|
|
39
50
|
continue;
|
|
40
|
-
const { list } = await module.list(subpath, { ...options, maxDepth: newMaxDepth });
|
|
51
|
+
const { list, message } = await module.list(subpath, { ...options, maxDepth: newMaxDepth });
|
|
41
52
|
results.push(...list.map((entry) => ({
|
|
42
53
|
...entry,
|
|
43
54
|
path: joinURL(mountPath, entry.path),
|
|
44
55
|
})));
|
|
56
|
+
if (message)
|
|
57
|
+
messages.push(message);
|
|
45
58
|
}
|
|
46
59
|
catch (error) {
|
|
47
60
|
console.error(`Error listing from module at ${mountPath}`, error);
|
|
48
61
|
}
|
|
49
62
|
}
|
|
50
|
-
return { list: results };
|
|
63
|
+
return { list: results, message: messages.join("; ") };
|
|
51
64
|
}
|
|
52
65
|
findModules(fullPath) {
|
|
53
66
|
const modules = [];
|
|
@@ -73,50 +86,60 @@ export class AFS extends Emitter {
|
|
|
73
86
|
else if (mp.startsWith(fp)) {
|
|
74
87
|
return {
|
|
75
88
|
matchedDepth: fullPathSegments.length,
|
|
76
|
-
subpath:
|
|
89
|
+
subpath: "/",
|
|
77
90
|
};
|
|
78
91
|
}
|
|
79
92
|
}
|
|
80
93
|
async read(path) {
|
|
81
94
|
const modules = this.findModules(path);
|
|
82
95
|
for (const { module, mountPath, subpath } of modules) {
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
96
|
+
const res = await module.read?.(subpath);
|
|
97
|
+
if (res?.result) {
|
|
85
98
|
return {
|
|
86
|
-
...
|
|
87
|
-
|
|
99
|
+
...res,
|
|
100
|
+
result: {
|
|
101
|
+
...res.result,
|
|
102
|
+
path: joinURL(mountPath, res.result.path),
|
|
103
|
+
},
|
|
88
104
|
};
|
|
89
105
|
}
|
|
90
106
|
}
|
|
107
|
+
return { result: undefined, message: "File not found" };
|
|
91
108
|
}
|
|
92
109
|
async write(path, content) {
|
|
93
110
|
const module = this.findModules(path)[0];
|
|
94
111
|
if (!module?.module.write)
|
|
95
112
|
throw new Error(`No module found for path: ${path}`);
|
|
96
|
-
const
|
|
113
|
+
const res = await module.module.write(module.subpath, content);
|
|
97
114
|
return {
|
|
98
|
-
...
|
|
99
|
-
|
|
115
|
+
...res,
|
|
116
|
+
result: {
|
|
117
|
+
...res.result,
|
|
118
|
+
path: joinURL(module.mountPath, res.result.path),
|
|
119
|
+
},
|
|
100
120
|
};
|
|
101
121
|
}
|
|
102
122
|
async search(path, query, options) {
|
|
103
123
|
const results = [];
|
|
124
|
+
const messages = [];
|
|
104
125
|
for (const { module, mountPath, subpath } of this.findModules(path)) {
|
|
105
126
|
if (mountPath.startsWith(path)) {
|
|
106
127
|
if (!module.search)
|
|
107
128
|
continue;
|
|
108
129
|
try {
|
|
109
|
-
const { list } = await module.search(subpath, query, options);
|
|
130
|
+
const { list, message } = await module.search(subpath, query, options);
|
|
110
131
|
results.push(...list.map((entry) => ({
|
|
111
132
|
...entry,
|
|
112
133
|
path: joinURL(mountPath, entry.path),
|
|
113
134
|
})));
|
|
135
|
+
if (message)
|
|
136
|
+
messages.push(message);
|
|
114
137
|
}
|
|
115
138
|
catch (error) {
|
|
116
139
|
console.error(`Error searching in module at ${mountPath}`, error);
|
|
117
140
|
}
|
|
118
141
|
}
|
|
119
142
|
}
|
|
120
|
-
return { list: results };
|
|
143
|
+
return { list: results, message: messages.join("; ") };
|
|
121
144
|
}
|
|
122
145
|
}
|
|
@@ -9,6 +9,12 @@ export declare class AFSHistory implements AFSModule {
|
|
|
9
9
|
list(path: string, options?: AFSListOptions): Promise<{
|
|
10
10
|
list: AFSEntry[];
|
|
11
11
|
}>;
|
|
12
|
-
read(path: string): Promise<
|
|
13
|
-
|
|
12
|
+
read(path: string): Promise<{
|
|
13
|
+
result: AFSEntry | undefined;
|
|
14
|
+
message?: string;
|
|
15
|
+
}>;
|
|
16
|
+
write(path: string, content: AFSWriteEntryPayload): Promise<{
|
|
17
|
+
result: AFSEntry;
|
|
18
|
+
message?: string;
|
|
19
|
+
}>;
|
|
14
20
|
}
|
package/lib/esm/history/index.js
CHANGED
|
@@ -30,12 +30,14 @@ export class AFSHistory {
|
|
|
30
30
|
async list(path, options) {
|
|
31
31
|
if (path !== "/")
|
|
32
32
|
return { list: [] };
|
|
33
|
-
return this.afs.storage(this).list(options);
|
|
33
|
+
return await this.afs.storage(this).list(options);
|
|
34
34
|
}
|
|
35
35
|
async read(path) {
|
|
36
|
-
|
|
36
|
+
const result = await this.afs.storage(this).read(path);
|
|
37
|
+
return { result };
|
|
37
38
|
}
|
|
38
39
|
async write(path, content) {
|
|
39
|
-
|
|
40
|
+
const result = await this.afs.storage(this).create({ ...content, path });
|
|
41
|
+
return { result };
|
|
40
42
|
}
|
|
41
43
|
}
|
package/lib/esm/type.d.ts
CHANGED
|
@@ -18,14 +18,23 @@ export interface AFSWriteEntryPayload extends Omit<AFSEntry, "id" | "path"> {
|
|
|
18
18
|
export interface AFSModule {
|
|
19
19
|
readonly moduleId: string;
|
|
20
20
|
readonly path: string;
|
|
21
|
+
readonly description?: string;
|
|
21
22
|
onMount?(root: AFSRoot): void;
|
|
22
23
|
list?(path: string, options?: AFSListOptions): Promise<{
|
|
23
24
|
list: AFSEntry[];
|
|
25
|
+
message?: string;
|
|
26
|
+
}>;
|
|
27
|
+
read?(path: string): Promise<{
|
|
28
|
+
result?: AFSEntry;
|
|
29
|
+
message?: string;
|
|
30
|
+
}>;
|
|
31
|
+
write?(path: string, content: AFSWriteEntryPayload): Promise<{
|
|
32
|
+
result: AFSEntry;
|
|
33
|
+
message?: string;
|
|
24
34
|
}>;
|
|
25
|
-
read?(path: string): Promise<AFSEntry | undefined>;
|
|
26
|
-
write?(path: string, content: AFSWriteEntryPayload): Promise<AFSEntry>;
|
|
27
35
|
search?(path: string, query: string, options?: AFSSearchOptions): Promise<{
|
|
28
36
|
list: AFSEntry[];
|
|
37
|
+
message?: string;
|
|
29
38
|
}>;
|
|
30
39
|
}
|
|
31
40
|
export type AFSRootEvents = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/afs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "AIGNE File System (AFS) is a virtual file system that supports various storage backends and provides a unified API for file operations.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@aigne/uuid": "^13.0.1",
|
|
51
51
|
"strict-event-emitter": "^0.5.1",
|
|
52
52
|
"ufo": "^1.6.1",
|
|
53
|
-
"@aigne/sqlite": "^0.4.3
|
|
53
|
+
"@aigne/sqlite": "^0.4.3"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/bun": "^1.2.22",
|