@pikku/core 0.12.1 → 0.12.3
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.
- package/CHANGELOG.md +34 -0
- package/dist/crypto-utils.d.ts +10 -0
- package/dist/crypto-utils.js +62 -0
- package/dist/function/function-runner.js +4 -4
- package/dist/function/functions.types.d.ts +26 -1
- package/dist/function/functions.types.js +16 -0
- package/dist/handle-error.d.ts +1 -1
- package/dist/handle-error.js +7 -3
- package/dist/index.d.ts +14 -2
- package/dist/index.js +1 -1
- package/dist/middleware-runner.js +1 -0
- package/dist/permissions.js +1 -0
- package/dist/pikku-state.js +7 -1
- package/dist/schema.js +1 -1
- package/dist/services/gateway-service.d.ts +19 -0
- package/dist/services/gateway-service.js +1 -0
- package/dist/services/in-memory-workflow-service.d.ts +8 -2
- package/dist/services/in-memory-workflow-service.js +28 -1
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +1 -0
- package/dist/services/local-gateway-service.d.ts +22 -0
- package/dist/services/local-gateway-service.js +51 -0
- package/dist/services/workflow-service.d.ts +8 -2
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/service-tests.d.ts +31 -0
- package/dist/testing/service-tests.js +598 -0
- package/dist/types/core.types.d.ts +12 -2
- package/dist/types/state.types.d.ts +9 -2
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +23 -0
- package/dist/utils.js +1 -1
- package/dist/wirings/ai-agent/agent-dynamic-workflow.d.ts +6 -0
- package/dist/wirings/ai-agent/agent-dynamic-workflow.js +348 -0
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +1 -1
- package/dist/wirings/ai-agent/ai-agent-memory.js +19 -7
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -7
- package/dist/wirings/ai-agent/ai-agent-prepare.js +141 -48
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +4 -0
- package/dist/wirings/ai-agent/ai-agent-runner.js +381 -27
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +7 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +126 -48
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +57 -3
- package/dist/wirings/ai-agent/index.d.ts +2 -3
- package/dist/wirings/ai-agent/index.js +1 -2
- package/dist/wirings/channel/channel-handler.d.ts +5 -2
- package/dist/wirings/channel/channel-handler.js +16 -2
- package/dist/wirings/channel/channel-middleware-runner.js +1 -0
- package/dist/wirings/channel/channel.types.d.ts +7 -7
- package/dist/wirings/channel/index.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-handler.d.ts +8 -1
- package/dist/wirings/channel/local/local-channel-handler.js +22 -3
- package/dist/wirings/channel/local/local-channel-runner.js +28 -5
- package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +2 -1
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +1 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +5 -2
- package/dist/wirings/cli/cli-runner.js +13 -2
- package/dist/wirings/cli/cli.types.d.ts +1 -0
- package/dist/wirings/gateway/gateway-runner.d.ts +24 -0
- package/dist/wirings/gateway/gateway-runner.js +325 -0
- package/dist/wirings/gateway/gateway.types.d.ts +127 -0
- package/dist/wirings/gateway/gateway.types.js +1 -0
- package/dist/wirings/gateway/index.d.ts +2 -0
- package/dist/wirings/gateway/index.js +1 -0
- package/dist/wirings/http/http-routes.js +0 -1
- package/dist/wirings/http/http-runner.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +28 -3
- package/dist/wirings/http/http.types.d.ts +3 -11
- package/dist/wirings/http/index.d.ts +2 -1
- package/dist/wirings/http/index.js +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.js +3 -0
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-response.js +4 -4
- package/dist/wirings/http/web-request.d.ts +12 -0
- package/dist/wirings/http/web-request.js +85 -0
- package/dist/wirings/mcp/mcp-endpoint-registry.js +1 -1
- package/dist/wirings/mcp/mcp-runner.js +13 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +30 -6
- package/dist/wirings/rpc/rpc-runner.js +36 -14
- package/dist/wirings/rpc/rpc-types.d.ts +6 -1
- package/dist/wirings/rpc/wire-addon.d.ts +1 -0
- package/dist/wirings/rpc/wire-addon.js +1 -1
- package/dist/wirings/scheduler/scheduler-runner.js +1 -0
- package/dist/wirings/workflow/graph/graph-validation.d.ts +3 -0
- package/dist/wirings/workflow/graph/graph-validation.js +175 -0
- package/dist/wirings/workflow/graph/index.d.ts +1 -0
- package/dist/wirings/workflow/graph/index.js +1 -0
- package/dist/wirings/workflow/index.d.ts +1 -1
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +8 -2
- package/dist/wirings/workflow/pikku-workflow-service.js +1 -2
- package/dist/wirings/workflow/workflow.types.d.ts +10 -1
- package/package.json +6 -3
- package/src/crypto-utils.test.ts +99 -1
- package/src/crypto-utils.ts +114 -0
- package/src/function/function-runner.ts +5 -5
- package/src/function/functions.types.ts +38 -1
- package/src/handle-error.test.ts +65 -2
- package/src/handle-error.ts +8 -4
- package/src/index.ts +14 -0
- package/src/middleware-runner.ts +1 -0
- package/src/permissions.ts +1 -0
- package/src/pikku-state.ts +8 -1
- package/src/schema.ts +1 -1
- package/src/services/gateway-service.ts +20 -0
- package/src/services/in-memory-workflow-service.ts +45 -2
- package/src/services/index.ts +2 -0
- package/src/services/local-gateway-service.ts +62 -0
- package/src/services/workflow-service.ts +12 -1
- package/src/testing/index.ts +2 -0
- package/src/testing/service-tests.ts +873 -0
- package/src/types/core.types.ts +12 -1
- package/src/types/state.types.ts +12 -2
- package/src/utils/hash.test.ts +68 -0
- package/src/utils/hash.ts +26 -0
- package/src/utils.ts +1 -1
- package/src/wirings/ai-agent/agent-dynamic-workflow.ts +469 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +17 -7
- package/src/wirings/ai-agent/ai-agent-prepare.ts +194 -62
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +3 -1
- package/src/wirings/ai-agent/ai-agent-runner.ts +553 -31
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +209 -2
- package/src/wirings/ai-agent/ai-agent-stream.ts +195 -91
- package/src/wirings/ai-agent/ai-agent.types.ts +57 -3
- package/src/wirings/ai-agent/index.ts +3 -5
- package/src/wirings/channel/channel-handler.ts +41 -4
- package/src/wirings/channel/channel-middleware-runner.ts +1 -0
- package/src/wirings/channel/channel.types.ts +12 -7
- package/src/wirings/channel/index.ts +1 -0
- package/src/wirings/channel/local/local-channel-handler.ts +31 -3
- package/src/wirings/channel/local/local-channel-runner.ts +32 -8
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +2 -0
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +8 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +5 -2
- package/src/wirings/cli/cli-runner.ts +15 -2
- package/src/wirings/cli/cli.types.ts +1 -0
- package/src/wirings/gateway/gateway-runner.test.ts +474 -0
- package/src/wirings/gateway/gateway-runner.ts +411 -0
- package/src/wirings/gateway/gateway.types.ts +149 -0
- package/src/wirings/gateway/index.ts +13 -0
- package/src/wirings/http/http-routes.ts +0 -1
- package/src/wirings/http/http-runner.ts +38 -10
- package/src/wirings/http/http.types.ts +3 -12
- package/src/wirings/http/index.ts +3 -0
- package/src/wirings/http/pikku-fetch-http-request.ts +4 -0
- package/src/wirings/http/pikku-fetch-http-response.ts +4 -4
- package/src/wirings/http/web-request.test.ts +236 -0
- package/src/wirings/http/web-request.ts +104 -0
- package/src/wirings/mcp/mcp-endpoint-registry.ts +1 -1
- package/src/wirings/mcp/mcp-runner.ts +30 -12
- package/src/wirings/rpc/rpc-runner.ts +45 -24
- package/src/wirings/rpc/rpc-types.ts +6 -1
- package/src/wirings/rpc/wire-addon.ts +2 -1
- package/src/wirings/scheduler/scheduler-runner.ts +1 -0
- package/src/wirings/workflow/graph/graph-validation.test.ts +170 -0
- package/src/wirings/workflow/graph/graph-validation.ts +237 -0
- package/src/wirings/workflow/graph/index.ts +5 -0
- package/src/wirings/workflow/index.ts +1 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +14 -3
- package/src/wirings/workflow/workflow.types.ts +9 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +0 -5
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +0 -146
- package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +0 -363
- package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +0 -214
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
CoreUserSession,
|
|
5
5
|
} from '../../types/core.types.js'
|
|
6
6
|
import type {
|
|
7
|
+
BinaryData,
|
|
7
8
|
ChannelMessageMeta,
|
|
8
9
|
CoreChannel,
|
|
9
10
|
PikkuChannelHandler,
|
|
@@ -97,11 +98,18 @@ export const processMessageHandlers = (
|
|
|
97
98
|
return
|
|
98
99
|
}
|
|
99
100
|
|
|
101
|
+
const routeMeta = getRouteMeta(
|
|
102
|
+
channelConfig.name,
|
|
103
|
+
routingProperty,
|
|
104
|
+
routerValue
|
|
105
|
+
)
|
|
100
106
|
const {
|
|
101
|
-
|
|
107
|
+
packageName,
|
|
102
108
|
middleware: routeInheritedMiddleware,
|
|
103
109
|
permissions: inheritedPermissions,
|
|
104
|
-
} =
|
|
110
|
+
} = routeMeta
|
|
111
|
+
|
|
112
|
+
const pikkuFuncId = routeMeta.pikkuFuncId
|
|
105
113
|
|
|
106
114
|
// Get wire middleware: channel-level middleware + message-specific middleware
|
|
107
115
|
const channelWireMiddleware = channelConfig.middleware || []
|
|
@@ -145,16 +153,18 @@ export const processMessageHandlers = (
|
|
|
145
153
|
wireChannelMiddleware: wireChannelMiddleware as any,
|
|
146
154
|
inheritedPermissions,
|
|
147
155
|
wirePermissions,
|
|
156
|
+
coerceDataFromSchema: true,
|
|
148
157
|
tags: channelConfig.tags,
|
|
149
158
|
sessionService: userSession,
|
|
150
159
|
wire: {
|
|
151
160
|
channel: channelHandler.getChannel(),
|
|
152
161
|
...(userSession && createMiddlewareSessionWireProps(userSession)),
|
|
153
162
|
},
|
|
163
|
+
packageName,
|
|
154
164
|
})
|
|
155
165
|
}
|
|
156
166
|
|
|
157
|
-
|
|
167
|
+
const onMessage = async (rawData: unknown): Promise<unknown> => {
|
|
158
168
|
let result: unknown
|
|
159
169
|
let processed = false
|
|
160
170
|
|
|
@@ -198,7 +208,10 @@ export const processMessageHandlers = (
|
|
|
198
208
|
// Default handler if no routes matched and json data wasn't parsed
|
|
199
209
|
if (!processed && channelConfig.onMessage) {
|
|
200
210
|
processed = true
|
|
201
|
-
result = await processMessage(
|
|
211
|
+
result = await processMessage(
|
|
212
|
+
rawData as JSONValue,
|
|
213
|
+
channelConfig.onMessage
|
|
214
|
+
)
|
|
202
215
|
}
|
|
203
216
|
|
|
204
217
|
if (!processed) {
|
|
@@ -210,4 +223,28 @@ export const processMessageHandlers = (
|
|
|
210
223
|
|
|
211
224
|
return result
|
|
212
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 }
|
|
213
250
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { PikkuError } from '../../errors/error-handler.js'
|
|
2
1
|
import type {
|
|
3
2
|
HTTPFunctionMetaInputTypes,
|
|
4
3
|
PikkuHTTPRequest,
|
|
@@ -10,6 +9,8 @@ import type {
|
|
|
10
9
|
PermissionMetadata,
|
|
11
10
|
} from '../../types/core.types.js'
|
|
12
11
|
|
|
12
|
+
export type BinaryData = ArrayBuffer | Uint8Array
|
|
13
|
+
|
|
13
14
|
export type CorePikkuChannelMiddleware<Services = any, Event = unknown> = (
|
|
14
15
|
services: Services,
|
|
15
16
|
event: Event,
|
|
@@ -45,6 +46,7 @@ export type RunChannelParams<ChannelData> = {
|
|
|
45
46
|
|
|
46
47
|
export interface ChannelMessageMeta {
|
|
47
48
|
pikkuFuncId: string
|
|
49
|
+
packageName?: string
|
|
48
50
|
summary?: string
|
|
49
51
|
description?: string
|
|
50
52
|
errors?: string[]
|
|
@@ -64,6 +66,7 @@ export interface ChannelMeta {
|
|
|
64
66
|
disconnect: ChannelMessageMeta | null
|
|
65
67
|
message: ChannelMessageMeta | null
|
|
66
68
|
messageWirings: Record<string, Record<string, ChannelMessageMeta>>
|
|
69
|
+
binary?: boolean | null
|
|
67
70
|
summary?: string
|
|
68
71
|
description?: string
|
|
69
72
|
errors?: string[]
|
|
@@ -132,12 +135,12 @@ export type CoreChannel<
|
|
|
132
135
|
>
|
|
133
136
|
permissions?: CorePermissionGroup<PikkuPermission>
|
|
134
137
|
auth?: boolean
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
binary?: boolean | null
|
|
139
|
+
onBinaryMessage?: (
|
|
140
|
+
services: any,
|
|
141
|
+
data: BinaryData,
|
|
142
|
+
channel: PikkuChannel<ChannelData, any>
|
|
143
|
+
) => Promise<BinaryData | void> | BinaryData | void
|
|
141
144
|
tags?: string[]
|
|
142
145
|
}
|
|
143
146
|
|
|
@@ -149,6 +152,7 @@ export interface PikkuChannel<OpeningData, out Out> {
|
|
|
149
152
|
openingData: OpeningData
|
|
150
153
|
// The data to send. This will fail is the stream has been closed.
|
|
151
154
|
send(data: Out, isBinary?: boolean): Promise<void> | void
|
|
155
|
+
sendBinary(data: BinaryData): Promise<void> | void
|
|
152
156
|
// This will close the channel.
|
|
153
157
|
close(): Promise<void> | void
|
|
154
158
|
// The current state of the channel
|
|
@@ -157,6 +161,7 @@ export interface PikkuChannel<OpeningData, out Out> {
|
|
|
157
161
|
|
|
158
162
|
export interface PikkuChannelHandler<OpeningData = unknown, Out = unknown> {
|
|
159
163
|
send(message: Out, isBinary?: boolean): Promise<void> | void
|
|
164
|
+
sendBinary(data: BinaryData): Promise<void> | void
|
|
160
165
|
getChannel(): PikkuChannel<OpeningData, Out>
|
|
161
166
|
}
|
|
162
167
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BinaryData } from '../channel.types.js'
|
|
1
2
|
import { PikkuAbstractChannelHandler } from '../pikku-abstract-channel-handler.js'
|
|
2
3
|
|
|
3
4
|
export class PikkuLocalChannelHandler<
|
|
@@ -5,9 +6,11 @@ export class PikkuLocalChannelHandler<
|
|
|
5
6
|
Out = unknown,
|
|
6
7
|
> extends PikkuAbstractChannelHandler<OpeningData, Out> {
|
|
7
8
|
private onMessageCallback?: (message: unknown) => void
|
|
9
|
+
private onBinaryMessageCallback?: (data: BinaryData) => void
|
|
8
10
|
private openCallBack?: () => void
|
|
9
|
-
private
|
|
11
|
+
private closeCallbacks: (() => void)[] = []
|
|
10
12
|
private sendCallback?: (message: Out, isBinary?: boolean) => void
|
|
13
|
+
private sendBinaryCallback?: (data: BinaryData) => void
|
|
11
14
|
|
|
12
15
|
public registerOnOpen(callback: () => void): void {
|
|
13
16
|
this.openCallBack = callback
|
|
@@ -28,8 +31,20 @@ export class PikkuLocalChannelHandler<
|
|
|
28
31
|
return this.onMessageCallback?.(data)
|
|
29
32
|
}
|
|
30
33
|
|
|
34
|
+
public registerOnBinaryMessage(
|
|
35
|
+
callback: (
|
|
36
|
+
data: BinaryData
|
|
37
|
+
) => Promise<BinaryData | void> | BinaryData | void
|
|
38
|
+
): void {
|
|
39
|
+
this.onBinaryMessageCallback = callback
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public async binaryMessage(data: BinaryData): Promise<BinaryData | void> {
|
|
43
|
+
return this.onBinaryMessageCallback?.(data)
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
public registerOnClose(callback: () => void): void {
|
|
32
|
-
this.
|
|
47
|
+
this.closeCallbacks.push(callback)
|
|
33
48
|
}
|
|
34
49
|
|
|
35
50
|
public close() {
|
|
@@ -37,7 +52,9 @@ export class PikkuLocalChannelHandler<
|
|
|
37
52
|
return
|
|
38
53
|
}
|
|
39
54
|
super.close()
|
|
40
|
-
this.
|
|
55
|
+
for (const cb of this.closeCallbacks) {
|
|
56
|
+
cb()
|
|
57
|
+
}
|
|
41
58
|
}
|
|
42
59
|
|
|
43
60
|
public registerOnSend(send: (message: Out) => void) {
|
|
@@ -50,4 +67,15 @@ export class PikkuLocalChannelHandler<
|
|
|
50
67
|
}
|
|
51
68
|
return this.sendCallback?.(message, isBinary)
|
|
52
69
|
}
|
|
70
|
+
|
|
71
|
+
public registerOnSendBinary(send: (data: BinaryData) => void) {
|
|
72
|
+
this.sendBinaryCallback = send
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public sendBinary(data: BinaryData): void {
|
|
76
|
+
if (!this.sendBinaryCallback) {
|
|
77
|
+
throw new Error('No sendBinary callback registered')
|
|
78
|
+
}
|
|
79
|
+
this.sendBinaryCallback(data)
|
|
80
|
+
}
|
|
53
81
|
}
|
|
@@ -119,9 +119,12 @@ export const runLocalChannel = async ({
|
|
|
119
119
|
if (result !== undefined) {
|
|
120
120
|
await channel.send(result)
|
|
121
121
|
}
|
|
122
|
-
} catch (e) {
|
|
122
|
+
} catch (e: any) {
|
|
123
123
|
singletonServices.logger.error(`Error handling onConnect: ${e}`)
|
|
124
|
-
channel.send({
|
|
124
|
+
channel.send({
|
|
125
|
+
error: e.message || 'Unknown error',
|
|
126
|
+
errorName: e.constructor?.name,
|
|
127
|
+
})
|
|
125
128
|
}
|
|
126
129
|
}
|
|
127
130
|
})
|
|
@@ -138,16 +141,19 @@ export const runLocalChannel = async ({
|
|
|
138
141
|
channel,
|
|
139
142
|
channelMiddlewareMeta: meta.channelMiddleware,
|
|
140
143
|
})
|
|
141
|
-
} catch (e) {
|
|
144
|
+
} catch (e: any) {
|
|
142
145
|
singletonServices.logger.error(`Error handling onDisconnect: ${e}`)
|
|
143
|
-
channel.send({
|
|
146
|
+
channel.send({
|
|
147
|
+
error: e.message || 'Unknown error',
|
|
148
|
+
errorName: e.constructor?.name,
|
|
149
|
+
})
|
|
144
150
|
}
|
|
145
151
|
}
|
|
146
152
|
|
|
147
153
|
await closeServices()
|
|
148
154
|
})
|
|
149
155
|
|
|
150
|
-
const onMessage = processMessageHandlers(
|
|
156
|
+
const { onMessage, onBinaryMessage } = processMessageHandlers(
|
|
151
157
|
services,
|
|
152
158
|
channelConfig as any,
|
|
153
159
|
channelHandler,
|
|
@@ -157,11 +163,29 @@ export const runLocalChannel = async ({
|
|
|
157
163
|
try {
|
|
158
164
|
const result = await onMessage(data)
|
|
159
165
|
await channel.send(result)
|
|
160
|
-
} catch (e) {
|
|
161
|
-
singletonServices.logger.error(
|
|
162
|
-
channel.send({
|
|
166
|
+
} catch (e: any) {
|
|
167
|
+
singletonServices.logger.error(e)
|
|
168
|
+
channel.send({
|
|
169
|
+
error: e.message || 'Unknown error',
|
|
170
|
+
errorName: e.constructor?.name,
|
|
171
|
+
})
|
|
172
|
+
setTimeout(() => channel.close(), 200)
|
|
163
173
|
}
|
|
164
174
|
})
|
|
175
|
+
if (onBinaryMessage) {
|
|
176
|
+
channelHandler.registerOnBinaryMessage(async (data) => {
|
|
177
|
+
try {
|
|
178
|
+
const result = await onBinaryMessage(data)
|
|
179
|
+
if (result) {
|
|
180
|
+
await channel.sendBinary(result)
|
|
181
|
+
}
|
|
182
|
+
} catch (e) {
|
|
183
|
+
singletonServices.logger.error(
|
|
184
|
+
`Error handling binary message: ${e.message}`
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
}
|
|
165
189
|
} catch (e: any) {
|
|
166
190
|
handleHTTPError(
|
|
167
191
|
e,
|
|
@@ -10,6 +10,8 @@ class TestChannelHandler extends PikkuAbstractChannelHandler<
|
|
|
10
10
|
public async send(message: { msg: string }, isBinary = false): Promise<void> {
|
|
11
11
|
// Mock send implementation
|
|
12
12
|
}
|
|
13
|
+
|
|
14
|
+
public sendBinary(_data: ArrayBuffer | Uint8Array): void {}
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
let handler: TestChannelHandler
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
BinaryData,
|
|
3
|
+
PikkuChannel,
|
|
4
|
+
PikkuChannelHandler,
|
|
5
|
+
} from './channel.types.js'
|
|
2
6
|
|
|
3
7
|
export abstract class PikkuAbstractChannelHandler<
|
|
4
8
|
OpeningData = unknown,
|
|
@@ -15,12 +19,15 @@ export abstract class PikkuAbstractChannelHandler<
|
|
|
15
19
|
|
|
16
20
|
public abstract send(message: Out, isBinary?: boolean): Promise<void> | void
|
|
17
21
|
|
|
22
|
+
public abstract sendBinary(data: BinaryData): Promise<void> | void
|
|
23
|
+
|
|
18
24
|
public getChannel(): PikkuChannel<OpeningData, Out> {
|
|
19
25
|
if (!this.channel) {
|
|
20
26
|
this.channel = {
|
|
21
27
|
channelId: this.channelId,
|
|
22
28
|
openingData: this.openingData,
|
|
23
29
|
send: this.send.bind(this),
|
|
30
|
+
sendBinary: this.sendBinary.bind(this),
|
|
24
31
|
close: this.close.bind(this),
|
|
25
32
|
state: 'initial',
|
|
26
33
|
}
|
|
@@ -265,7 +265,7 @@ export const runChannelMessage = async (
|
|
|
265
265
|
|
|
266
266
|
let response: unknown
|
|
267
267
|
try {
|
|
268
|
-
const onMessage = processMessageHandlers(
|
|
268
|
+
const { onMessage } = processMessageHandlers(
|
|
269
269
|
services,
|
|
270
270
|
channelConfig,
|
|
271
271
|
channelHandler,
|
|
@@ -276,7 +276,10 @@ export const runChannelMessage = async (
|
|
|
276
276
|
singletonServices.logger.error(
|
|
277
277
|
`Error processing message: ${e.message || e}`
|
|
278
278
|
)
|
|
279
|
-
return {
|
|
279
|
+
return {
|
|
280
|
+
error: e.message || 'Unknown error',
|
|
281
|
+
errorName: e.constructor?.name,
|
|
282
|
+
}
|
|
280
283
|
} finally {
|
|
281
284
|
if (wireServices) {
|
|
282
285
|
await closeWireServices(singletonServices.logger, wireServices)
|
|
@@ -218,7 +218,9 @@ function pluckCLIData(
|
|
|
218
218
|
const funcMeta = pikkuState(null, 'function', 'meta')[funcName]
|
|
219
219
|
const schemaName = funcMeta?.inputSchemaName
|
|
220
220
|
const schema = schemaName
|
|
221
|
-
? pikkuState(null, 'misc', 'schemas').get(
|
|
221
|
+
? pikkuState(funcMeta?.packageName ?? null, 'misc', 'schemas').get(
|
|
222
|
+
schemaName
|
|
223
|
+
)
|
|
222
224
|
: null
|
|
223
225
|
|
|
224
226
|
if (schema && schema.properties) {
|
|
@@ -226,7 +228,13 @@ function pluckCLIData(
|
|
|
226
228
|
const result: Record<string, any> = {}
|
|
227
229
|
for (const key of Object.keys(schema.properties)) {
|
|
228
230
|
if (key in mergedData) {
|
|
229
|
-
|
|
231
|
+
let value = mergedData[key]
|
|
232
|
+
// CLI passes all values as strings — coerce to array when schema expects one
|
|
233
|
+
const propSchema = schema.properties[key]
|
|
234
|
+
if (propSchema?.type === 'array' && !Array.isArray(value)) {
|
|
235
|
+
value = typeof value === 'string' ? value.split(',') : [value]
|
|
236
|
+
}
|
|
237
|
+
result[key] = value
|
|
230
238
|
} else if (availableOptions[key]?.default !== undefined) {
|
|
231
239
|
// Apply default if not provided
|
|
232
240
|
result[key] = availableOptions[key].default
|
|
@@ -321,6 +329,9 @@ export async function runCLICommand({
|
|
|
321
329
|
await Promise.resolve(renderer(singletonServices, data, undefined))
|
|
322
330
|
}
|
|
323
331
|
},
|
|
332
|
+
sendBinary: () => {
|
|
333
|
+
throw new Error('Binary data is not supported on CLI channels')
|
|
334
|
+
},
|
|
324
335
|
close: () => {
|
|
325
336
|
if (channel) {
|
|
326
337
|
channel.state = 'closed'
|
|
@@ -351,9 +362,11 @@ export async function runCLICommand({
|
|
|
351
362
|
wireMiddleware: allWireMiddleware,
|
|
352
363
|
inheritedPermissions: currentCommand.permissions,
|
|
353
364
|
wirePermissions: undefined,
|
|
365
|
+
coerceDataFromSchema: true,
|
|
354
366
|
tags: programData?.tags,
|
|
355
367
|
wire,
|
|
356
368
|
sessionService: userSession,
|
|
369
|
+
packageName: currentCommand.packageName,
|
|
357
370
|
})
|
|
358
371
|
|
|
359
372
|
// Apply renderer one final time with the final output (if renderer exists)
|