@pikku/inspector 0.12.58 → 0.12.60
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 +127 -0
- package/dist/add/add-agent-scorer.d.ts +2 -0
- package/dist/add/add-agent-scorer.js +61 -0
- package/dist/add/add-agent.d.ts +4 -0
- package/dist/add/add-agent.js +442 -0
- package/dist/add/add-channel.d.ts +1 -1
- package/dist/add/add-functions.js +1 -1
- package/dist/add/add-keyed-wiring.js +1 -1
- package/dist/add/add-middleware.js +5 -5
- package/dist/add/add-personas.js +1 -1
- package/dist/add/add-wire-addon.js +10 -0
- package/dist/add/add-workflow.d.ts +1 -1
- package/dist/error-codes.d.ts +1 -0
- package/dist/error-codes.js +1 -0
- package/dist/inspector.js +1 -1
- package/dist/types.d.ts +27 -22
- package/dist/utils/compute-required-schemas.d.ts +1 -1
- package/dist/utils/contract-hashes.d.ts +2 -1
- package/dist/utils/contract-hashes.js +1 -1
- package/dist/utils/extract-function-name.js +1 -1
- package/dist/utils/extract-services.d.ts +1 -1
- package/dist/utils/filter-inspector-state.js +1 -1
- package/dist/utils/filter-utils.d.ts +1 -1
- package/dist/utils/middleware.d.ts +2 -2
- package/dist/utils/middleware.js +5 -5
- package/dist/utils/permissions.d.ts +1 -1
- package/dist/utils/post-process.d.ts +2 -2
- package/dist/utils/post-process.js +24 -12
- package/dist/utils/resolve-deploy-target.d.ts +1 -1
- package/dist/utils/resolve-function-meta.d.ts +1 -1
- package/dist/utils/resolve-function-types.d.ts +1 -1
- package/dist/utils/resolve-versions.js +1 -1
- package/dist/utils/schema-generator.d.ts +1 -1
- package/dist/utils/serialize-inspector-state.d.ts +5 -3
- package/dist/utils/serialize-inspector-state.js +4 -4
- package/dist/utils/serialize-openapi-json.d.ts +2 -2
- package/dist/utils/workflow/derive-workflow-plan.d.ts +1 -1
- package/dist/utils/workflow/dsl/extract-dsl-workflow.d.ts +1 -1
- package/dist/utils/workflow/graph/convert-dsl-to-graph.d.ts +1 -1
- package/dist/utils/workflow/graph/finalize-workflows.js +1 -1
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +1 -1
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +2 -1
- package/dist/visit.js +4 -4
- package/package.json +3 -3
- package/src/add/{add-ai-scorer.test.ts → add-agent-scorer.test.ts} +11 -11
- package/src/add/{add-ai-scorer.ts → add-agent-scorer.ts} +4 -4
- package/src/add/{add-ai-agent.test.ts → add-agent.test.ts} +1 -1
- package/src/add/{add-ai-agent.ts → add-agent.ts} +11 -17
- package/src/add/add-auth.ts +1 -1
- package/src/add/add-channel.ts +4 -1
- package/src/add/add-cli.ts +1 -1
- package/src/add/add-functions.ts +9 -4
- package/src/add/add-gateway.ts +1 -1
- package/src/add/add-http-route.ts +1 -1
- package/src/add/add-keyed-wiring.ts +1 -1
- package/src/add/add-middleware.ts +7 -5
- package/src/add/add-permission.ts +1 -1
- package/src/add/add-personas.test.ts +2 -2
- package/src/add/add-personas.ts +3 -2
- package/src/add/add-scenario-step.test.ts +2 -1
- package/src/add/add-scope.test.ts +19 -19
- package/src/add/add-scope.ts +1 -1
- package/src/add/add-system-role.test.ts +12 -12
- package/src/add/add-wire-addon.test.ts +31 -0
- package/src/add/add-wire-addon.ts +8 -0
- package/src/add/add-workflow-graph-input.test.ts +1 -1
- package/src/add/add-workflow.ts +4 -1
- package/src/add/addon-contracts.test.ts +1 -1
- package/src/error-codes.ts +1 -0
- package/src/inspector.ts +1 -1
- package/src/types.ts +33 -23
- package/src/utils/compute-required-schemas.ts +1 -1
- package/src/utils/contract-hashes.test.ts +1 -1
- package/src/utils/contract-hashes.ts +3 -2
- package/src/utils/extract-function-name.ts +1 -1
- package/src/utils/extract-services.ts +4 -1
- package/src/utils/filter-inspector-state.ts +2 -2
- package/src/utils/filter-utils.ts +1 -1
- package/src/utils/middleware.test.ts +23 -23
- package/src/utils/middleware.ts +6 -6
- package/src/utils/permissions.ts +1 -1
- package/src/utils/post-process.test.ts +76 -9
- package/src/utils/post-process.ts +36 -14
- package/src/utils/resolve-deploy-target.ts +1 -1
- package/src/utils/resolve-function-meta.ts +4 -1
- package/src/utils/resolve-function-types.ts +1 -1
- package/src/utils/resolve-versions.ts +5 -2
- package/src/utils/schema-generator.ts +3 -2
- package/src/utils/serialize-inspector-state.ts +9 -7
- package/src/utils/serialize-mcp-json.ts +1 -1
- package/src/utils/serialize-openapi-json.ts +2 -2
- package/src/utils/workflow/derive-workflow-plan.test.ts +1 -1
- package/src/utils/workflow/derive-workflow-plan.ts +1 -1
- package/src/utils/workflow/dsl/extract-approval-policy.test.ts +5 -2
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +2 -2
- package/src/utils/workflow/graph/convert-dsl-to-graph-skip.test.ts +1 -1
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +4 -1
- package/src/utils/workflow/graph/finalize-workflow-wires.ts +1 -1
- package/src/utils/workflow/graph/finalize-workflows.ts +6 -2
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +1 -1
- package/src/utils/workflow/graph/workflow-graph.types.ts +2 -2
- package/src/visit.ts +4 -4
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -60,6 +60,8 @@ export function addWireAddon(
|
|
|
60
60
|
let secretOverrides: Record<string, string> | undefined
|
|
61
61
|
let variableOverrides: Record<string, string> | undefined
|
|
62
62
|
let credentialOverrides: Record<string, string> | undefined
|
|
63
|
+
let secretGrants: string[] | undefined
|
|
64
|
+
let credentialGrants: string[] | undefined
|
|
63
65
|
let globalSecrets: string | undefined
|
|
64
66
|
let globalCredentials: string | undefined
|
|
65
67
|
|
|
@@ -104,6 +106,10 @@ export function addWireAddon(
|
|
|
104
106
|
ts.isObjectLiteralExpression(prop.initializer)
|
|
105
107
|
) {
|
|
106
108
|
credentialOverrides = parseStringRecord(prop.initializer)
|
|
109
|
+
} else if (key === 'secretGrants') {
|
|
110
|
+
secretGrants = parseStringArray(prop.initializer)
|
|
111
|
+
} else if (key === 'credentialGrants') {
|
|
112
|
+
credentialGrants = parseStringArray(prop.initializer)
|
|
107
113
|
} else if (key === 'globalSecrets') {
|
|
108
114
|
// The grant is real at runtime whatever the reason evaluates to, so a
|
|
109
115
|
// non-literal is recorded as its source text rather than dropped.
|
|
@@ -130,6 +136,8 @@ export function addWireAddon(
|
|
|
130
136
|
secretOverrides,
|
|
131
137
|
variableOverrides,
|
|
132
138
|
credentialOverrides,
|
|
139
|
+
secretGrants,
|
|
140
|
+
credentialGrants,
|
|
133
141
|
globalSecrets,
|
|
134
142
|
globalCredentials,
|
|
135
143
|
})
|
|
@@ -36,7 +36,7 @@ describe('addWorkflowGraph — node input extraction', () => {
|
|
|
36
36
|
graphFile,
|
|
37
37
|
[
|
|
38
38
|
"import { pikkuWorkflowGraph } from '@pikku/core/workflow'",
|
|
39
|
-
"import { template } from '@pikku/core/workflow'",
|
|
39
|
+
"import { template } from '@pikku/core/ecosystem/workflow'",
|
|
40
40
|
'export const myGraph = pikkuWorkflowGraph({',
|
|
41
41
|
" name: 'input-graph',",
|
|
42
42
|
" nodes: { edit: 'edit' },",
|
package/src/add/add-workflow.ts
CHANGED
|
@@ -3,7 +3,10 @@ import type { AddWiring, InspectorState } from '../types.js'
|
|
|
3
3
|
import { extractFunctionName } from '../utils/extract-function-name.js'
|
|
4
4
|
import { extractFunctionNode } from '../utils/extract-function-node.js'
|
|
5
5
|
import { ErrorCode } from '../error-codes.js'
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
WorkflowStepMeta,
|
|
8
|
+
WorkflowContext,
|
|
9
|
+
} from '@pikku/core/ecosystem/workflow'
|
|
7
10
|
import {
|
|
8
11
|
extractStringLiteral,
|
|
9
12
|
isStringLike,
|
|
@@ -178,7 +178,7 @@ describe('addon contract metadata', () => {
|
|
|
178
178
|
await writeFile(
|
|
179
179
|
appFile,
|
|
180
180
|
[
|
|
181
|
-
"import { wireAddon } from '@pikku/core/rpc'",
|
|
181
|
+
"import { wireAddon } from '@pikku/core/ecosystem/rpc'",
|
|
182
182
|
"import { wireHTTPRoutes } from '@pikku/core/http'",
|
|
183
183
|
"import { wireChannel } from '@pikku/core/channel'",
|
|
184
184
|
"import { wireCLI } from '@pikku/core/cli'",
|
package/src/error-codes.ts
CHANGED
package/src/inspector.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -1,35 +1,41 @@
|
|
|
1
1
|
import type * as ts from 'typescript'
|
|
2
2
|
import type { SecretUsage } from './utils/extract-secret-usage.js'
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
9
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
ChannelMessageMeta,
|
|
5
|
+
ChannelsMeta,
|
|
6
|
+
} from '@pikku/core/ecosystem/channel'
|
|
7
|
+
import type { GatewaysMeta } from '@pikku/core/ecosystem/gateway'
|
|
8
|
+
import type { HTTPWiringsMeta } from '@pikku/core/ecosystem/http'
|
|
9
|
+
import type { ScheduledTasksMeta } from '@pikku/core/ecosystem/scheduler'
|
|
10
|
+
import type {
|
|
11
|
+
TriggerMeta,
|
|
12
|
+
TriggerSourceMeta,
|
|
13
|
+
} from '@pikku/core/ecosystem/trigger'
|
|
14
|
+
import type { QueueWorkersMeta } from '@pikku/core/ecosystem/queue'
|
|
15
|
+
import type { WorkflowsMeta } from '@pikku/core/ecosystem/workflow'
|
|
10
16
|
import type {
|
|
11
17
|
MCPResourceMeta,
|
|
12
18
|
MCPToolMeta,
|
|
13
19
|
MCPPromptMeta,
|
|
14
|
-
} from '@pikku/core/mcp'
|
|
15
|
-
import type {
|
|
16
|
-
import type { ScorerMeta } from '@pikku/core/
|
|
17
|
-
import type { CLIMeta } from '@pikku/core/cli'
|
|
18
|
-
import type { CLICommandMeta } from '@pikku/core/cli'
|
|
19
|
-
import type { NodesMeta } from '@pikku/core/node'
|
|
20
|
-
import type { SecretDefinitions } from '@pikku/core/secret'
|
|
21
|
-
import type { CredentialDefinitions } from '@pikku/core/credential'
|
|
22
|
-
import type { ScopeDefinitions } from '@pikku/core/scope'
|
|
23
|
-
import type { SystemRoleDefinitions } from '@pikku/core/role'
|
|
24
|
-
import type { PersonaDefinitions } from '@pikku/core/persona'
|
|
25
|
-
import type { VariableDefinitions } from '@pikku/core/variable'
|
|
20
|
+
} from '@pikku/core/ecosystem/mcp'
|
|
21
|
+
import type { AgentsMeta } from '@pikku/core/ecosystem/agent'
|
|
22
|
+
import type { ScorerMeta } from '@pikku/core/ecosystem/agent-scorer'
|
|
23
|
+
import type { CLIMeta } from '@pikku/core/ecosystem/cli'
|
|
24
|
+
import type { CLICommandMeta } from '@pikku/core/ecosystem/cli'
|
|
25
|
+
import type { NodesMeta } from '@pikku/core/ecosystem/node'
|
|
26
|
+
import type { SecretDefinitions } from '@pikku/core/ecosystem/secret'
|
|
27
|
+
import type { CredentialDefinitions } from '@pikku/core/ecosystem/credential'
|
|
28
|
+
import type { ScopeDefinitions } from '@pikku/core/ecosystem/scope'
|
|
29
|
+
import type { SystemRoleDefinitions } from '@pikku/core/ecosystem/role'
|
|
30
|
+
import type { PersonaDefinitions } from '@pikku/core/ecosystem/persona'
|
|
31
|
+
import type { VariableDefinitions } from '@pikku/core/ecosystem/variable'
|
|
26
32
|
import type { TypesMap } from './types-map.js'
|
|
33
|
+
import type { FunctionsMeta } from '@pikku/core/ecosystem/services'
|
|
27
34
|
import type {
|
|
28
|
-
FunctionsMeta,
|
|
29
35
|
FunctionServicesMeta,
|
|
30
36
|
FunctionWiresMeta,
|
|
31
37
|
JSONValue,
|
|
32
|
-
} from '@pikku/core'
|
|
38
|
+
} from '@pikku/core/ecosystem/types'
|
|
33
39
|
import type { OpenAPISpecInfo } from './utils/serialize-openapi-json.js'
|
|
34
40
|
import type { ErrorCode, CodedDiagnostic } from './error-codes.js'
|
|
35
41
|
import type {
|
|
@@ -588,6 +594,10 @@ export interface InspectorState {
|
|
|
588
594
|
secretOverrides?: Record<string, string>
|
|
589
595
|
variableOverrides?: Record<string, string>
|
|
590
596
|
credentialOverrides?: Record<string, string>
|
|
597
|
+
/** Secrets the app lends this instance, named as the addon reads them. */
|
|
598
|
+
secretGrants?: string[]
|
|
599
|
+
/** Credentials the app lends this instance, named as the addon reads them. */
|
|
600
|
+
credentialGrants?: string[]
|
|
591
601
|
/**
|
|
592
602
|
* The app's stated reason for handing this instance the whole
|
|
593
603
|
* `SecretService` instead of one scoped to its declared secrets.
|
|
@@ -609,7 +619,7 @@ export interface InspectorState {
|
|
|
609
619
|
files: Set<string>
|
|
610
620
|
}
|
|
611
621
|
agents: {
|
|
612
|
-
agentsMeta:
|
|
622
|
+
agentsMeta: AgentsMeta
|
|
613
623
|
files: Map<string, { path: string; exportedName: string }>
|
|
614
624
|
}
|
|
615
625
|
scorers: {
|
|
@@ -677,7 +687,7 @@ export interface InspectorState {
|
|
|
677
687
|
}
|
|
678
688
|
middleware: InspectorMiddlewareState
|
|
679
689
|
channelMiddleware: InspectorChannelMiddlewareState
|
|
680
|
-
|
|
690
|
+
agentMiddleware: InspectorAIMiddlewareState
|
|
681
691
|
permissions: InspectorPermissionState
|
|
682
692
|
serviceAggregation: {
|
|
683
693
|
requiredServices: Set<string>
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
extractContractsFromMeta,
|
|
11
11
|
} from './contract-hashes.js'
|
|
12
12
|
import type { ContractEntry, VersionManifest } from './contract-hashes.js'
|
|
13
|
-
import type { FunctionsMeta } from '@pikku/core'
|
|
13
|
+
import type { FunctionsMeta } from '@pikku/core/ecosystem/services'
|
|
14
14
|
import { ErrorCode } from '../error-codes.js'
|
|
15
15
|
|
|
16
16
|
function makeContracts(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { FunctionsMeta
|
|
2
|
-
import {
|
|
1
|
+
import type { FunctionsMeta } from '@pikku/core/ecosystem/services'
|
|
2
|
+
import type { JSONValue } from '@pikku/core/ecosystem/types'
|
|
3
|
+
import { parseVersionedId } from '@pikku/core/ecosystem/types'
|
|
3
4
|
import type { TypesMap } from '../types-map.js'
|
|
4
5
|
import { ErrorCode } from '../error-codes.js'
|
|
5
6
|
import { canonicalJSON, hashString } from './hash.js'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
2
|
import { createHash } from 'crypto'
|
|
3
3
|
import { relative } from 'path'
|
|
4
|
-
import { formatVersionedId } from '@pikku/core'
|
|
4
|
+
import { formatVersionedId } from '@pikku/core/ecosystem/types'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Deterministic placeholder id for an anonymous/unnamed pikku function or
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
FunctionServicesMeta,
|
|
4
|
+
FunctionWiresMeta,
|
|
5
|
+
} from '@pikku/core/ecosystem/types'
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
* Extract services from a function's first parameter destructuring pattern
|
|
@@ -3,8 +3,8 @@ import type {
|
|
|
3
3
|
InspectorFilters,
|
|
4
4
|
InspectorLogger,
|
|
5
5
|
} from '../types.js'
|
|
6
|
-
import type { PikkuWiringTypes } from '@pikku/core'
|
|
7
|
-
import { parseVersionedId } from '@pikku/core'
|
|
6
|
+
import type { PikkuWiringTypes } from '@pikku/core/ecosystem/types'
|
|
7
|
+
import { parseVersionedId } from '@pikku/core/ecosystem/types'
|
|
8
8
|
import { aggregateRequiredServices } from './post-process.js'
|
|
9
9
|
import { resolveDeployTarget } from './resolve-deploy-target.js'
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, test } from 'node:test'
|
|
2
2
|
import assert from 'node:assert'
|
|
3
|
-
import {
|
|
3
|
+
import { resolveAgentMiddleware } from './middleware.js'
|
|
4
4
|
import { getInitialInspectorState } from '../inspector.js'
|
|
5
5
|
import * as ts from 'typescript'
|
|
6
6
|
|
|
@@ -26,39 +26,39 @@ function createMockChecker(): ts.TypeChecker {
|
|
|
26
26
|
return {} as any
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
describe('
|
|
30
|
-
test('should return undefined when no
|
|
29
|
+
describe('resolveAgentMiddleware', () => {
|
|
30
|
+
test('should return undefined when no agentMiddleware property exists', () => {
|
|
31
31
|
const state = getInitialInspectorState('/test')
|
|
32
32
|
const src = createSourceFile('const x = { name: "test" }')
|
|
33
33
|
const obj = getObjectLiteral(src)
|
|
34
34
|
const checker = createMockChecker()
|
|
35
35
|
|
|
36
|
-
const result =
|
|
36
|
+
const result = resolveAgentMiddleware(state, obj, checker)
|
|
37
37
|
|
|
38
38
|
assert.strictEqual(result, undefined)
|
|
39
39
|
})
|
|
40
40
|
|
|
41
|
-
test('should return undefined when
|
|
41
|
+
test('should return undefined when agentMiddleware array is empty', () => {
|
|
42
42
|
const state = getInitialInspectorState('/test')
|
|
43
|
-
const src = createSourceFile('const x = {
|
|
43
|
+
const src = createSourceFile('const x = { agentMiddleware: [] }')
|
|
44
44
|
const obj = getObjectLiteral(src)
|
|
45
45
|
const checker = createMockChecker()
|
|
46
46
|
|
|
47
|
-
const result =
|
|
47
|
+
const result = resolveAgentMiddleware(state, obj, checker)
|
|
48
48
|
|
|
49
49
|
assert.strictEqual(result, undefined)
|
|
50
50
|
})
|
|
51
51
|
|
|
52
|
-
test('should resolve
|
|
52
|
+
test('should resolve agentMiddleware identifiers as wire metadata', () => {
|
|
53
53
|
const state = getInitialInspectorState('/test')
|
|
54
|
-
state.
|
|
54
|
+
state.agentMiddleware.definitions['myAIMW'] = {
|
|
55
55
|
services: { optimized: true, services: ['logger'] },
|
|
56
56
|
sourceFile: '/test/middleware.ts',
|
|
57
57
|
position: 0,
|
|
58
58
|
exportedName: 'myAIMW',
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
const code = 'const x = {
|
|
61
|
+
const code = 'const x = { agentMiddleware: [myAIMW] }'
|
|
62
62
|
const program = ts.createProgram({
|
|
63
63
|
rootNames: ['test.ts'],
|
|
64
64
|
options: { target: ts.ScriptTarget.ESNext },
|
|
@@ -77,7 +77,7 @@ describe('resolveAIMiddleware', () => {
|
|
|
77
77
|
const sourceFile = program.getSourceFile('test.ts')!
|
|
78
78
|
const obj = getObjectLiteral(sourceFile)
|
|
79
79
|
|
|
80
|
-
const result =
|
|
80
|
+
const result = resolveAgentMiddleware(state, obj, checker)
|
|
81
81
|
|
|
82
82
|
assert.ok(result)
|
|
83
83
|
assert.strictEqual(result.length, 1)
|
|
@@ -88,22 +88,22 @@ describe('resolveAIMiddleware', () => {
|
|
|
88
88
|
})
|
|
89
89
|
})
|
|
90
90
|
|
|
91
|
-
test('should resolve multiple
|
|
91
|
+
test('should resolve multiple agentMiddleware entries', () => {
|
|
92
92
|
const state = getInitialInspectorState('/test')
|
|
93
|
-
state.
|
|
93
|
+
state.agentMiddleware.definitions['firstMW'] = {
|
|
94
94
|
services: { optimized: true, services: ['logger'] },
|
|
95
95
|
sourceFile: '/test/middleware.ts',
|
|
96
96
|
position: 0,
|
|
97
97
|
exportedName: 'firstMW',
|
|
98
98
|
}
|
|
99
|
-
state.
|
|
99
|
+
state.agentMiddleware.definitions['secondMW'] = {
|
|
100
100
|
services: { optimized: true, services: [] },
|
|
101
101
|
sourceFile: '/test/middleware.ts',
|
|
102
102
|
position: 100,
|
|
103
103
|
exportedName: 'secondMW',
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
const code = 'const x = {
|
|
106
|
+
const code = 'const x = { agentMiddleware: [firstMW, secondMW] }'
|
|
107
107
|
const program = ts.createProgram({
|
|
108
108
|
rootNames: ['test.ts'],
|
|
109
109
|
options: { target: ts.ScriptTarget.ESNext },
|
|
@@ -122,7 +122,7 @@ describe('resolveAIMiddleware', () => {
|
|
|
122
122
|
const sourceFile = program.getSourceFile('test.ts')!
|
|
123
123
|
const obj = getObjectLiteral(sourceFile)
|
|
124
124
|
|
|
125
|
-
const result =
|
|
125
|
+
const result = resolveAgentMiddleware(state, obj, checker)
|
|
126
126
|
|
|
127
127
|
assert.ok(result)
|
|
128
128
|
assert.strictEqual(result.length, 2)
|
|
@@ -132,16 +132,16 @@ describe('resolveAIMiddleware', () => {
|
|
|
132
132
|
assert.strictEqual((result[1] as any).name, 'secondMW')
|
|
133
133
|
})
|
|
134
134
|
|
|
135
|
-
test('should mark inline
|
|
135
|
+
test('should mark inline agentMiddleware (null exportedName)', () => {
|
|
136
136
|
const state = getInitialInspectorState('/test')
|
|
137
|
-
state.
|
|
137
|
+
state.agentMiddleware.definitions['inlineMW'] = {
|
|
138
138
|
services: { optimized: true, services: [] },
|
|
139
139
|
sourceFile: '/test/middleware.ts',
|
|
140
140
|
position: 0,
|
|
141
141
|
exportedName: null,
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
const code = 'const x = {
|
|
144
|
+
const code = 'const x = { agentMiddleware: [inlineMW] }'
|
|
145
145
|
const program = ts.createProgram({
|
|
146
146
|
rootNames: ['test.ts'],
|
|
147
147
|
options: { target: ts.ScriptTarget.ESNext },
|
|
@@ -160,7 +160,7 @@ describe('resolveAIMiddleware', () => {
|
|
|
160
160
|
const sourceFile = program.getSourceFile('test.ts')!
|
|
161
161
|
const obj = getObjectLiteral(sourceFile)
|
|
162
162
|
|
|
163
|
-
const result =
|
|
163
|
+
const result = resolveAgentMiddleware(state, obj, checker)
|
|
164
164
|
|
|
165
165
|
assert.ok(result)
|
|
166
166
|
assert.strictEqual(result.length, 1)
|
|
@@ -171,10 +171,10 @@ describe('resolveAIMiddleware', () => {
|
|
|
171
171
|
})
|
|
172
172
|
})
|
|
173
173
|
|
|
174
|
-
test('should handle
|
|
174
|
+
test('should handle agentMiddleware referencing unknown definitions', () => {
|
|
175
175
|
const state = getInitialInspectorState('/test')
|
|
176
176
|
|
|
177
|
-
const code = 'const x = {
|
|
177
|
+
const code = 'const x = { agentMiddleware: [unknownMW] }'
|
|
178
178
|
const program = ts.createProgram({
|
|
179
179
|
rootNames: ['test.ts'],
|
|
180
180
|
options: { target: ts.ScriptTarget.ESNext },
|
|
@@ -193,7 +193,7 @@ describe('resolveAIMiddleware', () => {
|
|
|
193
193
|
const sourceFile = program.getSourceFile('test.ts')!
|
|
194
194
|
const obj = getObjectLiteral(sourceFile)
|
|
195
195
|
|
|
196
|
-
const result =
|
|
196
|
+
const result = resolveAgentMiddleware(state, obj, checker)
|
|
197
197
|
|
|
198
198
|
assert.ok(result)
|
|
199
199
|
assert.strictEqual(result.length, 1)
|
package/src/utils/middleware.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
|
-
import type { MiddlewareMetadata } from '@pikku/core'
|
|
2
|
+
import type { MiddlewareMetadata } from '@pikku/core/ecosystem/types'
|
|
3
3
|
import { extractFunctionName } from './extract-function-name.js'
|
|
4
4
|
import type { InspectorState } from '../types.js'
|
|
5
5
|
|
|
@@ -214,24 +214,24 @@ export function resolveHTTPMiddlewareFromObject(
|
|
|
214
214
|
)
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
function
|
|
217
|
+
function getAgentMiddlewareNode(
|
|
218
218
|
obj: ts.ObjectLiteralExpression
|
|
219
219
|
): ts.Expression | undefined {
|
|
220
220
|
const prop = obj.properties.find(
|
|
221
221
|
(p) =>
|
|
222
222
|
ts.isPropertyAssignment(p) &&
|
|
223
223
|
ts.isIdentifier(p.name) &&
|
|
224
|
-
p.name.text === '
|
|
224
|
+
p.name.text === 'agentMiddleware'
|
|
225
225
|
) as ts.PropertyAssignment | undefined
|
|
226
226
|
return prop?.initializer
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
export function
|
|
229
|
+
export function resolveAgentMiddleware(
|
|
230
230
|
state: InspectorState,
|
|
231
231
|
obj: ts.ObjectLiteralExpression,
|
|
232
232
|
checker: ts.TypeChecker
|
|
233
233
|
): MiddlewareMetadata[] | undefined {
|
|
234
|
-
const explicitNode =
|
|
234
|
+
const explicitNode = getAgentMiddlewareNode(obj)
|
|
235
235
|
if (!explicitNode) return undefined
|
|
236
236
|
|
|
237
237
|
const names = extractMiddlewarePikkuNames(
|
|
@@ -240,7 +240,7 @@ export function resolveAIMiddleware(
|
|
|
240
240
|
state.rootDir
|
|
241
241
|
)
|
|
242
242
|
const resolved: MiddlewareMetadata[] = names.map((name) => {
|
|
243
|
-
const def = state.
|
|
243
|
+
const def = state.agentMiddleware.definitions[name]
|
|
244
244
|
return {
|
|
245
245
|
type: 'wire' as const,
|
|
246
246
|
name,
|
package/src/utils/permissions.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
|
-
import type { PermissionMetadata } from '@pikku/core'
|
|
2
|
+
import type { PermissionMetadata } from '@pikku/core/ecosystem/types'
|
|
3
3
|
import { extractFunctionName } from './extract-function-name.js'
|
|
4
4
|
import type { InspectorState } from '../types.js'
|
|
5
5
|
|
|
@@ -59,6 +59,33 @@ const makeOverrideState = (
|
|
|
59
59
|
},
|
|
60
60
|
}) as unknown as Omit<InspectorState, 'typesLookup'>
|
|
61
61
|
|
|
62
|
+
const makeGrantState = (
|
|
63
|
+
kind: 'secrets' | 'credentials',
|
|
64
|
+
declaredNames: string[],
|
|
65
|
+
decl: {
|
|
66
|
+
secretGrants?: string[]
|
|
67
|
+
credentialGrants?: string[]
|
|
68
|
+
secretOverrides?: Record<string, string>
|
|
69
|
+
credentialOverrides?: Record<string, string>
|
|
70
|
+
}
|
|
71
|
+
): Omit<InspectorState, 'typesLookup'> =>
|
|
72
|
+
({
|
|
73
|
+
rpc: {
|
|
74
|
+
wireAddonDeclarations: new Map([
|
|
75
|
+
['slack-marketing', { package: '@addon/slack', ...decl }],
|
|
76
|
+
]),
|
|
77
|
+
},
|
|
78
|
+
secrets: {
|
|
79
|
+
definitions:
|
|
80
|
+
kind === 'secrets' ? declaredNames.map((name) => ({ name })) : [],
|
|
81
|
+
},
|
|
82
|
+
credentials: {
|
|
83
|
+
definitions:
|
|
84
|
+
kind === 'credentials' ? declaredNames.map((name) => ({ name })) : [],
|
|
85
|
+
},
|
|
86
|
+
variables: { definitions: [] },
|
|
87
|
+
}) as unknown as Omit<InspectorState, 'typesLookup'>
|
|
88
|
+
|
|
62
89
|
function makeState(
|
|
63
90
|
overrides: {
|
|
64
91
|
usedFunctions?: string[]
|
|
@@ -115,7 +142,7 @@ function makeState(
|
|
|
115
142
|
|
|
116
143
|
const CONSOLE_PARENT_SERVICES = [
|
|
117
144
|
'metaService',
|
|
118
|
-
'
|
|
145
|
+
'agentRunner',
|
|
119
146
|
'deploymentService',
|
|
120
147
|
'credentialService',
|
|
121
148
|
]
|
|
@@ -160,7 +187,7 @@ describe('aggregateRequiredServices — per-function addon services', () => {
|
|
|
160
187
|
runAgent: {
|
|
161
188
|
services: {
|
|
162
189
|
optimized: true,
|
|
163
|
-
services: ['
|
|
190
|
+
services: ['agentRunner', 'deploymentService'],
|
|
164
191
|
},
|
|
165
192
|
},
|
|
166
193
|
},
|
|
@@ -170,7 +197,7 @@ describe('aggregateRequiredServices — per-function addon services', () => {
|
|
|
170
197
|
aggregateRequiredServices(state)
|
|
171
198
|
const required = state.serviceAggregation.requiredServices
|
|
172
199
|
assert.ok(required.has('metaService'))
|
|
173
|
-
assert.ok(!required.has('
|
|
200
|
+
assert.ok(!required.has('agentRunner'))
|
|
174
201
|
assert.ok(!required.has('deploymentService'))
|
|
175
202
|
assert.ok(!required.has('credentialService'))
|
|
176
203
|
})
|
|
@@ -231,7 +258,7 @@ describe('aggregateRequiredServices — per-function addon services', () => {
|
|
|
231
258
|
const required = state.serviceAggregation.requiredServices
|
|
232
259
|
assert.ok(required.has('kysely'))
|
|
233
260
|
assert.ok(!required.has('metaService'))
|
|
234
|
-
assert.ok(!required.has('
|
|
261
|
+
assert.ok(!required.has('agentRunner'))
|
|
235
262
|
})
|
|
236
263
|
|
|
237
264
|
test('no used addon functions adds no parent services', () => {
|
|
@@ -252,7 +279,7 @@ describe('aggregateRequiredServices — per-function addon services', () => {
|
|
|
252
279
|
aggregateRequiredServices(state)
|
|
253
280
|
const required = state.serviceAggregation.requiredServices
|
|
254
281
|
assert.ok(!required.has('metaService'))
|
|
255
|
-
assert.ok(!required.has('
|
|
282
|
+
assert.ok(!required.has('agentRunner'))
|
|
256
283
|
})
|
|
257
284
|
|
|
258
285
|
test('internal services in addon function meta never force the blanket', () => {
|
|
@@ -273,7 +300,7 @@ describe('aggregateRequiredServices — per-function addon services', () => {
|
|
|
273
300
|
aggregateRequiredServices(state)
|
|
274
301
|
const required = state.serviceAggregation.requiredServices
|
|
275
302
|
assert.ok(required.has('metaService'))
|
|
276
|
-
assert.ok(!required.has('
|
|
303
|
+
assert.ok(!required.has('agentRunner'))
|
|
277
304
|
assert.ok(!required.has('rpc'))
|
|
278
305
|
})
|
|
279
306
|
|
|
@@ -318,7 +345,7 @@ describe('aggregateRequiredServices — per-function addon services', () => {
|
|
|
318
345
|
aggregateRequiredServices(state)
|
|
319
346
|
const required = state.serviceAggregation.requiredServices
|
|
320
347
|
assert.ok(required.has('metaService'))
|
|
321
|
-
assert.ok(!required.has('
|
|
348
|
+
assert.ok(!required.has('agentRunner'))
|
|
322
349
|
})
|
|
323
350
|
|
|
324
351
|
test('multiple used addon functions union their parent services', () => {
|
|
@@ -330,7 +357,7 @@ describe('aggregateRequiredServices — per-function addon services', () => {
|
|
|
330
357
|
services: { optimized: true, services: ['metaService'] },
|
|
331
358
|
},
|
|
332
359
|
runAgent: {
|
|
333
|
-
services: { optimized: true, services: ['
|
|
360
|
+
services: { optimized: true, services: ['agentRunner'] },
|
|
334
361
|
},
|
|
335
362
|
},
|
|
336
363
|
},
|
|
@@ -339,7 +366,7 @@ describe('aggregateRequiredServices — per-function addon services', () => {
|
|
|
339
366
|
aggregateRequiredServices(state)
|
|
340
367
|
const required = state.serviceAggregation.requiredServices
|
|
341
368
|
assert.ok(required.has('metaService'))
|
|
342
|
-
assert.ok(required.has('
|
|
369
|
+
assert.ok(required.has('agentRunner'))
|
|
343
370
|
assert.ok(!required.has('deploymentService'))
|
|
344
371
|
assert.ok(!required.has('credentialService'))
|
|
345
372
|
})
|
|
@@ -414,6 +441,46 @@ describe('override validation resolves the override target (value), not the logi
|
|
|
414
441
|
validateVariableOverrides(logger, state)
|
|
415
442
|
assert.deepEqual(criticals, [])
|
|
416
443
|
})
|
|
444
|
+
|
|
445
|
+
test('validateSecretOverrides accepts a grant naming a declared secret', () => {
|
|
446
|
+
const { logger, criticals } = makeCriticalLogger()
|
|
447
|
+
const state = makeGrantState('secrets', ['STRIPE_KEY'], {
|
|
448
|
+
secretGrants: ['STRIPE_KEY'],
|
|
449
|
+
})
|
|
450
|
+
validateSecretOverrides(logger, state)
|
|
451
|
+
assert.deepEqual(criticals, [])
|
|
452
|
+
})
|
|
453
|
+
|
|
454
|
+
test('validateSecretOverrides flags a grant naming no declared secret', () => {
|
|
455
|
+
const { logger, criticals } = makeCriticalLogger()
|
|
456
|
+
const state = makeGrantState('secrets', ['STRIPE_KEY'], {
|
|
457
|
+
secretGrants: ['STIRPE_KEY'],
|
|
458
|
+
})
|
|
459
|
+
validateSecretOverrides(logger, state)
|
|
460
|
+
assert.equal(criticals.length, 1)
|
|
461
|
+
assert.match(criticals[0]!.message, /STIRPE_KEY/)
|
|
462
|
+
assert.match(criticals[0]!.message, /STRIPE_KEY/)
|
|
463
|
+
})
|
|
464
|
+
|
|
465
|
+
test('validateSecretOverrides resolves a grant through its override before looking it up', () => {
|
|
466
|
+
const { logger, criticals } = makeCriticalLogger()
|
|
467
|
+
const state = makeGrantState('secrets', ['PROD_EMAIL_KEY'], {
|
|
468
|
+
secretGrants: ['MAILGUN_KEY'],
|
|
469
|
+
secretOverrides: { MAILGUN_KEY: 'PROD_EMAIL_KEY' },
|
|
470
|
+
})
|
|
471
|
+
validateSecretOverrides(logger, state)
|
|
472
|
+
assert.deepEqual(criticals, [])
|
|
473
|
+
})
|
|
474
|
+
|
|
475
|
+
test('validateCredentialOverrides flags a grant naming no declared credential', () => {
|
|
476
|
+
const { logger, criticals } = makeCriticalLogger()
|
|
477
|
+
const state = makeGrantState('credentials', ['marketing_cred'], {
|
|
478
|
+
credentialGrants: ['ghost_cred'],
|
|
479
|
+
})
|
|
480
|
+
validateCredentialOverrides(logger, state)
|
|
481
|
+
assert.equal(criticals.length, 1)
|
|
482
|
+
assert.match(criticals[0]!.message, /ghost_cred/)
|
|
483
|
+
})
|
|
417
484
|
})
|
|
418
485
|
|
|
419
486
|
const makeRemoteState = (
|