@kevisual/router 0.1.2 → 0.1.4
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/package.json +3 -3
- package/src/commander.ts +103 -23
- package/dist/app.d.ts +0 -5
- package/dist/app.js +0 -20175
- package/dist/commander.d.ts +0 -816
- package/dist/commander.js +0 -2790
- package/dist/opencode.d.ts +0 -811
- package/dist/opencode.js +0 -15308
- package/dist/router-browser.d.ts +0 -676
- package/dist/router-browser.js +0 -33383
- package/dist/router-define.d.ts +0 -560
- package/dist/router-define.js +0 -135
- package/dist/router-simple.d.ts +0 -110
- package/dist/router-simple.js +0 -708
- package/dist/router.d.ts +0 -1082
- package/dist/router.js +0 -19059
- package/dist/ws.d.ts +0 -860
- package/dist/ws.js +0 -3041
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@kevisual/router",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.4",
|
|
5
5
|
"description": "",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/router.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@kevisual/query": "^0.0.53",
|
|
31
31
|
"@kevisual/remote-app": "^0.0.7",
|
|
32
32
|
"@kevisual/use-config": "^1.0.30",
|
|
33
|
-
"@opencode-ai/plugin": "^1.2.
|
|
33
|
+
"@opencode-ai/plugin": "^1.2.27",
|
|
34
34
|
"@types/bun": "^1.3.10",
|
|
35
35
|
"@types/crypto-js": "^4.2.2",
|
|
36
36
|
"@types/node": "^25.5.0",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"eventemitter3": "^5.0.4",
|
|
44
44
|
"fast-glob": "^3.3.3",
|
|
45
45
|
"hono": "^4.12.8",
|
|
46
|
-
"nanoid": "^5.1.
|
|
46
|
+
"nanoid": "^5.1.7",
|
|
47
47
|
"path-to-regexp": "^8.3.0",
|
|
48
48
|
"send": "^1.2.1",
|
|
49
49
|
"typescript": "^5.9.3",
|
package/src/commander.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command, program } from 'commander';
|
|
2
|
-
import { App
|
|
2
|
+
import { App } from './app.ts';
|
|
3
3
|
import { RemoteApp } from '@kevisual/remote-app'
|
|
4
|
+
import z from 'zod';
|
|
4
5
|
export const groupByPath = (routes: App['routes']) => {
|
|
5
6
|
return routes.reduce((acc, route) => {
|
|
6
7
|
const path = route.path || 'default';
|
|
@@ -124,9 +125,10 @@ export const parse = async (opts: {
|
|
|
124
125
|
token?: string,
|
|
125
126
|
username?: string,
|
|
126
127
|
id?: string,
|
|
127
|
-
}
|
|
128
|
+
},
|
|
129
|
+
exitOnEnd?: boolean,
|
|
128
130
|
}) => {
|
|
129
|
-
const { description, parse = true, version } = opts;
|
|
131
|
+
const { description, parse = true, version, exitOnEnd = true } = opts;
|
|
130
132
|
const app = opts.app as App;
|
|
131
133
|
const _program = opts.program || program;
|
|
132
134
|
_program.description(description || 'Router 命令行工具');
|
|
@@ -134,25 +136,8 @@ export const parse = async (opts: {
|
|
|
134
136
|
_program.version(version);
|
|
135
137
|
}
|
|
136
138
|
app.createRouteList();
|
|
137
|
-
app.route({
|
|
138
|
-
path: 'cli',
|
|
139
|
-
key: 'list'
|
|
140
|
-
}).define(async () => {
|
|
141
|
-
const routes = app.routes.map(route => {
|
|
142
|
-
return {
|
|
143
|
-
path: route.path,
|
|
144
|
-
key: route.key,
|
|
145
|
-
description: route?.metadata?.summary || route.description || '',
|
|
146
|
-
};
|
|
147
|
-
});
|
|
148
|
-
// 输出为表格格式
|
|
149
|
-
const table = routes.map(route => {
|
|
150
|
-
return `${route.path} ${route.key} - ${route.description}`;
|
|
151
|
-
}).join('\n');
|
|
152
|
-
|
|
153
|
-
console.log(table);
|
|
154
|
-
}).addTo(app, { overwrite: false })
|
|
155
139
|
|
|
140
|
+
createCliList(app);
|
|
156
141
|
createCommand({ app: app as App, program: _program });
|
|
157
142
|
|
|
158
143
|
if (opts.remote) {
|
|
@@ -167,9 +152,104 @@ export const parse = async (opts: {
|
|
|
167
152
|
remoteApp.listenProxy();
|
|
168
153
|
console.log('已连接到远程应用,正在监听命令...');
|
|
169
154
|
}
|
|
170
|
-
return
|
|
155
|
+
return;
|
|
171
156
|
}
|
|
172
157
|
if (parse) {
|
|
173
|
-
_program.
|
|
158
|
+
await _program.parseAsync(process.argv);
|
|
159
|
+
if (exitOnEnd) {
|
|
160
|
+
process.exit(0);
|
|
161
|
+
}
|
|
174
162
|
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const createCliList = (app: App) => {
|
|
166
|
+
app.route({
|
|
167
|
+
path: 'cli',
|
|
168
|
+
key: 'list',
|
|
169
|
+
description: '列出所有可用的命令',
|
|
170
|
+
metadata: {
|
|
171
|
+
summary: '列出所有可用的命令',
|
|
172
|
+
args: {
|
|
173
|
+
q: z.string().optional().describe('查询关键词,支持模糊匹配命令'),
|
|
174
|
+
path: z.string().optional().describe('按路径前缀过滤,如 user、admin'),
|
|
175
|
+
tags: z.string().optional().describe('按标签过滤,多个标签用逗号分隔'),
|
|
176
|
+
sort: z.enum(['key', 'path', 'name']).optional().describe('排序方式'),
|
|
177
|
+
limit: z.number().optional().describe('限制返回数量'),
|
|
178
|
+
offset: z.number().optional().describe('偏移量,用于分页'),
|
|
179
|
+
format: z.enum(['table', 'simple', 'json']).optional().describe('输出格式'),
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}).define(async (ctx) => {
|
|
183
|
+
const { q, path: pathFilter, tags, sort, limit, offset, format } = ctx.query as any;
|
|
184
|
+
let routes = app.routes.map(route => {
|
|
185
|
+
return {
|
|
186
|
+
path: route.path,
|
|
187
|
+
key: route.key,
|
|
188
|
+
description: route?.metadata?.summary || route.description || '',
|
|
189
|
+
tags: route?.metadata?.tags || [],
|
|
190
|
+
};
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// 路径过滤
|
|
194
|
+
if (pathFilter) {
|
|
195
|
+
routes = routes.filter(route => route.path.startsWith(pathFilter));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// 标签过滤
|
|
199
|
+
if (tags) {
|
|
200
|
+
const tagList = tags.split(',').map((t: string) => t.trim().toLowerCase()).filter(Boolean);
|
|
201
|
+
if (tagList.length > 0) {
|
|
202
|
+
routes = routes.filter(route => {
|
|
203
|
+
const routeTags = Array.isArray(route.tags) ? route.tags.map((t: unknown) => String(t).toLowerCase()) : [];
|
|
204
|
+
return tagList.some((tag: string) => routeTags.includes(tag));
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// 关键词过滤
|
|
210
|
+
if (q) {
|
|
211
|
+
const keyword = q.toLowerCase();
|
|
212
|
+
routes = routes.filter(route => {
|
|
213
|
+
return route.path.toLowerCase().includes(keyword) ||
|
|
214
|
+
route.key.toLowerCase().includes(keyword) ||
|
|
215
|
+
route.description.toLowerCase().includes(keyword);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// 排序
|
|
220
|
+
if (sort) {
|
|
221
|
+
routes.sort((a, b) => {
|
|
222
|
+
if (sort === 'path') return a.path.localeCompare(b.path);
|
|
223
|
+
if (sort === 'key') return a.key.localeCompare(b.key);
|
|
224
|
+
return a.key.localeCompare(b.key); // name 默认为 key
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// 分页
|
|
229
|
+
const total = routes.length;
|
|
230
|
+
const start = offset || 0;
|
|
231
|
+
const end = limit ? start + limit : undefined;
|
|
232
|
+
routes = routes.slice(start, end);
|
|
233
|
+
|
|
234
|
+
// 输出
|
|
235
|
+
const outputFormat = format || 'table';
|
|
236
|
+
if (outputFormat === 'json') {
|
|
237
|
+
console.log(JSON.stringify({ total, offset: start, limit, routes }, null, 2));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (outputFormat === 'simple') {
|
|
242
|
+
routes.forEach(route => {
|
|
243
|
+
console.log(`${route.path} ${route.key}`);
|
|
244
|
+
});
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// table 格式
|
|
249
|
+
const table = routes.map(route => {
|
|
250
|
+
return `${route.path} ${route.key} - ${route.description}`;
|
|
251
|
+
}).join('\n');
|
|
252
|
+
|
|
253
|
+
console.log(table);
|
|
254
|
+
}).addTo(app, { overwrite: false })
|
|
175
255
|
}
|