@aigne/afs-explorer 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>AFS Explorer</title>
8
+ <script type="module" crossorigin src="/assets/index-viceiJOt.js"></script>
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,10 @@
1
+ import type { AFS } from "@aigne/afs";
2
+ import { ExplorerServer, type ExplorerServerOptions } from "./server.js";
3
+ export { ExplorerServer, type ExplorerServerOptions };
4
+ /**
5
+ * Start the AFS Explorer web server
6
+ * @param afs - The AFS instance to explore
7
+ * @param options - Server options
8
+ * @returns The ExplorerServer instance
9
+ */
10
+ export declare function startExplorer(afs: AFS, options?: ExplorerServerOptions): Promise<ExplorerServer>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExplorerServer = void 0;
4
+ exports.startExplorer = startExplorer;
5
+ const server_js_1 = require("./server.js");
6
+ Object.defineProperty(exports, "ExplorerServer", { enumerable: true, get: function () { return server_js_1.ExplorerServer; } });
7
+ /**
8
+ * Start the AFS Explorer web server
9
+ * @param afs - The AFS instance to explore
10
+ * @param options - Server options
11
+ * @returns The ExplorerServer instance
12
+ */
13
+ async function startExplorer(afs, options = {}) {
14
+ const server = new server_js_1.ExplorerServer(afs, options);
15
+ await server.start();
16
+ return server;
17
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,21 @@
1
+ import type { AFS } from "@aigne/afs";
2
+ export interface ExplorerServerOptions {
3
+ port?: number;
4
+ host?: string;
5
+ /**
6
+ * Path to the dist directory containing the built frontend.
7
+ * If not provided, static file serving will be disabled.
8
+ */
9
+ distPath?: string;
10
+ }
11
+ export declare class ExplorerServer {
12
+ private afs;
13
+ private options;
14
+ private app;
15
+ private server?;
16
+ constructor(afs: AFS, options?: ExplorerServerOptions);
17
+ private setupMiddleware;
18
+ private setupRoutes;
19
+ start(): Promise<void>;
20
+ stop(): Promise<void>;
21
+ }
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ExplorerServer = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const cors_1 = __importDefault(require("cors"));
9
+ const express_1 = __importDefault(require("express"));
10
+ class ExplorerServer {
11
+ afs;
12
+ options;
13
+ app;
14
+ server;
15
+ constructor(afs, options = {}) {
16
+ this.afs = afs;
17
+ this.options = options;
18
+ this.app = (0, express_1.default)();
19
+ this.setupMiddleware();
20
+ this.setupRoutes();
21
+ }
22
+ setupMiddleware() {
23
+ this.app.use((0, cors_1.default)());
24
+ this.app.use(express_1.default.json());
25
+ }
26
+ setupRoutes() {
27
+ // API Routes
28
+ this.app.get("/api/list", async (req, res) => {
29
+ try {
30
+ const path = req.query.path || "/";
31
+ const maxDepth = req.query.maxDepth ? Number.parseInt(req.query.maxDepth, 10) : 1;
32
+ const result = await this.afs.list(path, { maxDepth });
33
+ res.json(result);
34
+ }
35
+ catch (error) {
36
+ res.status(500).json({ error: String(error) });
37
+ }
38
+ });
39
+ this.app.get("/api/read", async (req, res) => {
40
+ try {
41
+ const path = req.query.path;
42
+ if (!path) {
43
+ res.status(400).json({ error: "Path is required" });
44
+ return;
45
+ }
46
+ const result = await this.afs.read(path);
47
+ res.json(result);
48
+ }
49
+ catch (error) {
50
+ res.status(500).json({ error: String(error) });
51
+ }
52
+ });
53
+ this.app.get("/api/search", async (req, res) => {
54
+ try {
55
+ const path = req.query.path || "/";
56
+ const query = req.query.query;
57
+ if (!query) {
58
+ res.status(400).json({ error: "Query is required" });
59
+ return;
60
+ }
61
+ const result = await this.afs.search(path, query);
62
+ res.json(result);
63
+ }
64
+ catch (error) {
65
+ res.status(500).json({ error: String(error) });
66
+ }
67
+ });
68
+ // Serve static files from the dist directory (if provided)
69
+ if (this.options.distPath) {
70
+ const distPath = node_path_1.default.resolve(this.options.distPath);
71
+ this.app.use(express_1.default.static(distPath));
72
+ // Serve index.html for all other routes (SPA fallback)
73
+ this.app.use((_req, res) => {
74
+ res.sendFile(node_path_1.default.join(distPath, "index.html"));
75
+ });
76
+ }
77
+ }
78
+ async start() {
79
+ const port = this.options.port || 3000;
80
+ const host = this.options.host || "localhost";
81
+ return new Promise((resolve) => {
82
+ this.server = this.app.listen(port, host, () => {
83
+ resolve();
84
+ });
85
+ });
86
+ }
87
+ async stop() {
88
+ return new Promise((resolve, reject) => {
89
+ if (this.server) {
90
+ this.server.close((err) => {
91
+ // Ignore ERR_SERVER_NOT_RUNNING error
92
+ if (err && err.code !== "ERR_SERVER_NOT_RUNNING") {
93
+ reject(err);
94
+ }
95
+ else {
96
+ this.server = undefined;
97
+ resolve();
98
+ }
99
+ });
100
+ }
101
+ else {
102
+ resolve();
103
+ }
104
+ });
105
+ }
106
+ }
107
+ exports.ExplorerServer = ExplorerServer;
@@ -0,0 +1,10 @@
1
+ import type { AFS } from "@aigne/afs";
2
+ import { ExplorerServer, type ExplorerServerOptions } from "./server.js";
3
+ export { ExplorerServer, type ExplorerServerOptions };
4
+ /**
5
+ * Start the AFS Explorer web server
6
+ * @param afs - The AFS instance to explore
7
+ * @param options - Server options
8
+ * @returns The ExplorerServer instance
9
+ */
10
+ export declare function startExplorer(afs: AFS, options?: ExplorerServerOptions): Promise<ExplorerServer>;
@@ -0,0 +1,21 @@
1
+ import type { AFS } from "@aigne/afs";
2
+ export interface ExplorerServerOptions {
3
+ port?: number;
4
+ host?: string;
5
+ /**
6
+ * Path to the dist directory containing the built frontend.
7
+ * If not provided, static file serving will be disabled.
8
+ */
9
+ distPath?: string;
10
+ }
11
+ export declare class ExplorerServer {
12
+ private afs;
13
+ private options;
14
+ private app;
15
+ private server?;
16
+ constructor(afs: AFS, options?: ExplorerServerOptions);
17
+ private setupMiddleware;
18
+ private setupRoutes;
19
+ start(): Promise<void>;
20
+ stop(): Promise<void>;
21
+ }
@@ -0,0 +1,10 @@
1
+ import type { AFS } from "@aigne/afs";
2
+ import { ExplorerServer, type ExplorerServerOptions } from "./server.js";
3
+ export { ExplorerServer, type ExplorerServerOptions };
4
+ /**
5
+ * Start the AFS Explorer web server
6
+ * @param afs - The AFS instance to explore
7
+ * @param options - Server options
8
+ * @returns The ExplorerServer instance
9
+ */
10
+ export declare function startExplorer(afs: AFS, options?: ExplorerServerOptions): Promise<ExplorerServer>;
@@ -0,0 +1,13 @@
1
+ import { ExplorerServer } from "./server.js";
2
+ export { ExplorerServer };
3
+ /**
4
+ * Start the AFS Explorer web server
5
+ * @param afs - The AFS instance to explore
6
+ * @param options - Server options
7
+ * @returns The ExplorerServer instance
8
+ */
9
+ export async function startExplorer(afs, options = {}) {
10
+ const server = new ExplorerServer(afs, options);
11
+ await server.start();
12
+ return server;
13
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,21 @@
1
+ import type { AFS } from "@aigne/afs";
2
+ export interface ExplorerServerOptions {
3
+ port?: number;
4
+ host?: string;
5
+ /**
6
+ * Path to the dist directory containing the built frontend.
7
+ * If not provided, static file serving will be disabled.
8
+ */
9
+ distPath?: string;
10
+ }
11
+ export declare class ExplorerServer {
12
+ private afs;
13
+ private options;
14
+ private app;
15
+ private server?;
16
+ constructor(afs: AFS, options?: ExplorerServerOptions);
17
+ private setupMiddleware;
18
+ private setupRoutes;
19
+ start(): Promise<void>;
20
+ stop(): Promise<void>;
21
+ }
@@ -0,0 +1,100 @@
1
+ import path from "node:path";
2
+ import cors from "cors";
3
+ import express from "express";
4
+ export class ExplorerServer {
5
+ afs;
6
+ options;
7
+ app;
8
+ server;
9
+ constructor(afs, options = {}) {
10
+ this.afs = afs;
11
+ this.options = options;
12
+ this.app = express();
13
+ this.setupMiddleware();
14
+ this.setupRoutes();
15
+ }
16
+ setupMiddleware() {
17
+ this.app.use(cors());
18
+ this.app.use(express.json());
19
+ }
20
+ setupRoutes() {
21
+ // API Routes
22
+ this.app.get("/api/list", async (req, res) => {
23
+ try {
24
+ const path = req.query.path || "/";
25
+ const maxDepth = req.query.maxDepth ? Number.parseInt(req.query.maxDepth, 10) : 1;
26
+ const result = await this.afs.list(path, { maxDepth });
27
+ res.json(result);
28
+ }
29
+ catch (error) {
30
+ res.status(500).json({ error: String(error) });
31
+ }
32
+ });
33
+ this.app.get("/api/read", async (req, res) => {
34
+ try {
35
+ const path = req.query.path;
36
+ if (!path) {
37
+ res.status(400).json({ error: "Path is required" });
38
+ return;
39
+ }
40
+ const result = await this.afs.read(path);
41
+ res.json(result);
42
+ }
43
+ catch (error) {
44
+ res.status(500).json({ error: String(error) });
45
+ }
46
+ });
47
+ this.app.get("/api/search", async (req, res) => {
48
+ try {
49
+ const path = req.query.path || "/";
50
+ const query = req.query.query;
51
+ if (!query) {
52
+ res.status(400).json({ error: "Query is required" });
53
+ return;
54
+ }
55
+ const result = await this.afs.search(path, query);
56
+ res.json(result);
57
+ }
58
+ catch (error) {
59
+ res.status(500).json({ error: String(error) });
60
+ }
61
+ });
62
+ // Serve static files from the dist directory (if provided)
63
+ if (this.options.distPath) {
64
+ const distPath = path.resolve(this.options.distPath);
65
+ this.app.use(express.static(distPath));
66
+ // Serve index.html for all other routes (SPA fallback)
67
+ this.app.use((_req, res) => {
68
+ res.sendFile(path.join(distPath, "index.html"));
69
+ });
70
+ }
71
+ }
72
+ async start() {
73
+ const port = this.options.port || 3000;
74
+ const host = this.options.host || "localhost";
75
+ return new Promise((resolve) => {
76
+ this.server = this.app.listen(port, host, () => {
77
+ resolve();
78
+ });
79
+ });
80
+ }
81
+ async stop() {
82
+ return new Promise((resolve, reject) => {
83
+ if (this.server) {
84
+ this.server.close((err) => {
85
+ // Ignore ERR_SERVER_NOT_RUNNING error
86
+ if (err && err.code !== "ERR_SERVER_NOT_RUNNING") {
87
+ reject(err);
88
+ }
89
+ else {
90
+ this.server = undefined;
91
+ resolve();
92
+ }
93
+ });
94
+ }
95
+ else {
96
+ resolve();
97
+ }
98
+ });
99
+ }
100
+ }
package/package.json ADDED
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "@aigne/afs-explorer",
3
+ "version": "1.0.0",
4
+ "description": "Explore and manage AFS file systems",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "author": "Arcblock <blocklet@arcblock.io> https://github.com/blocklet",
9
+ "homepage": "https://www.aigne.io/framework",
10
+ "license": "Elastic-2.0",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/AIGNE-io/aigne-framework"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/AIGNE-io/aigne-framework/issues"
17
+ },
18
+ "files": [
19
+ "lib/cjs",
20
+ "lib/dts",
21
+ "lib/esm",
22
+ "dist",
23
+ "LICENSE",
24
+ "README.md",
25
+ "CHANGELOG.md"
26
+ ],
27
+ "type": "module",
28
+ "main": "./lib/cjs/index.js",
29
+ "module": "./lib/esm/index.js",
30
+ "types": "./lib/dts/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./lib/dts/index.d.ts",
34
+ "import": "./lib/esm/index.js",
35
+ "require": "./lib/cjs/index.js"
36
+ },
37
+ "./index.html": "./dist/index.html",
38
+ "./*": {
39
+ "types": "./lib/dts/*",
40
+ "import": "./lib/esm/*",
41
+ "require": "./lib/cjs/*"
42
+ }
43
+ },
44
+ "typesVersions": {
45
+ "*": {
46
+ ".": [
47
+ "./lib/dts/index.d.ts"
48
+ ]
49
+ }
50
+ },
51
+ "dependencies": {
52
+ "cors": "^2.8.5",
53
+ "express": "^5.1.0",
54
+ "yaml": "^2.8.1",
55
+ "zod": "^3.25.67",
56
+ "@aigne/afs": "^1.4.0-beta.10",
57
+ "@aigne/core": "^1.72.0-beta.24"
58
+ },
59
+ "devDependencies": {
60
+ "@emotion/react": "^11.14.0",
61
+ "@emotion/styled": "^11.14.0",
62
+ "@mui/icons-material": "^7.3.2",
63
+ "@mui/material": "^7.3.2",
64
+ "@mui/x-data-grid": "^8.11.3",
65
+ "@mui/x-tree-view": "^8.25.0",
66
+ "@types/bun": "^1.2.22",
67
+ "@types/cors": "^2.8.18",
68
+ "@types/express": "^5.0.0",
69
+ "@types/react": "^19.0.6",
70
+ "@types/react-dom": "^19.0.3",
71
+ "@types/react-router-dom": "^5.3.3",
72
+ "@types/react-syntax-highlighter": "^15.5.13",
73
+ "@vitejs/plugin-react": "^4.3.4",
74
+ "npm-run-all": "^4.1.5",
75
+ "react": "^19.0.0",
76
+ "react-dom": "^19.0.0",
77
+ "react-markdown": "^10.1.0",
78
+ "react-router-dom": "^7.9.1",
79
+ "react-syntax-highlighter": "^16.1.0",
80
+ "remark-gfm": "^4.0.1",
81
+ "rimraf": "^6.0.1",
82
+ "typescript": "^5.9.2",
83
+ "vite": "^7.1.5",
84
+ "vite-plugin-svgr": "^4.3.0",
85
+ "@aigne/afs-git": "^1.0.0",
86
+ "@aigne/afs-history": "^1.2.0-beta.11",
87
+ "@aigne/afs-json": "^1.0.0",
88
+ "@aigne/afs-local-fs": "^1.4.0-beta.25",
89
+ "@aigne/test-utils": "^0.5.69-beta.24"
90
+ },
91
+ "scripts": {
92
+ "lint": "tsc --noEmit",
93
+ "build": "run-s build:web build:lib",
94
+ "build:lib": "tsc --build scripts/tsconfig.build.json",
95
+ "build:web": "vite build",
96
+ "dev": "vite",
97
+ "clean": "rimraf lib test/coverage dist",
98
+ "test": "bun test",
99
+ "test:coverage": "bun test --coverage --coverage-reporter=lcov --coverage-reporter=text",
100
+ "postbuild": "node ../../scripts/post-build-lib.mjs"
101
+ }
102
+ }