@pikku/core 0.12.2 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/crypto-utils.d.ts +10 -0
  3. package/dist/crypto-utils.js +62 -0
  4. package/dist/function/function-runner.js +4 -4
  5. package/dist/function/functions.types.d.ts +26 -1
  6. package/dist/function/functions.types.js +16 -0
  7. package/dist/handle-error.d.ts +1 -1
  8. package/dist/handle-error.js +7 -3
  9. package/dist/index.d.ts +14 -2
  10. package/dist/index.js +1 -1
  11. package/dist/pikku-state.js +3 -1
  12. package/dist/schema.js +1 -1
  13. package/dist/services/in-memory-workflow-service.d.ts +22 -3
  14. package/dist/services/in-memory-workflow-service.js +77 -1
  15. package/dist/services/workflow-service.d.ts +8 -2
  16. package/dist/testing/index.d.ts +2 -0
  17. package/dist/testing/index.js +1 -0
  18. package/dist/testing/service-tests.d.ts +31 -0
  19. package/dist/testing/service-tests.js +598 -0
  20. package/dist/types/core.types.d.ts +9 -1
  21. package/dist/types/state.types.d.ts +4 -2
  22. package/dist/utils/hash.d.ts +2 -0
  23. package/dist/utils/hash.js +23 -0
  24. package/dist/wirings/ai-agent/agent-dynamic-workflow.d.ts +6 -0
  25. package/dist/wirings/ai-agent/agent-dynamic-workflow.js +348 -0
  26. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +1 -1
  27. package/dist/wirings/ai-agent/ai-agent-memory.js +6 -5
  28. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -7
  29. package/dist/wirings/ai-agent/ai-agent-prepare.js +127 -47
  30. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +4 -0
  31. package/dist/wirings/ai-agent/ai-agent-runner.js +381 -27
  32. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +7 -2
  33. package/dist/wirings/ai-agent/ai-agent-stream.js +109 -46
  34. package/dist/wirings/ai-agent/ai-agent.types.d.ts +22 -1
  35. package/dist/wirings/ai-agent/index.d.ts +1 -2
  36. package/dist/wirings/ai-agent/index.js +1 -2
  37. package/dist/wirings/channel/channel-handler.js +5 -1
  38. package/dist/wirings/channel/channel.types.d.ts +1 -7
  39. package/dist/wirings/channel/local/local-channel-handler.d.ts +1 -1
  40. package/dist/wirings/channel/local/local-channel-handler.js +5 -3
  41. package/dist/wirings/channel/local/local-channel-runner.js +14 -4
  42. package/dist/wirings/channel/serverless/serverless-channel-runner.js +4 -1
  43. package/dist/wirings/cli/cli-runner.js +10 -2
  44. package/dist/wirings/cli/cli.types.d.ts +1 -0
  45. package/dist/wirings/http/http-routes.js +0 -1
  46. package/dist/wirings/http/http-runner.d.ts +1 -1
  47. package/dist/wirings/http/http-runner.js +25 -3
  48. package/dist/wirings/http/http.types.d.ts +3 -11
  49. package/dist/wirings/http/index.d.ts +2 -1
  50. package/dist/wirings/http/index.js +1 -0
  51. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
  52. package/dist/wirings/http/pikku-fetch-http-request.js +3 -0
  53. package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
  54. package/dist/wirings/http/pikku-fetch-http-response.js +4 -4
  55. package/dist/wirings/http/web-request.d.ts +12 -0
  56. package/dist/wirings/http/web-request.js +85 -0
  57. package/dist/wirings/mcp/mcp-endpoint-registry.js +1 -1
  58. package/dist/wirings/mcp/mcp-runner.js +13 -1
  59. package/dist/wirings/rpc/rpc-runner.d.ts +30 -6
  60. package/dist/wirings/rpc/rpc-runner.js +36 -14
  61. package/dist/wirings/rpc/rpc-types.d.ts +6 -1
  62. package/dist/wirings/rpc/wire-addon.d.ts +1 -0
  63. package/dist/wirings/rpc/wire-addon.js +1 -1
  64. package/dist/wirings/scheduler/scheduler-runner.js +1 -0
  65. package/dist/wirings/workflow/graph/graph-validation.d.ts +3 -0
  66. package/dist/wirings/workflow/graph/graph-validation.js +175 -0
  67. package/dist/wirings/workflow/graph/index.d.ts +1 -0
  68. package/dist/wirings/workflow/graph/index.js +1 -0
  69. package/dist/wirings/workflow/index.d.ts +1 -1
  70. package/dist/wirings/workflow/pikku-workflow-service.d.ts +8 -2
  71. package/dist/wirings/workflow/pikku-workflow-service.js +1 -2
  72. package/dist/wirings/workflow/workflow.types.d.ts +10 -1
  73. package/lcov.info +18891 -0
  74. package/package.json +4 -2
  75. package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +0 -5
  76. package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +0 -168
  77. package/src/crypto-utils.test.ts +0 -116
  78. package/src/crypto-utils.ts +0 -99
  79. package/src/errors/error-handler.ts +0 -62
  80. package/src/errors/error.test.ts +0 -195
  81. package/src/errors/errors.ts +0 -374
  82. package/src/errors/index.ts +0 -2
  83. package/src/factory-functions.test.ts +0 -109
  84. package/src/function/function-runner.test.ts +0 -536
  85. package/src/function/function-runner.ts +0 -365
  86. package/src/function/functions.types.ts +0 -267
  87. package/src/function/index.ts +0 -5
  88. package/src/handle-error.test.ts +0 -361
  89. package/src/handle-error.ts +0 -65
  90. package/src/index.ts +0 -104
  91. package/src/internal.ts +0 -6
  92. package/src/middleware/auth-apikey.test.ts +0 -363
  93. package/src/middleware/auth-apikey.ts +0 -47
  94. package/src/middleware/auth-bearer.test.ts +0 -450
  95. package/src/middleware/auth-bearer.ts +0 -72
  96. package/src/middleware/auth-cookie.test.ts +0 -528
  97. package/src/middleware/auth-cookie.ts +0 -80
  98. package/src/middleware/cors.test.ts +0 -424
  99. package/src/middleware/cors.ts +0 -104
  100. package/src/middleware/index.ts +0 -5
  101. package/src/middleware/remote-auth.test.ts +0 -488
  102. package/src/middleware/remote-auth.ts +0 -68
  103. package/src/middleware/timeout.ts +0 -15
  104. package/src/middleware-runner.test.ts +0 -418
  105. package/src/middleware-runner.ts +0 -234
  106. package/src/permissions.test.ts +0 -434
  107. package/src/permissions.ts +0 -319
  108. package/src/pikku-request.ts +0 -23
  109. package/src/pikku-response.ts +0 -5
  110. package/src/pikku-state.test.ts +0 -224
  111. package/src/pikku-state.ts +0 -214
  112. package/src/run-tests-script.test.ts +0 -49
  113. package/src/schema.test.ts +0 -249
  114. package/src/schema.ts +0 -151
  115. package/src/services/ai-agent-runner-service.ts +0 -41
  116. package/src/services/ai-run-state-service.ts +0 -20
  117. package/src/services/ai-storage-service.ts +0 -39
  118. package/src/services/content-service.ts +0 -76
  119. package/src/services/deployment-service.ts +0 -22
  120. package/src/services/gateway-service.ts +0 -20
  121. package/src/services/gopass-secrets.ts +0 -98
  122. package/src/services/in-memory-ai-run-state-service.ts +0 -73
  123. package/src/services/in-memory-trigger-service.ts +0 -64
  124. package/src/services/in-memory-workflow-service.test.ts +0 -351
  125. package/src/services/in-memory-workflow-service.ts +0 -395
  126. package/src/services/index.ts +0 -56
  127. package/src/services/jwt-service.ts +0 -30
  128. package/src/services/local-content.ts +0 -120
  129. package/src/services/local-gateway-service.ts +0 -62
  130. package/src/services/local-secrets.test.ts +0 -80
  131. package/src/services/local-secrets.ts +0 -94
  132. package/src/services/local-variables.test.ts +0 -61
  133. package/src/services/local-variables.ts +0 -39
  134. package/src/services/logger-console.test.ts +0 -118
  135. package/src/services/logger-console.ts +0 -98
  136. package/src/services/logger.ts +0 -57
  137. package/src/services/scheduler-service.ts +0 -86
  138. package/src/services/schema-service.ts +0 -33
  139. package/src/services/scoped-secret-service.test.ts +0 -74
  140. package/src/services/scoped-secret-service.ts +0 -41
  141. package/src/services/secret-service.ts +0 -38
  142. package/src/services/trigger-service.ts +0 -17
  143. package/src/services/typed-secret-service.test.ts +0 -93
  144. package/src/services/typed-secret-service.ts +0 -70
  145. package/src/services/typed-variables-service.test.ts +0 -73
  146. package/src/services/typed-variables-service.ts +0 -81
  147. package/src/services/user-session-service.test.ts +0 -113
  148. package/src/services/user-session-service.ts +0 -86
  149. package/src/services/variables-service.ts +0 -11
  150. package/src/services/workflow-service.ts +0 -84
  151. package/src/time-utils.test.ts +0 -56
  152. package/src/time-utils.ts +0 -107
  153. package/src/types/core.types.ts +0 -470
  154. package/src/types/state.types.ts +0 -186
  155. package/src/utils.test.ts +0 -350
  156. package/src/utils.ts +0 -129
  157. package/src/version.test.ts +0 -80
  158. package/src/version.ts +0 -25
  159. package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +0 -363
  160. package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +0 -238
  161. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +0 -152
  162. package/src/wirings/ai-agent/ai-agent-helpers.ts +0 -76
  163. package/src/wirings/ai-agent/ai-agent-memory.ts +0 -309
  164. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +0 -115
  165. package/src/wirings/ai-agent/ai-agent-model-config.ts +0 -43
  166. package/src/wirings/ai-agent/ai-agent-prepare.ts +0 -522
  167. package/src/wirings/ai-agent/ai-agent-registry.test.ts +0 -37
  168. package/src/wirings/ai-agent/ai-agent-registry.ts +0 -82
  169. package/src/wirings/ai-agent/ai-agent-runner.test.ts +0 -317
  170. package/src/wirings/ai-agent/ai-agent-runner.ts +0 -251
  171. package/src/wirings/ai-agent/ai-agent-stream.test.ts +0 -652
  172. package/src/wirings/ai-agent/ai-agent-stream.ts +0 -1060
  173. package/src/wirings/ai-agent/ai-agent.types.ts +0 -360
  174. package/src/wirings/ai-agent/index.ts +0 -41
  175. package/src/wirings/channel/channel-common.ts +0 -90
  176. package/src/wirings/channel/channel-handler.ts +0 -241
  177. package/src/wirings/channel/channel-middleware-runner.ts +0 -120
  178. package/src/wirings/channel/channel-runner.ts +0 -166
  179. package/src/wirings/channel/channel-store.ts +0 -29
  180. package/src/wirings/channel/channel.types.ts +0 -178
  181. package/src/wirings/channel/define-channel-routes.ts +0 -25
  182. package/src/wirings/channel/eventhub-service.ts +0 -34
  183. package/src/wirings/channel/eventhub-store.ts +0 -13
  184. package/src/wirings/channel/index.ts +0 -24
  185. package/src/wirings/channel/local/index.ts +0 -3
  186. package/src/wirings/channel/local/local-channel-handler.ts +0 -79
  187. package/src/wirings/channel/local/local-channel-runner.test.ts +0 -215
  188. package/src/wirings/channel/local/local-channel-runner.ts +0 -200
  189. package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -95
  190. package/src/wirings/channel/local/local-eventhub-service.ts +0 -101
  191. package/src/wirings/channel/log-channels.ts +0 -20
  192. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -54
  193. package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -45
  194. package/src/wirings/channel/serverless/index.ts +0 -5
  195. package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -286
  196. package/src/wirings/cli/channel/cli-channel-runner.ts +0 -136
  197. package/src/wirings/cli/channel/index.ts +0 -1
  198. package/src/wirings/cli/cli-runner.test.ts +0 -403
  199. package/src/wirings/cli/cli-runner.ts +0 -519
  200. package/src/wirings/cli/cli.types.ts +0 -357
  201. package/src/wirings/cli/command-parser.test.ts +0 -445
  202. package/src/wirings/cli/command-parser.ts +0 -504
  203. package/src/wirings/cli/define-cli-commands.ts +0 -24
  204. package/src/wirings/cli/index.ts +0 -19
  205. package/src/wirings/gateway/gateway-runner.test.ts +0 -474
  206. package/src/wirings/gateway/gateway-runner.ts +0 -411
  207. package/src/wirings/gateway/gateway.types.ts +0 -149
  208. package/src/wirings/gateway/index.ts +0 -13
  209. package/src/wirings/http/http-routes.test.ts +0 -322
  210. package/src/wirings/http/http-routes.ts +0 -198
  211. package/src/wirings/http/http-runner.test.ts +0 -144
  212. package/src/wirings/http/http-runner.ts +0 -563
  213. package/src/wirings/http/http.types.ts +0 -378
  214. package/src/wirings/http/index.ts +0 -25
  215. package/src/wirings/http/log-http-routes.ts +0 -22
  216. package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -237
  217. package/src/wirings/http/pikku-fetch-http-request.ts +0 -166
  218. package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -82
  219. package/src/wirings/http/pikku-fetch-http-response.ts +0 -147
  220. package/src/wirings/http/routers/http-router.ts +0 -13
  221. package/src/wirings/http/routers/path-to-regex.test.ts +0 -319
  222. package/src/wirings/http/routers/path-to-regex.ts +0 -126
  223. package/src/wirings/mcp/index.ts +0 -27
  224. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -389
  225. package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
  226. package/src/wirings/mcp/mcp-runner.ts +0 -305
  227. package/src/wirings/mcp/mcp.types.ts +0 -216
  228. package/src/wirings/node/index.ts +0 -2
  229. package/src/wirings/node/node.types.ts +0 -23
  230. package/src/wirings/oauth2/index.ts +0 -3
  231. package/src/wirings/oauth2/oauth2-client.test.ts +0 -929
  232. package/src/wirings/oauth2/oauth2-client.ts +0 -335
  233. package/src/wirings/oauth2/oauth2.types.ts +0 -69
  234. package/src/wirings/oauth2/wire-oauth2-credential.ts +0 -23
  235. package/src/wirings/queue/index.ts +0 -31
  236. package/src/wirings/queue/queue-runner.test.ts +0 -710
  237. package/src/wirings/queue/queue-runner.ts +0 -192
  238. package/src/wirings/queue/queue.types.ts +0 -189
  239. package/src/wirings/queue/register-queue-helper.ts +0 -60
  240. package/src/wirings/queue/validate-worker-config.test.ts +0 -108
  241. package/src/wirings/queue/validate-worker-config.ts +0 -116
  242. package/src/wirings/rpc/index.ts +0 -4
  243. package/src/wirings/rpc/rpc-runner.ts +0 -439
  244. package/src/wirings/rpc/rpc-types.ts +0 -51
  245. package/src/wirings/rpc/wire-addon.ts +0 -20
  246. package/src/wirings/scheduler/index.ts +0 -11
  247. package/src/wirings/scheduler/log-schedulers.ts +0 -20
  248. package/src/wirings/scheduler/scheduler-runner.test.ts +0 -660
  249. package/src/wirings/scheduler/scheduler-runner.ts +0 -132
  250. package/src/wirings/scheduler/scheduler.types.ts +0 -53
  251. package/src/wirings/secret/index.ts +0 -9
  252. package/src/wirings/secret/secret.types.ts +0 -32
  253. package/src/wirings/secret/validate-secret-definitions.test.ts +0 -140
  254. package/src/wirings/secret/validate-secret-definitions.ts +0 -82
  255. package/src/wirings/trigger/index.ts +0 -10
  256. package/src/wirings/trigger/pikku-trigger-service.ts +0 -112
  257. package/src/wirings/trigger/trigger-runner.test.ts +0 -79
  258. package/src/wirings/trigger/trigger-runner.ts +0 -135
  259. package/src/wirings/trigger/trigger.types.ts +0 -178
  260. package/src/wirings/variable/index.ts +0 -8
  261. package/src/wirings/variable/validate-variable-definitions.test.ts +0 -91
  262. package/src/wirings/variable/validate-variable-definitions.ts +0 -69
  263. package/src/wirings/variable/variable.types.ts +0 -22
  264. package/src/wirings/workflow/dsl/index.ts +0 -31
  265. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -320
  266. package/src/wirings/workflow/dsl/workflow-runner.ts +0 -28
  267. package/src/wirings/workflow/graph/graph-node.ts +0 -222
  268. package/src/wirings/workflow/graph/graph-runner.test.ts +0 -487
  269. package/src/wirings/workflow/graph/graph-runner.ts +0 -816
  270. package/src/wirings/workflow/graph/index.ts +0 -14
  271. package/src/wirings/workflow/graph/template.test.ts +0 -49
  272. package/src/wirings/workflow/graph/template.ts +0 -42
  273. package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -29
  274. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -104
  275. package/src/wirings/workflow/index.ts +0 -81
  276. package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -200
  277. package/src/wirings/workflow/pikku-workflow-service.ts +0 -1165
  278. package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
  279. package/src/wirings/workflow/workflow-helpers.ts +0 -79
  280. package/src/wirings/workflow/workflow.types.ts +0 -266
  281. package/tsconfig.json +0 -14
  282. package/tsconfig.tsbuildinfo +0 -1
@@ -1,474 +0,0 @@
1
- import { test, describe, beforeEach } from 'node:test'
2
- import * as assert from 'assert'
3
- import { wireGateway, createListenerMessageHandler } from './gateway-runner.js'
4
- import { pikkuState, resetPikkuState } from '../../pikku-state.js'
5
- import { httpRouter } from '../http/routers/http-router.js'
6
- import { fetch } from '../http/http-runner.js'
7
- import type {
8
- GatewayAdapter,
9
- GatewayInboundMessage,
10
- GatewayOutboundMessage,
11
- } from './gateway.types.js'
12
- import type { CorePikkuMiddleware } from '../../types/core.types.js'
13
-
14
- // --- Mock adapter ----------------------------------------------------------
15
-
16
- const createMockAdapter = (
17
- opts: {
18
- name?: string
19
- parseResult?: GatewayInboundMessage | null
20
- verifyResult?: { verified: true; response: unknown } | { verified: false }
21
- } = {}
22
- ): GatewayAdapter & {
23
- sentMessages: Array<{ senderId: string; message: GatewayOutboundMessage }>
24
- simulateMessage: (data: unknown) => Promise<void>
25
- } => {
26
- const sentMessages: Array<{
27
- senderId: string
28
- message: GatewayOutboundMessage
29
- }> = []
30
-
31
- let onMessage: ((data: unknown) => Promise<void>) | undefined
32
-
33
- return {
34
- name: opts.name ?? 'mock',
35
- sentMessages,
36
- parse(data: unknown): GatewayInboundMessage | null {
37
- if (opts.parseResult !== undefined) return opts.parseResult
38
- const d = data as Record<string, any>
39
- if (!d?.text) return null
40
- return {
41
- senderId: d.senderId ?? 'sender-1',
42
- text: d.text,
43
- raw: data,
44
- }
45
- },
46
- send: async (senderId, message) => {
47
- sentMessages.push({ senderId, message })
48
- },
49
- init: async (cb) => {
50
- onMessage = cb
51
- },
52
- close: async () => {
53
- onMessage = undefined
54
- },
55
- async simulateMessage(data: unknown) {
56
- if (onMessage) await onMessage(data)
57
- },
58
- ...(opts.verifyResult
59
- ? {
60
- verifyWebhook: () => opts.verifyResult!,
61
- }
62
- : {}),
63
- }
64
- }
65
-
66
- // --- Test helpers -----------------------------------------------------------
67
-
68
- const setupState = () => {
69
- resetPikkuState()
70
- httpRouter.reset()
71
-
72
- const singletonServices = {
73
- config: {},
74
- logger: {
75
- info: () => {},
76
- warn: () => {},
77
- error: () => {},
78
- },
79
- variables: {},
80
- secrets: {},
81
- }
82
-
83
- pikkuState(null, 'package', 'singletonServices', singletonServices as any)
84
- pikkuState(null, 'package', 'factories', {
85
- createWireServices: async () => ({}),
86
- } as any)
87
- }
88
-
89
- // --- Tests ------------------------------------------------------------------
90
-
91
- describe('wireGateway', () => {
92
- beforeEach(() => {
93
- setupState()
94
- })
95
-
96
- describe('type: webhook', () => {
97
- test('registers POST route and processes messages', async () => {
98
- const adapter = createMockAdapter()
99
- const funcCalls: any[] = []
100
-
101
- wireGateway({
102
- name: 'test-webhook',
103
- type: 'webhook',
104
- route: '/webhooks/test',
105
- adapter,
106
- func: {
107
- func: async (_services: any, data: any, wire: any) => {
108
- funcCalls.push({ data, gateway: wire.gateway })
109
- return { text: 'reply' }
110
- },
111
- },
112
- })
113
-
114
- httpRouter.initialize()
115
-
116
- const request = new Request('http://localhost/webhooks/test', {
117
- method: 'POST',
118
- headers: { 'Content-Type': 'application/json' },
119
- body: JSON.stringify({ senderId: 'user-1', text: 'hello' }),
120
- })
121
-
122
- const response = await fetch(request)
123
- assert.equal(response.status, 200)
124
-
125
- // Verify func was called with parsed message
126
- assert.equal(funcCalls.length, 1)
127
- assert.equal(funcCalls[0].data.senderId, 'user-1')
128
- assert.equal(funcCalls[0].data.text, 'hello')
129
-
130
- // Verify wire.gateway was populated
131
- assert.equal(funcCalls[0].gateway.gatewayName, 'test-webhook')
132
- assert.equal(funcCalls[0].gateway.senderId, 'user-1')
133
- assert.equal(funcCalls[0].gateway.platform, 'mock')
134
- assert.equal(typeof funcCalls[0].gateway.send, 'function')
135
-
136
- // Verify auto-send of response
137
- assert.equal(adapter.sentMessages.length, 1)
138
- assert.equal(adapter.sentMessages[0].senderId, 'user-1')
139
- assert.equal(adapter.sentMessages[0].message.text, 'reply')
140
- })
141
-
142
- test('returns 200 OK for ignored events (adapter returns null)', async () => {
143
- const adapter = createMockAdapter({ parseResult: null })
144
- const funcCalls: any[] = []
145
-
146
- wireGateway({
147
- name: 'test-ignore',
148
- type: 'webhook',
149
- route: '/webhooks/ignore',
150
- adapter,
151
- func: {
152
- func: async () => {
153
- funcCalls.push(true)
154
- },
155
- },
156
- })
157
-
158
- httpRouter.initialize()
159
-
160
- const request = new Request('http://localhost/webhooks/ignore', {
161
- method: 'POST',
162
- headers: { 'Content-Type': 'application/json' },
163
- body: JSON.stringify({ type: 'delivery_receipt' }),
164
- })
165
-
166
- const response = await fetch(request)
167
- assert.equal(response.status, 200)
168
-
169
- // Func should NOT be called
170
- assert.equal(funcCalls.length, 0)
171
- })
172
-
173
- test('runs middleware before func with wire.gateway available', async () => {
174
- const adapter = createMockAdapter()
175
- const middlewareCalls: any[] = []
176
-
177
- const testMiddleware: CorePikkuMiddleware = async (
178
- _services,
179
- wire,
180
- next
181
- ) => {
182
- middlewareCalls.push({
183
- gateway: (wire as any).gateway,
184
- hasSession: !!wire.session,
185
- })
186
- wire.setSession?.({ userId: 'resolved-user' } as any)
187
- await next()
188
- }
189
-
190
- wireGateway({
191
- name: 'test-middleware',
192
- type: 'webhook',
193
- route: '/webhooks/mw',
194
- adapter,
195
- middleware: [testMiddleware],
196
- func: {
197
- func: async (_services: any, _data: any, wire: any) => {
198
- return { text: `hello ${wire.session?.userId ?? 'unknown'}` }
199
- },
200
- },
201
- })
202
-
203
- httpRouter.initialize()
204
-
205
- const request = new Request('http://localhost/webhooks/mw', {
206
- method: 'POST',
207
- headers: { 'Content-Type': 'application/json' },
208
- body: JSON.stringify({ senderId: 'user-2', text: 'hi' }),
209
- })
210
-
211
- await fetch(request)
212
-
213
- // Middleware should have run
214
- assert.equal(middlewareCalls.length, 1)
215
- // Middleware should see wire.gateway
216
- assert.equal(middlewareCalls[0].gateway.senderId, 'user-2')
217
- assert.equal(middlewareCalls[0].gateway.platform, 'mock')
218
- })
219
-
220
- test('handles webhook verification via GET', async () => {
221
- const adapter = createMockAdapter({
222
- verifyResult: { verified: true, response: 'challenge-token-123' },
223
- })
224
-
225
- wireGateway({
226
- name: 'test-verify',
227
- type: 'webhook',
228
- route: '/webhooks/verify',
229
- adapter,
230
- func: { func: async () => {} },
231
- })
232
-
233
- httpRouter.initialize()
234
-
235
- const request = new Request(
236
- 'http://localhost/webhooks/verify?hub.mode=subscribe&hub.verify_token=tok&hub.challenge=challenge-token-123',
237
- { method: 'GET' }
238
- )
239
-
240
- const response = await fetch(request)
241
- assert.equal(response.status, 200)
242
-
243
- const body = await response.json()
244
- assert.equal(body, 'challenge-token-123')
245
- })
246
-
247
- test('handles POST-based verification (Slack style)', async () => {
248
- const adapter = createMockAdapter({
249
- parseResult: null,
250
- verifyResult: {
251
- verified: true,
252
- response: { challenge: 'abc123' },
253
- },
254
- })
255
-
256
- wireGateway({
257
- name: 'test-slack-verify',
258
- type: 'webhook',
259
- route: '/webhooks/slack',
260
- adapter,
261
- func: { func: async () => {} },
262
- })
263
-
264
- httpRouter.initialize()
265
-
266
- const request = new Request('http://localhost/webhooks/slack', {
267
- method: 'POST',
268
- headers: { 'Content-Type': 'application/json' },
269
- body: JSON.stringify({
270
- type: 'url_verification',
271
- challenge: 'abc123',
272
- }),
273
- })
274
-
275
- const response = await fetch(request)
276
- assert.equal(response.status, 200)
277
-
278
- const body = await response.json()
279
- assert.deepEqual(body, { challenge: 'abc123' })
280
- })
281
-
282
- test('wire.gateway.send() sends proactive messages', async () => {
283
- const adapter = createMockAdapter()
284
- let capturedGateway: any
285
-
286
- wireGateway({
287
- name: 'test-proactive',
288
- type: 'webhook',
289
- route: '/webhooks/proactive',
290
- adapter,
291
- func: {
292
- func: async (_services: any, _data: any, wire: any) => {
293
- capturedGateway = wire.gateway
294
- // Send a proactive message via gateway
295
- await wire.gateway.send({ text: 'proactive msg' })
296
- // Don't return a response (no auto-send)
297
- },
298
- },
299
- })
300
-
301
- httpRouter.initialize()
302
-
303
- const request = new Request('http://localhost/webhooks/proactive', {
304
- method: 'POST',
305
- headers: { 'Content-Type': 'application/json' },
306
- body: JSON.stringify({ senderId: 'user-3', text: 'trigger' }),
307
- })
308
-
309
- await fetch(request)
310
-
311
- // Proactive message was sent
312
- assert.equal(adapter.sentMessages.length, 1)
313
- assert.equal(adapter.sentMessages[0].message.text, 'proactive msg')
314
- })
315
- })
316
-
317
- describe('type: webhook errors', () => {
318
- test('throws if no route provided for webhook', () => {
319
- const adapter = createMockAdapter()
320
-
321
- assert.throws(
322
- () =>
323
- wireGateway({
324
- name: 'no-route',
325
- type: 'webhook',
326
- adapter,
327
- func: { func: async () => {} },
328
- }),
329
- /requires a route/
330
- )
331
- })
332
- })
333
-
334
- describe('type: listener', () => {
335
- test('stores gateway config in pikkuState', () => {
336
- const adapter = createMockAdapter()
337
-
338
- wireGateway({
339
- name: 'test-listener',
340
- type: 'listener',
341
- adapter,
342
- func: { func: async () => {} },
343
- })
344
-
345
- const gateways = pikkuState(null, 'gateway', 'gateways')
346
- assert.ok(gateways.has('test-listener'))
347
- assert.equal(gateways.get('test-listener').type, 'listener')
348
- })
349
- })
350
-
351
- describe('createListenerMessageHandler', () => {
352
- test('creates handler that processes messages', async () => {
353
- const adapter = createMockAdapter()
354
- const funcCalls: any[] = []
355
-
356
- const config = {
357
- name: 'test-listener',
358
- type: 'listener' as const,
359
- adapter,
360
- func: {
361
- func: async (_services: any, data: any, wire: any) => {
362
- funcCalls.push({ data, gateway: wire.gateway })
363
- return { text: 'listener-reply' }
364
- },
365
- },
366
- }
367
-
368
- wireGateway(config)
369
-
370
- const singletonServices = pikkuState(null, 'package', 'singletonServices')
371
- const handleMessage = createListenerMessageHandler(
372
- 'test-listener',
373
- config,
374
- singletonServices
375
- )
376
-
377
- // Simulate incoming message
378
- await handleMessage({
379
- senderId: 'listener-user',
380
- text: 'hello from listener',
381
- })
382
-
383
- assert.equal(funcCalls.length, 1)
384
- assert.equal(funcCalls[0].data.senderId, 'listener-user')
385
- assert.equal(funcCalls[0].data.text, 'hello from listener')
386
- assert.equal(funcCalls[0].gateway.platform, 'mock')
387
-
388
- // Auto-send response
389
- assert.equal(adapter.sentMessages.length, 1)
390
- assert.equal(adapter.sentMessages[0].message.text, 'listener-reply')
391
- })
392
-
393
- test('handler ignores events when adapter returns null', async () => {
394
- const adapter = createMockAdapter({ parseResult: null })
395
- const funcCalls: any[] = []
396
-
397
- const config = {
398
- name: 'test-listener-ignore',
399
- type: 'listener' as const,
400
- adapter,
401
- func: {
402
- func: async () => {
403
- funcCalls.push(true)
404
- },
405
- },
406
- }
407
-
408
- wireGateway(config)
409
-
410
- const singletonServices = pikkuState(null, 'package', 'singletonServices')
411
- const handleMessage = createListenerMessageHandler(
412
- 'test-listener-ignore',
413
- config,
414
- singletonServices
415
- )
416
-
417
- await handleMessage({ type: 'delivery_receipt' })
418
-
419
- assert.equal(funcCalls.length, 0)
420
- })
421
- })
422
-
423
- describe('gateway: true metadata flag', () => {
424
- test('webhook gateway adds gateway meta to pikkuState', () => {
425
- const adapter = createMockAdapter()
426
-
427
- wireGateway({
428
- name: 'test-meta',
429
- type: 'webhook',
430
- route: '/webhooks/meta',
431
- adapter,
432
- func: { func: async () => {} },
433
- })
434
-
435
- const gateways = pikkuState(null, 'gateway', 'gateways')
436
- const config = gateways.get('test-meta')
437
- assert.ok(config)
438
- assert.equal(config.type, 'webhook')
439
- assert.equal(config.name, 'test-meta')
440
- })
441
- })
442
-
443
- describe('type: websocket', () => {
444
- test('registers channel config', () => {
445
- const adapter = createMockAdapter()
446
-
447
- wireGateway({
448
- name: 'test-ws',
449
- type: 'websocket',
450
- route: '/gateway/ws',
451
- adapter,
452
- func: { func: async () => {} },
453
- })
454
-
455
- const channels = pikkuState(null, 'channel', 'channels')
456
- assert.ok(channels.has('test-ws'))
457
- })
458
-
459
- test('throws if no route provided', () => {
460
- const adapter = createMockAdapter()
461
-
462
- assert.throws(
463
- () =>
464
- wireGateway({
465
- name: 'no-route-ws',
466
- type: 'websocket',
467
- adapter,
468
- func: { func: async () => {} },
469
- }),
470
- /requires a route/
471
- )
472
- })
473
- })
474
- })