@pikku/core 0.12.3 → 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 (218) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/services/in-memory-workflow-service.d.ts +15 -2
  3. package/dist/services/in-memory-workflow-service.js +49 -0
  4. package/lcov.info +18891 -0
  5. package/package.json +1 -1
  6. package/src/crypto-utils.test.ts +0 -214
  7. package/src/crypto-utils.ts +0 -213
  8. package/src/errors/error-handler.ts +0 -62
  9. package/src/errors/error.test.ts +0 -195
  10. package/src/errors/errors.ts +0 -374
  11. package/src/errors/index.ts +0 -2
  12. package/src/factory-functions.test.ts +0 -109
  13. package/src/function/function-runner.test.ts +0 -536
  14. package/src/function/function-runner.ts +0 -365
  15. package/src/function/functions.types.ts +0 -304
  16. package/src/function/index.ts +0 -5
  17. package/src/handle-error.test.ts +0 -424
  18. package/src/handle-error.ts +0 -69
  19. package/src/index.ts +0 -118
  20. package/src/internal.ts +0 -6
  21. package/src/middleware/auth-apikey.test.ts +0 -363
  22. package/src/middleware/auth-apikey.ts +0 -47
  23. package/src/middleware/auth-bearer.test.ts +0 -450
  24. package/src/middleware/auth-bearer.ts +0 -72
  25. package/src/middleware/auth-cookie.test.ts +0 -528
  26. package/src/middleware/auth-cookie.ts +0 -80
  27. package/src/middleware/cors.test.ts +0 -424
  28. package/src/middleware/cors.ts +0 -104
  29. package/src/middleware/index.ts +0 -5
  30. package/src/middleware/remote-auth.test.ts +0 -488
  31. package/src/middleware/remote-auth.ts +0 -68
  32. package/src/middleware/timeout.ts +0 -15
  33. package/src/middleware-runner.test.ts +0 -418
  34. package/src/middleware-runner.ts +0 -234
  35. package/src/permissions.test.ts +0 -434
  36. package/src/permissions.ts +0 -319
  37. package/src/pikku-request.ts +0 -23
  38. package/src/pikku-response.ts +0 -5
  39. package/src/pikku-state.test.ts +0 -224
  40. package/src/pikku-state.ts +0 -216
  41. package/src/run-tests-script.test.ts +0 -49
  42. package/src/schema.test.ts +0 -249
  43. package/src/schema.ts +0 -151
  44. package/src/services/ai-agent-runner-service.ts +0 -41
  45. package/src/services/ai-run-state-service.ts +0 -20
  46. package/src/services/ai-storage-service.ts +0 -39
  47. package/src/services/content-service.ts +0 -76
  48. package/src/services/deployment-service.ts +0 -22
  49. package/src/services/gateway-service.ts +0 -20
  50. package/src/services/gopass-secrets.ts +0 -98
  51. package/src/services/in-memory-ai-run-state-service.ts +0 -73
  52. package/src/services/in-memory-trigger-service.ts +0 -64
  53. package/src/services/in-memory-workflow-service.test.ts +0 -351
  54. package/src/services/in-memory-workflow-service.ts +0 -438
  55. package/src/services/index.ts +0 -56
  56. package/src/services/jwt-service.ts +0 -30
  57. package/src/services/local-content.ts +0 -120
  58. package/src/services/local-gateway-service.ts +0 -62
  59. package/src/services/local-secrets.test.ts +0 -80
  60. package/src/services/local-secrets.ts +0 -94
  61. package/src/services/local-variables.test.ts +0 -61
  62. package/src/services/local-variables.ts +0 -39
  63. package/src/services/logger-console.test.ts +0 -118
  64. package/src/services/logger-console.ts +0 -98
  65. package/src/services/logger.ts +0 -57
  66. package/src/services/scheduler-service.ts +0 -86
  67. package/src/services/schema-service.ts +0 -33
  68. package/src/services/scoped-secret-service.test.ts +0 -74
  69. package/src/services/scoped-secret-service.ts +0 -41
  70. package/src/services/secret-service.ts +0 -38
  71. package/src/services/trigger-service.ts +0 -17
  72. package/src/services/typed-secret-service.test.ts +0 -93
  73. package/src/services/typed-secret-service.ts +0 -70
  74. package/src/services/typed-variables-service.test.ts +0 -73
  75. package/src/services/typed-variables-service.ts +0 -81
  76. package/src/services/user-session-service.test.ts +0 -113
  77. package/src/services/user-session-service.ts +0 -86
  78. package/src/services/variables-service.ts +0 -11
  79. package/src/services/workflow-service.ts +0 -95
  80. package/src/testing/index.ts +0 -2
  81. package/src/testing/service-tests.ts +0 -873
  82. package/src/time-utils.test.ts +0 -56
  83. package/src/time-utils.ts +0 -107
  84. package/src/types/core.types.ts +0 -478
  85. package/src/types/state.types.ts +0 -188
  86. package/src/utils/hash.test.ts +0 -68
  87. package/src/utils/hash.ts +0 -26
  88. package/src/utils.test.ts +0 -350
  89. package/src/utils.ts +0 -129
  90. package/src/version.test.ts +0 -80
  91. package/src/version.ts +0 -25
  92. package/src/wirings/ai-agent/agent-dynamic-workflow.ts +0 -469
  93. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +0 -152
  94. package/src/wirings/ai-agent/ai-agent-helpers.ts +0 -76
  95. package/src/wirings/ai-agent/ai-agent-memory.ts +0 -310
  96. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +0 -115
  97. package/src/wirings/ai-agent/ai-agent-model-config.ts +0 -43
  98. package/src/wirings/ai-agent/ai-agent-prepare.ts +0 -636
  99. package/src/wirings/ai-agent/ai-agent-registry.test.ts +0 -37
  100. package/src/wirings/ai-agent/ai-agent-registry.ts +0 -82
  101. package/src/wirings/ai-agent/ai-agent-runner.test.ts +0 -319
  102. package/src/wirings/ai-agent/ai-agent-runner.ts +0 -773
  103. package/src/wirings/ai-agent/ai-agent-stream.test.ts +0 -859
  104. package/src/wirings/ai-agent/ai-agent-stream.ts +0 -1153
  105. package/src/wirings/ai-agent/ai-agent.types.ts +0 -382
  106. package/src/wirings/ai-agent/index.ts +0 -37
  107. package/src/wirings/channel/channel-common.ts +0 -90
  108. package/src/wirings/channel/channel-handler.ts +0 -250
  109. package/src/wirings/channel/channel-middleware-runner.ts +0 -120
  110. package/src/wirings/channel/channel-runner.ts +0 -166
  111. package/src/wirings/channel/channel-store.ts +0 -29
  112. package/src/wirings/channel/channel.types.ts +0 -172
  113. package/src/wirings/channel/define-channel-routes.ts +0 -25
  114. package/src/wirings/channel/eventhub-service.ts +0 -34
  115. package/src/wirings/channel/eventhub-store.ts +0 -13
  116. package/src/wirings/channel/index.ts +0 -24
  117. package/src/wirings/channel/local/index.ts +0 -3
  118. package/src/wirings/channel/local/local-channel-handler.ts +0 -81
  119. package/src/wirings/channel/local/local-channel-runner.test.ts +0 -215
  120. package/src/wirings/channel/local/local-channel-runner.ts +0 -210
  121. package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -95
  122. package/src/wirings/channel/local/local-eventhub-service.ts +0 -101
  123. package/src/wirings/channel/log-channels.ts +0 -20
  124. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -54
  125. package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -45
  126. package/src/wirings/channel/serverless/index.ts +0 -5
  127. package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -289
  128. package/src/wirings/cli/channel/cli-channel-runner.ts +0 -136
  129. package/src/wirings/cli/channel/index.ts +0 -1
  130. package/src/wirings/cli/cli-runner.test.ts +0 -403
  131. package/src/wirings/cli/cli-runner.ts +0 -529
  132. package/src/wirings/cli/cli.types.ts +0 -358
  133. package/src/wirings/cli/command-parser.test.ts +0 -445
  134. package/src/wirings/cli/command-parser.ts +0 -504
  135. package/src/wirings/cli/define-cli-commands.ts +0 -24
  136. package/src/wirings/cli/index.ts +0 -19
  137. package/src/wirings/gateway/gateway-runner.test.ts +0 -474
  138. package/src/wirings/gateway/gateway-runner.ts +0 -411
  139. package/src/wirings/gateway/gateway.types.ts +0 -149
  140. package/src/wirings/gateway/index.ts +0 -13
  141. package/src/wirings/http/http-routes.test.ts +0 -322
  142. package/src/wirings/http/http-routes.ts +0 -197
  143. package/src/wirings/http/http-runner.test.ts +0 -144
  144. package/src/wirings/http/http-runner.ts +0 -588
  145. package/src/wirings/http/http.types.ts +0 -369
  146. package/src/wirings/http/index.ts +0 -28
  147. package/src/wirings/http/log-http-routes.ts +0 -22
  148. package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -237
  149. package/src/wirings/http/pikku-fetch-http-request.ts +0 -170
  150. package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -82
  151. package/src/wirings/http/pikku-fetch-http-response.ts +0 -147
  152. package/src/wirings/http/routers/http-router.ts +0 -13
  153. package/src/wirings/http/routers/path-to-regex.test.ts +0 -319
  154. package/src/wirings/http/routers/path-to-regex.ts +0 -126
  155. package/src/wirings/http/web-request.test.ts +0 -236
  156. package/src/wirings/http/web-request.ts +0 -104
  157. package/src/wirings/mcp/index.ts +0 -27
  158. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -389
  159. package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
  160. package/src/wirings/mcp/mcp-runner.ts +0 -323
  161. package/src/wirings/mcp/mcp.types.ts +0 -216
  162. package/src/wirings/node/index.ts +0 -2
  163. package/src/wirings/node/node.types.ts +0 -23
  164. package/src/wirings/oauth2/index.ts +0 -3
  165. package/src/wirings/oauth2/oauth2-client.test.ts +0 -929
  166. package/src/wirings/oauth2/oauth2-client.ts +0 -335
  167. package/src/wirings/oauth2/oauth2.types.ts +0 -69
  168. package/src/wirings/oauth2/wire-oauth2-credential.ts +0 -23
  169. package/src/wirings/queue/index.ts +0 -31
  170. package/src/wirings/queue/queue-runner.test.ts +0 -710
  171. package/src/wirings/queue/queue-runner.ts +0 -192
  172. package/src/wirings/queue/queue.types.ts +0 -189
  173. package/src/wirings/queue/register-queue-helper.ts +0 -60
  174. package/src/wirings/queue/validate-worker-config.test.ts +0 -108
  175. package/src/wirings/queue/validate-worker-config.ts +0 -116
  176. package/src/wirings/rpc/index.ts +0 -4
  177. package/src/wirings/rpc/rpc-runner.ts +0 -460
  178. package/src/wirings/rpc/rpc-types.ts +0 -56
  179. package/src/wirings/rpc/wire-addon.ts +0 -21
  180. package/src/wirings/scheduler/index.ts +0 -11
  181. package/src/wirings/scheduler/log-schedulers.ts +0 -20
  182. package/src/wirings/scheduler/scheduler-runner.test.ts +0 -660
  183. package/src/wirings/scheduler/scheduler-runner.ts +0 -133
  184. package/src/wirings/scheduler/scheduler.types.ts +0 -53
  185. package/src/wirings/secret/index.ts +0 -9
  186. package/src/wirings/secret/secret.types.ts +0 -32
  187. package/src/wirings/secret/validate-secret-definitions.test.ts +0 -140
  188. package/src/wirings/secret/validate-secret-definitions.ts +0 -82
  189. package/src/wirings/trigger/index.ts +0 -10
  190. package/src/wirings/trigger/pikku-trigger-service.ts +0 -112
  191. package/src/wirings/trigger/trigger-runner.test.ts +0 -79
  192. package/src/wirings/trigger/trigger-runner.ts +0 -135
  193. package/src/wirings/trigger/trigger.types.ts +0 -178
  194. package/src/wirings/variable/index.ts +0 -8
  195. package/src/wirings/variable/validate-variable-definitions.test.ts +0 -91
  196. package/src/wirings/variable/validate-variable-definitions.ts +0 -69
  197. package/src/wirings/variable/variable.types.ts +0 -22
  198. package/src/wirings/workflow/dsl/index.ts +0 -31
  199. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -320
  200. package/src/wirings/workflow/dsl/workflow-runner.ts +0 -28
  201. package/src/wirings/workflow/graph/graph-node.ts +0 -222
  202. package/src/wirings/workflow/graph/graph-runner.test.ts +0 -487
  203. package/src/wirings/workflow/graph/graph-runner.ts +0 -816
  204. package/src/wirings/workflow/graph/graph-validation.test.ts +0 -170
  205. package/src/wirings/workflow/graph/graph-validation.ts +0 -237
  206. package/src/wirings/workflow/graph/index.ts +0 -19
  207. package/src/wirings/workflow/graph/template.test.ts +0 -49
  208. package/src/wirings/workflow/graph/template.ts +0 -42
  209. package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -29
  210. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -104
  211. package/src/wirings/workflow/index.ts +0 -82
  212. package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -200
  213. package/src/wirings/workflow/pikku-workflow-service.ts +0 -1176
  214. package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
  215. package/src/wirings/workflow/workflow-helpers.ts +0 -79
  216. package/src/wirings/workflow/workflow.types.ts +0 -274
  217. package/tsconfig.json +0 -14
  218. package/tsconfig.tsbuildinfo +0 -1
@@ -1,250 +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 routeMeta = getRouteMeta(
102
- channelConfig.name,
103
- routingProperty,
104
- routerValue
105
- )
106
- const {
107
- packageName,
108
- middleware: routeInheritedMiddleware,
109
- permissions: inheritedPermissions,
110
- } = routeMeta
111
-
112
- const pikkuFuncId = routeMeta.pikkuFuncId
113
-
114
- // Get wire middleware: channel-level middleware + message-specific middleware
115
- const channelWireMiddleware = channelConfig.middleware || []
116
-
117
- // Check if onMessage is a wrapper object vs direct function config:
118
- // - Direct config: onMessage.func is a plain Function
119
- // - Wrapper: onMessage.func is a CorePikkuFunctionConfig (has onMessage.func.func)
120
- // - Simple wrapper: onMessage has both func (plain Function) and middleware properties
121
- const isWrapper =
122
- onMessage &&
123
- typeof onMessage === 'object' &&
124
- 'func' in onMessage &&
125
- ((typeof onMessage.func === 'object' && 'func' in onMessage.func) ||
126
- 'middleware' in onMessage)
127
- const messageWireMiddleware = isWrapper ? onMessage.middleware || [] : []
128
-
129
- // Combine channel middleware with message middleware (actual functions)
130
- // Channel middleware runs first, then message middleware
131
- const wireMiddleware = [...channelWireMiddleware, ...messageWireMiddleware]
132
-
133
- // Inherited middleware comes from metadata (tag groups, non-inline wire)
134
- const inheritedMiddleware = routeInheritedMiddleware || []
135
-
136
- const wirePermissions = isWrapper ? onMessage.permissions : undefined
137
-
138
- // Create unique cache key that includes routing info to avoid cache collisions
139
- // when multiple message handlers use the same function
140
- const cacheKey = routingProperty
141
- ? `${channelConfig.name}:${routingProperty}:${routerValue}`
142
- : `${channelConfig.name}:default`
143
-
144
- const channelMeta = getChannelMeta(channelConfig.name)
145
- const wireChannelMiddleware = channelConfig.channelMiddleware || []
146
-
147
- return await runPikkuFunc('channel', cacheKey, pikkuFuncId, {
148
- singletonServices: services,
149
- data: () => data,
150
- inheritedMiddleware,
151
- wireMiddleware,
152
- inheritedChannelMiddleware: channelMeta?.channelMiddleware,
153
- wireChannelMiddleware: wireChannelMiddleware as any,
154
- inheritedPermissions,
155
- wirePermissions,
156
- coerceDataFromSchema: true,
157
- tags: channelConfig.tags,
158
- sessionService: userSession,
159
- wire: {
160
- channel: channelHandler.getChannel(),
161
- ...(userSession && createMiddlewareSessionWireProps(userSession)),
162
- },
163
- packageName,
164
- })
165
- }
166
-
167
- const onMessage = async (rawData: unknown): Promise<unknown> => {
168
- let result: unknown
169
- let processed = false
170
-
171
- // Route-specific handling
172
- if (typeof rawData === 'string' && channelConfig.onMessageWiring) {
173
- let messageData: any
174
- try {
175
- messageData = JSON.parse(rawData)
176
- } catch {
177
- // Most likely a json error.. ignore
178
- }
179
-
180
- if (messageData) {
181
- const entries = Object.entries(channelConfig.onMessageWiring)
182
- for (const [routingProperty, routes] of entries) {
183
- const routerValue = messageData[routingProperty]
184
- if (routerValue && routes[routerValue]) {
185
- const { [routingProperty]: _, ...data } = messageData
186
-
187
- processed = true
188
- result =
189
- (await processMessage(
190
- data as any,
191
- routes[routerValue],
192
- routingProperty,
193
- routerValue
194
- )) || {}
195
- ;(result as any)[routingProperty] = routerValue
196
- break
197
- }
198
- }
199
-
200
- // Default handler if no routes matched but json data was parsed
201
- if (!processed && channelConfig.onMessage) {
202
- processed = true
203
- result = await processMessage(messageData, channelConfig.onMessage)
204
- }
205
- }
206
- }
207
-
208
- // Default handler if no routes matched and json data wasn't parsed
209
- if (!processed && channelConfig.onMessage) {
210
- processed = true
211
- result = await processMessage(
212
- rawData as JSONValue,
213
- channelConfig.onMessage
214
- )
215
- }
216
-
217
- if (!processed) {
218
- logger.error(
219
- `No handler found for message in channel ${channelConfig.name} for ${JSON.stringify(rawData)}`
220
- )
221
- logger.error(`Channel config name: ${channelConfig.name}`)
222
- }
223
-
224
- return result
225
- }
226
-
227
- const onBinaryMessage = channelConfig.onBinaryMessage
228
- ? async (data: BinaryData): Promise<BinaryData | void> => {
229
- if (
230
- !validateAuth(
231
- requiresSession,
232
- userSession?.get() as CoreUserSession | undefined,
233
- channelConfig
234
- )
235
- ) {
236
- logger.error(
237
- `Channel ${channelConfig.name} with id ${channelHandler.getChannel().channelId} requires a session for binary message`
238
- )
239
- return
240
- }
241
- return channelConfig.onBinaryMessage!(
242
- services,
243
- data,
244
- channelHandler.getChannel()
245
- )
246
- }
247
- : undefined
248
-
249
- return { onMessage, onBinaryMessage }
250
- }
@@ -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
- }