@pikku/core 0.9.12-next.0 → 0.10.0
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 +8 -0
- package/dist/errors/errors.d.ts +2 -0
- package/dist/errors/errors.js +6 -0
- package/dist/function/function-runner.d.ts +5 -4
- package/dist/function/function-runner.js +10 -4
- package/dist/function/functions.types.d.ts +67 -1
- package/dist/function/functions.types.js +43 -1
- package/dist/index.d.ts +1 -7
- package/dist/index.js +1 -7
- package/dist/middleware/auth-apikey.d.ts +19 -11
- package/dist/middleware/auth-apikey.js +33 -33
- package/dist/middleware/auth-bearer.d.ts +34 -7
- package/dist/middleware/auth-bearer.js +53 -36
- package/dist/middleware/auth-cookie.d.ts +30 -12
- package/dist/middleware/auth-cookie.js +51 -43
- package/dist/middleware/timeout.d.ts +6 -2
- package/dist/middleware/timeout.js +7 -9
- package/dist/middleware-runner.d.ts +0 -18
- package/dist/middleware-runner.js +0 -21
- package/dist/permissions.d.ts +82 -20
- package/dist/permissions.js +175 -62
- package/dist/pikku-state.d.ts +22 -2
- package/dist/pikku-state.js +7 -1
- package/dist/types/core.types.d.ts +58 -1
- package/dist/types/core.types.js +23 -1
- package/dist/utils.d.ts +1 -1
- package/dist/wirings/channel/channel-handler.js +6 -5
- package/dist/wirings/channel/channel-runner.d.ts +3 -1
- package/dist/wirings/channel/channel-runner.js +4 -21
- package/dist/wirings/channel/channel.types.d.ts +12 -13
- package/dist/wirings/cli/channel/cli-channel-runner.js +5 -2
- package/dist/wirings/cli/cli-runner.d.ts +10 -0
- package/dist/wirings/cli/cli-runner.js +44 -20
- package/dist/wirings/cli/cli.types.d.ts +54 -27
- package/dist/wirings/cli/command-parser.js +34 -4
- package/dist/wirings/cli/index.d.ts +1 -1
- package/dist/wirings/cli/index.js +1 -1
- package/dist/wirings/http/http-runner.d.ts +31 -1
- package/dist/wirings/http/http-runner.js +36 -1
- package/dist/wirings/http/http.types.d.ts +2 -1
- package/dist/wirings/http/index.d.ts +1 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
- package/dist/wirings/mcp/mcp-runner.js +2 -0
- package/dist/wirings/mcp/mcp.types.d.ts +35 -14
- package/dist/wirings/scheduler/scheduler-runner.js +1 -0
- package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
- package/package.json +6 -5
- package/src/errors/errors.ts +6 -0
- package/src/factory-functions.test.ts +60 -1
- package/src/function/function-runner.test.ts +8 -3
- package/src/function/function-runner.ts +18 -5
- package/src/function/functions.types.ts +85 -2
- package/src/index.ts +1 -21
- package/src/middleware/auth-apikey.ts +42 -57
- package/src/middleware/auth-bearer.ts +66 -49
- package/src/middleware/auth-cookie.ts +63 -82
- package/src/middleware/timeout.ts +10 -14
- package/src/middleware-runner.ts +0 -25
- package/src/permissions.test.ts +26 -27
- package/src/permissions.ts +215 -104
- package/src/pikku-state.ts +35 -3
- package/src/types/core.types.ts +70 -3
- package/src/utils.ts +1 -1
- package/src/wirings/channel/channel-handler.ts +11 -10
- package/src/wirings/channel/channel-runner.ts +18 -27
- package/src/wirings/channel/channel.types.ts +24 -15
- package/src/wirings/cli/channel/cli-channel-runner.ts +8 -3
- package/src/wirings/cli/cli-runner.test.ts +80 -59
- package/src/wirings/cli/cli-runner.ts +57 -21
- package/src/wirings/cli/cli.types.ts +74 -44
- package/src/wirings/cli/command-parser.test.ts +91 -86
- package/src/wirings/cli/command-parser.ts +38 -4
- package/src/wirings/cli/index.ts +1 -0
- package/src/wirings/http/http-runner.ts +41 -1
- package/src/wirings/http/http.types.ts +3 -1
- package/src/wirings/http/index.ts +7 -1
- package/src/wirings/mcp/mcp-endpoint-registry.ts +1 -1
- package/src/wirings/mcp/mcp-runner.ts +2 -0
- package/src/wirings/mcp/mcp.types.ts +48 -12
- package/src/wirings/scheduler/scheduler-runner.ts +1 -0
- package/src/wirings/scheduler/scheduler.types.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -33,7 +33,7 @@ export function parseCLIArguments(
|
|
|
33
33
|
errors: [],
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const meta = allMeta[programName]
|
|
36
|
+
const meta = allMeta.programs[programName]
|
|
37
37
|
if (!meta) {
|
|
38
38
|
result.errors.push(`Program not found: ${programName}`)
|
|
39
39
|
return result
|
|
@@ -66,10 +66,43 @@ export function parseCLIArguments(
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
// If no command was parsed, check for a default command
|
|
70
|
+
// Only use default if user didn't provide any non-flag arguments
|
|
71
|
+
const hasNonFlagArgs = args.some(
|
|
72
|
+
(arg, idx) => idx >= currentIndex && !arg.startsWith('-')
|
|
73
|
+
)
|
|
74
|
+
if (result.commandPath.length === 0 && meta.commands && !hasNonFlagArgs) {
|
|
75
|
+
for (const [name, cmd] of Object.entries(meta.commands)) {
|
|
76
|
+
if (cmd.isDefault) {
|
|
77
|
+
result.commandPath.push(name)
|
|
78
|
+
currentMeta = {
|
|
79
|
+
program: currentMeta.program,
|
|
80
|
+
commands: cmd.subcommands || {},
|
|
81
|
+
options: {
|
|
82
|
+
...currentMeta.options,
|
|
83
|
+
...cmd.options,
|
|
84
|
+
},
|
|
85
|
+
defaultRenderName: cmd.renderName || currentMeta.defaultRenderName,
|
|
86
|
+
}
|
|
87
|
+
break
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
69
92
|
// Get the final command metadata
|
|
70
93
|
const commandMeta = getCommandMeta(meta, result.commandPath)
|
|
71
94
|
if (!commandMeta) {
|
|
72
|
-
|
|
95
|
+
// If we have no command path but there are non-flag args, the first arg is likely an unknown command
|
|
96
|
+
if (
|
|
97
|
+
result.commandPath.length === 0 &&
|
|
98
|
+
hasNonFlagArgs &&
|
|
99
|
+
args.length > 0 &&
|
|
100
|
+
!args[0].startsWith('-')
|
|
101
|
+
) {
|
|
102
|
+
result.errors.push(`Unknown command: ${args[0]}`)
|
|
103
|
+
} else {
|
|
104
|
+
result.errors.push(`Unknown command: ${result.commandPath.join(' ')}`)
|
|
105
|
+
}
|
|
73
106
|
return result
|
|
74
107
|
}
|
|
75
108
|
|
|
@@ -360,7 +393,7 @@ export function generateCommandHelp(
|
|
|
360
393
|
commandPath: string[] = []
|
|
361
394
|
): string {
|
|
362
395
|
const lines: string[] = []
|
|
363
|
-
const meta = allMeta[programName]
|
|
396
|
+
const meta = allMeta.programs[programName]
|
|
364
397
|
|
|
365
398
|
if (!meta) {
|
|
366
399
|
return `Program not found: ${programName}`
|
|
@@ -374,7 +407,8 @@ export function generateCommandHelp(
|
|
|
374
407
|
|
|
375
408
|
for (const [name, cmd] of Object.entries(meta.commands)) {
|
|
376
409
|
const desc = cmd.description || ''
|
|
377
|
-
|
|
410
|
+
const defaultMarker = cmd.isDefault ? ' (default)' : ''
|
|
411
|
+
lines.push(` ${name.padEnd(20)} ${desc}${defaultMarker}`)
|
|
378
412
|
}
|
|
379
413
|
|
|
380
414
|
if (Object.keys(meta.options).length > 0) {
|
package/src/wirings/cli/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
CorePikkuFunction,
|
|
13
13
|
CorePikkuFunctionSessionless,
|
|
14
14
|
CorePikkuPermission,
|
|
15
|
+
CorePermissionGroup,
|
|
15
16
|
} from '../../function/functions.types.js'
|
|
16
17
|
import {
|
|
17
18
|
CoreUserSession,
|
|
@@ -75,6 +76,44 @@ export const addHTTPMiddleware = <PikkuMiddleware extends CorePikkuMiddleware>(
|
|
|
75
76
|
return middleware
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Registers HTTP permissions for a specific route pattern.
|
|
81
|
+
*
|
|
82
|
+
* This function registers permissions at runtime that will be applied to
|
|
83
|
+
* HTTP routes matching the specified pattern.
|
|
84
|
+
*
|
|
85
|
+
* For tree-shaking benefits, wrap in a factory function:
|
|
86
|
+
* `export const x = () => addHTTPPermission('pattern', [...])`
|
|
87
|
+
*
|
|
88
|
+
* @template PikkuPermission The permission type.
|
|
89
|
+
* @param {string} pattern - Route pattern (e.g., '*' for all routes, '/api/*' for specific routes).
|
|
90
|
+
* @param {CorePermissionGroup | CorePikkuPermission[]} permissions - Permissions for this route pattern.
|
|
91
|
+
*
|
|
92
|
+
* @returns {CorePermissionGroup | CorePikkuPermission[]} The permissions (for chaining/wrapping).
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* // Recommended: tree-shakeable
|
|
97
|
+
* export const httpGlobalPermissions = () => addHTTPPermission('*', [
|
|
98
|
+
* authenticatedPermission,
|
|
99
|
+
* rateLimitPermission
|
|
100
|
+
* ])
|
|
101
|
+
*
|
|
102
|
+
* // Also works: no tree-shaking
|
|
103
|
+
* export const apiPermissions = addHTTPPermission('/api/*', [
|
|
104
|
+
* adminPermission
|
|
105
|
+
* ])
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export const addHTTPPermission = <PikkuPermission extends CorePikkuPermission>(
|
|
109
|
+
pattern: string,
|
|
110
|
+
permissions: CorePermissionGroup | CorePikkuPermission[]
|
|
111
|
+
): CorePermissionGroup | CorePikkuPermission[] => {
|
|
112
|
+
const httpGroups = pikkuState('permissions', 'httpGroup')
|
|
113
|
+
httpGroups[pattern] = permissions
|
|
114
|
+
return permissions
|
|
115
|
+
}
|
|
116
|
+
|
|
78
117
|
/**
|
|
79
118
|
* Adds a new route to the global HTTP route registry.
|
|
80
119
|
*
|
|
@@ -320,9 +359,10 @@ const executeRoute = async (
|
|
|
320
359
|
auth: route.auth !== false,
|
|
321
360
|
userSession,
|
|
322
361
|
data,
|
|
323
|
-
permissions: route.permissions,
|
|
324
362
|
inheritedMiddleware: meta.middleware,
|
|
325
363
|
wireMiddleware: route.middleware,
|
|
364
|
+
inheritedPermissions: meta.permissions,
|
|
365
|
+
wirePermissions: route.permissions,
|
|
326
366
|
coerceDataFromSchema: options.coerceDataFromSchema,
|
|
327
367
|
tags: route.tags,
|
|
328
368
|
interaction,
|
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
CreateSessionServices,
|
|
9
9
|
CorePikkuMiddleware,
|
|
10
10
|
MiddlewareMetadata,
|
|
11
|
+
PermissionMetadata,
|
|
11
12
|
} from '../../types/core.types.js'
|
|
12
13
|
import type {
|
|
13
14
|
CorePikkuFunction,
|
|
@@ -251,7 +252,8 @@ export type HTTPWiringMeta = {
|
|
|
251
252
|
docs?: PikkuDocs
|
|
252
253
|
tags?: string[]
|
|
253
254
|
sse?: true
|
|
254
|
-
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (global + route + tag + explicit
|
|
255
|
+
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (global + route + tag + explicit)
|
|
256
|
+
permissions?: PermissionMetadata[] // Pre-resolved permission chain (global + route + tag + explicit)
|
|
255
257
|
}
|
|
256
258
|
export type HTTPWiringsMeta = Record<HTTPMethod, Record<string, HTTPWiringMeta>>
|
|
257
259
|
|
|
@@ -2,6 +2,12 @@ export * from './pikku-fetch-http-request.js'
|
|
|
2
2
|
export * from './pikku-fetch-http-response.js'
|
|
3
3
|
export * from './log-http-routes.js'
|
|
4
4
|
|
|
5
|
-
export {
|
|
5
|
+
export {
|
|
6
|
+
fetch,
|
|
7
|
+
fetchData,
|
|
8
|
+
wireHTTP,
|
|
9
|
+
addHTTPMiddleware,
|
|
10
|
+
addHTTPPermission,
|
|
11
|
+
} from './http-runner.js'
|
|
6
12
|
|
|
7
13
|
export type * from './http.types.js'
|
|
@@ -276,6 +276,8 @@ async function runMCPPikkuFunc(
|
|
|
276
276
|
data: () => request.params,
|
|
277
277
|
inheritedMiddleware: meta?.middleware,
|
|
278
278
|
wireMiddleware: mcp.middleware,
|
|
279
|
+
inheritedPermissions: meta?.permissions,
|
|
280
|
+
wirePermissions: mcp.permissions,
|
|
279
281
|
tags: mcp.tags,
|
|
280
282
|
interaction,
|
|
281
283
|
}
|
|
@@ -1,12 +1,40 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CorePermissionGroup,
|
|
2
3
|
CorePikkuFunctionConfig,
|
|
3
4
|
CorePikkuFunctionSessionless,
|
|
5
|
+
CorePikkuPermission,
|
|
4
6
|
} from '../../function/functions.types.js'
|
|
5
7
|
import {
|
|
6
8
|
CorePikkuMiddleware,
|
|
7
9
|
MiddlewareMetadata,
|
|
10
|
+
PermissionMetadata,
|
|
8
11
|
} from '../../types/core.types.js'
|
|
9
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Extract URI parameters from MCP resource URI template.
|
|
15
|
+
* E.g., "user/{userId}/post/{postId}" => "userId" | "postId"
|
|
16
|
+
*/
|
|
17
|
+
type ExtractMCPURIParams<S extends string> =
|
|
18
|
+
S extends `${string}{${infer Param}}/${infer Rest}`
|
|
19
|
+
? Param | ExtractMCPURIParams<Rest>
|
|
20
|
+
: S extends `${string}{${infer Param}}`
|
|
21
|
+
? Param
|
|
22
|
+
: never
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Type-level assertion that MCP resource URI parameters are present in the input type.
|
|
26
|
+
* This ensures compile-time safety for URI parameter validation.
|
|
27
|
+
*/
|
|
28
|
+
export type AssertMCPResourceURIParams<In, URI extends string> =
|
|
29
|
+
ExtractMCPURIParams<URI> extends keyof In
|
|
30
|
+
? unknown
|
|
31
|
+
: [
|
|
32
|
+
'Error: MCP Resource URI parameters',
|
|
33
|
+
ExtractMCPURIParams<URI>,
|
|
34
|
+
'not in input type',
|
|
35
|
+
keyof In,
|
|
36
|
+
]
|
|
37
|
+
|
|
10
38
|
export type PikkuMCP<Tools extends string = any> = {
|
|
11
39
|
// elicitInput: <Input>(message: string) => Promise<{ action: string, content: Input }>
|
|
12
40
|
uri?: string
|
|
@@ -21,11 +49,12 @@ export type PikkuMCP<Tools extends string = any> = {
|
|
|
21
49
|
*/
|
|
22
50
|
export type MCPResourceMeta = Record<
|
|
23
51
|
string,
|
|
24
|
-
Omit<CoreMCPResource, 'func' | 'middleware'> & {
|
|
52
|
+
Omit<CoreMCPResource, 'func' | 'middleware' | 'permissions'> & {
|
|
25
53
|
pikkuFuncName: string
|
|
26
54
|
inputSchema: string | null
|
|
27
55
|
outputSchema: string | null
|
|
28
56
|
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
57
|
+
permissions?: PermissionMetadata[] // Pre-resolved permission chain (tag + explicit)
|
|
29
58
|
}
|
|
30
59
|
>
|
|
31
60
|
|
|
@@ -34,11 +63,12 @@ export type MCPResourceMeta = Record<
|
|
|
34
63
|
*/
|
|
35
64
|
export type MCPToolMeta = Record<
|
|
36
65
|
string,
|
|
37
|
-
Omit<CoreMCPTool, 'func' | 'middleware'> & {
|
|
66
|
+
Omit<CoreMCPTool, 'func' | 'middleware' | 'permissions'> & {
|
|
38
67
|
pikkuFuncName: string
|
|
39
68
|
inputSchema: string | null
|
|
40
69
|
outputSchema: string | null
|
|
41
70
|
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
71
|
+
permissions?: PermissionMetadata[] // Pre-resolved permission chain (tag + explicit)
|
|
42
72
|
}
|
|
43
73
|
>
|
|
44
74
|
|
|
@@ -47,7 +77,7 @@ export type MCPToolMeta = Record<
|
|
|
47
77
|
*/
|
|
48
78
|
export type MCPPromptMeta = Record<
|
|
49
79
|
string,
|
|
50
|
-
Omit<CoreMCPPrompt, 'func' | 'middleware'> & {
|
|
80
|
+
Omit<CoreMCPPrompt, 'func' | 'middleware' | 'permissions'> & {
|
|
51
81
|
pikkuFuncName: string
|
|
52
82
|
inputSchema: string | null
|
|
53
83
|
outputSchema: string | null
|
|
@@ -57,6 +87,7 @@ export type MCPPromptMeta = Record<
|
|
|
57
87
|
required: boolean
|
|
58
88
|
}>
|
|
59
89
|
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
90
|
+
permissions?: PermissionMetadata[] // Pre-resolved permission chain (tag + explicit)
|
|
60
91
|
}
|
|
61
92
|
>
|
|
62
93
|
|
|
@@ -64,55 +95,60 @@ export type MCPPromptMeta = Record<
|
|
|
64
95
|
* Represents an MCP resource with specific properties.
|
|
65
96
|
*/
|
|
66
97
|
export type CoreMCPResource<
|
|
67
|
-
|
|
98
|
+
PikkuFunctionConfig = CorePikkuFunctionConfig<
|
|
68
99
|
CorePikkuFunctionSessionless<any, any>
|
|
69
100
|
>,
|
|
101
|
+
PikkuPermission = CorePikkuPermission<any, any>,
|
|
70
102
|
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
71
103
|
> = {
|
|
72
104
|
uri: string
|
|
73
105
|
title: string
|
|
74
|
-
description
|
|
106
|
+
description: string
|
|
75
107
|
mimeType?: string
|
|
76
108
|
size?: number
|
|
77
109
|
streaming?: boolean
|
|
78
|
-
func:
|
|
110
|
+
func: PikkuFunctionConfig
|
|
79
111
|
tags?: string[]
|
|
80
112
|
middleware?: PikkuMiddleware[]
|
|
113
|
+
permissions?: CorePermissionGroup<PikkuPermission>
|
|
81
114
|
}
|
|
82
115
|
|
|
83
116
|
/**
|
|
84
117
|
* Represents an MCP tool with specific properties.
|
|
85
118
|
*/
|
|
86
119
|
export type CoreMCPTool<
|
|
87
|
-
|
|
120
|
+
PikkuFunctionConfig = CorePikkuFunctionConfig<
|
|
88
121
|
CorePikkuFunctionSessionless<any, any>
|
|
89
122
|
>,
|
|
123
|
+
PikkuPermission = CorePikkuPermission<any, any>,
|
|
90
124
|
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
91
125
|
> = {
|
|
92
126
|
name: string
|
|
93
127
|
title?: string
|
|
94
128
|
description: string
|
|
95
|
-
|
|
96
|
-
func: PikkuFunction
|
|
129
|
+
func: PikkuFunctionConfig
|
|
97
130
|
tags?: string[]
|
|
98
131
|
streaming?: boolean
|
|
99
132
|
middleware?: PikkuMiddleware[]
|
|
133
|
+
permissions?: CorePermissionGroup<PikkuPermission>
|
|
100
134
|
}
|
|
101
135
|
|
|
102
136
|
/**
|
|
103
137
|
* Represents an MCP prompt with specific properties.
|
|
104
138
|
*/
|
|
105
139
|
export type CoreMCPPrompt<
|
|
106
|
-
|
|
140
|
+
PikkuFunctionConfig = CorePikkuFunctionConfig<
|
|
107
141
|
CorePikkuFunctionSessionless<any, MCPPromptResponse>
|
|
108
142
|
>,
|
|
143
|
+
PikkuPermission = CorePikkuPermission<any, any>,
|
|
109
144
|
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
110
145
|
> = {
|
|
111
146
|
name: string
|
|
112
|
-
description
|
|
113
|
-
func:
|
|
147
|
+
description: string
|
|
148
|
+
func: PikkuFunctionConfig
|
|
114
149
|
tags?: string[]
|
|
115
150
|
middleware?: PikkuMiddleware[]
|
|
151
|
+
permissions?: CorePermissionGroup<PikkuPermission>
|
|
116
152
|
}
|
|
117
153
|
|
|
118
154
|
export type JsonRpcRequest = {
|
|
@@ -30,14 +30,14 @@ export type ScheduledTasksMeta<UserSession extends CoreUserSession = any> =
|
|
|
30
30
|
* Represents a core scheduled task.
|
|
31
31
|
*/
|
|
32
32
|
export type CoreScheduledTask<
|
|
33
|
-
|
|
33
|
+
PikkuFunctionConfig = CorePikkuFunctionConfig<
|
|
34
34
|
CorePikkuFunctionSessionless<void, void>
|
|
35
35
|
>,
|
|
36
36
|
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
37
37
|
> = {
|
|
38
38
|
name: string
|
|
39
39
|
schedule: string
|
|
40
|
-
func:
|
|
40
|
+
func: PikkuFunctionConfig
|
|
41
41
|
docs?: PikkuDocs
|
|
42
42
|
tags?: string[]
|
|
43
43
|
middleware?: PikkuMiddleware[]
|