@pikku/core 0.10.2 → 0.11.1
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 +19 -0
- package/dist/errors/errors.d.ts +1 -1
- package/dist/errors/errors.js +3 -3
- package/dist/function/function-runner.d.ts +6 -7
- package/dist/function/function-runner.js +35 -16
- package/dist/function/functions.types.d.ts +23 -30
- package/dist/function/functions.types.js +9 -6
- package/dist/handle-error.d.ts +1 -1
- package/dist/handle-error.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/middleware/auth-apikey.d.ts +1 -0
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.d.ts +1 -0
- package/dist/middleware/auth-bearer.js +3 -3
- package/dist/middleware/auth-cookie.d.ts +1 -0
- package/dist/middleware/auth-cookie.js +5 -5
- package/dist/middleware/timeout.d.ts +1 -0
- package/dist/middleware/timeout.js +3 -2
- package/dist/middleware-runner.d.ts +3 -6
- package/dist/middleware-runner.js +11 -11
- package/dist/permissions.d.ts +6 -6
- package/dist/permissions.js +15 -15
- package/dist/pikku-state.d.ts +7 -2
- package/dist/pikku-state.js +4 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/scheduler-service.d.ts +63 -0
- package/dist/services/scheduler-service.js +6 -0
- package/dist/services/user-session-service.d.ts +7 -3
- package/dist/services/user-session-service.js +8 -1
- package/dist/time-utils.d.ts +14 -0
- package/dist/time-utils.js +62 -0
- package/dist/types/core.types.d.ts +48 -35
- package/dist/types/core.types.js +3 -13
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +3 -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 +6 -9
- package/dist/wirings/channel/channel-runner.d.ts +2 -2
- 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/serverless/serverless-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +41 -46
- package/dist/wirings/cli/channel/cli-channel-runner.js +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +5 -5
- package/dist/wirings/cli/cli-runner.js +11 -29
- package/dist/wirings/cli/cli.types.d.ts +15 -11
- package/dist/wirings/http/http-runner.d.ts +6 -6
- package/dist/wirings/http/http-runner.js +25 -39
- package/dist/wirings/http/http.types.d.ts +5 -10
- package/dist/wirings/mcp/mcp-runner.d.ts +2 -2
- package/dist/wirings/mcp/mcp-runner.js +12 -19
- 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 +7 -14
- package/dist/wirings/queue/queue.types.d.ts +4 -13
- 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 +13 -7
- package/dist/wirings/rpc/rpc-runner.js +50 -26
- package/dist/wirings/rpc/rpc-types.d.ts +1 -0
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -3
- package/dist/wirings/scheduler/scheduler-runner.js +13 -24
- package/dist/wirings/scheduler/scheduler.types.d.ts +3 -8
- package/dist/wirings/workflow/index.d.ts +15 -0
- package/dist/wirings/workflow/index.js +14 -0
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +160 -0
- package/dist/wirings/workflow/pikku-workflow-service.js +430 -0
- package/dist/wirings/workflow/workflow-runner.d.ts +34 -0
- package/dist/wirings/workflow/workflow-runner.js +65 -0
- package/dist/wirings/workflow/workflow.types.d.ts +332 -0
- package/dist/wirings/workflow/workflow.types.js +1 -0
- package/package.json +3 -4
- package/src/errors/errors.ts +3 -3
- package/src/factory-functions.test.ts +9 -36
- package/src/function/function-runner.test.ts +57 -68
- package/src/function/function-runner.ts +51 -28
- package/src/function/function-runner.ts.bak +188 -0
- package/src/function/functions.types.ts +69 -51
- package/src/handle-error.ts +1 -1
- package/src/index.ts +2 -0
- 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 +13 -15
- package/src/permissions.test.ts +41 -45
- package/src/permissions.ts +21 -20
- package/src/pikku-state.ts +14 -2
- package/src/services/index.ts +1 -0
- package/src/services/scheduler-service.ts +76 -0
- package/src/services/user-session-service.ts +14 -4
- package/src/time-utils.ts +75 -0
- package/src/types/core.types.ts +92 -51
- package/src/utils.ts +4 -4
- package/src/wirings/channel/channel-common.ts +4 -7
- package/src/wirings/channel/channel-handler.ts +16 -22
- package/src/wirings/channel/channel-runner.ts +2 -2
- package/src/wirings/channel/channel.types.ts +14 -11
- package/src/wirings/channel/local/local-channel-runner.test.ts +5 -3
- package/src/wirings/channel/local/local-channel-runner.ts +23 -38
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +51 -77
- package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +7 -7
- package/src/wirings/cli/cli-runner.ts +25 -63
- package/src/wirings/cli/cli.types.ts +22 -16
- package/src/wirings/http/http-runner.test.ts +8 -8
- package/src/wirings/http/http-runner.ts +29 -56
- package/src/wirings/http/http.types.ts +5 -14
- package/src/wirings/mcp/mcp-runner.ts +23 -48
- 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 +10 -24
- package/src/wirings/queue/queue.types.ts +5 -15
- package/src/wirings/rpc/index.ts +1 -1
- package/src/wirings/rpc/rpc-runner.ts +71 -32
- package/src/wirings/rpc/rpc-types.ts +1 -0
- package/src/wirings/scheduler/scheduler-runner.test.ts +627 -0
- package/src/wirings/scheduler/scheduler-runner.ts +24 -50
- package/src/wirings/scheduler/scheduler.types.ts +3 -9
- package/src/wirings/workflow/index.ts +43 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +746 -0
- package/src/wirings/workflow/workflow-runner.ts +72 -0
- package/src/wirings/workflow/workflow.types.ts +422 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/services/file-channel-store.d.ts +0 -19
- package/dist/services/file-channel-store.js +0 -69
- package/dist/services/file-eventhub-store.d.ts +0 -17
- package/dist/services/file-eventhub-store.js +0 -71
- package/src/services/file-channel-store.ts +0 -86
- package/src/services/file-eventhub-store.ts +0 -90
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import { NotFoundError } from '../../errors/errors.js'
|
|
2
2
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
|
|
3
3
|
import { pikkuState } from '../../pikku-state.js'
|
|
4
|
-
import {
|
|
5
|
-
CorePikkuMiddleware,
|
|
6
|
-
CoreUserSession,
|
|
7
|
-
SessionServices,
|
|
8
|
-
PikkuWiringTypes,
|
|
9
|
-
} from '../../types/core.types.js'
|
|
10
|
-
import { closeSessionServices } from '../../utils.js'
|
|
4
|
+
import { CorePikkuMiddleware, CoreUserSession } from '../../types/core.types.js'
|
|
11
5
|
import {
|
|
12
6
|
CoreCLI,
|
|
13
7
|
CLICommandMeta,
|
|
@@ -20,14 +14,13 @@ import {
|
|
|
20
14
|
import type {
|
|
21
15
|
CoreSingletonServices,
|
|
22
16
|
CoreServices,
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
CreateWireServices,
|
|
18
|
+
PikkuWire,
|
|
25
19
|
CreateConfig,
|
|
26
20
|
CreateSingletonServices,
|
|
27
21
|
} from '../../types/core.types.js'
|
|
28
22
|
import { PikkuChannel } from '../channel/channel.types.js'
|
|
29
|
-
import {
|
|
30
|
-
import { PikkuUserSessionService } from '../../services/user-session-service.js'
|
|
23
|
+
import { PikkuSessionService } from '../../services/user-session-service.js'
|
|
31
24
|
import { LocalVariablesService } from '../../services/local-variables.js'
|
|
32
25
|
import { generateCommandHelp, parseCLIArguments } from './command-parser.js'
|
|
33
26
|
|
|
@@ -247,13 +240,13 @@ export async function runCLICommand({
|
|
|
247
240
|
commandPath,
|
|
248
241
|
data,
|
|
249
242
|
singletonServices,
|
|
250
|
-
|
|
243
|
+
createWireServices,
|
|
251
244
|
}: {
|
|
252
245
|
program: string
|
|
253
246
|
commandPath: string[]
|
|
254
247
|
data: Record<string, any>
|
|
255
248
|
singletonServices: CoreSingletonServices
|
|
256
|
-
|
|
249
|
+
createWireServices?: CreateWireServices
|
|
257
250
|
}): Promise<any> {
|
|
258
251
|
// Get the command metadata to find the function name
|
|
259
252
|
const cliMeta = pikkuState('cli', 'meta')
|
|
@@ -329,57 +322,31 @@ export async function runCLICommand({
|
|
|
329
322
|
state: 'open',
|
|
330
323
|
}
|
|
331
324
|
|
|
332
|
-
const userSession = new
|
|
333
|
-
let sessionServices: SessionServices | undefined
|
|
325
|
+
const userSession = new PikkuSessionService<CoreUserSession>()
|
|
334
326
|
|
|
335
|
-
const
|
|
327
|
+
const wire: PikkuWire = {
|
|
336
328
|
cli: {
|
|
337
329
|
program,
|
|
338
330
|
command: commandPath,
|
|
339
331
|
data: pluckedData,
|
|
340
332
|
channel,
|
|
341
333
|
},
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const getAllServices = async (session?: CoreUserSession) => {
|
|
345
|
-
// Create session-specific services for handling the command
|
|
346
|
-
sessionServices = await createSessionServices?.(
|
|
347
|
-
singletonServices,
|
|
348
|
-
interaction,
|
|
349
|
-
session
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
return rpcService.injectRPCService(
|
|
353
|
-
{
|
|
354
|
-
...singletonServices,
|
|
355
|
-
...sessionServices,
|
|
356
|
-
userSession,
|
|
357
|
-
channel,
|
|
358
|
-
},
|
|
359
|
-
interaction,
|
|
360
|
-
false
|
|
361
|
-
)
|
|
334
|
+
session: userSession,
|
|
362
335
|
}
|
|
363
336
|
|
|
364
337
|
try {
|
|
365
|
-
const result = await runPikkuFunc(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
inheritedPermissions: currentCommand.permissions,
|
|
378
|
-
wirePermissions: undefined,
|
|
379
|
-
tags: programData?.tags,
|
|
380
|
-
interaction,
|
|
381
|
-
}
|
|
382
|
-
)
|
|
338
|
+
const result = await runPikkuFunc('cli', commandId, funcName, {
|
|
339
|
+
singletonServices,
|
|
340
|
+
createWireServices,
|
|
341
|
+
data: pluckedData,
|
|
342
|
+
auth: false,
|
|
343
|
+
inheritedMiddleware: currentCommand.middleware,
|
|
344
|
+
wireMiddleware: allWireMiddleware,
|
|
345
|
+
inheritedPermissions: currentCommand.permissions,
|
|
346
|
+
wirePermissions: undefined,
|
|
347
|
+
tags: programData?.tags,
|
|
348
|
+
wire,
|
|
349
|
+
})
|
|
383
350
|
|
|
384
351
|
// Apply renderer one final time with the final output (if renderer exists)
|
|
385
352
|
if (renderer) {
|
|
@@ -392,11 +359,6 @@ export async function runCLICommand({
|
|
|
392
359
|
} finally {
|
|
393
360
|
// Close the channel
|
|
394
361
|
channel.close()
|
|
395
|
-
|
|
396
|
-
// Clean up session services
|
|
397
|
-
if (sessionServices) {
|
|
398
|
-
await closeSessionServices(singletonServices.logger, sessionServices)
|
|
399
|
-
}
|
|
400
362
|
}
|
|
401
363
|
}
|
|
402
364
|
|
|
@@ -428,13 +390,13 @@ export async function executeCLI({
|
|
|
428
390
|
args,
|
|
429
391
|
createConfig,
|
|
430
392
|
createSingletonServices,
|
|
431
|
-
|
|
393
|
+
createWireServices,
|
|
432
394
|
}: {
|
|
433
395
|
programName: string
|
|
434
396
|
args?: string[]
|
|
435
397
|
createConfig: CreateConfig<any, any>
|
|
436
398
|
createSingletonServices: CreateSingletonServices<any, any>
|
|
437
|
-
|
|
399
|
+
createWireServices?: CreateWireServices<any, any, any>
|
|
438
400
|
}): Promise<void> {
|
|
439
401
|
if (!args) {
|
|
440
402
|
throw new Error(
|
|
@@ -449,7 +411,7 @@ export async function executeCLI({
|
|
|
449
411
|
| undefined
|
|
450
412
|
if (!allCLIMeta) {
|
|
451
413
|
throw new Error(
|
|
452
|
-
'[PKU342] CLI metadata not found. No CLI wirings were registered. See https://pikku.dev/errors/pku342 for more information.'
|
|
414
|
+
'[PKU342] CLI metadata not found. No CLI wirings were registered. See https://pikku.dev/docs/pikku-cli/errors/pku342 for more information.'
|
|
453
415
|
)
|
|
454
416
|
}
|
|
455
417
|
const programMeta = allCLIMeta.programs[programName]
|
|
@@ -518,7 +480,7 @@ export async function executeCLI({
|
|
|
518
480
|
commandPath: parsed.commandPath,
|
|
519
481
|
data,
|
|
520
482
|
singletonServices,
|
|
521
|
-
|
|
483
|
+
createWireServices,
|
|
522
484
|
})
|
|
523
485
|
} catch (error: any) {
|
|
524
486
|
// Re-throw CLIError as-is
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
CorePikkuMiddleware,
|
|
3
3
|
CoreSingletonServices,
|
|
4
4
|
CoreUserSession,
|
|
5
|
-
PikkuDocs,
|
|
6
5
|
CoreServices,
|
|
7
6
|
MiddlewareMetadata,
|
|
8
7
|
PermissionMetadata,
|
|
@@ -44,7 +43,7 @@ export interface CLIPositional {
|
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
/**
|
|
47
|
-
* CLI
|
|
46
|
+
* CLI wire context
|
|
48
47
|
*/
|
|
49
48
|
export type PikkuCLI = {
|
|
50
49
|
program: string
|
|
@@ -74,8 +73,9 @@ export interface CLICommandMeta {
|
|
|
74
73
|
positionals: CLIPositional[]
|
|
75
74
|
options: Record<string, CLIOption>
|
|
76
75
|
renderName?: string
|
|
76
|
+
summary?: string
|
|
77
77
|
description?: string
|
|
78
|
-
|
|
78
|
+
errors?: string[]
|
|
79
79
|
tags?: string[]
|
|
80
80
|
subcommands?: Record<string, CLICommandMeta>
|
|
81
81
|
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
@@ -131,8 +131,8 @@ export type CorePikkuCLIRender<
|
|
|
131
131
|
export type ExtractFunctionInput<Func> =
|
|
132
132
|
Func extends CorePikkuFunctionConfig<infer FuncType, any, any>
|
|
133
133
|
? FuncType extends
|
|
134
|
-
| CorePikkuFunction<infer Input, any, any, any
|
|
135
|
-
| CorePikkuFunctionSessionless<infer Input, any, any, any
|
|
134
|
+
| CorePikkuFunction<infer Input, any, any, any>
|
|
135
|
+
| CorePikkuFunctionSessionless<infer Input, any, any, any>
|
|
136
136
|
? Input
|
|
137
137
|
: never
|
|
138
138
|
: never
|
|
@@ -198,8 +198,8 @@ export type ValidateParameters<Params extends string, Input> =
|
|
|
198
198
|
export type ExtractFunctionOutput<Func> =
|
|
199
199
|
Func extends CorePikkuFunctionConfig<infer FuncType, any, any>
|
|
200
200
|
? FuncType extends
|
|
201
|
-
| CorePikkuFunction<any, infer Output, any, any
|
|
202
|
-
| CorePikkuFunctionSessionless<any, infer Output, any, any
|
|
201
|
+
| CorePikkuFunction<any, infer Output, any, any>
|
|
202
|
+
| CorePikkuFunctionSessionless<any, infer Output, any, any>
|
|
203
203
|
? Output
|
|
204
204
|
: never
|
|
205
205
|
: never
|
|
@@ -210,7 +210,10 @@ export type ExtractFunctionOutput<Func> =
|
|
|
210
210
|
*/
|
|
211
211
|
export type CoreCLICommandConfig<
|
|
212
212
|
FuncConfig,
|
|
213
|
-
PikkuMiddleware extends CorePikkuMiddleware<any> = CorePikkuMiddleware<
|
|
213
|
+
PikkuMiddleware extends CorePikkuMiddleware<any, any> = CorePikkuMiddleware<
|
|
214
|
+
any,
|
|
215
|
+
any
|
|
216
|
+
>,
|
|
214
217
|
PikkuCLIRender extends CorePikkuCLIRender<any, any, any> = CorePikkuCLIRender<
|
|
215
218
|
any,
|
|
216
219
|
any
|
|
@@ -245,8 +248,8 @@ export interface CoreCLICommand<
|
|
|
245
248
|
In,
|
|
246
249
|
Out,
|
|
247
250
|
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
248
|
-
| CorePikkuFunction<In, Out, any, any
|
|
249
|
-
| CorePikkuFunctionSessionless<In, Out, any, any
|
|
251
|
+
| CorePikkuFunction<In, Out, any, any>
|
|
252
|
+
| CorePikkuFunctionSessionless<In, Out, any, any>
|
|
250
253
|
>,
|
|
251
254
|
PikkuPermission extends CorePikkuPermission<any, any, any>,
|
|
252
255
|
PikkuMiddleware extends CorePikkuMiddleware,
|
|
@@ -264,7 +267,9 @@ export interface CoreCLICommand<
|
|
|
264
267
|
middleware?: PikkuMiddleware[]
|
|
265
268
|
permissions?: Record<string, PikkuPermission | PikkuPermission[]>
|
|
266
269
|
auth?: boolean
|
|
267
|
-
|
|
270
|
+
summary?: string
|
|
271
|
+
errors?: string[]
|
|
272
|
+
tags?: string[]
|
|
268
273
|
subcommands?: Subcommands
|
|
269
274
|
isDefault?: boolean
|
|
270
275
|
}
|
|
@@ -276,8 +281,8 @@ export type CLICommandShorthand<
|
|
|
276
281
|
In,
|
|
277
282
|
Out,
|
|
278
283
|
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
279
|
-
| CorePikkuFunction<In, Out, any, any
|
|
280
|
-
| CorePikkuFunctionSessionless<In, Out, any, any
|
|
284
|
+
| CorePikkuFunction<In, Out, any, any>
|
|
285
|
+
| CorePikkuFunctionSessionless<In, Out, any, any>
|
|
281
286
|
>,
|
|
282
287
|
> = PikkuFunctionConfig
|
|
283
288
|
|
|
@@ -288,8 +293,8 @@ export type CLICommandDefinition<
|
|
|
288
293
|
In,
|
|
289
294
|
Out,
|
|
290
295
|
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
291
|
-
| CorePikkuFunction<In, Out, any, any
|
|
292
|
-
| CorePikkuFunctionSessionless<In, Out, any, any
|
|
296
|
+
| CorePikkuFunction<In, Out, any, any>
|
|
297
|
+
| CorePikkuFunctionSessionless<In, Out, any, any>
|
|
293
298
|
>,
|
|
294
299
|
PikkuPermission extends CorePikkuPermission<any, any, any>,
|
|
295
300
|
PikkuMiddleware extends CorePikkuMiddleware,
|
|
@@ -325,7 +330,8 @@ export interface CoreCLI<
|
|
|
325
330
|
options?: CLIOptions<Options>
|
|
326
331
|
middleware?: PikkuMiddleware[]
|
|
327
332
|
render?: PikkuCLIRender
|
|
328
|
-
|
|
333
|
+
summary?: string
|
|
334
|
+
errors?: string[]
|
|
329
335
|
tags?: string[]
|
|
330
336
|
}
|
|
331
337
|
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
import { addFunction } from '../../function/function-runner.js'
|
|
12
12
|
import { httpRouter } from './routers/http-router.js'
|
|
13
13
|
|
|
14
|
-
const sessionMiddleware: CorePikkuMiddleware = async (services,
|
|
15
|
-
|
|
14
|
+
const sessionMiddleware: CorePikkuMiddleware = async (services, wire, next) => {
|
|
15
|
+
wire.session?.set({ userId: 'test' } as any)
|
|
16
16
|
await next()
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -43,7 +43,7 @@ const setHTTPFunctionMap = (func: any) => {
|
|
|
43
43
|
|
|
44
44
|
describe('fetch', () => {
|
|
45
45
|
let singletonServices: any
|
|
46
|
-
let
|
|
46
|
+
let createWireServices: any
|
|
47
47
|
let request: any
|
|
48
48
|
let response: any
|
|
49
49
|
|
|
@@ -59,7 +59,7 @@ describe('fetch', () => {
|
|
|
59
59
|
},
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
createWireServices = async () => ({})
|
|
63
63
|
request = new PikkuMockRequest('/test', 'get')
|
|
64
64
|
response = new PikkuMockResponse()
|
|
65
65
|
|
|
@@ -77,7 +77,7 @@ describe('fetch', () => {
|
|
|
77
77
|
async () =>
|
|
78
78
|
fetch(request, {
|
|
79
79
|
singletonServices,
|
|
80
|
-
|
|
80
|
+
createWireServices,
|
|
81
81
|
bubbleErrors: true,
|
|
82
82
|
}),
|
|
83
83
|
NotFoundError
|
|
@@ -99,7 +99,7 @@ describe('fetch', () => {
|
|
|
99
99
|
|
|
100
100
|
const result = await fetch(request, {
|
|
101
101
|
singletonServices,
|
|
102
|
-
|
|
102
|
+
createWireServices,
|
|
103
103
|
})
|
|
104
104
|
|
|
105
105
|
assert.deepStrictEqual(await result.json(), { success: true })
|
|
@@ -122,7 +122,7 @@ describe('fetch', () => {
|
|
|
122
122
|
|
|
123
123
|
await fetch(request, {
|
|
124
124
|
singletonServices,
|
|
125
|
-
|
|
125
|
+
createWireServices,
|
|
126
126
|
})
|
|
127
127
|
|
|
128
128
|
assert.strictEqual(await permissions.test(), true)
|
|
@@ -143,7 +143,7 @@ describe('fetch', () => {
|
|
|
143
143
|
async () =>
|
|
144
144
|
fetch(request, {
|
|
145
145
|
singletonServices,
|
|
146
|
-
|
|
146
|
+
createWireServices,
|
|
147
147
|
bubbleErrors: true,
|
|
148
148
|
}),
|
|
149
149
|
error
|
|
@@ -18,24 +18,23 @@ import {
|
|
|
18
18
|
CoreUserSession,
|
|
19
19
|
CorePikkuMiddleware,
|
|
20
20
|
CorePikkuMiddlewareGroup,
|
|
21
|
-
|
|
21
|
+
WireServices,
|
|
22
|
+
PikkuWire,
|
|
22
23
|
PikkuWiringTypes,
|
|
23
|
-
PikkuInteraction,
|
|
24
24
|
} from '../../types/core.types.js'
|
|
25
25
|
import { NotFoundError } from '../../errors/errors.js'
|
|
26
26
|
import {
|
|
27
|
-
|
|
27
|
+
closeWireServices,
|
|
28
28
|
createWeakUID,
|
|
29
29
|
isSerializable,
|
|
30
30
|
} from '../../utils.js'
|
|
31
|
-
import {
|
|
31
|
+
import { PikkuSessionService } from '../../services/user-session-service.js'
|
|
32
32
|
import { handleHTTPError } from '../../handle-error.js'
|
|
33
33
|
import { pikkuState } from '../../pikku-state.js'
|
|
34
34
|
import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js'
|
|
35
35
|
import { PikkuFetchHTTPRequest } from './pikku-fetch-http-request.js'
|
|
36
36
|
import { PikkuChannel } from '../channel/channel.types.js'
|
|
37
37
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
|
|
38
|
-
import { rpcService } from '../rpc/rpc-runner.js'
|
|
39
38
|
import { httpRouter } from './routers/http-router.js'
|
|
40
39
|
|
|
41
40
|
/**
|
|
@@ -203,16 +202,16 @@ const getMatchingRoute = (requestType: string, requestPath: string) => {
|
|
|
203
202
|
}
|
|
204
203
|
|
|
205
204
|
/**
|
|
206
|
-
* Combines the request and response objects into a single HTTP
|
|
205
|
+
* Combines the request and response objects into a single HTTP wire object.
|
|
207
206
|
*
|
|
208
207
|
* This utility function creates an object that holds both the HTTP request and response,
|
|
209
208
|
* which simplifies passing these around through middleware and route execution.
|
|
210
209
|
*
|
|
211
210
|
* @param {PikkuHTTPRequest | undefined} request - The HTTP request object.
|
|
212
211
|
* @param {PikkuHTTPResponse | undefined} response - The HTTP response object.
|
|
213
|
-
* @returns {PikkuHTTP | undefined} The combined HTTP
|
|
212
|
+
* @returns {PikkuHTTP | undefined} The combined HTTP wire object or undefined if none provided.
|
|
214
213
|
*/
|
|
215
|
-
export const
|
|
214
|
+
export const createHTTPWire = (
|
|
216
215
|
request: PikkuHTTPRequest | undefined,
|
|
217
216
|
response: PikkuHTTPResponse | undefined
|
|
218
217
|
): PikkuHTTP | undefined => {
|
|
@@ -246,15 +245,15 @@ export const createHTTPInteraction = (
|
|
|
246
245
|
*
|
|
247
246
|
* @param {Object} services - A collection of shared services and utilities.
|
|
248
247
|
* @param {Object} matchedRoute - Contains route details, URL parameters, and optional schema.
|
|
249
|
-
* @param {PikkuHTTP | undefined} http - The HTTP
|
|
248
|
+
* @param {PikkuHTTP | undefined} http - The HTTP wire object.
|
|
250
249
|
* @param {Object} options - Options for route execution (e.g., whether to coerce query strings to arrays).
|
|
251
|
-
* @returns {Promise<any>} An object containing the route handler result and
|
|
250
|
+
* @returns {Promise<any>} An object containing the route handler result and wire services (if any).
|
|
252
251
|
* @throws Throws errors like MissingSessionError or ForbiddenError on validation failures.
|
|
253
252
|
*/
|
|
254
253
|
const executeRoute = async (
|
|
255
254
|
services: {
|
|
256
255
|
singletonServices: any
|
|
257
|
-
|
|
256
|
+
createWireServices?: any
|
|
258
257
|
skipUserSession: boolean
|
|
259
258
|
requestId: string
|
|
260
259
|
},
|
|
@@ -269,17 +268,13 @@ const executeRoute = async (
|
|
|
269
268
|
coerceDataFromSchema: boolean
|
|
270
269
|
}
|
|
271
270
|
) => {
|
|
272
|
-
const userSession = new
|
|
271
|
+
const userSession = new PikkuSessionService<CoreUserSession>()
|
|
273
272
|
const { params, route, meta } = matchedRoute
|
|
274
|
-
const {
|
|
275
|
-
|
|
276
|
-
createSessionServices,
|
|
277
|
-
skipUserSession,
|
|
278
|
-
requestId,
|
|
279
|
-
} = services
|
|
273
|
+
const { singletonServices, createWireServices, skipUserSession, requestId } =
|
|
274
|
+
services
|
|
280
275
|
|
|
281
276
|
const requiresSession = route.auth !== false
|
|
282
|
-
let
|
|
277
|
+
let wireServices: any
|
|
283
278
|
let result: any
|
|
284
279
|
|
|
285
280
|
// Attach URL parameters to the request object
|
|
@@ -324,38 +319,16 @@ const executeRoute = async (
|
|
|
324
319
|
}
|
|
325
320
|
}
|
|
326
321
|
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
const getAllServices = async (session?: CoreUserSession) => {
|
|
330
|
-
// Create session-specific services for handling the request
|
|
331
|
-
sessionServices = await createSessionServices(
|
|
332
|
-
{ ...singletonServices, userSession, channel },
|
|
333
|
-
{ http },
|
|
334
|
-
session
|
|
335
|
-
)
|
|
336
|
-
|
|
337
|
-
return rpcService.injectRPCService(
|
|
338
|
-
{
|
|
339
|
-
...singletonServices,
|
|
340
|
-
...sessionServices,
|
|
341
|
-
http,
|
|
342
|
-
userSession,
|
|
343
|
-
channel,
|
|
344
|
-
},
|
|
345
|
-
interaction,
|
|
346
|
-
route.auth
|
|
347
|
-
)
|
|
348
|
-
}
|
|
322
|
+
const wire: PikkuWire = { http, channel, session: userSession }
|
|
349
323
|
|
|
350
324
|
result = await runPikkuFunc(
|
|
351
|
-
|
|
325
|
+
'http',
|
|
352
326
|
`${meta.method}:${meta.route}`,
|
|
353
327
|
meta.pikkuFuncName,
|
|
354
328
|
{
|
|
355
329
|
singletonServices,
|
|
356
|
-
|
|
330
|
+
createWireServices,
|
|
357
331
|
auth: route.auth !== false,
|
|
358
|
-
userSession,
|
|
359
332
|
data,
|
|
360
333
|
inheritedMiddleware: meta.middleware,
|
|
361
334
|
wireMiddleware: route.middleware,
|
|
@@ -363,7 +336,7 @@ const executeRoute = async (
|
|
|
363
336
|
wirePermissions: route.permissions,
|
|
364
337
|
coerceDataFromSchema: options.coerceDataFromSchema,
|
|
365
338
|
tags: route.tags,
|
|
366
|
-
|
|
339
|
+
wire,
|
|
367
340
|
}
|
|
368
341
|
)
|
|
369
342
|
|
|
@@ -378,7 +351,7 @@ const executeRoute = async (
|
|
|
378
351
|
// TODO: Evaluate if the response stream should be explicitly ended.
|
|
379
352
|
// http?.response?.end()
|
|
380
353
|
|
|
381
|
-
return
|
|
354
|
+
return wireServices ? { result, wireServices } : { result }
|
|
382
355
|
}
|
|
383
356
|
|
|
384
357
|
/**
|
|
@@ -431,11 +404,11 @@ export const pikkuFetch = async <In, Out>(
|
|
|
431
404
|
* middleware execution, error handling, and session service cleanup.
|
|
432
405
|
*
|
|
433
406
|
* This function does the following:
|
|
434
|
-
* - Wraps the incoming request and response into an HTTP
|
|
407
|
+
* - Wraps the incoming request and response into an HTTP wire object.
|
|
435
408
|
* - Determines the correct route based on HTTP method and path.
|
|
436
409
|
* - Executes middleware and the route handler.
|
|
437
410
|
* - Catches and handles errors, optionally bubbling them if configured.
|
|
438
|
-
* - Cleans up any
|
|
411
|
+
* - Cleans up any wire services created during processing.
|
|
439
412
|
*
|
|
440
413
|
* @template In Expected input data type.
|
|
441
414
|
* @template Out Expected output data type.
|
|
@@ -449,7 +422,7 @@ export const fetchData = async <In, Out>(
|
|
|
449
422
|
response: PikkuHTTPResponse,
|
|
450
423
|
{
|
|
451
424
|
singletonServices,
|
|
452
|
-
|
|
425
|
+
createWireServices,
|
|
453
426
|
skipUserSession = false,
|
|
454
427
|
respondWith404 = true,
|
|
455
428
|
logWarningsForStatusCodes = [],
|
|
@@ -462,11 +435,11 @@ export const fetchData = async <In, Out>(
|
|
|
462
435
|
(request as any).getHeader?.('x-request-id') ||
|
|
463
436
|
generateRequestId?.() ||
|
|
464
437
|
createWeakUID()
|
|
465
|
-
let
|
|
438
|
+
let wireServices: WireServices<typeof singletonServices> | undefined
|
|
466
439
|
let result: Out
|
|
467
440
|
|
|
468
|
-
// Combine the request and response into one
|
|
469
|
-
const http =
|
|
441
|
+
// Combine the request and response into one wire object
|
|
442
|
+
const http = createHTTPWire(
|
|
470
443
|
request instanceof Request ? new PikkuFetchHTTPRequest(request) : request,
|
|
471
444
|
response
|
|
472
445
|
)
|
|
@@ -487,10 +460,10 @@ export const fetchData = async <In, Out>(
|
|
|
487
460
|
}
|
|
488
461
|
|
|
489
462
|
// Execute the matched route along with its middleware and session management
|
|
490
|
-
;({ result,
|
|
463
|
+
;({ result, wireServices } = await executeRoute(
|
|
491
464
|
{
|
|
492
465
|
singletonServices,
|
|
493
|
-
|
|
466
|
+
createWireServices,
|
|
494
467
|
skipUserSession,
|
|
495
468
|
requestId,
|
|
496
469
|
},
|
|
@@ -513,8 +486,8 @@ export const fetchData = async <In, Out>(
|
|
|
513
486
|
)
|
|
514
487
|
} finally {
|
|
515
488
|
// Clean up any session-specific services created during processing
|
|
516
|
-
if (
|
|
517
|
-
await
|
|
489
|
+
if (wireServices) {
|
|
490
|
+
await closeWireServices(singletonServices.logger, wireServices)
|
|
518
491
|
}
|
|
519
492
|
}
|
|
520
493
|
}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type { SerializeOptions } from 'cookie'
|
|
2
2
|
import type { PikkuError } from '../../errors/error-handler.js'
|
|
3
3
|
import type {
|
|
4
|
-
PikkuDocs,
|
|
5
4
|
CoreServices,
|
|
6
5
|
CoreSingletonServices,
|
|
7
6
|
CoreUserSession,
|
|
8
|
-
|
|
7
|
+
CreateWireServices,
|
|
9
8
|
CorePikkuMiddleware,
|
|
10
|
-
|
|
11
|
-
PermissionMetadata,
|
|
9
|
+
CommonWireMeta,
|
|
12
10
|
} from '../../types/core.types.js'
|
|
13
11
|
import type {
|
|
14
12
|
CorePikkuFunction,
|
|
@@ -46,7 +44,7 @@ export type RunHTTPWiringOptions = Partial<{
|
|
|
46
44
|
|
|
47
45
|
export type RunHTTPWiringParams = {
|
|
48
46
|
singletonServices: CoreSingletonServices
|
|
49
|
-
|
|
47
|
+
createWireServices: CreateWireServices<
|
|
50
48
|
CoreSingletonServices,
|
|
51
49
|
CoreServices<CoreSingletonServices>,
|
|
52
50
|
CoreUserSession
|
|
@@ -83,7 +81,7 @@ export type CoreHTTPFunction = {
|
|
|
83
81
|
}>
|
|
84
82
|
}
|
|
85
83
|
/**
|
|
86
|
-
* Represents a http
|
|
84
|
+
* Represents a http wire within Pikku, including a request and response.
|
|
87
85
|
*/
|
|
88
86
|
export interface PikkuHTTP<In = unknown> {
|
|
89
87
|
request?: PikkuHTTPRequest<In>
|
|
@@ -123,14 +121,12 @@ export type CoreHTTPFunctionWiring<
|
|
|
123
121
|
In,
|
|
124
122
|
Out,
|
|
125
123
|
any,
|
|
126
|
-
any,
|
|
127
124
|
any
|
|
128
125
|
> = CorePikkuFunction<In, Out>,
|
|
129
126
|
PikkuFunctionSessionless extends CorePikkuFunctionSessionless<
|
|
130
127
|
In,
|
|
131
128
|
Out,
|
|
132
129
|
any,
|
|
133
|
-
any,
|
|
134
130
|
any
|
|
135
131
|
> = CorePikkuFunctionSessionless<In, Out>,
|
|
136
132
|
PikkuPermission extends CorePikkuPermission<
|
|
@@ -242,18 +238,13 @@ export type HTTPFunctionMetaInputTypes = {
|
|
|
242
238
|
/**
|
|
243
239
|
* Represents metadata for a set of HTTP wirings, including HTTP wiring details, methods, input/output types, and documentation.
|
|
244
240
|
*/
|
|
245
|
-
export type HTTPWiringMeta = {
|
|
246
|
-
pikkuFuncName: string
|
|
241
|
+
export type HTTPWiringMeta = CommonWireMeta & {
|
|
247
242
|
route: string
|
|
248
243
|
method: HTTPMethod
|
|
249
244
|
params?: string[]
|
|
250
245
|
query?: string[]
|
|
251
246
|
inputTypes?: HTTPFunctionMetaInputTypes
|
|
252
|
-
docs?: PikkuDocs
|
|
253
|
-
tags?: string[]
|
|
254
247
|
sse?: true
|
|
255
|
-
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (global + route + tag + explicit)
|
|
256
|
-
permissions?: PermissionMetadata[] // Pre-resolved permission chain (global + route + tag + explicit)
|
|
257
248
|
}
|
|
258
249
|
export type HTTPWiringsMeta = Record<HTTPMethod, Record<string, HTTPWiringMeta>>
|
|
259
250
|
|