@aalis/plugin-webui-server 0.14.1 → 0.16.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.
Files changed (118) hide show
  1. package/README.md +5 -1
  2. package/dist/admin-channel.d.ts +10 -0
  3. package/dist/admin-channel.d.ts.map +1 -0
  4. package/dist/admin-channel.js +57 -0
  5. package/dist/admin-channel.js.map +1 -0
  6. package/dist/attention.d.ts +36 -0
  7. package/dist/attention.d.ts.map +1 -0
  8. package/dist/attention.js +74 -0
  9. package/dist/attention.js.map +1 -0
  10. package/dist/auth.d.ts +32 -4
  11. package/dist/auth.d.ts.map +1 -1
  12. package/dist/auth.js +253 -79
  13. package/dist/auth.js.map +1 -1
  14. package/dist/client-discovery.d.ts +7 -3
  15. package/dist/client-discovery.d.ts.map +1 -1
  16. package/dist/client-discovery.js +9 -3
  17. package/dist/client-discovery.js.map +1 -1
  18. package/dist/client-switch-page.d.ts +26 -2
  19. package/dist/client-switch-page.d.ts.map +1 -1
  20. package/dist/client-switch-page.js +76 -45
  21. package/dist/client-switch-page.js.map +1 -1
  22. package/dist/gate.d.ts +3 -3
  23. package/dist/gate.d.ts.map +1 -1
  24. package/dist/gate.js +5 -4
  25. package/dist/gate.js.map +1 -1
  26. package/dist/html.d.ts +15 -0
  27. package/dist/html.d.ts.map +1 -0
  28. package/dist/html.js +38 -0
  29. package/dist/html.js.map +1 -0
  30. package/dist/index.d.ts +24 -26
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +627 -1102
  33. package/dist/index.js.map +1 -1
  34. package/dist/layout.d.ts +19 -0
  35. package/dist/layout.d.ts.map +1 -0
  36. package/dist/layout.js +200 -0
  37. package/dist/layout.js.map +1 -0
  38. package/dist/locales/en.d.ts +191 -0
  39. package/dist/locales/en.d.ts.map +1 -0
  40. package/dist/locales/en.js +191 -0
  41. package/dist/locales/en.js.map +1 -0
  42. package/dist/localize.d.ts +24 -0
  43. package/dist/localize.d.ts.map +1 -0
  44. package/dist/localize.js +68 -0
  45. package/dist/localize.js.map +1 -0
  46. package/dist/logs.d.ts +10 -0
  47. package/dist/logs.d.ts.map +1 -0
  48. package/dist/logs.js +50 -0
  49. package/dist/logs.js.map +1 -0
  50. package/dist/page-check.d.ts +56 -0
  51. package/dist/page-check.d.ts.map +1 -0
  52. package/dist/page-check.js +376 -0
  53. package/dist/page-check.js.map +1 -0
  54. package/dist/page-files.d.ts +13 -0
  55. package/dist/page-files.d.ts.map +1 -0
  56. package/dist/page-files.js +39 -0
  57. package/dist/page-files.js.map +1 -0
  58. package/dist/pages.d.ts +62 -0
  59. package/dist/pages.d.ts.map +1 -0
  60. package/dist/pages.js +486 -0
  61. package/dist/pages.js.map +1 -0
  62. package/dist/route.d.ts +14 -0
  63. package/dist/route.d.ts.map +1 -0
  64. package/dist/route.js +16 -0
  65. package/dist/route.js.map +1 -0
  66. package/dist/routes/files.d.ts +8 -9
  67. package/dist/routes/files.d.ts.map +1 -1
  68. package/dist/routes/files.js +33 -119
  69. package/dist/routes/files.js.map +1 -1
  70. package/dist/routes/frames.d.ts +4 -0
  71. package/dist/routes/frames.d.ts.map +1 -0
  72. package/dist/routes/frames.js +103 -0
  73. package/dist/routes/frames.js.map +1 -0
  74. package/dist/routes/i18n.d.ts +20 -0
  75. package/dist/routes/i18n.d.ts.map +1 -0
  76. package/dist/routes/i18n.js +78 -0
  77. package/dist/routes/i18n.js.map +1 -0
  78. package/dist/routes/marketplace.d.ts +46 -129
  79. package/dist/routes/marketplace.d.ts.map +1 -1
  80. package/dist/routes/marketplace.js +156 -106
  81. package/dist/routes/marketplace.js.map +1 -1
  82. package/dist/routes/media.d.ts +10 -0
  83. package/dist/routes/media.d.ts.map +1 -0
  84. package/dist/routes/media.js +66 -0
  85. package/dist/routes/media.js.map +1 -0
  86. package/dist/routes/pages.d.ts +22 -0
  87. package/dist/routes/pages.d.ts.map +1 -0
  88. package/dist/routes/pages.js +104 -0
  89. package/dist/routes/pages.js.map +1 -0
  90. package/dist/routes/pipe-to-response.d.ts +9 -0
  91. package/dist/routes/pipe-to-response.d.ts.map +1 -0
  92. package/dist/routes/pipe-to-response.js +16 -0
  93. package/dist/routes/pipe-to-response.js.map +1 -0
  94. package/dist/routes/plugins.d.ts +22 -28
  95. package/dist/routes/plugins.d.ts.map +1 -1
  96. package/dist/routes/plugins.js +339 -344
  97. package/dist/routes/plugins.js.map +1 -1
  98. package/dist/routes/proxy.d.ts +3 -2
  99. package/dist/routes/proxy.d.ts.map +1 -1
  100. package/dist/routes/proxy.js +64 -42
  101. package/dist/routes/proxy.js.map +1 -1
  102. package/dist/session-transport.d.ts +6 -0
  103. package/dist/session-transport.d.ts.map +1 -0
  104. package/dist/session-transport.js +32 -0
  105. package/dist/session-transport.js.map +1 -0
  106. package/dist/texts.d.ts +381 -0
  107. package/dist/texts.d.ts.map +1 -0
  108. package/dist/texts.js +194 -0
  109. package/dist/texts.js.map +1 -0
  110. package/package.json +38 -32
  111. package/dist/protocol.d.ts +0 -113
  112. package/dist/protocol.d.ts.map +0 -1
  113. package/dist/protocol.js +0 -59
  114. package/dist/protocol.js.map +0 -1
  115. package/dist/routes/uploaded-files.d.ts +0 -20
  116. package/dist/routes/uploaded-files.d.ts.map +0 -1
  117. package/dist/routes/uploaded-files.js +0 -161
  118. package/dist/routes/uploaded-files.js.map +0 -1
@@ -0,0 +1,10 @@
1
+ import { type StorageService } from '@aalis/api-storage';
2
+ import type { Logger } from '@aalis/core';
3
+ import { type MediaFormat } from '@aalis/util-file-signature';
4
+ import type express from 'express';
5
+ import type { RouteGate } from '../gate.js';
6
+ /** 按文件头判定出浏览器能直接显示或播放的格式,判不出或不在 {@link BROWSER_MEDIA} 里的为 undefined */
7
+ export declare function browserMediaOf(head: Uint8Array): MediaFormat | undefined;
8
+ /** 传入的是 storage 的业务句柄:区间读恒有定义,提供者不支持时调用即抛错 */
9
+ export declare function registerMediaRoutes(expressApp: express.Express, storage: StorageService & Required<Pick<StorageService, 'readFileRange'>>, logger: Logger, gate: RouteGate): void;
10
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/routes/media.ts"],"names":[],"mappings":"AAUA,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAsC,KAAK,WAAW,EAAwB,MAAM,4BAA4B,CAAC;AACxH,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAmB5C,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,SAAS,CAGxE;AAED,8CAA8C;AAC9C,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,OAAO,CAAC,OAAO,EAC3B,OAAO,EAAE,cAAc,GAAG,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC,EACzE,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,GACd,IAAI,CA8BN"}
@@ -0,0 +1,66 @@
1
+ // ============================================================
2
+ // routes/media.ts — 聊天里的图片、视频与音频按存储地址取
3
+ //
4
+ // GET /api/media?uri=<storage URI>(如 data:/images/x.png)。聊天消息与会话历史里的附件多半是存储
5
+ // 地址,浏览器拿它当不了图片地址;客户端把它换成这条路由。只有 owner(cookie 闸)能取;按文件头判定类型,
6
+ // 只放行浏览器能直接显示或播放的图片、视频与音频,其余(含 HTML、SVG、JSON 账本)一律 415,不在 WebUI 源里内联。
7
+ // 响应带 nosniff 与 sandbox CSP,类型取判定结果、不取扩展名。文件不存在回 404,其余读不出的(含存储拒绝的越界路径)
8
+ // 回 500 并记告警。
9
+ // ============================================================
10
+ import { isStorageNotFound, isStorageUri } from '@aalis/api-storage';
11
+ import { detectMediaFormat, FILE_HEAD_BYTES } from '@aalis/util-file-signature';
12
+ import { route } from '../route.js';
13
+ import { t } from '../texts.js';
14
+ import { pipeToResponse } from './pipe-to-response.js';
15
+ /** 浏览器能直接显示或播放的格式:这条路由与图片代理(只取其中的图片)都只提供这几种,响应类型取判定结果 */
16
+ const BROWSER_MEDIA = new Set([
17
+ 'PNG',
18
+ 'JPEG',
19
+ 'GIF',
20
+ 'WebP',
21
+ 'MP4',
22
+ 'WebM',
23
+ 'MP3',
24
+ 'WAV',
25
+ 'OGG',
26
+ 'M4A',
27
+ ]);
28
+ /** 按文件头判定出浏览器能直接显示或播放的格式,判不出或不在 {@link BROWSER_MEDIA} 里的为 undefined */
29
+ export function browserMediaOf(head) {
30
+ const format = detectMediaFormat(head.subarray(0, FILE_HEAD_BYTES));
31
+ return format && BROWSER_MEDIA.has(format.format) ? format : undefined;
32
+ }
33
+ /** 传入的是 storage 的业务句柄:区间读恒有定义,提供者不支持时调用即抛错 */
34
+ export function registerMediaRoutes(expressApp, storage, logger, gate) {
35
+ route(expressApp, 'GET /api/media', gate(), async (req, res) => {
36
+ const uri = String(req.query.uri ?? '');
37
+ if (!isStorageUri(uri)) {
38
+ res.status(400).json({ error: t('notStorageUri') });
39
+ return;
40
+ }
41
+ try {
42
+ const format = browserMediaOf(await storage.readFileRange(uri, 0, FILE_HEAD_BYTES));
43
+ if (!format) {
44
+ res.status(415).json({ error: t('notMedia') });
45
+ return;
46
+ }
47
+ const { stream, stat } = await storage.createReadStream(uri);
48
+ res.setHeader('Content-Type', format.mime);
49
+ res.setHeader('Content-Length', stat.size);
50
+ res.setHeader('Content-Disposition', 'inline');
51
+ res.setHeader('X-Content-Type-Options', 'nosniff');
52
+ res.setHeader('Content-Security-Policy', "sandbox; default-src 'none'");
53
+ res.setHeader('Cache-Control', 'private, max-age=3600');
54
+ pipeToResponse(stream, res, logger, `媒体文件 ${uri}`);
55
+ }
56
+ catch (err) {
57
+ if (isStorageNotFound(err)) {
58
+ res.status(404).json({ error: t('fileMissing') });
59
+ return;
60
+ }
61
+ logger.warn(`读取媒体文件 ${uri} 失败:`, err);
62
+ res.status(500).json({ error: t('readFailed') });
63
+ }
64
+ });
65
+ }
66
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/routes/media.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,uCAAuC;AACvC,EAAE;AACF,4EAA4E;AAC5E,6DAA6D;AAC7D,sEAAsE;AACtE,wEAAwE;AACxE,cAAc;AACd,+DAA+D;AAE/D,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAuB,MAAM,oBAAoB,CAAC;AAE1F,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAA0C,MAAM,4BAA4B,CAAC;AAGxH,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,yDAAyD;AACzD,MAAM,aAAa,GAAiC,IAAI,GAAG,CAAC;IAC1D,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC,CAAC;AAEH,uEAAuE;AACvE,MAAM,UAAU,cAAc,CAAC,IAAgB;IAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;IACpE,OAAO,MAAM,IAAI,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACzE,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,mBAAmB,CACjC,UAA2B,EAC3B,OAAyE,EACzE,MAAc,EACd,IAAe;IAEf,KAAK,CAAC,UAAU,EAAE,gBAAgB,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;YACpF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBAC/C,OAAO;YACT,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAC7D,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC3C,GAAG,CAAC,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,GAAG,CAAC,SAAS,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC;YAC/C,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;YACnD,GAAG,CAAC,SAAS,CAAC,yBAAyB,EAAE,6BAA6B,CAAC,CAAC;YACxE,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAAC;YACxD,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAG,EAAE,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;gBAClD,OAAO;YACT,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC;YACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { UserIdentity } from '@aalis/api-authority';
2
+ import type { FrameTexts, WebuiAdminEvent } from '@aalis/api-webui';
3
+ import { type Logger } from '@aalis/core';
4
+ import type express from 'express';
5
+ import type { RouteGate } from '../gate.js';
6
+ import { type LayoutStore } from '../layout.js';
7
+ import type { PageRegistry } from '../pages.js';
8
+ export declare function registerPageRoutes(expressApp: express.Express, deps: {
9
+ registry: PageRegistry;
10
+ layout: LayoutStore;
11
+ /** 存储服务在不在:布局记录读写要它 */
12
+ storageReady(): boolean;
13
+ send(event: WebuiAdminEvent): void;
14
+ logger: Logger;
15
+ /** 一个插件的字典,交给插件前端 */
16
+ texts(plugin: string): FrameTexts;
17
+ }, identify: (req: {
18
+ headers: {
19
+ cookie?: string;
20
+ };
21
+ }) => UserIdentity | undefined, gate: RouteGate): void;
22
+ //# sourceMappingURL=pages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/routes/pages.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAiB,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,KAAK,MAAM,EAAmB,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAc,KAAK,WAAW,EAAwB,MAAM,cAAc,CAAC;AAElF,OAAO,KAAK,EAAE,YAAY,EAAS,MAAM,aAAa,CAAC;AAIvD,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,OAAO,CAAC,OAAO,EAC3B,IAAI,EAAE;IACJ,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,uBAAuB;IACvB,YAAY,IAAI,OAAO,CAAC;IACxB,IAAI,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC;CACnC,EACD,QAAQ,EAAE,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,KAAK,YAAY,GAAG,SAAS,EAC7E,IAAI,EAAE,SAAS,GACd,IAAI,CA2FN"}
@@ -0,0 +1,104 @@
1
+ // ============================================================
2
+ // routes/pages.ts — 声明式页面、会话面板与布局记录的 REST 路由
3
+ //
4
+ // 路径与返回形状见 api-webui 的 page.ts。页面的数据源与动作要把调用者交给插件,这两条路由自己解析身份(与 gate 同一判定);
5
+ // 其余用 gate。闸门与校验在 pages.ts,这里只把请求交过去、把结果连同它要的渲染选项写回。插件前端的字典是这一页所属插件
6
+ // 的(插件名取实例 id 第一个「:」之前的部分),原样交出。布局记录存在插件数据里,存储服务不在时回 503。
7
+ // ============================================================
8
+ import { parseInstanceId } from '@aalis/core';
9
+ import { LayoutFull, parseLayoutOperation } from '../layout.js';
10
+ import { renderWith, skipSchemaDefaults } from '../localize.js';
11
+ import { route } from '../route.js';
12
+ import { t } from '../texts.js';
13
+ export function registerPageRoutes(expressApp, deps, identify, gate) {
14
+ const { registry, layout } = deps;
15
+ const reply = (res, { status, body, render }) => {
16
+ if (render)
17
+ renderWith(res, render);
18
+ res.status(status).json(body);
19
+ };
20
+ const forbidden = (res) => res.status(403).json({ error: t('ownerRequired') });
21
+ route(expressApp, 'GET /api/pages', gate(), (_req, res) => {
22
+ const pages = registry.views();
23
+ const inputs = pages.flatMap(page => Object.values(page.actions ?? {}).map(action => action.input));
24
+ renderWith(res, { skip: skipSchemaDefaults(inputs) });
25
+ res.json({ pages });
26
+ });
27
+ route(expressApp, 'GET /api/session-pages', gate(), async (req, res) => {
28
+ reply(res, await registry.panelPages(req.query.sessionId));
29
+ });
30
+ route(expressApp, 'GET /api/pages/:instance/:pageKey/texts', gate(), (req, res) => {
31
+ const { instance, pageKey } = req.params;
32
+ if (!registry.placementOf({ instance, pageKey })) {
33
+ return res.status(404).json({ error: t('pageMissing', { page: pageKey, instance }) });
34
+ }
35
+ // 字典是原样数据:译文表的键可能恰好是文字对象的那几个
36
+ renderWith(res, { skip: () => true });
37
+ res.json(deps.texts(parseInstanceId(instance).moduleName));
38
+ });
39
+ route(expressApp, 'GET /api/pages/:instance/:pageKey/data/:componentId', async (req, res) => {
40
+ const caller = identify(req);
41
+ if (!caller)
42
+ return forbidden(res);
43
+ const { instance, pageKey, componentId } = req.params;
44
+ reply(res, await registry.data(instance, pageKey, componentId, req.query, { caller }));
45
+ });
46
+ route(expressApp, 'POST /api/pages/:instance/:pageKey/actions/:action', async (req, res) => {
47
+ const caller = identify(req);
48
+ if (!caller)
49
+ return forbidden(res);
50
+ const { instance, pageKey, action } = req.params;
51
+ reply(res, await registry.act(instance, pageKey, action, req.body, { caller }, req.socket.remoteAddress ?? '未知'));
52
+ });
53
+ const storageMissing = (res) => res.status(503).json({ error: t('noStorageLayout') });
54
+ route(expressApp, 'GET /api/layout', gate(), async (_req, res) => {
55
+ if (!deps.storageReady())
56
+ return storageMissing(res);
57
+ try {
58
+ res.json(await layout.read());
59
+ }
60
+ catch (err) {
61
+ deps.logger.warn('读取布局记录失败:', err);
62
+ res.status(500).json({ error: t('layoutReadFailed') });
63
+ }
64
+ });
65
+ route(expressApp, 'POST /api/layout', gate(), async (req, res) => {
66
+ if (!deps.storageReady())
67
+ return storageMissing(res);
68
+ const operation = parseLayoutOperation(req.body);
69
+ if (!operation) {
70
+ return res.status(400).json({ error: t('layoutOpInvalid') });
71
+ }
72
+ // 固定与打开插件标签只收此刻登记着、位置对的页面;其余只动记录,所属插件停用时也能改
73
+ const wanted = operation.op === 'pin'
74
+ ? { page: operation.page, placement: 'plugin', refusal: t('pinPluginOnly') }
75
+ : operation.op === 'open-tab' && !('host' in operation.tab)
76
+ ? { page: operation.tab, placement: 'session', refusal: t('openSessionOnly') }
77
+ : undefined;
78
+ if (wanted) {
79
+ const placement = registry.placementOf(wanted.page);
80
+ if (!placement) {
81
+ return res
82
+ .status(404)
83
+ .json({ error: t('pageMissing', { page: wanted.page.pageKey, instance: wanted.page.instance }) });
84
+ }
85
+ if (placement !== wanted.placement)
86
+ return res.status(400).json({ error: wanted.refusal });
87
+ }
88
+ try {
89
+ const { records, changed } = await layout.apply(operation);
90
+ if (changed)
91
+ deps.send({ type: 'layout.changed' });
92
+ res.json(records);
93
+ }
94
+ catch (err) {
95
+ if (err instanceof LayoutFull) {
96
+ res.status(409).json({ error: err.text });
97
+ return;
98
+ }
99
+ deps.logger.warn('保存布局记录失败:', err);
100
+ res.status(500).json({ error: t('layoutSaveFailed') });
101
+ }
102
+ });
103
+ }
104
+ //# sourceMappingURL=pages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages.js","sourceRoot":"","sources":["../../src/routes/pages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Readable, Writable } from 'node:stream';
2
+ import type { Logger } from '@aalis/core';
3
+ /**
4
+ * 把读流写进响应。读流出错(打开前文件被删、读到一半出错)或客户端中途断开时,pipeline 把两端都销毁、断开这次
5
+ * 响应,响应头可能已经发出,不再改回错误码。裸 pipe 不处理源流的错误,没有监听的 'error' 会让进程退出;客户端断开
6
+ * 时也不销毁源流,fd 不回收。中途断开是常事,只记读流出错;label 是日志里这次发送的说明
7
+ */
8
+ export declare function pipeToResponse(stream: Readable, res: Writable, logger: Logger, label: string): void;
9
+ //# sourceMappingURL=pipe-to-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipe-to-response.d.ts","sourceRoot":"","sources":["../../src/routes/pipe-to-response.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAInG"}
@@ -0,0 +1,16 @@
1
+ // ============================================================
2
+ // routes/pipe-to-response.ts — 把存储读流写进 HTTP 响应
3
+ // ============================================================
4
+ import { pipeline } from 'node:stream/promises';
5
+ /**
6
+ * 把读流写进响应。读流出错(打开前文件被删、读到一半出错)或客户端中途断开时,pipeline 把两端都销毁、断开这次
7
+ * 响应,响应头可能已经发出,不再改回错误码。裸 pipe 不处理源流的错误,没有监听的 'error' 会让进程退出;客户端断开
8
+ * 时也不销毁源流,fd 不回收。中途断开是常事,只记读流出错;label 是日志里这次发送的说明
9
+ */
10
+ export function pipeToResponse(stream, res, logger, label) {
11
+ pipeline(stream, res).catch((err) => {
12
+ if (err.code !== 'ERR_STREAM_PREMATURE_CLOSE')
13
+ logger.warn(`${label} 读取出错: ${err.message}`);
14
+ });
15
+ }
16
+ //# sourceMappingURL=pipe-to-response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipe-to-response.js","sourceRoot":"","sources":["../../src/routes/pipe-to-response.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+CAA+C;AAC/C,+DAA+D;AAG/D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGhD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAgB,EAAE,GAAa,EAAE,MAAc,EAAE,KAAa;IAC3F,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAA0B,EAAE,EAAE;QACzD,IAAI,GAAG,CAAC,IAAI,KAAK,4BAA4B;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1,51 +1,45 @@
1
- import type { UserIdentity } from '@aalis/api-authority';
2
1
  import type { CommandService } from '@aalis/api-commands';
3
2
  import { type HostConfig } from '@aalis/api-host-config';
4
3
  import type { PluginSourceService } from '@aalis/api-plugin-source';
5
4
  import type { ToolService } from '@aalis/api-tools';
6
- import type { WebUIService, WebuiActionHandler } from '@aalis/api-webui';
7
- import type { AppService, Logger, PluginManagerService, ServiceRef } from '@aalis/core';
5
+ import type { ErrorResponse } from '@aalis/api-webui';
6
+ import type { AppService, Logger, PluginManagerService, ServiceSelection, Services } from '@aalis/core';
7
+ import { type TextRef } from '@aalis/schema-i18n';
8
8
  import type express from 'express';
9
9
  import type { RouteGate } from '../gate.js';
10
- /**
11
- * 落盘被拒后运行态怎样与文件对齐:插件配置与新建的实例随配置文件热重载(文件里没有配置段的后缀实例会被卸载);
12
- * 启停与服务偏好只在重启时按文件登记
13
- */
14
- declare const RECONCILE: {
15
- readonly reload: "修好配置文件后会按文件内容重载";
16
- readonly restart: "修好配置文件后,重启时以文件内容为准";
17
- };
18
10
  /**
19
11
  * 管理动作改完运行态之后落盘;失败时回 `applied: true` 并返回 false:改动已在运行态生效、只是没写进文件,
20
12
  * 调用方别当成「没改成」去重试。宿主拒写(配置文件有尚未生效的外部修改)回 409,之后以文件为准对账;
21
13
  * 其它失败(权限、磁盘写满等)回 500,文件没变也不会触发重载,改动留在文档里,下一次成功保存时一并写入。
14
+ * `reconcile` 是落盘被拒后运行态怎样与文件对齐:插件配置、新建的实例与服务偏好随配置文件热重载(reload,文件里没有配置段的
15
+ * 后缀实例会被卸载);启停只在重启时按文件登记(restart)。被拒的可能是配置文件,也可能是密钥文件,拒写原因里点了名,
16
+ * 这里不指具体哪个文件。
22
17
  * `outcome` 是动作之后插件没有落在预期状态的说明(如激活失败转 error、仍在激活、保持禁用):落盘也失败时放在回执开头,
23
18
  * 两件事一并说明。
24
19
  */
25
- export declare function saveAfterApply(doc: Pick<HostConfig, 'save'>, res: express.Response, reconcile: keyof typeof RECONCILE, outcome?: string): Promise<boolean>;
20
+ export declare function saveAfterApply(doc: Pick<HostConfig, 'save'>, res: express.Response<ErrorResponse>, reconcile: 'reload' | 'restart', outcome?: TextRef): Promise<boolean>;
26
21
  /** 插件管理 + 全局配置路由用到的能力 */
27
22
  interface PluginRoutesCaps {
28
- app: ServiceRef<AppService>;
29
- plugins: ServiceRef<PluginManagerService>;
23
+ app: Pick<ServiceSelection<AppService>, 'present' | 'use'>;
24
+ plugins: Pick<ServiceSelection<PluginManagerService>, 'present' | 'use'>;
30
25
  /** 宿主的插件来源;打包宿主不提供,扫描路由随之报不可用 */
31
- source: Pick<ServiceRef<PluginSourceService>, 'current'>;
26
+ source: Pick<ServiceSelection<PluginSourceService>, 'present' | 'use'>;
32
27
  /** 配置文档的读写与落盘(宿主提供;缺席时读写文档的路由返回 503) */
33
- hostConfig: Pick<ServiceRef<HostConfig>, 'current'>;
34
- tools: Pick<ServiceRef<ToolService>, 'current'>;
35
- commands: Pick<ServiceRef<CommandService>, 'current'>;
36
- /**
37
- * 取当前 webui-server 提供者(页面登记表的读取面)。本插件自己提供这个服务,
38
- * 写死引用就绕过了解析——第三方若以更高优先级接管 webui-server,页面列表该跟着走。
39
- */
40
- webui(): WebUIService | undefined;
28
+ hostConfig: Pick<ServiceSelection<HostConfig>, 'present' | 'use'>;
29
+ tools: Pick<ServiceSelection<ToolService>, 'present' | 'use'>;
30
+ commands: Pick<ServiceSelection<CommandService>, 'present' | 'use'>;
31
+ /** 当前有提供者的服务名:列表与回执据它判缺与在等;列表另据它读各插件的本插件偏好与此刻的选择 */
32
+ services: Pick<Services, 'names' | 'preferred' | 'inspect'>;
33
+ /** 提供这个界面的插件实例:经这些路由停用不了它,列表给它标 self */
34
+ self: string;
35
+ /** 家目录(宿主路径的 home):宿主配置一并给出;宿主不提供路径时没有 */
36
+ home?: string;
37
+ /** 本地已装包的版本,每取一次列表现查一遍(装卸与更新会改它) */
38
+ versions(): (name: string) => string | undefined;
41
39
  /** 裁剪 schema 外字段时点名 warn,保存全局配置后重启失败时记 error;测试可不传 */
42
40
  logger?: Logger;
43
41
  }
44
42
  /** 注册插件管理 + 全局配置相关 REST 路由 */
45
- export declare function registerPluginRoutes(expressApp: express.Express, caps: PluginRoutesCaps, identify: (req: {
46
- headers: {
47
- cookie?: string;
48
- };
49
- }) => UserIdentity | undefined, gate: RouteGate, getAction: (plugin: string, method: string) => WebuiActionHandler | undefined): void;
43
+ export declare function registerPluginRoutes(expressApp: express.Express, caps: PluginRoutesCaps, gate: RouteGate): void;
50
44
  export {};
51
45
  //# sourceMappingURL=plugins.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/routes/plugins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,KAAK,UAAU,EAAuB,MAAM,wBAAwB,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAa,MAAM,kBAAkB,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,EAAe,UAAU,EAAE,MAAM,aAAa,CAAC;AAWrG,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAM5C;;;GAGG;AACH,QAAA,MAAM,SAAS;;;CAGL,CAAC;AAEX;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,EAC7B,GAAG,EAAE,OAAO,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,OAAO,SAAS,EACjC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAmBlB;AA8BD,yBAAyB;AACzB,UAAU,gBAAgB;IACxB,GAAG,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,OAAO,EAAE,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAC1C,iCAAiC;IACjC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,SAAS,CAAC,CAAC;IACzD,wCAAwC;IACxC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;IACpD,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,CAAC;IAChD,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC,CAAC;IACtD;;;OAGG;IACH,KAAK,IAAI,YAAY,GAAG,SAAS,CAAC;IAClC,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,8BAA8B;AAC9B,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,OAAO,CAAC,OAAO,EAC3B,IAAI,EAAE,gBAAgB,EACtB,QAAQ,EAAE,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,KAAK,YAAY,GAAG,SAAS,EAC7E,IAAI,EAAE,SAAS,EACf,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,GAC5E,IAAI,CA8nBN"}
1
+ {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/routes/plugins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EAEL,KAAK,UAAU,EAGhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EACV,UAAU,EACV,MAAM,EACN,oBAAoB,EAGpB,gBAAgB,EAChB,QAAQ,EACT,MAAM,aAAa,CAAC;AAerB,OAAO,EAAU,KAAK,OAAO,EAAuB,MAAM,oBAAoB,CAAC;AAC/E,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAuB5C;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,EAC7B,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EACpC,SAAS,EAAE,QAAQ,GAAG,SAAS,EAC/B,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,OAAO,CAAC,CAQlB;AAuED,yBAAyB;AACzB,UAAU,gBAAgB;IACxB,GAAG,EAAE,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;IAC3D,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;IACzE,iCAAiC;IACjC,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;IACvE,wCAAwC;IACxC,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;IAClE,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;IAC9D,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;IACpE,oDAAoD;IACpD,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC,CAAC;IAC5D,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACjD,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,8BAA8B;AAC9B,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAomB/G"}