@openclaw/crabline 0.1.11 → 0.1.13

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 (214) hide show
  1. package/README.md +137 -23
  2. package/dist/src/bin/crabline.js +3 -1
  3. package/dist/src/bin/crabline.js.map +1 -1
  4. package/dist/src/cli/program.d.ts +5 -1
  5. package/dist/src/cli/program.js +281 -52
  6. package/dist/src/cli/program.js.map +1 -1
  7. package/dist/src/config/load.js +39 -3
  8. package/dist/src/config/load.js.map +1 -1
  9. package/dist/src/config/schema.d.ts +20 -0
  10. package/dist/src/config/schema.js +163 -35
  11. package/dist/src/config/schema.js.map +1 -1
  12. package/dist/src/core/errors.d.ts +1 -0
  13. package/dist/src/core/errors.js +6 -3
  14. package/dist/src/core/errors.js.map +1 -1
  15. package/dist/src/core/http-path.d.ts +1 -0
  16. package/dist/src/core/http-path.js +14 -0
  17. package/dist/src/core/http-path.js.map +1 -0
  18. package/dist/src/core/matcher.d.ts +3 -1
  19. package/dist/src/core/matcher.js +58 -2
  20. package/dist/src/core/matcher.js.map +1 -1
  21. package/dist/src/core/nonces.d.ts +2 -0
  22. package/dist/src/core/nonces.js +11 -1
  23. package/dist/src/core/nonces.js.map +1 -1
  24. package/dist/src/core/reporters.d.ts +5 -0
  25. package/dist/src/core/reporters.js +26 -2
  26. package/dist/src/core/reporters.js.map +1 -1
  27. package/dist/src/core/run.d.ts +3 -1
  28. package/dist/src/core/run.js +178 -66
  29. package/dist/src/core/run.js.map +1 -1
  30. package/dist/src/index.d.ts +12 -10
  31. package/dist/src/index.js +6 -5
  32. package/dist/src/index.js.map +1 -1
  33. package/dist/src/matrix-ids.d.ts +5 -0
  34. package/dist/src/matrix-ids.js +83 -0
  35. package/dist/src/matrix-ids.js.map +1 -0
  36. package/dist/src/openclaw/artifact-generation.d.ts +7 -6
  37. package/dist/src/openclaw/artifact-generation.js +385 -41
  38. package/dist/src/openclaw/artifact-generation.js.map +1 -1
  39. package/dist/src/openclaw/bridges/discord.d.ts +1 -0
  40. package/dist/src/openclaw/bridges/discord.js +149 -0
  41. package/dist/src/openclaw/bridges/discord.js.map +1 -0
  42. package/dist/src/openclaw/bridges/matrix.js +22 -5
  43. package/dist/src/openclaw/bridges/matrix.js.map +1 -1
  44. package/dist/src/openclaw/bridges/mattermost.js +14 -9
  45. package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
  46. package/dist/src/openclaw/bridges/probe-response.d.ts +1 -0
  47. package/dist/src/openclaw/bridges/probe-response.js +5 -0
  48. package/dist/src/openclaw/bridges/probe-response.js.map +1 -0
  49. package/dist/src/openclaw/bridges/signal.js +16 -7
  50. package/dist/src/openclaw/bridges/signal.js.map +1 -1
  51. package/dist/src/openclaw/bridges/slack.js +117 -24
  52. package/dist/src/openclaw/bridges/slack.js.map +1 -1
  53. package/dist/src/openclaw/bridges/telegram.js +46 -20
  54. package/dist/src/openclaw/bridges/telegram.js.map +1 -1
  55. package/dist/src/openclaw/bridges/whatsapp.js +33 -17
  56. package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
  57. package/dist/src/openclaw/bridges/zalo.js +9 -4
  58. package/dist/src/openclaw/bridges/zalo.js.map +1 -1
  59. package/dist/src/openclaw/outbound-contract.js +3 -0
  60. package/dist/src/openclaw/outbound-contract.js.map +1 -1
  61. package/dist/src/openclaw/private-file.d.ts +38 -3
  62. package/dist/src/openclaw/private-file.js +2008 -87
  63. package/dist/src/openclaw/private-file.js.map +1 -1
  64. package/dist/src/openclaw/{smoke-lock.d.ts → provider-readiness-lock.d.ts} +14 -5
  65. package/dist/src/openclaw/provider-readiness-lock.js +1320 -0
  66. package/dist/src/openclaw/provider-readiness-lock.js.map +1 -0
  67. package/dist/src/openclaw/shared.d.ts +10 -17
  68. package/dist/src/openclaw/shared.js +53 -19
  69. package/dist/src/openclaw/shared.js.map +1 -1
  70. package/dist/src/openclaw.d.ts +3 -5
  71. package/dist/src/openclaw.js +245 -60
  72. package/dist/src/openclaw.js.map +1 -1
  73. package/dist/src/platform/process-owned-lock.d.ts +11 -0
  74. package/dist/src/platform/process-owned-lock.js +1698 -0
  75. package/dist/src/platform/process-owned-lock.js.map +1 -0
  76. package/dist/src/platform/recorder-directory.d.ts +1 -0
  77. package/dist/src/platform/recorder-directory.js +14 -0
  78. package/dist/src/platform/recorder-directory.js.map +1 -0
  79. package/dist/src/platform/windows-acl.d.ts +18 -0
  80. package/dist/src/platform/windows-acl.js +1367 -0
  81. package/dist/src/platform/windows-acl.js.map +1 -0
  82. package/dist/src/platform/windows-lock-root.d.ts +13 -0
  83. package/dist/src/platform/windows-lock-root.js +98 -0
  84. package/dist/src/platform/windows-lock-root.js.map +1 -0
  85. package/dist/src/providers/builtin/discord.d.ts +4 -0
  86. package/dist/src/providers/builtin/discord.js +52 -9
  87. package/dist/src/providers/builtin/discord.js.map +1 -1
  88. package/dist/src/providers/builtin/external-webhook-auth.d.ts +1 -0
  89. package/dist/src/providers/builtin/external-webhook-auth.js +38 -1
  90. package/dist/src/providers/builtin/external-webhook-auth.js.map +1 -1
  91. package/dist/src/providers/builtin/feishu.d.ts +1 -0
  92. package/dist/src/providers/builtin/feishu.js +96 -26
  93. package/dist/src/providers/builtin/feishu.js.map +1 -1
  94. package/dist/src/providers/builtin/googlechat.d.ts +1 -0
  95. package/dist/src/providers/builtin/googlechat.js +95 -26
  96. package/dist/src/providers/builtin/googlechat.js.map +1 -1
  97. package/dist/src/providers/builtin/imessage.js +60 -17
  98. package/dist/src/providers/builtin/imessage.js.map +1 -1
  99. package/dist/src/providers/builtin/loopback.js +88 -35
  100. package/dist/src/providers/builtin/loopback.js.map +1 -1
  101. package/dist/src/providers/builtin/matrix.d.ts +2 -2
  102. package/dist/src/providers/builtin/matrix.js +78 -21
  103. package/dist/src/providers/builtin/matrix.js.map +1 -1
  104. package/dist/src/providers/builtin/mattermost.d.ts +11 -7
  105. package/dist/src/providers/builtin/mattermost.js +138 -24
  106. package/dist/src/providers/builtin/mattermost.js.map +1 -1
  107. package/dist/src/providers/builtin/msteams.d.ts +1 -0
  108. package/dist/src/providers/builtin/msteams.js +118 -38
  109. package/dist/src/providers/builtin/msteams.js.map +1 -1
  110. package/dist/src/providers/builtin/native-local-mock.js +4 -4
  111. package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
  112. package/dist/src/providers/builtin/script.js +1057 -146
  113. package/dist/src/providers/builtin/script.js.map +1 -1
  114. package/dist/src/providers/builtin/slack.d.ts +8 -1
  115. package/dist/src/providers/builtin/slack.js +327 -24
  116. package/dist/src/providers/builtin/slack.js.map +1 -1
  117. package/dist/src/providers/builtin/telegram.d.ts +1 -1
  118. package/dist/src/providers/builtin/telegram.js +55 -14
  119. package/dist/src/providers/builtin/telegram.js.map +1 -1
  120. package/dist/src/providers/builtin/whatsapp.d.ts +4 -3
  121. package/dist/src/providers/builtin/whatsapp.js +157 -29
  122. package/dist/src/providers/builtin/whatsapp.js.map +1 -1
  123. package/dist/src/providers/builtin/zalo.d.ts +5 -2
  124. package/dist/src/providers/builtin/zalo.js +31 -7
  125. package/dist/src/providers/builtin/zalo.js.map +1 -1
  126. package/dist/src/providers/catalog.d.ts +1 -1
  127. package/dist/src/providers/catalog.js +1 -1
  128. package/dist/src/providers/catalog.js.map +1 -1
  129. package/dist/src/providers/local-mock.d.ts +4 -0
  130. package/dist/src/providers/local-mock.js +162 -35
  131. package/dist/src/providers/local-mock.js.map +1 -1
  132. package/dist/src/providers/native-ids.d.ts +2 -0
  133. package/dist/src/providers/native-ids.js +3 -0
  134. package/dist/src/providers/native-ids.js.map +1 -1
  135. package/dist/src/providers/recorder.d.ts +14 -3
  136. package/dist/src/providers/recorder.js +521 -41
  137. package/dist/src/providers/recorder.js.map +1 -1
  138. package/dist/src/providers/registry.d.ts +1 -0
  139. package/dist/src/providers/registry.js +65 -20
  140. package/dist/src/providers/registry.js.map +1 -1
  141. package/dist/src/providers/signed-jwt.d.ts +6 -1
  142. package/dist/src/providers/signed-jwt.js +241 -50
  143. package/dist/src/providers/signed-jwt.js.map +1 -1
  144. package/dist/src/providers/slack-ids.d.ts +1 -0
  145. package/dist/src/providers/slack-ids.js +5 -0
  146. package/dist/src/providers/slack-ids.js.map +1 -1
  147. package/dist/src/providers/target-normalizers.d.ts +9 -1
  148. package/dist/src/providers/target-normalizers.js +177 -58
  149. package/dist/src/providers/target-normalizers.js.map +1 -1
  150. package/dist/src/providers/webhook-server.d.ts +3 -0
  151. package/dist/src/providers/webhook-server.js +268 -47
  152. package/dist/src/providers/webhook-server.js.map +1 -1
  153. package/dist/src/servers/discord.d.ts +40 -0
  154. package/dist/src/servers/discord.js +842 -0
  155. package/dist/src/servers/discord.js.map +1 -0
  156. package/dist/src/servers/http.d.ts +14 -2
  157. package/dist/src/servers/http.js +229 -58
  158. package/dist/src/servers/http.js.map +1 -1
  159. package/dist/src/servers/index.d.ts +10 -4
  160. package/dist/src/servers/index.js +4 -0
  161. package/dist/src/servers/index.js.map +1 -1
  162. package/dist/src/servers/matrix.d.ts +3 -0
  163. package/dist/src/servers/matrix.js +268 -110
  164. package/dist/src/servers/matrix.js.map +1 -1
  165. package/dist/src/servers/mattermost.d.ts +5 -0
  166. package/dist/src/servers/mattermost.js +389 -91
  167. package/dist/src/servers/mattermost.js.map +1 -1
  168. package/dist/src/servers/recorder.d.ts +11 -0
  169. package/dist/src/servers/recorder.js +1072 -69
  170. package/dist/src/servers/recorder.js.map +1 -1
  171. package/dist/src/servers/signal.d.ts +1 -0
  172. package/dist/src/servers/signal.js +279 -44
  173. package/dist/src/servers/signal.js.map +1 -1
  174. package/dist/src/servers/slack.d.ts +15 -0
  175. package/dist/src/servers/slack.js +270 -54
  176. package/dist/src/servers/slack.js.map +1 -1
  177. package/dist/src/servers/telegram-identity.d.ts +6 -0
  178. package/dist/src/servers/telegram-identity.js +27 -0
  179. package/dist/src/servers/telegram-identity.js.map +1 -0
  180. package/dist/src/servers/telegram.d.ts +17 -6
  181. package/dist/src/servers/telegram.js +1218 -107
  182. package/dist/src/servers/telegram.js.map +1 -1
  183. package/dist/src/servers/webhook-target.d.ts +12 -4
  184. package/dist/src/servers/webhook-target.js +226 -28
  185. package/dist/src/servers/webhook-target.js.map +1 -1
  186. package/dist/src/servers/whatsapp-baileys-websocket.d.ts +60 -1
  187. package/dist/src/servers/whatsapp-baileys-websocket.js +782 -112
  188. package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
  189. package/dist/src/servers/whatsapp-jid.d.ts +1 -0
  190. package/dist/src/servers/whatsapp-jid.js +9 -5
  191. package/dist/src/servers/whatsapp-jid.js.map +1 -1
  192. package/dist/src/servers/whatsapp-wire/binary-node.d.ts +1 -0
  193. package/dist/src/servers/whatsapp-wire/binary-node.js +37 -13
  194. package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
  195. package/dist/src/servers/whatsapp-wire/crypto.d.ts +3 -0
  196. package/dist/src/servers/whatsapp-wire/crypto.js +23 -8
  197. package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -1
  198. package/dist/src/servers/whatsapp-wire/handshake.d.ts +9 -3
  199. package/dist/src/servers/whatsapp-wire/handshake.js +173 -12
  200. package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -1
  201. package/dist/src/servers/whatsapp-wire/signal.js +3 -3
  202. package/dist/src/servers/whatsapp-wire/signal.js.map +1 -1
  203. package/dist/src/servers/whatsapp.d.ts +7 -1
  204. package/dist/src/servers/whatsapp.js +149 -25
  205. package/dist/src/servers/whatsapp.js.map +1 -1
  206. package/dist/src/servers/zalo.d.ts +1 -0
  207. package/dist/src/servers/zalo.js +193 -82
  208. package/dist/src/servers/zalo.js.map +1 -1
  209. package/docs/channel-setup.md +251 -64
  210. package/fixtures/examples/crabline.example.yaml +3 -2
  211. package/package.json +18 -10
  212. package/dist/src/openclaw/smoke-lock.js +0 -1004
  213. package/dist/src/openclaw/smoke-lock.js.map +0 -1
  214. package/fixtures/examples/openclaw-bridge.yaml +0 -125
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/servers/http.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { timingSafeEqual } from \"node:crypto\";\nimport { CrablineError } from \"../core/errors.js\";\n\nexport type ServerRequestEvent = {\n at: string;\n body?: unknown;\n method: string;\n path: string;\n query: Record<string, string>;\n type: \"admin\" | \"api\";\n};\n\nexport type HttpJsonHandlerResult =\n | Response\n | {\n onWriteFailure?(): Promise<void> | void;\n onWriteSuccess?(): Promise<void> | void;\n response: Response;\n };\n\nexport const ADMIN_TOKEN_HEADER = \"x-crabline-admin-token\";\nexport const DEFAULT_MAX_REQUEST_BODY_BYTES = 1024 * 1024;\nexport const DEFAULT_SERVER_SHUTDOWN_GRACE_MS = 250;\n\nexport class InvalidJsonBodyError extends Error {\n constructor(cause: unknown) {\n super(\"Request body is not valid JSON.\", { cause });\n this.name = \"InvalidJsonBodyError\";\n }\n}\n\nexport class RequestBodyTooLargeError extends Error {\n constructor(readonly maxBytes: number) {\n super(`Request body exceeds the ${maxBytes} byte limit.`);\n this.name = \"RequestBodyTooLargeError\";\n }\n}\n\nexport function jsonResponse(value: unknown, status = 200): Response {\n return Response.json(value, { status });\n}\n\nexport function drainRequestBody(request: IncomingMessage): void {\n const ignoreError = () => {};\n request.on(\"error\", ignoreError);\n if (request.destroyed || request.readableEnded) {\n return;\n }\n const cleanup = () => {\n request.off(\"close\", cleanup);\n request.off(\"end\", cleanup);\n request.off(\"error\", ignoreError);\n };\n\n request.once(\"close\", cleanup);\n request.once(\"end\", cleanup);\n request.resume();\n}\n\nexport async function readBody(\n request: IncomingMessage,\n maxBytes = DEFAULT_MAX_REQUEST_BODY_BYTES,\n): Promise<Buffer> {\n const contentLengthHeader = request.headers[\"content-length\"];\n const contentLengthValue = Array.isArray(contentLengthHeader)\n ? contentLengthHeader[0]\n : contentLengthHeader;\n if (contentLengthValue && /^\\d+$/u.test(contentLengthValue)) {\n const contentLength = Number(contentLengthValue);\n if (!Number.isSafeInteger(contentLength) || contentLength > maxBytes) {\n drainRequestBody(request);\n throw new RequestBodyTooLargeError(maxBytes);\n }\n }\n\n return await new Promise<Buffer>((resolve, reject) => {\n const chunks: Buffer[] = [];\n let length = 0;\n let settled = false;\n\n const cleanup = () => {\n request.off(\"aborted\", onAborted);\n request.off(\"data\", onData);\n request.off(\"end\", onEnd);\n request.off(\"error\", onError);\n };\n const fail = (error: Error) => {\n if (settled) {\n return;\n }\n settled = true;\n drainRequestBody(request);\n cleanup();\n reject(error);\n };\n const onAborted = () => fail(new Error(\"Request body stream was aborted.\"));\n const onData = (chunk: Buffer | string) => {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n length += buffer.length;\n if (length > maxBytes) {\n fail(new RequestBodyTooLargeError(maxBytes));\n return;\n }\n chunks.push(buffer);\n };\n const onEnd = () => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n resolve(Buffer.concat(chunks, length));\n };\n const onError = (error: Error) => fail(error);\n\n request.on(\"aborted\", onAborted);\n request.on(\"data\", onData);\n request.on(\"end\", onEnd);\n request.on(\"error\", onError);\n });\n}\n\nexport async function parseUnknownRequestBody(\n request: IncomingMessage,\n maxBytes = DEFAULT_MAX_REQUEST_BODY_BYTES,\n): Promise<unknown> {\n const body = await readBody(request, maxBytes);\n if (body.length === 0) {\n return {};\n }\n const contentType = request.headers[\"content-type\"] ?? \"\";\n const includesJson = Array.isArray(contentType)\n ? contentType.some((entry) => entry.toLowerCase().includes(\"json\"))\n : contentType.toLowerCase().includes(\"json\");\n if (includesJson) {\n try {\n return JSON.parse(body.toString(\"utf8\")) as unknown;\n } catch (error) {\n throw new InvalidJsonBodyError(error);\n }\n }\n const params = new URLSearchParams(body.toString(\"utf8\"));\n return Object.fromEntries(params.entries());\n}\n\nexport async function parseRequestBody(request: IncomingMessage): Promise<Record<string, unknown>> {\n return (await parseUnknownRequestBody(request, Number.MAX_SAFE_INTEGER)) as Record<\n string,\n unknown\n >;\n}\n\nexport function isJsonObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function queryRecord(url: URL): Record<string, string> {\n return Object.fromEntries(url.searchParams.entries());\n}\n\nexport function formatUrlHost(host: string): string {\n return host.includes(\":\") ? `[${host}]` : host;\n}\n\nexport function isLoopbackHost(host: string): boolean {\n const normalized = host\n .trim()\n .replace(/^\\[(.*)\\]$/u, \"$1\")\n .toLowerCase();\n return (\n normalized === \"localhost\" ||\n normalized.endsWith(\".localhost\") ||\n normalized === \"::1\" ||\n normalized.startsWith(\"::ffff:127.\") ||\n /^127(?:\\.\\d{1,3}){3}$/u.test(normalized)\n );\n}\n\nexport async function writeResponse(\n response: ServerResponse,\n fetchResponse: Response,\n): Promise<void> {\n response.statusCode = fetchResponse.status;\n for (const [name, value] of fetchResponse.headers) {\n if (name.toLowerCase() === \"set-cookie\") {\n continue;\n }\n response.setHeader(name, value);\n }\n const setCookies = fetchResponse.headers.getSetCookie();\n if (setCookies.length > 0) {\n response.setHeader(\"set-cookie\", setCookies);\n }\n const body = Buffer.from(await fetchResponse.arrayBuffer());\n await new Promise<void>((resolve, reject) => {\n if (\n response.destroyed ||\n response.req?.aborted ||\n response.req?.socket.destroyed ||\n response.socket?.destroyed\n ) {\n reject(new Error(\"HTTP response closed before delivery completed.\"));\n return;\n }\n const cleanup = () => {\n response.off(\"close\", onClose);\n response.off(\"error\", onError);\n response.off(\"finish\", onFinish);\n };\n const onClose = () => {\n if (response.writableFinished) {\n cleanup();\n resolve();\n return;\n }\n cleanup();\n reject(new Error(\"HTTP response closed before delivery completed.\"));\n };\n const onError = (error: Error) => {\n cleanup();\n reject(error);\n };\n const onFinish = () => {\n cleanup();\n resolve();\n };\n response.once(\"close\", onClose);\n response.once(\"error\", onError);\n response.once(\"finish\", onFinish);\n try {\n response.end(body);\n } catch (error) {\n cleanup();\n reject(error);\n }\n });\n}\n\nexport function closeServer(\n server: Server,\n graceMs = DEFAULT_SERVER_SHUTDOWN_GRACE_MS,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const closeIdleInterval = setInterval(() => server.closeIdleConnections(), 25);\n closeIdleInterval.unref();\n const forceCloseTimer = setTimeout(() => {\n server.closeAllConnections();\n }, graceMs);\n forceCloseTimer.unref();\n server.close((error) => {\n clearInterval(closeIdleInterval);\n clearTimeout(forceCloseTimer);\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n server.closeIdleConnections();\n });\n}\n\nexport async function startHttpJsonServer(params: {\n handle: (request: IncomingMessage, response: ServerResponse) => Promise<HttpJsonHandlerResult>;\n handleError?: (error: unknown, request: IncomingMessage) => Response | undefined;\n host: string;\n port: number;\n serverName: string;\n}): Promise<{ baseUrl: string; close(): Promise<void>; server: Server }> {\n const handleRequest = async (request: IncomingMessage, response: ServerResponse) => {\n try {\n const result = await params.handle(request, response);\n const handled = result instanceof Response ? { response: result } : result;\n try {\n await writeResponse(response, handled.response);\n } catch (error) {\n await handled.onWriteFailure?.();\n throw error;\n }\n try {\n await handled.onWriteSuccess?.();\n } catch {\n // Delivery is already committed; lifecycle failures must not trigger another response.\n }\n } catch (error) {\n let handled: Response | undefined;\n try {\n handled = params.handleError?.(error, request);\n } catch {\n handled = undefined;\n }\n try {\n await writeResponse(\n response,\n handled ??\n jsonResponse(\n {\n error: \"internal server error\",\n ok: false,\n },\n 500,\n ),\n );\n } catch {\n response.destroy();\n }\n }\n };\n const server = createServer((request, response) => {\n void handleRequest(request, response);\n });\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(params.port, params.host, () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address();\n if (!address || typeof address === \"string\") {\n throw new CrablineError(`Unable to resolve ${params.serverName} local server address.`, {\n kind: \"connectivity\",\n });\n }\n return {\n baseUrl: `http://${formatUrlHost(params.host)}:${address.port}`,\n async close() {\n await closeServer(server);\n },\n server,\n };\n}\n\nexport function readString(value: unknown): string | undefined {\n if (typeof value === \"string\" && value.length > 0) {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"bigint\") {\n return value.toString();\n }\n return undefined;\n}\n\nexport function readTrimmedString(value: unknown): string | undefined {\n const stringValue = readString(value)?.trim();\n return stringValue ? stringValue : undefined;\n}\n\nexport function readInteger(value: unknown): number | undefined {\n const stringValue = readTrimmedString(value);\n if (!stringValue || !/^-?\\d+$/u.test(stringValue)) {\n return undefined;\n }\n const parsed = Number(stringValue);\n return Number.isSafeInteger(parsed) ? parsed : undefined;\n}\n\nfunction readBearerToken(authorization: string | undefined): string | undefined {\n if (!authorization) {\n return undefined;\n }\n const trimmed = authorization.trimStart();\n if (trimmed.slice(0, 7).toLowerCase() !== \"bearer \") {\n return undefined;\n }\n return trimmed.slice(7);\n}\n\nexport function hasAdminToken(request: IncomingMessage, expectedToken: string): boolean {\n const header = request.headers[ADMIN_TOKEN_HEADER];\n const directToken = Array.isArray(header) ? header[0] : header;\n const providedToken = directToken ?? readBearerToken(request.headers.authorization);\n if (!providedToken) {\n return false;\n }\n\n const provided = Buffer.from(providedToken);\n const expected = Buffer.from(expectedToken);\n return provided.length === expected.length && timingSafeEqual(provided, expected);\n}\n\nexport function adminAuthError(): Response {\n return new Response(\"unauthorized\", {\n headers: { \"www-authenticate\": \"Bearer\" },\n status: 401,\n });\n}\n"]}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/servers/http.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { createHash, timingSafeEqual } from \"node:crypto\";\nimport { BlockList, isIP } from \"node:net\";\nimport { CrablineError } from \"../core/errors.js\";\n\nexport type ServerRequestEvent = {\n at: string;\n body?: unknown;\n method: string;\n path: string;\n query: Record<string, string>;\n type: \"admin\" | \"api\";\n};\n\nexport type HttpJsonHandlerResult =\n | Response\n | {\n onWriteFailure?(): Promise<void> | void;\n onWriteSuccess?(): Promise<void> | void;\n response: Response;\n };\n\nexport const ADMIN_TOKEN_HEADER = \"x-crabline-admin-token\";\nexport const DEFAULT_MAX_REQUEST_BODY_BYTES = 1024 * 1024;\nexport const DEFAULT_MAX_RESPONSE_BODY_BYTES = 8 * 1024 * 1024;\nexport const DEFAULT_SERVER_SHUTDOWN_GRACE_MS = 250;\nconst DRAINING_REQUESTS = new WeakSet<IncomingMessage>();\nconst LOOPBACK_ADDRESSES = new BlockList();\nLOOPBACK_ADDRESSES.addSubnet(\"127.0.0.0\", 8, \"ipv4\");\nLOOPBACK_ADDRESSES.addAddress(\"::1\", \"ipv6\");\nLOOPBACK_ADDRESSES.addSubnet(\"::ffff:127.0.0.0\", 104, \"ipv6\");\nconst UNSPECIFIED_ADDRESSES = new BlockList();\nUNSPECIFIED_ADDRESSES.addAddress(\"0.0.0.0\", \"ipv4\");\nUNSPECIFIED_ADDRESSES.addAddress(\"::\", \"ipv6\");\nconst HOP_BY_HOP_RESPONSE_HEADERS = new Set([\n \"connection\",\n \"keep-alive\",\n \"proxy-authenticate\",\n \"proxy-authorization\",\n \"proxy-connection\",\n \"te\",\n \"trailer\",\n \"transfer-encoding\",\n \"upgrade\",\n]);\n\nexport class InvalidJsonBodyError extends Error {\n constructor(cause: unknown, message = \"Request body is not valid JSON.\") {\n super(message, { cause });\n this.name = \"InvalidJsonBodyError\";\n }\n}\n\nexport class RequestBodyTooLargeError extends Error {\n constructor(readonly maxBytes: number) {\n super(`Request body exceeds the ${maxBytes} byte limit.`);\n this.name = \"RequestBodyTooLargeError\";\n }\n}\n\nexport class ResponseBodyTooLargeError extends Error {\n constructor(readonly maxBytes: number) {\n super(`Response body exceeds the ${maxBytes} byte limit.`);\n this.name = \"ResponseBodyTooLargeError\";\n }\n}\n\nexport function jsonResponse(value: unknown, status = 200): Response {\n return Response.json(value, { status });\n}\n\nexport function drainRequestBody(request: IncomingMessage): void {\n if (request.readableEnded || DRAINING_REQUESTS.has(request)) {\n return;\n }\n DRAINING_REQUESTS.add(request);\n const ignoreError = () => {};\n request.on(\"error\", ignoreError);\n if (request.destroyed) {\n // IncomingMessage may emit its terminal error after destroyed becomes true.\n return;\n }\n const cleanup = () => {\n DRAINING_REQUESTS.delete(request);\n request.off(\"close\", cleanup);\n request.off(\"end\", cleanup);\n request.off(\"error\", ignoreError);\n };\n\n request.once(\"close\", cleanup);\n request.once(\"end\", cleanup);\n request.resume();\n}\n\nexport async function readBody(\n request: IncomingMessage,\n maxBytes = DEFAULT_MAX_REQUEST_BODY_BYTES,\n): Promise<Buffer> {\n requirePositiveSafeInteger(maxBytes, \"maxBytes\");\n if (request.aborted) {\n throw new Error(\"Request body stream was aborted.\");\n }\n const contentLengthHeader = request.headers[\"content-length\"];\n const contentLengthValue = Array.isArray(contentLengthHeader)\n ? contentLengthHeader[0]\n : contentLengthHeader;\n if (contentLengthValue && /^\\d+$/u.test(contentLengthValue)) {\n const contentLength = Number(contentLengthValue);\n if (!Number.isSafeInteger(contentLength) || contentLength > maxBytes) {\n drainRequestBody(request);\n throw new RequestBodyTooLargeError(maxBytes);\n }\n }\n\n return await new Promise<Buffer>((resolve, reject) => {\n const chunks: Buffer[] = [];\n let length = 0;\n let settled = false;\n\n const cleanup = () => {\n request.off(\"aborted\", onAborted);\n request.off(\"data\", onData);\n request.off(\"end\", onEnd);\n request.off(\"error\", onError);\n };\n const fail = (error: Error) => {\n if (settled) {\n return;\n }\n settled = true;\n drainRequestBody(request);\n cleanup();\n reject(error);\n };\n const onAborted = () => fail(new Error(\"Request body stream was aborted.\"));\n const onData = (chunk: Buffer | string) => {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n length += buffer.length;\n if (length > maxBytes) {\n fail(new RequestBodyTooLargeError(maxBytes));\n return;\n }\n chunks.push(buffer);\n };\n const onEnd = () => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n resolve(Buffer.concat(chunks, length));\n };\n const onError = (error: Error) => fail(error);\n\n request.on(\"aborted\", onAborted);\n request.on(\"data\", onData);\n request.on(\"end\", onEnd);\n request.on(\"error\", onError);\n if (request.aborted) {\n onAborted();\n }\n });\n}\n\nexport async function parseUnknownRequestBody(\n request: IncomingMessage,\n maxBytes = DEFAULT_MAX_REQUEST_BODY_BYTES,\n): Promise<unknown> {\n const body = await readBody(request, maxBytes);\n if (body.length === 0) {\n return {};\n }\n const contentType = request.headers[\"content-type\"] ?? \"\";\n const isJson = Array.isArray(contentType)\n ? contentType.some(isJsonMediaType)\n : isJsonMediaType(contentType);\n if (isJson) {\n try {\n return JSON.parse(body.toString(\"utf8\")) as unknown;\n } catch (error) {\n throw new InvalidJsonBodyError(error);\n }\n }\n const params = new URLSearchParams(body.toString(\"utf8\"));\n return Object.fromEntries(params.entries());\n}\n\nexport function isJsonMediaType(value: string): boolean {\n const mediaType = value.split(\";\", 1)[0]?.trim().toLowerCase();\n return (\n mediaType === \"application/json\" ||\n /^[a-z0-9!#$%&'*+.^_`|~-]+\\/[a-z0-9!#$%&'*+.^_`|~-]+\\+json$/u.test(mediaType ?? \"\")\n );\n}\n\nexport async function parseRequestBody(request: IncomingMessage): Promise<Record<string, unknown>> {\n const body = await parseUnknownRequestBody(request);\n if (!isJsonObject(body)) {\n throw new InvalidJsonBodyError(undefined, \"Request body must be a JSON object.\");\n }\n return body;\n}\n\nexport function isJsonObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function queryRecord(url: URL): Record<string, string> {\n return Object.fromEntries(url.searchParams.entries());\n}\n\nexport function formatUrlHost(host: string): string {\n return host.includes(\":\") ? `[${host}]` : host;\n}\n\nfunction normalizeHost(host: string): string {\n return host\n .trim()\n .replace(/^\\[(.*)\\]$/u, \"$1\")\n .toLowerCase()\n .replace(/\\.$/u, \"\");\n}\n\nexport function isLoopbackAddress(address: string): boolean {\n const normalized = normalizeHost(address);\n const family = isIP(normalized);\n return family === 4\n ? LOOPBACK_ADDRESSES.check(normalized, \"ipv4\")\n : family === 6\n ? LOOPBACK_ADDRESSES.check(normalized, \"ipv6\")\n : false;\n}\n\nexport function isLoopbackHost(host: string): boolean {\n const normalized = normalizeHost(host);\n if (normalized === \"localhost\" || normalized.endsWith(\".localhost\")) {\n return true;\n }\n return isLoopbackAddress(normalized);\n}\n\nexport function advertisedHostForBindAddress(host: string, boundAddress: string): string {\n const normalizedBoundAddress = normalizeHost(boundAddress);\n const boundFamily = isIP(normalizedBoundAddress);\n if (boundFamily === 4 && UNSPECIFIED_ADDRESSES.check(normalizedBoundAddress, \"ipv4\")) {\n return \"127.0.0.1\";\n }\n if (boundFamily === 6 && UNSPECIFIED_ADDRESSES.check(normalizedBoundAddress, \"ipv6\")) {\n return \"::1\";\n }\n return isLoopbackHost(host) && isLoopbackAddress(boundAddress) ? boundAddress : host;\n}\n\nexport function assertLoopbackBindAddress(\n configuredHost: string,\n boundAddress: string,\n serverName: string,\n): void {\n if (isLoopbackHost(configuredHost) && !isLoopbackAddress(boundAddress)) {\n throw new CrablineError(\n `${serverName} resolved a loopback hostname to non-loopback address ${boundAddress}.`,\n { kind: \"connectivity\" },\n );\n }\n}\n\nexport function writeFetchResponseHeaders(response: ServerResponse, fetchResponse: Response): void {\n const preserveRepresentationLength =\n response.req?.method === \"HEAD\" || fetchResponse.status === 304;\n const connectionHeaders = new Set(\n (fetchResponse.headers.get(\"connection\") ?? \"\")\n .split(\",\")\n .map((name) => name.trim().toLowerCase())\n .filter(Boolean),\n );\n if (connectionHeaders.has(\"close\")) {\n response.shouldKeepAlive = false;\n }\n\n for (const [name, value] of fetchResponse.headers) {\n const normalizedName = name.toLowerCase();\n if (\n normalizedName === \"set-cookie\" ||\n HOP_BY_HOP_RESPONSE_HEADERS.has(normalizedName) ||\n connectionHeaders.has(normalizedName) ||\n (normalizedName === \"content-length\" && !preserveRepresentationLength)\n ) {\n continue;\n }\n response.setHeader(name, value);\n }\n\n const setCookies = fetchResponse.headers.getSetCookie();\n if (setCookies.length > 0 && !connectionHeaders.has(\"set-cookie\")) {\n response.setHeader(\"set-cookie\", setCookies);\n }\n}\n\nexport async function writeResponse(\n response: ServerResponse,\n fetchResponse: Response,\n maxBytes = DEFAULT_MAX_RESPONSE_BODY_BYTES,\n): Promise<void> {\n requirePositiveSafeInteger(maxBytes, \"maxResponseBodyBytes\");\n const reader = fetchResponse.body?.getReader();\n let cancellation: Promise<void> | undefined;\n let rejectStopped!: (error: Error) => void;\n let stoppedError: Error | undefined;\n const stopped = new Promise<never>((_, reject) => {\n rejectStopped = reject;\n });\n void stopped.catch(() => {});\n\n const cancelBody = (reason: Error) => {\n if (!reader || cancellation) {\n return;\n }\n cancellation = reader.cancel(reason).catch(() => {});\n };\n const stop = (error: Error) => {\n if (stoppedError) {\n return;\n }\n stoppedError = error;\n cancelBody(error);\n rejectStopped(error);\n };\n const onClose = () => {\n if (!response.writableFinished) {\n stop(new Error(\"HTTP response closed before delivery completed.\"));\n }\n };\n const onError = (error: Error) => stop(error);\n const onRequestAborted = () => stop(new Error(\"HTTP response request was aborted.\"));\n response.once(\"close\", onClose);\n response.once(\"error\", onError);\n response.req?.once(\"aborted\", onRequestAborted);\n\n try {\n if (\n response.destroyed ||\n response.req?.aborted ||\n response.req?.socket.destroyed ||\n response.socket?.destroyed\n ) {\n throw new Error(\"HTTP response closed before delivery completed.\");\n }\n\n if (response.req?.method === \"HEAD\") {\n cancelBody(new Error(\"HEAD response body is not transferred.\"));\n response.statusCode = fetchResponse.status;\n writeFetchResponseHeaders(response, fetchResponse);\n let onFinish!: () => void;\n const finished = new Promise<void>((resolve) => {\n onFinish = resolve;\n response.once(\"finish\", onFinish);\n });\n try {\n response.end();\n await Promise.race([finished, stopped]);\n } finally {\n response.off(\"finish\", onFinish);\n }\n return;\n }\n\n const chunks: Buffer[] = [];\n let bodyLength = 0;\n if (reader) {\n while (true) {\n const chunk = await Promise.race([reader.read(), stopped]);\n if (chunk.done) {\n break;\n }\n if (chunk.value.byteLength > 0) {\n if (bodyLength + chunk.value.byteLength > maxBytes) {\n throw new ResponseBodyTooLargeError(maxBytes);\n }\n const buffer = Buffer.from(chunk.value);\n chunks.push(buffer);\n bodyLength += buffer.length;\n }\n }\n }\n\n const body = Buffer.concat(chunks, bodyLength);\n response.statusCode = fetchResponse.status;\n writeFetchResponseHeaders(response, fetchResponse);\n let onFinish!: () => void;\n const finished = new Promise<void>((resolve) => {\n onFinish = resolve;\n response.once(\"finish\", onFinish);\n });\n try {\n response.end(body);\n await Promise.race([finished, stopped]);\n } finally {\n response.off(\"finish\", onFinish);\n }\n } catch (error) {\n cancelBody(error instanceof Error ? error : new Error(String(error)));\n throw error;\n } finally {\n response.off(\"close\", onClose);\n response.off(\"error\", onError);\n response.req?.off(\"aborted\", onRequestAborted);\n }\n}\n\nexport function closeServer(\n server: Server,\n graceMs = DEFAULT_SERVER_SHUTDOWN_GRACE_MS,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const closeIdleInterval = setInterval(() => server.closeIdleConnections(), 25);\n closeIdleInterval.unref();\n const forceCloseTimer = setTimeout(() => {\n server.closeAllConnections();\n }, graceMs);\n forceCloseTimer.unref();\n server.close((error) => {\n clearInterval(closeIdleInterval);\n clearTimeout(forceCloseTimer);\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n server.closeIdleConnections();\n });\n}\n\nexport async function startHttpJsonServer(params: {\n handle: (request: IncomingMessage, response: ServerResponse) => Promise<HttpJsonHandlerResult>;\n handleError?: (error: unknown, request: IncomingMessage) => Response | undefined;\n host: string;\n maxResponseBodyBytes?: number | undefined;\n port: number;\n serverName: string;\n}): Promise<{ baseUrl: string; close(): Promise<void>; server: Server }> {\n const maxResponseBodyBytes = requirePositiveSafeInteger(\n params.maxResponseBodyBytes ?? DEFAULT_MAX_RESPONSE_BODY_BYTES,\n \"maxResponseBodyBytes\",\n );\n const handleRequest = async (request: IncomingMessage, response: ServerResponse) => {\n try {\n const result = await params.handle(request, response);\n drainRequestBody(request);\n const handled = result instanceof Response ? { response: result } : result;\n try {\n await writeResponse(response, handled.response, maxResponseBodyBytes);\n } catch (error) {\n await handled.onWriteFailure?.();\n throw error;\n }\n try {\n await handled.onWriteSuccess?.();\n } catch {\n // Delivery is already committed; lifecycle failures must not trigger another response.\n }\n } catch (error) {\n drainRequestBody(request);\n let handled: Response | undefined;\n try {\n handled = params.handleError?.(error, request);\n } catch {\n handled = undefined;\n }\n try {\n await writeResponse(\n response,\n handled ??\n jsonResponse(\n {\n error: \"internal server error\",\n ok: false,\n },\n 500,\n ),\n maxResponseBodyBytes,\n );\n } catch {\n response.destroy();\n }\n }\n };\n const server = createServer((request, response) => {\n void handleRequest(request, response);\n });\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(params.port, params.host, () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address();\n if (!address || typeof address === \"string\") {\n throw new CrablineError(`Unable to resolve ${params.serverName} local server address.`, {\n kind: \"connectivity\",\n });\n }\n try {\n assertLoopbackBindAddress(params.host, address.address, params.serverName);\n } catch (error) {\n await closeServer(server);\n throw error;\n }\n const advertisedHost = advertisedHostForBindAddress(params.host, address.address);\n return {\n baseUrl: `http://${formatUrlHost(advertisedHost)}:${address.port}`,\n async close() {\n await closeServer(server);\n },\n server,\n };\n}\n\nfunction requirePositiveSafeInteger(value: number, name: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new RangeError(`${name} must be a positive safe integer.`);\n }\n return value;\n}\n\nexport function readString(value: unknown): string | undefined {\n if (typeof value === \"string\" && value.length > 0) {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"bigint\") {\n return value.toString();\n }\n return undefined;\n}\n\nexport function readTrimmedString(value: unknown): string | undefined {\n const stringValue = readString(value)?.trim();\n return stringValue ? stringValue : undefined;\n}\n\nexport function readInteger(value: unknown): number | undefined {\n const stringValue = readTrimmedString(value);\n if (!stringValue || !/^-?\\d+$/u.test(stringValue)) {\n return undefined;\n }\n const parsed = Number(stringValue);\n return Number.isSafeInteger(parsed) ? parsed : undefined;\n}\n\nfunction readBearerToken(authorization: string | undefined): string | undefined {\n if (!authorization) {\n return undefined;\n }\n const trimmed = authorization.trimStart();\n if (trimmed.slice(0, 7).toLowerCase() !== \"bearer \") {\n return undefined;\n }\n return trimmed.slice(7);\n}\n\nexport function constantTimeTokenEqual(providedToken: string, expectedToken: string): boolean {\n const provided = createHash(\"sha256\").update(providedToken).digest();\n const expected = createHash(\"sha256\").update(expectedToken).digest();\n return timingSafeEqual(provided, expected);\n}\n\nexport function hasAdminToken(request: IncomingMessage, expectedToken: string): boolean {\n const header = request.headers[ADMIN_TOKEN_HEADER];\n const directToken = Array.isArray(header) ? header[0] : header;\n const providedToken = directToken ?? readBearerToken(request.headers.authorization);\n if (!providedToken) {\n return false;\n }\n\n return constantTimeTokenEqual(providedToken, expectedToken);\n}\n\nexport function adminAuthError(): Response {\n return new Response(\"unauthorized\", {\n headers: { \"www-authenticate\": \"Bearer\" },\n status: 401,\n });\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { type DiscordServerManifest, type StartedDiscordServer, type StartDiscordServerParams } from "./discord.js";
1
2
  import { type MattermostServerManifest, type StartedMattermostServer, type StartMattermostServerParams } from "./mattermost.js";
2
3
  import { type MatrixServerManifest, type StartedMatrixServer, type StartMatrixServerParams } from "./matrix.js";
3
4
  import { type SignalServerManifest, type StartedSignalServer, type StartSignalServerParams } from "./signal.js";
@@ -5,11 +6,13 @@ import { type SlackServerManifest, type StartedSlackServer, type StartSlackServe
5
6
  import { type StartedTelegramServer, type StartTelegramServerParams, type TelegramServerManifest } from "./telegram.js";
6
7
  import { type StartedWhatsAppServer, type StartWhatsAppServerParams, type WhatsAppServerManifest } from "./whatsapp.js";
7
8
  import { type StartedZaloServer, type StartZaloServerParams, type ZaloServerManifest } from "./zalo.js";
8
- export declare const CRABLINE_SERVER_CHANNELS: readonly ["mattermost", "matrix", "signal", "slack", "telegram", "whatsapp", "zalo"];
9
+ export declare const CRABLINE_SERVER_CHANNELS: readonly ["discord", "mattermost", "matrix", "signal", "slack", "telegram", "whatsapp", "zalo"];
9
10
  export type CrablineServerChannel = (typeof CRABLINE_SERVER_CHANNELS)[number];
10
- export type CrablineServerManifest = MattermostServerManifest | MatrixServerManifest | SignalServerManifest | SlackServerManifest | TelegramServerManifest | WhatsAppServerManifest | ZaloServerManifest;
11
- export type StartedCrablineServer = StartedMattermostServer | StartedMatrixServer | StartedSignalServer | StartedSlackServer | StartedTelegramServer | StartedWhatsAppServer | StartedZaloServer;
12
- export type StartCrablineServerParams = (StartMattermostServerParams & {
11
+ export type CrablineServerManifest = DiscordServerManifest | MattermostServerManifest | MatrixServerManifest | SignalServerManifest | SlackServerManifest | TelegramServerManifest | WhatsAppServerManifest | ZaloServerManifest;
12
+ export type StartedCrablineServer = StartedDiscordServer | StartedMattermostServer | StartedMatrixServer | StartedSignalServer | StartedSlackServer | StartedTelegramServer | StartedWhatsAppServer | StartedZaloServer;
13
+ export type StartCrablineServerParams = (StartDiscordServerParams & {
14
+ channel: "discord";
15
+ }) | (StartMattermostServerParams & {
13
16
  channel: "mattermost";
14
17
  }) | (StartMatrixServerParams & {
15
18
  channel: "matrix";
@@ -25,6 +28,9 @@ export type StartCrablineServerParams = (StartMattermostServerParams & {
25
28
  channel: "zalo";
26
29
  });
27
30
  export declare function isCrablineServerChannel(value: string): value is CrablineServerChannel;
31
+ export declare function startCrablineServer(params: StartDiscordServerParams & {
32
+ channel: "discord";
33
+ }): Promise<StartedDiscordServer>;
28
34
  export declare function startCrablineServer(params: StartMattermostServerParams & {
29
35
  channel: "mattermost";
30
36
  }): Promise<StartedMattermostServer>;
@@ -1,3 +1,4 @@
1
+ import { startDiscordServer, } from "./discord.js";
1
2
  import { startMattermostServer, } from "./mattermost.js";
2
3
  import { startMatrixServer, } from "./matrix.js";
3
4
  import { startSignalServer, } from "./signal.js";
@@ -7,6 +8,7 @@ import { startWhatsAppServer, } from "./whatsapp.js";
7
8
  import { startZaloServer, } from "./zalo.js";
8
9
  import { CrablineError } from "../core/errors.js";
9
10
  export const CRABLINE_SERVER_CHANNELS = Object.freeze([
11
+ "discord",
10
12
  "mattermost",
11
13
  "matrix",
12
14
  "signal",
@@ -21,6 +23,8 @@ export function isCrablineServerChannel(value) {
21
23
  }
22
24
  export async function startCrablineServer(params) {
23
25
  switch (params.channel) {
26
+ case "discord":
27
+ return await startDiscordServer(params);
24
28
  case "mattermost":
25
29
  return await startMattermostServer(params);
26
30
  case "matrix":
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/servers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,GAItB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,GAIjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,GAIpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,GAIpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,GAIhB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,CAAC;IACpD,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,UAAU;IACV,UAAU;IACV,MAAM;CACE,CAAC,CAAC;AA+BZ,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,CAAC;AAE9E,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,2BAA2B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AA0BD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAiC;IAEjC,QAAQ,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,YAAY;YACf,OAAO,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC7C,KAAK,QAAQ;YACX,OAAO,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzC,KAAK,QAAQ;YACX,OAAO,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzC,KAAK,OAAO;YACV,OAAO,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACxC,KAAK,UAAU;YACb,OAAO,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,UAAU;YACb,OAAO,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,MAAM;YACT,OAAO,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;QACvC,SAAS,CAAC;YACR,MAAM,WAAW,GAAU,MAAM,CAAC;YAClC,KAAK,WAAW,CAAC;YACjB,MAAM,IAAI,aAAa,CAAC,6BAA6B,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import {\n startMattermostServer,\n type MattermostServerManifest,\n type StartedMattermostServer,\n type StartMattermostServerParams,\n} from \"./mattermost.js\";\nimport {\n startMatrixServer,\n type MatrixServerManifest,\n type StartedMatrixServer,\n type StartMatrixServerParams,\n} from \"./matrix.js\";\nimport {\n startSignalServer,\n type SignalServerManifest,\n type StartedSignalServer,\n type StartSignalServerParams,\n} from \"./signal.js\";\nimport {\n startSlackServer,\n type SlackServerManifest,\n type StartedSlackServer,\n type StartSlackServerParams,\n} from \"./slack.js\";\nimport {\n startTelegramServer,\n type StartedTelegramServer,\n type StartTelegramServerParams,\n type TelegramServerManifest,\n} from \"./telegram.js\";\nimport {\n startWhatsAppServer,\n type StartedWhatsAppServer,\n type StartWhatsAppServerParams,\n type WhatsAppServerManifest,\n} from \"./whatsapp.js\";\nimport {\n startZaloServer,\n type StartedZaloServer,\n type StartZaloServerParams,\n type ZaloServerManifest,\n} from \"./zalo.js\";\nimport { CrablineError } from \"../core/errors.js\";\n\nexport const CRABLINE_SERVER_CHANNELS = Object.freeze([\n \"mattermost\",\n \"matrix\",\n \"signal\",\n \"slack\",\n \"telegram\",\n \"whatsapp\",\n \"zalo\",\n] as const);\n\nexport type CrablineServerChannel = (typeof CRABLINE_SERVER_CHANNELS)[number];\n\nexport type CrablineServerManifest =\n | MattermostServerManifest\n | MatrixServerManifest\n | SignalServerManifest\n | SlackServerManifest\n | TelegramServerManifest\n | WhatsAppServerManifest\n | ZaloServerManifest;\n\nexport type StartedCrablineServer =\n | StartedMattermostServer\n | StartedMatrixServer\n | StartedSignalServer\n | StartedSlackServer\n | StartedTelegramServer\n | StartedWhatsAppServer\n | StartedZaloServer;\n\nexport type StartCrablineServerParams =\n | (StartMattermostServerParams & { channel: \"mattermost\" })\n | (StartMatrixServerParams & { channel: \"matrix\" })\n | (StartSignalServerParams & { channel: \"signal\" })\n | (StartSlackServerParams & { channel: \"slack\" })\n | (StartTelegramServerParams & { channel: \"telegram\" })\n | (StartWhatsAppServerParams & { channel: \"whatsapp\" })\n | (StartZaloServerParams & { channel: \"zalo\" });\n\nconst CRABLINE_SERVER_CHANNEL_SET = new Set<string>(CRABLINE_SERVER_CHANNELS);\n\nexport function isCrablineServerChannel(value: string): value is CrablineServerChannel {\n return CRABLINE_SERVER_CHANNEL_SET.has(value);\n}\n\nexport function startCrablineServer(\n params: StartMattermostServerParams & { channel: \"mattermost\" },\n): Promise<StartedMattermostServer>;\nexport function startCrablineServer(\n params: StartMatrixServerParams & { channel: \"matrix\" },\n): Promise<StartedMatrixServer>;\nexport function startCrablineServer(\n params: StartSignalServerParams & { channel: \"signal\" },\n): Promise<StartedSignalServer>;\nexport function startCrablineServer(\n params: StartSlackServerParams & { channel: \"slack\" },\n): Promise<StartedSlackServer>;\nexport function startCrablineServer(\n params: StartTelegramServerParams & { channel: \"telegram\" },\n): Promise<StartedTelegramServer>;\nexport function startCrablineServer(\n params: StartWhatsAppServerParams & { channel: \"whatsapp\" },\n): Promise<StartedWhatsAppServer>;\nexport function startCrablineServer(\n params: StartZaloServerParams & { channel: \"zalo\" },\n): Promise<StartedZaloServer>;\nexport function startCrablineServer(\n params: StartCrablineServerParams,\n): Promise<StartedCrablineServer>;\nexport async function startCrablineServer(\n params: StartCrablineServerParams,\n): Promise<StartedCrablineServer> {\n switch (params.channel) {\n case \"mattermost\":\n return await startMattermostServer(params);\n case \"matrix\":\n return await startMatrixServer(params);\n case \"signal\":\n return await startSignalServer(params);\n case \"slack\":\n return await startSlackServer(params);\n case \"telegram\":\n return await startTelegramServer(params);\n case \"whatsapp\":\n return await startWhatsAppServer(params);\n case \"zalo\":\n return await startZaloServer(params);\n default: {\n const unsupported: never = params;\n void unsupported;\n throw new CrablineError(\"Unsupported server channel.\", { kind: \"config\" });\n }\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/servers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAInB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,GAItB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,GAIjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,GAIpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,GAIpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,GAIhB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,CAAC;IACpD,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,UAAU;IACV,UAAU;IACV,MAAM;CACE,CAAC,CAAC;AAkCZ,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,CAAC;AAE9E,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,2BAA2B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AA6BD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAiC;IAEjC,QAAQ,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,SAAS;YACZ,OAAO,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1C,KAAK,YAAY;YACf,OAAO,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC7C,KAAK,QAAQ;YACX,OAAO,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzC,KAAK,QAAQ;YACX,OAAO,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzC,KAAK,OAAO;YACV,OAAO,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACxC,KAAK,UAAU;YACb,OAAO,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,UAAU;YACb,OAAO,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,MAAM;YACT,OAAO,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;QACvC,SAAS,CAAC;YACR,MAAM,WAAW,GAAU,MAAM,CAAC;YAClC,KAAK,WAAW,CAAC;YACjB,MAAM,IAAI,aAAa,CAAC,6BAA6B,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import {\n startDiscordServer,\n type DiscordServerManifest,\n type StartedDiscordServer,\n type StartDiscordServerParams,\n} from \"./discord.js\";\nimport {\n startMattermostServer,\n type MattermostServerManifest,\n type StartedMattermostServer,\n type StartMattermostServerParams,\n} from \"./mattermost.js\";\nimport {\n startMatrixServer,\n type MatrixServerManifest,\n type StartedMatrixServer,\n type StartMatrixServerParams,\n} from \"./matrix.js\";\nimport {\n startSignalServer,\n type SignalServerManifest,\n type StartedSignalServer,\n type StartSignalServerParams,\n} from \"./signal.js\";\nimport {\n startSlackServer,\n type SlackServerManifest,\n type StartedSlackServer,\n type StartSlackServerParams,\n} from \"./slack.js\";\nimport {\n startTelegramServer,\n type StartedTelegramServer,\n type StartTelegramServerParams,\n type TelegramServerManifest,\n} from \"./telegram.js\";\nimport {\n startWhatsAppServer,\n type StartedWhatsAppServer,\n type StartWhatsAppServerParams,\n type WhatsAppServerManifest,\n} from \"./whatsapp.js\";\nimport {\n startZaloServer,\n type StartedZaloServer,\n type StartZaloServerParams,\n type ZaloServerManifest,\n} from \"./zalo.js\";\nimport { CrablineError } from \"../core/errors.js\";\n\nexport const CRABLINE_SERVER_CHANNELS = Object.freeze([\n \"discord\",\n \"mattermost\",\n \"matrix\",\n \"signal\",\n \"slack\",\n \"telegram\",\n \"whatsapp\",\n \"zalo\",\n] as const);\n\nexport type CrablineServerChannel = (typeof CRABLINE_SERVER_CHANNELS)[number];\n\nexport type CrablineServerManifest =\n | DiscordServerManifest\n | MattermostServerManifest\n | MatrixServerManifest\n | SignalServerManifest\n | SlackServerManifest\n | TelegramServerManifest\n | WhatsAppServerManifest\n | ZaloServerManifest;\n\nexport type StartedCrablineServer =\n | StartedDiscordServer\n | StartedMattermostServer\n | StartedMatrixServer\n | StartedSignalServer\n | StartedSlackServer\n | StartedTelegramServer\n | StartedWhatsAppServer\n | StartedZaloServer;\n\nexport type StartCrablineServerParams =\n | (StartDiscordServerParams & { channel: \"discord\" })\n | (StartMattermostServerParams & { channel: \"mattermost\" })\n | (StartMatrixServerParams & { channel: \"matrix\" })\n | (StartSignalServerParams & { channel: \"signal\" })\n | (StartSlackServerParams & { channel: \"slack\" })\n | (StartTelegramServerParams & { channel: \"telegram\" })\n | (StartWhatsAppServerParams & { channel: \"whatsapp\" })\n | (StartZaloServerParams & { channel: \"zalo\" });\n\nconst CRABLINE_SERVER_CHANNEL_SET = new Set<string>(CRABLINE_SERVER_CHANNELS);\n\nexport function isCrablineServerChannel(value: string): value is CrablineServerChannel {\n return CRABLINE_SERVER_CHANNEL_SET.has(value);\n}\n\nexport function startCrablineServer(\n params: StartDiscordServerParams & { channel: \"discord\" },\n): Promise<StartedDiscordServer>;\nexport function startCrablineServer(\n params: StartMattermostServerParams & { channel: \"mattermost\" },\n): Promise<StartedMattermostServer>;\nexport function startCrablineServer(\n params: StartMatrixServerParams & { channel: \"matrix\" },\n): Promise<StartedMatrixServer>;\nexport function startCrablineServer(\n params: StartSignalServerParams & { channel: \"signal\" },\n): Promise<StartedSignalServer>;\nexport function startCrablineServer(\n params: StartSlackServerParams & { channel: \"slack\" },\n): Promise<StartedSlackServer>;\nexport function startCrablineServer(\n params: StartTelegramServerParams & { channel: \"telegram\" },\n): Promise<StartedTelegramServer>;\nexport function startCrablineServer(\n params: StartWhatsAppServerParams & { channel: \"whatsapp\" },\n): Promise<StartedWhatsAppServer>;\nexport function startCrablineServer(\n params: StartZaloServerParams & { channel: \"zalo\" },\n): Promise<StartedZaloServer>;\nexport function startCrablineServer(\n params: StartCrablineServerParams,\n): Promise<StartedCrablineServer>;\nexport async function startCrablineServer(\n params: StartCrablineServerParams,\n): Promise<StartedCrablineServer> {\n switch (params.channel) {\n case \"discord\":\n return await startDiscordServer(params);\n case \"mattermost\":\n return await startMattermostServer(params);\n case \"matrix\":\n return await startMatrixServer(params);\n case \"signal\":\n return await startSignalServer(params);\n case \"slack\":\n return await startSlackServer(params);\n case \"telegram\":\n return await startTelegramServer(params);\n case \"whatsapp\":\n return await startWhatsAppServer(params);\n case \"zalo\":\n return await startZaloServer(params);\n default: {\n const unsupported: never = params;\n void unsupported;\n throw new CrablineError(\"Unsupported server channel.\", { kind: \"config\" });\n }\n }\n}\n"]}
@@ -29,6 +29,9 @@ export type StartMatrixServerParams = {
29
29
  botUserId?: string | undefined;
30
30
  deviceId?: string | undefined;
31
31
  host?: string | undefined;
32
+ maxCommittedRooms?: number | undefined;
33
+ maxCommittedUsers?: number | undefined;
34
+ maxSyncResponseBytes?: number | undefined;
32
35
  onEvent?: ServerEventObserver | undefined;
33
36
  port?: number | undefined;
34
37
  recorderPath?: string | undefined;