@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.
Files changed (175) hide show
  1. package/README.md +8 -5
  2. package/dist/app/cli.d.ts +10 -0
  3. package/dist/app/cli.d.ts.map +1 -0
  4. package/dist/app/cli.js +37 -0
  5. package/dist/app/cli.js.map +1 -0
  6. package/dist/app/runtime.d.ts +121 -0
  7. package/dist/app/runtime.d.ts.map +1 -0
  8. package/dist/app/runtime.js +296 -0
  9. package/dist/app/runtime.js.map +1 -0
  10. package/dist/app.js +63 -273
  11. package/dist/app.js.map +1 -1
  12. package/dist/core/plugin/command-params.d.ts +3 -37
  13. package/dist/core/plugin/command-params.d.ts.map +1 -1
  14. package/dist/core/plugin/command-params.js +2 -580
  15. package/dist/core/plugin/command-params.js.map +1 -1
  16. package/dist/core/plugin/install/paths.d.ts +7 -0
  17. package/dist/core/plugin/install/paths.d.ts.map +1 -0
  18. package/dist/core/plugin/install/paths.js +49 -0
  19. package/dist/core/plugin/install/paths.js.map +1 -0
  20. package/dist/core/plugin/install/state.d.ts +23 -0
  21. package/dist/core/plugin/install/state.d.ts.map +1 -0
  22. package/dist/core/plugin/install/state.js +129 -0
  23. package/dist/core/plugin/install/state.js.map +1 -0
  24. package/dist/core/plugin/install/validate-script.d.ts +3 -0
  25. package/dist/core/plugin/install/validate-script.d.ts.map +1 -0
  26. package/dist/core/plugin/install/validate-script.js +154 -0
  27. package/dist/core/plugin/install/validate-script.js.map +1 -0
  28. package/dist/core/plugin/install-dir.d.ts +3 -28
  29. package/dist/core/plugin/install-dir.d.ts.map +1 -1
  30. package/dist/core/plugin/install-dir.js +3 -326
  31. package/dist/core/plugin/install-dir.js.map +1 -1
  32. package/dist/core/plugin/installer/checks.d.ts +6 -0
  33. package/dist/core/plugin/installer/checks.d.ts.map +1 -0
  34. package/dist/core/plugin/installer/checks.js +99 -0
  35. package/dist/core/plugin/installer/checks.js.map +1 -0
  36. package/dist/core/plugin/installer/support.d.ts +37 -0
  37. package/dist/core/plugin/installer/support.d.ts.map +1 -0
  38. package/dist/core/plugin/installer/support.js +67 -0
  39. package/dist/core/plugin/installer/support.js.map +1 -0
  40. package/dist/core/plugin/installer/warnings.d.ts +5 -0
  41. package/dist/core/plugin/installer/warnings.d.ts.map +1 -0
  42. package/dist/core/plugin/installer/warnings.js +28 -0
  43. package/dist/core/plugin/installer/warnings.js.map +1 -0
  44. package/dist/core/plugin/installer.d.ts +4 -30
  45. package/dist/core/plugin/installer.d.ts.map +1 -1
  46. package/dist/core/plugin/installer.js +21 -202
  47. package/dist/core/plugin/installer.js.map +1 -1
  48. package/dist/core/plugin/params/compile.d.ts +3 -0
  49. package/dist/core/plugin/params/compile.d.ts.map +1 -0
  50. package/dist/core/plugin/params/compile.js +23 -0
  51. package/dist/core/plugin/params/compile.js.map +1 -0
  52. package/dist/core/plugin/params/declaration.d.ts +9 -0
  53. package/dist/core/plugin/params/declaration.d.ts.map +1 -0
  54. package/dist/core/plugin/params/declaration.js +286 -0
  55. package/dist/core/plugin/params/declaration.js.map +1 -0
  56. package/dist/core/plugin/params/input.d.ts +5 -0
  57. package/dist/core/plugin/params/input.d.ts.map +1 -0
  58. package/dist/core/plugin/params/input.js +196 -0
  59. package/dist/core/plugin/params/input.js.map +1 -0
  60. package/dist/core/plugin/params/reply.d.ts +3 -0
  61. package/dist/core/plugin/params/reply.d.ts.map +1 -0
  62. package/dist/core/plugin/params/reply.js +49 -0
  63. package/dist/core/plugin/params/reply.js.map +1 -0
  64. package/dist/core/plugin/params/type-level.d.ts +24 -0
  65. package/dist/core/plugin/params/type-level.d.ts.map +1 -0
  66. package/dist/core/plugin/params/type-level.js +2 -0
  67. package/dist/core/plugin/params/type-level.js.map +1 -0
  68. package/dist/core/plugin/params/types.d.ts +33 -0
  69. package/dist/core/plugin/params/types.d.ts.map +1 -0
  70. package/dist/core/plugin/params/types.js +12 -0
  71. package/dist/core/plugin/params/types.js.map +1 -0
  72. package/dist/core/plugin/params/values.d.ts +7 -0
  73. package/dist/core/plugin/params/values.d.ts.map +1 -0
  74. package/dist/core/plugin/params/values.js +111 -0
  75. package/dist/core/plugin/params/values.js.map +1 -0
  76. package/dist/core/web/api.d.ts +2 -14
  77. package/dist/core/web/api.d.ts.map +1 -1
  78. package/dist/core/web/api.js +8 -500
  79. package/dist/core/web/api.js.map +1 -1
  80. package/dist/core/web/routes/actions.d.ts +4 -0
  81. package/dist/core/web/routes/actions.d.ts.map +1 -0
  82. package/dist/core/web/routes/actions.js +33 -0
  83. package/dist/core/web/routes/actions.js.map +1 -0
  84. package/dist/core/web/routes/config.d.ts +5 -0
  85. package/dist/core/web/routes/config.d.ts.map +1 -0
  86. package/dist/core/web/routes/config.js +30 -0
  87. package/dist/core/web/routes/config.js.map +1 -0
  88. package/dist/core/web/routes/kv.d.ts +6 -0
  89. package/dist/core/web/routes/kv.d.ts.map +1 -0
  90. package/dist/core/web/routes/kv.js +80 -0
  91. package/dist/core/web/routes/kv.js.map +1 -0
  92. package/dist/core/web/routes/plugins.d.ts +5 -0
  93. package/dist/core/web/routes/plugins.d.ts.map +1 -0
  94. package/dist/core/web/routes/plugins.js +98 -0
  95. package/dist/core/web/routes/plugins.js.map +1 -0
  96. package/dist/core/web/routes/sessions.d.ts +8 -0
  97. package/dist/core/web/routes/sessions.d.ts.map +1 -0
  98. package/dist/core/web/routes/sessions.js +130 -0
  99. package/dist/core/web/routes/sessions.js.map +1 -0
  100. package/dist/core/web/routes/shared.d.ts +18 -0
  101. package/dist/core/web/routes/shared.d.ts.map +1 -0
  102. package/dist/core/web/routes/shared.js +19 -0
  103. package/dist/core/web/routes/shared.js.map +1 -0
  104. package/dist/core/web/routes/status.d.ts +6 -0
  105. package/dist/core/web/routes/status.d.ts.map +1 -0
  106. package/dist/core/web/routes/status.js +132 -0
  107. package/dist/core/web/routes/status.js.map +1 -0
  108. package/dist/core/web/server/auth.d.ts +17 -0
  109. package/dist/core/web/server/auth.d.ts.map +1 -0
  110. package/dist/core/web/server/auth.js +68 -0
  111. package/dist/core/web/server/auth.js.map +1 -0
  112. package/dist/core/web/server/csp.d.ts +11 -0
  113. package/dist/core/web/server/csp.d.ts.map +1 -0
  114. package/dist/core/web/server/csp.js +31 -0
  115. package/dist/core/web/server/csp.js.map +1 -0
  116. package/dist/core/web/server/request.d.ts +6 -0
  117. package/dist/core/web/server/request.d.ts.map +1 -0
  118. package/dist/core/web/server/request.js +33 -0
  119. package/dist/core/web/server/request.js.map +1 -0
  120. package/dist/core/web/server/security.d.ts +4 -0
  121. package/dist/core/web/server/security.d.ts.map +1 -0
  122. package/dist/core/web/server/security.js +12 -0
  123. package/dist/core/web/server/security.js.map +1 -0
  124. package/dist/core/web/server/sse.d.ts +18 -0
  125. package/dist/core/web/server/sse.d.ts.map +1 -0
  126. package/dist/core/web/server/sse.js +49 -0
  127. package/dist/core/web/server/sse.js.map +1 -0
  128. package/dist/core/web/server/static.d.ts +16 -0
  129. package/dist/core/web/server/static.d.ts.map +1 -0
  130. package/dist/core/web/server/static.js +80 -0
  131. package/dist/core/web/server/static.js.map +1 -0
  132. package/dist/core/web/server.d.ts +0 -7
  133. package/dist/core/web/server.d.ts.map +1 -1
  134. package/dist/core/web/server.js +41 -263
  135. package/dist/core/web/server.js.map +1 -1
  136. package/docs/architecture.md +28 -11
  137. package/docs/configuration.md +1 -1
  138. package/docs/migration.md +2 -2
  139. package/docs/plugin-api.md +24 -11
  140. package/docs/plugin-development.md +1 -1
  141. package/package.json +19 -17
  142. package/src/app/cli.ts +47 -0
  143. package/src/app/runtime.ts +522 -0
  144. package/src/app.ts +87 -395
  145. package/src/core/plugin/command-params.ts +8 -871
  146. package/src/core/plugin/install/paths.ts +72 -0
  147. package/src/core/plugin/install/state.ts +196 -0
  148. package/src/core/plugin/install/validate-script.ts +154 -0
  149. package/src/core/plugin/install-dir.ts +19 -427
  150. package/src/core/plugin/installer/checks.ts +137 -0
  151. package/src/core/plugin/installer/support.ts +120 -0
  152. package/src/core/plugin/installer/warnings.ts +52 -0
  153. package/src/core/plugin/installer.ts +52 -301
  154. package/src/core/plugin/params/compile.ts +41 -0
  155. package/src/core/plugin/params/declaration.ts +394 -0
  156. package/src/core/plugin/params/input.ts +281 -0
  157. package/src/core/plugin/params/reply.ts +59 -0
  158. package/src/core/plugin/params/type-level.ts +75 -0
  159. package/src/core/plugin/params/types.ts +55 -0
  160. package/src/core/plugin/params/values.ts +150 -0
  161. package/src/core/web/api.ts +33 -759
  162. package/src/core/web/routes/actions.ts +43 -0
  163. package/src/core/web/routes/config.ts +42 -0
  164. package/src/core/web/routes/kv.ts +122 -0
  165. package/src/core/web/routes/plugins.ts +151 -0
  166. package/src/core/web/routes/sessions.ts +188 -0
  167. package/src/core/web/routes/shared.ts +42 -0
  168. package/src/core/web/routes/status.ts +191 -0
  169. package/src/core/web/server/auth.ts +126 -0
  170. package/src/core/web/server/csp.ts +33 -0
  171. package/src/core/web/server/request.ts +38 -0
  172. package/src/core/web/server/security.ts +14 -0
  173. package/src/core/web/server/sse.ts +74 -0
  174. package/src/core/web/server/static.ts +112 -0
  175. package/src/core/web/server.ts +41 -383
@@ -0,0 +1,68 @@
1
+ import { AuthManager } from '../auth.js';
2
+ import { clearCookie, clientIp, parseCookies, readJsonBody, sendData, sendError, serializeCookie, } from '../http.js';
3
+ import { HttpError } from '../http.js';
4
+ export const SESSION_COOKIE = 'jsbot_webui';
5
+ export function authenticate(auth, req) {
6
+ const cookies = parseCookies(req.headers.cookie);
7
+ return auth.authenticate(cookies[SESSION_COOKIE]);
8
+ }
9
+ export function tokenOf(req) {
10
+ const cookies = parseCookies(req.headers.cookie);
11
+ return cookies[SESSION_COOKIE];
12
+ }
13
+ export function isSecure(deps, req) {
14
+ if (!deps.getWebUiConfig().trustProxy)
15
+ return false;
16
+ const proto = req.headers['x-forwarded-proto'];
17
+ return typeof proto === 'string' && proto.split(',')[0]?.trim() === 'https';
18
+ }
19
+ export async function handleAuth(options) {
20
+ const { req, res, action, auth, deps, bodyLimit } = options;
21
+ const method = req.method ?? 'GET';
22
+ if (action === 'login' && method === 'POST') {
23
+ const body = await readJsonBody(req, bodyLimit);
24
+ const value = typeof body === 'object' && body !== null
25
+ ? body
26
+ : {};
27
+ const ip = clientIp(req, deps.getWebUiConfig().trustProxy);
28
+ const result = await auth.login(value['username'], value['password'], ip);
29
+ if (!result.ok || !result.session) {
30
+ const headers = {};
31
+ if (result.retryAfterSeconds !== undefined) {
32
+ headers['retry-after'] = String(result.retryAfterSeconds);
33
+ }
34
+ sendError(res, result.status, result.message ?? 'login failed', undefined, headers);
35
+ return;
36
+ }
37
+ res.setHeader('set-cookie', serializeCookie(SESSION_COOKIE, result.session.token, {
38
+ maxAgeSeconds: deps.getWebUiConfig().sessionTtlHours * 3600,
39
+ secure: isSecure(deps, req),
40
+ }));
41
+ sendData(res, result.status, {
42
+ username: result.session.username,
43
+ expiresAt: result.session.expiresAt,
44
+ });
45
+ return;
46
+ }
47
+ if (action === 'logout' && method === 'POST') {
48
+ const session = authenticate(auth, req);
49
+ auth.logout(tokenOf(req));
50
+ deps.logger.info(`webui logout: ${session?.username ?? 'unknown'}`);
51
+ res.setHeader('set-cookie', clearCookie(SESSION_COOKIE));
52
+ sendData(res, 200, { ok: true });
53
+ return;
54
+ }
55
+ if (action === 'me' && method === 'GET') {
56
+ const session = authenticate(auth, req);
57
+ if (session === null) {
58
+ throw new HttpError(401, '未登录或会话已过期');
59
+ }
60
+ sendData(res, 200, {
61
+ username: session.username,
62
+ expiresAt: session.expiresAt,
63
+ });
64
+ return;
65
+ }
66
+ throw new HttpError(404, `not found: ${method} /api/auth/${action ?? ''}`);
67
+ }
68
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../../src/core/web/server/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * CSP for the WebUI. webui/index.html ships a single authorized inline
3
+ * script (the no-flash appearance bootstrap for the first paint); its exact
4
+ * hash is derived from the built index.html on disk so editing the bootstrap
5
+ * only needs a rebuild, never a source edit. Every other inline script
6
+ * stays blocked.
7
+ */
8
+ export declare function buildCsp(scriptSrc: string): string;
9
+ /** Extracts the bootstrap script's sha256 from a built index.html. */
10
+ export declare function cspForStaticDir(staticDir: string): string | null;
11
+ //# sourceMappingURL=csp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csp.d.ts","sourceRoot":"","sources":["../../../../src/core/web/server/csp.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBhE"}
@@ -0,0 +1,31 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ /**
5
+ * CSP for the WebUI. webui/index.html ships a single authorized inline
6
+ * script (the no-flash appearance bootstrap for the first paint); its exact
7
+ * hash is derived from the built index.html on disk so editing the bootstrap
8
+ * only needs a rebuild, never a source edit. Every other inline script
9
+ * stays blocked.
10
+ */
11
+ export function buildCsp(scriptSrc) {
12
+ return `default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src ${scriptSrc}; connect-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'`;
13
+ }
14
+ /** Extracts the bootstrap script's sha256 from a built index.html. */
15
+ export function cspForStaticDir(staticDir) {
16
+ try {
17
+ const html = readFileSync(join(staticDir, 'index.html'), 'utf8');
18
+ const match = /<script>([\s\S]*?)<\/script>/.exec(html);
19
+ const bootstrap = match?.[1];
20
+ if (bootstrap === undefined)
21
+ return null;
22
+ const hash = createHash('sha256')
23
+ .update(bootstrap, 'utf8')
24
+ .digest('base64');
25
+ return buildCsp(`'self' 'sha256-${hash}'`);
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ //# sourceMappingURL=csp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csp.js","sourceRoot":"","sources":["../../../../src/core/web/server/csp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,SAAiB;IACtC,OAAO,0FAA0F,SAAS,mFAAmF,CAAA;AACjM,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC7C,IAAI,CAAC;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAA;QAChE,MAAM,KAAK,GAAG,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACvD,MAAM,SAAS,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;QAE5B,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAExC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC;aAC5B,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC;aACzB,MAAM,CAAC,QAAQ,CAAC,CAAA;QAErB,OAAO,QAAQ,CAAC,kBAAkB,IAAI,GAAG,CAAC,CAAA;IAC9C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAA;IACf,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { IncomingMessage } from 'node:http';
2
+ import type { URLSearchParamsLike } from '../http.js';
3
+ export declare function parseSearch(req: IncomingMessage): URLSearchParamsLike;
4
+ export declare function segmentsOf(pathname: string): string[];
5
+ export declare function pathnameOf(req: IncomingMessage): string;
6
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../../src/core/web/server/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAErD,wBAAgB,WAAW,CAAC,GAAG,EAAE,eAAe,GAAG,mBAAmB,CAKrE;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAWrD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAcvD"}
@@ -0,0 +1,33 @@
1
+ export function parseSearch(req) {
2
+ const index = (req.url ?? '').indexOf('?');
3
+ const query = index >= 0 ? (req.url ?? '').slice(index + 1) : '';
4
+ return new URLSearchParams(query);
5
+ }
6
+ export function segmentsOf(pathname) {
7
+ return pathname
8
+ .split('/')
9
+ .filter((segment) => segment.length > 0)
10
+ .map((segment) => {
11
+ try {
12
+ return decodeURIComponent(segment);
13
+ }
14
+ catch {
15
+ return segment;
16
+ }
17
+ });
18
+ }
19
+ export function pathnameOf(req) {
20
+ const url = req.url ?? '/';
21
+ const index = url.indexOf('?');
22
+ const raw = index >= 0 ? url.slice(0, index) : url;
23
+ if (raw.includes('%')) {
24
+ try {
25
+ return decodeURIComponent(raw);
26
+ }
27
+ catch {
28
+ return raw;
29
+ }
30
+ }
31
+ return raw;
32
+ }
33
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../../../src/core/web/server/request.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,WAAW,CAAC,GAAoB;IAC5C,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC1C,MAAM,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAEhE,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,CAAA;AACrC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACvC,OAAO,QAAQ;SACV,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;SACvC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACb,IAAI,CAAC;YACD,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAA;QACtC,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,OAAO,CAAA;QAClB,CAAC;IACL,CAAC,CAAC,CAAA;AACV,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAoB;IAC3C,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAA;IAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC9B,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IAElD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC;YACD,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAA;QAClC,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,GAAG,CAAA;QACd,CAAC;IACL,CAAC;IAED,OAAO,GAAG,CAAA;AACd,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ServerResponse } from 'node:http';
2
+ export declare const SECURITY_HEADERS: Record<string, string>;
3
+ export declare function applySecurityHeaders(res: ServerResponse): void;
4
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../../src/core/web/server/security.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE/C,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKnD,CAAA;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAI9D"}
@@ -0,0 +1,12 @@
1
+ export const SECURITY_HEADERS = {
2
+ 'x-content-type-options': 'nosniff',
3
+ 'x-frame-options': 'DENY',
4
+ 'referrer-policy': 'no-referrer',
5
+ 'cross-origin-opener-policy': 'same-origin',
6
+ };
7
+ export function applySecurityHeaders(res) {
8
+ for (const [key, value] of Object.entries(SECURITY_HEADERS)) {
9
+ res.setHeader(key, value);
10
+ }
11
+ }
12
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../../../src/core/web/server/security.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACpD,wBAAwB,EAAE,SAAS;IACnC,iBAAiB,EAAE,MAAM;IACzB,iBAAiB,EAAE,aAAa;IAChC,4BAA4B,EAAE,aAAa;CAC9C,CAAA;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAmB;IACpD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC1D,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC7B,CAAC;AACL,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ export declare const SSE_HEARTBEAT_MS = 15000;
3
+ export declare const DEFAULT_MAX_SSE_CLIENTS = 20;
4
+ export declare const SSE_TIMEOUT_MS = 60000;
5
+ export interface SseConnection {
6
+ res: ServerResponse;
7
+ close(): void;
8
+ }
9
+ export interface OpenSseOptions {
10
+ req: IncomingMessage;
11
+ res: ServerResponse;
12
+ subscribe: (listener: (entry: unknown) => void) => () => void;
13
+ openedAt: number;
14
+ maxClients: number;
15
+ connections: Set<SseConnection>;
16
+ }
17
+ export declare function openSse(options: OpenSseOptions): void;
18
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../../src/core/web/server/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAGhE,eAAO,MAAM,gBAAgB,QAAS,CAAA;AACtC,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC,eAAO,MAAM,cAAc,QAAS,CAAA;AAEpC,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,cAAc,CAAA;IACnB,KAAK,IAAI,IAAI,CAAA;CAChB;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,EAAE,eAAe,CAAA;IACpB,GAAG,EAAE,cAAc,CAAA;IACnB,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;IAC7D,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC,CAAA;CAClC;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAoDrD"}
@@ -0,0 +1,49 @@
1
+ import { HttpError, safeStringify } from '../http.js';
2
+ export const SSE_HEARTBEAT_MS = 15_000;
3
+ export const DEFAULT_MAX_SSE_CLIENTS = 20;
4
+ export const SSE_TIMEOUT_MS = 60_000;
5
+ export function openSse(options) {
6
+ const { req, res, subscribe, openedAt, maxClients, connections } = options;
7
+ if (connections.size >= maxClients) {
8
+ throw new HttpError(503, '实时连接数量已达上限');
9
+ }
10
+ res.writeHead(200, {
11
+ 'content-type': 'text/event-stream; charset=utf-8',
12
+ 'cache-control': 'no-store, no-transform',
13
+ connection: 'keep-alive',
14
+ });
15
+ res.write(':ok\n\n');
16
+ const connection = {
17
+ res,
18
+ close: () => {
19
+ unsubscribe();
20
+ clearInterval(heartbeat);
21
+ connections.delete(connection);
22
+ try {
23
+ res.end();
24
+ }
25
+ catch {
26
+ // Already closed.
27
+ }
28
+ },
29
+ };
30
+ let closing = false;
31
+ const unsubscribe = subscribe((entry) => {
32
+ if (closing)
33
+ return;
34
+ res.write(`data: ${safeStringify(entry)}\n\n`);
35
+ });
36
+ const heartbeat = setInterval(() => {
37
+ res.write(`:keepalive ${Date.now() - openedAt}\n\n`);
38
+ }, SSE_HEARTBEAT_MS);
39
+ req.on('close', () => {
40
+ if (closing)
41
+ return;
42
+ closing = true;
43
+ unsubscribe();
44
+ clearInterval(heartbeat);
45
+ connections.delete(connection);
46
+ });
47
+ connections.add(connection);
48
+ }
49
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../../../src/core/web/server/sse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAErD,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAA;AACtC,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAA;AACzC,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAA;AAgBpC,MAAM,UAAU,OAAO,CAAC,OAAuB;IAC3C,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,OAAO,CAAA;IAE1E,IAAI,WAAW,CAAC,IAAI,IAAI,UAAU,EAAE,CAAC;QACjC,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;IAC1C,CAAC;IAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;QACf,cAAc,EAAE,kCAAkC;QAClD,eAAe,EAAE,wBAAwB;QACzC,UAAU,EAAE,YAAY;KAC3B,CAAC,CAAA;IACF,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IAEpB,MAAM,UAAU,GAAkB;QAC9B,GAAG;QACH,KAAK,EAAE,GAAG,EAAE;YACR,WAAW,EAAE,CAAA;YACb,aAAa,CAAC,SAAS,CAAC,CAAA;YACxB,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;YAE9B,IAAI,CAAC;gBACD,GAAG,CAAC,GAAG,EAAE,CAAA;YACb,CAAC;YAAC,MAAM,CAAC;gBACL,kBAAkB;YACtB,CAAC;QACL,CAAC;KACJ,CAAA;IAED,IAAI,OAAO,GAAG,KAAK,CAAA;IAEnB,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QACpC,IAAI,OAAO;YAAE,OAAM;QAEnB,GAAG,CAAC,KAAK,CAAC,SAAS,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QAC/B,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,MAAM,CAAC,CAAA;IACxD,CAAC,EAAE,gBAAgB,CAAC,CAAA;IAEpB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACjB,IAAI,OAAO;YAAE,OAAM;QAEnB,OAAO,GAAG,IAAI,CAAA;QAEd,WAAW,EAAE,CAAA;QACb,aAAa,CAAC,SAAS,CAAC,CAAA;QACxB,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAClC,CAAC,CAAC,CAAA;IAEF,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;AAC/B,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { stat } from 'node:fs/promises';
2
+ import type { IncomingMessage, ServerResponse } from 'node:http';
3
+ export interface FallbackPageOptions {
4
+ listening: string;
5
+ }
6
+ export declare const FALLBACK_BODY: (options: FallbackPageOptions) => string;
7
+ export interface ServeStaticOptions {
8
+ req: IncomingMessage;
9
+ res: ServerResponse;
10
+ pathname: string;
11
+ staticDir: string | null;
12
+ fallbackBody: string;
13
+ }
14
+ export declare function serveStatic(options: ServeStaticOptions): Promise<void>;
15
+ export declare function statOrNull(filePath: string): Promise<Awaited<ReturnType<typeof stat>> | null>;
16
+ //# sourceMappingURL=static.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../../../src/core/web/server/static.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAIhE,MAAM,WAAW,mBAAmB;IAChC,SAAS,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,aAAa,YACb,mBAAmB,KAC7B,MAWF,CAAA;AAED,MAAM,WAAW,kBAAkB;IAC/B,GAAG,EAAE,eAAe,CAAA;IACpB,GAAG,EAAE,cAAc,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;CACvB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoE5E;AAED,wBAAsB,UAAU,CAC5B,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAMlD"}
@@ -0,0 +1,80 @@
1
+ import { createReadStream } from 'node:fs';
2
+ import { stat } from 'node:fs/promises';
3
+ import { extname, join, resolve, sep } from 'node:path';
4
+ import { HttpError, isImmutableAsset, mimeType, withTimeout } from '../http.js';
5
+ export const FALLBACK_BODY = (options) => `<!doctype html>
6
+ <html lang="zh-CN"><head><meta charset="utf-8">
7
+ <title>JsBot WebUI</title>
8
+ <style>body{font-family:system-ui,sans-serif;max-width:36em;margin:4rem auto;padding:0 1rem;color:#333}</style>
9
+ </head><body>
10
+ <h1>WebUI 前端未构建</h1>
11
+ <p>管理 API 正常运行,但静态资源缺失。请在项目根目录执行:</p>
12
+ <pre><code>npm run build:webui</code></pre>
13
+ <p>然后重启进程,访问 <code>${options.listening}</code>。</p>
14
+ <p>API 仍可通过 <code>/api/health</code>、登录和各接口访问。</p>
15
+ </body></html>
16
+ `;
17
+ export async function serveStatic(options) {
18
+ const { req, res, pathname, staticDir, fallbackBody } = options;
19
+ if (req.method !== 'GET' && req.method !== 'HEAD') {
20
+ throw new HttpError(405, `method not allowed: ${req.method}`);
21
+ }
22
+ if (staticDir === null) {
23
+ res.setHeader('content-type', 'text/html; charset=utf-8');
24
+ res.setHeader('cache-control', 'no-store');
25
+ res.writeHead(503);
26
+ res.end(fallbackBody);
27
+ return;
28
+ }
29
+ const cleaned = pathname.replace(/\/+$/, '') || '/';
30
+ let filePath = cleaned === '/'
31
+ ? join(staticDir, 'index.html')
32
+ : resolve(staticDir, `.${cleaned}`);
33
+ if (!filePath.startsWith(staticDir + sep) && filePath !== staticDir) {
34
+ throw new HttpError(403, 'forbidden');
35
+ }
36
+ let fileStat = await statOrNull(filePath);
37
+ if (fileStat?.isDirectory()) {
38
+ filePath = join(filePath, 'index.html');
39
+ fileStat = await statOrNull(filePath);
40
+ }
41
+ if (fileStat === null) {
42
+ // SPA fallback: only routes without a file extension.
43
+ if (extname(cleaned) === '') {
44
+ filePath = join(staticDir, 'index.html');
45
+ fileStat = await statOrNull(filePath);
46
+ }
47
+ if (fileStat === null)
48
+ throw new HttpError(404, 'not found');
49
+ }
50
+ const cacheControl = isImmutableAsset(cleaned)
51
+ ? 'public, max-age=31536000, immutable'
52
+ : 'no-cache';
53
+ res.setHeader('content-type', mimeType(filePath));
54
+ res.setHeader('cache-control', cacheControl);
55
+ res.setHeader('content-length', String(fileStat.size));
56
+ res.writeHead(200);
57
+ if (req.method === 'HEAD') {
58
+ res.end();
59
+ return;
60
+ }
61
+ const stream = createReadStream(filePath);
62
+ stream.on('error', () => {
63
+ try {
64
+ res.end();
65
+ }
66
+ catch {
67
+ // Already closed.
68
+ }
69
+ });
70
+ stream.pipe(res);
71
+ }
72
+ export async function statOrNull(filePath) {
73
+ try {
74
+ return await withTimeout(stat(filePath), 1_000);
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ }
80
+ //# sourceMappingURL=static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.js","sourceRoot":"","sources":["../../../../src/core/web/server/static.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAEvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAM/E,MAAM,CAAC,MAAM,aAAa,GAAG,CACzB,OAA4B,EACtB,EAAE,CAAC;;;;;;;;qBAQQ,OAAO,CAAC,SAAS;;;CAGrC,CAAA;AAUD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B;IACzD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAA;IAE/D,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAChD,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,uBAAuB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;IACjE,CAAC;IAED,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACrB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAA;QACzD,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;QAC1C,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAClB,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAErB,OAAM;IACV,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAA;IACnD,IAAI,QAAQ,GACR,OAAO,KAAK,GAAG;QACX,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;QAC/B,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,OAAO,EAAE,CAAC,CAAA;IAE3C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,GAAG,GAAG,CAAC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClE,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;IACzC,CAAC;IAED,IAAI,QAAQ,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAA;IAEzC,IAAI,QAAQ,EAAE,WAAW,EAAE,EAAE,CAAC;QAC1B,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QACvC,QAAQ,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAA;IACzC,CAAC;IAED,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACpB,sDAAsD;QACtD,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YAC1B,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;YACxC,QAAQ,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAA;QACzC,CAAC;QAED,IAAI,QAAQ,KAAK,IAAI;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;IAChE,CAAC;IAED,MAAM,YAAY,GAAG,gBAAgB,CAAC,OAAO,CAAC;QAC1C,CAAC,CAAC,qCAAqC;QACvC,CAAC,CAAC,UAAU,CAAA;IAEhB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAA;IACjD,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,YAAY,CAAC,CAAA;IAC5C,GAAG,CAAC,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;IACtD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAElB,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACxB,GAAG,CAAC,GAAG,EAAE,CAAA;QAET,OAAM;IACV,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAA;IAEzC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACpB,IAAI,CAAC;YACD,GAAG,CAAC,GAAG,EAAE,CAAA;QACb,CAAC;QAAC,MAAM,CAAC;YACL,kBAAkB;QACtB,CAAC;IACL,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC5B,QAAgB;IAEhB,IAAI,CAAC;QACD,OAAO,MAAM,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAA;IACnD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAA;IACf,CAAC;AACL,CAAC"}
@@ -19,12 +19,5 @@ export declare class WebUiServer {
19
19
  invalidateSessions(): void;
20
20
  private applySecurityHeaders;
21
21
  private handleRequest;
22
- private authenticate;
23
- private handleAuth;
24
- private tokenOf;
25
- private isSecure;
26
- private openSse;
27
- private serveStatic;
28
- private statOrNull;
29
22
  }
30
23
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/core/web/server.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,YAAY,EAAa,kBAAkB,EAAE,MAAM,YAAY,CAAA;AA6H7E,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoB;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA2B;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IAErC,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,QAAQ,CAAsB;IAEtC,YAAY,OAAO,EAAE,kBAAkB,EAoBtC;IAED,IAAI,OAAO,IAAI,YAAY,GAAG,IAAI,CAEjC;IAEK,KAAK,CACP,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GACrC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA0C9B;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAgB1B;IAED,kBAAkB,IAAI,IAAI,CAEzB;IAED,OAAO,CAAC,oBAAoB;YAkBd,aAAa;IAoF3B,OAAO,CAAC,YAAY;YAMN,UAAU;IAwFxB,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,OAAO;YAyDD,WAAW;YA0EX,UAAU;CAS3B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/core/web/server.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,YAAY,EAAa,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAwB7E,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoB;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA2B;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IAErC,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,QAAQ,CAAsB;IAEtC,YAAY,OAAO,EAAE,kBAAkB,EAoBtC;IAED,IAAI,OAAO,IAAI,YAAY,GAAG,IAAI,CAEjC;IAEK,KAAK,CACP,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GACrC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA0C9B;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAgB1B;IAED,kBAAkB,IAAI,IAAI,CAEzB;IAED,OAAO,CAAC,oBAAoB;YAgBd,aAAa;CAqG9B"}