@pikku/core 0.12.51 → 0.12.53
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 +74 -0
- package/dist/services/http-scenario-actors.d.ts +67 -0
- package/dist/services/http-scenario-actors.js +193 -0
- package/dist/services/http-user-flow-actors.d.ts +20 -0
- package/dist/services/http-user-flow-actors.js +100 -0
- package/dist/services/index.d.ts +5 -2
- package/dist/services/index.js +4 -1
- package/dist/services/istanbul-coverage-service.d.ts +12 -0
- package/dist/services/istanbul-coverage-service.js +41 -0
- package/dist/services/meta-service.d.ts +4 -4
- package/dist/services/meta-service.js +8 -8
- package/dist/services/scenario-actors-service.d.ts +21 -0
- package/dist/services/scenario-actors-service.js +1 -0
- package/dist/services/stub-tracker.d.ts +43 -0
- package/dist/services/stub-tracker.js +146 -0
- package/dist/services/user-flow-actors-service.d.ts +11 -1
- package/dist/services/v8-coverage-service.d.ts +41 -0
- package/dist/services/v8-coverage-service.js +63 -0
- package/dist/types/core.types.d.ts +13 -4
- package/dist/wirings/actor-flow/actor-flow.types.d.ts +68 -0
- package/dist/wirings/actor-flow/actor-flow.types.js +1 -0
- package/dist/wirings/actor-flow/index.d.ts +11 -0
- package/dist/wirings/actor-flow/index.js +1 -0
- package/dist/wirings/actor-flow/run-conversation.d.ts +36 -0
- package/dist/wirings/actor-flow/run-conversation.js +181 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +22 -6
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +4 -2
- package/dist/wirings/workflow/pikku-workflow-service.js +92 -2
- package/dist/wirings/workflow/workflow.types.d.ts +7 -7
- package/package.json +2 -1
- package/src/services/http-scenario-actors-converse.test.ts +222 -0
- package/src/services/{http-user-flow-actors.test.ts → http-scenario-actors.test.ts} +17 -7
- package/src/services/http-scenario-actors.ts +269 -0
- package/src/services/index.ts +27 -8
- package/src/services/istanbul-coverage-service.test.ts +66 -0
- package/src/services/istanbul-coverage-service.ts +65 -0
- package/src/services/meta-service.ts +9 -9
- package/src/services/scenario-actors-service.ts +27 -0
- package/src/services/stub-tracker.test.ts +104 -0
- package/src/services/stub-tracker.ts +185 -0
- package/src/services/v8-coverage-service.test.ts +69 -0
- package/src/services/v8-coverage-service.ts +121 -0
- package/src/types/core.types.ts +13 -4
- package/src/wirings/actor-flow/actor-flow.types.ts +73 -0
- package/src/wirings/actor-flow/index.ts +22 -0
- package/src/wirings/actor-flow/run-conversation.test.ts +176 -0
- package/src/wirings/actor-flow/run-conversation.ts +285 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +35 -6
- package/src/wirings/workflow/pikku-workflow-service.ts +144 -5
- package/src/wirings/workflow/{user-flow-step.test.ts → scenario-step.test.ts} +19 -14
- package/src/wirings/workflow/workflow.types.ts +8 -6
- package/tsconfig.tsbuildinfo +1 -1
- package/src/services/http-user-flow-actors.ts +0 -132
- package/src/services/user-flow-actors-service.ts +0 -31
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
UserFlowActor,
|
|
3
|
-
UserFlowActorConfig,
|
|
4
|
-
UserFlowActors,
|
|
5
|
-
} from './user-flow-actors-service.js'
|
|
6
|
-
|
|
7
|
-
export interface HttpUserFlowActorsConfig {
|
|
8
|
-
/**
|
|
9
|
-
* Base API URL of the target app, INCLUDING the HTTP prefix — e.g.
|
|
10
|
-
* `https://app.example.com/api` or `http://localhost:4000/api`. Actor
|
|
11
|
-
* sign-in is reached at `${apiUrl}${signInPath}` and exposed RPCs at
|
|
12
|
-
* `${apiUrl}${rpcPath}/:rpcName`.
|
|
13
|
-
*/
|
|
14
|
-
apiUrl: string
|
|
15
|
-
/**
|
|
16
|
-
* The actor impersonation secret. Sign-in only ever works for user rows
|
|
17
|
-
* flagged `actor: true` — knowing the secret never impersonates real users.
|
|
18
|
-
*/
|
|
19
|
-
secret: string
|
|
20
|
-
/** Actor name → config (usually from pikku.config.json's actor registry). */
|
|
21
|
-
actors: Record<string, UserFlowActorConfig>
|
|
22
|
-
/** Sign-in path under apiUrl. Default: the actor plugin's `/auth/sign-in/actor`. */
|
|
23
|
-
signInPath?: string
|
|
24
|
-
/** Exposed-RPC path prefix under apiUrl. Default `/rpc`. */
|
|
25
|
-
rpcPath?: string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Default HTTP-backed actor. Signs in lazily on first invoke via the Better
|
|
30
|
-
* Auth actor plugin (`POST /auth/sign-in/actor` with `{ email, secret }` —
|
|
31
|
-
* the plugin upserts the actor-flagged user row and mints a session whose
|
|
32
|
-
* `actor` flag flows into audits/analytics). Holds the session cookies for
|
|
33
|
-
* its lifetime; a 401 mid-run re-logs-in once (long health-check runs can
|
|
34
|
-
* outlive a session).
|
|
35
|
-
*/
|
|
36
|
-
export class HttpUserFlowActor implements UserFlowActor {
|
|
37
|
-
private cookie: string | null = null
|
|
38
|
-
private origin: string
|
|
39
|
-
|
|
40
|
-
constructor(
|
|
41
|
-
readonly name: string,
|
|
42
|
-
private actorConfig: UserFlowActorConfig,
|
|
43
|
-
private config: HttpUserFlowActorsConfig
|
|
44
|
-
) {
|
|
45
|
-
this.origin = new URL(config.apiUrl).origin
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
get email(): string {
|
|
49
|
-
return this.actorConfig.email
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async invoke(rpcName: string, data: unknown): Promise<unknown> {
|
|
53
|
-
const cookie = this.cookie ?? (await this.login())
|
|
54
|
-
const res = await this.postRpc(rpcName, data, cookie)
|
|
55
|
-
if (res.status === 401) {
|
|
56
|
-
// Session expired mid-run — re-login once and retry.
|
|
57
|
-
this.cookie = null
|
|
58
|
-
return this.readRpcResponse(rpcName, await this.postRpc(rpcName, data, await this.login()))
|
|
59
|
-
}
|
|
60
|
-
return this.readRpcResponse(rpcName, res)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private async postRpc(rpcName: string, data: unknown, cookie: string) {
|
|
64
|
-
const rpcPath = this.config.rpcPath ?? '/rpc'
|
|
65
|
-
return fetch(`${this.config.apiUrl}${rpcPath}/${rpcName}`, {
|
|
66
|
-
method: 'POST',
|
|
67
|
-
headers: {
|
|
68
|
-
'content-type': 'application/json',
|
|
69
|
-
origin: this.origin,
|
|
70
|
-
cookie,
|
|
71
|
-
},
|
|
72
|
-
body: JSON.stringify({ data }),
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
private async readRpcResponse(rpcName: string, res: Response) {
|
|
77
|
-
if (!res.ok) {
|
|
78
|
-
const body = (await res.text().catch(() => '')).slice(0, 300)
|
|
79
|
-
throw new Error(
|
|
80
|
-
`[user-flow] '${rpcName}' as '${this.name}' returned ${res.status}: ${body}`
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
if (res.status === 204) return undefined
|
|
84
|
-
const text = await res.text()
|
|
85
|
-
return text ? JSON.parse(text) : undefined
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private async login(): Promise<string> {
|
|
89
|
-
const signInPath = this.config.signInPath ?? '/auth/sign-in/actor'
|
|
90
|
-
const res = await fetch(`${this.config.apiUrl}${signInPath}`, {
|
|
91
|
-
method: 'POST',
|
|
92
|
-
headers: { 'content-type': 'application/json', origin: this.origin },
|
|
93
|
-
body: JSON.stringify({
|
|
94
|
-
email: this.actorConfig.email,
|
|
95
|
-
name: this.actorConfig.name ?? this.name,
|
|
96
|
-
secret: this.config.secret,
|
|
97
|
-
}),
|
|
98
|
-
})
|
|
99
|
-
if (!res.ok) {
|
|
100
|
-
const body = (await res.text().catch(() => '')).slice(0, 300)
|
|
101
|
-
throw new Error(
|
|
102
|
-
`[user-flow] actor sign-in failed for '${this.name}' (${res.status}): ${body}`
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
const setCookies = res.headers.getSetCookie?.() ?? []
|
|
106
|
-
const cookie = setCookies
|
|
107
|
-
.map((c) => c.split(';')[0]!)
|
|
108
|
-
.filter(Boolean)
|
|
109
|
-
.join('; ')
|
|
110
|
-
if (!cookie) {
|
|
111
|
-
throw new Error(
|
|
112
|
-
`[user-flow] actor sign-in for '${this.name}' returned no session cookie`
|
|
113
|
-
)
|
|
114
|
-
}
|
|
115
|
-
this.cookie = cookie
|
|
116
|
-
return cookie
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Build the injected `actors` service from the config registry: actor name →
|
|
122
|
-
* lazy HTTP actor. Wire the result as the `actors` singleton service.
|
|
123
|
-
*/
|
|
124
|
-
export function createHttpUserFlowActors(
|
|
125
|
-
config: HttpUserFlowActorsConfig
|
|
126
|
-
): UserFlowActors {
|
|
127
|
-
const actors: UserFlowActors = {}
|
|
128
|
-
for (const [name, actorConfig] of Object.entries(config.actors)) {
|
|
129
|
-
actors[name] = new HttpUserFlowActor(name, actorConfig, config)
|
|
130
|
-
}
|
|
131
|
-
return actors
|
|
132
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A user-flow actor: a synthetic user (a normal user row flagged `actor`) that
|
|
3
|
-
* workflow steps can run as. Passed to `workflow.do(step, rpc, data, { actor })`
|
|
4
|
-
* — the step then goes through the actor's authenticated client over the REAL
|
|
5
|
-
* transport (auth middleware, permissions, serialization all exercised),
|
|
6
|
-
* never through internal dispatch. Login is lazy: the first `invoke` signs the
|
|
7
|
-
* actor in and the session is cached for the actor's lifetime.
|
|
8
|
-
*/
|
|
9
|
-
export interface UserFlowActor {
|
|
10
|
-
/** Stable actor name (the key in pikku.config.json's actor registry). */
|
|
11
|
-
readonly name: string
|
|
12
|
-
/** The actor's user email — flows use it for invites/lookups. */
|
|
13
|
-
readonly email: string
|
|
14
|
-
/** Invoke an exposed RPC as this actor over the real transport. */
|
|
15
|
-
invoke(rpcName: string, data: unknown): Promise<unknown>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Display/config metadata for an actor (from pikku.config.json). The email
|
|
20
|
-
* identifies the actor's user row; personality/jobTitle exist for the console
|
|
21
|
-
* screen and for agent-driven flows (the agent plays the persona).
|
|
22
|
-
*/
|
|
23
|
-
export interface UserFlowActorConfig {
|
|
24
|
-
email: string
|
|
25
|
-
name?: string
|
|
26
|
-
jobTitle?: string
|
|
27
|
-
personality?: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** The injected `actors` service: actor name → actor. */
|
|
31
|
-
export type UserFlowActors = Record<string, UserFlowActor>
|