@pikku/core 0.11.0 → 0.11.2
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 +35 -1
- package/dist/errors/error-handler.js +3 -3
- package/dist/errors/errors.d.ts +1 -1
- package/dist/errors/errors.js +3 -3
- package/dist/function/function-runner.d.ts +8 -8
- package/dist/function/function-runner.js +88 -23
- package/dist/function/functions.types.d.ts +104 -33
- package/dist/function/functions.types.js +50 -7
- package/dist/handle-error.d.ts +1 -1
- package/dist/handle-error.js +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +5 -2
- package/dist/middleware/auth-apikey.d.ts +1 -1
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.d.ts +1 -1
- package/dist/middleware/auth-bearer.js +3 -3
- package/dist/middleware/auth-cookie.d.ts +1 -1
- package/dist/middleware/auth-cookie.js +5 -5
- package/dist/middleware/timeout.d.ts +1 -1
- package/dist/middleware/timeout.js +3 -2
- package/dist/middleware-runner.d.ts +6 -20
- package/dist/middleware-runner.js +19 -20
- package/dist/permissions.d.ts +6 -89
- package/dist/permissions.js +24 -81
- package/dist/pikku-state.d.ts +32 -104
- package/dist/pikku-state.js +140 -66
- package/dist/schema.d.ts +8 -6
- package/dist/schema.js +25 -13
- package/dist/services/user-session-service.d.ts +7 -3
- package/dist/services/user-session-service.js +8 -1
- package/dist/services/workflow-service.d.ts +38 -0
- package/dist/services/workflow-service.js +1 -0
- package/dist/types/core.types.d.ts +40 -41
- package/dist/types/core.types.js +4 -15
- package/dist/types/state.types.d.ts +135 -0
- package/dist/types/state.types.js +1 -0
- package/dist/utils.d.ts +9 -1
- package/dist/utils.js +48 -3
- package/dist/wirings/channel/channel-common.js +2 -3
- package/dist/wirings/channel/channel-handler.d.ts +3 -2
- package/dist/wirings/channel/channel-handler.js +7 -10
- package/dist/wirings/channel/channel-runner.d.ts +2 -2
- package/dist/wirings/channel/channel-runner.js +5 -5
- package/dist/wirings/channel/channel.types.d.ts +10 -5
- package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-runner.js +19 -26
- package/dist/wirings/channel/log-channels.js +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +43 -48
- package/dist/wirings/cli/channel/cli-channel-runner.js +3 -2
- package/dist/wirings/cli/cli-runner.d.ts +5 -5
- package/dist/wirings/cli/cli-runner.js +20 -38
- package/dist/wirings/cli/cli.types.d.ts +16 -11
- package/dist/wirings/forge-node/forge-node.types.d.ts +120 -0
- package/dist/wirings/forge-node/forge-node.types.js +38 -0
- package/dist/wirings/forge-node/index.d.ts +1 -0
- package/dist/wirings/forge-node/index.js +1 -0
- package/dist/wirings/http/http-runner.d.ts +8 -8
- package/dist/wirings/http/http-runner.js +46 -51
- package/dist/wirings/http/http.types.d.ts +19 -11
- package/dist/wirings/http/log-http-routes.js +1 -1
- package/dist/wirings/http/routers/path-to-regex.js +2 -2
- package/dist/wirings/mcp/mcp-runner.d.ts +2 -2
- package/dist/wirings/mcp/mcp-runner.js +33 -40
- package/dist/wirings/mcp/mcp.types.d.ts +6 -0
- package/dist/wirings/queue/queue-runner.d.ts +3 -3
- package/dist/wirings/queue/queue-runner.js +13 -23
- package/dist/wirings/queue/queue.types.d.ts +4 -11
- package/dist/wirings/rpc/index.d.ts +1 -1
- package/dist/wirings/rpc/index.js +1 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +17 -16
- package/dist/wirings/rpc/rpc-runner.js +98 -61
- package/dist/wirings/rpc/rpc-types.d.ts +7 -0
- package/dist/wirings/scheduler/log-schedulers.js +1 -1
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -3
- package/dist/wirings/scheduler/scheduler-runner.js +18 -29
- package/dist/wirings/scheduler/scheduler.types.d.ts +3 -8
- package/dist/wirings/trigger/index.d.ts +2 -0
- package/dist/wirings/trigger/index.js +2 -0
- package/dist/wirings/trigger/trigger-runner.d.ts +29 -0
- package/dist/wirings/trigger/trigger-runner.js +57 -0
- package/dist/wirings/trigger/trigger.types.d.ts +42 -0
- package/dist/wirings/trigger/trigger.types.js +1 -0
- package/dist/wirings/workflow/dsl/index.d.ts +5 -0
- package/dist/wirings/workflow/dsl/index.js +4 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +286 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.js +5 -0
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +5 -0
- package/dist/wirings/workflow/dsl/workflow-runner.js +22 -0
- package/dist/wirings/workflow/graph/graph-node.d.ts +122 -0
- package/dist/wirings/workflow/graph/graph-node.js +58 -0
- package/dist/wirings/workflow/graph/graph-runner.d.ts +35 -0
- package/dist/wirings/workflow/graph/graph-runner.js +452 -0
- package/dist/wirings/workflow/graph/index.d.ts +3 -0
- package/dist/wirings/workflow/graph/index.js +3 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +95 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.js +15 -0
- package/dist/wirings/workflow/index.d.ts +7 -3
- package/dist/wirings/workflow/index.js +6 -3
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +108 -10
- package/dist/wirings/workflow/pikku-workflow-service.js +274 -165
- package/dist/wirings/workflow/wire-workflow.d.ts +42 -0
- package/dist/wirings/workflow/wire-workflow.js +53 -0
- package/dist/wirings/workflow/workflow-utils.d.ts +23 -0
- package/dist/wirings/workflow/workflow-utils.js +66 -0
- package/dist/wirings/workflow/workflow.types.d.ts +135 -128
- package/package.json +11 -2
- package/src/errors/error-handler.ts +3 -3
- package/src/errors/errors.ts +3 -3
- package/src/factory-functions.test.ts +9 -36
- package/src/function/function-runner.test.ts +58 -69
- package/src/function/function-runner.ts +130 -37
- package/src/function/functions.types.ts +193 -54
- package/src/handle-error.ts +1 -1
- package/src/index.ts +10 -5
- package/src/middleware/auth-apikey.test.ts +360 -0
- package/src/middleware/auth-apikey.ts +3 -7
- package/src/middleware/auth-bearer.test.ts +447 -0
- package/src/middleware/auth-bearer.ts +27 -33
- package/src/middleware/auth-cookie.test.ts +525 -0
- package/src/middleware/auth-cookie.ts +6 -6
- package/src/middleware/timeout.ts +4 -2
- package/src/middleware-runner.test.ts +58 -127
- package/src/middleware-runner.ts +29 -25
- package/src/permissions.test.ts +68 -130
- package/src/permissions.ts +41 -100
- package/src/pikku-state.ts +156 -201
- package/src/schema.ts +42 -13
- package/src/services/user-session-service.ts +14 -4
- package/src/services/workflow-service.ts +74 -0
- package/src/types/core.types.ts +79 -58
- package/src/types/state.types.ts +195 -0
- package/src/utils.ts +59 -4
- package/src/wirings/channel/channel-common.ts +4 -7
- package/src/wirings/channel/channel-handler.ts +17 -23
- package/src/wirings/channel/channel-runner.ts +7 -7
- package/src/wirings/channel/channel.types.ts +14 -11
- package/src/wirings/channel/local/local-channel-runner.test.ts +8 -4
- package/src/wirings/channel/local/local-channel-runner.ts +23 -38
- package/src/wirings/channel/log-channels.ts +1 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +53 -79
- package/src/wirings/cli/channel/cli-channel-runner.ts +4 -3
- package/src/wirings/cli/cli-runner.test.ts +26 -26
- package/src/wirings/cli/cli-runner.ts +34 -71
- package/src/wirings/cli/cli.types.ts +23 -16
- package/src/wirings/forge-node/forge-node.types.ts +135 -0
- package/src/wirings/forge-node/index.ts +1 -0
- package/src/wirings/http/http-runner.test.ts +10 -10
- package/src/wirings/http/http-runner.ts +56 -66
- package/src/wirings/http/http.types.ts +19 -14
- package/src/wirings/http/log-http-routes.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.test.ts +30 -19
- package/src/wirings/http/routers/path-to-regex.ts +2 -2
- package/src/wirings/mcp/mcp-runner.ts +44 -69
- package/src/wirings/mcp/mcp.types.ts +6 -0
- package/src/wirings/queue/queue-runner.test.ts +641 -0
- package/src/wirings/queue/queue-runner.ts +16 -38
- package/src/wirings/queue/queue.types.ts +4 -11
- package/src/wirings/rpc/index.ts +1 -1
- package/src/wirings/rpc/rpc-runner.ts +129 -77
- package/src/wirings/rpc/rpc-types.ts +8 -0
- package/src/wirings/scheduler/log-schedulers.ts +1 -1
- package/src/wirings/scheduler/scheduler-runner.test.ts +627 -0
- package/src/wirings/scheduler/scheduler-runner.ts +29 -55
- package/src/wirings/scheduler/scheduler.types.ts +3 -9
- package/src/wirings/trigger/index.ts +2 -0
- package/src/wirings/trigger/trigger-runner.ts +96 -0
- package/src/wirings/trigger/trigger.types.ts +56 -0
- package/src/wirings/workflow/dsl/index.ts +30 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +312 -0
- package/src/wirings/workflow/dsl/workflow-runner.ts +27 -0
- package/src/wirings/workflow/graph/graph-node.ts +227 -0
- package/src/wirings/workflow/graph/graph-runner.ts +694 -0
- package/src/wirings/workflow/graph/index.ts +3 -0
- package/src/wirings/workflow/graph/workflow-graph.types.ts +126 -0
- package/src/wirings/workflow/index.ts +60 -12
- package/src/wirings/workflow/pikku-workflow-service.ts +401 -195
- package/src/wirings/workflow/wire-workflow.ts +94 -0
- package/src/wirings/workflow/workflow-utils.ts +120 -0
- package/src/wirings/workflow/workflow.types.ts +167 -188
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/workflow/workflow-runner.d.ts +0 -35
- package/dist/wirings/workflow/workflow-runner.js +0 -68
- package/src/wirings/workflow/workflow-runner.ts +0 -85
|
@@ -3,11 +3,7 @@ import * as assert from 'node:assert'
|
|
|
3
3
|
import { addFunction, runPikkuFunc } from './function-runner.js'
|
|
4
4
|
import { addMiddleware, addPermission } from '../index.js'
|
|
5
5
|
import { resetPikkuState, pikkuState } from '../pikku-state.js'
|
|
6
|
-
import {
|
|
7
|
-
CoreServices,
|
|
8
|
-
CorePikkuMiddleware,
|
|
9
|
-
PikkuWiringTypes,
|
|
10
|
-
} from '../types/core.types.js'
|
|
6
|
+
import { CoreServices, CorePikkuMiddleware } from '../types/core.types.js'
|
|
11
7
|
import { CorePermissionGroup } from './functions.types.js'
|
|
12
8
|
|
|
13
9
|
beforeEach(() => {
|
|
@@ -25,7 +21,7 @@ const addTestFunction = (funcName: string, funcConfig: any) => {
|
|
|
25
21
|
const permissions = funcConfig.tags
|
|
26
22
|
? funcConfig.tags.map((tag: string) => ({ type: 'tag' as const, tag }))
|
|
27
23
|
: undefined
|
|
28
|
-
pikkuState('function', 'meta')[funcName] = {
|
|
24
|
+
pikkuState(null, 'function', 'meta')[funcName] = {
|
|
29
25
|
pikkuFuncName: funcName,
|
|
30
26
|
inputSchemaName: null,
|
|
31
27
|
outputSchemaName: null,
|
|
@@ -51,7 +47,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
51
47
|
test('should execute middleware in correct order: wiringTags → wiringMiddleware → funcTags → funcMiddleware', async () => {
|
|
52
48
|
const executionOrder: string[] = []
|
|
53
49
|
const createMiddleware = (name: string): CorePikkuMiddleware => {
|
|
54
|
-
return async (services,
|
|
50
|
+
return async (services, wire, next) => {
|
|
55
51
|
executionOrder.push(name)
|
|
56
52
|
await next()
|
|
57
53
|
}
|
|
@@ -71,7 +67,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
71
67
|
})
|
|
72
68
|
|
|
73
69
|
const result = await runPikkuFunc(
|
|
74
|
-
|
|
70
|
+
'rpc',
|
|
75
71
|
Math.random().toString(),
|
|
76
72
|
'testFunc',
|
|
77
73
|
{
|
|
@@ -81,7 +77,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
81
77
|
wireMiddleware: [createMiddleware('wiringMiddleware')],
|
|
82
78
|
inheritedMiddleware: [{ type: 'tag', tag: 'wiringTag' }],
|
|
83
79
|
auth: false,
|
|
84
|
-
|
|
80
|
+
wire: {},
|
|
85
81
|
}
|
|
86
82
|
)
|
|
87
83
|
|
|
@@ -141,7 +137,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
141
137
|
})
|
|
142
138
|
|
|
143
139
|
const result = await runPikkuFunc(
|
|
144
|
-
|
|
140
|
+
'rpc',
|
|
145
141
|
Math.random().toString(),
|
|
146
142
|
'testFunc',
|
|
147
143
|
{
|
|
@@ -151,7 +147,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
151
147
|
wirePermissions: wiringPermissions,
|
|
152
148
|
tags: ['wiringTag'],
|
|
153
149
|
auth: false,
|
|
154
|
-
|
|
150
|
+
wire: {},
|
|
155
151
|
}
|
|
156
152
|
)
|
|
157
153
|
|
|
@@ -176,13 +172,13 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
176
172
|
})
|
|
177
173
|
|
|
178
174
|
await assert.rejects(
|
|
179
|
-
runPikkuFunc(
|
|
175
|
+
runPikkuFunc('rpc', Math.random().toString(), 'testFunc', {
|
|
180
176
|
singletonServices: mockSingletonServices,
|
|
181
177
|
getAllServices: () => mockServices,
|
|
182
178
|
data: () => ({}),
|
|
183
179
|
tags: ['wiringTag'],
|
|
184
180
|
auth: false,
|
|
185
|
-
|
|
181
|
+
wire: {},
|
|
186
182
|
}),
|
|
187
183
|
{
|
|
188
184
|
message: 'Permission denied',
|
|
@@ -200,13 +196,13 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
200
196
|
})
|
|
201
197
|
|
|
202
198
|
await assert.rejects(
|
|
203
|
-
runPikkuFunc(
|
|
199
|
+
runPikkuFunc('rpc', Math.random().toString(), 'testFunc', {
|
|
204
200
|
singletonServices: mockSingletonServices,
|
|
205
201
|
getAllServices: () => mockServices,
|
|
206
202
|
data: () => ({}),
|
|
207
203
|
wirePermissions: wiringPermissions,
|
|
208
204
|
auth: false,
|
|
209
|
-
|
|
205
|
+
wire: {},
|
|
210
206
|
}),
|
|
211
207
|
{
|
|
212
208
|
message: 'Permission denied',
|
|
@@ -225,12 +221,12 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
225
221
|
})
|
|
226
222
|
|
|
227
223
|
await assert.rejects(
|
|
228
|
-
runPikkuFunc(
|
|
224
|
+
runPikkuFunc('rpc', Math.random().toString(), 'testFunc', {
|
|
229
225
|
singletonServices: mockSingletonServices,
|
|
230
226
|
getAllServices: () => mockServices,
|
|
231
227
|
data: () => ({}),
|
|
232
228
|
auth: false,
|
|
233
|
-
|
|
229
|
+
wire: {},
|
|
234
230
|
}),
|
|
235
231
|
{
|
|
236
232
|
message: 'Permission denied',
|
|
@@ -249,12 +245,12 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
249
245
|
})
|
|
250
246
|
|
|
251
247
|
await assert.rejects(
|
|
252
|
-
runPikkuFunc(
|
|
248
|
+
runPikkuFunc('rpc', Math.random().toString(), 'testFunc', {
|
|
253
249
|
singletonServices: mockSingletonServices,
|
|
254
250
|
getAllServices: () => mockServices,
|
|
255
251
|
data: () => ({}),
|
|
256
252
|
auth: false,
|
|
257
|
-
|
|
253
|
+
wire: {},
|
|
258
254
|
}),
|
|
259
255
|
{
|
|
260
256
|
message: 'Permission denied',
|
|
@@ -267,7 +263,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
267
263
|
|
|
268
264
|
const duplicatedMiddleware: CorePikkuMiddleware = async (
|
|
269
265
|
services,
|
|
270
|
-
|
|
266
|
+
wire,
|
|
271
267
|
next
|
|
272
268
|
) => {
|
|
273
269
|
executionCount++
|
|
@@ -283,18 +279,13 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
283
279
|
tags: ['testTag'], // Same middleware via tag
|
|
284
280
|
})
|
|
285
281
|
|
|
286
|
-
await runPikkuFunc(
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
data: () => ({}),
|
|
294
|
-
auth: false,
|
|
295
|
-
interaction: {},
|
|
296
|
-
}
|
|
297
|
-
)
|
|
282
|
+
await runPikkuFunc('rpc', Math.random().toString(), 'testFunc', {
|
|
283
|
+
singletonServices: mockSingletonServices,
|
|
284
|
+
getAllServices: () => mockServices,
|
|
285
|
+
data: () => ({}),
|
|
286
|
+
auth: false,
|
|
287
|
+
wire: {},
|
|
288
|
+
})
|
|
298
289
|
|
|
299
290
|
// Should only execute once due to deduplication
|
|
300
291
|
assert.equal(executionCount, 1)
|
|
@@ -336,7 +327,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
336
327
|
})
|
|
337
328
|
|
|
338
329
|
const result = await runPikkuFunc(
|
|
339
|
-
|
|
330
|
+
'rpc',
|
|
340
331
|
Math.random().toString(),
|
|
341
332
|
'testFunc',
|
|
342
333
|
{
|
|
@@ -344,7 +335,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
344
335
|
getAllServices: () => mockServices,
|
|
345
336
|
data: () => ({}),
|
|
346
337
|
auth: false,
|
|
347
|
-
|
|
338
|
+
wire: {},
|
|
348
339
|
}
|
|
349
340
|
)
|
|
350
341
|
|
|
@@ -364,7 +355,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
364
355
|
})
|
|
365
356
|
|
|
366
357
|
const result = await runPikkuFunc(
|
|
367
|
-
|
|
358
|
+
'rpc',
|
|
368
359
|
Math.random().toString(),
|
|
369
360
|
'simpleFunc',
|
|
370
361
|
{
|
|
@@ -372,7 +363,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
372
363
|
getAllServices: () => mockServices,
|
|
373
364
|
data: () => ({}),
|
|
374
365
|
auth: false,
|
|
375
|
-
|
|
366
|
+
wire: {},
|
|
376
367
|
}
|
|
377
368
|
)
|
|
378
369
|
|
|
@@ -384,7 +375,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
384
375
|
|
|
385
376
|
const wiringMiddleware: CorePikkuMiddleware = async (
|
|
386
377
|
services,
|
|
387
|
-
|
|
378
|
+
wire,
|
|
388
379
|
next
|
|
389
380
|
) => {
|
|
390
381
|
executionOrder.push('wiringMiddleware')
|
|
@@ -408,7 +399,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
408
399
|
})
|
|
409
400
|
|
|
410
401
|
const result = await runPikkuFunc(
|
|
411
|
-
|
|
402
|
+
'rpc',
|
|
412
403
|
Math.random().toString(),
|
|
413
404
|
'testFunc',
|
|
414
405
|
{
|
|
@@ -418,7 +409,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
418
409
|
wireMiddleware: [wiringMiddleware],
|
|
419
410
|
wirePermissions: wiringPermissions,
|
|
420
411
|
auth: false,
|
|
421
|
-
|
|
412
|
+
wire: {},
|
|
422
413
|
}
|
|
423
414
|
)
|
|
424
415
|
|
|
@@ -436,7 +427,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
436
427
|
|
|
437
428
|
const funcMiddleware: CorePikkuMiddleware = async (
|
|
438
429
|
services,
|
|
439
|
-
|
|
430
|
+
wire,
|
|
440
431
|
next
|
|
441
432
|
) => {
|
|
442
433
|
executionOrder.push('funcMiddleware')
|
|
@@ -462,7 +453,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
462
453
|
})
|
|
463
454
|
|
|
464
455
|
const result = await runPikkuFunc(
|
|
465
|
-
|
|
456
|
+
'rpc',
|
|
466
457
|
Math.random().toString(),
|
|
467
458
|
'testFunc',
|
|
468
459
|
{
|
|
@@ -470,7 +461,7 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
470
461
|
getAllServices: () => mockServices,
|
|
471
462
|
data: () => ({}),
|
|
472
463
|
auth: false,
|
|
473
|
-
|
|
464
|
+
wire: {},
|
|
474
465
|
}
|
|
475
466
|
)
|
|
476
467
|
|
|
@@ -486,69 +477,67 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
486
477
|
test('should pass correct parameters to function', async () => {
|
|
487
478
|
let receivedServices: any
|
|
488
479
|
let receivedData: any
|
|
489
|
-
let
|
|
480
|
+
let receivedWire: any
|
|
490
481
|
|
|
491
482
|
const testData = { test: 'data' }
|
|
492
|
-
const testSession = { userId: 'test-user' }
|
|
493
483
|
|
|
494
484
|
addTestFunction('testFunc', {
|
|
495
|
-
func: async (services, data,
|
|
485
|
+
func: async (services, data, wire) => {
|
|
496
486
|
receivedServices = services
|
|
497
487
|
receivedData = data
|
|
498
|
-
|
|
488
|
+
receivedWire = wire
|
|
499
489
|
return 'success'
|
|
500
490
|
},
|
|
501
491
|
})
|
|
502
492
|
|
|
503
|
-
await runPikkuFunc(
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
{
|
|
508
|
-
|
|
509
|
-
getAllServices: () => mockServices,
|
|
510
|
-
data: () => testData,
|
|
511
|
-
userSession: { get: () => testSession, set: () => {} } as any,
|
|
512
|
-
auth: false,
|
|
513
|
-
interaction: {},
|
|
514
|
-
}
|
|
515
|
-
)
|
|
493
|
+
await runPikkuFunc('rpc', Math.random().toString(), 'testFunc', {
|
|
494
|
+
singletonServices: mockServices,
|
|
495
|
+
data: () => testData,
|
|
496
|
+
auth: false,
|
|
497
|
+
wire: { rpc: {} },
|
|
498
|
+
})
|
|
516
499
|
|
|
517
|
-
assert.
|
|
500
|
+
assert.deepEqual(receivedServices, mockServices)
|
|
518
501
|
assert.equal(receivedData, testData)
|
|
519
|
-
|
|
502
|
+
// Check that wire has rpc service and session
|
|
503
|
+
assert.ok(receivedWire.rpc)
|
|
504
|
+
assert.equal(receivedWire.session, undefined)
|
|
520
505
|
})
|
|
521
506
|
|
|
522
|
-
test('should handle async
|
|
507
|
+
test('should handle async createWireServices function', async () => {
|
|
523
508
|
let servicesProvided: any
|
|
509
|
+
const wireServices = { customService: 'value' }
|
|
524
510
|
|
|
525
511
|
addTestFunction('testFunc', {
|
|
526
|
-
func: async (services) => {
|
|
512
|
+
func: async (services, data, wire) => {
|
|
527
513
|
servicesProvided = services
|
|
528
514
|
return 'success'
|
|
529
515
|
},
|
|
530
516
|
})
|
|
531
517
|
|
|
532
|
-
const
|
|
518
|
+
const asyncCreateWireServices = async () => {
|
|
533
519
|
// Simulate async service creation
|
|
534
520
|
await new Promise((resolve) => setTimeout(resolve, 1))
|
|
535
|
-
return
|
|
521
|
+
return wireServices
|
|
536
522
|
}
|
|
537
523
|
|
|
538
524
|
const result = await runPikkuFunc(
|
|
539
|
-
|
|
525
|
+
'rpc',
|
|
540
526
|
Math.random().toString(),
|
|
541
527
|
'testFunc',
|
|
542
528
|
{
|
|
543
529
|
singletonServices: mockSingletonServices,
|
|
544
|
-
|
|
530
|
+
createWireServices: asyncCreateWireServices,
|
|
545
531
|
data: () => ({}),
|
|
546
532
|
auth: false,
|
|
547
|
-
|
|
533
|
+
wire: {},
|
|
548
534
|
}
|
|
549
535
|
)
|
|
550
536
|
|
|
551
537
|
assert.equal(result, 'success')
|
|
552
|
-
assert.
|
|
538
|
+
assert.deepEqual(servicesProvided, {
|
|
539
|
+
...mockSingletonServices,
|
|
540
|
+
...wireServices,
|
|
541
|
+
})
|
|
553
542
|
})
|
|
554
543
|
})
|
|
@@ -7,37 +7,94 @@ import {
|
|
|
7
7
|
CoreUserSession,
|
|
8
8
|
CorePikkuMiddleware,
|
|
9
9
|
PikkuWiringTypes,
|
|
10
|
-
|
|
11
|
-
PikkuInteraction,
|
|
10
|
+
PikkuWire,
|
|
12
11
|
MiddlewareMetadata,
|
|
13
12
|
PermissionMetadata,
|
|
13
|
+
CoreSingletonServices,
|
|
14
|
+
CreateWireServices,
|
|
15
|
+
CoreConfig,
|
|
14
16
|
} from '../types/core.types.js'
|
|
15
17
|
import {
|
|
16
18
|
CorePermissionGroup,
|
|
17
19
|
CorePikkuFunctionConfig,
|
|
18
20
|
CorePikkuPermission,
|
|
19
21
|
} from './functions.types.js'
|
|
20
|
-
import {
|
|
22
|
+
import { SessionService } from '../services/user-session-service.js'
|
|
21
23
|
import { ForbiddenError } from '../errors/errors.js'
|
|
24
|
+
import { rpcService } from '../wirings/rpc/rpc-runner.js'
|
|
25
|
+
import { closeWireServices } from '../utils.js'
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get or create singleton services for an external package.
|
|
29
|
+
* Services are cached in pikkuState to avoid recreation on each call.
|
|
30
|
+
*
|
|
31
|
+
* @param packageName - The external package name
|
|
32
|
+
* @param parentServices - The parent/caller's singleton services (used as base)
|
|
33
|
+
* @returns The package's singleton services
|
|
34
|
+
*/
|
|
35
|
+
const getOrCreatePackageSingletonServices = async (
|
|
36
|
+
packageName: string,
|
|
37
|
+
parentServices: CoreSingletonServices
|
|
38
|
+
): Promise<CoreSingletonServices> => {
|
|
39
|
+
// Check if we already have cached singleton services for this package
|
|
40
|
+
const cachedServices = pikkuState(packageName, 'package', 'singletonServices')
|
|
41
|
+
if (cachedServices) {
|
|
42
|
+
return cachedServices
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Get the package's service factories
|
|
46
|
+
const factories = pikkuState(packageName, 'package', 'factories')
|
|
47
|
+
if (!factories || !factories.createSingletonServices) {
|
|
48
|
+
// No factories registered, use parent services
|
|
49
|
+
return parentServices
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Create config for the package (use parent config if no factory)
|
|
53
|
+
let config: CoreConfig = parentServices.config
|
|
54
|
+
if (factories.createConfig) {
|
|
55
|
+
config = await factories.createConfig(parentServices.variables)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Create singleton services for the package, passing parent services as existing
|
|
59
|
+
const packageServices = await factories.createSingletonServices(
|
|
60
|
+
config,
|
|
61
|
+
parentServices
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
// Cache the services
|
|
65
|
+
pikkuState(packageName, 'package', 'singletonServices', packageServices)
|
|
66
|
+
|
|
67
|
+
return packageServices
|
|
68
|
+
}
|
|
22
69
|
|
|
23
70
|
export const addFunction = (
|
|
24
71
|
funcName: string,
|
|
25
|
-
funcConfig: CorePikkuFunctionConfig<any, any
|
|
72
|
+
funcConfig: CorePikkuFunctionConfig<any, any>,
|
|
73
|
+
packageName: string | null = null
|
|
26
74
|
) => {
|
|
27
|
-
pikkuState('function', 'functions').set(funcName, funcConfig)
|
|
75
|
+
pikkuState(packageName, 'function', 'functions').set(funcName, funcConfig)
|
|
28
76
|
}
|
|
29
77
|
|
|
30
78
|
export const runPikkuFuncDirectly = async <In, Out>(
|
|
31
79
|
funcName: string,
|
|
32
80
|
allServices: CoreServices,
|
|
81
|
+
wire: PikkuWire,
|
|
33
82
|
data: In,
|
|
34
|
-
|
|
83
|
+
userSession?: SessionService<CoreUserSession>,
|
|
84
|
+
packageName: string | null = null
|
|
35
85
|
) => {
|
|
36
|
-
const funcConfig = pikkuState('function', 'functions').get(
|
|
86
|
+
const funcConfig = pikkuState(packageName, 'function', 'functions').get(
|
|
87
|
+
funcName
|
|
88
|
+
)
|
|
37
89
|
if (!funcConfig) {
|
|
38
90
|
throw new Error(`Function not found: ${funcName}`)
|
|
39
91
|
}
|
|
40
|
-
|
|
92
|
+
// Inject session into wire
|
|
93
|
+
const wireWithSession = {
|
|
94
|
+
...wire,
|
|
95
|
+
session: userSession,
|
|
96
|
+
}
|
|
97
|
+
return (await funcConfig.func(allServices, data, wireWithSession)) as Out
|
|
41
98
|
}
|
|
42
99
|
|
|
43
100
|
export const runPikkuFunc = async <In = any, Out = any>(
|
|
@@ -45,10 +102,9 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
45
102
|
wireId: string,
|
|
46
103
|
funcName: string,
|
|
47
104
|
{
|
|
48
|
-
getAllServices,
|
|
49
105
|
singletonServices,
|
|
106
|
+
createWireServices,
|
|
50
107
|
data,
|
|
51
|
-
userSession,
|
|
52
108
|
auth: wiringAuth,
|
|
53
109
|
inheritedMiddleware,
|
|
54
110
|
wireMiddleware,
|
|
@@ -56,13 +112,11 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
56
112
|
wirePermissions,
|
|
57
113
|
coerceDataFromSchema,
|
|
58
114
|
tags = [],
|
|
59
|
-
|
|
115
|
+
wire,
|
|
116
|
+
packageName = null,
|
|
60
117
|
}: {
|
|
61
118
|
singletonServices: CoreSingletonServices
|
|
62
|
-
|
|
63
|
-
session?: CoreUserSession
|
|
64
|
-
) => Promise<CoreServices> | CoreServices
|
|
65
|
-
userSession?: UserSessionService<CoreUserSession>
|
|
119
|
+
createWireServices?: CreateWireServices
|
|
66
120
|
data: () => Promise<In> | In
|
|
67
121
|
auth?: boolean
|
|
68
122
|
inheritedMiddleware?: MiddlewareMetadata[]
|
|
@@ -71,18 +125,36 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
71
125
|
wirePermissions?: CorePermissionGroup | CorePikkuPermission[]
|
|
72
126
|
coerceDataFromSchema?: boolean
|
|
73
127
|
tags?: string[]
|
|
74
|
-
|
|
128
|
+
wire: PikkuWire
|
|
129
|
+
packageName?: string | null
|
|
75
130
|
}
|
|
76
131
|
): Promise<Out> => {
|
|
77
|
-
const funcConfig = pikkuState('function', 'functions').get(
|
|
132
|
+
const funcConfig = pikkuState(packageName, 'function', 'functions').get(
|
|
133
|
+
funcName
|
|
134
|
+
)
|
|
78
135
|
if (!funcConfig) {
|
|
79
136
|
throw new Error(`Function not found: ${funcName}`)
|
|
80
137
|
}
|
|
81
|
-
const
|
|
138
|
+
const allMeta = pikkuState(packageName, 'function', 'meta')
|
|
139
|
+
const funcMeta = allMeta[funcName]
|
|
82
140
|
if (!funcMeta) {
|
|
83
141
|
throw new Error(`Function meta not found: ${funcName}`)
|
|
84
142
|
}
|
|
85
143
|
|
|
144
|
+
// For external packages, get or create their singleton services
|
|
145
|
+
const resolvedSingletonServices = packageName
|
|
146
|
+
? await getOrCreatePackageSingletonServices(packageName, singletonServices)
|
|
147
|
+
: singletonServices
|
|
148
|
+
|
|
149
|
+
// Get the package's createWireServices if available
|
|
150
|
+
let resolvedCreateWireServices = createWireServices
|
|
151
|
+
if (packageName) {
|
|
152
|
+
const factories = pikkuState(packageName, 'package', 'factories')
|
|
153
|
+
if (factories?.createWireServices) {
|
|
154
|
+
resolvedCreateWireServices = factories.createWireServices
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
86
158
|
// Convert tags to PermissionMetadata and merge with inheritedPermissions
|
|
87
159
|
const mergedInheritedPermissions: PermissionMetadata[] = [
|
|
88
160
|
...(inheritedPermissions || []),
|
|
@@ -91,16 +163,23 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
91
163
|
|
|
92
164
|
// Helper function to run permissions and execute the function
|
|
93
165
|
const executeFunction = async () => {
|
|
94
|
-
const
|
|
166
|
+
const initialSession = wire.session?.freezeInitial()
|
|
167
|
+
|
|
168
|
+
const wireWithInitialSession: PikkuWire = {
|
|
169
|
+
...wire,
|
|
170
|
+
initialSession,
|
|
171
|
+
}
|
|
172
|
+
|
|
95
173
|
if (wiringAuth === true || funcConfig.auth === true) {
|
|
96
174
|
// This means it was explicitly enabled in either wiring or function and has to be respected
|
|
97
|
-
if (!
|
|
175
|
+
if (!initialSession) {
|
|
98
176
|
throw new ForbiddenError('Authentication required')
|
|
99
177
|
}
|
|
100
178
|
}
|
|
101
179
|
if (wiringAuth === undefined && funcConfig.auth === undefined) {
|
|
102
180
|
// We always default to requiring auth unless explicitly disabled
|
|
103
|
-
if (!
|
|
181
|
+
if (!initialSession) {
|
|
182
|
+
// TODO: Critical, we need to figure out how to make this work with different wirings
|
|
104
183
|
// throw new ForbiddenError('Authentication required')
|
|
105
184
|
}
|
|
106
185
|
}
|
|
@@ -113,48 +192,62 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
113
192
|
if (inputSchemaName) {
|
|
114
193
|
// Validate request data against the defined schema, if any
|
|
115
194
|
await validateSchema(
|
|
116
|
-
|
|
117
|
-
|
|
195
|
+
resolvedSingletonServices.logger,
|
|
196
|
+
resolvedSingletonServices.schema,
|
|
118
197
|
inputSchemaName,
|
|
119
|
-
actualData
|
|
198
|
+
actualData,
|
|
199
|
+
packageName
|
|
120
200
|
)
|
|
121
201
|
// Coerce (top level) query string parameters or date objects if specified by the schema
|
|
122
202
|
if (coerceDataFromSchema) {
|
|
123
|
-
coerceTopLevelDataFromSchema(inputSchemaName, actualData)
|
|
203
|
+
coerceTopLevelDataFromSchema(inputSchemaName, actualData, packageName)
|
|
124
204
|
}
|
|
125
205
|
}
|
|
126
206
|
|
|
127
|
-
const allServices = await getAllServices(session)
|
|
128
|
-
|
|
129
|
-
// Run permissions check with combined permissions: inheritedPermissions (including tags) → wirePermissions → funcPermissions
|
|
130
207
|
await runPermissions(wireType, wireId, {
|
|
131
208
|
wireInheritedPermissions: mergedInheritedPermissions,
|
|
132
209
|
wirePermissions: wirePermissions,
|
|
133
210
|
funcInheritedPermissions: funcMeta.permissions,
|
|
134
211
|
funcPermissions: funcConfig.permissions,
|
|
135
|
-
|
|
212
|
+
services: resolvedSingletonServices,
|
|
213
|
+
wire: { ...wireWithInitialSession, rpc: undefined } as any,
|
|
136
214
|
data: actualData,
|
|
137
|
-
|
|
215
|
+
packageName,
|
|
138
216
|
})
|
|
139
217
|
|
|
140
|
-
|
|
218
|
+
const wireServices = await resolvedCreateWireServices?.(
|
|
219
|
+
resolvedSingletonServices,
|
|
220
|
+
wireWithInitialSession
|
|
221
|
+
)
|
|
222
|
+
try {
|
|
223
|
+
const services = { ...resolvedSingletonServices, ...wireServices }
|
|
224
|
+
const rpc = rpcService.getContextRPCService(
|
|
225
|
+
services,
|
|
226
|
+
wireWithInitialSession
|
|
227
|
+
)
|
|
228
|
+
return await funcConfig.func(services, actualData, {
|
|
229
|
+
...wireWithInitialSession,
|
|
230
|
+
rpc,
|
|
231
|
+
})
|
|
232
|
+
} finally {
|
|
233
|
+
if (wireServices) {
|
|
234
|
+
await closeWireServices(resolvedSingletonServices.logger, wireServices)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
141
237
|
}
|
|
142
238
|
|
|
143
|
-
// Combine all middleware: inheritedMiddleware → wireMiddleware → funcMiddleware
|
|
144
239
|
const allMiddleware = combineMiddleware(wireType, wireId, {
|
|
145
240
|
wireInheritedMiddleware: inheritedMiddleware,
|
|
146
241
|
wireMiddleware,
|
|
147
242
|
funcInheritedMiddleware: funcMeta.middleware,
|
|
148
243
|
funcMiddleware: funcConfig.middleware,
|
|
244
|
+
packageName,
|
|
149
245
|
})
|
|
150
246
|
|
|
151
247
|
if (allMiddleware.length > 0) {
|
|
152
248
|
return (await runMiddleware<CorePikkuMiddleware>(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
userSession,
|
|
156
|
-
},
|
|
157
|
-
interaction,
|
|
249
|
+
resolvedSingletonServices,
|
|
250
|
+
wire,
|
|
158
251
|
allMiddleware,
|
|
159
252
|
executeFunction
|
|
160
253
|
)) as Out
|