@jsbot-tellus/core 2.5.0 → 2.6.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.
- package/README.md +8 -5
- package/dist/app/cli.d.ts +10 -0
- package/dist/app/cli.d.ts.map +1 -0
- package/dist/app/cli.js +37 -0
- package/dist/app/cli.js.map +1 -0
- package/dist/app/runtime.d.ts +121 -0
- package/dist/app/runtime.d.ts.map +1 -0
- package/dist/app/runtime.js +296 -0
- package/dist/app/runtime.js.map +1 -0
- package/dist/app.js +63 -273
- package/dist/app.js.map +1 -1
- package/dist/core/plugin/command-params.d.ts +3 -37
- package/dist/core/plugin/command-params.d.ts.map +1 -1
- package/dist/core/plugin/command-params.js +2 -580
- package/dist/core/plugin/command-params.js.map +1 -1
- package/dist/core/plugin/install/paths.d.ts +7 -0
- package/dist/core/plugin/install/paths.d.ts.map +1 -0
- package/dist/core/plugin/install/paths.js +49 -0
- package/dist/core/plugin/install/paths.js.map +1 -0
- package/dist/core/plugin/install/state.d.ts +23 -0
- package/dist/core/plugin/install/state.d.ts.map +1 -0
- package/dist/core/plugin/install/state.js +129 -0
- package/dist/core/plugin/install/state.js.map +1 -0
- package/dist/core/plugin/install/validate-script.d.ts +3 -0
- package/dist/core/plugin/install/validate-script.d.ts.map +1 -0
- package/dist/core/plugin/install/validate-script.js +154 -0
- package/dist/core/plugin/install/validate-script.js.map +1 -0
- package/dist/core/plugin/install-dir.d.ts +3 -28
- package/dist/core/plugin/install-dir.d.ts.map +1 -1
- package/dist/core/plugin/install-dir.js +3 -326
- package/dist/core/plugin/install-dir.js.map +1 -1
- package/dist/core/plugin/installer/checks.d.ts +6 -0
- package/dist/core/plugin/installer/checks.d.ts.map +1 -0
- package/dist/core/plugin/installer/checks.js +99 -0
- package/dist/core/plugin/installer/checks.js.map +1 -0
- package/dist/core/plugin/installer/support.d.ts +37 -0
- package/dist/core/plugin/installer/support.d.ts.map +1 -0
- package/dist/core/plugin/installer/support.js +67 -0
- package/dist/core/plugin/installer/support.js.map +1 -0
- package/dist/core/plugin/installer/warnings.d.ts +5 -0
- package/dist/core/plugin/installer/warnings.d.ts.map +1 -0
- package/dist/core/plugin/installer/warnings.js +28 -0
- package/dist/core/plugin/installer/warnings.js.map +1 -0
- package/dist/core/plugin/installer.d.ts +4 -30
- package/dist/core/plugin/installer.d.ts.map +1 -1
- package/dist/core/plugin/installer.js +21 -202
- package/dist/core/plugin/installer.js.map +1 -1
- package/dist/core/plugin/params/compile.d.ts +3 -0
- package/dist/core/plugin/params/compile.d.ts.map +1 -0
- package/dist/core/plugin/params/compile.js +23 -0
- package/dist/core/plugin/params/compile.js.map +1 -0
- package/dist/core/plugin/params/declaration.d.ts +9 -0
- package/dist/core/plugin/params/declaration.d.ts.map +1 -0
- package/dist/core/plugin/params/declaration.js +286 -0
- package/dist/core/plugin/params/declaration.js.map +1 -0
- package/dist/core/plugin/params/input.d.ts +5 -0
- package/dist/core/plugin/params/input.d.ts.map +1 -0
- package/dist/core/plugin/params/input.js +196 -0
- package/dist/core/plugin/params/input.js.map +1 -0
- package/dist/core/plugin/params/reply.d.ts +3 -0
- package/dist/core/plugin/params/reply.d.ts.map +1 -0
- package/dist/core/plugin/params/reply.js +49 -0
- package/dist/core/plugin/params/reply.js.map +1 -0
- package/dist/core/plugin/params/type-level.d.ts +24 -0
- package/dist/core/plugin/params/type-level.d.ts.map +1 -0
- package/dist/core/plugin/params/type-level.js +2 -0
- package/dist/core/plugin/params/type-level.js.map +1 -0
- package/dist/core/plugin/params/types.d.ts +33 -0
- package/dist/core/plugin/params/types.d.ts.map +1 -0
- package/dist/core/plugin/params/types.js +12 -0
- package/dist/core/plugin/params/types.js.map +1 -0
- package/dist/core/plugin/params/values.d.ts +7 -0
- package/dist/core/plugin/params/values.d.ts.map +1 -0
- package/dist/core/plugin/params/values.js +111 -0
- package/dist/core/plugin/params/values.js.map +1 -0
- package/dist/core/web/api.d.ts +2 -14
- package/dist/core/web/api.d.ts.map +1 -1
- package/dist/core/web/api.js +8 -500
- package/dist/core/web/api.js.map +1 -1
- package/dist/core/web/routes/actions.d.ts +4 -0
- package/dist/core/web/routes/actions.d.ts.map +1 -0
- package/dist/core/web/routes/actions.js +33 -0
- package/dist/core/web/routes/actions.js.map +1 -0
- package/dist/core/web/routes/config.d.ts +5 -0
- package/dist/core/web/routes/config.d.ts.map +1 -0
- package/dist/core/web/routes/config.js +30 -0
- package/dist/core/web/routes/config.js.map +1 -0
- package/dist/core/web/routes/kv.d.ts +6 -0
- package/dist/core/web/routes/kv.d.ts.map +1 -0
- package/dist/core/web/routes/kv.js +80 -0
- package/dist/core/web/routes/kv.js.map +1 -0
- package/dist/core/web/routes/plugins.d.ts +5 -0
- package/dist/core/web/routes/plugins.d.ts.map +1 -0
- package/dist/core/web/routes/plugins.js +98 -0
- package/dist/core/web/routes/plugins.js.map +1 -0
- package/dist/core/web/routes/sessions.d.ts +8 -0
- package/dist/core/web/routes/sessions.d.ts.map +1 -0
- package/dist/core/web/routes/sessions.js +130 -0
- package/dist/core/web/routes/sessions.js.map +1 -0
- package/dist/core/web/routes/shared.d.ts +18 -0
- package/dist/core/web/routes/shared.d.ts.map +1 -0
- package/dist/core/web/routes/shared.js +19 -0
- package/dist/core/web/routes/shared.js.map +1 -0
- package/dist/core/web/routes/status.d.ts +6 -0
- package/dist/core/web/routes/status.d.ts.map +1 -0
- package/dist/core/web/routes/status.js +132 -0
- package/dist/core/web/routes/status.js.map +1 -0
- package/dist/core/web/server/auth.d.ts +17 -0
- package/dist/core/web/server/auth.d.ts.map +1 -0
- package/dist/core/web/server/auth.js +68 -0
- package/dist/core/web/server/auth.js.map +1 -0
- package/dist/core/web/server/csp.d.ts +11 -0
- package/dist/core/web/server/csp.d.ts.map +1 -0
- package/dist/core/web/server/csp.js +31 -0
- package/dist/core/web/server/csp.js.map +1 -0
- package/dist/core/web/server/request.d.ts +6 -0
- package/dist/core/web/server/request.d.ts.map +1 -0
- package/dist/core/web/server/request.js +33 -0
- package/dist/core/web/server/request.js.map +1 -0
- package/dist/core/web/server/security.d.ts +4 -0
- package/dist/core/web/server/security.d.ts.map +1 -0
- package/dist/core/web/server/security.js +12 -0
- package/dist/core/web/server/security.js.map +1 -0
- package/dist/core/web/server/sse.d.ts +18 -0
- package/dist/core/web/server/sse.d.ts.map +1 -0
- package/dist/core/web/server/sse.js +49 -0
- package/dist/core/web/server/sse.js.map +1 -0
- package/dist/core/web/server/static.d.ts +16 -0
- package/dist/core/web/server/static.d.ts.map +1 -0
- package/dist/core/web/server/static.js +80 -0
- package/dist/core/web/server/static.js.map +1 -0
- package/dist/core/web/server.d.ts +0 -7
- package/dist/core/web/server.d.ts.map +1 -1
- package/dist/core/web/server.js +41 -263
- package/dist/core/web/server.js.map +1 -1
- package/docs/architecture.md +28 -11
- package/docs/configuration.md +1 -1
- package/docs/migration.md +2 -2
- package/docs/plugin-api.md +24 -11
- package/docs/plugin-development.md +1 -1
- package/package.json +19 -17
- package/src/app/cli.ts +47 -0
- package/src/app/runtime.ts +522 -0
- package/src/app.ts +87 -395
- package/src/core/plugin/command-params.ts +8 -871
- package/src/core/plugin/install/paths.ts +72 -0
- package/src/core/plugin/install/state.ts +196 -0
- package/src/core/plugin/install/validate-script.ts +154 -0
- package/src/core/plugin/install-dir.ts +19 -427
- package/src/core/plugin/installer/checks.ts +137 -0
- package/src/core/plugin/installer/support.ts +120 -0
- package/src/core/plugin/installer/warnings.ts +52 -0
- package/src/core/plugin/installer.ts +52 -301
- package/src/core/plugin/params/compile.ts +41 -0
- package/src/core/plugin/params/declaration.ts +394 -0
- package/src/core/plugin/params/input.ts +281 -0
- package/src/core/plugin/params/reply.ts +59 -0
- package/src/core/plugin/params/type-level.ts +75 -0
- package/src/core/plugin/params/types.ts +55 -0
- package/src/core/plugin/params/values.ts +150 -0
- package/src/core/web/api.ts +33 -759
- package/src/core/web/routes/actions.ts +43 -0
- package/src/core/web/routes/config.ts +42 -0
- package/src/core/web/routes/kv.ts +122 -0
- package/src/core/web/routes/plugins.ts +151 -0
- package/src/core/web/routes/sessions.ts +188 -0
- package/src/core/web/routes/shared.ts +42 -0
- package/src/core/web/routes/status.ts +191 -0
- package/src/core/web/server/auth.ts +126 -0
- package/src/core/web/server/csp.ts +33 -0
- package/src/core/web/server/request.ts +38 -0
- package/src/core/web/server/security.ts +14 -0
- package/src/core/web/server/sse.ts +74 -0
- package/src/core/web/server/static.ts +112 -0
- package/src/core/web/server.ts +41 -383
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/core/web/routes/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAmB,MAAM,aAAa,CAAA;AAEvD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAe;IACjD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAA;IAC5C,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IAE1C,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE;YACF,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;SAC5C;KACJ,CAAC,CAAA;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAe;IACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IAClD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IAE5D,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE;QACnB,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,MAAM,EAAE,MAAM,CAAC,MAAM;KACxB,CAAC,CAAA;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAe;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAA;IAEjC,QAAQ,CACJ,GAAG,CAAC,GAAG,EACP,GAAG,EACH,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CACtB,IAAI,CAAC,QAAQ,CAAC,EACd,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CACtD,CACJ,CAAA;AACL,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ApiContext } from './shared.js';
|
|
2
|
+
export declare function handleKvPlugins(ctx: ApiContext): Promise<void>;
|
|
3
|
+
export declare function handleKvList(ctx: ApiContext): Promise<void>;
|
|
4
|
+
export declare function handleKvPut(ctx: ApiContext): Promise<void>;
|
|
5
|
+
export declare function handleKvDelete(ctx: ApiContext): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=kv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../../../../src/core/web/routes/kv.ts"],"names":[],"mappings":"AAEA,OAAO,EAIH,KAAK,UAAU,EAClB,MAAM,aAAa,CAAA;AAgCpB,wBAAsB,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAapE;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCjE;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhE;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CASnE"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { SqlitePluginKV } from '../../plugin/kv.js';
|
|
2
|
+
import { HttpError, readJsonBody, sendData } from '../http.js';
|
|
3
|
+
import { asRecord, clampInt, requireRuntime, } from './shared.js';
|
|
4
|
+
function assertPluginId(value) {
|
|
5
|
+
if (!/^\w[\w.-]*$/.test(value)) {
|
|
6
|
+
throw new HttpError(400, `invalid plugin id: ${value}`);
|
|
7
|
+
}
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
function assertKey(value) {
|
|
11
|
+
if (value.length === 0 || value.length > 512) {
|
|
12
|
+
throw new HttpError(400, 'invalid key length');
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function parseKvValue(value) {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(value);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export async function handleKvPlugins(ctx) {
|
|
25
|
+
const runtime = requireRuntime(ctx.deps);
|
|
26
|
+
const rows = runtime.database.connection
|
|
27
|
+
.prepare('SELECT plugin_id, COUNT(*) AS count FROM plugin_kv GROUP BY plugin_id ORDER BY plugin_id')
|
|
28
|
+
.all();
|
|
29
|
+
sendData(ctx.res, 200, rows.map((row) => ({ pluginId: row.plugin_id, count: row.count })));
|
|
30
|
+
}
|
|
31
|
+
export async function handleKvList(ctx) {
|
|
32
|
+
const runtime = requireRuntime(ctx.deps);
|
|
33
|
+
const pluginId = assertPluginId(ctx.search.get('pluginId') ?? '');
|
|
34
|
+
const prefix = ctx.search.get('prefix') ?? '';
|
|
35
|
+
const limit = clampInt(ctx.search.get('limit'), 100, 1, 500);
|
|
36
|
+
const offset = clampInt(ctx.search.get('offset'), 0, 0, 10_000_000);
|
|
37
|
+
const pattern = prefix === ''
|
|
38
|
+
? '%'
|
|
39
|
+
: `${prefix.replace(/[%_]/g, (match) => `\\${match}`)}%`;
|
|
40
|
+
const rows = runtime.database.connection
|
|
41
|
+
.prepare(`SELECT key, value, updated_at FROM plugin_kv
|
|
42
|
+
WHERE plugin_id = ? AND key LIKE ? ESCAPE '\\'
|
|
43
|
+
ORDER BY key
|
|
44
|
+
LIMIT ? OFFSET ?`)
|
|
45
|
+
.all(pluginId, pattern, limit, offset);
|
|
46
|
+
const totalRow = runtime.database.connection
|
|
47
|
+
.prepare(`SELECT COUNT(*) AS count FROM plugin_kv
|
|
48
|
+
WHERE plugin_id = ? AND key LIKE ? ESCAPE '\\'`)
|
|
49
|
+
.get(pluginId, pattern);
|
|
50
|
+
sendData(ctx.res, 200, {
|
|
51
|
+
items: rows.map((row) => ({
|
|
52
|
+
pluginId,
|
|
53
|
+
key: row.key,
|
|
54
|
+
value: parseKvValue(row.value),
|
|
55
|
+
updatedAt: row.updated_at,
|
|
56
|
+
})),
|
|
57
|
+
total: totalRow?.count ?? 0,
|
|
58
|
+
limit,
|
|
59
|
+
offset,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export async function handleKvPut(ctx) {
|
|
63
|
+
const body = asRecord(await readJsonBody(ctx.req));
|
|
64
|
+
const runtime = requireRuntime(ctx.deps);
|
|
65
|
+
const pluginId = assertPluginId(typeof body['pluginId'] === 'string' ? body['pluginId'] : '');
|
|
66
|
+
const key = assertKey(typeof body['key'] === 'string' ? body['key'] : '');
|
|
67
|
+
if (typeof body['value'] === 'function') {
|
|
68
|
+
throw new HttpError(400, 'invalid value');
|
|
69
|
+
}
|
|
70
|
+
await new SqlitePluginKV(runtime.database, pluginId).set(key, body['value']);
|
|
71
|
+
sendData(ctx.res, 200, { ok: true });
|
|
72
|
+
}
|
|
73
|
+
export async function handleKvDelete(ctx) {
|
|
74
|
+
const runtime = requireRuntime(ctx.deps);
|
|
75
|
+
const pluginId = assertPluginId(ctx.search.get('pluginId') ?? '');
|
|
76
|
+
const key = assertKey(ctx.search.get('key') ?? '');
|
|
77
|
+
const deleted = await new SqlitePluginKV(runtime.database, pluginId).delete(key);
|
|
78
|
+
sendData(ctx.res, 200, { ok: deleted });
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=kv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv.js","sourceRoot":"","sources":["../../../../src/core/web/routes/kv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ApiContext } from './shared.js';
|
|
2
|
+
export declare function handlePluginsList(ctx: ApiContext): Promise<void>;
|
|
3
|
+
export declare function handlePluginConfigPut(ctx: ApiContext): Promise<void>;
|
|
4
|
+
export declare function handleInstallerAction(ctx: ApiContext): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=plugins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../../../src/core/web/routes/plugins.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAIvE,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCtE;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA0D1E;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4C1E"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { stripPluginEnvelope } from '../../plugin/host.js';
|
|
2
|
+
import { HttpError, isRecord, readJsonBody, sendData } from '../http.js';
|
|
3
|
+
import { asRecord, requireRuntime } from './shared.js';
|
|
4
|
+
const ENVELOPE_KEYS = new Set(['enabled', 'private', 'groups']);
|
|
5
|
+
export async function handlePluginsList(ctx) {
|
|
6
|
+
const runtime = requireRuntime(ctx.deps);
|
|
7
|
+
const statuses = new Map(runtime.kernel.listPlugins().map((entry) => [entry.id, entry]));
|
|
8
|
+
const plugins = runtime.plugins.map((definition) => {
|
|
9
|
+
const id = definition.manifest.id;
|
|
10
|
+
const status = statuses.get(id);
|
|
11
|
+
const envelope = asRecord(runtime.config.plugins[id]);
|
|
12
|
+
return {
|
|
13
|
+
id,
|
|
14
|
+
version: definition.manifest.version,
|
|
15
|
+
description: definition.manifest.description,
|
|
16
|
+
dependencies: definition.manifest.dependencies ?? [],
|
|
17
|
+
defaultEnabled: definition.manifest.defaultEnabled ?? false,
|
|
18
|
+
enabled: status?.enabled ?? false,
|
|
19
|
+
loaded: status?.loaded ?? false,
|
|
20
|
+
config: envelope,
|
|
21
|
+
options: stripPluginEnvelope(envelope),
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
const installed = runtime.installer.enabled
|
|
25
|
+
? await runtime.installer.list()
|
|
26
|
+
: [];
|
|
27
|
+
sendData(ctx.res, 200, {
|
|
28
|
+
plugins,
|
|
29
|
+
installed,
|
|
30
|
+
installerEnabled: runtime.installer.enabled,
|
|
31
|
+
configHash: (await ctx.deps.readConfig()).hash,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export async function handlePluginConfigPut(ctx) {
|
|
35
|
+
const body = asRecord(await readJsonBody(ctx.req));
|
|
36
|
+
const id = ctx.segments[2];
|
|
37
|
+
const document = await ctx.deps.readConfig();
|
|
38
|
+
if (id === undefined)
|
|
39
|
+
throw new HttpError(404, 'unknown plugin');
|
|
40
|
+
if (!isRecord(document.config.plugins[id])) {
|
|
41
|
+
throw new HttpError(404, `unknown plugin: ${id}`);
|
|
42
|
+
}
|
|
43
|
+
const existing = asRecord(document.config.plugins[id]);
|
|
44
|
+
const next = { ...existing };
|
|
45
|
+
if (typeof body['enabled'] === 'boolean') {
|
|
46
|
+
next['enabled'] = body['enabled'];
|
|
47
|
+
}
|
|
48
|
+
if (typeof body['private'] === 'boolean') {
|
|
49
|
+
next['private'] = body['private'];
|
|
50
|
+
}
|
|
51
|
+
if (body['groups'] !== undefined)
|
|
52
|
+
next['groups'] = body['groups'];
|
|
53
|
+
if (body['options'] !== undefined) {
|
|
54
|
+
if (!isRecord(body['options'])) {
|
|
55
|
+
throw new HttpError(400, 'options must be an object');
|
|
56
|
+
}
|
|
57
|
+
for (const key of Object.keys(next)) {
|
|
58
|
+
if (!ENVELOPE_KEYS.has(key))
|
|
59
|
+
delete next[key];
|
|
60
|
+
}
|
|
61
|
+
for (const [key, value] of Object.entries(body['options'])) {
|
|
62
|
+
if (!ENVELOPE_KEYS.has(key))
|
|
63
|
+
next[key] = value;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const config = {
|
|
67
|
+
...document.config,
|
|
68
|
+
plugins: {
|
|
69
|
+
...document.config.plugins,
|
|
70
|
+
[id]: next,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
const baseHash = body['baseHash'];
|
|
74
|
+
sendData(ctx.res, 200, await ctx.deps.applyConfig(config, typeof baseHash === 'string' ? baseHash : undefined));
|
|
75
|
+
}
|
|
76
|
+
export async function handleInstallerAction(ctx) {
|
|
77
|
+
const runtime = requireRuntime(ctx.deps);
|
|
78
|
+
if (!runtime.installer.enabled) {
|
|
79
|
+
throw new HttpError(403, '插件安装器未启用');
|
|
80
|
+
}
|
|
81
|
+
const body = asRecord(await readJsonBody(ctx.req));
|
|
82
|
+
const target = typeof body['target'] === 'string' ? body['target'] : '';
|
|
83
|
+
const spec = typeof body['spec'] === 'string' ? body['spec'] : '';
|
|
84
|
+
if (ctx.pathname.endsWith('/install')) {
|
|
85
|
+
if (!spec)
|
|
86
|
+
throw new HttpError(400, 'spec is required');
|
|
87
|
+
sendData(ctx.res, 200, await ctx.deps.runExclusive(() => runtime.installer.install(spec)));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (ctx.pathname.endsWith('/update')) {
|
|
91
|
+
sendData(ctx.res, 200, await ctx.deps.runExclusive(() => runtime.installer.update(target || undefined)));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
sendData(ctx.res, 200, await ctx.deps.runExclusive(async () => runtime.installer.remove(target, undefined, {
|
|
95
|
+
force: body['force'] === true,
|
|
96
|
+
})));
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../../../src/core/web/routes/plugins.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ApiContext } from './shared.js';
|
|
2
|
+
export declare function handleSessionList(ctx: ApiContext): Promise<void>;
|
|
3
|
+
export declare function handleSessionGet(ctx: ApiContext): Promise<void>;
|
|
4
|
+
export declare function handleSessionPut(ctx: ApiContext): Promise<void>;
|
|
5
|
+
export declare function handleSessionMessages(ctx: ApiContext): Promise<void>;
|
|
6
|
+
export declare function handleSessionSend(ctx: ApiContext): Promise<void>;
|
|
7
|
+
export declare function handleSessionDelete(ctx: ApiContext): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../../src/core/web/routes/sessions.ts"],"names":[],"mappings":"AAOA,OAAO,EAIH,KAAK,UAAU,EAClB,MAAM,aAAa,CAAA;AAsDpB,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtE;AAyBD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAErE;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBrE;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B1E;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBtE;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxE"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { SqliteSessionStore, } from '../../storage/session.js';
|
|
2
|
+
import { HttpError, isRecord, readJsonBody, sendData } from '../http.js';
|
|
3
|
+
import { asRecord, clampInt, requireRuntime, } from './shared.js';
|
|
4
|
+
const MAX_SESSION_MESSAGES = 10_000;
|
|
5
|
+
function parseSessionMessages(value) {
|
|
6
|
+
if (!Array.isArray(value)) {
|
|
7
|
+
throw new HttpError(400, 'messages must be an array');
|
|
8
|
+
}
|
|
9
|
+
if (value.length > MAX_SESSION_MESSAGES) {
|
|
10
|
+
throw new HttpError(400, 'messages too long');
|
|
11
|
+
}
|
|
12
|
+
return value.map((item, index) => {
|
|
13
|
+
if (!isRecord(item)) {
|
|
14
|
+
throw new HttpError(400, `invalid message at index ${index}`);
|
|
15
|
+
}
|
|
16
|
+
const role = item['role'];
|
|
17
|
+
const content = item['content'];
|
|
18
|
+
const at = item['at'];
|
|
19
|
+
if (role !== 'system' && role !== 'user' && role !== 'assistant') {
|
|
20
|
+
throw new HttpError(400, `invalid message role at index ${index}`);
|
|
21
|
+
}
|
|
22
|
+
if (typeof content !== 'string') {
|
|
23
|
+
throw new HttpError(400, `invalid message content at index ${index}`);
|
|
24
|
+
}
|
|
25
|
+
if (typeof at !== 'number' || !Number.isFinite(at)) {
|
|
26
|
+
throw new HttpError(400, `invalid message time at index ${index}`);
|
|
27
|
+
}
|
|
28
|
+
return { role: role, content, at };
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function clearableString(value, fallback) {
|
|
32
|
+
if (value === null)
|
|
33
|
+
return undefined;
|
|
34
|
+
if (value === undefined)
|
|
35
|
+
return fallback;
|
|
36
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
export async function handleSessionList(ctx) {
|
|
42
|
+
const runtime = requireRuntime(ctx.deps);
|
|
43
|
+
const store = new SqliteSessionStore(runtime.database);
|
|
44
|
+
const limit = clampInt(ctx.search.get('limit'), 50, 1, 200);
|
|
45
|
+
const offset = clampInt(ctx.search.get('offset'), 0, 0, 10_000_000);
|
|
46
|
+
const query = ctx.search.get('query')?.slice(0, 200) || undefined;
|
|
47
|
+
const items = await store.list({ limit, offset, query });
|
|
48
|
+
const total = await store.count(query);
|
|
49
|
+
sendData(ctx.res, 200, { items, total, limit, offset });
|
|
50
|
+
}
|
|
51
|
+
function sessionIdOf(ctx) {
|
|
52
|
+
const id = ctx.segments[2];
|
|
53
|
+
if (!id)
|
|
54
|
+
throw new HttpError(404, 'session not found');
|
|
55
|
+
return id;
|
|
56
|
+
}
|
|
57
|
+
function requireSessionStore(ctx) {
|
|
58
|
+
const runtime = requireRuntime(ctx.deps);
|
|
59
|
+
return new SqliteSessionStore(runtime.database);
|
|
60
|
+
}
|
|
61
|
+
async function sessionDetail(ctx) {
|
|
62
|
+
const id = sessionIdOf(ctx);
|
|
63
|
+
const state = await requireSessionStore(ctx).get(id);
|
|
64
|
+
if (!state)
|
|
65
|
+
throw new HttpError(404, 'session not found');
|
|
66
|
+
return state;
|
|
67
|
+
}
|
|
68
|
+
export async function handleSessionGet(ctx) {
|
|
69
|
+
sendData(ctx.res, 200, await sessionDetail(ctx));
|
|
70
|
+
}
|
|
71
|
+
export async function handleSessionPut(ctx) {
|
|
72
|
+
const body = asRecord(await readJsonBody(ctx.req));
|
|
73
|
+
await sessionDetail(ctx);
|
|
74
|
+
const messages = body['messages'] === undefined
|
|
75
|
+
? undefined
|
|
76
|
+
: parseSessionMessages(body['messages']);
|
|
77
|
+
const baseline = await sessionDetail(ctx);
|
|
78
|
+
const state = {
|
|
79
|
+
sessionId: sessionIdOf(ctx),
|
|
80
|
+
provider: clearableString(body['provider'], baseline.provider),
|
|
81
|
+
model: clearableString(body['model'], baseline.model),
|
|
82
|
+
persona: clearableString(body['persona'], baseline.persona),
|
|
83
|
+
messages: messages ?? baseline.messages,
|
|
84
|
+
updatedAt: Date.now(),
|
|
85
|
+
};
|
|
86
|
+
await requireSessionStore(ctx).save(state);
|
|
87
|
+
sendData(ctx.res, 200, state);
|
|
88
|
+
}
|
|
89
|
+
export async function handleSessionMessages(ctx) {
|
|
90
|
+
const body = asRecord(await readJsonBody(ctx.req));
|
|
91
|
+
const role = body['role'];
|
|
92
|
+
const content = body['content'];
|
|
93
|
+
if (role !== 'system' && role !== 'user' && role !== 'assistant') {
|
|
94
|
+
throw new HttpError(400, 'invalid message role');
|
|
95
|
+
}
|
|
96
|
+
if (typeof content !== 'string' ||
|
|
97
|
+
content.length === 0 ||
|
|
98
|
+
content.length > 100_000) {
|
|
99
|
+
throw new HttpError(400, 'invalid message content');
|
|
100
|
+
}
|
|
101
|
+
const state = await sessionDetail(ctx);
|
|
102
|
+
const message = { role: role, content, at: Date.now() };
|
|
103
|
+
const next = {
|
|
104
|
+
...state,
|
|
105
|
+
messages: [...state.messages, message],
|
|
106
|
+
updatedAt: Date.now(),
|
|
107
|
+
};
|
|
108
|
+
await requireSessionStore(ctx).save(next);
|
|
109
|
+
sendData(ctx.res, 200, next);
|
|
110
|
+
}
|
|
111
|
+
export async function handleSessionSend(ctx) {
|
|
112
|
+
const body = asRecord(await readJsonBody(ctx.req));
|
|
113
|
+
const id = sessionIdOf(ctx);
|
|
114
|
+
const message = body['message'];
|
|
115
|
+
const autoEscape = body['autoEscape'];
|
|
116
|
+
if (typeof message !== 'string' ||
|
|
117
|
+
message.length === 0 ||
|
|
118
|
+
message.length > 20_000) {
|
|
119
|
+
throw new HttpError(400, 'invalid message');
|
|
120
|
+
}
|
|
121
|
+
const runtime = requireRuntime(ctx.deps);
|
|
122
|
+
await sessionDetail(ctx);
|
|
123
|
+
const result = await runtime.api.send(id, message, typeof autoEscape === 'boolean' ? { autoEscape } : undefined);
|
|
124
|
+
sendData(ctx.res, 200, { result: result ?? null });
|
|
125
|
+
}
|
|
126
|
+
export async function handleSessionDelete(ctx) {
|
|
127
|
+
await requireSessionStore(ctx).clear(sessionIdOf(ctx));
|
|
128
|
+
sendData(ctx.res, 200, { cleared: true });
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../../src/core/web/routes/sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { AuthSession } from '../auth.js';
|
|
3
|
+
import { type URLSearchParamsLike } from '../http.js';
|
|
4
|
+
import type { WebUiDeps, WebUiRuntime } from '../types.js';
|
|
5
|
+
export interface ApiContext {
|
|
6
|
+
deps: WebUiDeps;
|
|
7
|
+
req: IncomingMessage;
|
|
8
|
+
res: ServerResponse;
|
|
9
|
+
method: string;
|
|
10
|
+
pathname: string;
|
|
11
|
+
segments: string[];
|
|
12
|
+
search: URLSearchParamsLike;
|
|
13
|
+
session: AuthSession;
|
|
14
|
+
}
|
|
15
|
+
export declare function requireRuntime(deps: WebUiDeps): WebUiRuntime;
|
|
16
|
+
export declare function clampInt(value: string | null, fallback: number, min: number, max: number): number;
|
|
17
|
+
export declare function asRecord(value: unknown): Record<string, unknown>;
|
|
18
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/core/web/routes/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAuB,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1D,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,SAAS,CAAA;IACf,GAAG,EAAE,eAAe,CAAA;IACpB,GAAG,EAAE,cAAc,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,OAAO,EAAE,WAAW,CAAA;CACvB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,YAAY,CAM5D;AAED,wBAAgB,QAAQ,CACpB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACZ,MAAM,CAQR;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEhE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { HttpError, isRecord } from '../http.js';
|
|
2
|
+
export function requireRuntime(deps) {
|
|
3
|
+
const runtime = deps.getRuntime();
|
|
4
|
+
if (!runtime)
|
|
5
|
+
throw new HttpError(503, '运行时不可用,请稍后再试');
|
|
6
|
+
return runtime;
|
|
7
|
+
}
|
|
8
|
+
export function clampInt(value, fallback, min, max) {
|
|
9
|
+
if (value === null)
|
|
10
|
+
return fallback;
|
|
11
|
+
const parsed = Number.parseInt(value, 10);
|
|
12
|
+
if (!Number.isFinite(parsed))
|
|
13
|
+
return fallback;
|
|
14
|
+
return Math.min(Math.max(parsed, min), max);
|
|
15
|
+
}
|
|
16
|
+
export function asRecord(value) {
|
|
17
|
+
return isRecord(value) ? value : {};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../src/core/web/routes/shared.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAA4B,MAAM,YAAY,CAAA;AAc1E,MAAM,UAAU,cAAc,CAAC,IAAe;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAA;IAEjC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IAEtD,OAAO,OAAO,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,QAAQ,CACpB,KAAoB,EACpB,QAAgB,EAChB,GAAW,EACX,GAAW;IAEX,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,QAAQ,CAAA;IAEnC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAEzC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,QAAQ,CAAA;IAE7C,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;AAC/C,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc;IACnC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;AACvC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ApiContext } from './shared.js';
|
|
2
|
+
export declare function handleStatus(ctx: ApiContext): Promise<void>;
|
|
3
|
+
export declare function handleCommands(ctx: ApiContext): Promise<void>;
|
|
4
|
+
export declare function handleLogsList(ctx: ApiContext): Promise<void>;
|
|
5
|
+
export declare function handleEventsList(ctx: ApiContext): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/core/web/routes/status.ts"],"names":[],"mappings":"AAKA,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAkHvE,wBAAsB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BjE;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBnE;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAerE"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { SqliteSessionStore } from '../../storage/session.js';
|
|
2
|
+
import { logLevels } from '../../logging/logger.js';
|
|
3
|
+
import { HttpError, sendData, withTimeout } from '../http.js';
|
|
4
|
+
import { clampInt, requireRuntime } from './shared.js';
|
|
5
|
+
const loginCache = new WeakMap();
|
|
6
|
+
async function loginInfo(runtime) {
|
|
7
|
+
if (!runtime.kernel.isConnected)
|
|
8
|
+
return null;
|
|
9
|
+
const cached = loginCache.get(runtime);
|
|
10
|
+
if (cached && Date.now() - cached.at < 10_000)
|
|
11
|
+
return cached.value;
|
|
12
|
+
let value = null;
|
|
13
|
+
try {
|
|
14
|
+
const info = await withTimeout(runtime.api.getLoginInfo(), 2_000);
|
|
15
|
+
if (typeof info.user_id === 'number') {
|
|
16
|
+
value = {
|
|
17
|
+
userId: info.user_id,
|
|
18
|
+
nickname: info.nickname || String(info.user_id),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
value = null;
|
|
24
|
+
}
|
|
25
|
+
loginCache.set(runtime, { at: Date.now(), value });
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
function countKvPlugins(database) {
|
|
29
|
+
const row = database.connection
|
|
30
|
+
.prepare('SELECT COUNT(DISTINCT plugin_id) AS count FROM plugin_kv')
|
|
31
|
+
.get();
|
|
32
|
+
return row?.count ?? 0;
|
|
33
|
+
}
|
|
34
|
+
async function runtimeStatus(runtime) {
|
|
35
|
+
const statuses = runtime.kernel.listPlugins();
|
|
36
|
+
const sessions = await new SqliteSessionStore(runtime.database).count();
|
|
37
|
+
return {
|
|
38
|
+
generation: runtime.generation,
|
|
39
|
+
state: runtime.kernel.state,
|
|
40
|
+
uptimeMs: runtime.kernel.uptimeMs,
|
|
41
|
+
connected: runtime.kernel.isConnected,
|
|
42
|
+
login: await loginInfo(runtime),
|
|
43
|
+
counts: {
|
|
44
|
+
plugins: statuses.length,
|
|
45
|
+
loadedPlugins: statuses.filter((entry) => entry.loaded).length,
|
|
46
|
+
enabledPlugins: statuses.filter((entry) => entry.enabled).length,
|
|
47
|
+
sessions,
|
|
48
|
+
kvPlugins: countKvPlugins(runtime.database),
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function pathsInfo(deps) {
|
|
53
|
+
return {
|
|
54
|
+
config: deps.paths.configPath,
|
|
55
|
+
data: deps.paths.dataDir,
|
|
56
|
+
plugins: deps.paths.pluginDir,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function assertLevel(value) {
|
|
60
|
+
if (!logLevels.includes(value)) {
|
|
61
|
+
throw new HttpError(400, `invalid log level: ${value}`);
|
|
62
|
+
}
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
const FEED_TYPES = [
|
|
66
|
+
'message',
|
|
67
|
+
'notice',
|
|
68
|
+
'request',
|
|
69
|
+
'meta',
|
|
70
|
+
'other',
|
|
71
|
+
];
|
|
72
|
+
function assertFeedType(value) {
|
|
73
|
+
if (!FEED_TYPES.includes(value)) {
|
|
74
|
+
throw new HttpError(400, `invalid event type: ${value}`);
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
export async function handleStatus(ctx) {
|
|
79
|
+
const { deps, res } = ctx;
|
|
80
|
+
const runtime = deps.getRuntime();
|
|
81
|
+
const webui = {
|
|
82
|
+
listening: deps.getListening(),
|
|
83
|
+
requiresProcessRestart: deps.getRequiresProcessRestart(),
|
|
84
|
+
};
|
|
85
|
+
if (!runtime) {
|
|
86
|
+
sendData(res, 200, {
|
|
87
|
+
restarting: deps.isRestarting(),
|
|
88
|
+
startupError: deps.getStartupError(),
|
|
89
|
+
runtime: null,
|
|
90
|
+
webui,
|
|
91
|
+
version: deps.version,
|
|
92
|
+
paths: pathsInfo(deps),
|
|
93
|
+
});
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
sendData(res, 200, {
|
|
97
|
+
restarting: deps.isRestarting(),
|
|
98
|
+
startupError: deps.getStartupError(),
|
|
99
|
+
runtime: await runtimeStatus(runtime),
|
|
100
|
+
webui,
|
|
101
|
+
version: deps.version,
|
|
102
|
+
paths: pathsInfo(deps),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
export async function handleCommands(ctx) {
|
|
106
|
+
sendData(ctx.res, 200, requireRuntime(ctx.deps).kernel.listCommands());
|
|
107
|
+
}
|
|
108
|
+
export async function handleLogsList(ctx) {
|
|
109
|
+
const level = ctx.search.get('level');
|
|
110
|
+
if (level)
|
|
111
|
+
assertLevel(level);
|
|
112
|
+
const scope = ctx.search.get('scope') ?? undefined;
|
|
113
|
+
const query = ctx.search.get('query') ?? undefined;
|
|
114
|
+
const limit = clampInt(ctx.search.get('limit'), 200, 1, 1_000);
|
|
115
|
+
sendData(ctx.res, 200, ctx.deps.logs.list({
|
|
116
|
+
...(level ? { level: assertLevel(level) } : {}),
|
|
117
|
+
scope,
|
|
118
|
+
query,
|
|
119
|
+
limit,
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
export async function handleEventsList(ctx) {
|
|
123
|
+
const type = ctx.search.get('type');
|
|
124
|
+
if (type)
|
|
125
|
+
assertFeedType(type);
|
|
126
|
+
const limit = clampInt(ctx.search.get('limit'), 100, 1, 500);
|
|
127
|
+
sendData(ctx.res, 200, ctx.deps.events.list({
|
|
128
|
+
...(type ? { type: assertFeedType(type) } : {}),
|
|
129
|
+
limit,
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/core/web/routes/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { AuthManager, type AuthSession } from '../auth.js';
|
|
3
|
+
import type { WebUiDeps } from '../types.js';
|
|
4
|
+
export declare const SESSION_COOKIE = "jsbot_webui";
|
|
5
|
+
export declare function authenticate(auth: AuthManager, req: IncomingMessage): AuthSession | null;
|
|
6
|
+
export declare function tokenOf(req: IncomingMessage): string | undefined;
|
|
7
|
+
export declare function isSecure(deps: WebUiDeps, req: IncomingMessage): boolean;
|
|
8
|
+
export interface HandleAuthOptions {
|
|
9
|
+
req: IncomingMessage;
|
|
10
|
+
res: ServerResponse;
|
|
11
|
+
action: string | undefined;
|
|
12
|
+
auth: AuthManager;
|
|
13
|
+
deps: WebUiDeps;
|
|
14
|
+
bodyLimit: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function handleAuth(options: HandleAuthOptions): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/core/web/server/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAW1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,eAAO,MAAM,cAAc,gBAAgB,CAAA;AAE3C,wBAAgB,YAAY,CACxB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,eAAe,GACrB,WAAW,GAAG,IAAI,CAIpB;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAIhE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAMvE;AAED,MAAM,WAAW,iBAAiB;IAC9B,GAAG,EAAE,eAAe,CAAA;IACpB,GAAG,EAAE,cAAc,CAAA;IACnB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,SAAS,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CACpB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6E1E"}
|