@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,411 +0,0 @@
1
- import { pikkuState } from '../../pikku-state.js'
2
- import { addFunction } from '../../function/function-runner.js'
3
- import { runMiddleware } from '../../middleware-runner.js'
4
- import { httpRouter } from '../http/routers/http-router.js'
5
- import type {
6
- CoreGateway,
7
- GatewayAdapter,
8
- GatewayOutboundMessage,
9
- PikkuGateway,
10
- } from './gateway.types.js'
11
- import type {
12
- PikkuWire,
13
- CorePikkuMiddleware,
14
- CoreSingletonServices,
15
- } from '../../types/core.types.js'
16
- import type { HTTPWiringMeta } from '../http/http.types.js'
17
-
18
- /**
19
- * Register a messaging gateway.
20
- *
21
- * `wireGateway` is a meta-wiring that composes existing primitives
22
- * (`wireHTTP`, `wireChannel`) under the hood. It does not replace them;
23
- * it layers on top.
24
- *
25
- * @param config - Gateway configuration (name, type, adapter, func, middleware, etc.)
26
- */
27
- export const wireGateway = (config: CoreGateway): void => {
28
- // Store gateway config
29
- pikkuState(null, 'gateway', 'gateways').set(config.name, config)
30
-
31
- switch (config.type) {
32
- case 'webhook':
33
- wireWebhookGateway(config)
34
- break
35
- case 'websocket':
36
- wireWebsocketGateway(config)
37
- break
38
- case 'listener':
39
- wireListenerGateway(config)
40
- break
41
- default:
42
- throw new Error(
43
- `Unknown gateway type '${(config as any).type}' for gateway '${config.name}'`
44
- )
45
- }
46
- }
47
-
48
- // ---------------------------------------------------------------------------
49
- // Webhook gateway — platform POSTs to us
50
- // ---------------------------------------------------------------------------
51
-
52
- const wireWebhookGateway = (config: CoreGateway): void => {
53
- const { name, route, adapter } = config
54
- if (!route) {
55
- throw new Error(`Webhook gateway '${name}' requires a route`)
56
- }
57
-
58
- const postFuncId = `gateway__${name}__post`
59
- const httpMeta = pikkuState(null, 'http', 'meta')
60
- const funcMeta = pikkuState(null, 'function', 'meta')
61
- const routes = pikkuState(null, 'http', 'routes')
62
-
63
- // --- POST handler (main message receiver) --------------------------------
64
-
65
- funcMeta[postFuncId] = {
66
- pikkuFuncId: postFuncId,
67
- inputSchemaName: null,
68
- outputSchemaName: null,
69
- sessionless: true,
70
- }
71
-
72
- httpMeta['post'][route] = {
73
- pikkuFuncId: postFuncId,
74
- route,
75
- method: 'post',
76
- } as HTTPWiringMeta
77
-
78
- const postHandler = {
79
- auth: false,
80
- func: createWebhookPostHandler(config),
81
- }
82
-
83
- addFunction(postFuncId, postHandler as any)
84
-
85
- if (!routes.has('post')) {
86
- routes.set('post', new Map())
87
- }
88
- routes.get('post')!.set(route, {
89
- method: 'post',
90
- route,
91
- func: postHandler,
92
- auth: false,
93
- } as any)
94
-
95
- // --- GET handler (webhook verification, e.g. WhatsApp challenge) ---------
96
-
97
- if (adapter.verifyWebhook) {
98
- const verifyFuncId = `gateway__${name}__verify`
99
-
100
- funcMeta[verifyFuncId] = {
101
- pikkuFuncId: verifyFuncId,
102
- inputSchemaName: null,
103
- outputSchemaName: null,
104
- sessionless: true,
105
- }
106
-
107
- httpMeta['get'][route] = {
108
- pikkuFuncId: verifyFuncId,
109
- route,
110
- method: 'get',
111
- } as HTTPWiringMeta
112
-
113
- const verifyHandler = {
114
- auth: false,
115
- func: createWebhookVerifyHandler(adapter),
116
- }
117
-
118
- addFunction(verifyFuncId, verifyHandler as any)
119
-
120
- if (!routes.has('get')) {
121
- routes.set('get', new Map())
122
- }
123
- routes.get('get')!.set(route, {
124
- method: 'get',
125
- route,
126
- func: verifyHandler,
127
- auth: false,
128
- } as any)
129
- }
130
-
131
- // Force router to re-initialize on next match
132
- httpRouter.reset()
133
- }
134
-
135
- /**
136
- * Creates the POST handler function for a webhook gateway.
137
- *
138
- * Flow:
139
- * 1. Check for POST-based verification (e.g. Slack `url_verification`)
140
- * 2. Parse body via adapter → GatewayInboundMessage (or null to ignore)
141
- * 3. Populate `wire.gateway`
142
- * 4. Run user middleware (which can read `wire.gateway` for auth)
143
- * 5. Call user func with parsed message
144
- * 6. Auto-send response via adapter if func returns outbound content
145
- */
146
- const createWebhookPostHandler = (config: CoreGateway) => {
147
- const { name, adapter, func: userFunc, middleware: userMiddleware } = config
148
- const userFuncConfig = userFunc as {
149
- func: Function
150
- middleware?: CorePikkuMiddleware[]
151
- }
152
-
153
- return async (
154
- services: CoreSingletonServices,
155
- data: unknown,
156
- wire: PikkuWire
157
- ) => {
158
- // Check for POST-based webhook verification (e.g. Slack url_verification)
159
- if (adapter.verifyWebhook) {
160
- const verifyResult = await adapter.verifyWebhook(data, wire.http?.request)
161
- if (verifyResult.verified) {
162
- return verifyResult.response
163
- }
164
- }
165
-
166
- // Parse the platform-specific payload
167
- const parsed = adapter.parse(data)
168
- if (!parsed) {
169
- // Ignored event (delivery receipt, typing indicator, etc.)
170
- return { ok: true }
171
- }
172
-
173
- // Populate wire.gateway
174
- const gateway: PikkuGateway = {
175
- gatewayName: name,
176
- senderId: parsed.senderId,
177
- platform: adapter.name,
178
- send: (msg: GatewayOutboundMessage) => adapter.send(parsed.senderId, msg),
179
- }
180
- ;(wire as any).gateway = gateway
181
-
182
- // Build combined middleware chain: gateway-level + func-level
183
- const allMiddleware: CorePikkuMiddleware[] = [
184
- ...((userMiddleware as CorePikkuMiddleware[] | undefined) || []),
185
- ...(userFuncConfig.middleware || []),
186
- ]
187
-
188
- const exec = async () => {
189
- const result = await userFuncConfig.func(services, parsed, wire)
190
- // Auto-send response if the func returns outbound content
191
- if (result && (result.text || result.richContent || result.attachments)) {
192
- await adapter.send(parsed.senderId, result as GatewayOutboundMessage)
193
- }
194
- return { ok: true }
195
- }
196
-
197
- if (allMiddleware.length > 0) {
198
- return await runMiddleware(services, wire, allMiddleware, exec)
199
- }
200
-
201
- return await exec()
202
- }
203
- }
204
-
205
- /**
206
- * Creates the GET handler for webhook verification challenges.
207
- * Passes query parameters to the adapter's verifyWebhook method.
208
- */
209
- const createWebhookVerifyHandler = (adapter: GatewayAdapter) => {
210
- return async (
211
- _services: CoreSingletonServices,
212
- _data: unknown,
213
- wire: PikkuWire
214
- ) => {
215
- if (!adapter.verifyWebhook) {
216
- return { error: 'Verification not supported' }
217
- }
218
-
219
- const query = wire.http?.request?.query()
220
- const result = await adapter.verifyWebhook(query, wire.http?.request)
221
- if (result.verified) {
222
- return result.response
223
- }
224
-
225
- return { error: 'Verification failed' }
226
- }
227
- }
228
-
229
- // ---------------------------------------------------------------------------
230
- // WebSocket gateway — client connects via WebSocket
231
- // ---------------------------------------------------------------------------
232
-
233
- const wireWebsocketGateway = (config: CoreGateway): void => {
234
- const { name, route, adapter } = config
235
- if (!route) {
236
- throw new Error(`WebSocket gateway '${name}' requires a route`)
237
- }
238
-
239
- // Store gateway config — the channel runner will reference this
240
- pikkuState(null, 'gateway', 'gateways').set(config.name, config)
241
-
242
- const channelsMeta = pikkuState(null, 'channel', 'meta')
243
- const channels = pikkuState(null, 'channel', 'channels')
244
-
245
- const messageFuncId = `gateway__${name}__message`
246
- const connectFuncId = `gateway__${name}__connect`
247
-
248
- // Add function metadata
249
- const funcMeta = pikkuState(null, 'function', 'meta')
250
- funcMeta[messageFuncId] = {
251
- pikkuFuncId: messageFuncId,
252
- inputSchemaName: null,
253
- outputSchemaName: null,
254
- sessionless: true,
255
- }
256
- funcMeta[connectFuncId] = {
257
- pikkuFuncId: connectFuncId,
258
- inputSchemaName: null,
259
- outputSchemaName: null,
260
- sessionless: true,
261
- }
262
-
263
- // Add channel metadata
264
- channelsMeta[name] = {
265
- name,
266
- route,
267
- gateway: true,
268
- connect: { pikkuFuncId: connectFuncId },
269
- message: { pikkuFuncId: messageFuncId },
270
- } as any
271
-
272
- const userFuncConfig = config.func as {
273
- func: Function
274
- middleware?: CorePikkuMiddleware[]
275
- }
276
- const userMiddleware = config.middleware as CorePikkuMiddleware[] | undefined
277
-
278
- // Register onConnect
279
- addFunction(connectFuncId, {
280
- auth: false,
281
- func: async (_services: any, _data: unknown, wire: PikkuWire) => {
282
- ;(wire as any).gateway = {
283
- gatewayName: name,
284
- senderId: '',
285
- platform: adapter.name,
286
- send: async (msg: GatewayOutboundMessage) => {
287
- wire.channel?.send(msg)
288
- },
289
- } satisfies PikkuGateway
290
- },
291
- } as any)
292
-
293
- // Register onMessage
294
- addFunction(messageFuncId, {
295
- auth: false,
296
- func: async (services: any, data: unknown, wire: PikkuWire) => {
297
- const parsed = adapter.parse(data)
298
- if (!parsed) return
299
-
300
- const gateway: PikkuGateway = {
301
- gatewayName: name,
302
- senderId: parsed.senderId,
303
- platform: adapter.name,
304
- send: async (msg: GatewayOutboundMessage) => {
305
- wire.channel?.send(msg)
306
- },
307
- }
308
- ;(wire as any).gateway = gateway
309
-
310
- const allMiddleware: CorePikkuMiddleware[] = [
311
- ...(userMiddleware || []),
312
- ...(userFuncConfig.middleware || []),
313
- ]
314
-
315
- const exec = async () => {
316
- const result = await userFuncConfig.func(services, parsed, wire)
317
- if (
318
- result &&
319
- (result.text || result.richContent || result.attachments)
320
- ) {
321
- wire.channel?.send(result)
322
- }
323
- }
324
-
325
- if (allMiddleware.length > 0) {
326
- await runMiddleware(services, wire, allMiddleware, exec)
327
- } else {
328
- await exec()
329
- }
330
- },
331
- } as any)
332
-
333
- // Store channel config
334
- channels.set(name, {
335
- name,
336
- route,
337
- auth: false,
338
- onConnect: { func: async () => {} },
339
- onMessage: { func: async () => {} },
340
- } as any)
341
-
342
- // Force router to re-initialize
343
- httpRouter.reset()
344
- }
345
-
346
- // ---------------------------------------------------------------------------
347
- // Listener gateway — standalone event loop, no route
348
- // ---------------------------------------------------------------------------
349
-
350
- const wireListenerGateway = (config: CoreGateway): void => {
351
- // Listener gateways don't register routes.
352
- // They are started manually and call into the gateway's func directly.
353
- // The gateway config is already stored in pikkuState.
354
- pikkuState(null, 'gateway', 'gateways').set(config.name, config)
355
- }
356
-
357
- /**
358
- * Create the message handler callback for a listener gateway.
359
- *
360
- * Returns a function `(rawData: unknown) => Promise<void>` that can be
361
- * passed to `adapter.init()`. Used by `LocalGatewayService` (and any
362
- * other GatewayService implementation) to wire up listener gateways.
363
- *
364
- * @param name - Gateway name (for wire.gateway metadata)
365
- * @param config - The gateway configuration (adapter, func, middleware)
366
- * @param singletonServices - Singleton services to pass to handler/middleware
367
- */
368
- export const createListenerMessageHandler = (
369
- name: string,
370
- config: CoreGateway,
371
- singletonServices: CoreSingletonServices
372
- ): ((rawData: unknown) => Promise<void>) => {
373
- const { adapter } = config
374
- const userFuncConfig = config.func as {
375
- func: Function
376
- middleware?: CorePikkuMiddleware[]
377
- }
378
- const userMiddleware = config.middleware as CorePikkuMiddleware[] | undefined
379
-
380
- return async (rawData: unknown): Promise<void> => {
381
- const parsed = adapter.parse(rawData)
382
- if (!parsed) return
383
-
384
- const wire: PikkuWire = {}
385
- const gateway: PikkuGateway = {
386
- gatewayName: name,
387
- senderId: parsed.senderId,
388
- platform: adapter.name,
389
- send: (msg: GatewayOutboundMessage) => adapter.send(parsed.senderId, msg),
390
- }
391
- ;(wire as any).gateway = gateway
392
-
393
- const allMiddleware: CorePikkuMiddleware[] = [
394
- ...(userMiddleware || []),
395
- ...(userFuncConfig.middleware || []),
396
- ]
397
-
398
- const exec = async () => {
399
- const result = await userFuncConfig.func(singletonServices, parsed, wire)
400
- if (result && (result.text || result.richContent || result.attachments)) {
401
- await adapter.send(parsed.senderId, result as GatewayOutboundMessage)
402
- }
403
- }
404
-
405
- if (allMiddleware.length > 0) {
406
- await runMiddleware(singletonServices, wire, allMiddleware, exec)
407
- } else {
408
- await exec()
409
- }
410
- }
411
- }
@@ -1,149 +0,0 @@
1
- import type {
2
- CommonWireMeta,
3
- CorePikkuMiddleware,
4
- CorePikkuMiddlewareGroup,
5
- } from '../../types/core.types.js'
6
- import type {
7
- CorePikkuFunctionConfig,
8
- CorePermissionGroup,
9
- CorePikkuPermission,
10
- } from '../../function/functions.types.js'
11
- import type { PikkuHTTPRequest } from '../http/http.types.js'
12
-
13
- /**
14
- * Attachment in gateway messages (images, files, etc.)
15
- */
16
- export interface GatewayAttachment {
17
- type: string
18
- url?: string
19
- data?: ArrayBuffer | Uint8Array
20
- mimeType?: string
21
- filename?: string
22
- }
23
-
24
- /**
25
- * Normalized inbound message from any platform
26
- */
27
- export interface GatewayInboundMessage {
28
- /** Platform-specific sender identifier (phone number, Slack user ID, etc.) */
29
- senderId: string
30
- /** Message text content */
31
- text: string
32
- /** Original platform-specific payload */
33
- raw: unknown
34
- /** Optional file/media attachments */
35
- attachments?: GatewayAttachment[]
36
- /** Optional platform-specific metadata */
37
- metadata?: Record<string, unknown>
38
- }
39
-
40
- /**
41
- * Outbound message to send back via the platform
42
- */
43
- export interface GatewayOutboundMessage {
44
- /** Plain text response */
45
- text?: string
46
- /** Platform-specific rich content (Slack blocks, WhatsApp templates, etc.) */
47
- richContent?: Record<string, unknown>
48
- /** Optional file/media attachments */
49
- attachments?: GatewayAttachment[]
50
- }
51
-
52
- /**
53
- * Result of webhook verification (e.g., WhatsApp GET challenge, Slack url_verification)
54
- */
55
- export type WebhookVerificationResult =
56
- | { verified: true; response: unknown }
57
- | { verified: false }
58
-
59
- /**
60
- * Gateway adapter interface — implemented by platform-specific addon packages.
61
- *
62
- * Two responsibilities:
63
- * 1. Parse incoming platform-specific format into normalized GatewayInboundMessage
64
- * 2. Send outgoing GatewayOutboundMessage via the platform's API
65
- */
66
- export interface GatewayAdapter {
67
- /** Platform name (e.g., 'whatsapp', 'slack', 'telegram') */
68
- name: string
69
- /** Parse platform-specific payload into normalized message. Return null to ignore (e.g., delivery receipts). */
70
- parse(data: unknown): GatewayInboundMessage | null
71
- /** Send a message to a specific sender via the platform's API */
72
- send(senderId: string, message: GatewayOutboundMessage): Promise<void>
73
- /** Initialize the adapter (connect to platform, start listening).
74
- * Called by GatewayService.start() — the adapter should call onMessage for each incoming event. */
75
- init(onMessage: (data: unknown) => Promise<void>): Promise<void>
76
- /** Tear down the adapter (disconnect, release resources). */
77
- close(): Promise<void>
78
- /** Handle webhook verification challenges (only for webhook type).
79
- * Receives the data (body or query params) and the Pikku HTTP request for additional inspection. */
80
- verifyWebhook?(
81
- data: unknown,
82
- request?: PikkuHTTPRequest
83
- ): WebhookVerificationResult | Promise<WebhookVerificationResult>
84
- }
85
-
86
- /**
87
- * The gateway wire object available on wire.gateway inside handler functions and middleware
88
- */
89
- export interface PikkuGateway {
90
- /** Name of this gateway instance */
91
- gatewayName: string
92
- /** Platform-specific sender identifier */
93
- senderId: string
94
- /** Platform name from adapter.name */
95
- platform: string
96
- /** Send a proactive message to the sender */
97
- send(msg: GatewayOutboundMessage): Promise<void>
98
- }
99
-
100
- /**
101
- * Gateway transport type:
102
- * - 'webhook': Platform POSTs to us (WhatsApp Cloud API, Slack Events API, Telegram webhooks)
103
- * - 'websocket': Client connects via WebSocket (WebChat, browser widget)
104
- * - 'listener': Standalone event loop, no route (Baileys, Signal CLI, Matrix sync)
105
- */
106
- export type GatewayTransportType = 'webhook' | 'websocket' | 'listener'
107
-
108
- /**
109
- * Core gateway configuration for wireGateway()
110
- */
111
- export type CoreGateway<
112
- PikkuFunctionConfig = CorePikkuFunctionConfig<any, any>,
113
- PikkuPermission extends CorePikkuPermission = CorePikkuPermission,
114
- PikkuMiddleware extends CorePikkuMiddleware = CorePikkuMiddleware,
115
- > = {
116
- /** Unique name for this gateway */
117
- name: string
118
- /** Transport type */
119
- type: GatewayTransportType
120
- /** HTTP route for webhook/websocket types */
121
- route?: string
122
- /** The gateway adapter (parse inbound, send outbound) */
123
- adapter: GatewayAdapter
124
- /** The handler function that processes parsed messages */
125
- func: PikkuFunctionConfig
126
- /** Optional middleware chain (e.g., auth) */
127
- middleware?: CorePikkuMiddlewareGroup<any, any>
128
- /** Optional permissions */
129
- permissions?: CorePermissionGroup | PikkuPermission[]
130
- /** Optional tags for categorization */
131
- tags?: string[]
132
- /** Whether authentication is required (default: true) */
133
- auth?: boolean
134
- }
135
-
136
- /**
137
- * Metadata for a registered gateway, stored in state
138
- */
139
- export type GatewayMeta = CommonWireMeta & {
140
- name: string
141
- type: GatewayTransportType
142
- route?: string
143
- gateway: true
144
- }
145
-
146
- /**
147
- * All gateway metadata keyed by name
148
- */
149
- export type GatewaysMeta = Record<string, GatewayMeta>
@@ -1,13 +0,0 @@
1
- export { wireGateway, createListenerMessageHandler } from './gateway-runner.js'
2
- export type {
3
- GatewayAdapter,
4
- GatewayAttachment,
5
- GatewayInboundMessage,
6
- GatewayOutboundMessage,
7
- GatewayMeta,
8
- GatewaysMeta,
9
- GatewayTransportType,
10
- CoreGateway,
11
- PikkuGateway,
12
- WebhookVerificationResult,
13
- } from './gateway.types.js'