@tangle-network/hub-sdk 0.23.0-develop.20260814092444.5f93bc1 → 0.23.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 +136 -6
- package/dist/index.d.ts +639 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +506 -254
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
package/dist/index.js
CHANGED
|
@@ -1,7 +1,245 @@
|
|
|
1
1
|
import { SSEChunkParser } from "@tangle-network/sdk-telemetry";
|
|
2
|
+
//#region src/json-init.ts
|
|
3
|
+
/** The init of a request whose body is JSON. Every client builds its bodies
|
|
4
|
+
* here, so the content type cannot drift from the encoding. */
|
|
5
|
+
function jsonInit(method, body) {
|
|
6
|
+
return {
|
|
7
|
+
method,
|
|
8
|
+
body: JSON.stringify(body),
|
|
9
|
+
headers: { "Content-Type": "application/json" }
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/allowances.ts
|
|
14
|
+
var HubAllowancesClient = class {
|
|
15
|
+
constructor(request) {
|
|
16
|
+
this.request = request;
|
|
17
|
+
}
|
|
18
|
+
async plan(meter) {
|
|
19
|
+
return (await this.request(this.path(meter), { method: "GET" })).plan;
|
|
20
|
+
}
|
|
21
|
+
async setPlan(meter, plan) {
|
|
22
|
+
return (await this.request(this.path(meter), this.body("PUT", plan))).plan;
|
|
23
|
+
}
|
|
24
|
+
/** Admit one turn or refuse it. Retrying the same `turnId` never counts twice. */
|
|
25
|
+
async admit(meter, input) {
|
|
26
|
+
return (await this.request(`${this.path(meter)}/turns`, this.body("POST", input))).allowance;
|
|
27
|
+
}
|
|
28
|
+
/** What the member's next turn would get, without counting anything. */
|
|
29
|
+
async status(meter, subject) {
|
|
30
|
+
const query = new URLSearchParams();
|
|
31
|
+
if (subject.role) query.set("role", subject.role);
|
|
32
|
+
if (subject.payer) query.set("payer", subject.payer);
|
|
33
|
+
if (subject.payerRole) query.set("payerRole", subject.payerRole);
|
|
34
|
+
const suffix = query.size ? `?${query}` : "";
|
|
35
|
+
return (await this.request(`${this.memberPath(meter, subject.member)}${suffix}`, { method: "GET" })).allowance;
|
|
36
|
+
}
|
|
37
|
+
/** Move a member to the paid allowance until `expiresAt` (the paid period's end). */
|
|
38
|
+
async grant(meter, member, input) {
|
|
39
|
+
return (await this.request(`${this.memberPath(meter, member)}/grant`, this.body("PUT", {
|
|
40
|
+
tier: "paid",
|
|
41
|
+
...input
|
|
42
|
+
}))).grant;
|
|
43
|
+
}
|
|
44
|
+
/** Synchronize a paid grant by durable product revision. Null expiry writes
|
|
45
|
+
* a retained revocation. A delayed older update is refused, never reactivated.
|
|
46
|
+
* There is no fallback to the unversioned grant endpoint on older servers. */
|
|
47
|
+
async syncGrant(meter, member, input) {
|
|
48
|
+
const { grant } = await this.request(`${this.memberPath(meter, member)}/grant/sync`, this.body("PUT", input));
|
|
49
|
+
if (grant.member !== member || grant.source !== input.source || grant.revision !== input.revision || grant.reference !== input.reference || grant.expiresAt !== (input.expiresAt === null ? null : new Date(input.expiresAt).toISOString())) throw new Error("The Hub returned a mismatched grant synchronization receipt");
|
|
50
|
+
return grant;
|
|
51
|
+
}
|
|
52
|
+
async revoke(meter, member) {
|
|
53
|
+
await this.request(`${this.memberPath(meter, member)}/grant`, { method: "DELETE" });
|
|
54
|
+
}
|
|
55
|
+
/** Turns per member and per line on one UTC day (default today). */
|
|
56
|
+
async usage(meter, day) {
|
|
57
|
+
const suffix = day ? `?day=${encodeURIComponent(day)}` : "";
|
|
58
|
+
return (await this.request(`${this.path(meter)}/usage${suffix}`, { method: "GET" })).usage;
|
|
59
|
+
}
|
|
60
|
+
path(meter) {
|
|
61
|
+
return `/v1/hub/allowances/${encodeURIComponent(meter)}`;
|
|
62
|
+
}
|
|
63
|
+
memberPath(meter, member) {
|
|
64
|
+
return `${this.path(meter)}/members/${encodeURIComponent(member)}`;
|
|
65
|
+
}
|
|
66
|
+
body(method, body) {
|
|
67
|
+
return jsonInit(method, body);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/apps.ts
|
|
72
|
+
function encodedId(id) {
|
|
73
|
+
if (typeof id !== "string" || !id || id.length > 256 || id === "." || id === "..") throw new Error("A bounded app or grant id is required");
|
|
74
|
+
return encodeURIComponent(id);
|
|
75
|
+
}
|
|
76
|
+
var HubAppsClient = class {
|
|
77
|
+
grants;
|
|
78
|
+
constructor(request) {
|
|
79
|
+
this.request = request;
|
|
80
|
+
this.grants = {
|
|
81
|
+
list: () => this.request("/v1/me/app-grants", { method: "GET" }),
|
|
82
|
+
revoke: async (grantId) => this.request(`/v1/me/app-grants/${encodedId(grantId)}/revoke`, { method: "POST" })
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
list() {
|
|
86
|
+
return this.request("/v1/apps", { method: "GET" });
|
|
87
|
+
}
|
|
88
|
+
/** The secret is returned only by creation; keep it in your server vault. */
|
|
89
|
+
create(input) {
|
|
90
|
+
return this.request("/v1/apps", jsonInit("POST", input));
|
|
91
|
+
}
|
|
92
|
+
/** Immutable association of two existing records with the same owner. */
|
|
93
|
+
async linkOAuthClient(appId, clientId) {
|
|
94
|
+
return this.request(`/v1/apps/${encodedId(appId)}/oidc-client`, jsonInit("POST", { clientId }));
|
|
95
|
+
}
|
|
96
|
+
async revoke(appId) {
|
|
97
|
+
return this.request(`/v1/apps/${encodedId(appId)}/revoke`, { method: "POST" });
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/inbound-webhooks.ts
|
|
102
|
+
var HubInboundWebhooksClient = class {
|
|
103
|
+
constructor(request) {
|
|
104
|
+
this.request = request;
|
|
105
|
+
}
|
|
106
|
+
async create(connectionId, options = {}) {
|
|
107
|
+
return this.request(this.path(connectionId), jsonInit("POST", options));
|
|
108
|
+
}
|
|
109
|
+
async get(connectionId) {
|
|
110
|
+
return this.request(this.path(connectionId), { method: "GET" });
|
|
111
|
+
}
|
|
112
|
+
/** Add one owned Linq WhatsApp number without rotating the webhook secret. */
|
|
113
|
+
async ensurePhoneNumber(connectionId, phoneNumberId) {
|
|
114
|
+
if (!phoneNumberId || phoneNumberId.length > 128 || !/^[\x21-\x7e]+$/.test(phoneNumberId)) throw new Error("A bounded phone-number id is required");
|
|
115
|
+
return this.request(`${this.path(connectionId)}/phone-numbers/ensure`, jsonInit("POST", { phoneNumberId }));
|
|
116
|
+
}
|
|
117
|
+
/** Remove event subscriptions first. This does not silently rotate a live URL. */
|
|
118
|
+
async delete(connectionId) {
|
|
119
|
+
return this.request(this.path(connectionId), { method: "DELETE" });
|
|
120
|
+
}
|
|
121
|
+
path(connectionId) {
|
|
122
|
+
if (!connectionId || connectionId.length > 256) throw new Error("A bounded connection id is required");
|
|
123
|
+
return `/v1/hub/connections/${encodeURIComponent(connectionId)}/inbound-webhook`;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/lines.ts
|
|
128
|
+
/** Line calls share HubClient authentication and envelope handling. */
|
|
129
|
+
var HubLinesClient = class {
|
|
130
|
+
members;
|
|
131
|
+
checkins;
|
|
132
|
+
constructor(request, createWorkflow, requestApplicationDispatchCurrent) {
|
|
133
|
+
this.request = request;
|
|
134
|
+
this.createWorkflow = createWorkflow;
|
|
135
|
+
this.requestApplicationDispatchCurrent = requestApplicationDispatchCurrent;
|
|
136
|
+
this.members = { list: async (lineId) => (await this.request(`/v1/hub/lines/${encodeURIComponent(lineId)}/members`, { method: "GET" })).members };
|
|
137
|
+
this.checkins = { schedule: (cron, options) => {
|
|
138
|
+
const name = options.name ?? `line-checkin-${crypto.randomUUID().slice(0, 8)}`;
|
|
139
|
+
const yaml = [
|
|
140
|
+
`name: ${JSON.stringify(name)}`,
|
|
141
|
+
"on:",
|
|
142
|
+
` schedule: { cron: ${JSON.stringify(cron)}, timezone: ${JSON.stringify(options.timezone)} }`,
|
|
143
|
+
"do:",
|
|
144
|
+
" - agent.run:",
|
|
145
|
+
" line:",
|
|
146
|
+
` id: ${JSON.stringify(options.lineId)}`,
|
|
147
|
+
` member: ${JSON.stringify(options.member)}`,
|
|
148
|
+
` prompt: ${JSON.stringify(options.prompt)}`
|
|
149
|
+
].join("\n");
|
|
150
|
+
return this.createWorkflow(yaml);
|
|
151
|
+
} };
|
|
152
|
+
}
|
|
153
|
+
async scheduleSend(cron, options) {
|
|
154
|
+
const name = options.name ?? `line-send-${crypto.randomUUID().slice(0, 8)}`;
|
|
155
|
+
const yaml = [
|
|
156
|
+
`name: ${JSON.stringify(name)}`,
|
|
157
|
+
"on:",
|
|
158
|
+
` schedule: { cron: ${JSON.stringify(cron)}, timezone: ${JSON.stringify(options.timezone)} }`,
|
|
159
|
+
"do:",
|
|
160
|
+
" - line.send:",
|
|
161
|
+
` lineId: ${JSON.stringify(options.lineId)}`,
|
|
162
|
+
` memberId: ${JSON.stringify(options.memberId)}`,
|
|
163
|
+
` text: ${JSON.stringify(options.text)}`,
|
|
164
|
+
...options.notBefore ? [` notBefore: ${JSON.stringify(options.notBefore)}`] : []
|
|
165
|
+
].join("\n");
|
|
166
|
+
return this.createWorkflow(yaml);
|
|
167
|
+
}
|
|
168
|
+
async context() {
|
|
169
|
+
return this.request("/v1/hub/lines/context", { method: "GET" });
|
|
170
|
+
}
|
|
171
|
+
async send(lineId, input) {
|
|
172
|
+
return this.request(`/v1/hub/lines/${encodeURIComponent(lineId)}/send`, jsonInit("POST", input));
|
|
173
|
+
}
|
|
174
|
+
async remind(lineId, input) {
|
|
175
|
+
return this.request(`/v1/hub/lines/${encodeURIComponent(lineId)}/remind`, jsonInit("POST", input));
|
|
176
|
+
}
|
|
177
|
+
async applicationDispatchCurrent(lineId, messageId, input, callbackBearer) {
|
|
178
|
+
if (!this.requestApplicationDispatchCurrent) throw new Error("Use HubClient to check application dispatch authority");
|
|
179
|
+
return (await this.requestApplicationDispatchCurrent(`/v1/hub/lines/${encodeURIComponent(lineId)}/messages/${encodeURIComponent(messageId)}/application-dispatch/current`, jsonInit("POST", input), callbackBearer)).current;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region src/managed-numbers.ts
|
|
184
|
+
/** Administrative number operations through Hub's authenticated transport.
|
|
185
|
+
* A mutation is one attempt; an uncertain create reuses its quote and reference. */
|
|
186
|
+
var HubManagedNumbersClient = class {
|
|
187
|
+
constructor(request) {
|
|
188
|
+
this.request = request;
|
|
189
|
+
}
|
|
190
|
+
readiness() {
|
|
191
|
+
return this.request("/v1/hub/numbers/readiness", { method: "GET" });
|
|
192
|
+
}
|
|
193
|
+
/** One page of orders. Scope by `clientReference` to ask about one binding,
|
|
194
|
+
* and follow `nextCursor` for the rest; a page is never ownership evidence. */
|
|
195
|
+
list(query = {}) {
|
|
196
|
+
const params = new URLSearchParams();
|
|
197
|
+
if (query.clientReference !== void 0) params.set("clientReference", query.clientReference);
|
|
198
|
+
if (query.cursor !== void 0) params.set("cursor", query.cursor);
|
|
199
|
+
if (query.limit !== void 0) params.set("limit", String(query.limit));
|
|
200
|
+
const search = params.toString();
|
|
201
|
+
return this.request(`/v1/hub/numbers${search ? `?${search}` : ""}`, { method: "GET" });
|
|
202
|
+
}
|
|
203
|
+
get(id) {
|
|
204
|
+
return this.request(this.path(id), { method: "GET" });
|
|
205
|
+
}
|
|
206
|
+
quote(input) {
|
|
207
|
+
return this.request("/v1/hub/numbers/quote", this.post(input));
|
|
208
|
+
}
|
|
209
|
+
/** `clientReference` and `transport`, when given, must match the signed
|
|
210
|
+
* quote or Hub refuses the purchase with a conflict. */
|
|
211
|
+
create(input) {
|
|
212
|
+
return this.request("/v1/hub/numbers", this.post(input));
|
|
213
|
+
}
|
|
214
|
+
/** Fences references so no order can take them again. Call it as the last
|
|
215
|
+
* step before retiring the resource they name: a purchase that races the
|
|
216
|
+
* retirement is then refused (`409 number_reference_fenced`) instead of
|
|
217
|
+
* binding a line to a resource that is gone. Refused with
|
|
218
|
+
* `409 number_reference_held` while a live order holds one of them; cancel
|
|
219
|
+
* it first. A cancelled order no longer holds its reference, so the fence
|
|
220
|
+
* succeeds as soon as `cancel` returns, whether or not its release is still
|
|
221
|
+
* pending. Repeating a fence is harmless. */
|
|
222
|
+
fence(input) {
|
|
223
|
+
return this.request("/v1/hub/numbers/fences", this.post(input));
|
|
224
|
+
}
|
|
225
|
+
advance(id) {
|
|
226
|
+
return this.request(`${this.path(id)}/advance`, this.post({}));
|
|
227
|
+
}
|
|
228
|
+
cancel(id) {
|
|
229
|
+
return this.request(`${this.path(id)}/cancel`, this.post({}));
|
|
230
|
+
}
|
|
231
|
+
path(id) {
|
|
232
|
+
if (!/^num_[a-f0-9]{36}$/.test(id)) throw new Error("Invalid managed number order id");
|
|
233
|
+
return `/v1/hub/numbers/${encodeURIComponent(id)}`;
|
|
234
|
+
}
|
|
235
|
+
post(body) {
|
|
236
|
+
return jsonInit("POST", body);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
//#endregion
|
|
2
240
|
//#region src/redaction.ts
|
|
3
241
|
const SECRET_KEY_PATTERN = /(api[_-]?key|authorization|capability[_-]?token|token|secret)/i;
|
|
4
|
-
const SECRET_VALUE_PATTERN = /\b(?:sk-tan[-_]|hubcap_|hct_|gh[pousr]_)[A-Za-z0-9_
|
|
242
|
+
const SECRET_VALUE_PATTERN = /\b(?:sk-tan[-_]|hubcap_|hct_|lrc_|gh[pousr]_)[A-Za-z0-9_.=-]+\b/g;
|
|
5
243
|
function redactHubValue(value) {
|
|
6
244
|
if (typeof value === "string") return value.replace(SECRET_VALUE_PATTERN, "[REDACTED]");
|
|
7
245
|
if (Array.isArray(value)) return value.map((item) => redactHubValue(item));
|
|
@@ -26,16 +264,18 @@ function bodySnippet(body, max = 200) {
|
|
|
26
264
|
const trimmed = body.trim();
|
|
27
265
|
return trimmed.length > max ? `${trimmed.slice(0, max)}…` : trimmed;
|
|
28
266
|
}
|
|
29
|
-
function httpError(path, status, statusText, body, contentType) {
|
|
30
|
-
const suffix = statusText ? ` ${statusText}` : "";
|
|
267
|
+
function httpError(path, status, statusText, body, contentType, omitResponseDetails = false) {
|
|
268
|
+
const suffix = !omitResponseDetails && statusText ? ` ${statusText}` : "";
|
|
31
269
|
return new HubSdkError({
|
|
32
270
|
code: `HUB_HTTP_${status}`,
|
|
33
271
|
message: `Hub request ${path} failed: HTTP ${status}${suffix}`,
|
|
34
272
|
details: {
|
|
35
273
|
status,
|
|
36
274
|
path,
|
|
37
|
-
|
|
38
|
-
|
|
275
|
+
...omitResponseDetails ? {} : {
|
|
276
|
+
contentType: contentType || null,
|
|
277
|
+
bodySnippet: bodySnippet(body)
|
|
278
|
+
}
|
|
39
279
|
}
|
|
40
280
|
}, { status });
|
|
41
281
|
}
|
|
@@ -52,8 +292,13 @@ function isHubSuccessEnvelope(value) {
|
|
|
52
292
|
function isRecord$1(value) {
|
|
53
293
|
return typeof value === "object" && value !== null;
|
|
54
294
|
}
|
|
55
|
-
function
|
|
56
|
-
return
|
|
295
|
+
function isDispatchCurrentData(value) {
|
|
296
|
+
return isRecord$1(value) && typeof value.current === "boolean";
|
|
297
|
+
}
|
|
298
|
+
/** Read a wire field as a string, or "" when the server sent anything else.
|
|
299
|
+
* `raw` is that field straight off the parsed payload, before any check. */
|
|
300
|
+
function optString(raw) {
|
|
301
|
+
return typeof raw === "string" ? raw : "";
|
|
57
302
|
}
|
|
58
303
|
/** An agent iteration's terminal status (`iteration.ended`) — only ever
|
|
59
304
|
* succeeded/failed; an iteration is never guard-skipped. */
|
|
@@ -81,63 +326,63 @@ function isRunDoneStatus(value) {
|
|
|
81
326
|
* malformed `token` can never reach a consumer as `{ delta: undefined }`, and
|
|
82
327
|
* new server event kinds don't break older clients.
|
|
83
328
|
*/
|
|
84
|
-
function toRunStreamEvent(eventType,
|
|
329
|
+
function toRunStreamEvent(eventType, raw) {
|
|
85
330
|
if (eventType === "ping") return { type: "ping" };
|
|
86
|
-
if (!isRecord$1(
|
|
331
|
+
if (!isRecord$1(raw)) return null;
|
|
87
332
|
switch (eventType) {
|
|
88
|
-
case "snapshot": return typeof
|
|
333
|
+
case "snapshot": return typeof raw.id === "string" && typeof raw.workflowId === "string" && typeof raw.status === "string" && Array.isArray(raw.actionResults) ? {
|
|
89
334
|
type: "snapshot",
|
|
90
|
-
run:
|
|
335
|
+
run: raw
|
|
91
336
|
} : null;
|
|
92
|
-
case "token": return typeof
|
|
337
|
+
case "token": return typeof raw.delta === "string" && typeof raw.actionIndex === "number" ? {
|
|
93
338
|
type: "token",
|
|
94
|
-
actionIndex:
|
|
95
|
-
delta:
|
|
96
|
-
at: optString(
|
|
339
|
+
actionIndex: raw.actionIndex,
|
|
340
|
+
delta: raw.delta,
|
|
341
|
+
at: optString(raw.at)
|
|
97
342
|
} : null;
|
|
98
|
-
case "run.done": return isRunDoneStatus(
|
|
343
|
+
case "run.done": return isRunDoneStatus(raw.status) ? {
|
|
99
344
|
type: "run.done",
|
|
100
|
-
status:
|
|
101
|
-
error: typeof
|
|
102
|
-
...typeof
|
|
345
|
+
status: raw.status,
|
|
346
|
+
error: typeof raw.error === "string" ? raw.error : null,
|
|
347
|
+
...typeof raw.at === "string" ? { at: raw.at } : {}
|
|
103
348
|
} : null;
|
|
104
|
-
case "run.waiting": return typeof
|
|
349
|
+
case "run.waiting": return typeof raw.decisionId === "string" && raw.decisionId.length > 0 ? {
|
|
105
350
|
type: "run.waiting",
|
|
106
|
-
decisionId:
|
|
107
|
-
...typeof
|
|
351
|
+
decisionId: raw.decisionId,
|
|
352
|
+
...typeof raw.at === "string" ? { at: raw.at } : {}
|
|
108
353
|
} : null;
|
|
109
|
-
case "action.started": return typeof
|
|
354
|
+
case "action.started": return typeof raw.index === "number" && typeof raw.kind === "string" && typeof raw.at === "string" ? {
|
|
110
355
|
type: "action.started",
|
|
111
|
-
index:
|
|
112
|
-
kind:
|
|
113
|
-
at:
|
|
356
|
+
index: raw.index,
|
|
357
|
+
kind: raw.kind,
|
|
358
|
+
at: raw.at
|
|
114
359
|
} : null;
|
|
115
|
-
case "action.finished": return typeof
|
|
360
|
+
case "action.finished": return typeof raw.index === "number" && typeof raw.kind === "string" && isActionFinishedStatus(raw.status) && typeof raw.at === "string" ? {
|
|
116
361
|
type: "action.finished",
|
|
117
|
-
index:
|
|
118
|
-
kind:
|
|
119
|
-
status:
|
|
120
|
-
at:
|
|
121
|
-
...typeof
|
|
122
|
-
...typeof
|
|
362
|
+
index: raw.index,
|
|
363
|
+
kind: raw.kind,
|
|
364
|
+
status: raw.status,
|
|
365
|
+
at: raw.at,
|
|
366
|
+
...typeof raw.costUsd === "number" ? { costUsd: raw.costUsd } : {},
|
|
367
|
+
...typeof raw.error === "string" ? { error: raw.error } : {}
|
|
123
368
|
} : null;
|
|
124
|
-
case "iteration.started": return typeof
|
|
369
|
+
case "iteration.started": return typeof raw.actionIndex === "number" && typeof raw.iterationIndex === "number" && typeof raw.at === "string" ? {
|
|
125
370
|
type: "iteration.started",
|
|
126
|
-
actionIndex:
|
|
127
|
-
iterationIndex:
|
|
128
|
-
at:
|
|
129
|
-
...typeof
|
|
371
|
+
actionIndex: raw.actionIndex,
|
|
372
|
+
iterationIndex: raw.iterationIndex,
|
|
373
|
+
at: raw.at,
|
|
374
|
+
...typeof raw.model === "string" ? { model: raw.model } : {}
|
|
130
375
|
} : null;
|
|
131
|
-
case "iteration.ended": return typeof
|
|
376
|
+
case "iteration.ended": return typeof raw.actionIndex === "number" && typeof raw.iterationIndex === "number" && isIterationStatus(raw.status) && typeof raw.at === "string" ? {
|
|
132
377
|
type: "iteration.ended",
|
|
133
|
-
actionIndex:
|
|
134
|
-
iterationIndex:
|
|
135
|
-
status:
|
|
136
|
-
at:
|
|
137
|
-
...typeof
|
|
138
|
-
...typeof
|
|
139
|
-
...typeof
|
|
140
|
-
...typeof
|
|
378
|
+
actionIndex: raw.actionIndex,
|
|
379
|
+
iterationIndex: raw.iterationIndex,
|
|
380
|
+
status: raw.status,
|
|
381
|
+
at: raw.at,
|
|
382
|
+
...typeof raw.outputPreview === "string" ? { outputPreview: raw.outputPreview } : {},
|
|
383
|
+
...typeof raw.inputTokens === "number" ? { inputTokens: raw.inputTokens } : {},
|
|
384
|
+
...typeof raw.outputTokens === "number" ? { outputTokens: raw.outputTokens } : {},
|
|
385
|
+
...typeof raw.costUsd === "number" ? { costUsd: raw.costUsd } : {}
|
|
141
386
|
} : null;
|
|
142
387
|
default: return null;
|
|
143
388
|
}
|
|
@@ -145,8 +390,8 @@ function toRunStreamEvent(eventType, data) {
|
|
|
145
390
|
/** True for an aborted/timed-out fetch (or any abort). fetch rejects with the
|
|
146
391
|
* signal's reason — a DOMException named `AbortError` (caller) or `TimeoutError`
|
|
147
392
|
* (AbortSignal.timeout). */
|
|
148
|
-
function isAbortError(
|
|
149
|
-
return
|
|
393
|
+
function isAbortError(cause) {
|
|
394
|
+
return cause instanceof Error && (cause.name === "AbortError" || cause.name === "TimeoutError");
|
|
150
395
|
}
|
|
151
396
|
/** A signal that aborts when the caller's signal aborts OR `timeoutMs` elapses.
|
|
152
397
|
* Returns undefined when neither bound applies (no per-request abort needed). */
|
|
@@ -220,13 +465,68 @@ function nonEmpty(value) {
|
|
|
220
465
|
function readProcessEnv() {
|
|
221
466
|
return globalThis.process?.env ?? {};
|
|
222
467
|
}
|
|
223
|
-
var
|
|
468
|
+
var HubTransport = class {
|
|
224
469
|
baseUrl;
|
|
225
470
|
fetch;
|
|
226
471
|
apiKey;
|
|
227
472
|
authHeaders;
|
|
473
|
+
constructor(options) {
|
|
474
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
475
|
+
this.apiKey = options.apiKey;
|
|
476
|
+
this.authHeaders = options.authHeaders;
|
|
477
|
+
this.fetch = options.fetch ?? fetch.bind(globalThis);
|
|
478
|
+
}
|
|
479
|
+
async request(path, init, options = {}) {
|
|
480
|
+
const callerAuth = options.auth === "caller";
|
|
481
|
+
const response = await this.fetch(`${this.baseUrl}${path}`, {
|
|
482
|
+
...init,
|
|
483
|
+
headers: await this.buildHeaders(init.headers, callerAuth)
|
|
484
|
+
});
|
|
485
|
+
const status = response.status;
|
|
486
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
487
|
+
const bodyText = await response.text();
|
|
488
|
+
if (!contentType.includes("application/json")) throw httpError(path, status, response.statusText, bodyText, contentType, callerAuth);
|
|
489
|
+
let parsed;
|
|
490
|
+
try {
|
|
491
|
+
parsed = JSON.parse(bodyText);
|
|
492
|
+
} catch {
|
|
493
|
+
throw httpError(path, status, response.statusText, bodyText, contentType, callerAuth);
|
|
494
|
+
}
|
|
495
|
+
if (isHubErrorEnvelope(parsed)) {
|
|
496
|
+
if (callerAuth) throw new HubSdkError({
|
|
497
|
+
code: parsed.error.code,
|
|
498
|
+
message: `Hub request ${path} failed: HTTP ${status}`
|
|
499
|
+
}, { status });
|
|
500
|
+
throw new HubSdkError(parsed.error, { status });
|
|
501
|
+
}
|
|
502
|
+
if (isHubSuccessEnvelope(parsed)) {
|
|
503
|
+
if (callerAuth && !response.ok) throw httpError(path, status, response.statusText, bodyText, contentType, callerAuth);
|
|
504
|
+
if (options.validateData && !options.validateData(parsed.data)) throw new HubSdkError({
|
|
505
|
+
code: `HUB_HTTP_${status}`,
|
|
506
|
+
message: `Hub request ${path} returned invalid data`,
|
|
507
|
+
details: {
|
|
508
|
+
status,
|
|
509
|
+
path
|
|
510
|
+
}
|
|
511
|
+
}, { status });
|
|
512
|
+
return parsed.data;
|
|
513
|
+
}
|
|
514
|
+
throw httpError(path, status, response.statusText, bodyText, contentType, callerAuth);
|
|
515
|
+
}
|
|
516
|
+
async buildHeaders(headers, callerAuth = false) {
|
|
517
|
+
const mergedHeaders = new Headers({ Accept: "application/json" });
|
|
518
|
+
if (!callerAuth && this.apiKey) mergedHeaders.set("Authorization", `Bearer ${this.apiKey}`);
|
|
519
|
+
if (!callerAuth && this.authHeaders) for (const [key, value] of new Headers(await this.authHeaders())) mergedHeaders.set(key, value);
|
|
520
|
+
for (const [key, value] of new Headers(headers)) mergedHeaders.set(key, value);
|
|
521
|
+
return mergedHeaders;
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
var HubClient = class HubClient extends HubTransport {
|
|
525
|
+
allowances;
|
|
526
|
+
apps;
|
|
228
527
|
connections;
|
|
229
528
|
channels;
|
|
529
|
+
numbers;
|
|
230
530
|
eventSubscriptions;
|
|
231
531
|
permissions;
|
|
232
532
|
tokens;
|
|
@@ -235,11 +535,12 @@ var HubClient = class HubClient {
|
|
|
235
535
|
audit;
|
|
236
536
|
githubApp;
|
|
237
537
|
workflows;
|
|
538
|
+
lines;
|
|
238
539
|
constructor(options) {
|
|
239
|
-
|
|
240
|
-
this.
|
|
241
|
-
this.
|
|
242
|
-
this.
|
|
540
|
+
super(options);
|
|
541
|
+
this.allowances = new HubAllowancesClient((path, init) => this.request(path, init));
|
|
542
|
+
this.apps = new HubAppsClient((path, init) => this.request(path, init));
|
|
543
|
+
this.numbers = new HubManagedNumbersClient((path, init) => this.request(path, init));
|
|
243
544
|
this.connections = new HubConnectionsClient((path, init) => this.request(path, init));
|
|
244
545
|
this.channels = new HubChannelsClient((path, init) => this.request(path, init));
|
|
245
546
|
this.eventSubscriptions = new HubEventSubscriptionsClient((path, init) => this.request(path, init));
|
|
@@ -250,6 +551,23 @@ var HubClient = class HubClient {
|
|
|
250
551
|
this.audit = new HubAuditClient((path, init) => this.request(path, init));
|
|
251
552
|
this.githubApp = new HubGithubAppClient((path, init) => this.request(path, init));
|
|
252
553
|
this.workflows = new HubWorkflowsClient((path, init) => this.request(path, init), (path, init) => this.stream(path, init), (path, init) => this.requestBytes(path, init));
|
|
554
|
+
this.lines = new HubLinesClient((path, init) => this.request(path, init), (yaml) => this.workflows.create(yaml), (path, init, callbackBearer) => {
|
|
555
|
+
if (typeof callbackBearer !== "string" || !/^[\x21-\x7e]{16,512}$/.test(callbackBearer)) throw new HubSdkError({
|
|
556
|
+
code: "HUB_INVALID_INPUT",
|
|
557
|
+
message: "Application callback bearer is invalid"
|
|
558
|
+
});
|
|
559
|
+
const headers = new Headers(init.headers);
|
|
560
|
+
headers.set("Authorization", `Bearer ${callbackBearer}`);
|
|
561
|
+
return this.request(path, {
|
|
562
|
+
...init,
|
|
563
|
+
headers,
|
|
564
|
+
credentials: "omit",
|
|
565
|
+
redirect: "manual"
|
|
566
|
+
}, {
|
|
567
|
+
auth: "caller",
|
|
568
|
+
validateData: isDispatchCurrentData
|
|
569
|
+
});
|
|
570
|
+
});
|
|
253
571
|
}
|
|
254
572
|
static fromEnv(options = {}) {
|
|
255
573
|
const env = options.env ?? readProcessEnv();
|
|
@@ -263,25 +581,6 @@ var HubClient = class HubClient {
|
|
|
263
581
|
async status() {
|
|
264
582
|
return this.request("/v1/hub/status", { method: "GET" });
|
|
265
583
|
}
|
|
266
|
-
async request(path, init) {
|
|
267
|
-
const response = await this.fetch(`${this.baseUrl}${path}`, {
|
|
268
|
-
...init,
|
|
269
|
-
headers: await this.buildHeaders(init.headers)
|
|
270
|
-
});
|
|
271
|
-
const status = response.status;
|
|
272
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
273
|
-
const bodyText = await response.text();
|
|
274
|
-
if (!contentType.includes("application/json")) throw httpError(path, status, response.statusText, bodyText, contentType);
|
|
275
|
-
let parsed;
|
|
276
|
-
try {
|
|
277
|
-
parsed = JSON.parse(bodyText);
|
|
278
|
-
} catch {
|
|
279
|
-
throw httpError(path, status, response.statusText, bodyText, contentType);
|
|
280
|
-
}
|
|
281
|
-
if (isHubErrorEnvelope(parsed)) throw new HubSdkError(parsed.error, { status });
|
|
282
|
-
if (isHubSuccessEnvelope(parsed)) return parsed.data;
|
|
283
|
-
throw httpError(path, status, response.statusText, bodyText, contentType);
|
|
284
|
-
}
|
|
285
584
|
/**
|
|
286
585
|
* Open a streaming (Server-Sent Events) response and return its raw body.
|
|
287
586
|
* Shares auth-header building + `fetch` with {@link request}, but does NOT
|
|
@@ -348,25 +647,13 @@ var HubClient = class HubClient {
|
|
|
348
647
|
contentType
|
|
349
648
|
};
|
|
350
649
|
}
|
|
351
|
-
async buildHeaders(headers) {
|
|
352
|
-
const mergedHeaders = new Headers(headers);
|
|
353
|
-
if (!mergedHeaders.has("Accept")) mergedHeaders.set("Accept", "application/json");
|
|
354
|
-
if (this.apiKey) mergedHeaders.set("Authorization", `Bearer ${this.apiKey}`);
|
|
355
|
-
if (this.authHeaders) for (const [key, value] of new Headers(await this.authHeaders())) mergedHeaders.set(key, value);
|
|
356
|
-
for (const [key, value] of new Headers(headers)) mergedHeaders.set(key, value);
|
|
357
|
-
return mergedHeaders;
|
|
358
|
-
}
|
|
359
650
|
};
|
|
360
651
|
var HubTokensClient = class {
|
|
361
652
|
constructor(request) {
|
|
362
653
|
this.request = request;
|
|
363
654
|
}
|
|
364
655
|
async mint(options) {
|
|
365
|
-
return this.request("/v1/hub/tokens",
|
|
366
|
-
method: "POST",
|
|
367
|
-
body: JSON.stringify(options),
|
|
368
|
-
headers: { "Content-Type": "application/json" }
|
|
369
|
-
});
|
|
656
|
+
return this.request("/v1/hub/tokens", jsonInit("POST", options));
|
|
370
657
|
}
|
|
371
658
|
async list(options = {}) {
|
|
372
659
|
const searchParams = new URLSearchParams();
|
|
@@ -400,38 +687,22 @@ var HubPermissionsClient = class {
|
|
|
400
687
|
return this.request(`/v1/hub/policies?connectionId=${encodeURIComponent(connectionId)}`, { method: "GET" });
|
|
401
688
|
}
|
|
402
689
|
async set(input) {
|
|
403
|
-
return this.request("/v1/hub/policies",
|
|
404
|
-
method: "PUT",
|
|
405
|
-
body: JSON.stringify(input),
|
|
406
|
-
headers: { "Content-Type": "application/json" }
|
|
407
|
-
});
|
|
690
|
+
return this.request("/v1/hub/policies", jsonInit("PUT", input));
|
|
408
691
|
}
|
|
409
692
|
/** Reset an action to its default by deleting any stored override. */
|
|
410
693
|
async delete(input) {
|
|
411
|
-
return this.request("/v1/hub/policies",
|
|
412
|
-
method: "DELETE",
|
|
413
|
-
body: JSON.stringify(input),
|
|
414
|
-
headers: { "Content-Type": "application/json" }
|
|
415
|
-
});
|
|
694
|
+
return this.request("/v1/hub/policies", jsonInit("DELETE", input));
|
|
416
695
|
}
|
|
417
696
|
/** Bulk-allow every write action of a connection's provider. Reads are
|
|
418
697
|
* already allowed for sandbox agents; destructive actions stay `ask`.
|
|
419
698
|
* Idempotent: actions with an existing policy are left untouched. */
|
|
420
699
|
async allowWrites(connectionId) {
|
|
421
|
-
return this.request("/v1/hub/policies/allow-writes", {
|
|
422
|
-
method: "POST",
|
|
423
|
-
body: JSON.stringify({ connectionId }),
|
|
424
|
-
headers: { "Content-Type": "application/json" }
|
|
425
|
-
});
|
|
700
|
+
return this.request("/v1/hub/policies/allow-writes", jsonInit("POST", { connectionId }));
|
|
426
701
|
}
|
|
427
702
|
/** Inverse of `allowWrites`: delete only the rows it created for this
|
|
428
703
|
* connection. Manual per-action decisions are left intact. */
|
|
429
704
|
async revertWrites(connectionId) {
|
|
430
|
-
return this.request("/v1/hub/policies/revert-writes", {
|
|
431
|
-
method: "POST",
|
|
432
|
-
body: JSON.stringify({ connectionId }),
|
|
433
|
-
headers: { "Content-Type": "application/json" }
|
|
434
|
-
});
|
|
705
|
+
return this.request("/v1/hub/policies/revert-writes", jsonInit("POST", { connectionId }));
|
|
435
706
|
}
|
|
436
707
|
};
|
|
437
708
|
var HubToolsClient = class {
|
|
@@ -439,34 +710,32 @@ var HubToolsClient = class {
|
|
|
439
710
|
this.request = request;
|
|
440
711
|
}
|
|
441
712
|
async search(query, options = {}) {
|
|
442
|
-
return this.request("/v1/hub/tools/search", {
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
limit: options.limit
|
|
448
|
-
}),
|
|
449
|
-
headers: { "Content-Type": "application/json" }
|
|
450
|
-
});
|
|
713
|
+
return this.request("/v1/hub/tools/search", jsonInit("POST", {
|
|
714
|
+
query,
|
|
715
|
+
provider: options.provider,
|
|
716
|
+
limit: options.limit
|
|
717
|
+
}));
|
|
451
718
|
}
|
|
452
719
|
async sources() {
|
|
453
720
|
return this.request("/v1/hub/tools/sources", { method: "GET" });
|
|
454
721
|
}
|
|
455
722
|
async describe(path) {
|
|
456
|
-
return this.request("/v1/hub/tools/describe", {
|
|
457
|
-
method: "POST",
|
|
458
|
-
body: JSON.stringify({ path }),
|
|
459
|
-
headers: { "Content-Type": "application/json" }
|
|
460
|
-
});
|
|
723
|
+
return this.request("/v1/hub/tools/describe", jsonInit("POST", { path }));
|
|
461
724
|
}
|
|
462
|
-
|
|
463
|
-
|
|
725
|
+
/**
|
|
726
|
+
* Run one hub tool. `raw` is the tool input: the SDK forwards it verbatim as
|
|
727
|
+
* the request body's `input`, and the server validates it against the tool's
|
|
728
|
+
* own schema, so the client never gives it a shape.
|
|
729
|
+
*/
|
|
730
|
+
async invoke(path, raw, options = {}) {
|
|
731
|
+
const execInit = this.buildExecInit(path, raw, options);
|
|
464
732
|
try {
|
|
465
733
|
return await this.request("/v1/hub/exec", execInit);
|
|
466
734
|
} catch (error) {
|
|
467
735
|
if (!(error instanceof HubSdkError) || !requiresCapabilityToken(error)) throw error;
|
|
736
|
+
const approvalId = getApprovalId(error);
|
|
737
|
+
if (approvalId && options.approve !== true) throw error;
|
|
468
738
|
if (options.approve) {
|
|
469
|
-
const approvalId = getApprovalId(error);
|
|
470
739
|
if (!approvalId) throw error;
|
|
471
740
|
const approved = await this.request(`/v1/hub/approvals/${encodeURIComponent(approvalId)}/approve`, { method: "POST" });
|
|
472
741
|
validateApprovedExecution(approved, path, options.connectionId);
|
|
@@ -484,15 +753,11 @@ var HubToolsClient = class {
|
|
|
484
753
|
});
|
|
485
754
|
}
|
|
486
755
|
}
|
|
487
|
-
const minted = await this.request("/v1/hub/tokens", {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
provider: options.connectionId ? void 0 : path.split(".")[0]
|
|
493
|
-
}),
|
|
494
|
-
headers: { "Content-Type": "application/json" }
|
|
495
|
-
});
|
|
756
|
+
const minted = await this.request("/v1/hub/tokens", jsonInit("POST", {
|
|
757
|
+
actionPath: path,
|
|
758
|
+
connectionId: options.connectionId,
|
|
759
|
+
provider: options.connectionId ? void 0 : path.split(".")[0]
|
|
760
|
+
}));
|
|
496
761
|
return this.request("/v1/hub/exec", {
|
|
497
762
|
...execInit,
|
|
498
763
|
headers: {
|
|
@@ -501,16 +766,13 @@ var HubToolsClient = class {
|
|
|
501
766
|
}
|
|
502
767
|
});
|
|
503
768
|
}
|
|
504
|
-
buildExecInit(path,
|
|
505
|
-
return {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
}),
|
|
512
|
-
headers: { "Content-Type": "application/json" }
|
|
513
|
-
};
|
|
769
|
+
buildExecInit(path, raw, options) {
|
|
770
|
+
return jsonInit("POST", {
|
|
771
|
+
path,
|
|
772
|
+
input: raw,
|
|
773
|
+
connectionId: options.connectionId,
|
|
774
|
+
idempotencyKey: options.idempotencyKey
|
|
775
|
+
});
|
|
514
776
|
}
|
|
515
777
|
};
|
|
516
778
|
function requiresCapabilityToken(error) {
|
|
@@ -540,6 +802,17 @@ function validateApprovedExecution(approved, path, connectionId) {
|
|
|
540
802
|
}
|
|
541
803
|
});
|
|
542
804
|
}
|
|
805
|
+
const GITHUB_EXACT_CONNECT_SCOPES = [
|
|
806
|
+
"read:user",
|
|
807
|
+
"repo",
|
|
808
|
+
"read:org"
|
|
809
|
+
];
|
|
810
|
+
function sameOAuthScopeSet(left, right) {
|
|
811
|
+
if (!Array.isArray(left)) return false;
|
|
812
|
+
const leftSet = new Set(left);
|
|
813
|
+
const rightSet = new Set(right);
|
|
814
|
+
return leftSet.size === left.length && rightSet.size === right.length && leftSet.size === rightSet.size && [...leftSet].every((scope) => rightSet.has(scope));
|
|
815
|
+
}
|
|
543
816
|
var HubChannelsClient = class {
|
|
544
817
|
constructor(request) {
|
|
545
818
|
this.request = request;
|
|
@@ -548,11 +821,7 @@ var HubChannelsClient = class {
|
|
|
548
821
|
return this.request("/v1/hub/channels", { method: "GET" });
|
|
549
822
|
}
|
|
550
823
|
async createEmail(input = {}) {
|
|
551
|
-
return this.request("/v1/hub/channels/email",
|
|
552
|
-
method: "POST",
|
|
553
|
-
body: JSON.stringify(input),
|
|
554
|
-
headers: { "Content-Type": "application/json" }
|
|
555
|
-
});
|
|
824
|
+
return this.request("/v1/hub/channels/email", jsonInit("POST", input));
|
|
556
825
|
}
|
|
557
826
|
async delete(channelId) {
|
|
558
827
|
return this.request(`/v1/hub/channels/${encodeURIComponent(channelId)}`, { method: "DELETE" });
|
|
@@ -566,19 +835,17 @@ var HubEventSubscriptionsClient = class {
|
|
|
566
835
|
return this.request("/v1/hub/event-subscriptions", { method: "GET" });
|
|
567
836
|
}
|
|
568
837
|
async create(input) {
|
|
569
|
-
return this.request("/v1/hub/event-subscriptions",
|
|
570
|
-
method: "POST",
|
|
571
|
-
body: JSON.stringify(input),
|
|
572
|
-
headers: { "Content-Type": "application/json" }
|
|
573
|
-
});
|
|
838
|
+
return this.request("/v1/hub/event-subscriptions", jsonInit("POST", input));
|
|
574
839
|
}
|
|
575
840
|
async delete(subscriptionId) {
|
|
576
841
|
return this.request(`/v1/hub/event-subscriptions/${encodeURIComponent(subscriptionId)}`, { method: "DELETE" });
|
|
577
842
|
}
|
|
578
843
|
};
|
|
579
844
|
var HubConnectionsClient = class {
|
|
845
|
+
inboundWebhook;
|
|
580
846
|
constructor(request) {
|
|
581
847
|
this.request = request;
|
|
848
|
+
this.inboundWebhook = new HubInboundWebhooksClient(request);
|
|
582
849
|
}
|
|
583
850
|
async list() {
|
|
584
851
|
return this.request("/v1/hub/connections", { method: "GET" });
|
|
@@ -590,40 +857,38 @@ var HubConnectionsClient = class {
|
|
|
590
857
|
return this.request("/v1/hub/providers", { method: "GET" });
|
|
591
858
|
}
|
|
592
859
|
async start(provider, options = {}) {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
returnUrl: options.returnUrl,
|
|
597
|
-
cli: options.cli,
|
|
598
|
-
connectionParameters: options.connectionParameters
|
|
599
|
-
}),
|
|
600
|
-
headers: { "Content-Type": "application/json" }
|
|
860
|
+
if (options.requestedScopes !== void 0 && (provider !== "github" || !sameOAuthScopeSet(options.requestedScopes, GITHUB_EXACT_CONNECT_SCOPES))) throw new HubSdkError({
|
|
861
|
+
code: "HUB_INVALID_INPUT",
|
|
862
|
+
message: "GitHub requestedScopes must be read:user, repo, and read:org"
|
|
601
863
|
});
|
|
864
|
+
const started = await this.request(`/v1/hub/connections/${encodeURIComponent(provider)}/start`, jsonInit("POST", {
|
|
865
|
+
returnUrl: options.returnUrl,
|
|
866
|
+
cli: options.cli,
|
|
867
|
+
connectionParameters: options.connectionParameters,
|
|
868
|
+
requestedScopes: options.requestedScopes
|
|
869
|
+
}));
|
|
870
|
+
if (options.requestedScopes !== void 0 && (started.provider !== provider || !sameOAuthScopeSet(started.scopes, options.requestedScopes))) throw new HubSdkError({
|
|
871
|
+
code: "HUB_CONFIG_MISSING",
|
|
872
|
+
message: "Hub did not preserve the requested OAuth scopes"
|
|
873
|
+
});
|
|
874
|
+
return started;
|
|
602
875
|
}
|
|
603
876
|
async startWhatsappEmbeddedSignup(options = {}) {
|
|
604
|
-
return this.request("/v1/hub/connections/whatsapp-business/embedded-signup/start", {
|
|
605
|
-
method: "POST",
|
|
606
|
-
body: JSON.stringify({ returnUrl: options.returnUrl }),
|
|
607
|
-
headers: { "Content-Type": "application/json" }
|
|
608
|
-
});
|
|
877
|
+
return this.request("/v1/hub/connections/whatsapp-business/embedded-signup/start", jsonInit("POST", { returnUrl: options.returnUrl }));
|
|
609
878
|
}
|
|
610
879
|
async completeWhatsappEmbeddedSignup(input) {
|
|
611
|
-
return this.request("/v1/hub/connections/whatsapp-business/embedded-signup/complete",
|
|
612
|
-
method: "POST",
|
|
613
|
-
body: JSON.stringify(input),
|
|
614
|
-
headers: { "Content-Type": "application/json" }
|
|
615
|
-
});
|
|
880
|
+
return this.request("/v1/hub/connections/whatsapp-business/embedded-signup/complete", jsonInit("POST", input));
|
|
616
881
|
}
|
|
617
882
|
/** Connect a non-OAuth (api-key) connector by submitting the user's key.
|
|
618
883
|
* The server validates the key with a live probe before persisting and
|
|
619
884
|
* returns the created (or reconnected) connection — there is no redirect,
|
|
620
|
-
* unlike `start`.
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
});
|
|
885
|
+
* unlike `start`. Cloudbeds requires propertyId metadata and PriceLabs
|
|
886
|
+
* requires listing ID/PMS pairs; other providers have no metadata. */
|
|
887
|
+
async connectApiKey(provider, apiKey, metadata) {
|
|
888
|
+
return this.request(`/v1/hub/connections/${encodeURIComponent(provider)}/connect-key`, jsonInit("POST", {
|
|
889
|
+
apiKey,
|
|
890
|
+
...metadata === void 0 ? {} : { metadata }
|
|
891
|
+
}));
|
|
627
892
|
}
|
|
628
893
|
async revoke(connectionId) {
|
|
629
894
|
return this.request(`/v1/hub/connections/${encodeURIComponent(connectionId)}`, { method: "DELETE" });
|
|
@@ -651,11 +916,7 @@ var HubGithubAppClient = class {
|
|
|
651
916
|
this.request = request;
|
|
652
917
|
}
|
|
653
918
|
async mintInstallationToken(input) {
|
|
654
|
-
return this.request("/v1/hub/github-app/mint-installation-token",
|
|
655
|
-
method: "POST",
|
|
656
|
-
body: JSON.stringify(input),
|
|
657
|
-
headers: { "Content-Type": "application/json" }
|
|
658
|
-
});
|
|
919
|
+
return this.request("/v1/hub/github-app/mint-installation-token", jsonInit("POST", input));
|
|
659
920
|
}
|
|
660
921
|
/** Every installation the caller may act through — their own and any org's
|
|
661
922
|
* they were verified against. The management surface's read. */
|
|
@@ -730,11 +991,7 @@ var HubWorkflowsClient = class {
|
|
|
730
991
|
return this.request(`/v1/workflows/${encodeURIComponent(id)}`, { method: "GET" });
|
|
731
992
|
}
|
|
732
993
|
async create(yaml) {
|
|
733
|
-
return this.request("/v1/workflows", {
|
|
734
|
-
method: "POST",
|
|
735
|
-
body: JSON.stringify({ yaml }),
|
|
736
|
-
headers: { "Content-Type": "application/json" }
|
|
737
|
-
});
|
|
994
|
+
return this.request("/v1/workflows", jsonInit("POST", { yaml }));
|
|
738
995
|
}
|
|
739
996
|
/**
|
|
740
997
|
* Replace the workflow's definition from YAML (recompiled server-side,
|
|
@@ -745,14 +1002,10 @@ var HubWorkflowsClient = class {
|
|
|
745
1002
|
* concurrent modification, `NOT_FOUND` for an unknown/foreign id.
|
|
746
1003
|
*/
|
|
747
1004
|
async update(id, yaml, opts = {}) {
|
|
748
|
-
return this.request(`/v1/workflows/${encodeURIComponent(id)}`, {
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
...opts.note !== void 0 ? { note: opts.note } : {}
|
|
753
|
-
}),
|
|
754
|
-
headers: { "Content-Type": "application/json" }
|
|
755
|
-
});
|
|
1005
|
+
return this.request(`/v1/workflows/${encodeURIComponent(id)}`, jsonInit("PUT", {
|
|
1006
|
+
yaml,
|
|
1007
|
+
...opts.note !== void 0 ? { note: opts.note } : {}
|
|
1008
|
+
}));
|
|
756
1009
|
}
|
|
757
1010
|
async delete(id) {
|
|
758
1011
|
await this.request(`/v1/workflows/${encodeURIComponent(id)}`, { method: "DELETE" });
|
|
@@ -763,11 +1016,7 @@ var HubWorkflowsClient = class {
|
|
|
763
1016
|
* via `update`, but it can still be paused/resumed here).
|
|
764
1017
|
*/
|
|
765
1018
|
async setEnabled(id, enabled) {
|
|
766
|
-
return this.request(`/v1/workflows/${encodeURIComponent(id)}`, {
|
|
767
|
-
method: "PATCH",
|
|
768
|
-
body: JSON.stringify({ enabled }),
|
|
769
|
-
headers: { "Content-Type": "application/json" }
|
|
770
|
-
});
|
|
1019
|
+
return this.request(`/v1/workflows/${encodeURIComponent(id)}`, jsonInit("PATCH", { enabled }));
|
|
771
1020
|
}
|
|
772
1021
|
/**
|
|
773
1022
|
* One page of run history, newest first. Pass the previous page's
|
|
@@ -795,9 +1044,7 @@ var HubWorkflowsClient = class {
|
|
|
795
1044
|
async run(id, inputs, opts = {}) {
|
|
796
1045
|
const hasInputs = inputs !== void 0 && Object.keys(inputs).length > 0;
|
|
797
1046
|
return this.request(`/v1/workflows/${encodeURIComponent(id)}/run`, {
|
|
798
|
-
|
|
799
|
-
body: JSON.stringify(hasInputs ? { inputs } : {}),
|
|
800
|
-
headers: { "Content-Type": "application/json" },
|
|
1047
|
+
...jsonInit("POST", hasInputs ? { inputs } : {}),
|
|
801
1048
|
...opts.signal ? { signal: opts.signal } : {}
|
|
802
1049
|
});
|
|
803
1050
|
}
|
|
@@ -976,11 +1223,7 @@ var HubWorkflowsClient = class {
|
|
|
976
1223
|
* YAML no longer compiles, `CONFLICT` on a concurrent modification.
|
|
977
1224
|
*/
|
|
978
1225
|
async rollback(id, rev) {
|
|
979
|
-
return this.request(`/v1/workflows/${encodeURIComponent(id)}/rollback`, {
|
|
980
|
-
method: "POST",
|
|
981
|
-
body: JSON.stringify({ rev }),
|
|
982
|
-
headers: { "Content-Type": "application/json" }
|
|
983
|
-
});
|
|
1226
|
+
return this.request(`/v1/workflows/${encodeURIComponent(id)}/rollback`, jsonInit("POST", { rev }));
|
|
984
1227
|
}
|
|
985
1228
|
/**
|
|
986
1229
|
* Deterministic health stats over the workflow's last N terminal runs
|
|
@@ -1001,11 +1244,7 @@ var HubWorkflowsClient = class {
|
|
|
1001
1244
|
* until an owner approves.
|
|
1002
1245
|
*/
|
|
1003
1246
|
async propose(id, input) {
|
|
1004
|
-
return this.request(`/v1/workflows/${encodeURIComponent(id)}/proposals`,
|
|
1005
|
-
method: "POST",
|
|
1006
|
-
body: JSON.stringify(input),
|
|
1007
|
-
headers: { "Content-Type": "application/json" }
|
|
1008
|
-
});
|
|
1247
|
+
return this.request(`/v1/workflows/${encodeURIComponent(id)}/proposals`, jsonInit("POST", input));
|
|
1009
1248
|
}
|
|
1010
1249
|
/**
|
|
1011
1250
|
* Pending (proposed) and declined (rejected) revisions, newest first, with
|
|
@@ -1032,11 +1271,7 @@ var HubWorkflowsClient = class {
|
|
|
1032
1271
|
* pending proposal.
|
|
1033
1272
|
*/
|
|
1034
1273
|
async rejectProposal(id, rev, opts = {}) {
|
|
1035
|
-
return this.request(`/v1/workflows/${encodeURIComponent(id)}/proposals/${encodeURIComponent(String(rev))}/reject`, {
|
|
1036
|
-
method: "POST",
|
|
1037
|
-
body: JSON.stringify(opts.reason !== void 0 ? { reason: opts.reason } : {}),
|
|
1038
|
-
headers: { "Content-Type": "application/json" }
|
|
1039
|
-
});
|
|
1274
|
+
return this.request(`/v1/workflows/${encodeURIComponent(id)}/proposals/${encodeURIComponent(String(rev))}/reject`, jsonInit("POST", opts.reason !== void 0 ? { reason: opts.reason } : {}));
|
|
1040
1275
|
}
|
|
1041
1276
|
/**
|
|
1042
1277
|
* Mint a fresh webhook hook token, retiring the current one immediately.
|
|
@@ -1112,29 +1347,24 @@ var HubWorkflowsClient = class {
|
|
|
1112
1347
|
/**
|
|
1113
1348
|
* Upsert a key; returns the entry with its NEW version (increments on every
|
|
1114
1349
|
* write). Throws `HubSdkError(KV_VALUE_TOO_LARGE)` past the 64KiB value cap
|
|
1115
|
-
* or `KV_KEY_LIMIT` past the per-workflow key cap.
|
|
1350
|
+
* or `KV_KEY_LIMIT` past the per-workflow key cap. `raw` is the caller's
|
|
1351
|
+
* value, stored and read back verbatim, so the client never gives it a shape.
|
|
1116
1352
|
*/
|
|
1117
|
-
async putKv(id, key,
|
|
1118
|
-
return this.request(`/v1/workflows/${encodeURIComponent(id)}/kv/${encodeURIComponent(key)}`, {
|
|
1119
|
-
method: "PUT",
|
|
1120
|
-
body: JSON.stringify({ value }),
|
|
1121
|
-
headers: { "Content-Type": "application/json" }
|
|
1122
|
-
});
|
|
1353
|
+
async putKv(id, key, raw) {
|
|
1354
|
+
return this.request(`/v1/workflows/${encodeURIComponent(id)}/kv/${encodeURIComponent(key)}`, jsonInit("PUT", { value: raw }));
|
|
1123
1355
|
}
|
|
1124
1356
|
/**
|
|
1125
1357
|
* Compare-and-swap: the write lands only when the stored version still
|
|
1126
1358
|
* equals `expectedVersion`; otherwise `HubSdkError(KV_VERSION_CONFLICT)`
|
|
1127
|
-
* (409) — re-read and retry. Creation is {@link putKv}'s job.
|
|
1359
|
+
* (409) — re-read and retry. Creation is {@link putKv}'s job. `raw` is the
|
|
1360
|
+
* caller's value, stored and read back verbatim, so the client never gives it
|
|
1361
|
+
* a shape.
|
|
1128
1362
|
*/
|
|
1129
|
-
async casKv(id, key, expectedVersion,
|
|
1130
|
-
return this.request(`/v1/workflows/${encodeURIComponent(id)}/kv/${encodeURIComponent(key)}/cas`, {
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
value
|
|
1135
|
-
}),
|
|
1136
|
-
headers: { "Content-Type": "application/json" }
|
|
1137
|
-
});
|
|
1363
|
+
async casKv(id, key, expectedVersion, raw) {
|
|
1364
|
+
return this.request(`/v1/workflows/${encodeURIComponent(id)}/kv/${encodeURIComponent(key)}/cas`, jsonInit("POST", {
|
|
1365
|
+
expectedVersion,
|
|
1366
|
+
value: raw
|
|
1367
|
+
}));
|
|
1138
1368
|
}
|
|
1139
1369
|
/** Delete a key; idempotent — `deleted` reports whether a row was removed. */
|
|
1140
1370
|
async deleteKv(id, key) {
|
|
@@ -1154,11 +1384,7 @@ var HubWorkflowsClient = class {
|
|
|
1154
1384
|
* (400); an unknown template id throws `NOT_FOUND`.
|
|
1155
1385
|
*/
|
|
1156
1386
|
async instantiateTemplate(templateId, parameters) {
|
|
1157
|
-
return this.request(`/v1/workflows/templates/${encodeURIComponent(templateId)}/instantiate`, {
|
|
1158
|
-
method: "POST",
|
|
1159
|
-
body: JSON.stringify(parameters ? { parameters } : {}),
|
|
1160
|
-
headers: { "Content-Type": "application/json" }
|
|
1161
|
-
});
|
|
1387
|
+
return this.request(`/v1/workflows/templates/${encodeURIComponent(templateId)}/instantiate`, jsonInit("POST", parameters ? { parameters } : {}));
|
|
1162
1388
|
}
|
|
1163
1389
|
/**
|
|
1164
1390
|
* The caller's open decisions across all workflows — the always-available
|
|
@@ -1185,11 +1411,7 @@ var HubWorkflowsClient = class {
|
|
|
1185
1411
|
* (409 — answered, timed out, or cancelled first).
|
|
1186
1412
|
*/
|
|
1187
1413
|
async resolveRunDecision(id, runId, input) {
|
|
1188
|
-
return this.request(`/v1/workflows/${encodeURIComponent(id)}/runs/${encodeURIComponent(runId)}/decision/resolve`,
|
|
1189
|
-
method: "POST",
|
|
1190
|
-
body: JSON.stringify(input),
|
|
1191
|
-
headers: { "Content-Type": "application/json" }
|
|
1192
|
-
});
|
|
1414
|
+
return this.request(`/v1/workflows/${encodeURIComponent(id)}/runs/${encodeURIComponent(runId)}/decision/resolve`, jsonInit("POST", input));
|
|
1193
1415
|
}
|
|
1194
1416
|
/**
|
|
1195
1417
|
* Dry-run a YAML definition against the platform compiler without saving it.
|
|
@@ -1202,14 +1424,10 @@ var HubWorkflowsClient = class {
|
|
|
1202
1424
|
* the unconnected providers is the point.
|
|
1203
1425
|
*/
|
|
1204
1426
|
async validate(yaml, opts = {}) {
|
|
1205
|
-
return this.request("/v1/workflows/validate", {
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
...opts.structural ? { structural: true } : {}
|
|
1210
|
-
}),
|
|
1211
|
-
headers: { "Content-Type": "application/json" }
|
|
1212
|
-
});
|
|
1427
|
+
return this.request("/v1/workflows/validate", jsonInit("POST", {
|
|
1428
|
+
yaml,
|
|
1429
|
+
...opts.structural ? { structural: true } : {}
|
|
1430
|
+
}));
|
|
1213
1431
|
}
|
|
1214
1432
|
async schema() {
|
|
1215
1433
|
return this.request("/v1/workflows/schema", { method: "GET" });
|
|
@@ -1473,6 +1691,40 @@ function requestFailure(code, status, error, headers) {
|
|
|
1473
1691
|
};
|
|
1474
1692
|
}
|
|
1475
1693
|
//#endregion
|
|
1476
|
-
|
|
1694
|
+
//#region src/line-grants.ts
|
|
1695
|
+
function path(binding, suffix = "") {
|
|
1696
|
+
if (!binding.workspaceId || !binding.workspaceAgentId) throw new Error("A workspace and agent are required for a line grant");
|
|
1697
|
+
return `/v1/hub/line-grants/current${suffix}?${new URLSearchParams({
|
|
1698
|
+
workspaceId: binding.workspaceId,
|
|
1699
|
+
workspaceAgentId: binding.workspaceAgentId
|
|
1700
|
+
})}`;
|
|
1701
|
+
}
|
|
1702
|
+
/** Every call uses HubTransport's authHeaders, so one-use app broker tokens can be minted per request. */
|
|
1703
|
+
var HubLineGrantsClient = class extends HubTransport {
|
|
1704
|
+
current(binding) {
|
|
1705
|
+
return this.request(path(binding), { method: "GET" });
|
|
1706
|
+
}
|
|
1707
|
+
async line(binding) {
|
|
1708
|
+
return (await this.request(path(binding, "/line"), { method: "GET" })).line;
|
|
1709
|
+
}
|
|
1710
|
+
async attach(binding, input) {
|
|
1711
|
+
return (await this.request(path(binding, "/attachment"), jsonInit("PUT", input))).attachment;
|
|
1712
|
+
}
|
|
1713
|
+
detach(binding) {
|
|
1714
|
+
return this.request(path(binding, "/attachment"), { method: "DELETE" });
|
|
1715
|
+
}
|
|
1716
|
+
async threads(binding) {
|
|
1717
|
+
return (await this.request(path(binding, "/threads"), { method: "GET" })).threads;
|
|
1718
|
+
}
|
|
1719
|
+
async messages(binding, threadId) {
|
|
1720
|
+
if (!threadId || threadId.length > 256) throw new Error("A bounded line thread id is required");
|
|
1721
|
+
return (await this.request(path(binding, `/threads/${encodeURIComponent(threadId)}/messages`), { method: "GET" })).messages;
|
|
1722
|
+
}
|
|
1723
|
+
revoke(binding) {
|
|
1724
|
+
return this.request(path(binding), { method: "DELETE" });
|
|
1725
|
+
}
|
|
1726
|
+
};
|
|
1727
|
+
//#endregion
|
|
1728
|
+
export { HUB_API_KEY_ENV_VAR, HUB_CAPABILITY_TOKEN_ENV_VAR, HUB_URL_ENV_VAR, HubAllowancesClient, HubApprovalsClient, HubAppsClient, HubAuditClient, HubChannelsClient, HubClient, HubConnectionsClient, HubEventDeliveryError, HubEventSubscriptionsClient, HubGithubAppClient, HubInboundWebhooksClient, HubLineGrantsClient, HubLinesClient, HubManagedNumbersClient, HubPermissionsClient, HubSdkError, HubTokensClient, HubToolsClient, HubWorkflowsClient, authenticateHubEventRequest, deriveHubEventCallbackSecret, parseHubEventDelivery, redactHubValue, resolveHubAuth, resolveHubBaseUrl, verifyHubEventSignature };
|
|
1477
1729
|
|
|
1478
1730
|
//# sourceMappingURL=index.js.map
|