@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,241 +0,0 @@
1
- import type {
2
- CoreServices,
3
- JSONValue,
4
- CoreUserSession,
5
- } from '../../types/core.types.js'
6
- import type {
7
- BinaryData,
8
- ChannelMessageMeta,
9
- CoreChannel,
10
- PikkuChannelHandler,
11
- } from './channel.types.js'
12
- import { pikkuState } from '../../pikku-state.js'
13
- import { runPikkuFunc } from '../../function/function-runner.js'
14
- import type { SessionService } from '../../services/user-session-service.js'
15
- import { createMiddlewareSessionWireProps } from '../../services/user-session-service.js'
16
-
17
- const getChannelMeta = (channelName: string) => {
18
- return pikkuState(null, 'channel', 'meta')[channelName]
19
- }
20
-
21
- const getRouteMeta = (
22
- channelName: string,
23
- routingProperty?: string,
24
- routerValue?: string
25
- ): ChannelMessageMeta => {
26
- const channelMeta = pikkuState(null, 'channel', 'meta')[channelName]
27
- if (!channelMeta) {
28
- throw new Error(`Channel ${channelName} not found`)
29
- }
30
- if (!routingProperty) {
31
- if (!channelMeta.message) {
32
- throw new Error(`Channel ${channelName} has no default message route`)
33
- }
34
- return channelMeta.message
35
- }
36
- if (!routerValue) {
37
- throw new Error(
38
- `Channel ${channelName} requires a router value for ${routingProperty}`
39
- )
40
- }
41
- const route = channelMeta.messageWirings[routingProperty]?.[routerValue]
42
- if (!route) {
43
- throw new Error(
44
- `Channel ${channelName} has no route for ${routingProperty}:${routerValue}`
45
- )
46
- }
47
- return route
48
- }
49
-
50
- const validateAuth = (
51
- requiresSession: boolean,
52
- session: CoreUserSession | undefined,
53
- onMessage: any
54
- ) => {
55
- const auth =
56
- typeof onMessage === 'function'
57
- ? requiresSession
58
- : onMessage.auth === undefined
59
- ? requiresSession
60
- : onMessage.auth
61
-
62
- if (auth && !session) {
63
- return false
64
- }
65
- return true
66
- }
67
-
68
- export const processMessageHandlers = (
69
- services: CoreServices,
70
- channelConfig: CoreChannel<any, any>,
71
- channelHandler: PikkuChannelHandler,
72
- userSession?: SessionService<CoreUserSession>
73
- ) => {
74
- const logger = services.logger
75
- const requiresSession = channelConfig.auth !== false
76
-
77
- const processMessage = async (
78
- data: JSONValue,
79
- onMessage: any,
80
- routingProperty?: string,
81
- routerValue?: string
82
- ): Promise<unknown> => {
83
- if (
84
- !validateAuth(
85
- requiresSession,
86
- userSession?.get() as CoreUserSession | undefined,
87
- onMessage
88
- )
89
- ) {
90
- const routeMessage = routingProperty
91
- ? `route '${routingProperty}:${routerValue}'`
92
- : 'the default message route'
93
- logger.error(
94
- `Channel ${channelConfig.name} with id ${channelHandler.getChannel().channelId} requires a session for ${routeMessage}`
95
- )
96
- // TODO: Send error message back breaks typescript, but should be implemented somehow
97
- channelHandler.getChannel().send(`Unauthorized for ${routeMessage}`)
98
- return
99
- }
100
-
101
- const {
102
- pikkuFuncId,
103
- middleware: routeInheritedMiddleware,
104
- permissions: inheritedPermissions,
105
- } = getRouteMeta(channelConfig.name, routingProperty, routerValue)
106
-
107
- // Get wire middleware: channel-level middleware + message-specific middleware
108
- const channelWireMiddleware = channelConfig.middleware || []
109
-
110
- // Check if onMessage is a wrapper object vs direct function config:
111
- // - Direct config: onMessage.func is a plain Function
112
- // - Wrapper: onMessage.func is a CorePikkuFunctionConfig (has onMessage.func.func)
113
- // - Simple wrapper: onMessage has both func (plain Function) and middleware properties
114
- const isWrapper =
115
- onMessage &&
116
- typeof onMessage === 'object' &&
117
- 'func' in onMessage &&
118
- ((typeof onMessage.func === 'object' && 'func' in onMessage.func) ||
119
- 'middleware' in onMessage)
120
- const messageWireMiddleware = isWrapper ? onMessage.middleware || [] : []
121
-
122
- // Combine channel middleware with message middleware (actual functions)
123
- // Channel middleware runs first, then message middleware
124
- const wireMiddleware = [...channelWireMiddleware, ...messageWireMiddleware]
125
-
126
- // Inherited middleware comes from metadata (tag groups, non-inline wire)
127
- const inheritedMiddleware = routeInheritedMiddleware || []
128
-
129
- const wirePermissions = isWrapper ? onMessage.permissions : undefined
130
-
131
- // Create unique cache key that includes routing info to avoid cache collisions
132
- // when multiple message handlers use the same function
133
- const cacheKey = routingProperty
134
- ? `${channelConfig.name}:${routingProperty}:${routerValue}`
135
- : `${channelConfig.name}:default`
136
-
137
- const channelMeta = getChannelMeta(channelConfig.name)
138
- const wireChannelMiddleware = channelConfig.channelMiddleware || []
139
-
140
- return await runPikkuFunc('channel', cacheKey, pikkuFuncId, {
141
- singletonServices: services,
142
- data: () => data,
143
- inheritedMiddleware,
144
- wireMiddleware,
145
- inheritedChannelMiddleware: channelMeta?.channelMiddleware,
146
- wireChannelMiddleware: wireChannelMiddleware as any,
147
- inheritedPermissions,
148
- wirePermissions,
149
- tags: channelConfig.tags,
150
- sessionService: userSession,
151
- wire: {
152
- channel: channelHandler.getChannel(),
153
- ...(userSession && createMiddlewareSessionWireProps(userSession)),
154
- },
155
- })
156
- }
157
-
158
- const onMessage = async (rawData: unknown): Promise<unknown> => {
159
- let result: unknown
160
- let processed = false
161
-
162
- // Route-specific handling
163
- if (typeof rawData === 'string' && channelConfig.onMessageWiring) {
164
- let messageData: any
165
- try {
166
- messageData = JSON.parse(rawData)
167
- } catch {
168
- // Most likely a json error.. ignore
169
- }
170
-
171
- if (messageData) {
172
- const entries = Object.entries(channelConfig.onMessageWiring)
173
- for (const [routingProperty, routes] of entries) {
174
- const routerValue = messageData[routingProperty]
175
- if (routerValue && routes[routerValue]) {
176
- const { [routingProperty]: _, ...data } = messageData
177
-
178
- processed = true
179
- result =
180
- (await processMessage(
181
- data as any,
182
- routes[routerValue],
183
- routingProperty,
184
- routerValue
185
- )) || {}
186
- ;(result as any)[routingProperty] = routerValue
187
- break
188
- }
189
- }
190
-
191
- // Default handler if no routes matched but json data was parsed
192
- if (!processed && channelConfig.onMessage) {
193
- processed = true
194
- result = await processMessage(messageData, channelConfig.onMessage)
195
- }
196
- }
197
- }
198
-
199
- // Default handler if no routes matched and json data wasn't parsed
200
- if (!processed && channelConfig.onMessage) {
201
- processed = true
202
- result = await processMessage(
203
- rawData as JSONValue,
204
- channelConfig.onMessage
205
- )
206
- }
207
-
208
- if (!processed) {
209
- logger.error(
210
- `No handler found for message in channel ${channelConfig.name} for ${JSON.stringify(rawData)}`
211
- )
212
- logger.error(`Channel config name: ${channelConfig.name}`)
213
- }
214
-
215
- return result
216
- }
217
-
218
- const onBinaryMessage = channelConfig.onBinaryMessage
219
- ? async (data: BinaryData): Promise<BinaryData | void> => {
220
- if (
221
- !validateAuth(
222
- requiresSession,
223
- userSession?.get() as CoreUserSession | undefined,
224
- channelConfig
225
- )
226
- ) {
227
- logger.error(
228
- `Channel ${channelConfig.name} with id ${channelHandler.getChannel().channelId} requires a session for binary message`
229
- )
230
- return
231
- }
232
- return channelConfig.onBinaryMessage!(
233
- services,
234
- data,
235
- channelHandler.getChannel()
236
- )
237
- }
238
- : undefined
239
-
240
- return { onMessage, onBinaryMessage }
241
- }
@@ -1,120 +0,0 @@
1
- import type {
2
- CoreSingletonServices,
3
- MiddlewareMetadata,
4
- PikkuWire,
5
- } from '../../types/core.types.js'
6
- import type { CorePikkuChannelMiddleware } from './channel.types.js'
7
- import { pikkuState } from '../../pikku-state.js'
8
- import { freezeDedupe, getTagGroups } from '../../utils.js'
9
-
10
- export const addChannelMiddleware = (
11
- tag: string,
12
- middleware: CorePikkuChannelMiddleware[],
13
- packageName: string | null = null
14
- ): CorePikkuChannelMiddleware[] => {
15
- const tagGroups = pikkuState(packageName, 'channelMiddleware', 'tagGroup')
16
- tagGroups[tag] = middleware
17
- return middleware
18
- }
19
-
20
- const getChannelMiddlewareByName = (
21
- name: string
22
- ): CorePikkuChannelMiddleware | undefined => {
23
- const store = pikkuState(null, 'misc', 'channelMiddleware')
24
- const middleware = store[name]
25
- return middleware?.[0]
26
- }
27
-
28
- const channelMiddlewareCache: Record<
29
- string,
30
- readonly CorePikkuChannelMiddleware[]
31
- > = {}
32
-
33
- export const combineChannelMiddleware = (
34
- wireType: string,
35
- uid: string,
36
- {
37
- wireInheritedChannelMiddleware,
38
- wireChannelMiddleware,
39
- packageName = null,
40
- }: {
41
- wireInheritedChannelMiddleware?: MiddlewareMetadata[]
42
- wireChannelMiddleware?: CorePikkuChannelMiddleware[]
43
- packageName?: string | null
44
- } = {}
45
- ): readonly CorePikkuChannelMiddleware[] => {
46
- const cacheKey = `${wireType}:${uid}`
47
- if (channelMiddlewareCache[cacheKey]) {
48
- return channelMiddlewareCache[cacheKey]
49
- }
50
-
51
- const resolved: CorePikkuChannelMiddleware[] = []
52
-
53
- if (wireInheritedChannelMiddleware) {
54
- for (const meta of wireInheritedChannelMiddleware) {
55
- if (meta.type === 'tag') {
56
- const groups = getTagGroups(
57
- pikkuState(packageName, 'channelMiddleware', 'tagGroup'),
58
- meta.tag
59
- )
60
- for (const group of groups) {
61
- resolved.push(...group)
62
- }
63
- } else if (meta.type === 'wire') {
64
- const middleware = getChannelMiddlewareByName(meta.name)
65
- if (middleware) {
66
- resolved.push(middleware)
67
- }
68
- }
69
- }
70
- }
71
-
72
- if (wireChannelMiddleware) {
73
- resolved.push(...wireChannelMiddleware)
74
- }
75
-
76
- channelMiddlewareCache[cacheKey] = freezeDedupe(
77
- resolved
78
- ) as readonly CorePikkuChannelMiddleware[]
79
-
80
- return channelMiddlewareCache[cacheKey]
81
- }
82
-
83
- export function wrapChannelWithMiddleware<Out>(
84
- wire: PikkuWire,
85
- services: CoreSingletonServices,
86
- middlewares: readonly CorePikkuChannelMiddleware[]
87
- ): PikkuWire {
88
- if (middlewares.length === 0 || !wire.channel) return wire
89
-
90
- const channel = wire.channel
91
- const originalSend = channel.send.bind(channel)
92
-
93
- const dispatch = async (index: number, event: Out): Promise<void> => {
94
- if (index >= middlewares.length) {
95
- await originalSend(event)
96
- return
97
- }
98
-
99
- const middleware = middlewares[index]!
100
- await middleware(services, event, async (result: any) => {
101
- if (result === null || result === undefined) return
102
- if (Array.isArray(result)) {
103
- for (const item of result) {
104
- await dispatch(index + 1, item)
105
- }
106
- } else {
107
- await dispatch(index + 1, result)
108
- }
109
- })
110
- }
111
-
112
- return {
113
- ...wire,
114
- channel: {
115
- ...channel,
116
- send: ((data: Out) => dispatch(0, data)) as typeof channel.send,
117
- sendBinary: channel.sendBinary,
118
- },
119
- }
120
- }
@@ -1,166 +0,0 @@
1
- import { NotFoundError, PikkuMissingMetaError } from '../../errors/errors.js'
2
- import { addFunction } from '../../function/function-runner.js'
3
- import type { CorePikkuPermission } from '../../function/functions.types.js'
4
- import { pikkuState, getSingletonServices } from '../../pikku-state.js'
5
- import { coerceTopLevelDataFromSchema, validateSchema } from '../../schema.js'
6
- import type { SessionService } from '../../services/user-session-service.js'
7
- import type { CorePikkuMiddleware } from '../../types/core.types.js'
8
- import { httpRouter } from '../http/routers/http-router.js'
9
- import type {
10
- ChannelMeta,
11
- CoreChannel,
12
- RunChannelOptions,
13
- RunChannelParams,
14
- } from './channel.types.js'
15
-
16
- /**
17
- * Adds a channel and registers all functions referenced in it using the
18
- * function names already stored in the channel metadata
19
- */
20
- export const wireChannel = <
21
- In,
22
- Channel extends string,
23
- PikkuPermission extends CorePikkuPermission<In>,
24
- PikkuMiddleware extends CorePikkuMiddleware,
25
- ChannelFunction,
26
- >(
27
- channel: CoreChannel<
28
- In,
29
- Channel,
30
- PikkuPermission,
31
- PikkuMiddleware,
32
- ChannelFunction
33
- >
34
- ) => {
35
- // Get the channel metadata
36
- const channelsMeta = pikkuState(null, 'channel', 'meta')
37
- const channelMeta = channelsMeta[channel.name]
38
- if (!channelMeta) {
39
- throw new PikkuMissingMetaError(
40
- `Missing generated metadata for channel '${channel.name}'`
41
- )
42
- }
43
-
44
- pikkuState(null, 'channel', 'channels').set(channel.name, channel as any)
45
-
46
- // Register onConnect function if provided
47
- if (channel.onConnect && channelMeta.connect) {
48
- addFunction(channelMeta.connect.pikkuFuncId, channel.onConnect as any)
49
- }
50
-
51
- // Register onDisconnect function if provided
52
- if (channel.onDisconnect && channelMeta.disconnect) {
53
- addFunction(channelMeta.disconnect.pikkuFuncId, channel.onDisconnect as any)
54
- }
55
-
56
- // Register onMessage function if provided
57
- if (channel.onMessage && channelMeta.message?.pikkuFuncId) {
58
- addFunction(
59
- channelMeta.message.pikkuFuncId,
60
- (channel.onMessage as any).func instanceof Function
61
- ? channel.onMessage
62
- : (channel.onMessage as any).func
63
- )
64
- }
65
-
66
- // Register functions in onMessageWiring
67
- if (channel.onMessageWiring && channelMeta.messageWirings) {
68
- // Iterate through each channel in onMessageWiring
69
- Object.entries(channel.onMessageWiring).forEach(([channelKey, wirings]) => {
70
- const channelWirings = channelMeta.messageWirings[channelKey]
71
- if (!channelWirings) return
72
-
73
- // Iterate through each wiring in the channel
74
- Object.entries(wirings).forEach(([wiringKey, handler]) => {
75
- const wiringMeta = channelWirings[wiringKey]
76
- if (!wiringMeta) return
77
-
78
- // Register the function using the pikku name from metadata
79
- // It could be a FuncConfig or a wiring override with a funcConfig
80
- addFunction(
81
- wiringMeta.pikkuFuncId,
82
- (handler as any).func instanceof Function
83
- ? handler
84
- : (handler as any).func
85
- )
86
- })
87
- })
88
- }
89
-
90
- // Store the channel configuration
91
- pikkuState(null, 'channel', 'channels').set(channel.name, channel as any)
92
- }
93
-
94
- const getMatchingChannelConfig = (path: string) => {
95
- const matchedPath = httpRouter.match('get', path)
96
- if (!matchedPath) {
97
- return null
98
- }
99
-
100
- const meta = pikkuState(null, 'channel', 'meta')
101
- const channelMeta = Object.values(meta).find(
102
- (channelConfig) => channelConfig.route === matchedPath.route
103
- )
104
- if (!channelMeta) {
105
- return null
106
- }
107
-
108
- const channels = pikkuState(null, 'channel', 'channels')
109
- const channelConfig = channels.get(channelMeta.name)
110
- if (!channelConfig) {
111
- return null
112
- }
113
-
114
- return {
115
- matchedPath,
116
- params: matchedPath.params,
117
- channelConfig,
118
- schemaName: channelMeta.input,
119
- meta: channelMeta,
120
- }
121
- }
122
-
123
- export const openChannel = async ({
124
- route,
125
- coerceDataFromSchema = true,
126
- request,
127
- }: Pick<CoreChannel<unknown, string>, 'route'> &
128
- RunChannelParams<unknown> & {
129
- userSession: SessionService<any>
130
- } & RunChannelOptions): Promise<{
131
- openingData: unknown
132
- channelConfig: CoreChannel<unknown, any>
133
- meta: ChannelMeta
134
- }> => {
135
- const singletonServices = getSingletonServices()
136
- const matchingChannel = getMatchingChannelConfig(route)
137
- if (!matchingChannel) {
138
- singletonServices.logger.info(`Channel not found: ${route}`)
139
- throw new NotFoundError(`Channel not found: ${route}`)
140
- }
141
-
142
- const { params, channelConfig, schemaName, meta } = matchingChannel
143
-
144
- const requiresSession = channelConfig.auth !== false
145
- request?.setParams(params)
146
-
147
- singletonServices.logger.info(
148
- `Matched channel: ${channelConfig.name} | route: ${channelConfig.route} | auth: ${requiresSession.toString()}`
149
- )
150
-
151
- let openingData: any | undefined
152
- if (request) {
153
- openingData = await request.data()
154
- if (coerceDataFromSchema && schemaName) {
155
- coerceTopLevelDataFromSchema(schemaName, openingData)
156
- }
157
- await validateSchema(
158
- singletonServices.logger,
159
- singletonServices.schema,
160
- schemaName,
161
- openingData
162
- )
163
- }
164
-
165
- return { openingData, channelConfig, meta }
166
- }
@@ -1,29 +0,0 @@
1
- import type { CoreUserSession } from '../../types/core.types.js'
2
-
3
- export type Channel<ChannelType = unknown, OpeningData = unknown> = {
4
- channelId: string
5
- channelName: string
6
- channelObject?: ChannelType
7
- openingData?: OpeningData
8
- }
9
-
10
- export abstract class ChannelStore<
11
- ChannelType = unknown,
12
- OpeningData = unknown,
13
- UserSession extends CoreUserSession = CoreUserSession,
14
- TypedChannel = Channel<ChannelType, OpeningData>,
15
- > {
16
- public abstract addChannel(
17
- channel: Channel<ChannelType, OpeningData>
18
- ): Promise<void> | void
19
- public abstract removeChannels(channelId: string[]): Promise<void> | void
20
- public abstract setUserSession(
21
- channelId: string,
22
- userSession: UserSession | null
23
- ): Promise<void> | void
24
- public abstract getChannelAndSession(
25
- channelId: string
26
- ):
27
- | Promise<TypedChannel & { session: UserSession }>
28
- | (TypedChannel & { session: UserSession })
29
- }