@pingroom/sdk 0.7.1 → 0.9.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 +288 -44
- package/dist/client.d.ts +27 -312
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +33 -1154
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +40 -6
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +56 -4
- package/dist/errors.js.map +1 -1
- package/dist/http.d.ts +12 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +47 -18
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/internal/async.d.ts +2 -0
- package/dist/internal/async.d.ts.map +1 -1
- package/dist/internal/async.js +6 -0
- package/dist/internal/async.js.map +1 -1
- package/dist/internal/guards.d.ts +16 -0
- package/dist/internal/guards.d.ts.map +1 -1
- package/dist/internal/guards.js +22 -1
- package/dist/internal/guards.js.map +1 -1
- package/dist/internal/request.d.ts +41 -0
- package/dist/internal/request.d.ts.map +1 -0
- package/dist/internal/request.js +78 -0
- package/dist/internal/request.js.map +1 -0
- package/dist/internal/retry.d.ts +65 -0
- package/dist/internal/retry.d.ts.map +1 -0
- package/dist/internal/retry.js +126 -0
- package/dist/internal/retry.js.map +1 -0
- package/dist/internal/url.d.ts +9 -0
- package/dist/internal/url.d.ts.map +1 -1
- package/dist/internal/url.js +25 -0
- package/dist/internal/url.js.map +1 -1
- package/dist/internal/validate.d.ts +13 -0
- package/dist/internal/validate.d.ts.map +1 -0
- package/dist/internal/validate.js +36 -0
- package/dist/internal/validate.js.map +1 -0
- package/dist/linkPing.d.ts.map +1 -1
- package/dist/linkPing.js +6 -2
- package/dist/linkPing.js.map +1 -1
- package/dist/liveStatus.d.ts +106 -11
- package/dist/liveStatus.d.ts.map +1 -1
- package/dist/liveStatus.js +20 -3
- package/dist/liveStatus.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +40 -10
- package/dist/mcp.js.map +1 -1
- package/dist/namespaces/actions.d.ts +50 -0
- package/dist/namespaces/actions.d.ts.map +1 -0
- package/dist/namespaces/actions.js +219 -0
- package/dist/namespaces/actions.js.map +1 -0
- package/dist/namespaces/approvals.d.ts +23 -0
- package/dist/namespaces/approvals.d.ts.map +1 -0
- package/dist/namespaces/approvals.js +78 -0
- package/dist/namespaces/approvals.js.map +1 -0
- package/dist/namespaces/attachments.d.ts +37 -0
- package/dist/namespaces/attachments.d.ts.map +1 -0
- package/dist/namespaces/attachments.js +91 -0
- package/dist/namespaces/attachments.js.map +1 -0
- package/dist/namespaces/auth.d.ts +58 -0
- package/dist/namespaces/auth.d.ts.map +1 -0
- package/dist/namespaces/auth.js +242 -0
- package/dist/namespaces/auth.js.map +1 -0
- package/dist/namespaces/directory.d.ts +10 -0
- package/dist/namespaces/directory.d.ts.map +1 -0
- package/dist/namespaces/directory.js +19 -0
- package/dist/namespaces/directory.js.map +1 -0
- package/dist/namespaces/handoffs.d.ts +47 -0
- package/dist/namespaces/handoffs.d.ts.map +1 -0
- package/dist/namespaces/handoffs.js +126 -0
- package/dist/namespaces/handoffs.js.map +1 -0
- package/dist/namespaces/inbox.d.ts +17 -0
- package/dist/namespaces/inbox.d.ts.map +1 -0
- package/dist/namespaces/inbox.js +192 -0
- package/dist/namespaces/inbox.js.map +1 -0
- package/dist/namespaces/live.d.ts +57 -0
- package/dist/namespaces/live.d.ts.map +1 -0
- package/dist/namespaces/live.js +116 -0
- package/dist/namespaces/live.js.map +1 -0
- package/dist/namespaces/notifications.d.ts +25 -0
- package/dist/namespaces/notifications.d.ts.map +1 -0
- package/dist/namespaces/notifications.js +128 -0
- package/dist/namespaces/notifications.js.map +1 -0
- package/dist/namespaces/profile.d.ts +19 -0
- package/dist/namespaces/profile.d.ts.map +1 -0
- package/dist/namespaces/profile.js +22 -0
- package/dist/namespaces/profile.js.map +1 -0
- package/dist/namespaces/questions.d.ts +41 -0
- package/dist/namespaces/questions.d.ts.map +1 -0
- package/dist/namespaces/questions.js +107 -0
- package/dist/namespaces/questions.js.map +1 -0
- package/dist/namespaces/rooms.d.ts +13 -0
- package/dist/namespaces/rooms.d.ts.map +1 -0
- package/dist/namespaces/rooms.js +41 -0
- package/dist/namespaces/rooms.js.map +1 -0
- package/dist/namespaces/webhooks.d.ts +11 -0
- package/dist/namespaces/webhooks.d.ts.map +1 -0
- package/dist/namespaces/webhooks.js +32 -0
- package/dist/namespaces/webhooks.js.map +1 -0
- package/dist/types/approvals.d.ts +62 -0
- package/dist/types/approvals.d.ts.map +1 -0
- package/dist/types/approvals.js +2 -0
- package/dist/types/approvals.js.map +1 -0
- package/dist/types/auth.d.ts +185 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +2 -0
- package/dist/types/auth.js.map +1 -0
- package/dist/types/common.d.ts +43 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +2 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/handoffs.d.ts +121 -0
- package/dist/types/handoffs.d.ts.map +1 -0
- package/dist/types/handoffs.js +2 -0
- package/dist/types/handoffs.js.map +1 -0
- package/dist/types/inbox.d.ts +51 -0
- package/dist/types/inbox.d.ts.map +1 -0
- package/dist/types/inbox.js +2 -0
- package/dist/types/inbox.js.map +1 -0
- package/dist/types/notifications.d.ts +376 -0
- package/dist/types/notifications.d.ts.map +1 -0
- package/dist/types/notifications.js +2 -0
- package/dist/types/notifications.js.map +1 -0
- package/dist/types/profile.d.ts +30 -0
- package/dist/types/profile.d.ts.map +1 -0
- package/dist/types/profile.js +3 -0
- package/dist/types/profile.js.map +1 -0
- package/dist/types/questions.d.ts +210 -0
- package/dist/types/questions.d.ts.map +1 -0
- package/dist/types/questions.js +2 -0
- package/dist/types/questions.js.map +1 -0
- package/dist/types/rooms.d.ts +163 -0
- package/dist/types/rooms.d.ts.map +1 -0
- package/dist/types/rooms.js +3 -0
- package/dist/types/rooms.js.map +1 -0
- package/dist/types.d.ts +9 -1035
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/webhooks.d.ts +32 -5
- package/dist/webhooks.d.ts.map +1 -1
- package/dist/webhooks.js +44 -14
- package/dist/webhooks.js.map +1 -1
- package/package.json +4 -2
- package/src/client.ts +115 -0
- package/src/errors.ts +291 -0
- package/src/http.ts +225 -0
- package/src/index.ts +97 -0
- package/src/internal/async.ts +54 -0
- package/src/internal/guards.ts +129 -0
- package/src/internal/request.ts +97 -0
- package/src/internal/retry.ts +157 -0
- package/src/internal/url.ts +78 -0
- package/src/internal/validate.ts +42 -0
- package/src/linkPing.ts +56 -0
- package/src/liveStatus.ts +337 -0
- package/src/locationPing.ts +101 -0
- package/src/mcp.ts +161 -0
- package/src/namespaces/actions.ts +234 -0
- package/src/namespaces/approvals.ts +104 -0
- package/src/namespaces/attachments.ts +106 -0
- package/src/namespaces/auth.ts +284 -0
- package/src/namespaces/directory.ts +21 -0
- package/src/namespaces/handoffs.ts +160 -0
- package/src/namespaces/inbox.ts +253 -0
- package/src/namespaces/live.ts +134 -0
- package/src/namespaces/notifications.ts +152 -0
- package/src/namespaces/profile.ts +24 -0
- package/src/namespaces/questions.ts +133 -0
- package/src/namespaces/rooms.ts +53 -0
- package/src/namespaces/webhooks.ts +38 -0
- package/src/types/approvals.ts +67 -0
- package/src/types/auth.ts +202 -0
- package/src/types/common.ts +74 -0
- package/src/types/handoffs.ts +148 -0
- package/src/types/inbox.ts +64 -0
- package/src/types/notifications.ts +393 -0
- package/src/types/profile.ts +37 -0
- package/src/types/questions.ts +226 -0
- package/src/types/rooms.ts +169 -0
- package/src/types.ts +17 -0
- package/src/version.ts +2 -0
- package/src/webhooks.ts +373 -0
- package/dist/liveActivity.d.ts +0 -101
- package/dist/liveActivity.d.ts.map +0 -1
- package/dist/liveActivity.js +0 -83
- package/dist/liveActivity.js.map +0 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { HttpClient } from '../http.js';
|
|
2
|
+
import type { Approval, ApprovalInput, WaitApprovalInput, WaitForOutcomeOptions } from '../types.js';
|
|
3
|
+
export declare class ApprovalsApi {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: HttpClient);
|
|
6
|
+
/** Ask the human you act for to decide; returns the pending approval. */
|
|
7
|
+
request(inviteCode: string, input: ApprovalInput): Promise<Approval>;
|
|
8
|
+
get(approvalId: string): Promise<Approval>;
|
|
9
|
+
/** One long-poll for the decision; returns the (possibly still-pending) approval. */
|
|
10
|
+
wait(approvalId: string, input?: WaitApprovalInput): Promise<Approval>;
|
|
11
|
+
/**
|
|
12
|
+
* Block until the human decides (or the request expires or is cancelled),
|
|
13
|
+
* looping wait() under the hood, with polls started at least 2.1 s apart. A
|
|
14
|
+
* response that is not this approval in a known status rejects with
|
|
15
|
+
* `invalid_response`. Network failures, 429 and 5xx are retried with backoff
|
|
16
|
+
* (honouring `retryAfter`), and reported to `onRetry`, until `signal` aborts
|
|
17
|
+
* or the outage outlasts the approval's `expires_at` by 5 minutes (15 minutes
|
|
18
|
+
* of failures while no `expires_at` has been read); that rejects with
|
|
19
|
+
* `unavailable`. See {@link WaitForOutcomeOptions}.
|
|
20
|
+
*/
|
|
21
|
+
waitForDecision(approvalId: string, input?: WaitForOutcomeOptions): Promise<Approval>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=approvals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../src/namespaces/approvals.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,aAAa,CAAC;AA0CrB,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,yEAAyE;IACzE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC;IAUpE,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAI1C,qFAAqF;IACrF,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,iBAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQ1E;;;;;;;;;OASG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,qBAA0B,GAAG,OAAO,CAAC,QAAQ,CAAC;CAchG"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// `pr.approvals`: two-option human-in-the-loop decisions.
|
|
2
|
+
import { assertStructuredData, requireNonEmpty } from '../internal/guards.js';
|
|
3
|
+
import { pollUntilSettled } from '../internal/retry.js';
|
|
4
|
+
import { MIN_WAIT_POLL_INTERVAL_MS, enc, splitIdempotencyKey, assertOnRetry, dropUndefined, waitTimeoutMs, } from '../internal/request.js';
|
|
5
|
+
import { isRecord, isNonEmptyString, isNullableString, sameId, invalidWaitResponse, } from '../internal/validate.js';
|
|
6
|
+
const APPROVAL_STATUSES = new Set(['pending', 'decided', 'expired', 'cancelled']);
|
|
7
|
+
/**
|
|
8
|
+
* A wait response is trusted as an outcome only when it is the approval that
|
|
9
|
+
* was asked about, in a known status. A captive portal's HTML, `{}`, or another
|
|
10
|
+
* approval must not read as "decided".
|
|
11
|
+
*/
|
|
12
|
+
function validateApprovalWait(value, approvalId) {
|
|
13
|
+
const status = isRecord(value) ? value['status'] : undefined;
|
|
14
|
+
if (!isRecord(value)
|
|
15
|
+
|| !sameId(value['id'], approvalId)
|
|
16
|
+
|| typeof status !== 'string'
|
|
17
|
+
|| !APPROVAL_STATUSES.has(status)
|
|
18
|
+
|| !isNullableString(value['decided_at'])
|
|
19
|
+
// A gate acts on `decision`; a decided approval without one, or a pending
|
|
20
|
+
// one already stamped decided, is not an outcome it can act on.
|
|
21
|
+
|| (status === 'decided' && !isNonEmptyString(value['decision']))
|
|
22
|
+
|| (status === 'pending' && value['decided_at'] !== null)) {
|
|
23
|
+
return invalidWaitResponse('approval', approvalId, value, 'status');
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
export class ApprovalsApi {
|
|
28
|
+
http;
|
|
29
|
+
constructor(http) {
|
|
30
|
+
this.http = http;
|
|
31
|
+
}
|
|
32
|
+
/** Ask the human you act for to decide; returns the pending approval. */
|
|
33
|
+
request(inviteCode, input) {
|
|
34
|
+
requireNonEmpty(input.question, 'question');
|
|
35
|
+
assertStructuredData(input.data);
|
|
36
|
+
const { body, headers } = splitIdempotencyKey(input);
|
|
37
|
+
return this.http.request('POST', `/api/agent/rooms/${enc(inviteCode)}/approvals`, {
|
|
38
|
+
body: dropUndefined({ ...body }),
|
|
39
|
+
...(headers ? { headers } : {}),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
get(approvalId) {
|
|
43
|
+
return this.http.request('GET', `/api/agent/approvals/${enc(approvalId)}`);
|
|
44
|
+
}
|
|
45
|
+
/** One long-poll for the decision; returns the (possibly still-pending) approval. */
|
|
46
|
+
wait(approvalId, input = {}) {
|
|
47
|
+
return this.http.request('GET', `/api/agent/approvals/${enc(approvalId)}/wait`, {
|
|
48
|
+
query: dropUndefined({ timeout: input.timeout }),
|
|
49
|
+
timeoutMs: waitTimeoutMs(input.timeout),
|
|
50
|
+
...(input.signal ? { signal: input.signal } : {}),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Block until the human decides (or the request expires or is cancelled),
|
|
55
|
+
* looping wait() under the hood, with polls started at least 2.1 s apart. A
|
|
56
|
+
* response that is not this approval in a known status rejects with
|
|
57
|
+
* `invalid_response`. Network failures, 429 and 5xx are retried with backoff
|
|
58
|
+
* (honouring `retryAfter`), and reported to `onRetry`, until `signal` aborts
|
|
59
|
+
* or the outage outlasts the approval's `expires_at` by 5 minutes (15 minutes
|
|
60
|
+
* of failures while no `expires_at` has been read); that rejects with
|
|
61
|
+
* `unavailable`. See {@link WaitForOutcomeOptions}.
|
|
62
|
+
*/
|
|
63
|
+
async waitForDecision(approvalId, input = {}) {
|
|
64
|
+
requireNonEmpty(approvalId, 'approvalId');
|
|
65
|
+
assertOnRetry(input.onRetry);
|
|
66
|
+
return pollUntilSettled({
|
|
67
|
+
poll: () => this.wait(approvalId, input.signal ? { signal: input.signal } : {}),
|
|
68
|
+
validate: (value) => validateApprovalWait(value, approvalId),
|
|
69
|
+
settled: (approval) => approval.status !== 'pending',
|
|
70
|
+
expiresAt: (approval) => approval.expires_at,
|
|
71
|
+
what: `approval ${approvalId}`,
|
|
72
|
+
minIntervalMs: MIN_WAIT_POLL_INTERVAL_MS,
|
|
73
|
+
...(input.signal ? { signal: input.signal } : {}),
|
|
74
|
+
...(input.onRetry ? { onRetry: input.onRetry } : {}),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=approvals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../src/namespaces/approvals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { HttpClient } from '../http.js';
|
|
2
|
+
import type { Attachment, ZipManifest, UploadAttachmentInput } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Private files that a Ping or Question can carry.
|
|
5
|
+
*
|
|
6
|
+
* Upload first, then pass the returned ids to `broadcast()` / `questions.ask()`
|
|
7
|
+
* as `attachment_ids`. Bytes never travel inside a JSON ping body (the MCP
|
|
8
|
+
* `upload_attachment` tool takes only small files, about 90 KiB, as base64). An
|
|
9
|
+
* upload that is never attached expires on its own after 24 hours.
|
|
10
|
+
* Each file must be 1 byte–5 MiB with an md/pdf/html/txt/jpg/jpeg/png/zip filename;
|
|
11
|
+
* a Ping or Question accepts at most four ids.
|
|
12
|
+
*
|
|
13
|
+
* Uploading requires the bound account to hold Pro (the API answers 402
|
|
14
|
+
* `pro_required` otherwise). Reading and deleting are not gated.
|
|
15
|
+
*/
|
|
16
|
+
export declare class AttachmentsApi {
|
|
17
|
+
private readonly http;
|
|
18
|
+
constructor(http: HttpClient);
|
|
19
|
+
/** Upload one file and get back the id a send can claim. */
|
|
20
|
+
upload(input: UploadAttachmentInput): Promise<Attachment>;
|
|
21
|
+
/**
|
|
22
|
+
* Raw bytes for an attachment this credential is allowed to see. Returns the
|
|
23
|
+
* undecoded Response so a caller can stream it, or read text/arrayBuffer.
|
|
24
|
+
*/
|
|
25
|
+
content(attachmentId: string, signal?: AbortSignal): Promise<Response>;
|
|
26
|
+
/**
|
|
27
|
+
* The listing of a `.zip`'s contents, recorded when it was uploaded.
|
|
28
|
+
*
|
|
29
|
+
* Resolves null for a non-archive, and for an archive whose central
|
|
30
|
+
* directory did not parse. Nothing decompresses the file to produce this, so
|
|
31
|
+
* the declared sizes are what the archive claims, not verified output.
|
|
32
|
+
*/
|
|
33
|
+
manifest(attachmentId: string, signal?: AbortSignal): Promise<ZipManifest | null>;
|
|
34
|
+
/** Discard an upload that has not been attached to a ping yet. */
|
|
35
|
+
delete(attachmentId: string): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=attachments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/namespaces/attachments.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAYlF;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,4DAA4D;IAC5D,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC;IAqBzD;;;OAGG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOtE;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAWjF,kEAAkE;IAClE,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAI5C"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// `pr.attachments`: upload, read and discard private files.
|
|
2
|
+
import { PingRoomError } from '../errors.js';
|
|
3
|
+
import { requireNonEmpty } from '../internal/guards.js';
|
|
4
|
+
import { enc } from '../internal/request.js';
|
|
5
|
+
/** Server cap per uploaded file; a larger body is a 413 the server answers before reading it. */
|
|
6
|
+
const ATTACHMENT_MAX_BYTES = 5 * 1024 * 1024;
|
|
7
|
+
function attachmentByteLength(content) {
|
|
8
|
+
if (content instanceof Blob)
|
|
9
|
+
return content.size;
|
|
10
|
+
if (typeof content === 'string')
|
|
11
|
+
return new TextEncoder().encode(content).byteLength;
|
|
12
|
+
return content.byteLength;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Private files that a Ping or Question can carry.
|
|
16
|
+
*
|
|
17
|
+
* Upload first, then pass the returned ids to `broadcast()` / `questions.ask()`
|
|
18
|
+
* as `attachment_ids`. Bytes never travel inside a JSON ping body (the MCP
|
|
19
|
+
* `upload_attachment` tool takes only small files, about 90 KiB, as base64). An
|
|
20
|
+
* upload that is never attached expires on its own after 24 hours.
|
|
21
|
+
* Each file must be 1 byte–5 MiB with an md/pdf/html/txt/jpg/jpeg/png/zip filename;
|
|
22
|
+
* a Ping or Question accepts at most four ids.
|
|
23
|
+
*
|
|
24
|
+
* Uploading requires the bound account to hold Pro (the API answers 402
|
|
25
|
+
* `pro_required` otherwise). Reading and deleting are not gated.
|
|
26
|
+
*/
|
|
27
|
+
export class AttachmentsApi {
|
|
28
|
+
http;
|
|
29
|
+
constructor(http) {
|
|
30
|
+
this.http = http;
|
|
31
|
+
}
|
|
32
|
+
/** Upload one file and get back the id a send can claim. */
|
|
33
|
+
upload(input) {
|
|
34
|
+
requireNonEmpty(input.filename, 'filename');
|
|
35
|
+
// The server answers an oversized body with 413 before reading it; refuse
|
|
36
|
+
// locally so no bytes travel for a file that can never be accepted.
|
|
37
|
+
if (attachmentByteLength(input.content) > ATTACHMENT_MAX_BYTES) {
|
|
38
|
+
return Promise.reject(new PingRoomError('Attachments are at most 5 MiB each.', { code: 'attachment_too_large', status: 413 }));
|
|
39
|
+
}
|
|
40
|
+
const body = new FormData();
|
|
41
|
+
body.append('file', toAttachmentBlob(input), input.filename);
|
|
42
|
+
return this.http
|
|
43
|
+
.request('POST', '/api/agent/attachments', {
|
|
44
|
+
body,
|
|
45
|
+
...(input.signal ? { signal: input.signal } : {}),
|
|
46
|
+
})
|
|
47
|
+
.then((res) => res.attachment);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Raw bytes for an attachment this credential is allowed to see. Returns the
|
|
51
|
+
* undecoded Response so a caller can stream it, or read text/arrayBuffer.
|
|
52
|
+
*/
|
|
53
|
+
content(attachmentId, signal) {
|
|
54
|
+
requireNonEmpty(attachmentId, 'attachmentId');
|
|
55
|
+
return this.http.raw('GET', `/api/agent/attachments/${enc(attachmentId)}/content`, {
|
|
56
|
+
...(signal ? { signal } : {}),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The listing of a `.zip`'s contents, recorded when it was uploaded.
|
|
61
|
+
*
|
|
62
|
+
* Resolves null for a non-archive, and for an archive whose central
|
|
63
|
+
* directory did not parse. Nothing decompresses the file to produce this, so
|
|
64
|
+
* the declared sizes are what the archive claims, not verified output.
|
|
65
|
+
*/
|
|
66
|
+
manifest(attachmentId, signal) {
|
|
67
|
+
requireNonEmpty(attachmentId, 'attachmentId');
|
|
68
|
+
return this.http
|
|
69
|
+
.request('GET', `/api/agent/attachments/${enc(attachmentId)}/manifest`, { ...(signal ? { signal } : {}) })
|
|
70
|
+
.then((res) => res.manifest ?? null);
|
|
71
|
+
}
|
|
72
|
+
/** Discard an upload that has not been attached to a ping yet. */
|
|
73
|
+
delete(attachmentId) {
|
|
74
|
+
requireNonEmpty(attachmentId, 'attachmentId');
|
|
75
|
+
return this.http.request('DELETE', `/api/agent/attachments/${enc(attachmentId)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Normalise the three accepted content shapes into one multipart part. */
|
|
79
|
+
function toAttachmentBlob(input) {
|
|
80
|
+
const type = input.contentType ?? '';
|
|
81
|
+
if (input.content instanceof Blob) {
|
|
82
|
+
return type ? new Blob([input.content], { type }) : input.content;
|
|
83
|
+
}
|
|
84
|
+
// Copy into a plain ArrayBuffer: a Uint8Array view may be a window onto a
|
|
85
|
+
// larger (or SharedArrayBuffer-backed) buffer, which Blob would not accept.
|
|
86
|
+
const parts = typeof input.content === 'string'
|
|
87
|
+
? [input.content]
|
|
88
|
+
: [new Uint8Array(input.content).slice().buffer];
|
|
89
|
+
return new Blob(parts, type ? { type } : undefined);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/namespaces/attachments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { HttpClient } from '../http.js';
|
|
2
|
+
import type { AgentConnectionInfo, AgentDisconnectResult, Credential, ClaimCompleteParams, ClaimStartParams, RegisterParams, PairingStart, PairingStatus, PairedCredential, StartPairingParams, WaitForPairingOptions } from '../types.js';
|
|
3
|
+
/** Agent credential lifecycle (auth.md flow). */
|
|
4
|
+
export declare class AuthApi {
|
|
5
|
+
private readonly http;
|
|
6
|
+
private pairing;
|
|
7
|
+
constructor(http: HttpClient);
|
|
8
|
+
/** Register an agent. Anonymous or via an identity assertion (ID-JAG / verified email). Public. */
|
|
9
|
+
register(params: RegisterParams): Promise<Credential>;
|
|
10
|
+
/** Begin claiming a pre-claim credential onto a human account; emails an OTP. */
|
|
11
|
+
claimStart(params: ClaimStartParams): Promise<{
|
|
12
|
+
message: string;
|
|
13
|
+
expires_in: number;
|
|
14
|
+
}>;
|
|
15
|
+
/** Complete the claim with the emailed OTP; returns an active credential + handle. */
|
|
16
|
+
claimComplete(params: ClaimCompleteParams): Promise<Credential>;
|
|
17
|
+
/**
|
|
18
|
+
* Register a pending agent and create a short-lived link that opens the
|
|
19
|
+
* PingRoom app. The server owns the full grant shown to the approver; this
|
|
20
|
+
* client sends no scope list. The pending credential stays private inside the
|
|
21
|
+
* client and is replaced automatically once waitForPairing() succeeds. If the
|
|
22
|
+
* client already held a credential, it is put back when the pairing expires
|
|
23
|
+
* or the wait is aborted, so a re-pairing that never completes leaves the
|
|
24
|
+
* client on the working credential rather than the dead pending one.
|
|
25
|
+
*/
|
|
26
|
+
startPairing(params?: StartPairingParams): Promise<PairingStart>;
|
|
27
|
+
/** Read the current state of an app pairing using the pending credential. */
|
|
28
|
+
pairingStatus(options?: Pick<WaitForPairingOptions, 'signal'>): Promise<PairingStatus>;
|
|
29
|
+
/**
|
|
30
|
+
* Wait until the person approves in PingRoom, or the short-lived link
|
|
31
|
+
* expires. Transient network, 429, and 5xx failures are retried inside the
|
|
32
|
+
* server-provided lifetime. On success the client immediately starts using
|
|
33
|
+
* the active credential returned by the server. When the link expires or the
|
|
34
|
+
* wait is aborted, the credential the client held before startPairing() is
|
|
35
|
+
* restored; calling waitForPairing() again after an abort resumes the same
|
|
36
|
+
* pairing.
|
|
37
|
+
*/
|
|
38
|
+
waitForPairing(pairing: PairingStart, options?: WaitForPairingOptions): Promise<PairedCredential>;
|
|
39
|
+
private pollPairing;
|
|
40
|
+
/** Rotate to a fresh credential (same scopes/handle). */
|
|
41
|
+
refresh(): Promise<Credential>;
|
|
42
|
+
/** Revoke the current credential. */
|
|
43
|
+
revoke(): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* What this credential is connected to: the robot, the owner's public id and
|
|
46
|
+
* name, the home room and room memberships, and the room grant. Check
|
|
47
|
+
* `owner.id` and `handle` against the account and robot you approved before
|
|
48
|
+
* sending anything.
|
|
49
|
+
*/
|
|
50
|
+
connection(): Promise<AgentConnectionInfo>;
|
|
51
|
+
/**
|
|
52
|
+
* Disconnect this agent: revokes the calling credential and its refresh
|
|
53
|
+
* credentials. The client keeps the now-revoked token; clear it with
|
|
54
|
+
* `setToken(null)` or pair again.
|
|
55
|
+
*/
|
|
56
|
+
disconnect(): Promise<AgentDisconnectResult>;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/namespaces/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACrB,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,aAAa,CAAC;AA2CrB,iDAAiD;AACjD,qBAAa,OAAO;IAGN,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,OAAO,CAA+B;gBAEjB,IAAI,EAAE,UAAU;IAE7C,mGAAmG;IACnG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAKrD,iFAAiF;IACjF,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAKtF,sFAAsF;IACtF,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAM/D;;;;;;;;OAQG;IACG,YAAY,CAAC,MAAM,GAAE,kBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC;IA8B1E,6EAA6E;IAC7E,aAAa,CAAC,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAI1F;;;;;;;;OAQG;IACG,cAAc,CAClB,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,gBAAgB,CAAC;YAyBd,WAAW;IAwFzB,yDAAyD;IACzD,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAI9B,qCAAqC;IACrC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB;;;;;OAKG;IACH,UAAU,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAI1C;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,qBAAqB,CAAC;CAG7C"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
// `pr.auth`: registration, claim, app pairing and the credential lifecycle.
|
|
2
|
+
import { PingRoomError } from '../errors.js';
|
|
3
|
+
import { sleep, throwIfAborted } from '../internal/async.js';
|
|
4
|
+
import { requireNonEmpty } from '../internal/guards.js';
|
|
5
|
+
import { dropUndefined } from '../internal/request.js';
|
|
6
|
+
import { isRecord } from '../internal/validate.js';
|
|
7
|
+
/** Drop a malformed or unsafe server-provided URL without rejecting its response. */
|
|
8
|
+
function normalizePublicHttpUrl(candidate) {
|
|
9
|
+
if (typeof candidate !== 'string' || candidate.trim() === '')
|
|
10
|
+
return undefined;
|
|
11
|
+
const trimmed = candidate.trim();
|
|
12
|
+
// eslint-disable-next-line no-control-regex
|
|
13
|
+
if (/[\u0000-\u001F\u007F-\u009F]/.test(trimmed))
|
|
14
|
+
return undefined;
|
|
15
|
+
try {
|
|
16
|
+
const url = new URL(trimmed);
|
|
17
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:')
|
|
18
|
+
return undefined;
|
|
19
|
+
if (url.username !== '' || url.password !== '')
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return trimmed;
|
|
26
|
+
}
|
|
27
|
+
/** Drop malformed or unsafe server-provided links without rejecting a valid credential. */
|
|
28
|
+
function normalizePairingLinks(value) {
|
|
29
|
+
if (!isRecord(value))
|
|
30
|
+
return undefined;
|
|
31
|
+
const latestPings = normalizePublicHttpUrl(value['latest_pings']);
|
|
32
|
+
if (!latestPings)
|
|
33
|
+
return undefined;
|
|
34
|
+
const installApp = normalizePublicHttpUrl(value['install_app']);
|
|
35
|
+
return {
|
|
36
|
+
latest_pings: latestPings,
|
|
37
|
+
...(installApp ? { install_app: installApp } : {}),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Agent credential lifecycle (auth.md flow). */
|
|
41
|
+
export class AuthApi {
|
|
42
|
+
http;
|
|
43
|
+
pairing = null;
|
|
44
|
+
constructor(http) {
|
|
45
|
+
this.http = http;
|
|
46
|
+
}
|
|
47
|
+
/** Register an agent. Anonymous or via an identity assertion (ID-JAG / verified email). Public. */
|
|
48
|
+
register(params) {
|
|
49
|
+
requireNonEmpty(params.type, 'type');
|
|
50
|
+
return this.http.request('POST', '/api/agent/auth', { auth: false, body: dropUndefined({ ...params }) });
|
|
51
|
+
}
|
|
52
|
+
/** Begin claiming a pre-claim credential onto a human account; emails an OTP. */
|
|
53
|
+
claimStart(params) {
|
|
54
|
+
requireNonEmpty(params.email, 'email');
|
|
55
|
+
return this.http.request('POST', '/api/agent/auth/claim/start', { body: { email: params.email } });
|
|
56
|
+
}
|
|
57
|
+
/** Complete the claim with the emailed OTP; returns an active credential + handle. */
|
|
58
|
+
claimComplete(params) {
|
|
59
|
+
requireNonEmpty(params.email, 'email');
|
|
60
|
+
requireNonEmpty(params.otp, 'otp');
|
|
61
|
+
return this.http.request('POST', '/api/agent/auth/claim/complete', { body: dropUndefined({ ...params }) });
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Register a pending agent and create a short-lived link that opens the
|
|
65
|
+
* PingRoom app. The server owns the full grant shown to the approver; this
|
|
66
|
+
* client sends no scope list. The pending credential stays private inside the
|
|
67
|
+
* client and is replaced automatically once waitForPairing() succeeds. If the
|
|
68
|
+
* client already held a credential, it is put back when the pairing expires
|
|
69
|
+
* or the wait is aborted, so a re-pairing that never completes leaves the
|
|
70
|
+
* client on the working credential rather than the dead pending one.
|
|
71
|
+
*/
|
|
72
|
+
async startPairing(params = {}) {
|
|
73
|
+
const previousToken = this.http.getToken();
|
|
74
|
+
const pending = await this.register({
|
|
75
|
+
type: 'anonymous',
|
|
76
|
+
...(params.agent_label ? { agent_label: params.agent_label } : {}),
|
|
77
|
+
});
|
|
78
|
+
this.http.setToken(pending.credential);
|
|
79
|
+
try {
|
|
80
|
+
const started = await this.http.request('POST', '/api/agent/auth/pair/start', {
|
|
81
|
+
body: {},
|
|
82
|
+
});
|
|
83
|
+
// A second pairing started while the first is still pending falls back
|
|
84
|
+
// to the credential beneath it, not to the first pairing's pending one.
|
|
85
|
+
this.pairing = {
|
|
86
|
+
pairToken: started.pair_token,
|
|
87
|
+
pending: pending.credential,
|
|
88
|
+
previous: this.pairing !== null && this.pairing.pending === previousToken
|
|
89
|
+
? this.pairing.previous
|
|
90
|
+
: previousToken,
|
|
91
|
+
};
|
|
92
|
+
return started;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (this.http.getToken() === pending.credential) {
|
|
96
|
+
this.http.setToken(previousToken);
|
|
97
|
+
}
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** Read the current state of an app pairing using the pending credential. */
|
|
102
|
+
pairingStatus(options = {}) {
|
|
103
|
+
return this.http.request('GET', '/api/agent/auth/pair/status', { signal: options.signal });
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Wait until the person approves in PingRoom, or the short-lived link
|
|
107
|
+
* expires. Transient network, 429, and 5xx failures are retried inside the
|
|
108
|
+
* server-provided lifetime. On success the client immediately starts using
|
|
109
|
+
* the active credential returned by the server. When the link expires or the
|
|
110
|
+
* wait is aborted, the credential the client held before startPairing() is
|
|
111
|
+
* restored; calling waitForPairing() again after an abort resumes the same
|
|
112
|
+
* pairing.
|
|
113
|
+
*/
|
|
114
|
+
async waitForPairing(pairing, options = {}) {
|
|
115
|
+
const tracked = this.pairing !== null && this.pairing.pairToken === pairing.pair_token
|
|
116
|
+
? this.pairing
|
|
117
|
+
: null;
|
|
118
|
+
if (tracked !== null && this.http.getToken() === tracked.previous) {
|
|
119
|
+
// Resuming after an abort put the earlier credential back.
|
|
120
|
+
this.http.setToken(tracked.pending);
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const paired = await this.pollPairing(pairing, options);
|
|
124
|
+
if (tracked !== null && this.pairing === tracked)
|
|
125
|
+
this.pairing = null;
|
|
126
|
+
return paired;
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (tracked !== null && this.pairing === tracked) {
|
|
130
|
+
const expired = error instanceof PingRoomError && error.code === 'pairing_expired';
|
|
131
|
+
if (expired || options.signal?.aborted === true) {
|
|
132
|
+
if (this.http.getToken() === tracked.pending)
|
|
133
|
+
this.http.setToken(tracked.previous);
|
|
134
|
+
}
|
|
135
|
+
// An expired pairing cannot be resumed; an aborted one can.
|
|
136
|
+
if (expired)
|
|
137
|
+
this.pairing = null;
|
|
138
|
+
}
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async pollPairing(pairing, options) {
|
|
143
|
+
const lifetimeMs = Math.max(1, Number(pairing.expires_in) || 900) * 1000;
|
|
144
|
+
const requestedInterval = options.pollIntervalMs ?? pairing.poll_interval_ms;
|
|
145
|
+
const intervalMs = Math.min(Math.max(Number(requestedInterval) || 1500, 1000), 10_000);
|
|
146
|
+
const startedAt = Date.now();
|
|
147
|
+
const deadline = startedAt + lifetimeMs;
|
|
148
|
+
let transientFailures = 0;
|
|
149
|
+
while (Date.now() < deadline) {
|
|
150
|
+
throwIfAborted(options.signal);
|
|
151
|
+
try {
|
|
152
|
+
const status = await this.pairingStatus({ signal: options.signal });
|
|
153
|
+
throwIfAborted(options.signal);
|
|
154
|
+
transientFailures = 0;
|
|
155
|
+
if (status.status === 'active') {
|
|
156
|
+
if (typeof status.credential !== 'string'
|
|
157
|
+
|| status.credential.trim() === ''
|
|
158
|
+
|| status.credential_type !== 'active'
|
|
159
|
+
|| (status.expires_in !== null
|
|
160
|
+
&& (typeof status.expires_in !== 'number'
|
|
161
|
+
|| !Number.isFinite(status.expires_in)
|
|
162
|
+
|| status.expires_in < 0))
|
|
163
|
+
// A null/absent `room` is valid when the account has no eligible
|
|
164
|
+
// private delivery room (and on older servers). Only a room that is
|
|
165
|
+
// present but malformed is a broken response.
|
|
166
|
+
|| (status.room != null
|
|
167
|
+
&& (typeof status.room.invite_code !== 'string'
|
|
168
|
+
|| status.room.invite_code.trim() === ''))) {
|
|
169
|
+
throw new PingRoomError('PingRoom returned an incomplete approved pairing.', {
|
|
170
|
+
code: 'pairing_invalid_response',
|
|
171
|
+
body: { status: status.status },
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
this.http.setToken(status.credential);
|
|
175
|
+
// Pairing is server-authoritative. Some servers still include their
|
|
176
|
+
// internal grant marker for protocol compatibility; it is neither a
|
|
177
|
+
// client input nor part of the paired credential surface.
|
|
178
|
+
const { status: _status, scopes: _serverScopes, links: rawLinks, ...credential } = status;
|
|
179
|
+
const links = normalizePairingLinks(rawLinks);
|
|
180
|
+
return links ? { ...credential, links } : credential;
|
|
181
|
+
}
|
|
182
|
+
if (status.status === 'expired') {
|
|
183
|
+
throw new PingRoomError('The PingRoom pairing link expired before it was approved.', {
|
|
184
|
+
code: 'pairing_expired',
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if (error instanceof PingRoomError
|
|
190
|
+
&& [401, 403, 404].includes(error.status)
|
|
191
|
+
&& Date.now() - startedAt >= lifetimeMs / 2) {
|
|
192
|
+
// The pending bearer can expire before the server returns an
|
|
193
|
+
// explicit expired pairing state. Keep early auth failures intact.
|
|
194
|
+
throw new PingRoomError('The PingRoom pairing link expired before it was approved.', {
|
|
195
|
+
code: 'pairing_expired',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (error instanceof PingRoomError
|
|
199
|
+
&& (error.code === 'network_error'
|
|
200
|
+
|| error.code === 'timeout'
|
|
201
|
+
|| error.status === 429
|
|
202
|
+
|| error.status >= 500)) {
|
|
203
|
+
transientFailures += 1;
|
|
204
|
+
const backoffMs = Math.min(intervalMs * 2 ** Math.max(0, transientFailures - 3), 30_000);
|
|
205
|
+
await sleep(Math.max(0, Math.min(backoffMs, deadline - Date.now())), options.signal);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
await sleep(Math.max(0, Math.min(intervalMs, deadline - Date.now())), options.signal);
|
|
211
|
+
}
|
|
212
|
+
throw new PingRoomError('The PingRoom pairing link expired before it was approved.', {
|
|
213
|
+
code: 'pairing_expired',
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/** Rotate to a fresh credential (same scopes/handle). */
|
|
217
|
+
refresh() {
|
|
218
|
+
return this.http.request('POST', '/api/agent/auth/refresh', { body: {} });
|
|
219
|
+
}
|
|
220
|
+
/** Revoke the current credential. */
|
|
221
|
+
revoke() {
|
|
222
|
+
return this.http.request('POST', '/api/agent/auth/revoke', { body: {} });
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* What this credential is connected to: the robot, the owner's public id and
|
|
226
|
+
* name, the home room and room memberships, and the room grant. Check
|
|
227
|
+
* `owner.id` and `handle` against the account and robot you approved before
|
|
228
|
+
* sending anything.
|
|
229
|
+
*/
|
|
230
|
+
connection() {
|
|
231
|
+
return this.http.request('GET', '/api/agent/connection');
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Disconnect this agent: revokes the calling credential and its refresh
|
|
235
|
+
* credentials. The client keeps the now-revoked token; clear it with
|
|
236
|
+
* `setToken(null)` or pair again.
|
|
237
|
+
*/
|
|
238
|
+
disconnect() {
|
|
239
|
+
return this.http.request('POST', '/api/agent/disconnect', { body: {} });
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/namespaces/auth.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAcxD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,qFAAqF;AACrF,SAAS,sBAAsB,CAAC,SAAkB;IAChD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC/E,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IACjC,4CAA4C;IAC5C,IAAI,8BAA8B,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IACnE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO;YAAE,OAAO,SAAS,CAAC;QAC5E,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE;YAAE,OAAO,SAAS,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,2FAA2F;AAC3F,SAAS,qBAAqB,CAAC,KAAc;IAC3C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,MAAM,WAAW,GAAG,sBAAsB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;IAClE,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,UAAU,GAAG,sBAAsB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IAChE,OAAO;QACL,YAAY,EAAE,WAAW;QACzB,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnD,CAAC;AACJ,CAAC;AAaD,iDAAiD;AACjD,MAAM,OAAO,OAAO;IAGW;IAFrB,OAAO,GAA0B,IAAI,CAAC;IAE9C,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAEjD,mGAAmG;IACnG,QAAQ,CAAC,MAAsB;QAC7B,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3G,CAAC;IAED,iFAAiF;IACjF,UAAU,CAAC,MAAwB;QACjC,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,6BAA6B,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrG,CAAC;IAED,sFAAsF;IACtF,aAAa,CAAC,MAA2B;QACvC,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACvC,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,gCAAgC,EAAE,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7G,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,YAAY,CAAC,SAA6B,EAAE;QAChD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;YAClC,IAAI,EAAE,WAAW;YACjB,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAe,MAAM,EAAE,4BAA4B,EAAE;gBAC1F,IAAI,EAAE,EAAE;aACT,CAAC,CAAC;YACH,uEAAuE;YACvE,wEAAwE;YACxE,IAAI,CAAC,OAAO,GAAG;gBACb,SAAS,EAAE,OAAO,CAAC,UAAU;gBAC7B,OAAO,EAAE,OAAO,CAAC,UAAU;gBAC3B,QAAQ,EAAE,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,aAAa;oBACvE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ;oBACvB,CAAC,CAAC,aAAa;aAClB,CAAC;YACF,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;gBAChD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,aAAa,CAAC,UAAiD,EAAE;QAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,6BAA6B,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7F,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,cAAc,CAClB,OAAqB,EACrB,UAAiC,EAAE;QAEnC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,UAAU;YACpF,CAAC,CAAC,IAAI,CAAC,OAAO;YACd,CAAC,CAAC,IAAI,CAAC;QACT,IAAI,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;YAClE,2DAA2D;YAC3D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxD,IAAI,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO;gBAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACtE,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;gBACjD,MAAM,OAAO,GAAG,KAAK,YAAY,aAAa,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC;gBACnF,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;oBAChD,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,OAAO;wBAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACrF,CAAC;gBACD,4DAA4D;gBAC5D,IAAI,OAAO;oBAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACnC,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,WAAW,CACvB,OAAqB,EACrB,OAA8B;QAE9B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC;QACzE,MAAM,iBAAiB,GAAG,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,gBAAgB,CAAC;QAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACvF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;QACxC,IAAI,iBAAiB,GAAG,CAAC,CAAC;QAE1B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;YAC7B,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAE/B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpE,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC/B,iBAAiB,GAAG,CAAC,CAAC;gBAEtB,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC/B,IACE,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ;2BAClC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE;2BAC/B,MAAM,CAAC,eAAe,KAAK,QAAQ;2BACnC,CAAC,MAAM,CAAC,UAAU,KAAK,IAAI;+BACzB,CAAC,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ;mCACpC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC;mCACnC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;wBAC9B,iEAAiE;wBACjE,oEAAoE;wBACpE,8CAA8C;2BAC3C,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI;+BAClB,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,QAAQ;mCAC1C,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAC9C,CAAC;wBACD,MAAM,IAAI,aAAa,CAAC,mDAAmD,EAAE;4BAC3E,IAAI,EAAE,0BAA0B;4BAChC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;yBAChC,CAAC,CAAC;oBACL,CAAC;oBACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;oBACtC,oEAAoE;oBACpE,oEAAoE;oBACpE,0DAA0D;oBAC1D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC;oBAC1F,MAAM,KAAK,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;oBAC9C,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;gBACvD,CAAC;gBACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAChC,MAAM,IAAI,aAAa,CAAC,2DAA2D,EAAE;wBACnF,IAAI,EAAE,iBAAiB;qBACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IACE,KAAK,YAAY,aAAa;uBAC3B,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;uBACtC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,UAAU,GAAG,CAAC,EAC3C,CAAC;oBACD,6DAA6D;oBAC7D,mEAAmE;oBACnE,MAAM,IAAI,aAAa,CAAC,2DAA2D,EAAE;wBACnF,IAAI,EAAE,iBAAiB;qBACxB,CAAC,CAAC;gBACL,CAAC;gBACD,IACE,KAAK,YAAY,aAAa;uBAC3B,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe;2BAC7B,KAAK,CAAC,IAAI,KAAK,SAAS;2BACxB,KAAK,CAAC,MAAM,KAAK,GAAG;2BACpB,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,EACzB,CAAC;oBACD,iBAAiB,IAAI,CAAC,CAAC;oBACvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,iBAAiB,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;oBACzF,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;oBACrF,SAAS;gBACX,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACxF,CAAC;QAED,MAAM,IAAI,aAAa,CAAC,2DAA2D,EAAE;YACnF,IAAI,EAAE,iBAAiB;SACxB,CAAC,CAAC;IACL,CAAC;IAED,yDAAyD;IACzD,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,yBAAyB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,qCAAqC;IACrC,MAAM;QACJ,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,wBAAwB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;OAKG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC;IAC3D,CAAC;IAED;;;;OAIG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,uBAAuB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1E,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HttpClient } from '../http.js';
|
|
2
|
+
import type { DirectoryEntry, DirectoryListInput, DirectoryProfile, Paginated } from '../types.js';
|
|
3
|
+
/** Public, unauthenticated agent directory. */
|
|
4
|
+
export declare class DirectoryApi {
|
|
5
|
+
private readonly http;
|
|
6
|
+
constructor(http: HttpClient);
|
|
7
|
+
list(input?: DirectoryListInput): Promise<Paginated<DirectoryEntry>>;
|
|
8
|
+
get(handle: string): Promise<DirectoryProfile>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=directory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/namespaces/directory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGnG,+CAA+C;AAC/C,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,CAAC,KAAK,GAAE,kBAAuB,GAAG,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAOxE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAG/C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// `pr.directory`: the public agent directory.
|
|
2
|
+
import { enc, dropUndefined } from '../internal/request.js';
|
|
3
|
+
/** Public, unauthenticated agent directory. */
|
|
4
|
+
export class DirectoryApi {
|
|
5
|
+
http;
|
|
6
|
+
constructor(http) {
|
|
7
|
+
this.http = http;
|
|
8
|
+
}
|
|
9
|
+
list(input = {}) {
|
|
10
|
+
return this.http.request('GET', '/api/agents/directory', {
|
|
11
|
+
auth: false,
|
|
12
|
+
query: dropUndefined({ ...input }),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
get(handle) {
|
|
16
|
+
return this.http.request('GET', `/api/agents/directory/${enc(handle)}`, { auth: false });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/namespaces/directory.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAI9C,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,+CAA+C;AAC/C,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAEjD,IAAI,CAAC,QAA4B,EAAE;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,uBAAuB,EAAE;YACvD,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;SACnC,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,MAAc;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,yBAAyB,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3F,CAAC;CACF"}
|