@hainiva/agent-sdk 0.0.0-stage → 0.3.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/CHANGELOG.md +73 -0
- package/LICENSE +21 -0
- package/README.md +278 -2
- package/SECURITY.md +33 -0
- package/dist/cjs/agent.cjs +320 -0
- package/dist/cjs/agent.d.cts +239 -0
- package/dist/cjs/calls.cjs +277 -0
- package/dist/cjs/calls.d.cts +232 -0
- package/dist/cjs/contract.cjs +14 -0
- package/dist/cjs/contract.d.cts +225 -0
- package/dist/cjs/embed.cjs +253 -0
- package/dist/cjs/embed.d.cts +187 -0
- package/dist/cjs/emitter.cjs +50 -0
- package/dist/cjs/emitter.d.cts +22 -0
- package/dist/cjs/errors.cjs +28 -0
- package/dist/cjs/errors.d.cts +15 -0
- package/dist/cjs/events.cjs +97 -0
- package/dist/cjs/events.d.cts +97 -0
- package/dist/cjs/index.cjs +72 -0
- package/dist/cjs/index.d.cts +28 -0
- package/dist/cjs/livekit.cjs +56 -0
- package/dist/cjs/livekit.d.cts +35 -0
- package/dist/cjs/log.cjs +15 -0
- package/dist/cjs/log.d.cts +5 -0
- package/dist/cjs/react-native.cjs +32 -0
- package/dist/cjs/react-native.d.cts +39 -0
- package/dist/cjs/reactNativeDesk.cjs +107 -0
- package/dist/cjs/reactNativeDesk.d.cts +53 -0
- package/dist/cjs/redact.cjs +71 -0
- package/dist/cjs/redact.d.cts +21 -0
- package/dist/cjs/rest.cjs +286 -0
- package/dist/cjs/rest.d.cts +172 -0
- package/dist/cjs/session.cjs +159 -0
- package/dist/cjs/session.d.cts +101 -0
- package/dist/cjs/singleFlight.cjs +49 -0
- package/dist/cjs/singleFlight.d.cts +32 -0
- package/dist/cjs/url.cjs +39 -0
- package/dist/cjs/url.d.cts +13 -0
- package/dist/cjs/web.cjs +28 -0
- package/dist/cjs/web.d.cts +23 -0
- package/dist/cjs/ws.cjs +246 -0
- package/dist/cjs/ws.d.cts +134 -0
- package/dist/esm/agent.d.ts +240 -0
- package/dist/esm/agent.d.ts.map +1 -0
- package/dist/esm/agent.js +317 -0
- package/dist/esm/agent.js.map +1 -0
- package/dist/esm/calls.d.ts +233 -0
- package/dist/esm/calls.d.ts.map +1 -0
- package/dist/esm/calls.js +271 -0
- package/dist/esm/calls.js.map +1 -0
- package/dist/esm/contract.d.ts +226 -0
- package/dist/esm/contract.d.ts.map +1 -0
- package/dist/esm/contract.js +12 -0
- package/dist/esm/contract.js.map +1 -0
- package/dist/esm/embed.d.ts +188 -0
- package/dist/esm/embed.d.ts.map +1 -0
- package/dist/esm/embed.js +247 -0
- package/dist/esm/embed.js.map +1 -0
- package/dist/esm/emitter.d.ts +23 -0
- package/dist/esm/emitter.d.ts.map +1 -0
- package/dist/esm/emitter.js +47 -0
- package/dist/esm/emitter.js.map +1 -0
- package/dist/esm/errors.d.ts +16 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +25 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/events.d.ts +98 -0
- package/dist/esm/events.d.ts.map +1 -0
- package/dist/esm/events.js +90 -0
- package/dist/esm/events.js.map +1 -0
- package/dist/esm/index.d.ts +29 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +29 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/livekit.d.ts +36 -0
- package/dist/esm/livekit.d.ts.map +1 -0
- package/dist/esm/livekit.js +54 -0
- package/dist/esm/livekit.js.map +1 -0
- package/dist/esm/log.d.ts +6 -0
- package/dist/esm/log.d.ts.map +1 -0
- package/dist/esm/log.js +13 -0
- package/dist/esm/log.js.map +1 -0
- package/dist/esm/react-native.d.ts +40 -0
- package/dist/esm/react-native.d.ts.map +1 -0
- package/dist/esm/react-native.js +26 -0
- package/dist/esm/react-native.js.map +1 -0
- package/dist/esm/reactNativeDesk.d.ts +54 -0
- package/dist/esm/reactNativeDesk.d.ts.map +1 -0
- package/dist/esm/reactNativeDesk.js +103 -0
- package/dist/esm/reactNativeDesk.js.map +1 -0
- package/dist/esm/redact.d.ts +22 -0
- package/dist/esm/redact.d.ts.map +1 -0
- package/dist/esm/redact.js +66 -0
- package/dist/esm/redact.js.map +1 -0
- package/dist/esm/rest.d.ts +173 -0
- package/dist/esm/rest.d.ts.map +1 -0
- package/dist/esm/rest.js +281 -0
- package/dist/esm/rest.js.map +1 -0
- package/dist/esm/session.d.ts +102 -0
- package/dist/esm/session.d.ts.map +1 -0
- package/dist/esm/session.js +155 -0
- package/dist/esm/session.js.map +1 -0
- package/dist/esm/singleFlight.d.ts +33 -0
- package/dist/esm/singleFlight.d.ts.map +1 -0
- package/dist/esm/singleFlight.js +46 -0
- package/dist/esm/singleFlight.js.map +1 -0
- package/dist/esm/url.d.ts +14 -0
- package/dist/esm/url.d.ts.map +1 -0
- package/dist/esm/url.js +37 -0
- package/dist/esm/url.js.map +1 -0
- package/dist/esm/web.d.ts +24 -0
- package/dist/esm/web.d.ts.map +1 -0
- package/dist/esm/web.js +23 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/esm/ws.d.ts +135 -0
- package/dist/esm/ws.d.ts.map +1 -0
- package/dist/esm/ws.js +242 -0
- package/dist/esm/ws.js.map +1 -0
- package/package.json +117 -4
package/dist/esm/rest.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { HainivaAgentError } from "./errors.js";
|
|
2
|
+
import { safeLogger } from "./log.js";
|
|
3
|
+
import { Redactor } from "./redact.js";
|
|
4
|
+
import { assertSafeUrl } from "./url.js";
|
|
5
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
6
|
+
const TENANT = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7
|
+
/** A random UUID v4: crypto.randomUUID where it exists (browsers, Node), else getRandomValues, else Math.random (Idempotency-Key only, not a secret). */
|
|
8
|
+
export function newIdempotencyKey() {
|
|
9
|
+
const c = globalThis.crypto;
|
|
10
|
+
if (c?.randomUUID)
|
|
11
|
+
return c.randomUUID();
|
|
12
|
+
const b = new Uint8Array(16);
|
|
13
|
+
if (c?.getRandomValues)
|
|
14
|
+
c.getRandomValues(b);
|
|
15
|
+
else
|
|
16
|
+
for (let i = 0; i < 16; i++)
|
|
17
|
+
b[i] = Math.floor(Math.random() * 256);
|
|
18
|
+
b[6] = (b[6] & 0x0f) | 0x40;
|
|
19
|
+
b[8] = (b[8] & 0x3f) | 0x80;
|
|
20
|
+
const h = [...b].map((x) => x.toString(16).padStart(2, "0")).join("");
|
|
21
|
+
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;
|
|
22
|
+
}
|
|
23
|
+
/** An id that goes into a path: a UUID, or the request is refused before it leaves (no path tricks). */
|
|
24
|
+
function id(v, what) {
|
|
25
|
+
if (typeof v !== "string" || !UUID.test(v))
|
|
26
|
+
throw new HainivaAgentError(0, "invalid_id", { field: what });
|
|
27
|
+
return v.toLowerCase();
|
|
28
|
+
}
|
|
29
|
+
function isObject(v) {
|
|
30
|
+
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
31
|
+
}
|
|
32
|
+
/** Pure: the error a non-2xx answer becomes. Exported for tests. */
|
|
33
|
+
export function errorFromResponse(status, data, redactor, retryAfter) {
|
|
34
|
+
const e = isObject(data) ? data["error"] : undefined;
|
|
35
|
+
let code = status === 401 ? "unauthorized" : status === 403 ? "forbidden" : status === 404 ? "not_found" : status === 409 ? "conflict" : status === 429 ? "rate_limited" : status >= 500 ? "server_error" : "invalid_request";
|
|
36
|
+
let message;
|
|
37
|
+
if (isObject(e)) {
|
|
38
|
+
if (typeof e["code"] === "string" && e["code"])
|
|
39
|
+
code = e["code"].slice(0, 80);
|
|
40
|
+
if (typeof e["message"] === "string")
|
|
41
|
+
message = e["message"].slice(0, 500);
|
|
42
|
+
}
|
|
43
|
+
else if (typeof e === "string") {
|
|
44
|
+
message = e.slice(0, 500);
|
|
45
|
+
}
|
|
46
|
+
const body = {};
|
|
47
|
+
if (message)
|
|
48
|
+
body["message"] = message;
|
|
49
|
+
if (retryAfter && /^\d{1,6}$/.test(retryAfter))
|
|
50
|
+
body["retryAfterSec"] = Number(retryAfter);
|
|
51
|
+
return new HainivaAgentError(status, code, body, redactor);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The Agent API over fetch. `tokens` is normally the SessionManager; the
|
|
55
|
+
* client's own `sessions` transport is what that SessionManager signs in with.
|
|
56
|
+
*/
|
|
57
|
+
export class AgentRestClient {
|
|
58
|
+
constructor(o, tokens) {
|
|
59
|
+
this.o = o;
|
|
60
|
+
// ── Sessions (the SessionManager's transport) ───────────────────────────────
|
|
61
|
+
this.sessions = {
|
|
62
|
+
exchange: (assertion) => this.raw("POST", "/agent/v1/sessions", {
|
|
63
|
+
body: { tenantId: this.o.tenantId, assertion, ...(this.o.device ? { device: this.o.device } : {}) },
|
|
64
|
+
}, null).then((s) => s),
|
|
65
|
+
refresh: (refreshToken) => this.raw("POST", "/agent/v1/sessions/refresh", {
|
|
66
|
+
body: { tenantId: this.o.tenantId, refreshToken },
|
|
67
|
+
}, null).then((s) => s),
|
|
68
|
+
revoke: async (session) => {
|
|
69
|
+
await this.raw("DELETE", "/agent/v1/sessions/current", {}, session.accessToken);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
const u = assertSafeUrl(o.baseUrl, { kind: "http", ...(o.allowInsecureLocalhost ? { allowInsecureLocalhost: true } : {}) });
|
|
73
|
+
if (u.search || u.hash)
|
|
74
|
+
throw new HainivaAgentError(0, "invalid_url", { hint: "baseUrl takes no query or fragment" });
|
|
75
|
+
if (typeof o.tenantId !== "string" || !TENANT.test(o.tenantId))
|
|
76
|
+
throw new HainivaAgentError(0, "invalid_tenant_id");
|
|
77
|
+
this.baseUrl = u.origin + u.pathname.replace(/\/+$/, "");
|
|
78
|
+
const f = o.fetch ?? globalThis.fetch;
|
|
79
|
+
if (!f)
|
|
80
|
+
throw new HainivaAgentError(0, "no_fetch", { hint: "pass options.fetch" });
|
|
81
|
+
this.fetchFn = f.bind(globalThis);
|
|
82
|
+
this.timeoutMs = o.timeoutMs ?? 15000;
|
|
83
|
+
this.redactor = o.redactor ?? new Redactor();
|
|
84
|
+
this.log = safeLogger(o.log, this.redactor);
|
|
85
|
+
this.tokens = tokens ?? null;
|
|
86
|
+
}
|
|
87
|
+
/** Attach the token source after construction (the SessionManager needs `sessions` first). */
|
|
88
|
+
useTokens(tokens) { this.tokens = tokens; }
|
|
89
|
+
/** The wss:// URL of the event stream, derived from baseUrl (never from a server answer). */
|
|
90
|
+
get wsUrl() {
|
|
91
|
+
return `${this.baseUrl.replace(/^http/, "ws")}/agent/v1/ws`;
|
|
92
|
+
}
|
|
93
|
+
// ── The generic request ─────────────────────────────────────────────────────
|
|
94
|
+
/** An authenticated request: refresh-and-retry once on an expired token. */
|
|
95
|
+
async request(method, path, opts = {}) {
|
|
96
|
+
if (!this.tokens)
|
|
97
|
+
throw new HainivaAgentError(0, "not_signed_in");
|
|
98
|
+
const idem = method === "POST" ? newIdempotencyKey() : undefined;
|
|
99
|
+
const token = await this.tokens.accessToken();
|
|
100
|
+
try {
|
|
101
|
+
return await this.raw(method, path, opts, token, idem);
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
if (!(e instanceof HainivaAgentError) || e.status !== 401 || (e.code !== "token_expired" && e.code !== "token_invalid"))
|
|
105
|
+
throw e;
|
|
106
|
+
this.log("access_token_refused", { code: e.code });
|
|
107
|
+
this.tokens.invalidate(token);
|
|
108
|
+
const next = await this.tokens.accessToken();
|
|
109
|
+
return this.raw(method, path, opts, next, idem);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async raw(method, path, opts, token, idem) {
|
|
113
|
+
let url = `${this.baseUrl}${path}`;
|
|
114
|
+
if (opts.query) {
|
|
115
|
+
const q = new URLSearchParams();
|
|
116
|
+
for (const [k, v] of Object.entries(opts.query))
|
|
117
|
+
if (v !== undefined && v !== "")
|
|
118
|
+
q.set(k, String(v));
|
|
119
|
+
const s = q.toString();
|
|
120
|
+
if (s)
|
|
121
|
+
url += `?${s}`;
|
|
122
|
+
}
|
|
123
|
+
const headers = { accept: "application/json" };
|
|
124
|
+
if (token) {
|
|
125
|
+
this.redactor.add(token);
|
|
126
|
+
headers["authorization"] = `Bearer ${token}`;
|
|
127
|
+
}
|
|
128
|
+
if (idem)
|
|
129
|
+
headers["idempotency-key"] = idem;
|
|
130
|
+
let body;
|
|
131
|
+
if (opts.body !== undefined) {
|
|
132
|
+
headers["content-type"] = "application/json";
|
|
133
|
+
body = JSON.stringify(opts.body);
|
|
134
|
+
}
|
|
135
|
+
const ctl = new AbortController();
|
|
136
|
+
const timeout = opts.timeoutMs ?? this.timeoutMs;
|
|
137
|
+
let timedOut = false;
|
|
138
|
+
const timer = setTimeout(() => { timedOut = true; ctl.abort(); }, timeout);
|
|
139
|
+
const onAbort = () => ctl.abort();
|
|
140
|
+
if (opts.signal) {
|
|
141
|
+
if (opts.signal.aborted) {
|
|
142
|
+
clearTimeout(timer);
|
|
143
|
+
throw new HainivaAgentError(0, "aborted");
|
|
144
|
+
}
|
|
145
|
+
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
146
|
+
}
|
|
147
|
+
let res;
|
|
148
|
+
try {
|
|
149
|
+
res = await this.fetchFn(url, { method, headers, ...(body !== undefined ? { body } : {}), signal: ctl.signal });
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
if (timedOut)
|
|
153
|
+
throw new HainivaAgentError(0, "timeout", { timeoutMs: timeout });
|
|
154
|
+
if (opts.signal?.aborted)
|
|
155
|
+
throw new HainivaAgentError(0, "aborted");
|
|
156
|
+
throw HainivaAgentError.from(e, "network_error", this.redactor);
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
clearTimeout(timer);
|
|
160
|
+
opts.signal?.removeEventListener("abort", onAbort);
|
|
161
|
+
}
|
|
162
|
+
if (res.status === 204)
|
|
163
|
+
return undefined;
|
|
164
|
+
let data = null;
|
|
165
|
+
const text = await res.text().catch(() => "");
|
|
166
|
+
if (text) {
|
|
167
|
+
try {
|
|
168
|
+
data = JSON.parse(text);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
data = null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (!res.ok)
|
|
175
|
+
throw errorFromResponse(res.status, data, this.redactor, res.headers?.get?.("retry-after") ?? null);
|
|
176
|
+
if (data === null || typeof data !== "object")
|
|
177
|
+
throw new HainivaAgentError(res.status, "invalid_response", {}, this.redactor);
|
|
178
|
+
return data;
|
|
179
|
+
}
|
|
180
|
+
// ── Me ──────────────────────────────────────────────────────────────────────
|
|
181
|
+
async me(o) { return this.request("GET", "/agent/v1/me", o); }
|
|
182
|
+
async setStatus(status, o) {
|
|
183
|
+
return this.request("PUT", "/agent/v1/me/status", { ...o, body: { status } });
|
|
184
|
+
}
|
|
185
|
+
/** Rings for this member now (after a cold start, a missed push or a resync). */
|
|
186
|
+
async pendingRings(o) {
|
|
187
|
+
const r = await this.request("GET", "/agent/v1/rings/pending", o);
|
|
188
|
+
return Array.isArray(r.data) ? r.data : [];
|
|
189
|
+
}
|
|
190
|
+
// ── Calls ───────────────────────────────────────────────────────────────────
|
|
191
|
+
async getCall(callId, o) { return this.request("GET", `/agent/v1/calls/${id(callId, "callId")}`, o); }
|
|
192
|
+
async acceptCall(callId, o) { return this.request("POST", `/agent/v1/calls/${id(callId, "callId")}/accept`, { ...o, body: {} }); }
|
|
193
|
+
async declineCall(callId, o) { return this.request("POST", `/agent/v1/calls/${id(callId, "callId")}/decline`, { ...o, body: {} }); }
|
|
194
|
+
async endCall(callId, o) { return this.request("POST", `/agent/v1/calls/${id(callId, "callId")}/end`, { ...o, body: {} }); }
|
|
195
|
+
async holdCall(callId, on, o) {
|
|
196
|
+
return this.request("POST", `/agent/v1/calls/${id(callId, "callId")}/hold`, { ...o, body: { on } });
|
|
197
|
+
}
|
|
198
|
+
async transferCall(callId, target, o) {
|
|
199
|
+
let body;
|
|
200
|
+
if ("agentId" in target)
|
|
201
|
+
body = { targetAgentId: id(target.agentId, "agentId"), mode: target.mode ?? "warm" };
|
|
202
|
+
else if ("queueId" in target)
|
|
203
|
+
body = { queueId: id(target.queueId, "queueId") };
|
|
204
|
+
else
|
|
205
|
+
body = { number: target.number, mode: target.mode ?? "warm" };
|
|
206
|
+
return this.request("POST", `/agent/v1/calls/${id(callId, "callId")}/transfer`, { ...o, body });
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* A 15-minute desk token for the embedded HAINIVA desk (S4): give it to the
|
|
210
|
+
* desk over postMessage only (`@hainiva/agent-sdk/embed` does). Never put it
|
|
211
|
+
* in a URL or storage. Ends with this session.
|
|
212
|
+
*/
|
|
213
|
+
async deskSession(o) { return this.request("POST", "/agent/v1/desk-session", { ...o, body: {} }); }
|
|
214
|
+
/** Re-mint the LiveKit token while still a participant (reconnect, token near expiry). */
|
|
215
|
+
async mediaToken(callId, o) { return this.request("POST", `/agent/v1/calls/${id(callId, "callId")}/media-token`, { ...o, body: {} }); }
|
|
216
|
+
// ── Wrap-up ─────────────────────────────────────────────────────────────────
|
|
217
|
+
async dispositions(channel, o) {
|
|
218
|
+
const r = await this.request("GET", "/agent/v1/dispositions", { ...o, ...(channel ? { query: { channel } } : {}) });
|
|
219
|
+
return Array.isArray(r.data) ? r.data : [];
|
|
220
|
+
}
|
|
221
|
+
async wrapUp(callId, w = {}, o) {
|
|
222
|
+
return this.request("POST", `/agent/v1/calls/${id(callId, "callId")}/wrapup`, { ...o, body: w });
|
|
223
|
+
}
|
|
224
|
+
// ── Conversations and messages ──────────────────────────────────────────────
|
|
225
|
+
async listConversations(q = {}, o) {
|
|
226
|
+
return this.request("GET", "/agent/v1/conversations", { ...o, query: { scope: q.scope, status: q.status, cursor: q.cursor, limit: q.limit } }).then((page));
|
|
227
|
+
}
|
|
228
|
+
async getConversation(conversationId, o) {
|
|
229
|
+
return this.request("GET", `/agent/v1/conversations/${id(conversationId, "conversationId")}`, o);
|
|
230
|
+
}
|
|
231
|
+
/** Claim it (no agentId), or — a supervisor — assign it to a colleague. */
|
|
232
|
+
async assignConversation(conversationId, agentId, o) {
|
|
233
|
+
return this.request("POST", `/agent/v1/conversations/${id(conversationId, "conversationId")}/assign`, { ...o, body: agentId ? { agentId: id(agentId, "agentId") } : {} });
|
|
234
|
+
}
|
|
235
|
+
async releaseConversation(conversationId, note, o) {
|
|
236
|
+
return this.request("POST", `/agent/v1/conversations/${id(conversationId, "conversationId")}/release`, { ...o, body: note ? { note } : {} });
|
|
237
|
+
}
|
|
238
|
+
async transferConversation(conversationId, to, o) {
|
|
239
|
+
const body = "agentId" in to ? { agentId: id(to.agentId, "agentId") } : { queueId: id(to.queueId, "queueId"), ...(to.note ? { note: to.note } : {}) };
|
|
240
|
+
return this.request("POST", `/agent/v1/conversations/${id(conversationId, "conversationId")}/transfer`, { ...o, body });
|
|
241
|
+
}
|
|
242
|
+
async closeConversation(conversationId, o) {
|
|
243
|
+
return this.request("POST", `/agent/v1/conversations/${id(conversationId, "conversationId")}/close`, { ...o, body: {} });
|
|
244
|
+
}
|
|
245
|
+
async listMessages(conversationId, q = {}, o) {
|
|
246
|
+
return this.request("GET", `/agent/v1/conversations/${id(conversationId, "conversationId")}/messages`, { ...o, query: { after: q.after, limit: q.limit } }).then((page));
|
|
247
|
+
}
|
|
248
|
+
async sendMessage(conversationId, text, o) {
|
|
249
|
+
return this.request("POST", `/agent/v1/conversations/${id(conversationId, "conversationId")}/messages`, { ...o, body: { text } });
|
|
250
|
+
}
|
|
251
|
+
async typing(conversationId, o) {
|
|
252
|
+
return this.request("POST", `/agent/v1/conversations/${id(conversationId, "conversationId")}/typing`, { ...o, body: {} });
|
|
253
|
+
}
|
|
254
|
+
// ── Supervisor ──────────────────────────────────────────────────────────────
|
|
255
|
+
async liveCalls(o) {
|
|
256
|
+
const r = await this.request("GET", "/agent/v1/supervisor/live-calls", o);
|
|
257
|
+
return Array.isArray(r.data) ? r.data : [];
|
|
258
|
+
}
|
|
259
|
+
async teamAgents(o) {
|
|
260
|
+
const r = await this.request("GET", "/agent/v1/supervisor/agents", o);
|
|
261
|
+
return Array.isArray(r.data) ? r.data : [];
|
|
262
|
+
}
|
|
263
|
+
async supervise(callId, mode = "monitor", o) {
|
|
264
|
+
return this.request("POST", `/agent/v1/supervisor/calls/${id(callId, "callId")}/supervise`, { ...o, body: { mode } });
|
|
265
|
+
}
|
|
266
|
+
async setSuperviseMode(callId, mode, supervisorTrackSid, o) {
|
|
267
|
+
return this.request("PUT", `/agent/v1/supervisor/calls/${id(callId, "callId")}/supervise-mode`, { ...o, body: { mode, ...(supervisorTrackSid ? { supervisorTrackSid } : {}) } });
|
|
268
|
+
}
|
|
269
|
+
// ── Push (your app's own FCM / APNs credentials, uploaded by your admin) ─────
|
|
270
|
+
async registerPush(sub, o) {
|
|
271
|
+
return this.request("POST", "/agent/v1/push/subscriptions", { ...o, body: sub });
|
|
272
|
+
}
|
|
273
|
+
async unregisterPush(token, o) {
|
|
274
|
+
await this.request("DELETE", "/agent/v1/push/subscriptions", { ...o, body: { token } });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function page(r) {
|
|
278
|
+
const x = isObject(r) ? r : {};
|
|
279
|
+
return { data: Array.isArray(x["data"]) ? x["data"] : [], nextCursor: typeof x["nextCursor"] === "string" ? x["nextCursor"] : null };
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=rest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../src/rest.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,UAAU,EAAe,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA8CzC,MAAM,IAAI,GAAG,iEAAiE,CAAC;AAC/E,MAAM,MAAM,GAAG,uBAAuB,CAAC;AAEvC,yJAAyJ;AACzJ,MAAM,UAAU,iBAAiB;IAC/B,MAAM,CAAC,GAAI,UAA0G,CAAC,MAAM,CAAC;IAC7H,IAAI,CAAC,EAAE,UAAU;QAAE,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC;IACzC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,eAAe;QAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;YAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7B,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtE,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;AACnG,CAAC;AAED,wGAAwG;AACxG,SAAS,EAAE,CAAC,CAAS,EAAE,IAAY;IACjC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1G,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,IAAa,EAAE,QAAmB,EAAE,UAA0B;IAC9G,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,IAAI,IAAI,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAC9N,IAAI,OAA2B,CAAC;IAChC,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC;YAAE,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9E,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7E,CAAC;SAAM,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,IAAI,OAAO;QAAE,IAAI,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC;IACvC,IAAI,UAAU,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,IAAI,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3F,OAAO,IAAI,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,eAAe;IAQ1B,YAA6B,CAAmB,EAAE,MAAoB;QAAzC,MAAC,GAAD,CAAC,CAAkB;QAsBhD,+EAA+E;QAEtE,aAAQ,GAAqD;YACpE,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAkB,MAAM,EAAE,oBAAoB,EAAE;gBAC/E,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;aACpG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAmC,CAAC;YACzD,OAAO,EAAE,CAAC,YAAY,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAkB,MAAM,EAAE,4BAA4B,EAAE;gBACzF,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE;aAClD,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAmC,CAAC;YACzD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;gBACxB,MAAM,IAAI,CAAC,GAAG,CAAO,QAAQ,EAAE,4BAA4B,EAAE,EAAE,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;YACxF,CAAC;SACF,CAAC;QAjCA,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,sBAAsB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5H,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI;YAAE,MAAM,IAAI,iBAAiB,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,oCAAoC,EAAE,CAAC,CAAC;QACtH,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,iBAAiB,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACpH,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,IAAK,UAAuC,CAAC,KAAK,CAAC;QACpE,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,iBAAiB,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,IAAI,KAAM,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC7C,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,IAAI,CAAC;IAC/B,CAAC;IAED,8FAA8F;IAC9F,SAAS,CAAC,MAAmB,IAAU,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IAE9D,6FAA6F;IAC7F,IAAI,KAAK;QACP,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC;IAC9D,CAAC;IAgBD,+EAA+E;IAE/E,4EAA4E;IAC5E,KAAK,CAAC,OAAO,CAAI,MAAyC,EAAE,IAAY,EAAE,OAAuB,EAAE;QACjG,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,iBAAiB,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACjE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,GAAG,CAAI,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,CAAC,YAAY,iBAAiB,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,IAAI,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC;gBAAE,MAAM,CAAC,CAAC;YACjI,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC9B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC,GAAG,CAAI,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,GAAG,CAAI,MAAc,EAAE,IAAY,EAAE,IAAoB,EAAE,KAAoB,EAAE,IAAa;QAC1G,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QACnC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;YAChC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;gBAAE,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE;oBAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACtG,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;YACvB,IAAI,CAAC;gBAAE,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;QACxB,CAAC;QACD,MAAM,OAAO,GAA2B,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;QACvE,IAAI,KAAK,EAAE,CAAC;YAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;QAAC,CAAC;QACtF,IAAI,IAAI;YAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC;QAC5C,IAAI,IAAwB,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAAC,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAEhH,MAAM,GAAG,GAAG,IAAI,eAAe,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;QACjD,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,QAAQ,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC3E,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBAAC,MAAM,IAAI,iBAAiB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YAAC,CAAC;YAC5F,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAClH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,QAAQ;gBAAE,MAAM,IAAI,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAChF,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO;gBAAE,MAAM,IAAI,iBAAiB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YACpE,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClE,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,SAAc,CAAC;QAC9C,IAAI,IAAI,GAAY,IAAI,CAAC;QACzB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,IAAI,EAAE,CAAC;YAAC,IAAI,CAAC;gBAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,IAAI,GAAG,IAAI,CAAC;YAAC,CAAC;QAAC,CAAC;QACrE,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,CAAC;QACjH,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,MAAM,IAAI,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9H,OAAO,IAAS,CAAC;IACnB,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,EAAE,CAAC,CAAkB,IAAyB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpG,KAAK,CAAC,SAAS,CAAC,MAAmB,EAAE,CAAkB;QACrD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,qBAAqB,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,YAAY,CAAC,CAAkB;QACnC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAqB,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC,CAAC;QACtF,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,IAAuB,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,CAAkB,IAA2B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACtJ,KAAK,CAAC,UAAU,CAAC,MAAc,EAAE,CAAkB,IAA6B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACpL,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,CAAkB,IAAiD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1M,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,CAAkB,IAA8C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/L,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,EAAW,EAAE,CAAkB;QAC5D,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACtG,CAAC;IACD,KAAK,CAAC,YAAY,CAAC,MAAc,EAAE,MAA0B,EAAE,CAAkB;QAC/E,IAAI,IAA6B,CAAC;QAClC,IAAI,SAAS,IAAI,MAAM;YAAE,IAAI,GAAG,EAAE,aAAa,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC;aACzG,IAAI,SAAS,IAAI,MAAM;YAAE,IAAI,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;;YAC3E,IAAI,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC;QACnE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAClG,CAAC;IACD;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,CAAkB,IAAkC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,wBAAwB,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAClJ,0FAA0F;IAC1F,KAAK,CAAC,UAAU,CAAC,MAAc,EAAE,CAAkB,IAA+B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAE3L,+EAA+E;IAE/E,KAAK,CAAC,YAAY,CAAC,OAAgB,EAAE,CAAkB;QACrD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAqB,KAAK,EAAE,wBAAwB,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACxI,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,IAA8B,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,IAAkD,EAAE,EAAE,CAAkB;QACnG,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACnG,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,iBAAiB,CAAC,IAA2B,EAAE,EAAE,CAAkB;QACvE,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,yBAAyB,EAAE,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA,IAA0B,CAAA,CAAC,CAAC;IAClL,CAAC;IACD,KAAK,CAAC,eAAe,CAAC,cAAsB,EAAE,CAAkB;QAC9D,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,2BAA2B,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACnG,CAAC;IACD,2EAA2E;IAC3E,KAAK,CAAC,kBAAkB,CAAC,cAAsB,EAAE,OAAgB,EAAE,CAAkB;QACnF,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5K,CAAC;IACD,KAAK,CAAC,mBAAmB,CAAC,cAAsB,EAAE,IAAa,EAAE,CAAkB;QACjF,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/I,CAAC;IACD,KAAK,CAAC,oBAAoB,CAAC,cAAsB,EAAE,EAA4D,EAAE,CAAkB;QACjI,MAAM,IAAI,GAAG,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACtJ,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1H,CAAC;IACD,KAAK,CAAC,iBAAiB,CAAC,cAAsB,EAAE,CAAkB;QAChE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3H,CAAC;IACD,KAAK,CAAC,YAAY,CAAC,cAAsB,EAAE,IAAwC,EAAE,EAAE,CAAkB;QACvG,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,2BAA2B,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA,IAAqB,CAAA,CAAC,CAAC;IAC1L,CAAC;IACD,KAAK,CAAC,WAAW,CAAC,cAAsB,EAAE,IAAY,EAAE,CAAkB;QACxE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IACpI,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,cAAsB,EAAE,CAAkB;QACrD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5H,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,SAAS,CAAC,CAAkB;QAChC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAqB,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC,CAAC;QAC9F,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,IAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,CAAkB;QACjC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAqB,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC,CAAC;QAC1F,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,IAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,CAAC;IACD,KAAK,CAAC,SAAS,CAAC,MAAc,EAAE,OAAwC,SAAS,EAAE,CAAkB;QACnG,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,8BAA8B,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IACxH,CAAC;IACD,KAAK,CAAC,gBAAgB,CAAC,MAAc,EAAE,IAAqC,EAAE,kBAA2B,EAAE,CAAkB;QAC3H,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,8BAA8B,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,iBAAiB,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACnL,CAAC;IAED,gFAAgF;IAEhF,KAAK,CAAC,YAAY,CAAC,GAA+B,EAAE,CAAkB;QACpE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,8BAA8B,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,KAAa,EAAE,CAAkB;QACpD,MAAM,IAAI,CAAC,OAAO,CAAU,QAAQ,EAAE,8BAA8B,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACnG,CAAC;CACF;AAED,SAAS,IAAI,CAAI,CAAU;IACzB,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,MAAM,CAAS,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAChJ,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { TypedEmitter } from "./emitter.js";
|
|
2
|
+
import { type Logger } from "./log.js";
|
|
3
|
+
import { Redactor } from "./redact.js";
|
|
4
|
+
/**
|
|
5
|
+
* Where the session is kept between launches. Same shape as @hainiva/app-sdk's.
|
|
6
|
+
* The default is in memory (nothing persisted). On the web, `localStorageStore`
|
|
7
|
+
* (`@hainiva/agent-sdk/web`) is opt-in; in React Native use
|
|
8
|
+
* `secureStoreSessionStore` (`@hainiva/agent-sdk/react-native`) — the refresh
|
|
9
|
+
* token then lives only in the Keychain / Android Keystore.
|
|
10
|
+
*/
|
|
11
|
+
export interface SessionStore {
|
|
12
|
+
get(): Promise<string | null> | string | null;
|
|
13
|
+
set(value: string): Promise<void> | void;
|
|
14
|
+
remove(): Promise<void> | void;
|
|
15
|
+
}
|
|
16
|
+
/** Keeps the session for the life of the page / JS context only. The default. */
|
|
17
|
+
export declare function memoryStore(): SessionStore;
|
|
18
|
+
/** A staff session. Fields beyond these are kept as the server sent them. */
|
|
19
|
+
export interface AgentSession {
|
|
20
|
+
accessToken: string;
|
|
21
|
+
/** ISO time. */
|
|
22
|
+
accessExpiresAt: string;
|
|
23
|
+
refreshToken: string;
|
|
24
|
+
/** ISO time. */
|
|
25
|
+
refreshExpiresAt: string;
|
|
26
|
+
[field: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Ask YOUR backend for a fresh staff assertion (a short-lived JWT it signs with
|
|
30
|
+
* the agent app's private key). Called every time a new session is needed —
|
|
31
|
+
* the SDK never caches or stores an assertion, and you must not either: each
|
|
32
|
+
* one carries a single-use `jti` and expires in minutes.
|
|
33
|
+
*/
|
|
34
|
+
export type GetAssertion = () => Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* How sessions are created and refreshed — bound by the REST client.
|
|
37
|
+
* TODO(S3b): implemented against `/agent/v1/sessions` once the S2 contract is final.
|
|
38
|
+
*/
|
|
39
|
+
export interface SessionTransport<S extends AgentSession = AgentSession> {
|
|
40
|
+
/** Exchange an assertion for a session (POST /agent/v1/sessions). */
|
|
41
|
+
exchange(assertion: string): Promise<S>;
|
|
42
|
+
/** Rotate: a new access token and (rotating) refresh token. */
|
|
43
|
+
refresh(refreshToken: string): Promise<Pick<S, "accessToken" | "accessExpiresAt"> & Partial<S>>;
|
|
44
|
+
/** End the session on the server (best effort). */
|
|
45
|
+
revoke?(session: S): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
export interface SessionManagerOptions<S extends AgentSession> {
|
|
48
|
+
getAssertion: GetAssertion;
|
|
49
|
+
transport: SessionTransport<S>;
|
|
50
|
+
/** Default: memoryStore(). */
|
|
51
|
+
store?: SessionStore;
|
|
52
|
+
/** Refresh this long before the access token expires. Default 60 s. */
|
|
53
|
+
refreshSkewMs?: number;
|
|
54
|
+
now?: () => number;
|
|
55
|
+
redactor?: Redactor;
|
|
56
|
+
log?: Logger;
|
|
57
|
+
}
|
|
58
|
+
export interface SessionEvents<S extends AgentSession> {
|
|
59
|
+
/** A new access token (after sign-in or refresh): e.g. send it on the socket. */
|
|
60
|
+
token: string;
|
|
61
|
+
session: S | null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The staff session: sign in with a fresh assertion, keep it in the store,
|
|
65
|
+
* refresh before expiry (single flight — one refresh however many callers),
|
|
66
|
+
* sign in again with a NEW assertion when the refresh is refused.
|
|
67
|
+
*/
|
|
68
|
+
export declare class SessionManager<S extends AgentSession = AgentSession> {
|
|
69
|
+
private readonly o;
|
|
70
|
+
readonly events: TypedEmitter<SessionEvents<S>>;
|
|
71
|
+
private session;
|
|
72
|
+
private readonly store;
|
|
73
|
+
private readonly skew;
|
|
74
|
+
private readonly now;
|
|
75
|
+
readonly redactor: Redactor;
|
|
76
|
+
private readonly log;
|
|
77
|
+
private readonly refreshOnce;
|
|
78
|
+
private forceNext;
|
|
79
|
+
constructor(o: SessionManagerOptions<S>);
|
|
80
|
+
get current(): S | null;
|
|
81
|
+
/** Restore the stored session if it can still be refreshed, else sign in afresh. */
|
|
82
|
+
signIn(): Promise<S>;
|
|
83
|
+
/** A valid access token, refreshing first when it is about to expire. */
|
|
84
|
+
accessToken(): Promise<string>;
|
|
85
|
+
/**
|
|
86
|
+
* The server refused the access token (401 / socket 4001): the next
|
|
87
|
+
* accessToken() refreshes. Pass the token that was refused: a refusal of an
|
|
88
|
+
* OLDER token (a request that was in flight while another caller already
|
|
89
|
+
* refreshed) is ignored, so ten parallel 401s cause one refresh, not ten.
|
|
90
|
+
*/
|
|
91
|
+
invalidate(refused?: string): void;
|
|
92
|
+
/** Forget the session here only (the server already ended it): no revoke call. */
|
|
93
|
+
clear(): Promise<void>;
|
|
94
|
+
/** End the session here and (best effort) on the server. */
|
|
95
|
+
signOut(): Promise<void>;
|
|
96
|
+
private fresh;
|
|
97
|
+
private doRefresh;
|
|
98
|
+
private readonly freshSignIn;
|
|
99
|
+
private keep;
|
|
100
|
+
private adopt;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { TypedEmitter } from "./emitter.js";
|
|
2
|
+
import { HainivaAgentError } from "./errors.js";
|
|
3
|
+
import { safeLogger } from "./log.js";
|
|
4
|
+
import { Redactor } from "./redact.js";
|
|
5
|
+
import { singleFlight } from "./singleFlight.js";
|
|
6
|
+
/** Keeps the session for the life of the page / JS context only. The default. */
|
|
7
|
+
export function memoryStore() {
|
|
8
|
+
let v = null;
|
|
9
|
+
return { get: () => v, set: (x) => { v = x; }, remove: () => { v = null; } };
|
|
10
|
+
}
|
|
11
|
+
const isSession = (v) => {
|
|
12
|
+
const s = v;
|
|
13
|
+
return !!s && typeof s === "object" && typeof s["accessToken"] === "string" && typeof s["refreshToken"] === "string"
|
|
14
|
+
&& typeof s["accessExpiresAt"] === "string" && typeof s["refreshExpiresAt"] === "string";
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* The staff session: sign in with a fresh assertion, keep it in the store,
|
|
18
|
+
* refresh before expiry (single flight — one refresh however many callers),
|
|
19
|
+
* sign in again with a NEW assertion when the refresh is refused.
|
|
20
|
+
*/
|
|
21
|
+
export class SessionManager {
|
|
22
|
+
constructor(o) {
|
|
23
|
+
this.o = o;
|
|
24
|
+
this.events = new TypedEmitter();
|
|
25
|
+
this.session = null;
|
|
26
|
+
this.forceNext = false;
|
|
27
|
+
this.freshSignIn = singleFlight(async () => {
|
|
28
|
+
// Always a new assertion: never cached, never stored, never reused.
|
|
29
|
+
let assertion;
|
|
30
|
+
try {
|
|
31
|
+
assertion = await this.o.getAssertion();
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
throw HainivaAgentError.from(e, "assertion_failed", this.redactor);
|
|
35
|
+
}
|
|
36
|
+
if (typeof assertion !== "string" || assertion.split(".").length !== 3) {
|
|
37
|
+
throw new HainivaAgentError(0, "invalid_assertion", { hint: "getAssertion must resolve to a signed JWT from your backend" });
|
|
38
|
+
}
|
|
39
|
+
this.redactor.add(assertion);
|
|
40
|
+
try {
|
|
41
|
+
const s = await this.o.transport.exchange(assertion);
|
|
42
|
+
if (!isSession(s))
|
|
43
|
+
throw new HainivaAgentError(0, "invalid_session", {}, this.redactor);
|
|
44
|
+
await this.keep(s);
|
|
45
|
+
return s;
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
throw HainivaAgentError.from(e, "sign_in_failed", this.redactor);
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
this.redactor.remove(assertion);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
this.store = o.store ?? memoryStore();
|
|
55
|
+
this.skew = o.refreshSkewMs ?? 60000;
|
|
56
|
+
this.now = o.now ?? Date.now;
|
|
57
|
+
this.redactor = o.redactor ?? new Redactor();
|
|
58
|
+
this.log = safeLogger(o.log, this.redactor);
|
|
59
|
+
this.refreshOnce = singleFlight(() => this.doRefresh());
|
|
60
|
+
}
|
|
61
|
+
get current() { return this.session; }
|
|
62
|
+
/** Restore the stored session if it can still be refreshed, else sign in afresh. */
|
|
63
|
+
async signIn() {
|
|
64
|
+
const saved = await Promise.resolve().then(() => this.store.get()).catch((e) => { this.log("store_read_failed", e); return null; });
|
|
65
|
+
if (saved) {
|
|
66
|
+
try {
|
|
67
|
+
const s = JSON.parse(saved);
|
|
68
|
+
if (isSession(s) && Date.parse(s.refreshExpiresAt) > this.now() + this.skew) {
|
|
69
|
+
this.adopt(s);
|
|
70
|
+
return await this.fresh();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch { /* corrupt or refused: sign in afresh */ }
|
|
74
|
+
await Promise.resolve().then(() => this.store.remove()).catch(() => undefined);
|
|
75
|
+
}
|
|
76
|
+
return this.freshSignIn();
|
|
77
|
+
}
|
|
78
|
+
/** A valid access token, refreshing first when it is about to expire. */
|
|
79
|
+
async accessToken() {
|
|
80
|
+
return (await this.fresh()).accessToken;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The server refused the access token (401 / socket 4001): the next
|
|
84
|
+
* accessToken() refreshes. Pass the token that was refused: a refusal of an
|
|
85
|
+
* OLDER token (a request that was in flight while another caller already
|
|
86
|
+
* refreshed) is ignored, so ten parallel 401s cause one refresh, not ten.
|
|
87
|
+
*/
|
|
88
|
+
invalidate(refused) {
|
|
89
|
+
if (refused && this.session && this.session.accessToken !== refused)
|
|
90
|
+
return;
|
|
91
|
+
this.forceNext = true;
|
|
92
|
+
}
|
|
93
|
+
/** Forget the session here only (the server already ended it): no revoke call. */
|
|
94
|
+
async clear() {
|
|
95
|
+
this.adopt(null);
|
|
96
|
+
await Promise.resolve().then(() => this.store.remove()).catch(() => undefined);
|
|
97
|
+
}
|
|
98
|
+
/** End the session here and (best effort) on the server. */
|
|
99
|
+
async signOut() {
|
|
100
|
+
const s = this.session;
|
|
101
|
+
this.adopt(null);
|
|
102
|
+
await Promise.resolve().then(() => this.store.remove()).catch(() => undefined);
|
|
103
|
+
if (s && this.o.transport.revoke)
|
|
104
|
+
await this.o.transport.revoke(s).catch((e) => this.log("revoke_failed", e));
|
|
105
|
+
this.redactor.clear();
|
|
106
|
+
}
|
|
107
|
+
async fresh() {
|
|
108
|
+
if (!this.session)
|
|
109
|
+
return this.freshSignIn();
|
|
110
|
+
const left = Date.parse(this.session.accessExpiresAt) - this.now();
|
|
111
|
+
if (!this.forceNext && left > this.skew)
|
|
112
|
+
return this.session;
|
|
113
|
+
return this.refreshOnce();
|
|
114
|
+
}
|
|
115
|
+
async doRefresh() {
|
|
116
|
+
const s = this.session;
|
|
117
|
+
if (!s)
|
|
118
|
+
return this.freshSignIn();
|
|
119
|
+
this.forceNext = false;
|
|
120
|
+
try {
|
|
121
|
+
const r = await this.o.transport.refresh(s.refreshToken);
|
|
122
|
+
if (!r || typeof r.accessToken !== "string" || !r.accessToken)
|
|
123
|
+
throw new HainivaAgentError(0, "refresh_failed", {}, this.redactor);
|
|
124
|
+
const next = { ...s, ...r };
|
|
125
|
+
await this.keep(next);
|
|
126
|
+
return next;
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
// Refused (expired, revoked, reused): a new session from a NEW assertion.
|
|
130
|
+
if (e instanceof HainivaAgentError && (e.status === 401 || e.status === 403)) {
|
|
131
|
+
this.log("refresh_refused", { status: e.status });
|
|
132
|
+
await Promise.resolve().then(() => this.store.remove()).catch(() => undefined);
|
|
133
|
+
this.adopt(null);
|
|
134
|
+
return this.freshSignIn();
|
|
135
|
+
}
|
|
136
|
+
this.forceNext = true;
|
|
137
|
+
throw HainivaAgentError.from(e, "refresh_failed", this.redactor);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async keep(s) {
|
|
141
|
+
this.adopt(s);
|
|
142
|
+
await Promise.resolve().then(() => this.store.set(JSON.stringify(s))).catch((e) => this.log("store_write_failed", e));
|
|
143
|
+
}
|
|
144
|
+
adopt(s) {
|
|
145
|
+
const prev = this.session;
|
|
146
|
+
this.session = s;
|
|
147
|
+
// Old tokens stay redacted: they may still appear in an in-flight error.
|
|
148
|
+
if (s)
|
|
149
|
+
this.redactor.add(s.accessToken, s.refreshToken);
|
|
150
|
+
this.events.emit("session", s);
|
|
151
|
+
if (s && s.accessToken !== prev?.accessToken)
|
|
152
|
+
this.events.emit("token", s.accessToken);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calls `fn` at most once at a time: callers that arrive while it runs share its
|
|
3
|
+
* result (or its error). The next call after it settles runs `fn` again.
|
|
4
|
+
*/
|
|
5
|
+
export declare function singleFlight<T>(fn: () => Promise<T>): () => Promise<T>;
|
|
6
|
+
export interface RefreshedToken {
|
|
7
|
+
token: string;
|
|
8
|
+
/** Epoch ms. */
|
|
9
|
+
expiresAt: number;
|
|
10
|
+
}
|
|
11
|
+
export interface TokenRefresherOptions {
|
|
12
|
+
/** Fetch a new token. Called once however many callers wait for it. */
|
|
13
|
+
refresh: () => Promise<RefreshedToken>;
|
|
14
|
+
/** Refresh this long before expiry. Default 60 s. */
|
|
15
|
+
skewMs?: number;
|
|
16
|
+
now?: () => number;
|
|
17
|
+
}
|
|
18
|
+
export interface TokenRefresher {
|
|
19
|
+
/** A token valid for at least `skewMs`, refreshing (once, shared) when needed. */
|
|
20
|
+
get(): Promise<string>;
|
|
21
|
+
/** Forget the current token (the server refused it): the next get() refreshes. */
|
|
22
|
+
invalidate(): void;
|
|
23
|
+
/** Whether a token is held that is still valid beyond the skew. */
|
|
24
|
+
readonly valid: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Single-flight token refresh with a pluggable refresh function. Ten requests that
|
|
28
|
+
* find the token expired cause one refresh, not ten — which also keeps a
|
|
29
|
+
* rotating refresh token from being spent twice (reuse detection would then
|
|
30
|
+
* revoke the whole session family).
|
|
31
|
+
*/
|
|
32
|
+
export declare function createTokenRefresher(o: TokenRefresherOptions): TokenRefresher;
|
|
33
|
+
//# sourceMappingURL=singleFlight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singleFlight.d.ts","sourceRoot":"","sources":["../../src/singleFlight.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,CAStE;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,uEAAuE;IACvE,OAAO,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;IACvC,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACvB,kFAAkF;IAClF,UAAU,IAAI,IAAI,CAAC;IACnB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,qBAAqB,GAAG,cAAc,CAkB7E"}
|