mioku-service-webui 4.8.0 → 4.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +0 -2
- package/package.json +1 -1
- package/routes/access-control.ts +24 -11
- package/routes/adapter-config.ts +13 -11
- package/system.ts +17 -16
- package/utils.ts +5 -0
package/index.ts
CHANGED
package/package.json
CHANGED
package/routes/access-control.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import { logger } from "mioku";
|
|
5
|
-
import { readJsonFile, writeJsonFile, NODE_MODULES_DIR } from "../utils";
|
|
4
|
+
import { getActiveCommandManager, logger } from "mioku";
|
|
5
|
+
import { isPackageDir, readJsonFile, writeJsonFile, NODE_MODULES_DIR } from "../utils";
|
|
6
6
|
|
|
7
7
|
const ACCESS_CONFIG_PATH = path.resolve(
|
|
8
8
|
process.cwd(),
|
|
@@ -38,24 +38,37 @@ interface AccessItem {
|
|
|
38
38
|
desc?: string;
|
|
39
39
|
match?: string;
|
|
40
40
|
event?: string;
|
|
41
|
+
permission?: string;
|
|
42
|
+
priority?: number;
|
|
41
43
|
fromHook: boolean;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
function readAccessCatalog(): AccessItem[] {
|
|
47
|
+
const manager = getActiveCommandManager();
|
|
48
|
+
if (manager) {
|
|
49
|
+
return manager.catalog().map((item) => ({
|
|
50
|
+
kind: item.kind,
|
|
51
|
+
plugin: item.plugin,
|
|
52
|
+
id: item.id,
|
|
53
|
+
label: item.label,
|
|
54
|
+
desc: item.desc,
|
|
55
|
+
match: item.match,
|
|
56
|
+
event: item.event,
|
|
57
|
+
permission: item.permission,
|
|
58
|
+
priority: item.priority,
|
|
59
|
+
fromHook:
|
|
60
|
+
item.source === "manifest" && Boolean(item.match || item.event),
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
45
63
|
if (!fs.existsSync(NODE_MODULES_DIR)) return [];
|
|
46
64
|
const entries = fs.readdirSync(NODE_MODULES_DIR, { withFileTypes: true });
|
|
47
65
|
const items: AccessItem[] = [];
|
|
48
66
|
|
|
49
67
|
for (const entry of entries) {
|
|
50
|
-
if (!entry.name.startsWith("mioku-plugin-")) continue;
|
|
68
|
+
if (!entry.name.toLowerCase().startsWith("mioku-plugin-")) continue;
|
|
51
69
|
const fullPath = path.join(NODE_MODULES_DIR, entry.name);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
stat = fs.lstatSync(fullPath);
|
|
55
|
-
} catch {
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (!stat.isDirectory() && !stat.isSymbolicLink()) continue;
|
|
70
|
+
// Windows 上 pnpm/bun workspace 会用 NTFS junction,旧 lstat 检查会误判
|
|
71
|
+
if (!isPackageDir(fullPath)) continue;
|
|
59
72
|
|
|
60
73
|
const pkgPath = path.join(fullPath, "package.json");
|
|
61
74
|
if (!fs.existsSync(pkgPath)) continue;
|
|
@@ -66,7 +79,7 @@ function readAccessCatalog(): AccessItem[] {
|
|
|
66
79
|
continue;
|
|
67
80
|
}
|
|
68
81
|
|
|
69
|
-
const name = entry.name.replace(/^mioku-plugin
|
|
82
|
+
const name = entry.name.replace(/^mioku-plugin-/i, "");
|
|
70
83
|
const mioku = pkg.mioku || {};
|
|
71
84
|
const help = mioku.help || { title: name, description: "", commands: [] };
|
|
72
85
|
const hooks: Array<{ id: string; match?: string; event?: string; description?: string }> =
|
package/routes/adapter-config.ts
CHANGED
|
@@ -3,23 +3,25 @@ import * as fs from "node:fs";
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { loadAdapterConfigPage } from "../config-page-loader";
|
|
5
5
|
import { getAdapterConfigs, updateAdapterConfig } from "../system";
|
|
6
|
+
import { isPackageDir } from "../utils";
|
|
6
7
|
|
|
7
8
|
function listAdaptersFromNodeModules(): string[] {
|
|
8
9
|
const modulesPath = path.join(process.cwd(), "node_modules");
|
|
9
|
-
if (!fs.existsSync(modulesPath)) return [];
|
|
10
10
|
const adapters: string[] = [];
|
|
11
|
-
|
|
11
|
+
if (!fs.existsSync(modulesPath)) return adapters;
|
|
12
|
+
|
|
13
|
+
let entries: import("fs").Dirent[];
|
|
14
|
+
try {
|
|
15
|
+
entries = fs.readdirSync(modulesPath, { withFileTypes: true });
|
|
16
|
+
} catch {
|
|
17
|
+
return adapters;
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
for (const entry of entries) {
|
|
13
|
-
if (!entry.name.startsWith("mioku-adapter-")) continue;
|
|
21
|
+
if (!entry.name.toLowerCase().startsWith("mioku-adapter-")) continue;
|
|
14
22
|
const fullPath = path.join(modulesPath, entry.name);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
stat = fs.lstatSync(fullPath);
|
|
18
|
-
} catch {
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
if (!stat.isDirectory() && !stat.isSymbolicLink()) continue;
|
|
22
|
-
adapters.push(entry.name.replace(/^mioku-adapter-/, ""));
|
|
23
|
+
if (!isPackageDir(fullPath)) continue;
|
|
24
|
+
adapters.push(entry.name.replace(/^mioku-adapter-/i, ""));
|
|
23
25
|
}
|
|
24
26
|
return adapters.sort((a, b) => a.localeCompare(b));
|
|
25
27
|
}
|
package/system.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
ensureDir,
|
|
22
22
|
getInstallCommand,
|
|
23
23
|
isNpmPackageName,
|
|
24
|
+
isPackageDir,
|
|
24
25
|
isValidRepoUrl,
|
|
25
26
|
LOCAL_CONFIG_PATH,
|
|
26
27
|
NODE_MODULES_DIR,
|
|
@@ -887,11 +888,11 @@ function listPluginsFromNodeModules(): Array<Record<string, any>> {
|
|
|
887
888
|
|
|
888
889
|
const entries = fs.readdirSync(modulesPath, { withFileTypes: true });
|
|
889
890
|
for (const entry of entries) {
|
|
890
|
-
if (!entry.name.startsWith("mioku-plugin-")) continue;
|
|
891
|
+
if (!entry.name.toLowerCase().startsWith("mioku-plugin-")) continue;
|
|
891
892
|
const fullPath = path.join(modulesPath, entry.name);
|
|
892
|
-
|
|
893
|
-
if (!
|
|
894
|
-
const name = entry.name.replace(/^mioku-plugin
|
|
893
|
+
// Windows 上 pnpm/bun workspace 会用 NTFS junction,旧 lstat 检查会误判
|
|
894
|
+
if (!isPackageDir(fullPath)) continue;
|
|
895
|
+
const name = entry.name.replace(/^mioku-plugin-/i, "");
|
|
895
896
|
const pkg = readPackageJson(fullPath);
|
|
896
897
|
plugins.push({
|
|
897
898
|
name,
|
|
@@ -915,11 +916,11 @@ function listServicesFromNodeModules(): Array<Record<string, any>> {
|
|
|
915
916
|
|
|
916
917
|
const entries = fs.readdirSync(modulesPath, { withFileTypes: true });
|
|
917
918
|
for (const entry of entries) {
|
|
918
|
-
if (!entry.name.startsWith("mioku-service-")) continue;
|
|
919
|
+
if (!entry.name.toLowerCase().startsWith("mioku-service-")) continue;
|
|
919
920
|
const fullPath = path.join(modulesPath, entry.name);
|
|
920
|
-
|
|
921
|
-
if (!
|
|
922
|
-
const name = entry.name.replace(/^mioku-service
|
|
921
|
+
// Windows 上 pnpm/bun workspace 会用 NTFS junction,旧 lstat 检查会误判
|
|
922
|
+
if (!isPackageDir(fullPath)) continue;
|
|
923
|
+
const name = entry.name.replace(/^mioku-service-/i, "");
|
|
923
924
|
const pkg = readPackageJson(fullPath);
|
|
924
925
|
services.push({
|
|
925
926
|
name,
|
|
@@ -943,11 +944,11 @@ function listAdaptersFromNodeModules(): Array<Record<string, any>> {
|
|
|
943
944
|
|
|
944
945
|
const entries = fs.readdirSync(modulesPath, { withFileTypes: true });
|
|
945
946
|
for (const entry of entries) {
|
|
946
|
-
if (!entry.name.startsWith("mioku-adapter-")) continue;
|
|
947
|
+
if (!entry.name.toLowerCase().startsWith("mioku-adapter-")) continue;
|
|
947
948
|
const fullPath = path.join(modulesPath, entry.name);
|
|
948
|
-
|
|
949
|
-
if (!
|
|
950
|
-
const name = entry.name.replace(/^mioku-adapter
|
|
949
|
+
// Windows 上 pnpm/bun workspace 会用 NTFS junction,旧 lstat 检查会误判
|
|
950
|
+
if (!isPackageDir(fullPath)) continue;
|
|
951
|
+
const name = entry.name.replace(/^mioku-adapter-/i, "");
|
|
951
952
|
const pkg = readPackageJson(fullPath);
|
|
952
953
|
adapters.push({
|
|
953
954
|
name,
|
|
@@ -2401,11 +2402,11 @@ export function getAvailablePlugins(): string[] {
|
|
|
2401
2402
|
const plugins: string[] = [];
|
|
2402
2403
|
const entries = fs.readdirSync(modulesPath, { withFileTypes: true });
|
|
2403
2404
|
for (const entry of entries) {
|
|
2404
|
-
if (!entry.name.startsWith("mioku-plugin-")) continue;
|
|
2405
|
+
if (!entry.name.toLowerCase().startsWith("mioku-plugin-")) continue;
|
|
2405
2406
|
const fullPath = path.join(modulesPath, entry.name);
|
|
2406
|
-
|
|
2407
|
-
if (!
|
|
2408
|
-
plugins.push(entry.name.replace(/^mioku-plugin
|
|
2407
|
+
// Windows 上 pnpm/bun workspace 会用 NTFS junction,旧 lstat 检查会误判
|
|
2408
|
+
if (!isPackageDir(fullPath)) continue;
|
|
2409
|
+
plugins.push(entry.name.replace(/^mioku-plugin-/i, ""));
|
|
2409
2410
|
}
|
|
2410
2411
|
return plugins.sort((a, b) => a.localeCompare(b));
|
|
2411
2412
|
}
|
package/utils.ts
CHANGED
|
@@ -97,6 +97,11 @@ export function normalizePackageManager(): PackageManager {
|
|
|
97
97
|
return "bun";
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
export function isPackageDir(fullPath: string | null | undefined): boolean {
|
|
101
|
+
if (!fullPath) return false;
|
|
102
|
+
return fs.existsSync(path.join(fullPath, "package.json"));
|
|
103
|
+
}
|
|
104
|
+
|
|
100
105
|
export function isValidRepoUrl(url: string): boolean {
|
|
101
106
|
const trimmed = url.trim();
|
|
102
107
|
// 拒绝空白字符:堵 `ssh://host -o ProxyCommand=...` 之类参数注入
|