@aigne/afs-toml 1.11.0-beta.6 → 1.11.0-beta.8
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/dist/index.cjs +169 -20
- package/dist/index.d.cts +31 -25
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +31 -25
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +168 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1
2
|
const require_decorate = require('./_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs');
|
|
3
|
+
let node_fs = require("node:fs");
|
|
2
4
|
let node_fs_promises = require("node:fs/promises");
|
|
3
5
|
let node_path = require("node:path");
|
|
4
6
|
let _aigne_afs = require("@aigne/afs");
|
|
@@ -32,10 +34,20 @@ var AFSTOML = class AFSTOML extends _aigne_afs_provider.AFSBaseProvider {
|
|
|
32
34
|
static schema() {
|
|
33
35
|
return afsTOMLOptionsSchema;
|
|
34
36
|
}
|
|
35
|
-
static
|
|
37
|
+
static manifest() {
|
|
38
|
+
return {
|
|
39
|
+
name: "toml",
|
|
40
|
+
description: "Mount a TOML file as a virtual filesystem",
|
|
41
|
+
uriTemplate: "toml://{localPath+}",
|
|
42
|
+
category: "structured-data",
|
|
43
|
+
schema: zod.z.object({ localPath: zod.z.string() }),
|
|
44
|
+
tags: ["toml", "structured-data"]
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
static async load({ basePath, config } = {}) {
|
|
36
48
|
return new AFSTOML({
|
|
37
|
-
...await AFSTOML.schema().parseAsync(
|
|
38
|
-
cwd:
|
|
49
|
+
...await AFSTOML.schema().parseAsync(config),
|
|
50
|
+
cwd: basePath
|
|
39
51
|
});
|
|
40
52
|
}
|
|
41
53
|
name;
|
|
@@ -47,11 +59,16 @@ var AFSTOML = class AFSTOML extends _aigne_afs_provider.AFSBaseProvider {
|
|
|
47
59
|
constructor(options) {
|
|
48
60
|
super();
|
|
49
61
|
this.options = options;
|
|
62
|
+
if (options.localPath && !options.tomlPath) options.tomlPath = options.localPath;
|
|
50
63
|
(0, _aigne_afs_utils_zod.zodParse)(afsTOMLOptionsSchema, options);
|
|
51
64
|
let tomlPath;
|
|
52
65
|
tomlPath = options.tomlPath.replaceAll("${CWD}", process.cwd());
|
|
53
66
|
if (tomlPath.startsWith("~/")) tomlPath = (0, node_path.join)(process.env.HOME || "", tomlPath.slice(2));
|
|
54
67
|
if (!(0, node_path.isAbsolute)(tomlPath)) tomlPath = (0, node_path.join)(options.cwd || process.cwd(), tomlPath);
|
|
68
|
+
if (!(0, node_fs.existsSync)(tomlPath)) {
|
|
69
|
+
(0, node_fs.mkdirSync)((0, node_path.dirname)(tomlPath), { recursive: true });
|
|
70
|
+
(0, node_fs.writeFileSync)(tomlPath, "", "utf8");
|
|
71
|
+
}
|
|
55
72
|
let name = (0, node_path.basename)(tomlPath);
|
|
56
73
|
if (name.endsWith(".toml")) name = name.slice(0, -5);
|
|
57
74
|
this.name = options.name || name || "toml";
|
|
@@ -62,7 +79,7 @@ var AFSTOML = class AFSTOML extends _aigne_afs_provider.AFSBaseProvider {
|
|
|
62
79
|
/**
|
|
63
80
|
* Read metadata for a TOML node via /.meta or /path/.meta
|
|
64
81
|
* Returns stored metadata merged with computed type information
|
|
65
|
-
* Note: Meta is read-only. To write metadata, use write() with payload.
|
|
82
|
+
* Note: Meta is read-only. To write metadata, use write() with payload.meta.
|
|
66
83
|
*/
|
|
67
84
|
async readMetaHandler(ctx) {
|
|
68
85
|
await this.ensureLoaded();
|
|
@@ -91,12 +108,15 @@ var AFSTOML = class AFSTOML extends _aigne_afs_provider.AFSBaseProvider {
|
|
|
91
108
|
if (this.fileStats.birthtime) computedMeta.created = this.fileStats.birthtime;
|
|
92
109
|
if (this.fileStats.mtime) computedMeta.modified = this.fileStats.mtime;
|
|
93
110
|
return this.buildEntry((0, ufo.joinURL)(nodePath, ".meta"), {
|
|
94
|
-
|
|
111
|
+
meta: storedMeta,
|
|
95
112
|
content: computedMeta,
|
|
96
113
|
createdAt: this.fileStats.birthtime,
|
|
97
114
|
updatedAt: this.fileStats.mtime
|
|
98
115
|
});
|
|
99
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Note: list() returns only children, never the path itself (per new semantics)
|
|
119
|
+
*/
|
|
100
120
|
async listHandler(ctx) {
|
|
101
121
|
await this.ensureLoaded();
|
|
102
122
|
const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : "/";
|
|
@@ -107,12 +127,15 @@ var AFSTOML = class AFSTOML extends _aigne_afs_provider.AFSBaseProvider {
|
|
|
107
127
|
const segments = this.getPathSegments(normalizedPath);
|
|
108
128
|
const value = this.getValueAtPath(this.tomlData, segments);
|
|
109
129
|
if (value === void 0) throw new _aigne_afs.AFSNotFoundError(normalizedPath);
|
|
130
|
+
if (maxDepth === 0) return { data: [] };
|
|
131
|
+
if (!this.isDirectoryValue(value)) return { data: [] };
|
|
110
132
|
const entries = [];
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
133
|
+
const rootChildren = this.getChildren(value);
|
|
134
|
+
const queue = (rootChildren.length > maxChildren ? rootChildren.slice(0, maxChildren) : rootChildren).map((child) => ({
|
|
135
|
+
path: normalizedPath === "/" ? `/${child.key}` : `${normalizedPath}/${child.key}`,
|
|
136
|
+
value: child.value,
|
|
137
|
+
depth: 1
|
|
138
|
+
}));
|
|
116
139
|
while (queue.length > 0) {
|
|
117
140
|
const item = queue.shift();
|
|
118
141
|
if (!item) break;
|
|
@@ -157,10 +180,10 @@ var AFSTOML = class AFSTOML extends _aigne_afs_provider.AFSBaseProvider {
|
|
|
157
180
|
const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : "/";
|
|
158
181
|
const segments = this.getPathSegments(normalizedPath);
|
|
159
182
|
if (payload.content !== void 0) this.setValueAtPath(this.tomlData, segments, payload.content);
|
|
160
|
-
if (payload.
|
|
183
|
+
if (payload.meta !== void 0 && typeof payload.meta === "object") {
|
|
161
184
|
const finalMeta = {
|
|
162
185
|
...this.loadMeta(normalizedPath) || {},
|
|
163
|
-
...payload.
|
|
186
|
+
...payload.meta
|
|
164
187
|
};
|
|
165
188
|
this.saveMeta(normalizedPath, finalMeta);
|
|
166
189
|
}
|
|
@@ -176,7 +199,7 @@ var AFSTOML = class AFSTOML extends _aigne_afs_provider.AFSBaseProvider {
|
|
|
176
199
|
summary: payload.summary,
|
|
177
200
|
createdAt: this.fileStats.birthtime,
|
|
178
201
|
updatedAt: this.fileStats.mtime,
|
|
179
|
-
|
|
202
|
+
meta: {
|
|
180
203
|
...storedMeta,
|
|
181
204
|
childrenCount: isDir ? children.length : void 0
|
|
182
205
|
},
|
|
@@ -252,15 +275,133 @@ var AFSTOML = class AFSTOML extends _aigne_afs_provider.AFSBaseProvider {
|
|
|
252
275
|
if (value === void 0) throw new _aigne_afs.AFSNotFoundError(normalizedPath);
|
|
253
276
|
const isDir = this.isDirectoryValue(value);
|
|
254
277
|
const children = isDir ? this.getChildren(value) : [];
|
|
255
|
-
const meta = this.loadMeta(normalizedPath);
|
|
278
|
+
const meta = { ...this.loadMeta(normalizedPath) };
|
|
279
|
+
if (isDir) meta.childrenCount = children.length;
|
|
256
280
|
return { data: {
|
|
281
|
+
id: segments.length > 0 ? segments[segments.length - 1] : "/",
|
|
257
282
|
path: normalizedPath,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
meta: meta ?? void 0
|
|
283
|
+
createdAt: this.fileStats.birthtime,
|
|
284
|
+
updatedAt: this.fileStats.mtime,
|
|
285
|
+
meta
|
|
262
286
|
} };
|
|
263
287
|
}
|
|
288
|
+
async readCapabilitiesHandler(_ctx) {
|
|
289
|
+
await this.ensureLoaded();
|
|
290
|
+
const operations = [
|
|
291
|
+
"list",
|
|
292
|
+
"read",
|
|
293
|
+
"stat",
|
|
294
|
+
"explain",
|
|
295
|
+
"search"
|
|
296
|
+
];
|
|
297
|
+
if (this.accessMode === "readwrite") operations.push("write", "delete", "rename");
|
|
298
|
+
return {
|
|
299
|
+
id: "/.meta/.capabilities",
|
|
300
|
+
path: "/.meta/.capabilities",
|
|
301
|
+
content: {
|
|
302
|
+
schemaVersion: 1,
|
|
303
|
+
provider: this.name,
|
|
304
|
+
description: this.description || "TOML virtual filesystem",
|
|
305
|
+
tools: [],
|
|
306
|
+
actions: [],
|
|
307
|
+
operations: this.getOperationsDeclaration()
|
|
308
|
+
},
|
|
309
|
+
meta: {
|
|
310
|
+
kind: "afs:capabilities",
|
|
311
|
+
operations
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
async explainHandler(ctx) {
|
|
316
|
+
await this.ensureLoaded();
|
|
317
|
+
const normalizedPath = (0, ufo.joinURL)("/", ctx.params.path ?? "");
|
|
318
|
+
const format = ctx.options?.format || "markdown";
|
|
319
|
+
const segments = this.getPathSegments(normalizedPath);
|
|
320
|
+
const value = this.getValueAtPath(this.tomlData, segments);
|
|
321
|
+
if (value === void 0) throw new _aigne_afs.AFSNotFoundError(normalizedPath);
|
|
322
|
+
const nodeName = segments.length > 0 ? segments[segments.length - 1] : "/";
|
|
323
|
+
const isDir = this.isDirectoryValue(value);
|
|
324
|
+
const storedMeta = this.loadMeta(normalizedPath);
|
|
325
|
+
const lines = [];
|
|
326
|
+
if (format === "markdown") {
|
|
327
|
+
lines.push(`# ${nodeName}`);
|
|
328
|
+
lines.push("");
|
|
329
|
+
lines.push(`**Path:** \`${normalizedPath}\``);
|
|
330
|
+
lines.push(`**Format:** TOML`);
|
|
331
|
+
if (normalizedPath === "/") {
|
|
332
|
+
const children = this.getChildren(this.tomlData);
|
|
333
|
+
lines.push(`**Top-level keys:** ${children.length}`);
|
|
334
|
+
if (children.length > 0) {
|
|
335
|
+
lines.push("");
|
|
336
|
+
lines.push("## Keys");
|
|
337
|
+
lines.push("");
|
|
338
|
+
for (const child of children.slice(0, 30)) {
|
|
339
|
+
const childType = this.describeType(child.value);
|
|
340
|
+
lines.push(`- \`${child.key}\` — ${childType}`);
|
|
341
|
+
}
|
|
342
|
+
if (children.length > 30) lines.push(`- ... and ${children.length - 30} more`);
|
|
343
|
+
}
|
|
344
|
+
} else if (Array.isArray(value)) {
|
|
345
|
+
lines.push(`**Type:** array of tables`);
|
|
346
|
+
lines.push(`**Elements:** ${value.length}`);
|
|
347
|
+
if (value.length > 0) {
|
|
348
|
+
const elementType = this.describeType(value[0]);
|
|
349
|
+
lines.push(`**Element type:** ${elementType}`);
|
|
350
|
+
}
|
|
351
|
+
} else if (typeof value === "object" && value !== null) {
|
|
352
|
+
const children = this.getChildren(value);
|
|
353
|
+
lines.push(`**Type:** table`);
|
|
354
|
+
lines.push(`**Keys:** ${children.length}`);
|
|
355
|
+
if (children.length > 0) {
|
|
356
|
+
lines.push("");
|
|
357
|
+
lines.push("## Keys");
|
|
358
|
+
lines.push("");
|
|
359
|
+
for (const child of children.slice(0, 30)) {
|
|
360
|
+
const childType = this.describeType(child.value);
|
|
361
|
+
lines.push(`- \`${child.key}\` — ${childType}`);
|
|
362
|
+
}
|
|
363
|
+
if (children.length > 30) lines.push(`- ... and ${children.length - 30} more`);
|
|
364
|
+
}
|
|
365
|
+
} else {
|
|
366
|
+
const valType = value === null ? "null" : typeof value;
|
|
367
|
+
lines.push(`**Type:** ${valType}`);
|
|
368
|
+
const valStr = String(value);
|
|
369
|
+
if (valStr.length > 200) lines.push(`**Value:** ${valStr.slice(0, 200)}...`);
|
|
370
|
+
else lines.push(`**Value:** ${valStr}`);
|
|
371
|
+
}
|
|
372
|
+
if (storedMeta) {
|
|
373
|
+
lines.push("");
|
|
374
|
+
lines.push("## Metadata");
|
|
375
|
+
for (const [key, val] of Object.entries(storedMeta)) lines.push(`- **${key}:** ${JSON.stringify(val)}`);
|
|
376
|
+
}
|
|
377
|
+
} else {
|
|
378
|
+
lines.push(`${nodeName} (${isDir ? "table" : "value"})`);
|
|
379
|
+
lines.push(`Path: ${normalizedPath}`);
|
|
380
|
+
lines.push(`Format: TOML`);
|
|
381
|
+
if (isDir) {
|
|
382
|
+
const children = this.getChildren(value);
|
|
383
|
+
lines.push(`Children: ${children.length}`);
|
|
384
|
+
} else {
|
|
385
|
+
const valStr = String(value);
|
|
386
|
+
lines.push(`Type: ${value === null ? "null" : typeof value}`);
|
|
387
|
+
lines.push(`Value: ${valStr.length > 200 ? `${valStr.slice(0, 200)}...` : valStr}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return {
|
|
391
|
+
content: lines.join("\n"),
|
|
392
|
+
format
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Get a human-readable type description for a TOML value.
|
|
397
|
+
*/
|
|
398
|
+
describeType(value) {
|
|
399
|
+
if (value === null || value === void 0) return "null";
|
|
400
|
+
if (value instanceof Date) return "datetime";
|
|
401
|
+
if (Array.isArray(value)) return `array[${value.length}]`;
|
|
402
|
+
if (typeof value === "object") return `table{${Object.keys(value).filter((k) => !this.isMetaKey(k)).length} keys}`;
|
|
403
|
+
return typeof value;
|
|
404
|
+
}
|
|
264
405
|
/**
|
|
265
406
|
* Check if a key is a hidden meta key that should be filtered from listings
|
|
266
407
|
*/
|
|
@@ -478,9 +619,13 @@ var AFSTOML = class AFSTOML extends _aigne_afs_provider.AFSBaseProvider {
|
|
|
478
619
|
valueToAFSEntry(path, value) {
|
|
479
620
|
const isDir = this.isDirectoryValue(value);
|
|
480
621
|
const children = isDir ? this.getChildren(value) : [];
|
|
622
|
+
const kind = Array.isArray(value) ? "toml:array" : isDir ? "toml:table" : "toml:value";
|
|
481
623
|
return this.buildEntry(path, {
|
|
482
624
|
content: isDir ? void 0 : value,
|
|
483
|
-
|
|
625
|
+
meta: {
|
|
626
|
+
kind,
|
|
627
|
+
childrenCount: isDir ? children.length : void 0
|
|
628
|
+
},
|
|
484
629
|
createdAt: this.fileStats.birthtime,
|
|
485
630
|
updatedAt: this.fileStats.mtime
|
|
486
631
|
});
|
|
@@ -494,6 +639,10 @@ require_decorate.__decorate([(0, _aigne_afs_provider.Delete)("/:path*")], AFSTOM
|
|
|
494
639
|
require_decorate.__decorate([(0, _aigne_afs_provider.Rename)("/:path*")], AFSTOML.prototype, "renameHandler", null);
|
|
495
640
|
require_decorate.__decorate([(0, _aigne_afs_provider.Search)("/:path*")], AFSTOML.prototype, "searchHandler", null);
|
|
496
641
|
require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/:path*")], AFSTOML.prototype, "statHandler", null);
|
|
642
|
+
require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/.meta/.capabilities")], AFSTOML.prototype, "readCapabilitiesHandler", null);
|
|
643
|
+
require_decorate.__decorate([(0, _aigne_afs_provider.Explain)("/:path*")], AFSTOML.prototype, "explainHandler", null);
|
|
644
|
+
var src_default = AFSTOML;
|
|
497
645
|
|
|
498
646
|
//#endregion
|
|
499
|
-
exports.AFSTOML = AFSTOML;
|
|
647
|
+
exports.AFSTOML = AFSTOML;
|
|
648
|
+
exports.default = src_default;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AFSAccessMode, AFSEntry, AFSListResult, AFSModuleLoadParams, AFSSearchOptions, AFSStatResult, AFSWriteEntryPayload } from "@aigne/afs";
|
|
1
|
+
import { AFSAccessMode, AFSEntry, AFSExplainResult, AFSListResult, AFSModuleLoadParams, AFSSearchOptions, AFSStatResult, AFSWriteEntryPayload, ProviderManifest } from "@aigne/afs";
|
|
2
2
|
import { AFSBaseProvider, RouteContext } from "@aigne/afs/provider";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
@@ -24,32 +24,25 @@ interface AFSTOMLOptions {
|
|
|
24
24
|
declare class AFSTOML extends AFSBaseProvider {
|
|
25
25
|
options: AFSTOMLOptions & {
|
|
26
26
|
cwd?: string;
|
|
27
|
+
localPath?: string;
|
|
28
|
+
uri?: string;
|
|
27
29
|
};
|
|
28
|
-
static schema(): z.
|
|
29
|
-
name:
|
|
30
|
-
tomlPath: z.ZodString;
|
|
31
|
-
description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
|
|
32
|
-
accessMode: z.ZodType<"readonly" | "readwrite" | undefined, z.ZodTypeDef, "readonly" | "readwrite" | undefined>;
|
|
33
|
-
}, "strip", z.ZodTypeAny, {
|
|
30
|
+
static schema(): z.ZodType<{
|
|
31
|
+
name: string | undefined;
|
|
34
32
|
tomlPath: string;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
description: string | undefined;
|
|
34
|
+
accessMode: "readonly" | "readwrite" | undefined;
|
|
35
|
+
}, unknown, z.core.$ZodTypeInternals<{
|
|
36
|
+
name: string | undefined;
|
|
39
37
|
tomlPath: string;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
tomlPath: string;
|
|
45
|
-
name?: string | undefined;
|
|
46
|
-
description?: string | undefined;
|
|
47
|
-
accessMode?: "readonly" | "readwrite" | undefined;
|
|
48
|
-
}, any>;
|
|
38
|
+
description: string | undefined;
|
|
39
|
+
accessMode: "readonly" | "readwrite" | undefined;
|
|
40
|
+
}, unknown>>;
|
|
41
|
+
static manifest(): ProviderManifest;
|
|
49
42
|
static load({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
43
|
+
basePath,
|
|
44
|
+
config
|
|
45
|
+
}?: AFSModuleLoadParams): Promise<AFSTOML>;
|
|
53
46
|
readonly name: string;
|
|
54
47
|
readonly description?: string;
|
|
55
48
|
readonly accessMode: AFSAccessMode;
|
|
@@ -58,15 +51,20 @@ declare class AFSTOML extends AFSBaseProvider {
|
|
|
58
51
|
private resolvedTomlPath;
|
|
59
52
|
constructor(options: AFSTOMLOptions & {
|
|
60
53
|
cwd?: string;
|
|
54
|
+
localPath?: string;
|
|
55
|
+
uri?: string;
|
|
61
56
|
});
|
|
62
57
|
/**
|
|
63
58
|
* Read metadata for a TOML node via /.meta or /path/.meta
|
|
64
59
|
* Returns stored metadata merged with computed type information
|
|
65
|
-
* Note: Meta is read-only. To write metadata, use write() with payload.
|
|
60
|
+
* Note: Meta is read-only. To write metadata, use write() with payload.meta.
|
|
66
61
|
*/
|
|
67
62
|
readMetaHandler(ctx: RouteContext<{
|
|
68
63
|
path?: string;
|
|
69
64
|
}>): Promise<AFSEntry | undefined>;
|
|
65
|
+
/**
|
|
66
|
+
* Note: list() returns only children, never the path itself (per new semantics)
|
|
67
|
+
*/
|
|
70
68
|
listHandler(ctx: RouteContext<{
|
|
71
69
|
path?: string;
|
|
72
70
|
}>): Promise<AFSListResult & {
|
|
@@ -108,6 +106,14 @@ declare class AFSTOML extends AFSBaseProvider {
|
|
|
108
106
|
statHandler(ctx: RouteContext<{
|
|
109
107
|
path?: string;
|
|
110
108
|
}>): Promise<AFSStatResult>;
|
|
109
|
+
readCapabilitiesHandler(_ctx: RouteContext): Promise<AFSEntry | undefined>;
|
|
110
|
+
explainHandler(ctx: RouteContext<{
|
|
111
|
+
path?: string;
|
|
112
|
+
}>): Promise<AFSExplainResult>;
|
|
113
|
+
/**
|
|
114
|
+
* Get a human-readable type description for a TOML value.
|
|
115
|
+
*/
|
|
116
|
+
private describeType;
|
|
111
117
|
/**
|
|
112
118
|
* Check if a key is a hidden meta key that should be filtered from listings
|
|
113
119
|
*/
|
|
@@ -166,5 +172,5 @@ declare class AFSTOML extends AFSBaseProvider {
|
|
|
166
172
|
private valueToAFSEntry;
|
|
167
173
|
}
|
|
168
174
|
//#endregion
|
|
169
|
-
export { AFSTOML, AFSTOMLOptions };
|
|
175
|
+
export { AFSTOML, AFSTOML as default, AFSTOMLOptions };
|
|
170
176
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;UAkDiB,cAAA;EACf,IAAA;EACA,QAAA;EACA,WAAA;;;;;;;EAOA,UAAA,GAAa,aAAA;AAAA;;AAoBf;;;;;cAAa,OAAA,SAAgB,eAAA;EAgCR,OAAA,EAAS,cAAA;IAAmB,GAAA;IAAc,SAAA;IAAoB,GAAA;EAAA;EAAA,OA/B1E,MAAA,CAAA,GAAM,CAAA,CAAA,OAAA;;;;;;;;;;;SAIN,QAAA,CAAA,GAAY,gBAAA;EAAA,OAWN,IAAA,CAAA;IAAO,QAAA;IAAU;EAAA,IAAU,mBAAA,GAAwB,OAAA,CAAA,OAAA;EAAA,SAKvD,IAAA;EAAA,SACA,WAAA;EAAA,SACA,UAAA,EAAY,aAAA;EAAA,QAEb,QAAA;EAAA,QACA,SAAA;EAAA,QAIA,gBAAA;cAEW,OAAA,EAAS,cAAA;IAAmB,GAAA;IAAc,SAAA;IAAoB,GAAA;EAAA;EAmZ1D;;;;;EAhWjB,eAAA,CAAgB,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA,CAAQ,QAAA;EA6ZT;;;EAnVtD,WAAA,CACJ,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KACnB,OAAA,CAAQ,aAAA;IAAkB,QAAA;EAAA;EAgFvB,WAAA,CAAY,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA,CAAQ,QAAA;EA9OpD;;;;;;;;;EAsQP,YAAA,CACJ,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,IACpB,OAAA,EAAS,oBAAA,GACR,OAAA;IAAU,IAAA,EAAM,QAAA;EAAA;EAgDb,aAAA,CAAc,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA;IAAU,OAAA;EAAA;EA0B/D,aAAA,CACJ,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,IACpB,OAAA,WACC,OAAA;IAAU,OAAA;EAAA;EAiCP,aAAA,CACJ,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,IACpB,KAAA,UACA,OAAA,GAAU,gBAAA,GACT,OAAA;IAAU,IAAA,EAAM,QAAA;IAAY,OAAA;EAAA;EAuDzB,WAAA,CAAY,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA,CAAQ,aAAA;EAmC3D,uBAAA,CAAwB,IAAA,EAAM,YAAA,GAAe,OAAA,CAAQ,QAAA;EA0BrD,cAAA,CAAe,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA,CAAQ,gBAAA;EA7ZzC;;;EAAA,QAqgBnB,YAAA;EArgB6D;;;EAAA,QAqhB7D,SAAA;EA1cN;;;;;;;EAAA,QAqdM,QAAA;EApYiD;;;;;;;EAAA,QAocjD,QAAA;EAzaL;;;EAAA,QAueW,YAAA;EAvbW;;;EAAA,QAgdX,UAAA;EAhduD;;;EAAA,QA+d7D,eAAA;EApcN;;;EAAA,QA6cM,cAAA;EA1aF;;;EAAA,QAkcE,cAAA;EAhcN;;;EAAA,QA2fM,iBAAA;EAzfK;;;EAAA,QAsiBL,gBAAA;EA/ee;;;EAAA,QA4ff,WAAA;EA5fyD;;;EAAA,QA2gBzD,eAAA;AAAA"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AFSAccessMode, AFSEntry, AFSListResult, AFSModuleLoadParams, AFSSearchOptions, AFSStatResult, AFSWriteEntryPayload } from "@aigne/afs";
|
|
1
|
+
import { AFSAccessMode, AFSEntry, AFSExplainResult, AFSListResult, AFSModuleLoadParams, AFSSearchOptions, AFSStatResult, AFSWriteEntryPayload, ProviderManifest } from "@aigne/afs";
|
|
2
2
|
import { AFSBaseProvider, RouteContext } from "@aigne/afs/provider";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
@@ -24,32 +24,25 @@ interface AFSTOMLOptions {
|
|
|
24
24
|
declare class AFSTOML extends AFSBaseProvider {
|
|
25
25
|
options: AFSTOMLOptions & {
|
|
26
26
|
cwd?: string;
|
|
27
|
+
localPath?: string;
|
|
28
|
+
uri?: string;
|
|
27
29
|
};
|
|
28
|
-
static schema(): z.
|
|
29
|
-
name:
|
|
30
|
-
tomlPath: z.ZodString;
|
|
31
|
-
description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
|
|
32
|
-
accessMode: z.ZodType<"readonly" | "readwrite" | undefined, z.ZodTypeDef, "readonly" | "readwrite" | undefined>;
|
|
33
|
-
}, "strip", z.ZodTypeAny, {
|
|
30
|
+
static schema(): z.ZodType<{
|
|
31
|
+
name: string | undefined;
|
|
34
32
|
tomlPath: string;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
description: string | undefined;
|
|
34
|
+
accessMode: "readonly" | "readwrite" | undefined;
|
|
35
|
+
}, unknown, z.core.$ZodTypeInternals<{
|
|
36
|
+
name: string | undefined;
|
|
39
37
|
tomlPath: string;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
tomlPath: string;
|
|
45
|
-
name?: string | undefined;
|
|
46
|
-
description?: string | undefined;
|
|
47
|
-
accessMode?: "readonly" | "readwrite" | undefined;
|
|
48
|
-
}, any>;
|
|
38
|
+
description: string | undefined;
|
|
39
|
+
accessMode: "readonly" | "readwrite" | undefined;
|
|
40
|
+
}, unknown>>;
|
|
41
|
+
static manifest(): ProviderManifest;
|
|
49
42
|
static load({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
43
|
+
basePath,
|
|
44
|
+
config
|
|
45
|
+
}?: AFSModuleLoadParams): Promise<AFSTOML>;
|
|
53
46
|
readonly name: string;
|
|
54
47
|
readonly description?: string;
|
|
55
48
|
readonly accessMode: AFSAccessMode;
|
|
@@ -58,15 +51,20 @@ declare class AFSTOML extends AFSBaseProvider {
|
|
|
58
51
|
private resolvedTomlPath;
|
|
59
52
|
constructor(options: AFSTOMLOptions & {
|
|
60
53
|
cwd?: string;
|
|
54
|
+
localPath?: string;
|
|
55
|
+
uri?: string;
|
|
61
56
|
});
|
|
62
57
|
/**
|
|
63
58
|
* Read metadata for a TOML node via /.meta or /path/.meta
|
|
64
59
|
* Returns stored metadata merged with computed type information
|
|
65
|
-
* Note: Meta is read-only. To write metadata, use write() with payload.
|
|
60
|
+
* Note: Meta is read-only. To write metadata, use write() with payload.meta.
|
|
66
61
|
*/
|
|
67
62
|
readMetaHandler(ctx: RouteContext<{
|
|
68
63
|
path?: string;
|
|
69
64
|
}>): Promise<AFSEntry | undefined>;
|
|
65
|
+
/**
|
|
66
|
+
* Note: list() returns only children, never the path itself (per new semantics)
|
|
67
|
+
*/
|
|
70
68
|
listHandler(ctx: RouteContext<{
|
|
71
69
|
path?: string;
|
|
72
70
|
}>): Promise<AFSListResult & {
|
|
@@ -108,6 +106,14 @@ declare class AFSTOML extends AFSBaseProvider {
|
|
|
108
106
|
statHandler(ctx: RouteContext<{
|
|
109
107
|
path?: string;
|
|
110
108
|
}>): Promise<AFSStatResult>;
|
|
109
|
+
readCapabilitiesHandler(_ctx: RouteContext): Promise<AFSEntry | undefined>;
|
|
110
|
+
explainHandler(ctx: RouteContext<{
|
|
111
|
+
path?: string;
|
|
112
|
+
}>): Promise<AFSExplainResult>;
|
|
113
|
+
/**
|
|
114
|
+
* Get a human-readable type description for a TOML value.
|
|
115
|
+
*/
|
|
116
|
+
private describeType;
|
|
111
117
|
/**
|
|
112
118
|
* Check if a key is a hidden meta key that should be filtered from listings
|
|
113
119
|
*/
|
|
@@ -166,5 +172,5 @@ declare class AFSTOML extends AFSBaseProvider {
|
|
|
166
172
|
private valueToAFSEntry;
|
|
167
173
|
}
|
|
168
174
|
//#endregion
|
|
169
|
-
export { AFSTOML, AFSTOMLOptions };
|
|
175
|
+
export { AFSTOML, AFSTOML as default, AFSTOMLOptions };
|
|
170
176
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;UAkDiB,cAAA;EACf,IAAA;EACA,QAAA;EACA,WAAA;;;;;;;EAOA,UAAA,GAAa,aAAA;AAAA;;AAoBf;;;;;cAAa,OAAA,SAAgB,eAAA;EAgCR,OAAA,EAAS,cAAA;IAAmB,GAAA;IAAc,SAAA;IAAoB,GAAA;EAAA;EAAA,OA/B1E,MAAA,CAAA,GAAM,CAAA,CAAA,OAAA;;;;;;;;;;;SAIN,QAAA,CAAA,GAAY,gBAAA;EAAA,OAWN,IAAA,CAAA;IAAO,QAAA;IAAU;EAAA,IAAU,mBAAA,GAAwB,OAAA,CAAA,OAAA;EAAA,SAKvD,IAAA;EAAA,SACA,WAAA;EAAA,SACA,UAAA,EAAY,aAAA;EAAA,QAEb,QAAA;EAAA,QACA,SAAA;EAAA,QAIA,gBAAA;cAEW,OAAA,EAAS,cAAA;IAAmB,GAAA;IAAc,SAAA;IAAoB,GAAA;EAAA;EAmZ1D;;;;;EAhWjB,eAAA,CAAgB,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA,CAAQ,QAAA;EA6ZT;;;EAnVtD,WAAA,CACJ,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KACnB,OAAA,CAAQ,aAAA;IAAkB,QAAA;EAAA;EAgFvB,WAAA,CAAY,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA,CAAQ,QAAA;EA9OpD;;;;;;;;;EAsQP,YAAA,CACJ,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,IACpB,OAAA,EAAS,oBAAA,GACR,OAAA;IAAU,IAAA,EAAM,QAAA;EAAA;EAgDb,aAAA,CAAc,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA;IAAU,OAAA;EAAA;EA0B/D,aAAA,CACJ,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,IACpB,OAAA,WACC,OAAA;IAAU,OAAA;EAAA;EAiCP,aAAA,CACJ,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,IACpB,KAAA,UACA,OAAA,GAAU,gBAAA,GACT,OAAA;IAAU,IAAA,EAAM,QAAA;IAAY,OAAA;EAAA;EAuDzB,WAAA,CAAY,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA,CAAQ,aAAA;EAmC3D,uBAAA,CAAwB,IAAA,EAAM,YAAA,GAAe,OAAA,CAAQ,QAAA;EA0BrD,cAAA,CAAe,GAAA,EAAK,YAAA;IAAe,IAAA;EAAA,KAAmB,OAAA,CAAQ,gBAAA;EA7ZzC;;;EAAA,QAqgBnB,YAAA;EArgB6D;;;EAAA,QAqhB7D,SAAA;EA1cN;;;;;;;EAAA,QAqdM,QAAA;EApYiD;;;;;;;EAAA,QAocjD,QAAA;EAzaL;;;EAAA,QAueW,YAAA;EAvbW;;;EAAA,QAgdX,UAAA;EAhduD;;;EAAA,QA+d7D,eAAA;EApcN;;;EAAA,QA6cM,cAAA;EA1aF;;;EAAA,QAkcE,cAAA;EAhcN;;;EAAA,QA2fM,iBAAA;EAzfK;;;EAAA,QAsiBL,gBAAA;EA/ee;;;EAAA,QA4ff,WAAA;EA5fyD;;;EAAA,QA2gBzD,eAAA;AAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { __decorate } from "./_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs";
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { readFile, stat, writeFile } from "node:fs/promises";
|
|
3
4
|
import { basename, dirname, isAbsolute, join } from "node:path";
|
|
4
5
|
import { AFSNotFoundError } from "@aigne/afs";
|
|
5
|
-
import { AFSBaseProvider, Delete, List, Meta, Read, Rename, Search, Stat, Write } from "@aigne/afs/provider";
|
|
6
|
+
import { AFSBaseProvider, Delete, Explain, List, Meta, Read, Rename, Search, Stat, Write } from "@aigne/afs/provider";
|
|
6
7
|
import { camelize, optionalize, zodParse } from "@aigne/afs/utils/zod";
|
|
7
8
|
import { parse, stringify } from "smol-toml";
|
|
8
9
|
import { joinURL } from "ufo";
|
|
@@ -32,10 +33,20 @@ var AFSTOML = class AFSTOML extends AFSBaseProvider {
|
|
|
32
33
|
static schema() {
|
|
33
34
|
return afsTOMLOptionsSchema;
|
|
34
35
|
}
|
|
35
|
-
static
|
|
36
|
+
static manifest() {
|
|
37
|
+
return {
|
|
38
|
+
name: "toml",
|
|
39
|
+
description: "Mount a TOML file as a virtual filesystem",
|
|
40
|
+
uriTemplate: "toml://{localPath+}",
|
|
41
|
+
category: "structured-data",
|
|
42
|
+
schema: z.object({ localPath: z.string() }),
|
|
43
|
+
tags: ["toml", "structured-data"]
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
static async load({ basePath, config } = {}) {
|
|
36
47
|
return new AFSTOML({
|
|
37
|
-
...await AFSTOML.schema().parseAsync(
|
|
38
|
-
cwd:
|
|
48
|
+
...await AFSTOML.schema().parseAsync(config),
|
|
49
|
+
cwd: basePath
|
|
39
50
|
});
|
|
40
51
|
}
|
|
41
52
|
name;
|
|
@@ -47,11 +58,16 @@ var AFSTOML = class AFSTOML extends AFSBaseProvider {
|
|
|
47
58
|
constructor(options) {
|
|
48
59
|
super();
|
|
49
60
|
this.options = options;
|
|
61
|
+
if (options.localPath && !options.tomlPath) options.tomlPath = options.localPath;
|
|
50
62
|
zodParse(afsTOMLOptionsSchema, options);
|
|
51
63
|
let tomlPath;
|
|
52
64
|
tomlPath = options.tomlPath.replaceAll("${CWD}", process.cwd());
|
|
53
65
|
if (tomlPath.startsWith("~/")) tomlPath = join(process.env.HOME || "", tomlPath.slice(2));
|
|
54
66
|
if (!isAbsolute(tomlPath)) tomlPath = join(options.cwd || process.cwd(), tomlPath);
|
|
67
|
+
if (!existsSync(tomlPath)) {
|
|
68
|
+
mkdirSync(dirname(tomlPath), { recursive: true });
|
|
69
|
+
writeFileSync(tomlPath, "", "utf8");
|
|
70
|
+
}
|
|
55
71
|
let name = basename(tomlPath);
|
|
56
72
|
if (name.endsWith(".toml")) name = name.slice(0, -5);
|
|
57
73
|
this.name = options.name || name || "toml";
|
|
@@ -62,7 +78,7 @@ var AFSTOML = class AFSTOML extends AFSBaseProvider {
|
|
|
62
78
|
/**
|
|
63
79
|
* Read metadata for a TOML node via /.meta or /path/.meta
|
|
64
80
|
* Returns stored metadata merged with computed type information
|
|
65
|
-
* Note: Meta is read-only. To write metadata, use write() with payload.
|
|
81
|
+
* Note: Meta is read-only. To write metadata, use write() with payload.meta.
|
|
66
82
|
*/
|
|
67
83
|
async readMetaHandler(ctx) {
|
|
68
84
|
await this.ensureLoaded();
|
|
@@ -91,12 +107,15 @@ var AFSTOML = class AFSTOML extends AFSBaseProvider {
|
|
|
91
107
|
if (this.fileStats.birthtime) computedMeta.created = this.fileStats.birthtime;
|
|
92
108
|
if (this.fileStats.mtime) computedMeta.modified = this.fileStats.mtime;
|
|
93
109
|
return this.buildEntry(joinURL(nodePath, ".meta"), {
|
|
94
|
-
|
|
110
|
+
meta: storedMeta,
|
|
95
111
|
content: computedMeta,
|
|
96
112
|
createdAt: this.fileStats.birthtime,
|
|
97
113
|
updatedAt: this.fileStats.mtime
|
|
98
114
|
});
|
|
99
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Note: list() returns only children, never the path itself (per new semantics)
|
|
118
|
+
*/
|
|
100
119
|
async listHandler(ctx) {
|
|
101
120
|
await this.ensureLoaded();
|
|
102
121
|
const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : "/";
|
|
@@ -107,12 +126,15 @@ var AFSTOML = class AFSTOML extends AFSBaseProvider {
|
|
|
107
126
|
const segments = this.getPathSegments(normalizedPath);
|
|
108
127
|
const value = this.getValueAtPath(this.tomlData, segments);
|
|
109
128
|
if (value === void 0) throw new AFSNotFoundError(normalizedPath);
|
|
129
|
+
if (maxDepth === 0) return { data: [] };
|
|
130
|
+
if (!this.isDirectoryValue(value)) return { data: [] };
|
|
110
131
|
const entries = [];
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
132
|
+
const rootChildren = this.getChildren(value);
|
|
133
|
+
const queue = (rootChildren.length > maxChildren ? rootChildren.slice(0, maxChildren) : rootChildren).map((child) => ({
|
|
134
|
+
path: normalizedPath === "/" ? `/${child.key}` : `${normalizedPath}/${child.key}`,
|
|
135
|
+
value: child.value,
|
|
136
|
+
depth: 1
|
|
137
|
+
}));
|
|
116
138
|
while (queue.length > 0) {
|
|
117
139
|
const item = queue.shift();
|
|
118
140
|
if (!item) break;
|
|
@@ -157,10 +179,10 @@ var AFSTOML = class AFSTOML extends AFSBaseProvider {
|
|
|
157
179
|
const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : "/";
|
|
158
180
|
const segments = this.getPathSegments(normalizedPath);
|
|
159
181
|
if (payload.content !== void 0) this.setValueAtPath(this.tomlData, segments, payload.content);
|
|
160
|
-
if (payload.
|
|
182
|
+
if (payload.meta !== void 0 && typeof payload.meta === "object") {
|
|
161
183
|
const finalMeta = {
|
|
162
184
|
...this.loadMeta(normalizedPath) || {},
|
|
163
|
-
...payload.
|
|
185
|
+
...payload.meta
|
|
164
186
|
};
|
|
165
187
|
this.saveMeta(normalizedPath, finalMeta);
|
|
166
188
|
}
|
|
@@ -176,7 +198,7 @@ var AFSTOML = class AFSTOML extends AFSBaseProvider {
|
|
|
176
198
|
summary: payload.summary,
|
|
177
199
|
createdAt: this.fileStats.birthtime,
|
|
178
200
|
updatedAt: this.fileStats.mtime,
|
|
179
|
-
|
|
201
|
+
meta: {
|
|
180
202
|
...storedMeta,
|
|
181
203
|
childrenCount: isDir ? children.length : void 0
|
|
182
204
|
},
|
|
@@ -252,15 +274,133 @@ var AFSTOML = class AFSTOML extends AFSBaseProvider {
|
|
|
252
274
|
if (value === void 0) throw new AFSNotFoundError(normalizedPath);
|
|
253
275
|
const isDir = this.isDirectoryValue(value);
|
|
254
276
|
const children = isDir ? this.getChildren(value) : [];
|
|
255
|
-
const meta = this.loadMeta(normalizedPath);
|
|
277
|
+
const meta = { ...this.loadMeta(normalizedPath) };
|
|
278
|
+
if (isDir) meta.childrenCount = children.length;
|
|
256
279
|
return { data: {
|
|
280
|
+
id: segments.length > 0 ? segments[segments.length - 1] : "/",
|
|
257
281
|
path: normalizedPath,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
meta: meta ?? void 0
|
|
282
|
+
createdAt: this.fileStats.birthtime,
|
|
283
|
+
updatedAt: this.fileStats.mtime,
|
|
284
|
+
meta
|
|
262
285
|
} };
|
|
263
286
|
}
|
|
287
|
+
async readCapabilitiesHandler(_ctx) {
|
|
288
|
+
await this.ensureLoaded();
|
|
289
|
+
const operations = [
|
|
290
|
+
"list",
|
|
291
|
+
"read",
|
|
292
|
+
"stat",
|
|
293
|
+
"explain",
|
|
294
|
+
"search"
|
|
295
|
+
];
|
|
296
|
+
if (this.accessMode === "readwrite") operations.push("write", "delete", "rename");
|
|
297
|
+
return {
|
|
298
|
+
id: "/.meta/.capabilities",
|
|
299
|
+
path: "/.meta/.capabilities",
|
|
300
|
+
content: {
|
|
301
|
+
schemaVersion: 1,
|
|
302
|
+
provider: this.name,
|
|
303
|
+
description: this.description || "TOML virtual filesystem",
|
|
304
|
+
tools: [],
|
|
305
|
+
actions: [],
|
|
306
|
+
operations: this.getOperationsDeclaration()
|
|
307
|
+
},
|
|
308
|
+
meta: {
|
|
309
|
+
kind: "afs:capabilities",
|
|
310
|
+
operations
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
async explainHandler(ctx) {
|
|
315
|
+
await this.ensureLoaded();
|
|
316
|
+
const normalizedPath = joinURL("/", ctx.params.path ?? "");
|
|
317
|
+
const format = ctx.options?.format || "markdown";
|
|
318
|
+
const segments = this.getPathSegments(normalizedPath);
|
|
319
|
+
const value = this.getValueAtPath(this.tomlData, segments);
|
|
320
|
+
if (value === void 0) throw new AFSNotFoundError(normalizedPath);
|
|
321
|
+
const nodeName = segments.length > 0 ? segments[segments.length - 1] : "/";
|
|
322
|
+
const isDir = this.isDirectoryValue(value);
|
|
323
|
+
const storedMeta = this.loadMeta(normalizedPath);
|
|
324
|
+
const lines = [];
|
|
325
|
+
if (format === "markdown") {
|
|
326
|
+
lines.push(`# ${nodeName}`);
|
|
327
|
+
lines.push("");
|
|
328
|
+
lines.push(`**Path:** \`${normalizedPath}\``);
|
|
329
|
+
lines.push(`**Format:** TOML`);
|
|
330
|
+
if (normalizedPath === "/") {
|
|
331
|
+
const children = this.getChildren(this.tomlData);
|
|
332
|
+
lines.push(`**Top-level keys:** ${children.length}`);
|
|
333
|
+
if (children.length > 0) {
|
|
334
|
+
lines.push("");
|
|
335
|
+
lines.push("## Keys");
|
|
336
|
+
lines.push("");
|
|
337
|
+
for (const child of children.slice(0, 30)) {
|
|
338
|
+
const childType = this.describeType(child.value);
|
|
339
|
+
lines.push(`- \`${child.key}\` — ${childType}`);
|
|
340
|
+
}
|
|
341
|
+
if (children.length > 30) lines.push(`- ... and ${children.length - 30} more`);
|
|
342
|
+
}
|
|
343
|
+
} else if (Array.isArray(value)) {
|
|
344
|
+
lines.push(`**Type:** array of tables`);
|
|
345
|
+
lines.push(`**Elements:** ${value.length}`);
|
|
346
|
+
if (value.length > 0) {
|
|
347
|
+
const elementType = this.describeType(value[0]);
|
|
348
|
+
lines.push(`**Element type:** ${elementType}`);
|
|
349
|
+
}
|
|
350
|
+
} else if (typeof value === "object" && value !== null) {
|
|
351
|
+
const children = this.getChildren(value);
|
|
352
|
+
lines.push(`**Type:** table`);
|
|
353
|
+
lines.push(`**Keys:** ${children.length}`);
|
|
354
|
+
if (children.length > 0) {
|
|
355
|
+
lines.push("");
|
|
356
|
+
lines.push("## Keys");
|
|
357
|
+
lines.push("");
|
|
358
|
+
for (const child of children.slice(0, 30)) {
|
|
359
|
+
const childType = this.describeType(child.value);
|
|
360
|
+
lines.push(`- \`${child.key}\` — ${childType}`);
|
|
361
|
+
}
|
|
362
|
+
if (children.length > 30) lines.push(`- ... and ${children.length - 30} more`);
|
|
363
|
+
}
|
|
364
|
+
} else {
|
|
365
|
+
const valType = value === null ? "null" : typeof value;
|
|
366
|
+
lines.push(`**Type:** ${valType}`);
|
|
367
|
+
const valStr = String(value);
|
|
368
|
+
if (valStr.length > 200) lines.push(`**Value:** ${valStr.slice(0, 200)}...`);
|
|
369
|
+
else lines.push(`**Value:** ${valStr}`);
|
|
370
|
+
}
|
|
371
|
+
if (storedMeta) {
|
|
372
|
+
lines.push("");
|
|
373
|
+
lines.push("## Metadata");
|
|
374
|
+
for (const [key, val] of Object.entries(storedMeta)) lines.push(`- **${key}:** ${JSON.stringify(val)}`);
|
|
375
|
+
}
|
|
376
|
+
} else {
|
|
377
|
+
lines.push(`${nodeName} (${isDir ? "table" : "value"})`);
|
|
378
|
+
lines.push(`Path: ${normalizedPath}`);
|
|
379
|
+
lines.push(`Format: TOML`);
|
|
380
|
+
if (isDir) {
|
|
381
|
+
const children = this.getChildren(value);
|
|
382
|
+
lines.push(`Children: ${children.length}`);
|
|
383
|
+
} else {
|
|
384
|
+
const valStr = String(value);
|
|
385
|
+
lines.push(`Type: ${value === null ? "null" : typeof value}`);
|
|
386
|
+
lines.push(`Value: ${valStr.length > 200 ? `${valStr.slice(0, 200)}...` : valStr}`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return {
|
|
390
|
+
content: lines.join("\n"),
|
|
391
|
+
format
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Get a human-readable type description for a TOML value.
|
|
396
|
+
*/
|
|
397
|
+
describeType(value) {
|
|
398
|
+
if (value === null || value === void 0) return "null";
|
|
399
|
+
if (value instanceof Date) return "datetime";
|
|
400
|
+
if (Array.isArray(value)) return `array[${value.length}]`;
|
|
401
|
+
if (typeof value === "object") return `table{${Object.keys(value).filter((k) => !this.isMetaKey(k)).length} keys}`;
|
|
402
|
+
return typeof value;
|
|
403
|
+
}
|
|
264
404
|
/**
|
|
265
405
|
* Check if a key is a hidden meta key that should be filtered from listings
|
|
266
406
|
*/
|
|
@@ -478,9 +618,13 @@ var AFSTOML = class AFSTOML extends AFSBaseProvider {
|
|
|
478
618
|
valueToAFSEntry(path, value) {
|
|
479
619
|
const isDir = this.isDirectoryValue(value);
|
|
480
620
|
const children = isDir ? this.getChildren(value) : [];
|
|
621
|
+
const kind = Array.isArray(value) ? "toml:array" : isDir ? "toml:table" : "toml:value";
|
|
481
622
|
return this.buildEntry(path, {
|
|
482
623
|
content: isDir ? void 0 : value,
|
|
483
|
-
|
|
624
|
+
meta: {
|
|
625
|
+
kind,
|
|
626
|
+
childrenCount: isDir ? children.length : void 0
|
|
627
|
+
},
|
|
484
628
|
createdAt: this.fileStats.birthtime,
|
|
485
629
|
updatedAt: this.fileStats.mtime
|
|
486
630
|
});
|
|
@@ -494,7 +638,10 @@ __decorate([Delete("/:path*")], AFSTOML.prototype, "deleteHandler", null);
|
|
|
494
638
|
__decorate([Rename("/:path*")], AFSTOML.prototype, "renameHandler", null);
|
|
495
639
|
__decorate([Search("/:path*")], AFSTOML.prototype, "searchHandler", null);
|
|
496
640
|
__decorate([Stat("/:path*")], AFSTOML.prototype, "statHandler", null);
|
|
641
|
+
__decorate([Read("/.meta/.capabilities")], AFSTOML.prototype, "readCapabilitiesHandler", null);
|
|
642
|
+
__decorate([Explain("/:path*")], AFSTOML.prototype, "explainHandler", null);
|
|
643
|
+
var src_default = AFSTOML;
|
|
497
644
|
|
|
498
645
|
//#endregion
|
|
499
|
-
export { AFSTOML };
|
|
646
|
+
export { AFSTOML, src_default as default };
|
|
500
647
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["afs","meta","parseTOML","stringifyTOML"],"sources":["../src/index.ts"],"sourcesContent":["import { readFile, stat, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join } from \"node:path\";\nimport {\n type AFSAccessMode,\n type AFSDeleteOptions,\n type AFSEntry,\n type AFSEntryMetadata,\n type AFSListResult,\n type AFSModuleClass,\n type AFSModuleLoadParams,\n AFSNotFoundError,\n type AFSRenameOptions,\n type AFSSearchOptions,\n type AFSStatResult,\n type AFSWriteEntryPayload,\n} from \"@aigne/afs\";\nimport {\n AFSBaseProvider,\n Delete,\n List,\n Meta,\n Read,\n Rename,\n type RouteContext,\n Search,\n Stat,\n Write,\n} from \"@aigne/afs/provider\";\nimport { camelize, optionalize, zodParse } from \"@aigne/afs/utils/zod\";\nimport { parse as parseTOML, stringify as stringifyTOML } from \"smol-toml\";\nimport { joinURL } from \"ufo\";\nimport { z } from \"zod\";\n\nconst LIST_MAX_LIMIT = 1000;\n\n/** Hidden key for storing AFS metadata (mirrors FS provider's .afs directory) */\nconst AFS_KEY = \".afs\";\n\n/** Subkey for storing metadata (mirrors FS provider's meta.yaml file) */\nconst META_KEY = \"meta\";\n\n/** Subkey for storing child node metadata (mirrors FS provider's .nodes directory) */\nconst NODES_KEY = \".nodes\";\n\nexport interface AFSTOMLOptions {\n name?: string;\n tomlPath: string;\n description?: string;\n /**\n * Access mode for this module.\n * - \"readonly\": Only read operations are allowed\n * - \"readwrite\": All operations are allowed (default)\n * @default \"readwrite\"\n */\n accessMode?: AFSAccessMode;\n}\n\nconst afsTOMLOptionsSchema = camelize(\n z.object({\n name: optionalize(z.string()),\n tomlPath: z.string().describe(\"The path to the TOML file to mount\"),\n description: optionalize(z.string().describe(\"A description of the TOML module\")),\n accessMode: optionalize(\n z.enum([\"readonly\", \"readwrite\"]).describe(\"Access mode for this module\"),\n ),\n }),\n);\n\n/**\n * AFS module for mounting TOML files as virtual file systems.\n *\n * TOML tables are treated as directories, and properties as files.\n * Supports nested structures and path-based access to data values.\n */\nexport class AFSTOML extends AFSBaseProvider {\n static schema() {\n return afsTOMLOptionsSchema;\n }\n\n static async load({ filepath, parsed }: AFSModuleLoadParams) {\n const valid = await AFSTOML.schema().parseAsync(parsed);\n return new AFSTOML({ ...valid, cwd: dirname(filepath) });\n }\n\n readonly name: string;\n readonly description?: string;\n readonly accessMode: AFSAccessMode;\n\n private tomlData: Record<string, unknown> | null = null;\n private fileStats: {\n birthtime?: Date;\n mtime?: Date;\n } = {};\n private resolvedTomlPath: string;\n\n constructor(public options: AFSTOMLOptions & { cwd?: string }) {\n super();\n zodParse(afsTOMLOptionsSchema, options);\n\n let tomlPath: string;\n\n tomlPath = options.tomlPath.replaceAll(\"${CWD}\", process.cwd());\n if (tomlPath.startsWith(\"~/\")) {\n tomlPath = join(process.env.HOME || \"\", tomlPath.slice(2));\n }\n if (!isAbsolute(tomlPath)) {\n tomlPath = join(options.cwd || process.cwd(), tomlPath);\n }\n\n // Extract name without extension\n let name = basename(tomlPath);\n if (name.endsWith(\".toml\")) {\n name = name.slice(0, -5);\n }\n\n this.name = options.name || name || \"toml\";\n this.description = options.description;\n this.accessMode = options.accessMode ?? \"readwrite\";\n this.resolvedTomlPath = tomlPath;\n }\n\n // ========== Meta Handlers ==========\n // Meta is read-only introspection. Metadata writes are handled by @Write via payload.metadata.\n //\n // Meta storage strategy (mirrors FS provider's .afs directory):\n // - For tables (directories): metadata stored in `.afs.meta` key within the table\n // - For primitives (files): metadata stored in parent's `.afs[\".nodes\"][key].meta` structure\n\n /**\n * Read metadata for a TOML node via /.meta or /path/.meta\n * Returns stored metadata merged with computed type information\n * Note: Meta is read-only. To write metadata, use write() with payload.metadata.\n */\n @Meta(\"/:path*\")\n async readMetaHandler(ctx: RouteContext<{ path?: string }>): Promise<AFSEntry | undefined> {\n await this.ensureLoaded();\n\n const nodePath = joinURL(\"/\", ctx.params.path ?? \"\");\n const segments = this.getPathSegments(nodePath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(nodePath);\n }\n\n const isDir = this.isDirectoryValue(value);\n const children = isDir ? this.getChildren(value) : [];\n\n // Determine the value type\n let type: string;\n if (Array.isArray(value)) {\n type = \"array\";\n } else if (value === null) {\n type = \"null\";\n } else if (value instanceof Date) {\n type = \"datetime\";\n } else if (typeof value === \"object\") {\n type = \"table\";\n } else {\n type = typeof value;\n }\n\n // Load stored user-defined metadata\n const storedMeta = this.loadMeta(nodePath) || {};\n\n // Build computed metadata (type info, etc.)\n const computedMeta: Record<string, unknown> = {\n type,\n path: nodePath,\n };\n\n if (isDir) {\n computedMeta.childrenCount = children.length;\n if (Array.isArray(value)) {\n computedMeta.length = value.length;\n } else {\n // Filter out internal keys from keys list\n computedMeta.keys = Object.keys(value as Record<string, unknown>).filter(\n (k) => !this.isMetaKey(k),\n );\n }\n } else {\n computedMeta.value = value;\n }\n\n if (this.fileStats.birthtime) {\n computedMeta.created = this.fileStats.birthtime;\n }\n if (this.fileStats.mtime) {\n computedMeta.modified = this.fileStats.mtime;\n }\n\n return this.buildEntry(joinURL(nodePath, \".meta\"), {\n // User-defined metadata goes in metadata field (for conformance)\n metadata: storedMeta as AFSEntryMetadata,\n // Computed type info goes in content (TOML-specific)\n content: computedMeta,\n createdAt: this.fileStats.birthtime,\n updatedAt: this.fileStats.mtime,\n });\n }\n\n // ========== Route Handlers ==========\n\n @List(\"/:path*\", { handleDepth: true })\n async listHandler(\n ctx: RouteContext<{ path?: string }>,\n ): Promise<AFSListResult & { noExpand?: string[] }> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const options = ctx.options as { limit?: number; maxChildren?: number; maxDepth?: number };\n const limit = Math.min(options?.limit || LIST_MAX_LIMIT, LIST_MAX_LIMIT);\n const maxChildren =\n typeof options?.maxChildren === \"number\" ? options.maxChildren : Number.MAX_SAFE_INTEGER;\n const maxDepth = options?.maxDepth ?? 1;\n\n const segments = this.getPathSegments(normalizedPath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n const entries: AFSEntry[] = [];\n\n interface QueueItem {\n path: string;\n value: unknown;\n depth: number;\n }\n\n const queue: QueueItem[] = [{ path: normalizedPath, value, depth: 0 }];\n\n while (queue.length > 0) {\n const item = queue.shift();\n if (!item) break;\n\n const { path: itemPath, value: itemValue, depth } = item;\n\n const entry = this.valueToAFSEntry(itemPath, itemValue);\n entries.push(entry);\n\n if (entries.length >= limit) {\n break;\n }\n\n // Process children if within depth limit\n if (this.isDirectoryValue(itemValue) && depth < maxDepth) {\n const children = this.getChildren(itemValue);\n const childrenToProcess =\n children.length > maxChildren ? children.slice(0, maxChildren) : children;\n\n for (const child of childrenToProcess) {\n const childPath = itemPath === \"/\" ? `/${child.key}` : `${itemPath}/${child.key}`;\n queue.push({\n path: childPath,\n value: child.value,\n depth: depth + 1,\n });\n }\n }\n }\n\n return { data: entries };\n }\n\n @Read(\"/:path*\")\n async readHandler(ctx: RouteContext<{ path?: string }>): Promise<AFSEntry | undefined> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const segments = this.getPathSegments(normalizedPath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n return this.valueToAFSEntry(normalizedPath, value);\n }\n\n /**\n * Write handler - supports writing content and/or metadata\n *\n * | payload | behavior |\n * |---------|----------|\n * | { content } | write content only |\n * | { metadata } | write metadata only (to .afs storage) |\n * | { content, metadata } | write both |\n */\n @Write(\"/:path*\")\n async writeHandler(\n ctx: RouteContext<{ path?: string }>,\n payload: AFSWriteEntryPayload,\n ): Promise<{ data: AFSEntry }> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const segments = this.getPathSegments(normalizedPath);\n\n // Write content if provided\n if (payload.content !== undefined) {\n this.setValueAtPath(this.tomlData!, segments, payload.content);\n }\n\n // Write metadata if provided (merge with existing)\n if (payload.metadata !== undefined && typeof payload.metadata === \"object\") {\n const existingMeta = this.loadMeta(normalizedPath) || {};\n const finalMeta = { ...existingMeta, ...payload.metadata };\n this.saveMeta(normalizedPath, finalMeta);\n }\n\n // Save back to file\n await this.saveToFile();\n\n const newValue = this.getValueAtPath(this.tomlData, segments);\n const isDir = this.isDirectoryValue(newValue);\n const children = isDir ? this.getChildren(newValue) : [];\n\n // Load stored metadata for response\n const storedMeta = this.loadMeta(normalizedPath) || {};\n\n const writtenEntry: AFSEntry = {\n id: normalizedPath,\n path: normalizedPath,\n content: payload.content !== undefined ? payload.content : newValue,\n summary: payload.summary,\n createdAt: this.fileStats.birthtime,\n updatedAt: this.fileStats.mtime,\n metadata: {\n ...storedMeta,\n childrenCount: isDir ? children.length : undefined,\n } as AFSEntryMetadata,\n userId: payload.userId,\n sessionId: payload.sessionId,\n linkTo: payload.linkTo,\n };\n\n return { data: writtenEntry };\n }\n\n @Delete(\"/:path*\")\n async deleteHandler(ctx: RouteContext<{ path?: string }>): Promise<{ message: string }> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const options = ctx.options as AFSDeleteOptions | undefined;\n const segments = this.getPathSegments(normalizedPath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n const hasChildren = this.isDirectoryValue(value) && this.getChildren(value).length > 0;\n if (hasChildren && !options?.recursive) {\n throw new Error(\n `Cannot delete directory '${normalizedPath}' without recursive option. Set recursive: true to delete directories.`,\n );\n }\n\n this.deleteValueAtPath(this.tomlData!, segments);\n await this.saveToFile();\n\n return { message: `Successfully deleted: ${normalizedPath}` };\n }\n\n @Rename(\"/:path*\")\n async renameHandler(\n ctx: RouteContext<{ path?: string }>,\n newPath: string,\n ): Promise<{ message: string }> {\n await this.ensureLoaded();\n\n const normalizedOldPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const normalizedNewPath = this.normalizePath(newPath);\n const options = ctx.options as AFSRenameOptions | undefined;\n\n const oldSegments = this.getPathSegments(normalizedOldPath);\n const newSegments = this.getPathSegments(normalizedNewPath);\n\n const oldValue = this.getValueAtPath(this.tomlData, oldSegments);\n if (oldValue === undefined) {\n throw new AFSNotFoundError(normalizedOldPath);\n }\n\n const existingNewValue = this.getValueAtPath(this.tomlData, newSegments);\n if (existingNewValue !== undefined && !options?.overwrite) {\n throw new Error(\n `Destination '${normalizedNewPath}' already exists. Set overwrite: true to replace it.`,\n );\n }\n\n // Copy to new location and delete old\n this.setValueAtPath(this.tomlData!, newSegments, oldValue);\n this.deleteValueAtPath(this.tomlData!, oldSegments);\n await this.saveToFile();\n\n return {\n message: `Successfully renamed '${normalizedOldPath}' to '${normalizedNewPath}'`,\n };\n }\n\n @Search(\"/:path*\")\n async searchHandler(\n ctx: RouteContext<{ path?: string }>,\n query: string,\n options?: AFSSearchOptions,\n ): Promise<{ data: AFSEntry[]; message?: string }> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const limit = Math.min(options?.limit || LIST_MAX_LIMIT, LIST_MAX_LIMIT);\n const caseSensitive = options?.caseSensitive ?? false;\n\n const segments = this.getPathSegments(normalizedPath);\n const rootValue = this.getValueAtPath(this.tomlData, segments);\n\n if (rootValue === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n const entries: AFSEntry[] = [];\n const searchQuery = caseSensitive ? query : query.toLowerCase();\n\n const searchInValue = (valuePath: string, value: unknown): void => {\n if (entries.length >= limit) return;\n\n let matched = false;\n\n // Search in the value itself\n if (!this.isDirectoryValue(value)) {\n const valueStr = typeof value === \"string\" ? value : JSON.stringify(value);\n const searchValue = caseSensitive ? valueStr : valueStr.toLowerCase();\n if (searchValue.includes(searchQuery)) {\n matched = true;\n }\n }\n\n if (matched) {\n entries.push(this.valueToAFSEntry(valuePath, value));\n }\n\n // Recursively search children\n if (this.isDirectoryValue(value)) {\n const children = this.getChildren(value);\n for (const child of children) {\n if (entries.length >= limit) break;\n const childPath = valuePath === \"/\" ? `/${child.key}` : `${valuePath}/${child.key}`;\n searchInValue(childPath, child.value);\n }\n }\n };\n\n searchInValue(normalizedPath, rootValue);\n\n return {\n data: entries,\n message: entries.length >= limit ? `Results truncated to limit ${limit}` : undefined,\n };\n }\n\n @Stat(\"/:path*\")\n async statHandler(ctx: RouteContext<{ path?: string }>): Promise<AFSStatResult> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const segments = this.getPathSegments(normalizedPath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n const isDir = this.isDirectoryValue(value);\n const children = isDir ? this.getChildren(value) : [];\n const meta = this.loadMeta(normalizedPath);\n\n return {\n data: {\n path: normalizedPath,\n childrenCount: isDir ? children.length : undefined,\n created: this.fileStats.birthtime,\n modified: this.fileStats.mtime,\n meta: meta ?? undefined,\n },\n };\n }\n\n // ========== Private Helper Methods ==========\n\n /**\n * Check if a key is a hidden meta key that should be filtered from listings\n */\n private isMetaKey(key: string): boolean {\n return key === AFS_KEY;\n }\n\n /**\n * Load metadata for a node.\n *\n * Storage location depends on node type (mirrors FS provider's .afs structure):\n * - Objects: `.afs.meta` key within the object itself\n * - Primitives: parent's `.afs[\".nodes\"][key].meta`\n */\n private loadMeta(nodePath: string): Record<string, unknown> | null {\n const segments = this.getPathSegments(nodePath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n return null;\n }\n\n if (this.isDirectoryValue(value) && !Array.isArray(value)) {\n // Object: meta is in value[\".afs\"].meta\n const afs = (value as Record<string, unknown>)[AFS_KEY];\n if (afs && typeof afs === \"object\" && !Array.isArray(afs)) {\n const meta = (afs as Record<string, unknown>)[META_KEY];\n if (meta && typeof meta === \"object\" && !Array.isArray(meta)) {\n return meta as Record<string, unknown>;\n }\n }\n return null;\n }\n\n // Primitive or array: meta is in parent's .afs[\".nodes\"][key].meta\n if (segments.length === 0) {\n // Root is always an object, handled above\n return null;\n }\n\n const parentSegments = segments.slice(0, -1);\n const nodeKey = segments[segments.length - 1]!;\n const parentValue = this.getValueAtPath(this.tomlData, parentSegments);\n\n if (!parentValue || Array.isArray(parentValue) || typeof parentValue !== \"object\") {\n return null;\n }\n\n const afs = (parentValue as Record<string, unknown>)[AFS_KEY];\n if (!afs || typeof afs !== \"object\" || Array.isArray(afs)) {\n return null;\n }\n\n const nodes = (afs as Record<string, unknown>)[NODES_KEY];\n if (!nodes || typeof nodes !== \"object\" || Array.isArray(nodes)) {\n return null;\n }\n\n const nodeEntry = (nodes as Record<string, unknown>)[nodeKey];\n if (!nodeEntry || typeof nodeEntry !== \"object\" || Array.isArray(nodeEntry)) {\n return null;\n }\n\n const meta = (nodeEntry as Record<string, unknown>)[META_KEY];\n if (!meta || typeof meta !== \"object\" || Array.isArray(meta)) {\n return null;\n }\n\n return meta as Record<string, unknown>;\n }\n\n /**\n * Save metadata for a node.\n *\n * Storage location depends on node type (mirrors FS provider's .afs structure):\n * - Objects: `.afs.meta` key within the object itself\n * - Primitives: parent's `.afs[\".nodes\"][key].meta`\n */\n private saveMeta(nodePath: string, meta: Record<string, unknown>): void {\n const segments = this.getPathSegments(nodePath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(nodePath);\n }\n\n if (this.isDirectoryValue(value) && !Array.isArray(value)) {\n // Object: store in value[\".afs\"].meta\n const obj = value as Record<string, unknown>;\n if (!obj[AFS_KEY]) {\n obj[AFS_KEY] = {};\n }\n // Store in .meta key\n (obj[AFS_KEY] as Record<string, unknown>)[META_KEY] = meta;\n return;\n }\n\n // Primitive or array: store in parent's .afs[\".nodes\"][key].meta\n if (segments.length === 0) {\n throw new Error(\"Cannot save meta for root when root is not an object\");\n }\n\n const parentSegments = segments.slice(0, -1);\n const nodeKey = segments[segments.length - 1]!;\n const parentValue = this.getValueAtPath(this.tomlData, parentSegments);\n\n if (!parentValue || typeof parentValue !== \"object\") {\n throw new Error(`Parent path is not an object`);\n }\n\n if (Array.isArray(parentValue)) {\n throw new Error(`Cannot save meta for array elements`);\n }\n\n const parentObj = parentValue as Record<string, unknown>;\n\n // Ensure .afs exists\n if (!parentObj[AFS_KEY]) {\n parentObj[AFS_KEY] = {};\n }\n\n // Ensure .afs[\".nodes\"] exists\n const afs = parentObj[AFS_KEY] as Record<string, unknown>;\n if (!afs[NODES_KEY]) {\n afs[NODES_KEY] = {};\n }\n\n // Ensure .afs[\".nodes\"][nodeKey] exists\n const nodes = afs[NODES_KEY] as Record<string, unknown>;\n if (!nodes[nodeKey]) {\n nodes[nodeKey] = {};\n }\n\n // Store the meta in .meta key\n (nodes[nodeKey] as Record<string, unknown>)[META_KEY] = meta;\n }\n\n /**\n * Load TOML data from file. Called lazily on first access.\n */\n private async ensureLoaded(): Promise<void> {\n if (this.tomlData !== null) return;\n\n try {\n const stats = await stat(this.resolvedTomlPath);\n this.fileStats = {\n birthtime: stats.birthtime,\n mtime: stats.mtime,\n };\n\n const content = await readFile(this.resolvedTomlPath, \"utf8\");\n this.tomlData = parseTOML(content);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n // File doesn't exist yet, start with empty object\n this.tomlData = {};\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Save TOML data back to file. Only called in readwrite mode.\n */\n private async saveToFile(): Promise<void> {\n const content = stringifyTOML(this.tomlData as Record<string, unknown>);\n await writeFile(this.resolvedTomlPath, content, \"utf8\");\n\n // Update file stats\n const stats = await stat(this.resolvedTomlPath);\n this.fileStats = {\n birthtime: this.fileStats.birthtime || stats.birthtime,\n mtime: stats.mtime,\n };\n }\n\n /**\n * Get path segments from normalized path\n */\n private getPathSegments(path: string): string[] {\n const normalized = this.normalizePath(path);\n if (normalized === \"/\") return [];\n return normalized.slice(1).split(\"/\");\n }\n\n /**\n * Navigate to a value in the TOML structure using path segments\n */\n private getValueAtPath(data: unknown, segments: string[]): unknown {\n let current = data;\n for (const segment of segments) {\n if (current == null) return undefined;\n\n // Handle array indices\n if (Array.isArray(current)) {\n const index = Number.parseInt(segment, 10);\n if (Number.isNaN(index) || index < 0 || index >= current.length) {\n return undefined;\n }\n current = current[index];\n } else if (typeof current === \"object\") {\n current = (current as Record<string, unknown>)[segment];\n } else {\n return undefined;\n }\n }\n return current;\n }\n\n /**\n * Set a value in the TOML structure at the given path\n */\n private setValueAtPath(data: Record<string, unknown>, segments: string[], value: unknown): void {\n if (segments.length === 0) {\n throw new Error(\"Cannot set value at root path\");\n }\n\n let current: unknown = data;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i]!;\n const nextSegment = segments[i + 1]!;\n\n if (Array.isArray(current)) {\n const index = Number.parseInt(segment, 10);\n if (Number.isNaN(index) || index < 0) {\n throw new Error(`Invalid array index: ${segment}`);\n }\n\n // Extend array if necessary\n while (current.length <= index) {\n current.push(null);\n }\n\n if (current[index] == null) {\n // Determine if next level should be array or object\n const isNextArray = !Number.isNaN(Number.parseInt(nextSegment, 10));\n current[index] = isNextArray ? [] : {};\n }\n current = current[index];\n } else if (typeof current === \"object\" && current !== null) {\n const obj = current as Record<string, unknown>;\n if (obj[segment] == null) {\n // Determine if next level should be array or object\n const isNextArray = !Number.isNaN(Number.parseInt(nextSegment, 10));\n obj[segment] = isNextArray ? [] : {};\n }\n current = obj[segment];\n } else {\n throw new Error(\n `Cannot set property on non-object at ${segments.slice(0, i + 1).join(\"/\")}`,\n );\n }\n }\n\n const lastSegment = segments[segments.length - 1]!;\n if (Array.isArray(current)) {\n const index = Number.parseInt(lastSegment, 10);\n if (Number.isNaN(index) || index < 0) {\n throw new Error(`Invalid array index: ${lastSegment}`);\n }\n current[index] = value;\n } else if (typeof current === \"object\" && current !== null) {\n (current as Record<string, unknown>)[lastSegment] = value;\n } else {\n throw new Error(\"Cannot set property on non-object\");\n }\n }\n\n /**\n * Delete a value from the TOML structure at the given path\n */\n private deleteValueAtPath(data: Record<string, unknown>, segments: string[]): boolean {\n if (segments.length === 0) {\n throw new Error(\"Cannot delete root path\");\n }\n\n let current: unknown = data;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i]!;\n\n if (Array.isArray(current)) {\n const index = Number.parseInt(segment, 10);\n if (Number.isNaN(index) || index < 0 || index >= current.length) {\n return false;\n }\n current = current[index];\n } else if (typeof current === \"object\" && current !== null) {\n const obj = current as Record<string, unknown>;\n if (!(segment in obj)) return false;\n current = obj[segment];\n } else {\n return false;\n }\n }\n\n const lastSegment = segments[segments.length - 1]!;\n if (Array.isArray(current)) {\n const index = Number.parseInt(lastSegment, 10);\n if (Number.isNaN(index) || index < 0 || index >= current.length) {\n return false;\n }\n current.splice(index, 1);\n return true;\n }\n if (typeof current === \"object\" && current !== null) {\n const obj = current as Record<string, unknown>;\n if (!(lastSegment in obj)) return false;\n delete obj[lastSegment];\n return true;\n }\n return false;\n }\n\n /**\n * Check if a value is a \"directory\" (object or array with children)\n */\n private isDirectoryValue(value: unknown): boolean {\n if (Array.isArray(value)) return true;\n if (typeof value === \"object\" && value !== null) {\n // Check if it's a Date object (TOML datetime)\n if (value instanceof Date) return false;\n return true;\n }\n return false;\n }\n\n /**\n * Get children of a directory value (filters out .afs meta key)\n */\n private getChildren(value: unknown): Array<{ key: string; value: unknown }> {\n if (Array.isArray(value)) {\n return value.map((item, index) => ({ key: String(index), value: item }));\n }\n if (typeof value === \"object\" && value !== null && !(value instanceof Date)) {\n return Object.entries(value)\n .filter(([key]) => !this.isMetaKey(key))\n .map(([key, val]) => ({ key, value: val }));\n }\n return [];\n }\n\n /**\n * Convert a TOML value to an AFSEntry\n */\n private valueToAFSEntry(path: string, value: unknown): AFSEntry {\n const isDir = this.isDirectoryValue(value);\n const children = isDir ? this.getChildren(value) : [];\n\n return this.buildEntry(path, {\n content: isDir ? undefined : value,\n metadata: {\n childrenCount: isDir ? children.length : undefined,\n },\n createdAt: this.fileStats.birthtime,\n updatedAt: this.fileStats.mtime,\n });\n }\n}\n\nconst _typeCheck: AFSModuleClass<AFSTOML, AFSTOMLOptions> = AFSTOML;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["afs","meta","parseTOML","stringifyTOML"],"sources":["../src/index.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { readFile, stat, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join } from \"node:path\";\nimport {\n type AFSAccessMode,\n type AFSDeleteOptions,\n type AFSEntry,\n type AFSEntryMetadata,\n type AFSExplainOptions,\n type AFSExplainResult,\n type AFSListResult,\n type AFSModuleClass,\n type AFSModuleLoadParams,\n AFSNotFoundError,\n type AFSRenameOptions,\n type AFSSearchOptions,\n type AFSStatResult,\n type AFSWriteEntryPayload,\n type CapabilitiesManifest,\n type ProviderManifest,\n} from \"@aigne/afs\";\nimport {\n AFSBaseProvider,\n Delete,\n Explain,\n List,\n Meta,\n Read,\n Rename,\n type RouteContext,\n Search,\n Stat,\n Write,\n} from \"@aigne/afs/provider\";\nimport { camelize, optionalize, zodParse } from \"@aigne/afs/utils/zod\";\nimport { parse as parseTOML, stringify as stringifyTOML } from \"smol-toml\";\nimport { joinURL } from \"ufo\";\nimport { z } from \"zod\";\n\nconst LIST_MAX_LIMIT = 1000;\n\n/** Hidden key for storing AFS metadata (mirrors FS provider's .afs directory) */\nconst AFS_KEY = \".afs\";\n\n/** Subkey for storing metadata (mirrors FS provider's meta.yaml file) */\nconst META_KEY = \"meta\";\n\n/** Subkey for storing child node metadata (mirrors FS provider's .nodes directory) */\nconst NODES_KEY = \".nodes\";\n\nexport interface AFSTOMLOptions {\n name?: string;\n tomlPath: string;\n description?: string;\n /**\n * Access mode for this module.\n * - \"readonly\": Only read operations are allowed\n * - \"readwrite\": All operations are allowed (default)\n * @default \"readwrite\"\n */\n accessMode?: AFSAccessMode;\n}\n\nconst afsTOMLOptionsSchema = camelize(\n z.object({\n name: optionalize(z.string()),\n tomlPath: z.string().describe(\"The path to the TOML file to mount\"),\n description: optionalize(z.string().describe(\"A description of the TOML module\")),\n accessMode: optionalize(\n z.enum([\"readonly\", \"readwrite\"]).describe(\"Access mode for this module\"),\n ),\n }),\n);\n\n/**\n * AFS module for mounting TOML files as virtual file systems.\n *\n * TOML tables are treated as directories, and properties as files.\n * Supports nested structures and path-based access to data values.\n */\nexport class AFSTOML extends AFSBaseProvider {\n static schema() {\n return afsTOMLOptionsSchema;\n }\n\n static manifest(): ProviderManifest {\n return {\n name: \"toml\",\n description: \"Mount a TOML file as a virtual filesystem\",\n uriTemplate: \"toml://{localPath+}\",\n category: \"structured-data\",\n schema: z.object({ localPath: z.string() }),\n tags: [\"toml\", \"structured-data\"],\n };\n }\n\n static async load({ basePath, config }: AFSModuleLoadParams = {}) {\n const valid = await AFSTOML.schema().parseAsync(config);\n return new AFSTOML({ ...valid, cwd: basePath });\n }\n\n readonly name: string;\n readonly description?: string;\n readonly accessMode: AFSAccessMode;\n\n private tomlData: Record<string, unknown> | null = null;\n private fileStats: {\n birthtime?: Date;\n mtime?: Date;\n } = {};\n private resolvedTomlPath: string;\n\n constructor(public options: AFSTOMLOptions & { cwd?: string; localPath?: string; uri?: string }) {\n super();\n\n // Normalize registry-passed template vars: localPath → tomlPath\n if ((options as any).localPath && !options.tomlPath) {\n options.tomlPath = (options as any).localPath;\n }\n\n zodParse(afsTOMLOptionsSchema, options);\n\n let tomlPath: string;\n\n tomlPath = options.tomlPath.replaceAll(\"${CWD}\", process.cwd());\n if (tomlPath.startsWith(\"~/\")) {\n tomlPath = join(process.env.HOME || \"\", tomlPath.slice(2));\n }\n if (!isAbsolute(tomlPath)) {\n tomlPath = join(options.cwd || process.cwd(), tomlPath);\n }\n\n // Auto-create TOML file if it doesn't exist\n if (!existsSync(tomlPath)) {\n mkdirSync(dirname(tomlPath), { recursive: true });\n writeFileSync(tomlPath, \"\", \"utf8\");\n }\n\n // Extract name without extension\n let name = basename(tomlPath);\n if (name.endsWith(\".toml\")) {\n name = name.slice(0, -5);\n }\n\n this.name = options.name || name || \"toml\";\n this.description = options.description;\n this.accessMode = options.accessMode ?? \"readwrite\";\n this.resolvedTomlPath = tomlPath;\n }\n\n // ========== Meta Handlers ==========\n // Meta is read-only introspection. Metadata writes are handled by @Write via payload.meta.\n //\n // Meta storage strategy (mirrors FS provider's .afs directory):\n // - For tables (directories): metadata stored in `.afs.meta` key within the table\n // - For primitives (files): metadata stored in parent's `.afs[\".nodes\"][key].meta` structure\n\n /**\n * Read metadata for a TOML node via /.meta or /path/.meta\n * Returns stored metadata merged with computed type information\n * Note: Meta is read-only. To write metadata, use write() with payload.meta.\n */\n @Meta(\"/:path*\")\n async readMetaHandler(ctx: RouteContext<{ path?: string }>): Promise<AFSEntry | undefined> {\n await this.ensureLoaded();\n\n const nodePath = joinURL(\"/\", ctx.params.path ?? \"\");\n const segments = this.getPathSegments(nodePath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(nodePath);\n }\n\n const isDir = this.isDirectoryValue(value);\n const children = isDir ? this.getChildren(value) : [];\n\n // Determine the value type\n let type: string;\n if (Array.isArray(value)) {\n type = \"array\";\n } else if (value === null) {\n type = \"null\";\n } else if (value instanceof Date) {\n type = \"datetime\";\n } else if (typeof value === \"object\") {\n type = \"table\";\n } else {\n type = typeof value;\n }\n\n // Load stored user-defined metadata\n const storedMeta = this.loadMeta(nodePath) || {};\n\n // Build computed metadata (type info, etc.)\n const computedMeta: Record<string, unknown> = {\n type,\n path: nodePath,\n };\n\n if (isDir) {\n computedMeta.childrenCount = children.length;\n if (Array.isArray(value)) {\n computedMeta.length = value.length;\n } else {\n // Filter out internal keys from keys list\n computedMeta.keys = Object.keys(value as Record<string, unknown>).filter(\n (k) => !this.isMetaKey(k),\n );\n }\n } else {\n computedMeta.value = value;\n }\n\n if (this.fileStats.birthtime) {\n computedMeta.created = this.fileStats.birthtime;\n }\n if (this.fileStats.mtime) {\n computedMeta.modified = this.fileStats.mtime;\n }\n\n return this.buildEntry(joinURL(nodePath, \".meta\"), {\n // User-defined metadata goes in metadata field (for conformance)\n meta: storedMeta as AFSEntryMetadata,\n // Computed type info goes in content (TOML-specific)\n content: computedMeta,\n createdAt: this.fileStats.birthtime,\n updatedAt: this.fileStats.mtime,\n });\n }\n\n // ========== Route Handlers ==========\n\n /**\n * Note: list() returns only children, never the path itself (per new semantics)\n */\n @List(\"/:path*\", { handleDepth: true })\n async listHandler(\n ctx: RouteContext<{ path?: string }>,\n ): Promise<AFSListResult & { noExpand?: string[] }> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const options = ctx.options as { limit?: number; maxChildren?: number; maxDepth?: number };\n const limit = Math.min(options?.limit || LIST_MAX_LIMIT, LIST_MAX_LIMIT);\n const maxChildren =\n typeof options?.maxChildren === \"number\" ? options.maxChildren : Number.MAX_SAFE_INTEGER;\n const maxDepth = options?.maxDepth ?? 1;\n\n const segments = this.getPathSegments(normalizedPath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n // maxDepth=0 means no children\n if (maxDepth === 0) {\n return { data: [] };\n }\n\n // If the value is not a directory, it has no children\n if (!this.isDirectoryValue(value)) {\n return { data: [] };\n }\n\n const entries: AFSEntry[] = [];\n\n interface QueueItem {\n path: string;\n value: unknown;\n depth: number;\n }\n\n // Start with immediate children at depth 1 (not the path itself at depth 0)\n const rootChildren = this.getChildren(value);\n const rootChildrenToProcess =\n rootChildren.length > maxChildren ? rootChildren.slice(0, maxChildren) : rootChildren;\n\n const queue: QueueItem[] = rootChildrenToProcess.map((child) => ({\n path: normalizedPath === \"/\" ? `/${child.key}` : `${normalizedPath}/${child.key}`,\n value: child.value,\n depth: 1,\n }));\n\n while (queue.length > 0) {\n const item = queue.shift();\n if (!item) break;\n\n const { path: itemPath, value: itemValue, depth } = item;\n\n const entry = this.valueToAFSEntry(itemPath, itemValue);\n entries.push(entry);\n\n if (entries.length >= limit) {\n break;\n }\n\n // Process children if within depth limit\n if (this.isDirectoryValue(itemValue) && depth < maxDepth) {\n const children = this.getChildren(itemValue);\n const childrenToProcess =\n children.length > maxChildren ? children.slice(0, maxChildren) : children;\n\n for (const child of childrenToProcess) {\n const childPath = itemPath === \"/\" ? `/${child.key}` : `${itemPath}/${child.key}`;\n queue.push({\n path: childPath,\n value: child.value,\n depth: depth + 1,\n });\n }\n }\n }\n\n return { data: entries };\n }\n\n @Read(\"/:path*\")\n async readHandler(ctx: RouteContext<{ path?: string }>): Promise<AFSEntry | undefined> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const segments = this.getPathSegments(normalizedPath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n return this.valueToAFSEntry(normalizedPath, value);\n }\n\n /**\n * Write handler - supports writing content and/or metadata\n *\n * | payload | behavior |\n * |---------|----------|\n * | { content } | write content only |\n * | { metadata } | write metadata only (to .afs storage) |\n * | { content, metadata } | write both |\n */\n @Write(\"/:path*\")\n async writeHandler(\n ctx: RouteContext<{ path?: string }>,\n payload: AFSWriteEntryPayload,\n ): Promise<{ data: AFSEntry }> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const segments = this.getPathSegments(normalizedPath);\n\n // Write content if provided\n if (payload.content !== undefined) {\n this.setValueAtPath(this.tomlData!, segments, payload.content);\n }\n\n // Write metadata if provided (merge with existing)\n if (payload.meta !== undefined && typeof payload.meta === \"object\") {\n const existingMeta = this.loadMeta(normalizedPath) || {};\n const finalMeta = { ...existingMeta, ...payload.meta };\n this.saveMeta(normalizedPath, finalMeta);\n }\n\n // Save back to file\n await this.saveToFile();\n\n const newValue = this.getValueAtPath(this.tomlData, segments);\n const isDir = this.isDirectoryValue(newValue);\n const children = isDir ? this.getChildren(newValue) : [];\n\n // Load stored metadata for response\n const storedMeta = this.loadMeta(normalizedPath) || {};\n\n const writtenEntry: AFSEntry = {\n id: normalizedPath,\n path: normalizedPath,\n content: payload.content !== undefined ? payload.content : newValue,\n summary: payload.summary,\n createdAt: this.fileStats.birthtime,\n updatedAt: this.fileStats.mtime,\n meta: {\n ...storedMeta,\n childrenCount: isDir ? children.length : undefined,\n } as AFSEntryMetadata,\n userId: payload.userId,\n sessionId: payload.sessionId,\n linkTo: payload.linkTo,\n };\n\n return { data: writtenEntry };\n }\n\n @Delete(\"/:path*\")\n async deleteHandler(ctx: RouteContext<{ path?: string }>): Promise<{ message: string }> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const options = ctx.options as AFSDeleteOptions | undefined;\n const segments = this.getPathSegments(normalizedPath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n const hasChildren = this.isDirectoryValue(value) && this.getChildren(value).length > 0;\n if (hasChildren && !options?.recursive) {\n throw new Error(\n `Cannot delete directory '${normalizedPath}' without recursive option. Set recursive: true to delete directories.`,\n );\n }\n\n this.deleteValueAtPath(this.tomlData!, segments);\n await this.saveToFile();\n\n return { message: `Successfully deleted: ${normalizedPath}` };\n }\n\n @Rename(\"/:path*\")\n async renameHandler(\n ctx: RouteContext<{ path?: string }>,\n newPath: string,\n ): Promise<{ message: string }> {\n await this.ensureLoaded();\n\n const normalizedOldPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const normalizedNewPath = this.normalizePath(newPath);\n const options = ctx.options as AFSRenameOptions | undefined;\n\n const oldSegments = this.getPathSegments(normalizedOldPath);\n const newSegments = this.getPathSegments(normalizedNewPath);\n\n const oldValue = this.getValueAtPath(this.tomlData, oldSegments);\n if (oldValue === undefined) {\n throw new AFSNotFoundError(normalizedOldPath);\n }\n\n const existingNewValue = this.getValueAtPath(this.tomlData, newSegments);\n if (existingNewValue !== undefined && !options?.overwrite) {\n throw new Error(\n `Destination '${normalizedNewPath}' already exists. Set overwrite: true to replace it.`,\n );\n }\n\n // Copy to new location and delete old\n this.setValueAtPath(this.tomlData!, newSegments, oldValue);\n this.deleteValueAtPath(this.tomlData!, oldSegments);\n await this.saveToFile();\n\n return {\n message: `Successfully renamed '${normalizedOldPath}' to '${normalizedNewPath}'`,\n };\n }\n\n @Search(\"/:path*\")\n async searchHandler(\n ctx: RouteContext<{ path?: string }>,\n query: string,\n options?: AFSSearchOptions,\n ): Promise<{ data: AFSEntry[]; message?: string }> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const limit = Math.min(options?.limit || LIST_MAX_LIMIT, LIST_MAX_LIMIT);\n const caseSensitive = options?.caseSensitive ?? false;\n\n const segments = this.getPathSegments(normalizedPath);\n const rootValue = this.getValueAtPath(this.tomlData, segments);\n\n if (rootValue === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n const entries: AFSEntry[] = [];\n const searchQuery = caseSensitive ? query : query.toLowerCase();\n\n const searchInValue = (valuePath: string, value: unknown): void => {\n if (entries.length >= limit) return;\n\n let matched = false;\n\n // Search in the value itself\n if (!this.isDirectoryValue(value)) {\n const valueStr = typeof value === \"string\" ? value : JSON.stringify(value);\n const searchValue = caseSensitive ? valueStr : valueStr.toLowerCase();\n if (searchValue.includes(searchQuery)) {\n matched = true;\n }\n }\n\n if (matched) {\n entries.push(this.valueToAFSEntry(valuePath, value));\n }\n\n // Recursively search children\n if (this.isDirectoryValue(value)) {\n const children = this.getChildren(value);\n for (const child of children) {\n if (entries.length >= limit) break;\n const childPath = valuePath === \"/\" ? `/${child.key}` : `${valuePath}/${child.key}`;\n searchInValue(childPath, child.value);\n }\n }\n };\n\n searchInValue(normalizedPath, rootValue);\n\n return {\n data: entries,\n message: entries.length >= limit ? `Results truncated to limit ${limit}` : undefined,\n };\n }\n\n @Stat(\"/:path*\")\n async statHandler(ctx: RouteContext<{ path?: string }>): Promise<AFSStatResult> {\n await this.ensureLoaded();\n\n const normalizedPath = ctx.params.path ? `/${ctx.params.path}` : \"/\";\n const segments = this.getPathSegments(normalizedPath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n const isDir = this.isDirectoryValue(value);\n const children = isDir ? this.getChildren(value) : [];\n const loadedMeta = this.loadMeta(normalizedPath);\n const meta: Record<string, unknown> = { ...loadedMeta };\n if (isDir) {\n meta.childrenCount = children.length;\n }\n\n const id = segments.length > 0 ? (segments[segments.length - 1] as string) : \"/\";\n\n return {\n data: {\n id,\n path: normalizedPath,\n createdAt: this.fileStats.birthtime,\n updatedAt: this.fileStats.mtime,\n meta,\n },\n };\n }\n\n // ========== Explain & Capabilities ==========\n\n @Read(\"/.meta/.capabilities\")\n async readCapabilitiesHandler(_ctx: RouteContext): Promise<AFSEntry | undefined> {\n await this.ensureLoaded();\n\n const operations = [\"list\", \"read\", \"stat\", \"explain\", \"search\"];\n if (this.accessMode === \"readwrite\") {\n operations.push(\"write\", \"delete\", \"rename\");\n }\n\n const manifest: CapabilitiesManifest = {\n schemaVersion: 1,\n provider: this.name,\n description: this.description || \"TOML virtual filesystem\",\n tools: [],\n actions: [],\n operations: this.getOperationsDeclaration(),\n };\n\n return {\n id: \"/.meta/.capabilities\",\n path: \"/.meta/.capabilities\",\n content: manifest,\n meta: { kind: \"afs:capabilities\", operations },\n };\n }\n\n @Explain(\"/:path*\")\n async explainHandler(ctx: RouteContext<{ path?: string }>): Promise<AFSExplainResult> {\n await this.ensureLoaded();\n\n const normalizedPath = joinURL(\"/\", ctx.params.path ?? \"\");\n const format = (ctx.options as AFSExplainOptions)?.format || \"markdown\";\n const segments = this.getPathSegments(normalizedPath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(normalizedPath);\n }\n\n const nodeName = segments.length > 0 ? segments[segments.length - 1]! : \"/\";\n const isDir = this.isDirectoryValue(value);\n const storedMeta = this.loadMeta(normalizedPath);\n const lines: string[] = [];\n\n if (format === \"markdown\") {\n lines.push(`# ${nodeName}`);\n lines.push(\"\");\n lines.push(`**Path:** \\`${normalizedPath}\\``);\n lines.push(`**Format:** TOML`);\n\n if (normalizedPath === \"/\") {\n // Root: describe file, top-level key list\n const children = this.getChildren(this.tomlData);\n lines.push(`**Top-level keys:** ${children.length}`);\n if (children.length > 0) {\n lines.push(\"\");\n lines.push(\"## Keys\");\n lines.push(\"\");\n for (const child of children.slice(0, 30)) {\n const childType = this.describeType(child.value);\n lines.push(`- \\`${child.key}\\` — ${childType}`);\n }\n if (children.length > 30) {\n lines.push(`- ... and ${children.length - 30} more`);\n }\n }\n } else if (Array.isArray(value)) {\n // Array of tables\n lines.push(`**Type:** array of tables`);\n lines.push(`**Elements:** ${value.length}`);\n if (value.length > 0) {\n const elementType = this.describeType(value[0]);\n lines.push(`**Element type:** ${elementType}`);\n }\n } else if (typeof value === \"object\" && value !== null) {\n // TOML table\n const children = this.getChildren(value);\n lines.push(`**Type:** table`);\n lines.push(`**Keys:** ${children.length}`);\n if (children.length > 0) {\n lines.push(\"\");\n lines.push(\"## Keys\");\n lines.push(\"\");\n for (const child of children.slice(0, 30)) {\n const childType = this.describeType(child.value);\n lines.push(`- \\`${child.key}\\` — ${childType}`);\n }\n if (children.length > 30) {\n lines.push(`- ... and ${children.length - 30} more`);\n }\n }\n } else {\n // Primitive value\n const valType = value === null ? \"null\" : typeof value;\n lines.push(`**Type:** ${valType}`);\n const valStr = String(value);\n if (valStr.length > 200) {\n lines.push(`**Value:** ${valStr.slice(0, 200)}...`);\n } else {\n lines.push(`**Value:** ${valStr}`);\n }\n }\n\n if (storedMeta) {\n lines.push(\"\");\n lines.push(\"## Metadata\");\n for (const [key, val] of Object.entries(storedMeta)) {\n lines.push(`- **${key}:** ${JSON.stringify(val)}`);\n }\n }\n } else {\n // text format\n lines.push(`${nodeName} (${isDir ? \"table\" : \"value\"})`);\n lines.push(`Path: ${normalizedPath}`);\n lines.push(`Format: TOML`);\n if (isDir) {\n const children = this.getChildren(value);\n lines.push(`Children: ${children.length}`);\n } else {\n const valStr = String(value);\n lines.push(`Type: ${value === null ? \"null\" : typeof value}`);\n lines.push(`Value: ${valStr.length > 200 ? `${valStr.slice(0, 200)}...` : valStr}`);\n }\n }\n\n return { content: lines.join(\"\\n\"), format };\n }\n\n /**\n * Get a human-readable type description for a TOML value.\n */\n private describeType(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (value instanceof Date) return \"datetime\";\n if (Array.isArray(value)) return `array[${value.length}]`;\n if (typeof value === \"object\") {\n const keys = Object.keys(value).filter((k) => !this.isMetaKey(k));\n return `table{${keys.length} keys}`;\n }\n return typeof value;\n }\n\n // ========== Private Helper Methods ==========\n\n /**\n * Check if a key is a hidden meta key that should be filtered from listings\n */\n private isMetaKey(key: string): boolean {\n return key === AFS_KEY;\n }\n\n /**\n * Load metadata for a node.\n *\n * Storage location depends on node type (mirrors FS provider's .afs structure):\n * - Objects: `.afs.meta` key within the object itself\n * - Primitives: parent's `.afs[\".nodes\"][key].meta`\n */\n private loadMeta(nodePath: string): Record<string, unknown> | null {\n const segments = this.getPathSegments(nodePath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n return null;\n }\n\n if (this.isDirectoryValue(value) && !Array.isArray(value)) {\n // Object: meta is in value[\".afs\"].meta\n const afs = (value as Record<string, unknown>)[AFS_KEY];\n if (afs && typeof afs === \"object\" && !Array.isArray(afs)) {\n const meta = (afs as Record<string, unknown>)[META_KEY];\n if (meta && typeof meta === \"object\" && !Array.isArray(meta)) {\n return meta as Record<string, unknown>;\n }\n }\n return null;\n }\n\n // Primitive or array: meta is in parent's .afs[\".nodes\"][key].meta\n if (segments.length === 0) {\n // Root is always an object, handled above\n return null;\n }\n\n const parentSegments = segments.slice(0, -1);\n const nodeKey = segments[segments.length - 1]!;\n const parentValue = this.getValueAtPath(this.tomlData, parentSegments);\n\n if (!parentValue || Array.isArray(parentValue) || typeof parentValue !== \"object\") {\n return null;\n }\n\n const afs = (parentValue as Record<string, unknown>)[AFS_KEY];\n if (!afs || typeof afs !== \"object\" || Array.isArray(afs)) {\n return null;\n }\n\n const nodes = (afs as Record<string, unknown>)[NODES_KEY];\n if (!nodes || typeof nodes !== \"object\" || Array.isArray(nodes)) {\n return null;\n }\n\n const nodeEntry = (nodes as Record<string, unknown>)[nodeKey];\n if (!nodeEntry || typeof nodeEntry !== \"object\" || Array.isArray(nodeEntry)) {\n return null;\n }\n\n const meta = (nodeEntry as Record<string, unknown>)[META_KEY];\n if (!meta || typeof meta !== \"object\" || Array.isArray(meta)) {\n return null;\n }\n\n return meta as Record<string, unknown>;\n }\n\n /**\n * Save metadata for a node.\n *\n * Storage location depends on node type (mirrors FS provider's .afs structure):\n * - Objects: `.afs.meta` key within the object itself\n * - Primitives: parent's `.afs[\".nodes\"][key].meta`\n */\n private saveMeta(nodePath: string, meta: Record<string, unknown>): void {\n const segments = this.getPathSegments(nodePath);\n const value = this.getValueAtPath(this.tomlData, segments);\n\n if (value === undefined) {\n throw new AFSNotFoundError(nodePath);\n }\n\n if (this.isDirectoryValue(value) && !Array.isArray(value)) {\n // Object: store in value[\".afs\"].meta\n const obj = value as Record<string, unknown>;\n if (!obj[AFS_KEY]) {\n obj[AFS_KEY] = {};\n }\n // Store in .meta key\n (obj[AFS_KEY] as Record<string, unknown>)[META_KEY] = meta;\n return;\n }\n\n // Primitive or array: store in parent's .afs[\".nodes\"][key].meta\n if (segments.length === 0) {\n throw new Error(\"Cannot save meta for root when root is not an object\");\n }\n\n const parentSegments = segments.slice(0, -1);\n const nodeKey = segments[segments.length - 1]!;\n const parentValue = this.getValueAtPath(this.tomlData, parentSegments);\n\n if (!parentValue || typeof parentValue !== \"object\") {\n throw new Error(`Parent path is not an object`);\n }\n\n if (Array.isArray(parentValue)) {\n throw new Error(`Cannot save meta for array elements`);\n }\n\n const parentObj = parentValue as Record<string, unknown>;\n\n // Ensure .afs exists\n if (!parentObj[AFS_KEY]) {\n parentObj[AFS_KEY] = {};\n }\n\n // Ensure .afs[\".nodes\"] exists\n const afs = parentObj[AFS_KEY] as Record<string, unknown>;\n if (!afs[NODES_KEY]) {\n afs[NODES_KEY] = {};\n }\n\n // Ensure .afs[\".nodes\"][nodeKey] exists\n const nodes = afs[NODES_KEY] as Record<string, unknown>;\n if (!nodes[nodeKey]) {\n nodes[nodeKey] = {};\n }\n\n // Store the meta in .meta key\n (nodes[nodeKey] as Record<string, unknown>)[META_KEY] = meta;\n }\n\n /**\n * Load TOML data from file. Called lazily on first access.\n */\n private async ensureLoaded(): Promise<void> {\n if (this.tomlData !== null) return;\n\n try {\n const stats = await stat(this.resolvedTomlPath);\n this.fileStats = {\n birthtime: stats.birthtime,\n mtime: stats.mtime,\n };\n\n const content = await readFile(this.resolvedTomlPath, \"utf8\");\n this.tomlData = parseTOML(content);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n // File doesn't exist yet, start with empty object\n this.tomlData = {};\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Save TOML data back to file. Only called in readwrite mode.\n */\n private async saveToFile(): Promise<void> {\n const content = stringifyTOML(this.tomlData as Record<string, unknown>);\n await writeFile(this.resolvedTomlPath, content, \"utf8\");\n\n // Update file stats\n const stats = await stat(this.resolvedTomlPath);\n this.fileStats = {\n birthtime: this.fileStats.birthtime || stats.birthtime,\n mtime: stats.mtime,\n };\n }\n\n /**\n * Get path segments from normalized path\n */\n private getPathSegments(path: string): string[] {\n const normalized = this.normalizePath(path);\n if (normalized === \"/\") return [];\n return normalized.slice(1).split(\"/\");\n }\n\n /**\n * Navigate to a value in the TOML structure using path segments\n */\n private getValueAtPath(data: unknown, segments: string[]): unknown {\n let current = data;\n for (const segment of segments) {\n if (current == null) return undefined;\n\n // Handle array indices\n if (Array.isArray(current)) {\n const index = Number.parseInt(segment, 10);\n if (Number.isNaN(index) || index < 0 || index >= current.length) {\n return undefined;\n }\n current = current[index];\n } else if (typeof current === \"object\") {\n current = (current as Record<string, unknown>)[segment];\n } else {\n return undefined;\n }\n }\n return current;\n }\n\n /**\n * Set a value in the TOML structure at the given path\n */\n private setValueAtPath(data: Record<string, unknown>, segments: string[], value: unknown): void {\n if (segments.length === 0) {\n throw new Error(\"Cannot set value at root path\");\n }\n\n let current: unknown = data;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i]!;\n const nextSegment = segments[i + 1]!;\n\n if (Array.isArray(current)) {\n const index = Number.parseInt(segment, 10);\n if (Number.isNaN(index) || index < 0) {\n throw new Error(`Invalid array index: ${segment}`);\n }\n\n // Extend array if necessary\n while (current.length <= index) {\n current.push(null);\n }\n\n if (current[index] == null) {\n // Determine if next level should be array or object\n const isNextArray = !Number.isNaN(Number.parseInt(nextSegment, 10));\n current[index] = isNextArray ? [] : {};\n }\n current = current[index];\n } else if (typeof current === \"object\" && current !== null) {\n const obj = current as Record<string, unknown>;\n if (obj[segment] == null) {\n // Determine if next level should be array or object\n const isNextArray = !Number.isNaN(Number.parseInt(nextSegment, 10));\n obj[segment] = isNextArray ? [] : {};\n }\n current = obj[segment];\n } else {\n throw new Error(\n `Cannot set property on non-object at ${segments.slice(0, i + 1).join(\"/\")}`,\n );\n }\n }\n\n const lastSegment = segments[segments.length - 1]!;\n if (Array.isArray(current)) {\n const index = Number.parseInt(lastSegment, 10);\n if (Number.isNaN(index) || index < 0) {\n throw new Error(`Invalid array index: ${lastSegment}`);\n }\n current[index] = value;\n } else if (typeof current === \"object\" && current !== null) {\n (current as Record<string, unknown>)[lastSegment] = value;\n } else {\n throw new Error(\"Cannot set property on non-object\");\n }\n }\n\n /**\n * Delete a value from the TOML structure at the given path\n */\n private deleteValueAtPath(data: Record<string, unknown>, segments: string[]): boolean {\n if (segments.length === 0) {\n throw new Error(\"Cannot delete root path\");\n }\n\n let current: unknown = data;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i]!;\n\n if (Array.isArray(current)) {\n const index = Number.parseInt(segment, 10);\n if (Number.isNaN(index) || index < 0 || index >= current.length) {\n return false;\n }\n current = current[index];\n } else if (typeof current === \"object\" && current !== null) {\n const obj = current as Record<string, unknown>;\n if (!(segment in obj)) return false;\n current = obj[segment];\n } else {\n return false;\n }\n }\n\n const lastSegment = segments[segments.length - 1]!;\n if (Array.isArray(current)) {\n const index = Number.parseInt(lastSegment, 10);\n if (Number.isNaN(index) || index < 0 || index >= current.length) {\n return false;\n }\n current.splice(index, 1);\n return true;\n }\n if (typeof current === \"object\" && current !== null) {\n const obj = current as Record<string, unknown>;\n if (!(lastSegment in obj)) return false;\n delete obj[lastSegment];\n return true;\n }\n return false;\n }\n\n /**\n * Check if a value is a \"directory\" (object or array with children)\n */\n private isDirectoryValue(value: unknown): boolean {\n if (Array.isArray(value)) return true;\n if (typeof value === \"object\" && value !== null) {\n // Check if it's a Date object (TOML datetime)\n if (value instanceof Date) return false;\n return true;\n }\n return false;\n }\n\n /**\n * Get children of a directory value (filters out .afs meta key)\n */\n private getChildren(value: unknown): Array<{ key: string; value: unknown }> {\n if (Array.isArray(value)) {\n return value.map((item, index) => ({ key: String(index), value: item }));\n }\n if (typeof value === \"object\" && value !== null && !(value instanceof Date)) {\n return Object.entries(value)\n .filter(([key]) => !this.isMetaKey(key))\n .map(([key, val]) => ({ key, value: val }));\n }\n return [];\n }\n\n /**\n * Convert a TOML value to an AFSEntry\n */\n private valueToAFSEntry(path: string, value: unknown): AFSEntry {\n const isDir = this.isDirectoryValue(value);\n const children = isDir ? this.getChildren(value) : [];\n const kind = Array.isArray(value) ? \"toml:array\" : isDir ? \"toml:table\" : \"toml:value\";\n\n return this.buildEntry(path, {\n content: isDir ? undefined : value,\n meta: {\n kind,\n childrenCount: isDir ? children.length : undefined,\n },\n createdAt: this.fileStats.birthtime,\n updatedAt: this.fileStats.mtime,\n });\n }\n}\n\nconst _typeCheck: AFSModuleClass<AFSTOML, AFSTOMLOptions> = AFSTOML;\n\nexport default AFSTOML;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/afs-toml",
|
|
3
|
-
"version": "1.11.0-beta.
|
|
3
|
+
"version": "1.11.0-beta.8",
|
|
4
4
|
"description": "AIGNE AFS module for TOML file storage",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"publishConfig": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"smol-toml": "^1.4.1",
|
|
37
37
|
"ufo": "^1.6.3",
|
|
38
|
-
"zod": "^
|
|
39
|
-
"@aigne/afs": "^1.11.0-beta.
|
|
38
|
+
"zod": "^4.0.0",
|
|
39
|
+
"@aigne/afs": "^1.11.0-beta.8"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/bun": "^1.3.6",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"tsdown": "0.20.0-beta.3",
|
|
46
46
|
"typescript": "5.9.2",
|
|
47
47
|
"@aigne/scripts": "0.0.0",
|
|
48
|
-
"@aigne/typescript-config": "0.0.0"
|
|
48
|
+
"@aigne/typescript-config": "0.0.0",
|
|
49
|
+
"@aigne/afs-testing": "1.11.0-beta.8"
|
|
49
50
|
},
|
|
50
51
|
"scripts": {
|
|
51
52
|
"build": "tsdown",
|