@w6w/sdk 0.3.0 → 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/dist/src/client.d.ts +28 -0
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +29 -0
- 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/package.json +5 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.console.dashboard.*` — the account-scoped dashboard rollup,
|
|
3
|
+
* relocated from the 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
|
+
* One operation: `stats`, `GET /dashboard/stats`. AUTHENTICATED — the account
|
|
15
|
+
* is derived server-side from the principal (`admin/dashboard.ts:44-96`), so
|
|
16
|
+
* this uses the default, unconditional `requireAuth` (HITL-9); the client
|
|
17
|
+
* never sends an account. Unlike `client.documents.*` and `client.vars.*`,
|
|
18
|
+
* the response carries **no envelope key** — the `DashboardStats`-shaped
|
|
19
|
+
* object IS the top-level response body (`admin/dashboard.ts:90-95`, which
|
|
20
|
+
* answers `c.json({range, headline, series, recent})`), so `stats` returns
|
|
21
|
+
* `res.body` directly and never calls this package's `unwrap()` helper.
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* The `console.dashboard` namespace on a `W6wClient`.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const rollup = await client.console.dashboard.stats({ bucket: "week" });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class DashboardApi {
|
|
34
|
+
#host;
|
|
35
|
+
/**
|
|
36
|
+
* @param host - The client this namespace issues requests through.
|
|
37
|
+
*/
|
|
38
|
+
constructor(host) {
|
|
39
|
+
this.#host = host;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Fetch the account-scoped dashboard rollup.
|
|
43
|
+
*
|
|
44
|
+
* @param params - Optional `from`/`to`/`bucket`; each is forwarded as a
|
|
45
|
+
* query parameter when given, and omitted from the query string entirely
|
|
46
|
+
* when not (the server applies its own defaults).
|
|
47
|
+
* @returns The rollup, exactly as the server sent it — no envelope key to peel.
|
|
48
|
+
* @throws {ApiError} On any non-2xx.
|
|
49
|
+
*/
|
|
50
|
+
async stats(params = {}) {
|
|
51
|
+
const res = await this.#host.request({
|
|
52
|
+
method: "GET",
|
|
53
|
+
path: "/dashboard/stats",
|
|
54
|
+
query: { from: params.from, to: params.to, bucket: params.bucket },
|
|
55
|
+
});
|
|
56
|
+
return res.body;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/console/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA6CH;;;;;;;GAOG;AACH,MAAM,OAAO,YAAY;IACd,KAAK,CAAgB;IAE9B;;OAEG;IACH,YAAY,IAAmB;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,KAAK,CAAC,SAA+B,EAAE;QAC3C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAiB;YACnD,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,kBAAkB;YACxB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;SACnE,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.console.endpoints.*` — the named, stable callable-entry-point
|
|
3
|
+
* surface (`list`/`get`/`upsert`/`invoke`), relocated from the studio's own
|
|
4
|
+
* API client.
|
|
5
|
+
*
|
|
6
|
+
* **Studio-internal, not the published partner contract.** This namespace
|
|
7
|
+
* lives under the `console` subpath export (`@w6w/sdk/console`), excluded
|
|
8
|
+
* from `endpoints.json` and from the root barrel (`mod.ts`) — see
|
|
9
|
+
* `docs/console.md` and HITL-1 in this task's contract. `@w6w/sdk`'s
|
|
10
|
+
* instance-state mechanism pin still applies here exactly as it does to
|
|
11
|
+
* every other namespace (`docs/implementation.md` §MECHANISM PIN — instance
|
|
12
|
+
* state, never globals): this class holds no state of its own beyond the
|
|
13
|
+
* injected host, so two clients in one process never share a credential.
|
|
14
|
+
*
|
|
15
|
+
* **`invoke`'s wire path is a PINNED mechanism, not a choice — read this
|
|
16
|
+
* before touching `invoke` below.** {@linkcode EndpointsApi.invoke} MUST call
|
|
17
|
+
* `POST /endpoints/:id/invoke` directly. It must NEVER be implemented by
|
|
18
|
+
* delegating to `client.run()`/`runUrn()`/`POST /run`, even though that
|
|
19
|
+
* dispatcher can also resolve an `ep_…` URN. Verified directly against the
|
|
20
|
+
* server: `packages/server/packages/bll/resolve-run.ts`'s `ep_` arm
|
|
21
|
+
* (`:198-207`) delegates to `InvokeEndpointService.invoke()` but then
|
|
22
|
+
* **remaps** the action-kind result's field from `output` to `value`
|
|
23
|
+
* (`return { kind: "action", value: result.output };`) to match `run()`'s own
|
|
24
|
+
* `ActionRunEnvelope` shape. The dedicated `/endpoints/:id/invoke` route
|
|
25
|
+
* (`packages/server/packages/api/admin/endpoints.ts:319-360`) does NOT do
|
|
26
|
+
* this remap — it returns `InvokeEndpointResult` VERBATIM (`{kind:"action",
|
|
27
|
+
* output}` for an action target). Studio's `EndpointsPage.tsx` renders the
|
|
28
|
+
* raw envelope it gets back directly (`JSON.stringify(result, null, 2)`), so
|
|
29
|
+
* this field name is user-visible. Routing `invoke` through `/run` instead of
|
|
30
|
+
* the dedicated route would silently rename `output` to `value` and break
|
|
31
|
+
* that page — a "simplification" that looks harmless and is not.
|
|
32
|
+
*
|
|
33
|
+
* Four methods relocate from the studio's `// Endpoints` comment block
|
|
34
|
+
* (`packages/studio/src/api/client.ts:281-314`): `listEndpoints`→`list`,
|
|
35
|
+
* `getEndpoint`→`get`, `saveEndpoint`→`upsert`, `invokeEndpoint`→`invoke`.
|
|
36
|
+
*
|
|
37
|
+
* None of the four methods take a client-side default-project fallback or a
|
|
38
|
+
* `?project=` scoping parameter — neither is reachable via any HTTP route on
|
|
39
|
+
* this domain — so `EndpointsHost` needs only the transport, mirroring
|
|
40
|
+
* `WorkflowsHost`/`SchedulesHost`, not the base `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 `WorkflowsHost` in `./workflows.ts`.
|
|
50
|
+
*/
|
|
51
|
+
export interface EndpointsHost {
|
|
52
|
+
/** Perform one request. */
|
|
53
|
+
request<T>(options: RequestOptions): Promise<HttpResponse<T>>;
|
|
54
|
+
}
|
|
55
|
+
/** What an Endpoint dispatches to, when the target is a Function or Workflow. */
|
|
56
|
+
export type Callable = {
|
|
57
|
+
kind: "function";
|
|
58
|
+
function: string;
|
|
59
|
+
} | {
|
|
60
|
+
kind: "workflow";
|
|
61
|
+
workflow: string;
|
|
62
|
+
};
|
|
63
|
+
/** What an Endpoint dispatches to, when the target is a direct app Action. */
|
|
64
|
+
export interface ActionTarget {
|
|
65
|
+
kind: "action";
|
|
66
|
+
uses: {
|
|
67
|
+
app: string;
|
|
68
|
+
action: string;
|
|
69
|
+
connection?: string | null;
|
|
70
|
+
};
|
|
71
|
+
with?: Record<string, unknown>;
|
|
72
|
+
}
|
|
73
|
+
/** The full discriminated union of what an Endpoint may dispatch to. */
|
|
74
|
+
export type EndpointTarget = Callable | ActionTarget;
|
|
75
|
+
/** The inbound auth mode an Endpoint's public exposure enforces. */
|
|
76
|
+
export type EndpointAuthMode = "platform" | "none" | "basic" | "header" | "jwt";
|
|
77
|
+
/**
|
|
78
|
+
* An Endpoint's inbound security policy. Secret-carrying fields
|
|
79
|
+
* (`basicPassword`, `headerValue`, `jwtSecret`) come back from a `GET` masked
|
|
80
|
+
* with {@linkcode SECRET_MASK}, never as plaintext or ciphertext — sending the
|
|
81
|
+
* mask back on `upsert` preserves whatever is already stored.
|
|
82
|
+
*/
|
|
83
|
+
export interface EndpointSecurity {
|
|
84
|
+
auth: EndpointAuthMode;
|
|
85
|
+
basicUser?: string;
|
|
86
|
+
basicPassword?: string;
|
|
87
|
+
headerName?: string;
|
|
88
|
+
headerValue?: string;
|
|
89
|
+
jwtSecret?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The placeholder a `GET` returns in place of a configured secret, and which
|
|
93
|
+
* an `upsert` may send back to mean "keep what is stored". Relocated
|
|
94
|
+
* verbatim from `admin/endpoints.ts`'s own exported constant — same value,
|
|
95
|
+
* same meaning.
|
|
96
|
+
*/
|
|
97
|
+
export declare const SECRET_MASK = "__stored__";
|
|
98
|
+
/** How an Endpoint may additionally be reachable, declaratively. */
|
|
99
|
+
export interface Exposure {
|
|
100
|
+
http?: {
|
|
101
|
+
method?: "POST" | "GET";
|
|
102
|
+
path?: string;
|
|
103
|
+
auth?: "none" | "token" | "tenant";
|
|
104
|
+
};
|
|
105
|
+
security?: EndpointSecurity;
|
|
106
|
+
}
|
|
107
|
+
/** One declared input an Endpoint accepts. */
|
|
108
|
+
export interface EndpointInput {
|
|
109
|
+
key: string;
|
|
110
|
+
label: string;
|
|
111
|
+
type: string;
|
|
112
|
+
required?: boolean;
|
|
113
|
+
default?: unknown;
|
|
114
|
+
hint?: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* An Endpoint definition — a named, stable callable entry point that
|
|
118
|
+
* dispatches to exactly one target: an app Action, a Function, or a Workflow
|
|
119
|
+
* (`rfcs/endpoint.md`). Callers bind to the Endpoint id; the target beneath
|
|
120
|
+
* it can change without breaking them.
|
|
121
|
+
*
|
|
122
|
+
* `key` is **immutable after first save** — it is a public URL segment. A
|
|
123
|
+
* save that changes `key` on an already-stored Endpoint answers `409
|
|
124
|
+
* key_immutable`; a first save with a malformed `key` answers `400
|
|
125
|
+
* invalid_endpoint`.
|
|
126
|
+
*/
|
|
127
|
+
export interface EndpointDef {
|
|
128
|
+
manifestVersion: string;
|
|
129
|
+
id: string;
|
|
130
|
+
key: string;
|
|
131
|
+
displayName?: string;
|
|
132
|
+
description?: string;
|
|
133
|
+
target: EndpointTarget;
|
|
134
|
+
input?: EndpointInput[];
|
|
135
|
+
exposure?: Exposure;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* One row of `list`'s result — an Endpoint's summary, not its full
|
|
139
|
+
* definition. Each row already carries its own `invokeUrl`, merged in
|
|
140
|
+
* server-side.
|
|
141
|
+
*/
|
|
142
|
+
export interface EndpointSummary {
|
|
143
|
+
id: string;
|
|
144
|
+
key: string;
|
|
145
|
+
displayName: string;
|
|
146
|
+
description: string;
|
|
147
|
+
updatedAt: string;
|
|
148
|
+
invokeUrl: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* What {@linkcode EndpointsApi.invoke} resolves to — the discriminated result
|
|
152
|
+
* of dispatching one Endpoint, returned VERBATIM from the dedicated invoke
|
|
153
|
+
* route. `output` (action/function) and `runId` (workflow) are the server's
|
|
154
|
+
* own field names — never renamed, never normalised, per this module's
|
|
155
|
+
* header pin.
|
|
156
|
+
*/
|
|
157
|
+
export type EndpointInvokeResult = {
|
|
158
|
+
kind: "action";
|
|
159
|
+
output: unknown;
|
|
160
|
+
} | {
|
|
161
|
+
kind: "function";
|
|
162
|
+
output: unknown;
|
|
163
|
+
} | {
|
|
164
|
+
kind: "workflow";
|
|
165
|
+
runId: string;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* The `console.endpoints` namespace on a `W6wClient`.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* const endpoints = await client.console.endpoints.list();
|
|
173
|
+
* const { endpoint, invokeUrl } = await client.console.endpoints.get(endpoints[0].id);
|
|
174
|
+
* const result = await client.console.endpoints.invoke(endpoint.id, { to: "a@b.com" });
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
export declare class EndpointsApi {
|
|
178
|
+
#private;
|
|
179
|
+
/**
|
|
180
|
+
* @param host - The client this namespace issues requests through.
|
|
181
|
+
*/
|
|
182
|
+
constructor(host: EndpointsHost);
|
|
183
|
+
/**
|
|
184
|
+
* List the caller's Endpoint definitions.
|
|
185
|
+
*
|
|
186
|
+
* @returns The Endpoints, unwrapped from the `endpoints` envelope; each row
|
|
187
|
+
* carries its own `invokeUrl`/`invokeUrlByKey`, preserved untouched.
|
|
188
|
+
*/
|
|
189
|
+
list(): Promise<EndpointSummary[]>;
|
|
190
|
+
/**
|
|
191
|
+
* Fetch one Endpoint's stored definition plus its callable URL(s). Any
|
|
192
|
+
* configured secret comes back masked with {@linkcode SECRET_MASK}, never
|
|
193
|
+
* as plaintext or ciphertext.
|
|
194
|
+
*
|
|
195
|
+
* **Returns the response body VERBATIM — a three-key top-level shape, NOT
|
|
196
|
+
* merged.** `invokeUrl`/`invokeUrlByKey` are never spliced into `endpoint`;
|
|
197
|
+
* this mirrors `console.workflows.get`'s "no envelope key to peel, multiple
|
|
198
|
+
* top-level siblings" precedent, deliberately NOT
|
|
199
|
+
* `console.functions.get`'s merge — these are two different,
|
|
200
|
+
* individually-verified, individually-pinned shapes. `invokeUrl` is ALWAYS
|
|
201
|
+
* present; `invokeUrlByKey` is present only when the owning account has a
|
|
202
|
+
* slug — genuinely absent from the body otherwise, never an
|
|
203
|
+
* `undefined`-valued key.
|
|
204
|
+
*
|
|
205
|
+
* No 404 special-casing — propagates as `ApiError` like every other "get"
|
|
206
|
+
* in this package except `console.schedules.get`'s documented exception.
|
|
207
|
+
*
|
|
208
|
+
* @param id - The `ep_…` id.
|
|
209
|
+
* @returns The whole response body — no envelope key to peel.
|
|
210
|
+
* @throws {ApiError} `404 unknown_endpoint` when there is no such id.
|
|
211
|
+
*/
|
|
212
|
+
get(id: string): Promise<{
|
|
213
|
+
endpoint: EndpointDef;
|
|
214
|
+
invokeUrl: string;
|
|
215
|
+
invokeUrlByKey?: string;
|
|
216
|
+
}>;
|
|
217
|
+
/**
|
|
218
|
+
* Register (create or overwrite) an Endpoint definition.
|
|
219
|
+
*
|
|
220
|
+
* `definition` is the whole definition, sent verbatim as the request body —
|
|
221
|
+
* not wrapped in an envelope key. **Returns the response body VERBATIM**,
|
|
222
|
+
* same three-key shape as {@linkcode get} — no merge, no `unwrap()`.
|
|
223
|
+
*
|
|
224
|
+
* None of the four error codes below need special client-side handling —
|
|
225
|
+
* they propagate as an ordinary `ApiError` with the server's own
|
|
226
|
+
* `.message`, exactly like every other write in this package; this method
|
|
227
|
+
* does not branch on any of them.
|
|
228
|
+
*
|
|
229
|
+
* @param definition - The whole Endpoint definition, forwarded verbatim.
|
|
230
|
+
* @returns The new/updated Endpoint's id and key, plus its callable URL(s).
|
|
231
|
+
* @throws {ApiError} `400 invalid_endpoint` — structurally invalid body, or (first save only) a malformed `key`.
|
|
232
|
+
* @throws {ApiError} `409 key_immutable` — `key` differs from the already-stored row's `key`.
|
|
233
|
+
* @throws {ApiError} `409 endpoint_conflict` — another `(tenant,subject)` owns this id.
|
|
234
|
+
* @throws {ApiError} `409 endpoint_key_conflict` — another Endpoint already holds this `key`.
|
|
235
|
+
*/
|
|
236
|
+
upsert(definition: EndpointDef): Promise<{
|
|
237
|
+
endpoint: {
|
|
238
|
+
id: string;
|
|
239
|
+
key: string;
|
|
240
|
+
};
|
|
241
|
+
invokeUrl: string;
|
|
242
|
+
invokeUrlByKey?: string;
|
|
243
|
+
}>;
|
|
244
|
+
/**
|
|
245
|
+
* Invoke an Endpoint: dispatches to its configured target (an app Action, a
|
|
246
|
+
* Function, or a Workflow) and returns the discriminated result.
|
|
247
|
+
*
|
|
248
|
+
* **Calls the DEDICATED `POST /endpoints/:id/invoke` route directly — see
|
|
249
|
+
* this module's header for why it must NEVER delegate to `client.run()`/
|
|
250
|
+
* `runUrn()`/`POST /run` instead.** The response body is returned
|
|
251
|
+
* VERBATIM, field names untouched: an `action`/`function` target answers
|
|
252
|
+
* `200` with `{kind, output}`; a `workflow` target answers `202` with
|
|
253
|
+
* `{kind:"workflow", runId}` — both are success on this API, mirroring
|
|
254
|
+
* `console.workflows`'s/base `run()`'s own "202 is success" convention.
|
|
255
|
+
*
|
|
256
|
+
* @param id - The `ep_…` id.
|
|
257
|
+
* @param input - The Endpoint's declared inputs, forwarded verbatim as `{input}`.
|
|
258
|
+
* @returns The discriminated dispatch result, unmodified from the wire.
|
|
259
|
+
* @throws {ApiError} `404 unknown_endpoint` / `404 unknown_function` / `404 unknown_workflow`.
|
|
260
|
+
* @throws {ApiError} `422 function_incomplete` — the target Function is not runnable.
|
|
261
|
+
*/
|
|
262
|
+
invoke(id: string, input: Record<string, unknown>): Promise<EndpointInvokeResult>;
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=endpoints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../../src/console/endpoints.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.console.endpoints.*` — the named, stable callable-entry-point
|
|
3
|
+
* surface (`list`/`get`/`upsert`/`invoke`), relocated from the studio's own
|
|
4
|
+
* API client.
|
|
5
|
+
*
|
|
6
|
+
* **Studio-internal, not the published partner contract.** This namespace
|
|
7
|
+
* lives under the `console` subpath export (`@w6w/sdk/console`), excluded
|
|
8
|
+
* from `endpoints.json` and from the root barrel (`mod.ts`) — see
|
|
9
|
+
* `docs/console.md` and HITL-1 in this task's contract. `@w6w/sdk`'s
|
|
10
|
+
* instance-state mechanism pin still applies here exactly as it does to
|
|
11
|
+
* every other namespace (`docs/implementation.md` §MECHANISM PIN — instance
|
|
12
|
+
* state, never globals): this class holds no state of its own beyond the
|
|
13
|
+
* injected host, so two clients in one process never share a credential.
|
|
14
|
+
*
|
|
15
|
+
* **`invoke`'s wire path is a PINNED mechanism, not a choice — read this
|
|
16
|
+
* before touching `invoke` below.** {@linkcode EndpointsApi.invoke} MUST call
|
|
17
|
+
* `POST /endpoints/:id/invoke` directly. It must NEVER be implemented by
|
|
18
|
+
* delegating to `client.run()`/`runUrn()`/`POST /run`, even though that
|
|
19
|
+
* dispatcher can also resolve an `ep_…` URN. Verified directly against the
|
|
20
|
+
* server: `packages/server/packages/bll/resolve-run.ts`'s `ep_` arm
|
|
21
|
+
* (`:198-207`) delegates to `InvokeEndpointService.invoke()` but then
|
|
22
|
+
* **remaps** the action-kind result's field from `output` to `value`
|
|
23
|
+
* (`return { kind: "action", value: result.output };`) to match `run()`'s own
|
|
24
|
+
* `ActionRunEnvelope` shape. The dedicated `/endpoints/:id/invoke` route
|
|
25
|
+
* (`packages/server/packages/api/admin/endpoints.ts:319-360`) does NOT do
|
|
26
|
+
* this remap — it returns `InvokeEndpointResult` VERBATIM (`{kind:"action",
|
|
27
|
+
* output}` for an action target). Studio's `EndpointsPage.tsx` renders the
|
|
28
|
+
* raw envelope it gets back directly (`JSON.stringify(result, null, 2)`), so
|
|
29
|
+
* this field name is user-visible. Routing `invoke` through `/run` instead of
|
|
30
|
+
* the dedicated route would silently rename `output` to `value` and break
|
|
31
|
+
* that page — a "simplification" that looks harmless and is not.
|
|
32
|
+
*
|
|
33
|
+
* Four methods relocate from the studio's `// Endpoints` comment block
|
|
34
|
+
* (`packages/studio/src/api/client.ts:281-314`): `listEndpoints`→`list`,
|
|
35
|
+
* `getEndpoint`→`get`, `saveEndpoint`→`upsert`, `invokeEndpoint`→`invoke`.
|
|
36
|
+
*
|
|
37
|
+
* None of the four methods take a client-side default-project fallback or a
|
|
38
|
+
* `?project=` scoping parameter — neither is reachable via any HTTP route on
|
|
39
|
+
* this domain — so `EndpointsHost` needs only the transport, mirroring
|
|
40
|
+
* `WorkflowsHost`/`SchedulesHost`, not the base `DocumentsHost`.
|
|
41
|
+
*
|
|
42
|
+
* @module
|
|
43
|
+
*/
|
|
44
|
+
import { path } from "../http.js";
|
|
45
|
+
import { unwrap } from "../types.js";
|
|
46
|
+
/**
|
|
47
|
+
* The placeholder a `GET` returns in place of a configured secret, and which
|
|
48
|
+
* an `upsert` may send back to mean "keep what is stored". Relocated
|
|
49
|
+
* verbatim from `admin/endpoints.ts`'s own exported constant — same value,
|
|
50
|
+
* same meaning.
|
|
51
|
+
*/
|
|
52
|
+
export const SECRET_MASK = "__stored__";
|
|
53
|
+
/**
|
|
54
|
+
* The `console.endpoints` namespace on a `W6wClient`.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* const endpoints = await client.console.endpoints.list();
|
|
59
|
+
* const { endpoint, invokeUrl } = await client.console.endpoints.get(endpoints[0].id);
|
|
60
|
+
* const result = await client.console.endpoints.invoke(endpoint.id, { to: "a@b.com" });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export class EndpointsApi {
|
|
64
|
+
#host;
|
|
65
|
+
/**
|
|
66
|
+
* @param host - The client this namespace issues requests through.
|
|
67
|
+
*/
|
|
68
|
+
constructor(host) {
|
|
69
|
+
this.#host = host;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* List the caller's Endpoint definitions.
|
|
73
|
+
*
|
|
74
|
+
* @returns The Endpoints, unwrapped from the `endpoints` envelope; each row
|
|
75
|
+
* carries its own `invokeUrl`/`invokeUrlByKey`, preserved untouched.
|
|
76
|
+
*/
|
|
77
|
+
async list() {
|
|
78
|
+
const res = await this.#host.request({ method: "GET", path: "/endpoints" });
|
|
79
|
+
return unwrap(res, "endpoints");
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Fetch one Endpoint's stored definition plus its callable URL(s). Any
|
|
83
|
+
* configured secret comes back masked with {@linkcode SECRET_MASK}, never
|
|
84
|
+
* as plaintext or ciphertext.
|
|
85
|
+
*
|
|
86
|
+
* **Returns the response body VERBATIM — a three-key top-level shape, NOT
|
|
87
|
+
* merged.** `invokeUrl`/`invokeUrlByKey` are never spliced into `endpoint`;
|
|
88
|
+
* this mirrors `console.workflows.get`'s "no envelope key to peel, multiple
|
|
89
|
+
* top-level siblings" precedent, deliberately NOT
|
|
90
|
+
* `console.functions.get`'s merge — these are two different,
|
|
91
|
+
* individually-verified, individually-pinned shapes. `invokeUrl` is ALWAYS
|
|
92
|
+
* present; `invokeUrlByKey` is present only when the owning account has a
|
|
93
|
+
* slug — genuinely absent from the body otherwise, never an
|
|
94
|
+
* `undefined`-valued key.
|
|
95
|
+
*
|
|
96
|
+
* No 404 special-casing — propagates as `ApiError` like every other "get"
|
|
97
|
+
* in this package except `console.schedules.get`'s documented exception.
|
|
98
|
+
*
|
|
99
|
+
* @param id - The `ep_…` id.
|
|
100
|
+
* @returns The whole response body — no envelope key to peel.
|
|
101
|
+
* @throws {ApiError} `404 unknown_endpoint` when there is no such id.
|
|
102
|
+
*/
|
|
103
|
+
async get(id) {
|
|
104
|
+
const res = await this.#host.request({
|
|
105
|
+
method: "GET",
|
|
106
|
+
path: path `/endpoints/${id}`,
|
|
107
|
+
});
|
|
108
|
+
return res.body;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Register (create or overwrite) an Endpoint definition.
|
|
112
|
+
*
|
|
113
|
+
* `definition` is the whole definition, sent verbatim as the request body —
|
|
114
|
+
* not wrapped in an envelope key. **Returns the response body VERBATIM**,
|
|
115
|
+
* same three-key shape as {@linkcode get} — no merge, no `unwrap()`.
|
|
116
|
+
*
|
|
117
|
+
* None of the four error codes below need special client-side handling —
|
|
118
|
+
* they propagate as an ordinary `ApiError` with the server's own
|
|
119
|
+
* `.message`, exactly like every other write in this package; this method
|
|
120
|
+
* does not branch on any of them.
|
|
121
|
+
*
|
|
122
|
+
* @param definition - The whole Endpoint definition, forwarded verbatim.
|
|
123
|
+
* @returns The new/updated Endpoint's id and key, plus its callable URL(s).
|
|
124
|
+
* @throws {ApiError} `400 invalid_endpoint` — structurally invalid body, or (first save only) a malformed `key`.
|
|
125
|
+
* @throws {ApiError} `409 key_immutable` — `key` differs from the already-stored row's `key`.
|
|
126
|
+
* @throws {ApiError} `409 endpoint_conflict` — another `(tenant,subject)` owns this id.
|
|
127
|
+
* @throws {ApiError} `409 endpoint_key_conflict` — another Endpoint already holds this `key`.
|
|
128
|
+
*/
|
|
129
|
+
async upsert(definition) {
|
|
130
|
+
const res = await this.#host.request({
|
|
131
|
+
method: "POST",
|
|
132
|
+
path: "/endpoints",
|
|
133
|
+
body: definition,
|
|
134
|
+
});
|
|
135
|
+
return res.body;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Invoke an Endpoint: dispatches to its configured target (an app Action, a
|
|
139
|
+
* Function, or a Workflow) and returns the discriminated result.
|
|
140
|
+
*
|
|
141
|
+
* **Calls the DEDICATED `POST /endpoints/:id/invoke` route directly — see
|
|
142
|
+
* this module's header for why it must NEVER delegate to `client.run()`/
|
|
143
|
+
* `runUrn()`/`POST /run` instead.** The response body is returned
|
|
144
|
+
* VERBATIM, field names untouched: an `action`/`function` target answers
|
|
145
|
+
* `200` with `{kind, output}`; a `workflow` target answers `202` with
|
|
146
|
+
* `{kind:"workflow", runId}` — both are success on this API, mirroring
|
|
147
|
+
* `console.workflows`'s/base `run()`'s own "202 is success" convention.
|
|
148
|
+
*
|
|
149
|
+
* @param id - The `ep_…` id.
|
|
150
|
+
* @param input - The Endpoint's declared inputs, forwarded verbatim as `{input}`.
|
|
151
|
+
* @returns The discriminated dispatch result, unmodified from the wire.
|
|
152
|
+
* @throws {ApiError} `404 unknown_endpoint` / `404 unknown_function` / `404 unknown_workflow`.
|
|
153
|
+
* @throws {ApiError} `422 function_incomplete` — the target Function is not runnable.
|
|
154
|
+
*/
|
|
155
|
+
async invoke(id, input) {
|
|
156
|
+
const res = await this.#host.request({
|
|
157
|
+
method: "POST",
|
|
158
|
+
path: path `/endpoints/${id}/invoke`,
|
|
159
|
+
body: { input },
|
|
160
|
+
});
|
|
161
|
+
return res.body;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=endpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../../src/console/endpoints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAqB,IAAI,EAAuB,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA8CrC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC;AAkExC;;;;;;;;;GASG;AACH,MAAM,OAAO,YAAY;IACd,KAAK,CAAgB;IAE9B;;OAEG;IACH,YAAY,IAAmB;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;QACrF,OAAO,MAAM,CAAoB,GAAG,EAAE,WAAW,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,GAAG,CACP,EAAU;QAEV,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAElC;YACA,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAAI,CAAA,cAAc,EAAE,EAAE;SAC7B,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,MAAM,CACV,UAAuB;QAIvB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAElC;YACA,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,UAAU;SACjB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,KAA8B;QACrD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAuB;YACzD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAA,cAAc,EAAE,SAAS;YACnC,IAAI,EAAE,EAAE,KAAK,EAAE;SAChB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.console.functions.*` — the canonical, vendor-stable Function
|
|
3
|
+
* definition surface (`list`/`get`/`upsert`), relocated from the studio's own
|
|
4
|
+
* API client.
|
|
5
|
+
*
|
|
6
|
+
* **Studio-internal, not the published partner contract.** This namespace
|
|
7
|
+
* lives under the `console` subpath export (`@w6w/sdk/console`), excluded
|
|
8
|
+
* from `endpoints.json` and from the root barrel (`mod.ts`) — see
|
|
9
|
+
* `docs/console.md` and HITL-1 in this task's contract. `@w6w/sdk`'s
|
|
10
|
+
* instance-state mechanism pin still applies here exactly as it does to
|
|
11
|
+
* every other namespace (`docs/implementation.md` §MECHANISM PIN — instance
|
|
12
|
+
* state, never globals): this class holds no state of its own beyond the
|
|
13
|
+
* injected host, so two clients in one process never share a credential.
|
|
14
|
+
*
|
|
15
|
+
* **`invoke` is deliberately NOT modeled here.** The base
|
|
16
|
+
* `client.run({urn, payload})` (already-published surface,
|
|
17
|
+
* `endpoints.json`-named, exported from the root `mod.ts`) dispatches a
|
|
18
|
+
* `fn_…` URN through the exact same `InvokeFunctionService` the dedicated
|
|
19
|
+
* `/functions/:id/invoke` route uses, returning `{kind:"function", output}` —
|
|
20
|
+
* field-for-field identical to what the dedicated route returns. Adding a
|
|
21
|
+
* duplicate `console.functions.invoke` would give a caller two ways to reach
|
|
22
|
+
* the same route, the anti-duplication defect this project's own rules flag
|
|
23
|
+
* — mirrors `console.workflows`'s established precedent of NOT re-wrapping
|
|
24
|
+
* base `list`/`run`. Studio composes `client.run()` + `isFunctionRun` itself;
|
|
25
|
+
* no invoke method lives here, and none should be added later without
|
|
26
|
+
* re-litigating this reasoning.
|
|
27
|
+
*
|
|
28
|
+
* Three methods relocate from the studio's `// Functions` comment block
|
|
29
|
+
* (`packages/studio/src/api/client.ts:255-268`): `listFunctions`→`list`,
|
|
30
|
+
* `getFunction`→`get`, `saveFunction`→`upsert`.
|
|
31
|
+
*
|
|
32
|
+
* None of the three methods take a client-side default-project fallback or a
|
|
33
|
+
* `?project=` scoping parameter — neither is reachable via either HTTP route
|
|
34
|
+
* — so `FunctionsHost` needs only the transport, mirroring
|
|
35
|
+
* `WorkflowsHost`/`SchedulesHost`, not the base `DocumentsHost`.
|
|
36
|
+
*
|
|
37
|
+
* @module
|
|
38
|
+
*/
|
|
39
|
+
import { type HttpResponse, type RequestOptions } from "../http.ts";
|
|
40
|
+
/**
|
|
41
|
+
* The slice of `W6wClient` this namespace needs: the transport, and nothing
|
|
42
|
+
* else. Structural rather than a concrete client type, so the namespace stays
|
|
43
|
+
* independently constructible in a test and this module never imports the
|
|
44
|
+
* client back — mirrors `WorkflowsHost` in `./workflows.ts`.
|
|
45
|
+
*/
|
|
46
|
+
export interface FunctionsHost {
|
|
47
|
+
/** Perform one request. */
|
|
48
|
+
request<T>(options: RequestOptions): Promise<HttpResponse<T>>;
|
|
49
|
+
}
|
|
50
|
+
/** One declared input a Function accepts. */
|
|
51
|
+
export interface FunctionInput {
|
|
52
|
+
key: string;
|
|
53
|
+
label: string;
|
|
54
|
+
type: "string" | "text" | "number" | "boolean" | "json" | "secret" | string;
|
|
55
|
+
required?: boolean;
|
|
56
|
+
default?: unknown;
|
|
57
|
+
hint?: string;
|
|
58
|
+
}
|
|
59
|
+
/** One declared field of a Function's output shape. */
|
|
60
|
+
export interface FunctionOutputField {
|
|
61
|
+
key: string;
|
|
62
|
+
type: "string" | "number" | "boolean" | "object" | "array" | string;
|
|
63
|
+
label?: string;
|
|
64
|
+
}
|
|
65
|
+
/** What a Function is bound to: one app Action, plus the mapping around it. */
|
|
66
|
+
export interface FunctionImpl {
|
|
67
|
+
uses: {
|
|
68
|
+
app: string;
|
|
69
|
+
action: string;
|
|
70
|
+
connection?: string | null;
|
|
71
|
+
};
|
|
72
|
+
with?: Record<string, unknown>;
|
|
73
|
+
outputMap?: Record<string, unknown>;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A Function definition — a canonical, vendor-stable interface bound to one
|
|
77
|
+
* swappable app Action (`rfcs/function.md`). Callers bind to `inputs`/
|
|
78
|
+
* `output`; a vendor swap rewrites only `impl.uses`, so no caller breaks.
|
|
79
|
+
*
|
|
80
|
+
* `valid` is **server-computed**, spliced in by {@linkcode FunctionsApi.get}
|
|
81
|
+
* — see that method's doc. It is never sent by a caller on `upsert`.
|
|
82
|
+
*/
|
|
83
|
+
export interface FunctionDef {
|
|
84
|
+
manifestVersion: string;
|
|
85
|
+
id: string;
|
|
86
|
+
key: string;
|
|
87
|
+
displayName?: string;
|
|
88
|
+
description?: string;
|
|
89
|
+
inputs: FunctionInput[];
|
|
90
|
+
output?: FunctionOutputField[];
|
|
91
|
+
impl: FunctionImpl;
|
|
92
|
+
/** Server-computed, spliced in by `console.functions.get` — see above. Read-only. */
|
|
93
|
+
valid: boolean;
|
|
94
|
+
}
|
|
95
|
+
/** One row of `list`'s result — a Function's summary, not its full definition. */
|
|
96
|
+
export interface FunctionSummary {
|
|
97
|
+
id: string;
|
|
98
|
+
key: string;
|
|
99
|
+
displayName: string;
|
|
100
|
+
description: string;
|
|
101
|
+
updatedAt: string;
|
|
102
|
+
valid: boolean;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The `console.functions` namespace on a `W6wClient`.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* const fns = await client.console.functions.list();
|
|
110
|
+
* const fn = await client.console.functions.get(fns[0].id);
|
|
111
|
+
* await client.console.functions.upsert({ ...fn, description: "Send an email" });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare class FunctionsApi {
|
|
115
|
+
#private;
|
|
116
|
+
/**
|
|
117
|
+
* @param host - The client this namespace issues requests through.
|
|
118
|
+
*/
|
|
119
|
+
constructor(host: FunctionsHost);
|
|
120
|
+
/**
|
|
121
|
+
* List the caller's Function definitions.
|
|
122
|
+
*
|
|
123
|
+
* Each row already carries `valid` — server-computed
|
|
124
|
+
* (`db/repos/functions.ts`'s `list()`) — same as {@linkcode get}'s splice,
|
|
125
|
+
* but here it arrives already flat on the summary row, nothing to merge.
|
|
126
|
+
*
|
|
127
|
+
* @returns The Functions, unwrapped from the `functions` envelope.
|
|
128
|
+
*/
|
|
129
|
+
list(): Promise<FunctionSummary[]>;
|
|
130
|
+
/**
|
|
131
|
+
* Fetch one Function's stored definition.
|
|
132
|
+
*
|
|
133
|
+
* **`valid` is a TOP-LEVEL SIBLING of `function` on the wire, never spliced
|
|
134
|
+
* into the stored definition itself** (`admin/functions.ts:82-93`) — but
|
|
135
|
+
* this method DOES splice it into its own return value, for caller
|
|
136
|
+
* convenience: `{...body.function, valid: body.valid}`. This is a
|
|
137
|
+
* deliberate, behavior-preserving relocation of studio's own current
|
|
138
|
+
* `getFunction` (`client.ts:259-262`), not a redesign — a raw
|
|
139
|
+
* `{function, valid}` return would be a regression.
|
|
140
|
+
*
|
|
141
|
+
* No 404 special-casing — propagates as `ApiError` like every other "get"
|
|
142
|
+
* in this package except `console.schedules.get`'s documented exception.
|
|
143
|
+
*
|
|
144
|
+
* @param id - The `fn_…` id.
|
|
145
|
+
* @returns The Function definition with `valid` merged in at the top level.
|
|
146
|
+
* @throws {ApiError} `404 unknown_function` when there is no such id.
|
|
147
|
+
*/
|
|
148
|
+
get(id: string): Promise<FunctionDef>;
|
|
149
|
+
/**
|
|
150
|
+
* Register (create or overwrite) a Function definition.
|
|
151
|
+
*
|
|
152
|
+
* `definition` is the whole definition, sent verbatim as the request body —
|
|
153
|
+
* not wrapped in an envelope key.
|
|
154
|
+
*
|
|
155
|
+
* @param definition - The whole Function definition, forwarded verbatim.
|
|
156
|
+
* @returns The new/updated Function's id and key.
|
|
157
|
+
* @throws {ApiError} `400 invalid_function` — structurally invalid body.
|
|
158
|
+
* @throws {ApiError} `409 function_conflict` — another `(tenant,subject)` owns this id.
|
|
159
|
+
*/
|
|
160
|
+
upsert(definition: FunctionDef): Promise<{
|
|
161
|
+
id: string;
|
|
162
|
+
key: string;
|
|
163
|
+
}>;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=functions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../../src/console/functions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;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,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,uDAAuD;AACvD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,qFAAqF;IACrF,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,qBAAa,YAAY;;IAGvB;;OAEG;gBACS,IAAI,EAAE,aAAa;IAI/B;;;;;;;;OAQG;IACG,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAKxC;;;;;;;;;;;;;;;;;OAiBG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAQ3C;;;;;;;;;;OAUG;IACG,MAAM,CAAC,UAAU,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAQ5E"}
|