@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
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge node types for workflow builder visualization.
|
|
3
|
+
* wireForgeNode is metadata-only - no runtime behavior.
|
|
4
|
+
* The CLI extracts this via AST and generates JSON metadata.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* The type of forge node.
|
|
8
|
+
* - trigger: Starts workflows (webhooks, schedules, events)
|
|
9
|
+
* - action: Operations that do something (API calls, send email, database ops)
|
|
10
|
+
* - end: Terminal nodes with no outputs (logging, notifications)
|
|
11
|
+
*/
|
|
12
|
+
export type ForgeNodeType = 'trigger' | 'action' | 'end';
|
|
13
|
+
/**
|
|
14
|
+
* Configuration for wireForgeNode.
|
|
15
|
+
* This is the input type that developers use when defining nodes.
|
|
16
|
+
*/
|
|
17
|
+
export type CoreForgeNode = {
|
|
18
|
+
/** Unique identifier for this node */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Human-readable name for UI display */
|
|
21
|
+
displayName: string;
|
|
22
|
+
/** Grouping category (validated against forge.node.categories in config) */
|
|
23
|
+
category: string;
|
|
24
|
+
/** Node type determining behavior and outputs */
|
|
25
|
+
type: ForgeNodeType;
|
|
26
|
+
/** RPC name to call when node executes (local name, Forge handles package aliasing) */
|
|
27
|
+
rpc: string;
|
|
28
|
+
/** Optional description for UI */
|
|
29
|
+
description?: string;
|
|
30
|
+
/** Whether to add an error output port alongside the default output */
|
|
31
|
+
errorOutput?: boolean;
|
|
32
|
+
/** Optional tags for filtering/categorization */
|
|
33
|
+
tags?: string[];
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Metadata generated for each forge node.
|
|
37
|
+
* This is the output type that the CLI generates.
|
|
38
|
+
*/
|
|
39
|
+
export type ForgeNodeMeta = {
|
|
40
|
+
name: string;
|
|
41
|
+
displayName: string;
|
|
42
|
+
category: string;
|
|
43
|
+
type: ForgeNodeType;
|
|
44
|
+
/** RPC name (local, remapped by Forge for external packages) */
|
|
45
|
+
rpc: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
/** Whether node has error output port */
|
|
48
|
+
errorOutput: boolean;
|
|
49
|
+
/** Input schema name extracted from RPC */
|
|
50
|
+
inputSchemaName: string | null;
|
|
51
|
+
/** Output schema name extracted from RPC */
|
|
52
|
+
outputSchemaName: string | null;
|
|
53
|
+
tags?: string[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Record of all forge node metadata, keyed by node name.
|
|
57
|
+
*/
|
|
58
|
+
export type ForgeNodesMeta = Record<string, ForgeNodeMeta>;
|
|
59
|
+
/**
|
|
60
|
+
* No-op function for wireForgeNode.
|
|
61
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
62
|
+
* The CLI extracts metadata via AST parsing.
|
|
63
|
+
*/
|
|
64
|
+
export declare const wireForgeNode: (_config: CoreForgeNode) => void;
|
|
65
|
+
/**
|
|
66
|
+
* Configuration for wireForgeCredential.
|
|
67
|
+
* Declares credentials/secrets required by a Forge package.
|
|
68
|
+
* Uses Zod for schema definition - converted to JSON Schema at build time.
|
|
69
|
+
*/
|
|
70
|
+
export type CoreForgeCredential<T = unknown> = {
|
|
71
|
+
/** Unique identifier for this credential */
|
|
72
|
+
name: string;
|
|
73
|
+
/** Human-readable name for UI display */
|
|
74
|
+
displayName: string;
|
|
75
|
+
/** Optional description for UI */
|
|
76
|
+
description?: string;
|
|
77
|
+
/** Key used with SecretService.getSecret() to retrieve the credential */
|
|
78
|
+
secretId: string;
|
|
79
|
+
/** Zod schema defining the structure of the credential */
|
|
80
|
+
schema: T;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Metadata generated for each forge credential.
|
|
84
|
+
* Schema is converted from Zod to JSON Schema at build time.
|
|
85
|
+
*/
|
|
86
|
+
export type ForgeCredentialMeta = {
|
|
87
|
+
name: string;
|
|
88
|
+
displayName: string;
|
|
89
|
+
description?: string;
|
|
90
|
+
secretId: string;
|
|
91
|
+
/** JSON Schema (converted from Zod at build time) or zodLookup reference name */
|
|
92
|
+
schema: Record<string, unknown> | string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Record of all forge credential metadata, keyed by credential name.
|
|
96
|
+
*/
|
|
97
|
+
export type ForgeCredentialsMeta = Record<string, ForgeCredentialMeta>;
|
|
98
|
+
/**
|
|
99
|
+
* No-op function for wireForgeCredential.
|
|
100
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
101
|
+
* The CLI extracts metadata via AST parsing.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* import { z } from 'zod'
|
|
106
|
+
*
|
|
107
|
+
* const slackCredentials = z.object({
|
|
108
|
+
* botToken: z.string().describe('Bot OAuth token'),
|
|
109
|
+
* signingSecret: z.string().describe('Request signing secret')
|
|
110
|
+
* })
|
|
111
|
+
*
|
|
112
|
+
* wireForgeCredential({
|
|
113
|
+
* name: 'slack',
|
|
114
|
+
* displayName: 'Slack Credentials',
|
|
115
|
+
* secretId: 'SLACK_CREDENTIALS',
|
|
116
|
+
* schema: slackCredentials
|
|
117
|
+
* })
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare const wireForgeCredential: <T>(_config: CoreForgeCredential<T>) => void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge node types for workflow builder visualization.
|
|
3
|
+
* wireForgeNode is metadata-only - no runtime behavior.
|
|
4
|
+
* The CLI extracts this via AST and generates JSON metadata.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* No-op function for wireForgeNode.
|
|
8
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
9
|
+
* The CLI extracts metadata via AST parsing.
|
|
10
|
+
*/
|
|
11
|
+
export const wireForgeNode = (_config) => {
|
|
12
|
+
// No-op - metadata only, extracted by CLI via AST
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* No-op function for wireForgeCredential.
|
|
16
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
17
|
+
* The CLI extracts metadata via AST parsing.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { z } from 'zod'
|
|
22
|
+
*
|
|
23
|
+
* const slackCredentials = z.object({
|
|
24
|
+
* botToken: z.string().describe('Bot OAuth token'),
|
|
25
|
+
* signingSecret: z.string().describe('Request signing secret')
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* wireForgeCredential({
|
|
29
|
+
* name: 'slack',
|
|
30
|
+
* displayName: 'Slack Credentials',
|
|
31
|
+
* secretId: 'SLACK_CREDENTIALS',
|
|
32
|
+
* schema: slackCredentials
|
|
33
|
+
* })
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export const wireForgeCredential = (_config) => {
|
|
37
|
+
// No-op - metadata only, extracted by CLI via AST
|
|
38
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './forge-node.types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './forge-node.types.js';
|
|
@@ -31,7 +31,7 @@ import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js';
|
|
|
31
31
|
* ])
|
|
32
32
|
* ```
|
|
33
33
|
*/
|
|
34
|
-
export declare const addHTTPMiddleware: <PikkuMiddleware extends CorePikkuMiddleware>(pattern: string, middleware: CorePikkuMiddlewareGroup) => CorePikkuMiddlewareGroup;
|
|
34
|
+
export declare const addHTTPMiddleware: <PikkuMiddleware extends CorePikkuMiddleware>(pattern: string, middleware: CorePikkuMiddlewareGroup, packageName?: string | null) => CorePikkuMiddlewareGroup;
|
|
35
35
|
/**
|
|
36
36
|
* Registers HTTP permissions for a specific route pattern.
|
|
37
37
|
*
|
|
@@ -61,7 +61,7 @@ export declare const addHTTPMiddleware: <PikkuMiddleware extends CorePikkuMiddle
|
|
|
61
61
|
* ])
|
|
62
62
|
* ```
|
|
63
63
|
*/
|
|
64
|
-
export declare const addHTTPPermission: <PikkuPermission extends CorePikkuPermission>(pattern: string, permissions: CorePermissionGroup | CorePikkuPermission[]) => CorePermissionGroup | CorePikkuPermission[];
|
|
64
|
+
export declare const addHTTPPermission: <PikkuPermission extends CorePikkuPermission>(pattern: string, permissions: CorePermissionGroup | CorePikkuPermission[], packageName?: string | null) => CorePermissionGroup | CorePikkuPermission[];
|
|
65
65
|
/**
|
|
66
66
|
* Adds a new route to the global HTTP route registry.
|
|
67
67
|
*
|
|
@@ -79,16 +79,16 @@ export declare const addHTTPPermission: <PikkuPermission extends CorePikkuPermis
|
|
|
79
79
|
*/
|
|
80
80
|
export declare const wireHTTP: <In, Out, Route extends string, PikkuFunction extends CorePikkuFunction<In, Out> = CorePikkuFunction<In, Out>, PikkuFunctionSessionless extends CorePikkuFunctionSessionless<In, Out> = CorePikkuFunctionSessionless<In, Out>, PikkuPermissionGroup extends CorePikkuPermission<In> = CorePikkuPermission<In>, PikkuMiddleware extends CorePikkuMiddleware = CorePikkuMiddleware>(httpWiring: CoreHTTPFunctionWiring<In, Out, Route, PikkuFunction, PikkuFunctionSessionless, PikkuPermissionGroup, PikkuMiddleware>) => void;
|
|
81
81
|
/**
|
|
82
|
-
* Combines the request and response objects into a single HTTP
|
|
82
|
+
* Combines the request and response objects into a single HTTP wire object.
|
|
83
83
|
*
|
|
84
84
|
* This utility function creates an object that holds both the HTTP request and response,
|
|
85
85
|
* which simplifies passing these around through middleware and route execution.
|
|
86
86
|
*
|
|
87
87
|
* @param {PikkuHTTPRequest | undefined} request - The HTTP request object.
|
|
88
88
|
* @param {PikkuHTTPResponse | undefined} response - The HTTP response object.
|
|
89
|
-
* @returns {PikkuHTTP | undefined} The combined HTTP
|
|
89
|
+
* @returns {PikkuHTTP | undefined} The combined HTTP wire object or undefined if none provided.
|
|
90
90
|
*/
|
|
91
|
-
export declare const
|
|
91
|
+
export declare const createHTTPWire: (request: PikkuHTTPRequest | undefined, response: PikkuHTTPResponse | undefined) => PikkuHTTP | undefined;
|
|
92
92
|
/**
|
|
93
93
|
* Executes an HTTP route for a given Fetch API request.
|
|
94
94
|
*
|
|
@@ -123,11 +123,11 @@ export declare const pikkuFetch: <In, Out>(request: Request | PikkuHTTPRequest,
|
|
|
123
123
|
* middleware execution, error handling, and session service cleanup.
|
|
124
124
|
*
|
|
125
125
|
* This function does the following:
|
|
126
|
-
* - Wraps the incoming request and response into an HTTP
|
|
126
|
+
* - Wraps the incoming request and response into an HTTP wire object.
|
|
127
127
|
* - Determines the correct route based on HTTP method and path.
|
|
128
128
|
* - Executes middleware and the route handler.
|
|
129
129
|
* - Catches and handles errors, optionally bubbling them if configured.
|
|
130
|
-
* - Cleans up any
|
|
130
|
+
* - Cleans up any wire services created during processing.
|
|
131
131
|
*
|
|
132
132
|
* @template In Expected input data type.
|
|
133
133
|
* @template Out Expected output data type.
|
|
@@ -136,4 +136,4 @@ export declare const pikkuFetch: <In, Out>(request: Request | PikkuHTTPRequest,
|
|
|
136
136
|
* @param {RunHTTPWiringOptions & RunHTTPWiringParams} options - Options such as singleton services, session handling, and error configuration.
|
|
137
137
|
* @returns {Promise<Out | void>} The output from the route handler or void if an error occurred.
|
|
138
138
|
*/
|
|
139
|
-
export declare const fetchData: <In, Out>(request: Request | PikkuHTTPRequest, response: PikkuHTTPResponse, { singletonServices,
|
|
139
|
+
export declare const fetchData: <In, Out>(request: Request | PikkuHTTPRequest, response: PikkuHTTPResponse, { singletonServices, createWireServices, skipUserSession, respondWith404, logWarningsForStatusCodes, coerceDataFromSchema, bubbleErrors, generateRequestId, }: RunHTTPWiringOptions & RunHTTPWiringParams) => Promise<Out | void>;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { PikkuWiringTypes, } from '../../types/core.types.js';
|
|
2
1
|
import { NotFoundError } from '../../errors/errors.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { closeWireServices, createWeakUID, isSerializable, } from '../../utils.js';
|
|
3
|
+
import { PikkuSessionService } from '../../services/user-session-service.js';
|
|
5
4
|
import { handleHTTPError } from '../../handle-error.js';
|
|
6
5
|
import { pikkuState } from '../../pikku-state.js';
|
|
7
6
|
import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js';
|
|
8
7
|
import { PikkuFetchHTTPRequest } from './pikku-fetch-http-request.js';
|
|
9
8
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
|
|
10
|
-
import { rpcService } from '../rpc/rpc-runner.js';
|
|
11
9
|
import { httpRouter } from './routers/http-router.js';
|
|
10
|
+
import { startWorkflowByHttpWire } from '../workflow/workflow-utils.js';
|
|
12
11
|
/**
|
|
13
12
|
* Registers HTTP middleware for a specific route pattern.
|
|
14
13
|
*
|
|
@@ -38,8 +37,8 @@ import { httpRouter } from './routers/http-router.js';
|
|
|
38
37
|
* ])
|
|
39
38
|
* ```
|
|
40
39
|
*/
|
|
41
|
-
export const addHTTPMiddleware = (pattern, middleware) => {
|
|
42
|
-
const httpGroups = pikkuState('middleware', 'httpGroup');
|
|
40
|
+
export const addHTTPMiddleware = (pattern, middleware, packageName = null) => {
|
|
41
|
+
const httpGroups = pikkuState(packageName, 'middleware', 'httpGroup');
|
|
43
42
|
httpGroups[pattern] = middleware;
|
|
44
43
|
return middleware;
|
|
45
44
|
};
|
|
@@ -72,8 +71,8 @@ export const addHTTPMiddleware = (pattern, middleware) => {
|
|
|
72
71
|
* ])
|
|
73
72
|
* ```
|
|
74
73
|
*/
|
|
75
|
-
export const addHTTPPermission = (pattern, permissions) => {
|
|
76
|
-
const httpGroups = pikkuState('permissions', 'httpGroup');
|
|
74
|
+
export const addHTTPPermission = (pattern, permissions, packageName = null) => {
|
|
75
|
+
const httpGroups = pikkuState(packageName, 'permissions', 'httpGroup');
|
|
77
76
|
httpGroups[pattern] = permissions;
|
|
78
77
|
return permissions;
|
|
79
78
|
};
|
|
@@ -93,17 +92,19 @@ export const addHTTPPermission = (pattern, permissions) => {
|
|
|
93
92
|
* @param {CoreHTTPFunctionWiring<In, Out, Route, PikkuFunction, PikkuFunctionSessionless, PikkuPermission, PikkuMiddleware>} httpWiring - The HTTP wiring configuration object.
|
|
94
93
|
*/
|
|
95
94
|
export const wireHTTP = (httpWiring) => {
|
|
96
|
-
const httpMeta = pikkuState('http', 'meta');
|
|
95
|
+
const httpMeta = pikkuState(null, 'http', 'meta');
|
|
97
96
|
const routeMeta = httpMeta[httpWiring.method][httpWiring.route];
|
|
98
97
|
if (!routeMeta) {
|
|
99
98
|
throw new Error('Route metadata not found');
|
|
100
99
|
}
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
if (httpWiring.func) {
|
|
101
|
+
addFunction(routeMeta.pikkuFuncName, httpWiring.func);
|
|
102
|
+
}
|
|
103
|
+
const routes = pikkuState(null, 'http', 'routes');
|
|
103
104
|
if (!routes.has(httpWiring.method)) {
|
|
104
105
|
routes.set(httpWiring.method, new Map());
|
|
105
106
|
}
|
|
106
|
-
pikkuState('http', 'routes')
|
|
107
|
+
pikkuState(null, 'http', 'routes')
|
|
107
108
|
.get(httpWiring.method)
|
|
108
109
|
?.set(httpWiring.route, httpWiring);
|
|
109
110
|
};
|
|
@@ -121,10 +122,10 @@ export const wireHTTP = (httpWiring) => {
|
|
|
121
122
|
const getMatchingRoute = (requestType, requestPath) => {
|
|
122
123
|
const matchedPath = httpRouter.match(requestType.toLowerCase(), requestPath);
|
|
123
124
|
if (matchedPath) {
|
|
124
|
-
const route = pikkuState('http', 'routes')
|
|
125
|
+
const route = pikkuState(null, 'http', 'routes')
|
|
125
126
|
.get(requestType.toLowerCase())
|
|
126
127
|
.get(matchedPath.route);
|
|
127
|
-
const meta = pikkuState('http', 'meta')[requestType.toLowerCase()][route.route];
|
|
128
|
+
const meta = pikkuState(null, 'http', 'meta')[requestType.toLowerCase()][route.route];
|
|
128
129
|
return {
|
|
129
130
|
matchedPath,
|
|
130
131
|
params: matchedPath.params,
|
|
@@ -135,16 +136,16 @@ const getMatchingRoute = (requestType, requestPath) => {
|
|
|
135
136
|
}
|
|
136
137
|
};
|
|
137
138
|
/**
|
|
138
|
-
* Combines the request and response objects into a single HTTP
|
|
139
|
+
* Combines the request and response objects into a single HTTP wire object.
|
|
139
140
|
*
|
|
140
141
|
* This utility function creates an object that holds both the HTTP request and response,
|
|
141
142
|
* which simplifies passing these around through middleware and route execution.
|
|
142
143
|
*
|
|
143
144
|
* @param {PikkuHTTPRequest | undefined} request - The HTTP request object.
|
|
144
145
|
* @param {PikkuHTTPResponse | undefined} response - The HTTP response object.
|
|
145
|
-
* @returns {PikkuHTTP | undefined} The combined HTTP
|
|
146
|
+
* @returns {PikkuHTTP | undefined} The combined HTTP wire object or undefined if none provided.
|
|
146
147
|
*/
|
|
147
|
-
export const
|
|
148
|
+
export const createHTTPWire = (request, response) => {
|
|
148
149
|
let http = undefined;
|
|
149
150
|
if (request || response) {
|
|
150
151
|
http = {};
|
|
@@ -172,20 +173,20 @@ export const createHTTPInteraction = (request, response) => {
|
|
|
172
173
|
*
|
|
173
174
|
* @param {Object} services - A collection of shared services and utilities.
|
|
174
175
|
* @param {Object} matchedRoute - Contains route details, URL parameters, and optional schema.
|
|
175
|
-
* @param {PikkuHTTP | undefined} http - The HTTP
|
|
176
|
+
* @param {PikkuHTTP | undefined} http - The HTTP wire object.
|
|
176
177
|
* @param {Object} options - Options for route execution (e.g., whether to coerce query strings to arrays).
|
|
177
|
-
* @returns {Promise<any>} An object containing the route handler result and
|
|
178
|
+
* @returns {Promise<any>} An object containing the route handler result and wire services (if any).
|
|
178
179
|
* @throws Throws errors like MissingSessionError or ForbiddenError on validation failures.
|
|
179
180
|
*/
|
|
180
181
|
const executeRoute = async (services, matchedRoute, http, options) => {
|
|
181
|
-
const userSession = new
|
|
182
|
+
const userSession = new PikkuSessionService();
|
|
182
183
|
const { params, route, meta } = matchedRoute;
|
|
183
|
-
const { singletonServices,
|
|
184
|
-
const requiresSession = route.auth !== false;
|
|
185
|
-
let sessionServices;
|
|
186
|
-
let result;
|
|
184
|
+
const { singletonServices, createWireServices, skipUserSession, requestId } = services;
|
|
187
185
|
// Attach URL parameters to the request object
|
|
188
186
|
http?.request?.setParams(params);
|
|
187
|
+
const requiresSession = route.auth !== false;
|
|
188
|
+
let wireServices;
|
|
189
|
+
let result;
|
|
189
190
|
singletonServices.logger.info(`Matched route: ${route.route} | method: ${route.method.toUpperCase()} | auth: ${requiresSession.toString()}`);
|
|
190
191
|
// Ensure session is available when required
|
|
191
192
|
if (skipUserSession && requiresSession) {
|
|
@@ -219,23 +220,17 @@ const executeRoute = async (services, matchedRoute, http, options) => {
|
|
|
219
220
|
state: 'open',
|
|
220
221
|
};
|
|
221
222
|
}
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
userSession,
|
|
231
|
-
channel,
|
|
232
|
-
}, interaction, route.auth);
|
|
233
|
-
};
|
|
234
|
-
result = await runPikkuFunc(PikkuWiringTypes.http, `${meta.method}:${meta.route}`, meta.pikkuFuncName, {
|
|
223
|
+
const wire = { http, channel, session: userSession };
|
|
224
|
+
if (matchedRoute.meta.workflow === true) {
|
|
225
|
+
await startWorkflowByHttpWire(singletonServices, createWireServices, matchedRoute, wire);
|
|
226
|
+
return wireServices
|
|
227
|
+
? { wireServices, result: http.response }
|
|
228
|
+
: { result: http.response };
|
|
229
|
+
}
|
|
230
|
+
result = await runPikkuFunc('http', `${meta.method}:${meta.route}`, meta.pikkuFuncName, {
|
|
235
231
|
singletonServices,
|
|
236
|
-
|
|
232
|
+
createWireServices,
|
|
237
233
|
auth: route.auth !== false,
|
|
238
|
-
userSession,
|
|
239
234
|
data,
|
|
240
235
|
inheritedMiddleware: meta.middleware,
|
|
241
236
|
wireMiddleware: route.middleware,
|
|
@@ -243,7 +238,7 @@ const executeRoute = async (services, matchedRoute, http, options) => {
|
|
|
243
238
|
wirePermissions: route.permissions,
|
|
244
239
|
coerceDataFromSchema: options.coerceDataFromSchema,
|
|
245
240
|
tags: route.tags,
|
|
246
|
-
|
|
241
|
+
wire,
|
|
247
242
|
});
|
|
248
243
|
// Respond with either a binary or JSON response based on configuration
|
|
249
244
|
if (route.returnsJSON === false) {
|
|
@@ -255,7 +250,7 @@ const executeRoute = async (services, matchedRoute, http, options) => {
|
|
|
255
250
|
http?.response?.status(200);
|
|
256
251
|
// TODO: Evaluate if the response stream should be explicitly ended.
|
|
257
252
|
// http?.response?.end()
|
|
258
|
-
return
|
|
253
|
+
return wireServices ? { result, wireServices } : { result };
|
|
259
254
|
};
|
|
260
255
|
/**
|
|
261
256
|
* Executes an HTTP route for a given Fetch API request.
|
|
@@ -299,11 +294,11 @@ export const pikkuFetch = async (request, params) => {
|
|
|
299
294
|
* middleware execution, error handling, and session service cleanup.
|
|
300
295
|
*
|
|
301
296
|
* This function does the following:
|
|
302
|
-
* - Wraps the incoming request and response into an HTTP
|
|
297
|
+
* - Wraps the incoming request and response into an HTTP wire object.
|
|
303
298
|
* - Determines the correct route based on HTTP method and path.
|
|
304
299
|
* - Executes middleware and the route handler.
|
|
305
300
|
* - Catches and handles errors, optionally bubbling them if configured.
|
|
306
|
-
* - Cleans up any
|
|
301
|
+
* - Cleans up any wire services created during processing.
|
|
307
302
|
*
|
|
308
303
|
* @template In Expected input data type.
|
|
309
304
|
* @template Out Expected output data type.
|
|
@@ -312,14 +307,14 @@ export const pikkuFetch = async (request, params) => {
|
|
|
312
307
|
* @param {RunHTTPWiringOptions & RunHTTPWiringParams} options - Options such as singleton services, session handling, and error configuration.
|
|
313
308
|
* @returns {Promise<Out | void>} The output from the route handler or void if an error occurred.
|
|
314
309
|
*/
|
|
315
|
-
export const fetchData = async (request, response, { singletonServices,
|
|
310
|
+
export const fetchData = async (request, response, { singletonServices, createWireServices, skipUserSession = false, respondWith404 = true, logWarningsForStatusCodes = [], coerceDataFromSchema = true, bubbleErrors = false, generateRequestId, }) => {
|
|
316
311
|
const requestId = request.getHeader?.('x-request-id') ||
|
|
317
312
|
generateRequestId?.() ||
|
|
318
313
|
createWeakUID();
|
|
319
|
-
let
|
|
314
|
+
let wireServices;
|
|
320
315
|
let result;
|
|
321
|
-
// Combine the request and response into one
|
|
322
|
-
const http =
|
|
316
|
+
// Combine the request and response into one wire object
|
|
317
|
+
const http = createHTTPWire(request instanceof Request ? new PikkuFetchHTTPRequest(request) : request, response);
|
|
323
318
|
const apiType = http.request.method();
|
|
324
319
|
const apiRoute = http.request.path();
|
|
325
320
|
// Locate the matching route based on the HTTP method and path
|
|
@@ -336,9 +331,9 @@ export const fetchData = async (request, response, { singletonServices, createSe
|
|
|
336
331
|
}
|
|
337
332
|
// Execute the matched route along with its middleware and session management
|
|
338
333
|
;
|
|
339
|
-
({ result,
|
|
334
|
+
({ result, wireServices } = await executeRoute({
|
|
340
335
|
singletonServices,
|
|
341
|
-
|
|
336
|
+
createWireServices,
|
|
342
337
|
skipUserSession,
|
|
343
338
|
requestId,
|
|
344
339
|
}, matchedRoute, http, { coerceDataFromSchema }));
|
|
@@ -350,8 +345,8 @@ export const fetchData = async (request, response, { singletonServices, createSe
|
|
|
350
345
|
}
|
|
351
346
|
finally {
|
|
352
347
|
// Clean up any session-specific services created during processing
|
|
353
|
-
if (
|
|
354
|
-
await
|
|
348
|
+
if (wireServices) {
|
|
349
|
+
await closeWireServices(singletonServices.logger, wireServices);
|
|
355
350
|
}
|
|
356
351
|
}
|
|
357
352
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SerializeOptions } from 'cookie';
|
|
2
2
|
import type { PikkuError } from '../../errors/error-handler.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { CoreServices, CoreSingletonServices, CoreUserSession, CreateWireServices, CorePikkuMiddleware, CommonWireMeta } from '../../types/core.types.js';
|
|
4
4
|
import type { CorePikkuFunction, CorePikkuFunctionSessionless, CorePikkuPermission, CorePermissionGroup, CorePikkuFunctionConfig } from '../../function/functions.types.js';
|
|
5
5
|
type ExtractHTTPWiringParams<S extends string> = S extends `${string}:${infer Param}/${infer Rest}` ? Param | ExtractHTTPWiringParams<`/${Rest}`> : S extends `${string}:${infer Param}` ? Param : never;
|
|
6
6
|
export type AssertHTTPWiringParams<In, HTTPWiring extends string> = ExtractHTTPWiringParams<HTTPWiring> extends keyof In ? unknown : [
|
|
@@ -19,7 +19,7 @@ export type RunHTTPWiringOptions = Partial<{
|
|
|
19
19
|
}>;
|
|
20
20
|
export type RunHTTPWiringParams = {
|
|
21
21
|
singletonServices: CoreSingletonServices;
|
|
22
|
-
|
|
22
|
+
createWireServices: CreateWireServices<CoreSingletonServices, CoreServices<CoreSingletonServices>, CoreUserSession>;
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
25
25
|
* Represents the HTTP methods supported for API HTTP wirings.
|
|
@@ -43,7 +43,7 @@ export type CoreHTTPFunction = {
|
|
|
43
43
|
}>;
|
|
44
44
|
};
|
|
45
45
|
/**
|
|
46
|
-
* Represents a http
|
|
46
|
+
* Represents a http wire within Pikku, including a request and response.
|
|
47
47
|
*/
|
|
48
48
|
export interface PikkuHTTP<In = unknown> {
|
|
49
49
|
request?: PikkuHTTPRequest<In>;
|
|
@@ -67,7 +67,7 @@ export type PikkuQuery<T = Record<string, string | undefined>> = Record<string,
|
|
|
67
67
|
* @template PikkuFunctionSessionless - The sessionless API function type, defaults to `CorePikkuFunctionSessionless`.
|
|
68
68
|
* @template PikkuPermission - The permission function type, defaults to `CorePikkuPermission`.
|
|
69
69
|
*/
|
|
70
|
-
export type CoreHTTPFunctionWiring<In, Out, R extends string, PikkuFunction extends CorePikkuFunction<In, Out, any, any
|
|
70
|
+
export type CoreHTTPFunctionWiring<In, Out, R extends string, PikkuFunction extends CorePikkuFunction<In, Out, any, any> = CorePikkuFunction<In, Out>, PikkuFunctionSessionless extends CorePikkuFunctionSessionless<In, Out, any, any> = CorePikkuFunctionSessionless<In, Out>, PikkuPermission extends CorePikkuPermission<In, any, any> = CorePikkuPermission<In, any, any>, PikkuMiddleware extends CorePikkuMiddleware<any, any> = CorePikkuMiddleware<any>> = (CoreHTTPFunction & {
|
|
71
71
|
route: R;
|
|
72
72
|
method: HTTPMethod;
|
|
73
73
|
func: CorePikkuFunctionConfig<PikkuFunction, PikkuPermission, PikkuMiddleware>;
|
|
@@ -123,7 +123,19 @@ export type CoreHTTPFunctionWiring<In, Out, R extends string, PikkuFunction exte
|
|
|
123
123
|
tags?: string[];
|
|
124
124
|
middleware?: PikkuMiddleware[];
|
|
125
125
|
sse?: undefined;
|
|
126
|
-
})
|
|
126
|
+
}) | {
|
|
127
|
+
/** Route triggers a workflow matched by route/method from workflow wires.http */
|
|
128
|
+
route: R;
|
|
129
|
+
method: HTTPMethod;
|
|
130
|
+
workflow: true;
|
|
131
|
+
func?: undefined;
|
|
132
|
+
permissions?: undefined;
|
|
133
|
+
auth?: undefined;
|
|
134
|
+
tags?: undefined;
|
|
135
|
+
middleware?: undefined;
|
|
136
|
+
returnsJSON?: undefined;
|
|
137
|
+
sse?: boolean;
|
|
138
|
+
};
|
|
127
139
|
/**
|
|
128
140
|
* Represents the input types for HTTP wiring metadata, including parameters, query, and body types.
|
|
129
141
|
*/
|
|
@@ -135,18 +147,14 @@ export type HTTPFunctionMetaInputTypes = {
|
|
|
135
147
|
/**
|
|
136
148
|
* Represents metadata for a set of HTTP wirings, including HTTP wiring details, methods, input/output types, and documentation.
|
|
137
149
|
*/
|
|
138
|
-
export type HTTPWiringMeta = {
|
|
139
|
-
pikkuFuncName: string;
|
|
150
|
+
export type HTTPWiringMeta = CommonWireMeta & {
|
|
140
151
|
route: string;
|
|
141
152
|
method: HTTPMethod;
|
|
142
153
|
params?: string[];
|
|
143
154
|
query?: string[];
|
|
144
155
|
inputTypes?: HTTPFunctionMetaInputTypes;
|
|
145
|
-
docs?: PikkuDocs;
|
|
146
|
-
tags?: string[];
|
|
147
156
|
sse?: true;
|
|
148
|
-
|
|
149
|
-
permissions?: PermissionMetadata[];
|
|
157
|
+
workflow?: true;
|
|
150
158
|
};
|
|
151
159
|
export type HTTPWiringsMeta = Record<HTTPMethod, Record<string, HTTPWiringMeta>>;
|
|
152
160
|
export type HTTPFunctionsMeta = Array<{
|
|
@@ -4,7 +4,7 @@ import { pikkuState } from '../../pikku-state.js';
|
|
|
4
4
|
* @param logger - A logger for logging information.
|
|
5
5
|
*/
|
|
6
6
|
export const logRoutes = (logger) => {
|
|
7
|
-
const routesByType = pikkuState('http', 'routes');
|
|
7
|
+
const routesByType = pikkuState(null, 'http', 'routes');
|
|
8
8
|
if (routesByType.size === 0) {
|
|
9
9
|
logger.info('No routes added');
|
|
10
10
|
return;
|
|
@@ -10,8 +10,8 @@ export class PathToRegexRouter {
|
|
|
10
10
|
this.isInitialized = false;
|
|
11
11
|
}
|
|
12
12
|
initialize() {
|
|
13
|
-
const routes = pikkuState('http', 'routes');
|
|
14
|
-
const channelRoutes = pikkuState('channel', 'channels');
|
|
13
|
+
const routes = pikkuState(null, 'http', 'routes');
|
|
14
|
+
const channelRoutes = pikkuState(null, 'channel', 'channels');
|
|
15
15
|
// Helper function to compile routes for a given method
|
|
16
16
|
const compileRoutesForMethod = (method, routeEntries) => {
|
|
17
17
|
const methodCompiledRoutes = this.compiledRoutes.get(method) || new Map();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CoreServices, type CoreSingletonServices, type CoreUserSession, type
|
|
1
|
+
import { type CoreServices, type CoreSingletonServices, type CoreUserSession, type CreateWireServices } from '../../types/core.types.js';
|
|
2
2
|
import type { CoreMCPResource, CoreMCPTool, CoreMCPPrompt, JsonRpcRequest, JsonRpcResponse, JsonRpcErrorResponse, PikkuMCP } from './mcp.types.js';
|
|
3
3
|
import type { CorePikkuFunctionConfig, CorePikkuFunctionSessionless } from '../../function/functions.types.js';
|
|
4
4
|
export declare class MCPError extends Error {
|
|
@@ -8,7 +8,7 @@ export declare class MCPError extends Error {
|
|
|
8
8
|
export type RunMCPEndpointParams<Tools extends string = any> = {
|
|
9
9
|
singletonServices: CoreSingletonServices;
|
|
10
10
|
mcp?: PikkuMCP<Tools>;
|
|
11
|
-
|
|
11
|
+
createWireServices?: CreateWireServices<CoreSingletonServices, CoreServices<CoreSingletonServices>, CoreUserSession>;
|
|
12
12
|
};
|
|
13
13
|
export type JsonRpcError = {
|
|
14
14
|
code: number;
|