@w6w/sdk 0.2.1 → 0.4.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/README.md +1 -1
- package/dist/src/client.d.ts +33 -1
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +34 -1
- package/dist/src/client.js.map +1 -1
- package/dist/src/console/api-calls.d.ts +80 -0
- package/dist/src/console/api-calls.d.ts.map +1 -0
- package/dist/src/console/api-calls.js +69 -0
- package/dist/src/console/api-calls.js.map +1 -0
- package/dist/src/console/apps.d.ts +689 -0
- package/dist/src/console/apps.d.ts.map +1 -0
- package/dist/src/console/apps.js +402 -0
- package/dist/src/console/apps.js.map +1 -0
- package/dist/src/console/auth.d.ts +241 -0
- package/dist/src/console/auth.d.ts.map +1 -0
- package/dist/src/console/auth.js +173 -0
- package/dist/src/console/auth.js.map +1 -0
- package/dist/src/console/connections.d.ts +188 -0
- package/dist/src/console/connections.d.ts.map +1 -0
- package/dist/src/console/connections.js +182 -0
- package/dist/src/console/connections.js.map +1 -0
- package/dist/src/console/dashboard.d.ts +102 -0
- package/dist/src/console/dashboard.d.ts.map +1 -0
- package/dist/src/console/dashboard.js +59 -0
- package/dist/src/console/dashboard.js.map +1 -0
- package/dist/src/console/endpoints.d.ts +264 -0
- package/dist/src/console/endpoints.d.ts.map +1 -0
- package/dist/src/console/endpoints.js +164 -0
- package/dist/src/console/endpoints.js.map +1 -0
- package/dist/src/console/functions.d.ts +165 -0
- package/dist/src/console/functions.d.ts.map +1 -0
- package/dist/src/console/functions.js +117 -0
- package/dist/src/console/functions.js.map +1 -0
- package/dist/src/console/mod.d.ts +131 -0
- package/dist/src/console/mod.d.ts.map +1 -0
- package/dist/src/console/mod.js +121 -0
- package/dist/src/console/mod.js.map +1 -0
- package/dist/src/console/projects.d.ts +107 -0
- package/dist/src/console/projects.d.ts.map +1 -0
- package/dist/src/console/projects.js +97 -0
- package/dist/src/console/projects.js.map +1 -0
- package/dist/src/console/reliability.d.ts +149 -0
- package/dist/src/console/reliability.d.ts.map +1 -0
- package/dist/src/console/reliability.js +56 -0
- package/dist/src/console/reliability.js.map +1 -0
- package/dist/src/console/saved-tests.d.ts +198 -0
- package/dist/src/console/saved-tests.d.ts.map +1 -0
- package/dist/src/console/saved-tests.js +172 -0
- package/dist/src/console/saved-tests.js.map +1 -0
- package/dist/src/console/schedules.d.ts +127 -0
- package/dist/src/console/schedules.d.ts.map +1 -0
- package/dist/src/console/schedules.js +118 -0
- package/dist/src/console/schedules.js.map +1 -0
- package/dist/src/console/step-tests.d.ts +159 -0
- package/dist/src/console/step-tests.d.ts.map +1 -0
- package/dist/src/console/step-tests.js +129 -0
- package/dist/src/console/step-tests.js.map +1 -0
- package/dist/src/console/subscriptions.d.ts +199 -0
- package/dist/src/console/subscriptions.d.ts.map +1 -0
- package/dist/src/console/subscriptions.js +191 -0
- package/dist/src/console/subscriptions.js.map +1 -0
- package/dist/src/console/tenant-oauth-apps.d.ts +188 -0
- package/dist/src/console/tenant-oauth-apps.d.ts.map +1 -0
- package/dist/src/console/tenant-oauth-apps.js +152 -0
- package/dist/src/console/tenant-oauth-apps.js.map +1 -0
- package/dist/src/console/tokens.d.ts +159 -0
- package/dist/src/console/tokens.d.ts.map +1 -0
- package/dist/src/console/tokens.js +145 -0
- package/dist/src/console/tokens.js.map +1 -0
- package/dist/src/console/vault.d.ts +188 -0
- package/dist/src/console/vault.d.ts.map +1 -0
- package/dist/src/console/vault.js +164 -0
- package/dist/src/console/vault.js.map +1 -0
- package/dist/src/console/workflows.d.ts +243 -0
- package/dist/src/console/workflows.d.ts.map +1 -0
- package/dist/src/console/workflows.js +205 -0
- package/dist/src/console/workflows.js.map +1 -0
- package/dist/src/http.d.ts +32 -2
- package/dist/src/http.d.ts.map +1 -1
- package/dist/src/http.js +11 -2
- package/dist/src/http.js.map +1 -1
- package/dist/src/types.d.ts +2 -2
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/workflows.d.ts +11 -4
- package/dist/src/workflows.d.ts.map +1 -1
- package/dist/src/workflows.js +3 -3
- package/dist/src/workflows.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.console.schedules.*` — per-workflow schedules, relocated from the
|
|
3
|
+
* studio's own API client.
|
|
4
|
+
*
|
|
5
|
+
* **Studio-internal, not the published partner contract.** This namespace
|
|
6
|
+
* lives under the `console` subpath export (`@w6w/sdk/console`), excluded from
|
|
7
|
+
* `endpoints.json` and from the root barrel (`mod.ts`) — see `docs/console.md`
|
|
8
|
+
* and HITL-1 in this task's contract. `@w6w/sdk`'s instance-state mechanism
|
|
9
|
+
* pin still applies here exactly as it does to every other namespace
|
|
10
|
+
* (`docs/implementation.md` §MECHANISM PIN — instance state, never globals):
|
|
11
|
+
* this class holds no state of its own beyond the injected host, so two
|
|
12
|
+
* clients in one process never share a credential.
|
|
13
|
+
*
|
|
14
|
+
* **`GET /schedules` (list) is deliberately not modeled here.** Studio's
|
|
15
|
+
* `api/client.ts` never wrapped it (zero client-side coverage) — see this
|
|
16
|
+
* task's contract Requirement and `plan.md`'s FINDINGS DISPOSITION for the
|
|
17
|
+
* full reasoning.
|
|
18
|
+
*
|
|
19
|
+
* Schedules are addressed by `workflowId` alone, never by a project or account
|
|
20
|
+
* scope, so `SchedulesHost` needs only the transport, no client configuration —
|
|
21
|
+
* mirrors `VarsHost` in `../vars.ts`, not `DocumentsHost`.
|
|
22
|
+
*
|
|
23
|
+
* **`get`'s 404→`null` behavior is a deliberate, pinned deviation from every
|
|
24
|
+
* other "get" method in this package** (`documents.get`, `vars.get`, … all
|
|
25
|
+
* throw `ApiError` on 404). It is relocated verbatim from
|
|
26
|
+
* `packages/studio/src/api/client.ts:535-542`, which catches ANY 404
|
|
27
|
+
* (regardless of the server's error `code`) and resolves `null` instead of
|
|
28
|
+
* throwing. The server sends two different codes for "no schedule to show" —
|
|
29
|
+
* `unknown_workflow` and `no_schedule` (`admin/schedules.ts:82,85`) — and this
|
|
30
|
+
* method does not discriminate between them, only the HTTP status: any other
|
|
31
|
+
* status (400, 500, …) still throws, unchanged.
|
|
32
|
+
*
|
|
33
|
+
* @module
|
|
34
|
+
*/
|
|
35
|
+
import { type HttpResponse, type RequestOptions } from "../http.ts";
|
|
36
|
+
/**
|
|
37
|
+
* The slice of `W6wClient` this namespace needs: the transport, and nothing
|
|
38
|
+
* else. Structural rather than a concrete client type, so the namespace stays
|
|
39
|
+
* independently constructible in a test and this module never imports the
|
|
40
|
+
* client back — mirrors `VarsHost` in `../vars.ts`.
|
|
41
|
+
*/
|
|
42
|
+
export interface SchedulesHost {
|
|
43
|
+
/** Perform one request. */
|
|
44
|
+
request<T>(options: RequestOptions): Promise<HttpResponse<T>>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A workflow's schedule. Field-for-field per
|
|
48
|
+
* `packages/studio/src/api/types.ts:368-375` — this module does not redesign
|
|
49
|
+
* the shape, only gives it a second home.
|
|
50
|
+
*/
|
|
51
|
+
export interface Schedule {
|
|
52
|
+
workflowId: string;
|
|
53
|
+
cron: string;
|
|
54
|
+
enabled: boolean;
|
|
55
|
+
variables: Record<string, unknown>;
|
|
56
|
+
nextRunAt: string;
|
|
57
|
+
lastRunAt: string | null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The body of `schedules.upsert`.
|
|
61
|
+
*
|
|
62
|
+
* Create-or-update — there is no distinct "create" and "update" on this
|
|
63
|
+
* domain, mirroring `POST /workflows/:id/schedule`'s own create-or-update
|
|
64
|
+
* semantics (`admin/schedules.ts:32-77`, `200` either way, no distinct `201`).
|
|
65
|
+
*/
|
|
66
|
+
export interface ScheduleUpsertInput {
|
|
67
|
+
/** A standard 5-field cron expression. `400 invalid_cron` if malformed. */
|
|
68
|
+
cron: string;
|
|
69
|
+
/** Omitted, the server applies its own default. */
|
|
70
|
+
enabled?: boolean;
|
|
71
|
+
/** Variables bound into the scheduled run. Omitted, the server applies its own default. */
|
|
72
|
+
variables?: Record<string, unknown>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The `console.schedules` namespace on a `W6wClient`.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* const schedule = await client.console.schedules.get("wf_1");
|
|
80
|
+
* if (schedule === null) {
|
|
81
|
+
* await client.console.schedules.upsert("wf_1", { cron: "0 * * * *" });
|
|
82
|
+
* }
|
|
83
|
+
* await client.console.schedules.delete("wf_1");
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare class SchedulesApi {
|
|
87
|
+
#private;
|
|
88
|
+
/**
|
|
89
|
+
* @param host - The client this namespace issues requests through.
|
|
90
|
+
*/
|
|
91
|
+
constructor(host: SchedulesHost);
|
|
92
|
+
/**
|
|
93
|
+
* Fetch a workflow's schedule.
|
|
94
|
+
*
|
|
95
|
+
* **Resolves `null` on a 404, of any code — it does not throw.** This is a
|
|
96
|
+
* deliberate deviation from every other "get" method in this package, pinned
|
|
97
|
+
* exactly from `client.ts:535-542`: see this module's header. Any other
|
|
98
|
+
* error status (400, 500, …) still throws.
|
|
99
|
+
*
|
|
100
|
+
* @param workflowId - The `wf_…` id.
|
|
101
|
+
* @returns The schedule, or `null` when there is none to show.
|
|
102
|
+
* @throws {ApiError} On any non-404 non-2xx.
|
|
103
|
+
*/
|
|
104
|
+
get(workflowId: string): Promise<Schedule | null>;
|
|
105
|
+
/**
|
|
106
|
+
* Create or overwrite a workflow's schedule.
|
|
107
|
+
*
|
|
108
|
+
* @param workflowId - The `wf_…` id.
|
|
109
|
+
* @param body - The schedule to set; forwarded as-is.
|
|
110
|
+
* @returns The resulting schedule (the server answers `200`, create-or-update alike).
|
|
111
|
+
* @throws {ApiError} `404 unknown_workflow`; `400 invalid_body`/`invalid_cron`.
|
|
112
|
+
*/
|
|
113
|
+
upsert(workflowId: string, body: ScheduleUpsertInput): Promise<Schedule>;
|
|
114
|
+
/**
|
|
115
|
+
* Delete a workflow's schedule.
|
|
116
|
+
*
|
|
117
|
+
* Returns nothing: the server's `{ok: true}` carries no information a caller
|
|
118
|
+
* can use. Unlike `get`, this method does NOT catch a 404 — deleting a
|
|
119
|
+
* schedule that does not exist is `404 unknown_workflow`, not a silent
|
|
120
|
+
* success.
|
|
121
|
+
*
|
|
122
|
+
* @param workflowId - The `wf_…` id.
|
|
123
|
+
* @throws {ApiError} `404 unknown_workflow` when there is no such workflow.
|
|
124
|
+
*/
|
|
125
|
+
delete(workflowId: string): Promise<void>;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=schedules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedules.d.ts","sourceRoot":"","sources":["../../../src/console/schedules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAQ,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAI1E;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,YAAY;;IAGvB;;OAEG;gBACS,IAAI,EAAE,aAAa;IAI/B;;;;;;;;;;;OAWG;IACG,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAavD;;;;;;;OAOG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAS9E;;;;;;;;;;OAUG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMhD"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.console.schedules.*` — per-workflow schedules, relocated from the
|
|
3
|
+
* studio's own API client.
|
|
4
|
+
*
|
|
5
|
+
* **Studio-internal, not the published partner contract.** This namespace
|
|
6
|
+
* lives under the `console` subpath export (`@w6w/sdk/console`), excluded from
|
|
7
|
+
* `endpoints.json` and from the root barrel (`mod.ts`) — see `docs/console.md`
|
|
8
|
+
* and HITL-1 in this task's contract. `@w6w/sdk`'s instance-state mechanism
|
|
9
|
+
* pin still applies here exactly as it does to every other namespace
|
|
10
|
+
* (`docs/implementation.md` §MECHANISM PIN — instance state, never globals):
|
|
11
|
+
* this class holds no state of its own beyond the injected host, so two
|
|
12
|
+
* clients in one process never share a credential.
|
|
13
|
+
*
|
|
14
|
+
* **`GET /schedules` (list) is deliberately not modeled here.** Studio's
|
|
15
|
+
* `api/client.ts` never wrapped it (zero client-side coverage) — see this
|
|
16
|
+
* task's contract Requirement and `plan.md`'s FINDINGS DISPOSITION for the
|
|
17
|
+
* full reasoning.
|
|
18
|
+
*
|
|
19
|
+
* Schedules are addressed by `workflowId` alone, never by a project or account
|
|
20
|
+
* scope, so `SchedulesHost` needs only the transport, no client configuration —
|
|
21
|
+
* mirrors `VarsHost` in `../vars.ts`, not `DocumentsHost`.
|
|
22
|
+
*
|
|
23
|
+
* **`get`'s 404→`null` behavior is a deliberate, pinned deviation from every
|
|
24
|
+
* other "get" method in this package** (`documents.get`, `vars.get`, … all
|
|
25
|
+
* throw `ApiError` on 404). It is relocated verbatim from
|
|
26
|
+
* `packages/studio/src/api/client.ts:535-542`, which catches ANY 404
|
|
27
|
+
* (regardless of the server's error `code`) and resolves `null` instead of
|
|
28
|
+
* throwing. The server sends two different codes for "no schedule to show" —
|
|
29
|
+
* `unknown_workflow` and `no_schedule` (`admin/schedules.ts:82,85`) — and this
|
|
30
|
+
* method does not discriminate between them, only the HTTP status: any other
|
|
31
|
+
* status (400, 500, …) still throws, unchanged.
|
|
32
|
+
*
|
|
33
|
+
* @module
|
|
34
|
+
*/
|
|
35
|
+
import { path } from "../http.js";
|
|
36
|
+
import { ApiError } from "../errors.js";
|
|
37
|
+
import { unwrap } from "../types.js";
|
|
38
|
+
/**
|
|
39
|
+
* The `console.schedules` namespace on a `W6wClient`.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const schedule = await client.console.schedules.get("wf_1");
|
|
44
|
+
* if (schedule === null) {
|
|
45
|
+
* await client.console.schedules.upsert("wf_1", { cron: "0 * * * *" });
|
|
46
|
+
* }
|
|
47
|
+
* await client.console.schedules.delete("wf_1");
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export class SchedulesApi {
|
|
51
|
+
#host;
|
|
52
|
+
/**
|
|
53
|
+
* @param host - The client this namespace issues requests through.
|
|
54
|
+
*/
|
|
55
|
+
constructor(host) {
|
|
56
|
+
this.#host = host;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Fetch a workflow's schedule.
|
|
60
|
+
*
|
|
61
|
+
* **Resolves `null` on a 404, of any code — it does not throw.** This is a
|
|
62
|
+
* deliberate deviation from every other "get" method in this package, pinned
|
|
63
|
+
* exactly from `client.ts:535-542`: see this module's header. Any other
|
|
64
|
+
* error status (400, 500, …) still throws.
|
|
65
|
+
*
|
|
66
|
+
* @param workflowId - The `wf_…` id.
|
|
67
|
+
* @returns The schedule, or `null` when there is none to show.
|
|
68
|
+
* @throws {ApiError} On any non-404 non-2xx.
|
|
69
|
+
*/
|
|
70
|
+
async get(workflowId) {
|
|
71
|
+
try {
|
|
72
|
+
const res = await this.#host.request({
|
|
73
|
+
method: "GET",
|
|
74
|
+
path: path `/workflows/${workflowId}/schedule`,
|
|
75
|
+
});
|
|
76
|
+
return unwrap(res, "schedule");
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
if (err instanceof ApiError && err.status === 404)
|
|
80
|
+
return null;
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create or overwrite a workflow's schedule.
|
|
86
|
+
*
|
|
87
|
+
* @param workflowId - The `wf_…` id.
|
|
88
|
+
* @param body - The schedule to set; forwarded as-is.
|
|
89
|
+
* @returns The resulting schedule (the server answers `200`, create-or-update alike).
|
|
90
|
+
* @throws {ApiError} `404 unknown_workflow`; `400 invalid_body`/`invalid_cron`.
|
|
91
|
+
*/
|
|
92
|
+
async upsert(workflowId, body) {
|
|
93
|
+
const res = await this.#host.request({
|
|
94
|
+
method: "POST",
|
|
95
|
+
path: path `/workflows/${workflowId}/schedule`,
|
|
96
|
+
body,
|
|
97
|
+
});
|
|
98
|
+
return unwrap(res, "schedule");
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Delete a workflow's schedule.
|
|
102
|
+
*
|
|
103
|
+
* Returns nothing: the server's `{ok: true}` carries no information a caller
|
|
104
|
+
* can use. Unlike `get`, this method does NOT catch a 404 — deleting a
|
|
105
|
+
* schedule that does not exist is `404 unknown_workflow`, not a silent
|
|
106
|
+
* success.
|
|
107
|
+
*
|
|
108
|
+
* @param workflowId - The `wf_…` id.
|
|
109
|
+
* @throws {ApiError} `404 unknown_workflow` when there is no such workflow.
|
|
110
|
+
*/
|
|
111
|
+
async delete(workflowId) {
|
|
112
|
+
await this.#host.request({
|
|
113
|
+
method: "DELETE",
|
|
114
|
+
path: path `/workflows/${workflowId}/schedule`,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=schedules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedules.js","sourceRoot":"","sources":["../../../src/console/schedules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAqB,IAAI,EAAuB,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA2CrC;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,YAAY;IACd,KAAK,CAAgB;IAE9B;;OAEG;IACH,YAAY,IAAmB;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,GAAG,CAAC,UAAkB;QAC1B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;gBAC5C,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,IAAI,CAAA,cAAc,UAAU,WAAW;aAC9C,CAAC,CAAC;YACH,OAAO,MAAM,CAAW,GAAG,EAAE,UAAU,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC;YAC/D,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,MAAM,CAAC,UAAkB,EAAE,IAAyB;QACxD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAA,cAAc,UAAU,WAAW;YAC7C,IAAI;SACL,CAAC,CAAC;QACH,OAAO,MAAM,CAAW,GAAG,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,MAAM,CAAC,UAAkB;QAC7B,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAChC,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,IAAI,CAAA,cAAc,UAAU,WAAW;SAC9C,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.console.stepTests.*` — reusable, workflow-step-scoped test
|
|
3
|
+
* fixtures for a step's resolved incoming state (`input`) and its params
|
|
4
|
+
* (`with`), plus their run-log, relocated from the studio's own API client.
|
|
5
|
+
*
|
|
6
|
+
* **Studio-internal, not the published partner contract.** This namespace
|
|
7
|
+
* lives under the `console` subpath export (`@w6w/sdk/console`), excluded from
|
|
8
|
+
* `endpoints.json` and from the root barrel (`mod.ts`) — see `docs/console.md`
|
|
9
|
+
* and HITL-1 in this task's contract. `@w6w/sdk`'s instance-state mechanism
|
|
10
|
+
* pin still applies here exactly as it does to every other namespace
|
|
11
|
+
* (`docs/implementation.md` §MECHANISM PIN — instance state, never globals):
|
|
12
|
+
* this class holds no state of its own beyond the injected host, so two
|
|
13
|
+
* clients in one process never share a credential.
|
|
14
|
+
*
|
|
15
|
+
* Three methods relocate from the studio's own `// Saved per-step tests`
|
|
16
|
+
* comment block (`packages/studio/src/api/client.ts:317-351` on the studio
|
|
17
|
+
* base tree) — field-for-field, not redesigned. Method names here are
|
|
18
|
+
* SHORTENED versus `client.ts`'s flat names (`saveStepTest` → `save`,
|
|
19
|
+
* `listStepTests` → `list`, `recordStepTestRun` → `recordRun`), mirroring
|
|
20
|
+
* `console.connections.listForApp`/`console.workflows.get`'s own convention:
|
|
21
|
+
* the domain prefix (`console.stepTests.*`) already disambiguates.
|
|
22
|
+
*
|
|
23
|
+
* **`PATCH`/`DELETE /workflows/:workflowId/steps/:stepId/tests/:id` also
|
|
24
|
+
* exist server-side but have ZERO client-side coverage anywhere (studio or
|
|
25
|
+
* `@w6w/ui`) — deliberately NOT wrapped here.** Same disposition prior
|
|
26
|
+
* console domains already established for their own orphan routes
|
|
27
|
+
* (HITL-4's philosophy applied one step further).
|
|
28
|
+
*
|
|
29
|
+
* **`recordRun` returns the REAL created row, not `void`.** Studio's current
|
|
30
|
+
* `client.ts` discards it to `void` (`.then(() => {})`) only so its `api`
|
|
31
|
+
* object stays assignable to `@w6w/ui`'s `W6wApi.recordStepTestRun` (typed
|
|
32
|
+
* `Promise<void>`, `packages/ui/src/provider.tsx:211-221`) — that is
|
|
33
|
+
* STUDIO's constraint, not the SDK's. Mirrors `./saved-tests.ts`'s
|
|
34
|
+
* `recordTestRun` exactly; the void-discard happens at studio's own repo
|
|
35
|
+
* layer (`src/repos/step-tests.ts`, a later task), not here.
|
|
36
|
+
*
|
|
37
|
+
* None of these methods take a `project` scoping parameter — step tests
|
|
38
|
+
* carry no `?project=`, the server scopes by workflow/tenant — so
|
|
39
|
+
* `StepTestsHost` needs only the transport, mirroring `ConnectionsHost`, not
|
|
40
|
+
* `DocumentsHost`.
|
|
41
|
+
*
|
|
42
|
+
* @module
|
|
43
|
+
*/
|
|
44
|
+
import { type HttpResponse, type RequestOptions } from "../http.ts";
|
|
45
|
+
/**
|
|
46
|
+
* The slice of `W6wClient` this namespace needs: the transport, and nothing
|
|
47
|
+
* else. Structural rather than a concrete client type, so the namespace stays
|
|
48
|
+
* independently constructible in a test and this module never imports the
|
|
49
|
+
* client back — mirrors `ConnectionsHost` in `./connections.ts`.
|
|
50
|
+
*/
|
|
51
|
+
export interface StepTestsHost {
|
|
52
|
+
/** Perform one request. */
|
|
53
|
+
request<T>(options: RequestOptions): Promise<HttpResponse<T>>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A saved per-step test fixture — a reusable, project-owned named capture of
|
|
57
|
+
* a workflow step's resolved incoming state (`input`) and its params
|
|
58
|
+
* (`with`), keyed by `(workflowId, stepId)`. Mirrors the connection-scoped
|
|
59
|
+
* `SavedTest`, re-keyed to a workflow step. `lastRun*` denormalizes the most
|
|
60
|
+
* recent run.
|
|
61
|
+
*/
|
|
62
|
+
export interface StepTest {
|
|
63
|
+
id: string;
|
|
64
|
+
workflowId: string;
|
|
65
|
+
stepId: string;
|
|
66
|
+
name: string | null;
|
|
67
|
+
input: Record<string, unknown>;
|
|
68
|
+
with: Record<string, unknown>;
|
|
69
|
+
createdAt: string;
|
|
70
|
+
updatedAt: string;
|
|
71
|
+
lastRunAt?: string | null;
|
|
72
|
+
lastRunStatus?: string | null;
|
|
73
|
+
lastRunError?: unknown;
|
|
74
|
+
lastRunOutput?: unknown;
|
|
75
|
+
}
|
|
76
|
+
/** The real row `recordRun` creates (mirrors the server's `StepTestRun`). */
|
|
77
|
+
export interface StepTestRun {
|
|
78
|
+
id: string;
|
|
79
|
+
stepTestId: string | null;
|
|
80
|
+
workflowId: string;
|
|
81
|
+
stepId: string;
|
|
82
|
+
status: string;
|
|
83
|
+
input: unknown;
|
|
84
|
+
output: unknown;
|
|
85
|
+
error: unknown;
|
|
86
|
+
createdAt: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The `console.stepTests` namespace on a `W6wClient`.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* const fixture = await client.console.stepTests.save("wf_1", "nd_1", {
|
|
94
|
+
* input: { foo: "bar" },
|
|
95
|
+
* with: { to: "a@b.com" },
|
|
96
|
+
* });
|
|
97
|
+
* const fixtures = await client.console.stepTests.list("wf_1", "nd_1");
|
|
98
|
+
* const run = await client.console.stepTests.recordRun("wf_1", "nd_1", {
|
|
99
|
+
* stepTestId: fixture.id,
|
|
100
|
+
* status: "succeeded",
|
|
101
|
+
* output: { ok: true },
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare class StepTestsApi {
|
|
106
|
+
#private;
|
|
107
|
+
/**
|
|
108
|
+
* @param host - The client this namespace issues requests through.
|
|
109
|
+
*/
|
|
110
|
+
constructor(host: StepTestsHost);
|
|
111
|
+
/**
|
|
112
|
+
* Save a step-test fixture.
|
|
113
|
+
*
|
|
114
|
+
* @param workflowId - The `wf_…` id.
|
|
115
|
+
* @param stepId - The step's id within that workflow.
|
|
116
|
+
* @param body - Optional `name`, plus `input`/`with`, forwarded verbatim.
|
|
117
|
+
* @returns The created step test, unwrapped from the `stepTest` envelope (the server answers `201`).
|
|
118
|
+
* @throws {ApiError} `400 invalid_name`/`invalid_input`/`invalid_with`;
|
|
119
|
+
* `404 unknown_workflow`.
|
|
120
|
+
*/
|
|
121
|
+
save(workflowId: string, stepId: string, body: {
|
|
122
|
+
name?: string;
|
|
123
|
+
input: Record<string, unknown>;
|
|
124
|
+
with: Record<string, unknown>;
|
|
125
|
+
}): Promise<StepTest>;
|
|
126
|
+
/**
|
|
127
|
+
* List a step's saved test fixtures.
|
|
128
|
+
*
|
|
129
|
+
* @param workflowId - The `wf_…` id.
|
|
130
|
+
* @param stepId - The step's id within that workflow.
|
|
131
|
+
* @returns The step tests, unwrapped from the `stepTests` envelope.
|
|
132
|
+
*/
|
|
133
|
+
list(workflowId: string, stepId: string): Promise<StepTest[]>;
|
|
134
|
+
/**
|
|
135
|
+
* Record the outcome of a step-test run. Appends a `step_test_runs` row
|
|
136
|
+
* (and a best-effort `run_log` ledger row) server-side; when `stepTestId`
|
|
137
|
+
* is present, the fixture's `lastRun*` fields are updated too.
|
|
138
|
+
*
|
|
139
|
+
* Returns the REAL created row — see this module's header. Does NOT
|
|
140
|
+
* discard to `void`; a caller wanting the studio-facade `void` shape
|
|
141
|
+
* adapts it themselves.
|
|
142
|
+
*
|
|
143
|
+
* @param workflowId - The `wf_…` id.
|
|
144
|
+
* @param stepId - The step's id within that workflow.
|
|
145
|
+
* @param body - `stepTestId` (optional), `status`, and optional
|
|
146
|
+
* `input`/`output`/`error`, forwarded verbatim.
|
|
147
|
+
* @returns The created `StepTestRun`, unwrapped from the `run` envelope (the server answers `201`).
|
|
148
|
+
* @throws {ApiError} `400 invalid_body`/`invalid_status`. No `404` — the
|
|
149
|
+
* route never checks the workflow/step exist before writing.
|
|
150
|
+
*/
|
|
151
|
+
recordRun(workflowId: string, stepId: string, body: {
|
|
152
|
+
stepTestId?: string | null;
|
|
153
|
+
status: string;
|
|
154
|
+
input?: unknown;
|
|
155
|
+
output?: unknown;
|
|
156
|
+
error?: unknown;
|
|
157
|
+
}): Promise<StepTestRun>;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=step-tests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-tests.d.ts","sourceRoot":"","sources":["../../../src/console/step-tests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAQ,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAG1E;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAY;;IAGvB;;OAEG;gBACS,IAAI,EAAE,aAAa;IAI/B;;;;;;;;;OASG;IACG,IAAI,CACR,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GACrF,OAAO,CAAC,QAAQ,CAAC;IASpB;;;;;;OAMG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAQnE;;;;;;;;;;;;;;;;OAgBG;IACG,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;QACJ,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,GACA,OAAO,CAAC,WAAW,CAAC;CAQxB"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.console.stepTests.*` — reusable, workflow-step-scoped test
|
|
3
|
+
* fixtures for a step's resolved incoming state (`input`) and its params
|
|
4
|
+
* (`with`), plus their run-log, relocated from the studio's own API client.
|
|
5
|
+
*
|
|
6
|
+
* **Studio-internal, not the published partner contract.** This namespace
|
|
7
|
+
* lives under the `console` subpath export (`@w6w/sdk/console`), excluded from
|
|
8
|
+
* `endpoints.json` and from the root barrel (`mod.ts`) — see `docs/console.md`
|
|
9
|
+
* and HITL-1 in this task's contract. `@w6w/sdk`'s instance-state mechanism
|
|
10
|
+
* pin still applies here exactly as it does to every other namespace
|
|
11
|
+
* (`docs/implementation.md` §MECHANISM PIN — instance state, never globals):
|
|
12
|
+
* this class holds no state of its own beyond the injected host, so two
|
|
13
|
+
* clients in one process never share a credential.
|
|
14
|
+
*
|
|
15
|
+
* Three methods relocate from the studio's own `// Saved per-step tests`
|
|
16
|
+
* comment block (`packages/studio/src/api/client.ts:317-351` on the studio
|
|
17
|
+
* base tree) — field-for-field, not redesigned. Method names here are
|
|
18
|
+
* SHORTENED versus `client.ts`'s flat names (`saveStepTest` → `save`,
|
|
19
|
+
* `listStepTests` → `list`, `recordStepTestRun` → `recordRun`), mirroring
|
|
20
|
+
* `console.connections.listForApp`/`console.workflows.get`'s own convention:
|
|
21
|
+
* the domain prefix (`console.stepTests.*`) already disambiguates.
|
|
22
|
+
*
|
|
23
|
+
* **`PATCH`/`DELETE /workflows/:workflowId/steps/:stepId/tests/:id` also
|
|
24
|
+
* exist server-side but have ZERO client-side coverage anywhere (studio or
|
|
25
|
+
* `@w6w/ui`) — deliberately NOT wrapped here.** Same disposition prior
|
|
26
|
+
* console domains already established for their own orphan routes
|
|
27
|
+
* (HITL-4's philosophy applied one step further).
|
|
28
|
+
*
|
|
29
|
+
* **`recordRun` returns the REAL created row, not `void`.** Studio's current
|
|
30
|
+
* `client.ts` discards it to `void` (`.then(() => {})`) only so its `api`
|
|
31
|
+
* object stays assignable to `@w6w/ui`'s `W6wApi.recordStepTestRun` (typed
|
|
32
|
+
* `Promise<void>`, `packages/ui/src/provider.tsx:211-221`) — that is
|
|
33
|
+
* STUDIO's constraint, not the SDK's. Mirrors `./saved-tests.ts`'s
|
|
34
|
+
* `recordTestRun` exactly; the void-discard happens at studio's own repo
|
|
35
|
+
* layer (`src/repos/step-tests.ts`, a later task), not here.
|
|
36
|
+
*
|
|
37
|
+
* None of these methods take a `project` scoping parameter — step tests
|
|
38
|
+
* carry no `?project=`, the server scopes by workflow/tenant — so
|
|
39
|
+
* `StepTestsHost` needs only the transport, mirroring `ConnectionsHost`, not
|
|
40
|
+
* `DocumentsHost`.
|
|
41
|
+
*
|
|
42
|
+
* @module
|
|
43
|
+
*/
|
|
44
|
+
import { path } from "../http.js";
|
|
45
|
+
import { unwrap } from "../types.js";
|
|
46
|
+
/**
|
|
47
|
+
* The `console.stepTests` namespace on a `W6wClient`.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const fixture = await client.console.stepTests.save("wf_1", "nd_1", {
|
|
52
|
+
* input: { foo: "bar" },
|
|
53
|
+
* with: { to: "a@b.com" },
|
|
54
|
+
* });
|
|
55
|
+
* const fixtures = await client.console.stepTests.list("wf_1", "nd_1");
|
|
56
|
+
* const run = await client.console.stepTests.recordRun("wf_1", "nd_1", {
|
|
57
|
+
* stepTestId: fixture.id,
|
|
58
|
+
* status: "succeeded",
|
|
59
|
+
* output: { ok: true },
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export class StepTestsApi {
|
|
64
|
+
#host;
|
|
65
|
+
/**
|
|
66
|
+
* @param host - The client this namespace issues requests through.
|
|
67
|
+
*/
|
|
68
|
+
constructor(host) {
|
|
69
|
+
this.#host = host;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Save a step-test fixture.
|
|
73
|
+
*
|
|
74
|
+
* @param workflowId - The `wf_…` id.
|
|
75
|
+
* @param stepId - The step's id within that workflow.
|
|
76
|
+
* @param body - Optional `name`, plus `input`/`with`, forwarded verbatim.
|
|
77
|
+
* @returns The created step test, unwrapped from the `stepTest` envelope (the server answers `201`).
|
|
78
|
+
* @throws {ApiError} `400 invalid_name`/`invalid_input`/`invalid_with`;
|
|
79
|
+
* `404 unknown_workflow`.
|
|
80
|
+
*/
|
|
81
|
+
async save(workflowId, stepId, body) {
|
|
82
|
+
const res = await this.#host.request({
|
|
83
|
+
method: "POST",
|
|
84
|
+
path: path `/workflows/${workflowId}/steps/${stepId}/tests`,
|
|
85
|
+
body,
|
|
86
|
+
});
|
|
87
|
+
return unwrap(res, "stepTest");
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* List a step's saved test fixtures.
|
|
91
|
+
*
|
|
92
|
+
* @param workflowId - The `wf_…` id.
|
|
93
|
+
* @param stepId - The step's id within that workflow.
|
|
94
|
+
* @returns The step tests, unwrapped from the `stepTests` envelope.
|
|
95
|
+
*/
|
|
96
|
+
async list(workflowId, stepId) {
|
|
97
|
+
const res = await this.#host.request({
|
|
98
|
+
method: "GET",
|
|
99
|
+
path: path `/workflows/${workflowId}/steps/${stepId}/tests`,
|
|
100
|
+
});
|
|
101
|
+
return unwrap(res, "stepTests");
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Record the outcome of a step-test run. Appends a `step_test_runs` row
|
|
105
|
+
* (and a best-effort `run_log` ledger row) server-side; when `stepTestId`
|
|
106
|
+
* is present, the fixture's `lastRun*` fields are updated too.
|
|
107
|
+
*
|
|
108
|
+
* Returns the REAL created row — see this module's header. Does NOT
|
|
109
|
+
* discard to `void`; a caller wanting the studio-facade `void` shape
|
|
110
|
+
* adapts it themselves.
|
|
111
|
+
*
|
|
112
|
+
* @param workflowId - The `wf_…` id.
|
|
113
|
+
* @param stepId - The step's id within that workflow.
|
|
114
|
+
* @param body - `stepTestId` (optional), `status`, and optional
|
|
115
|
+
* `input`/`output`/`error`, forwarded verbatim.
|
|
116
|
+
* @returns The created `StepTestRun`, unwrapped from the `run` envelope (the server answers `201`).
|
|
117
|
+
* @throws {ApiError} `400 invalid_body`/`invalid_status`. No `404` — the
|
|
118
|
+
* route never checks the workflow/step exist before writing.
|
|
119
|
+
*/
|
|
120
|
+
async recordRun(workflowId, stepId, body) {
|
|
121
|
+
const res = await this.#host.request({
|
|
122
|
+
method: "POST",
|
|
123
|
+
path: path `/workflows/${workflowId}/steps/${stepId}/test-runs`,
|
|
124
|
+
body,
|
|
125
|
+
});
|
|
126
|
+
return unwrap(res, "run");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=step-tests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-tests.js","sourceRoot":"","sources":["../../../src/console/step-tests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAqB,IAAI,EAAuB,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAgDrC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,YAAY;IACd,KAAK,CAAgB;IAE9B;;OAEG;IACH,YAAY,IAAmB;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,IAAI,CACR,UAAkB,EAClB,MAAc,EACd,IAAsF;QAEtF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAA,cAAc,UAAU,UAAU,MAAM,QAAQ;YAC1D,IAAI;SACL,CAAC,CAAC;QACH,OAAO,MAAM,CAAW,GAAG,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,CAAC,UAAkB,EAAE,MAAc;QAC3C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAAI,CAAA,cAAc,UAAU,UAAU,MAAM,QAAQ;SAC3D,CAAC,CAAC;QACH,OAAO,MAAM,CAAa,GAAG,EAAE,WAAW,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,SAAS,CACb,UAAkB,EAClB,MAAc,EACd,IAMC;QAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAA,cAAc,UAAU,UAAU,MAAM,YAAY;YAC9D,IAAI;SACL,CAAC,CAAC;QACH,OAAO,MAAM,CAAc,GAAG,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;CACF"}
|