@aigne/afs 1.1.0 → 1.1.1
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 +9 -0
- package/lib/cjs/afs.d.ts +1 -2
- package/lib/cjs/afs.js +75 -63
- package/lib/dts/afs.d.ts +1 -2
- package/lib/esm/afs.d.ts +1 -2
- package/lib/esm/afs.js +75 -63
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.1](https://github.com/AIGNE-io/aigne-framework/compare/afs-v1.1.1-beta...afs-v1.1.1) (2025-10-31)
|
|
4
|
+
|
|
5
|
+
## [1.1.1-beta](https://github.com/AIGNE-io/aigne-framework/compare/afs-v1.1.0...afs-v1.1.1-beta) (2025-10-23)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **afs:** improve module path resolution and depth handling ([#659](https://github.com/AIGNE-io/aigne-framework/issues/659)) ([c609d4f](https://github.com/AIGNE-io/aigne-framework/commit/c609d4fc9614123afcf4b8f86b3382a613ace417))
|
|
11
|
+
|
|
3
12
|
## [1.1.0](https://github.com/AIGNE-io/aigne-framework/compare/afs-v1.1.0-beta...afs-v1.1.0) (2025-10-19)
|
|
4
13
|
|
|
5
14
|
|
package/lib/cjs/afs.d.ts
CHANGED
|
@@ -23,8 +23,6 @@ export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
|
23
23
|
list: AFSEntry[];
|
|
24
24
|
message?: string;
|
|
25
25
|
}>;
|
|
26
|
-
private findModules;
|
|
27
|
-
private isSubpath;
|
|
28
26
|
read(path: string): Promise<{
|
|
29
27
|
result?: AFSEntry;
|
|
30
28
|
message?: string;
|
|
@@ -37,4 +35,5 @@ export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
|
37
35
|
list: AFSEntry[];
|
|
38
36
|
message?: string;
|
|
39
37
|
}>;
|
|
38
|
+
private findModules;
|
|
40
39
|
}
|
package/lib/cjs/afs.js
CHANGED
|
@@ -5,7 +5,7 @@ const strict_event_emitter_1 = require("strict-event-emitter");
|
|
|
5
5
|
const ufo_1 = require("ufo");
|
|
6
6
|
const index_js_1 = require("./history/index.js");
|
|
7
7
|
const index_js_2 = require("./storage/index.js");
|
|
8
|
-
const DEFAULT_MAX_DEPTH =
|
|
8
|
+
const DEFAULT_MAX_DEPTH = 1;
|
|
9
9
|
class AFS extends strict_event_emitter_1.Emitter {
|
|
10
10
|
moduleId = "AFSRoot";
|
|
11
11
|
path = "/";
|
|
@@ -43,66 +43,52 @@ class AFS extends strict_event_emitter_1.Emitter {
|
|
|
43
43
|
throw new Error(`Invalid maxDepth: ${maxDepth}`);
|
|
44
44
|
const results = [];
|
|
45
45
|
const messages = [];
|
|
46
|
-
const
|
|
47
|
-
for (const
|
|
48
|
-
|
|
46
|
+
const matches = this.findModules(path, options);
|
|
47
|
+
for (const matched of matches) {
|
|
48
|
+
const moduleEntry = {
|
|
49
|
+
id: matched.module.moduleId,
|
|
50
|
+
path: matched.remainedModulePath,
|
|
51
|
+
summary: matched.module.description,
|
|
52
|
+
};
|
|
53
|
+
if (matched.maxDepth === 0) {
|
|
54
|
+
results.push(moduleEntry);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (!matched.module.list)
|
|
49
58
|
continue;
|
|
50
59
|
try {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
...entry
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
const { list, message } = await matched.module.list(matched.subpath, {
|
|
61
|
+
...options,
|
|
62
|
+
maxDepth: matched.maxDepth,
|
|
63
|
+
});
|
|
64
|
+
if (list.length) {
|
|
65
|
+
results.push(...list.map((entry) => ({
|
|
66
|
+
...entry,
|
|
67
|
+
path: (0, ufo_1.joinURL)(matched.module.path, entry.path),
|
|
68
|
+
})));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
results.push(moduleEntry);
|
|
72
|
+
}
|
|
59
73
|
if (message)
|
|
60
74
|
messages.push(message);
|
|
61
75
|
}
|
|
62
76
|
catch (error) {
|
|
63
|
-
console.error(`Error listing from module at ${
|
|
77
|
+
console.error(`Error listing from module at ${matched.module.path}`, error);
|
|
64
78
|
}
|
|
65
79
|
}
|
|
66
|
-
return { list: results, message: messages.join("; ") };
|
|
67
|
-
}
|
|
68
|
-
findModules(fullPath) {
|
|
69
|
-
const modules = [];
|
|
70
|
-
for (const [mountPath, module] of this.modules) {
|
|
71
|
-
const match = this.isSubpath(fullPath, mountPath);
|
|
72
|
-
if (!match)
|
|
73
|
-
continue;
|
|
74
|
-
modules.push({ ...match, module, mountPath });
|
|
75
|
-
}
|
|
76
|
-
return modules.sort((a, b) => b.matchedDepth - a.matchedDepth);
|
|
77
|
-
}
|
|
78
|
-
isSubpath(fullPath, mountPath) {
|
|
79
|
-
const fullPathSegments = fullPath.split("/").filter(Boolean);
|
|
80
|
-
const mountPathSegments = mountPath.split("/").filter(Boolean);
|
|
81
|
-
const fp = fullPathSegments.join("/");
|
|
82
|
-
const mp = mountPathSegments.join("/");
|
|
83
|
-
if (fp.startsWith(mp)) {
|
|
84
|
-
return {
|
|
85
|
-
matchedDepth: mountPathSegments.length,
|
|
86
|
-
subpath: (0, ufo_1.joinURL)("/", ...fullPathSegments.slice(mountPathSegments.length)),
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
else if (mp.startsWith(fp)) {
|
|
90
|
-
return {
|
|
91
|
-
matchedDepth: fullPathSegments.length,
|
|
92
|
-
subpath: "/",
|
|
93
|
-
};
|
|
94
|
-
}
|
|
80
|
+
return { list: results, message: messages.join("; ").trim() || undefined };
|
|
95
81
|
}
|
|
96
82
|
async read(path) {
|
|
97
|
-
const modules = this.findModules(path);
|
|
98
|
-
for (const { module,
|
|
83
|
+
const modules = this.findModules(path, { exactMatch: true });
|
|
84
|
+
for (const { module, subpath } of modules) {
|
|
99
85
|
const res = await module.read?.(subpath);
|
|
100
86
|
if (res?.result) {
|
|
101
87
|
return {
|
|
102
88
|
...res,
|
|
103
89
|
result: {
|
|
104
90
|
...res.result,
|
|
105
|
-
path: (0, ufo_1.joinURL)(
|
|
91
|
+
path: (0, ufo_1.joinURL)(module.path, res.result.path),
|
|
106
92
|
},
|
|
107
93
|
};
|
|
108
94
|
}
|
|
@@ -110,7 +96,7 @@ class AFS extends strict_event_emitter_1.Emitter {
|
|
|
110
96
|
return { result: undefined, message: "File not found" };
|
|
111
97
|
}
|
|
112
98
|
async write(path, content) {
|
|
113
|
-
const module = this.findModules(path)[0];
|
|
99
|
+
const module = this.findModules(path, { exactMatch: true })[0];
|
|
114
100
|
if (!module?.module.write)
|
|
115
101
|
throw new Error(`No module found for path: ${path}`);
|
|
116
102
|
const res = await module.module.write(module.subpath, content);
|
|
@@ -118,32 +104,58 @@ class AFS extends strict_event_emitter_1.Emitter {
|
|
|
118
104
|
...res,
|
|
119
105
|
result: {
|
|
120
106
|
...res.result,
|
|
121
|
-
path: (0, ufo_1.joinURL)(module.
|
|
107
|
+
path: (0, ufo_1.joinURL)(module.module.path, res.result.path),
|
|
122
108
|
},
|
|
123
109
|
};
|
|
124
110
|
}
|
|
125
111
|
async search(path, query, options) {
|
|
126
112
|
const results = [];
|
|
127
113
|
const messages = [];
|
|
128
|
-
for (const { module,
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
console.error(`Error searching in module at ${mountPath}`, error);
|
|
143
|
-
}
|
|
114
|
+
for (const { module, subpath } of this.findModules(path)) {
|
|
115
|
+
if (!module.search)
|
|
116
|
+
continue;
|
|
117
|
+
try {
|
|
118
|
+
const { list, message } = await module.search(subpath, query, options);
|
|
119
|
+
results.push(...list.map((entry) => ({
|
|
120
|
+
...entry,
|
|
121
|
+
path: (0, ufo_1.joinURL)(module.path, entry.path),
|
|
122
|
+
})));
|
|
123
|
+
if (message)
|
|
124
|
+
messages.push(message);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
console.error(`Error searching in module at ${module.path}`, error);
|
|
144
128
|
}
|
|
145
129
|
}
|
|
146
130
|
return { list: results, message: messages.join("; ") };
|
|
147
131
|
}
|
|
132
|
+
findModules(path, options) {
|
|
133
|
+
const maxDepth = Math.max(options?.maxDepth ?? DEFAULT_MAX_DEPTH, 1);
|
|
134
|
+
const matched = [];
|
|
135
|
+
for (const [modulePath, module] of this.modules) {
|
|
136
|
+
const pathSegments = path.split("/").filter(Boolean);
|
|
137
|
+
const modulePathSegments = modulePath.split("/").filter(Boolean);
|
|
138
|
+
let newMaxDepth;
|
|
139
|
+
let subpath;
|
|
140
|
+
let remainedModulePath;
|
|
141
|
+
if (!options?.exactMatch && modulePath.startsWith(path)) {
|
|
142
|
+
newMaxDepth = Math.max(0, maxDepth - (modulePathSegments.length - pathSegments.length));
|
|
143
|
+
subpath = "/";
|
|
144
|
+
remainedModulePath = (0, ufo_1.joinURL)("/", ...modulePathSegments.slice(pathSegments.length).slice(0, maxDepth));
|
|
145
|
+
}
|
|
146
|
+
else if (path.startsWith(modulePath)) {
|
|
147
|
+
newMaxDepth = maxDepth;
|
|
148
|
+
subpath = (0, ufo_1.joinURL)("/", ...pathSegments.slice(modulePathSegments.length));
|
|
149
|
+
remainedModulePath = "/";
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (newMaxDepth < 0)
|
|
155
|
+
continue;
|
|
156
|
+
matched.push({ module, maxDepth: newMaxDepth, subpath, remainedModulePath });
|
|
157
|
+
}
|
|
158
|
+
return matched;
|
|
159
|
+
}
|
|
148
160
|
}
|
|
149
161
|
exports.AFS = AFS;
|
package/lib/dts/afs.d.ts
CHANGED
|
@@ -23,8 +23,6 @@ export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
|
23
23
|
list: AFSEntry[];
|
|
24
24
|
message?: string;
|
|
25
25
|
}>;
|
|
26
|
-
private findModules;
|
|
27
|
-
private isSubpath;
|
|
28
26
|
read(path: string): Promise<{
|
|
29
27
|
result?: AFSEntry;
|
|
30
28
|
message?: string;
|
|
@@ -37,4 +35,5 @@ export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
|
37
35
|
list: AFSEntry[];
|
|
38
36
|
message?: string;
|
|
39
37
|
}>;
|
|
38
|
+
private findModules;
|
|
40
39
|
}
|
package/lib/esm/afs.d.ts
CHANGED
|
@@ -23,8 +23,6 @@ export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
|
23
23
|
list: AFSEntry[];
|
|
24
24
|
message?: string;
|
|
25
25
|
}>;
|
|
26
|
-
private findModules;
|
|
27
|
-
private isSubpath;
|
|
28
26
|
read(path: string): Promise<{
|
|
29
27
|
result?: AFSEntry;
|
|
30
28
|
message?: string;
|
|
@@ -37,4 +35,5 @@ export declare class AFS extends Emitter<AFSRootEvents> implements AFSRoot {
|
|
|
37
35
|
list: AFSEntry[];
|
|
38
36
|
message?: string;
|
|
39
37
|
}>;
|
|
38
|
+
private findModules;
|
|
40
39
|
}
|
package/lib/esm/afs.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Emitter } from "strict-event-emitter";
|
|
|
2
2
|
import { joinURL } from "ufo";
|
|
3
3
|
import { AFSHistory } from "./history/index.js";
|
|
4
4
|
import { SharedAFSStorage } from "./storage/index.js";
|
|
5
|
-
const DEFAULT_MAX_DEPTH =
|
|
5
|
+
const DEFAULT_MAX_DEPTH = 1;
|
|
6
6
|
export class AFS extends Emitter {
|
|
7
7
|
moduleId = "AFSRoot";
|
|
8
8
|
path = "/";
|
|
@@ -40,66 +40,52 @@ export class AFS extends Emitter {
|
|
|
40
40
|
throw new Error(`Invalid maxDepth: ${maxDepth}`);
|
|
41
41
|
const results = [];
|
|
42
42
|
const messages = [];
|
|
43
|
-
const
|
|
44
|
-
for (const
|
|
45
|
-
|
|
43
|
+
const matches = this.findModules(path, options);
|
|
44
|
+
for (const matched of matches) {
|
|
45
|
+
const moduleEntry = {
|
|
46
|
+
id: matched.module.moduleId,
|
|
47
|
+
path: matched.remainedModulePath,
|
|
48
|
+
summary: matched.module.description,
|
|
49
|
+
};
|
|
50
|
+
if (matched.maxDepth === 0) {
|
|
51
|
+
results.push(moduleEntry);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (!matched.module.list)
|
|
46
55
|
continue;
|
|
47
56
|
try {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
...entry
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
const { list, message } = await matched.module.list(matched.subpath, {
|
|
58
|
+
...options,
|
|
59
|
+
maxDepth: matched.maxDepth,
|
|
60
|
+
});
|
|
61
|
+
if (list.length) {
|
|
62
|
+
results.push(...list.map((entry) => ({
|
|
63
|
+
...entry,
|
|
64
|
+
path: joinURL(matched.module.path, entry.path),
|
|
65
|
+
})));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
results.push(moduleEntry);
|
|
69
|
+
}
|
|
56
70
|
if (message)
|
|
57
71
|
messages.push(message);
|
|
58
72
|
}
|
|
59
73
|
catch (error) {
|
|
60
|
-
console.error(`Error listing from module at ${
|
|
74
|
+
console.error(`Error listing from module at ${matched.module.path}`, error);
|
|
61
75
|
}
|
|
62
76
|
}
|
|
63
|
-
return { list: results, message: messages.join("; ") };
|
|
64
|
-
}
|
|
65
|
-
findModules(fullPath) {
|
|
66
|
-
const modules = [];
|
|
67
|
-
for (const [mountPath, module] of this.modules) {
|
|
68
|
-
const match = this.isSubpath(fullPath, mountPath);
|
|
69
|
-
if (!match)
|
|
70
|
-
continue;
|
|
71
|
-
modules.push({ ...match, module, mountPath });
|
|
72
|
-
}
|
|
73
|
-
return modules.sort((a, b) => b.matchedDepth - a.matchedDepth);
|
|
74
|
-
}
|
|
75
|
-
isSubpath(fullPath, mountPath) {
|
|
76
|
-
const fullPathSegments = fullPath.split("/").filter(Boolean);
|
|
77
|
-
const mountPathSegments = mountPath.split("/").filter(Boolean);
|
|
78
|
-
const fp = fullPathSegments.join("/");
|
|
79
|
-
const mp = mountPathSegments.join("/");
|
|
80
|
-
if (fp.startsWith(mp)) {
|
|
81
|
-
return {
|
|
82
|
-
matchedDepth: mountPathSegments.length,
|
|
83
|
-
subpath: joinURL("/", ...fullPathSegments.slice(mountPathSegments.length)),
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
else if (mp.startsWith(fp)) {
|
|
87
|
-
return {
|
|
88
|
-
matchedDepth: fullPathSegments.length,
|
|
89
|
-
subpath: "/",
|
|
90
|
-
};
|
|
91
|
-
}
|
|
77
|
+
return { list: results, message: messages.join("; ").trim() || undefined };
|
|
92
78
|
}
|
|
93
79
|
async read(path) {
|
|
94
|
-
const modules = this.findModules(path);
|
|
95
|
-
for (const { module,
|
|
80
|
+
const modules = this.findModules(path, { exactMatch: true });
|
|
81
|
+
for (const { module, subpath } of modules) {
|
|
96
82
|
const res = await module.read?.(subpath);
|
|
97
83
|
if (res?.result) {
|
|
98
84
|
return {
|
|
99
85
|
...res,
|
|
100
86
|
result: {
|
|
101
87
|
...res.result,
|
|
102
|
-
path: joinURL(
|
|
88
|
+
path: joinURL(module.path, res.result.path),
|
|
103
89
|
},
|
|
104
90
|
};
|
|
105
91
|
}
|
|
@@ -107,7 +93,7 @@ export class AFS extends Emitter {
|
|
|
107
93
|
return { result: undefined, message: "File not found" };
|
|
108
94
|
}
|
|
109
95
|
async write(path, content) {
|
|
110
|
-
const module = this.findModules(path)[0];
|
|
96
|
+
const module = this.findModules(path, { exactMatch: true })[0];
|
|
111
97
|
if (!module?.module.write)
|
|
112
98
|
throw new Error(`No module found for path: ${path}`);
|
|
113
99
|
const res = await module.module.write(module.subpath, content);
|
|
@@ -115,31 +101,57 @@ export class AFS extends Emitter {
|
|
|
115
101
|
...res,
|
|
116
102
|
result: {
|
|
117
103
|
...res.result,
|
|
118
|
-
path: joinURL(module.
|
|
104
|
+
path: joinURL(module.module.path, res.result.path),
|
|
119
105
|
},
|
|
120
106
|
};
|
|
121
107
|
}
|
|
122
108
|
async search(path, query, options) {
|
|
123
109
|
const results = [];
|
|
124
110
|
const messages = [];
|
|
125
|
-
for (const { module,
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
console.error(`Error searching in module at ${mountPath}`, error);
|
|
140
|
-
}
|
|
111
|
+
for (const { module, subpath } of this.findModules(path)) {
|
|
112
|
+
if (!module.search)
|
|
113
|
+
continue;
|
|
114
|
+
try {
|
|
115
|
+
const { list, message } = await module.search(subpath, query, options);
|
|
116
|
+
results.push(...list.map((entry) => ({
|
|
117
|
+
...entry,
|
|
118
|
+
path: joinURL(module.path, entry.path),
|
|
119
|
+
})));
|
|
120
|
+
if (message)
|
|
121
|
+
messages.push(message);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error(`Error searching in module at ${module.path}`, error);
|
|
141
125
|
}
|
|
142
126
|
}
|
|
143
127
|
return { list: results, message: messages.join("; ") };
|
|
144
128
|
}
|
|
129
|
+
findModules(path, options) {
|
|
130
|
+
const maxDepth = Math.max(options?.maxDepth ?? DEFAULT_MAX_DEPTH, 1);
|
|
131
|
+
const matched = [];
|
|
132
|
+
for (const [modulePath, module] of this.modules) {
|
|
133
|
+
const pathSegments = path.split("/").filter(Boolean);
|
|
134
|
+
const modulePathSegments = modulePath.split("/").filter(Boolean);
|
|
135
|
+
let newMaxDepth;
|
|
136
|
+
let subpath;
|
|
137
|
+
let remainedModulePath;
|
|
138
|
+
if (!options?.exactMatch && modulePath.startsWith(path)) {
|
|
139
|
+
newMaxDepth = Math.max(0, maxDepth - (modulePathSegments.length - pathSegments.length));
|
|
140
|
+
subpath = "/";
|
|
141
|
+
remainedModulePath = joinURL("/", ...modulePathSegments.slice(pathSegments.length).slice(0, maxDepth));
|
|
142
|
+
}
|
|
143
|
+
else if (path.startsWith(modulePath)) {
|
|
144
|
+
newMaxDepth = maxDepth;
|
|
145
|
+
subpath = joinURL("/", ...pathSegments.slice(modulePathSegments.length));
|
|
146
|
+
remainedModulePath = "/";
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (newMaxDepth < 0)
|
|
152
|
+
continue;
|
|
153
|
+
matched.push({ module, maxDepth: newMaxDepth, subpath, remainedModulePath });
|
|
154
|
+
}
|
|
155
|
+
return matched;
|
|
156
|
+
}
|
|
145
157
|
}
|
package/package.json
CHANGED