initiative-plugin-sdk 2.0.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/LICENSE +21 -0
- package/README.md +656 -0
- package/dist/build.d.ts +52 -0
- package/dist/build.js +229 -0
- package/dist/build.js.map +1 -0
- package/dist/cli.d.ts +24 -0
- package/dist/cli.js +160 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +288 -0
- package/dist/client.js +539 -0
- package/dist/client.js.map +1 -0
- package/dist/contract.d.ts +1247 -0
- package/dist/contract.js +167 -0
- package/dist/contract.js.map +1 -0
- package/dist/define.d.ts +336 -0
- package/dist/define.js +120 -0
- package/dist/define.js.map +1 -0
- package/dist/dev.d.ts +28 -0
- package/dist/dev.js +147 -0
- package/dist/dev.js.map +1 -0
- package/dist/expression.d.ts +28 -0
- package/dist/expression.js +67 -0
- package/dist/expression.js.map +1 -0
- package/dist/init.d.ts +14 -0
- package/dist/init.js +52 -0
- package/dist/init.js.map +1 -0
- package/dist/keys.d.ts +85 -0
- package/dist/keys.js +109 -0
- package/dist/keys.js.map +1 -0
- package/dist/manifest.d.ts +8 -0
- package/dist/manifest.js +8 -0
- package/dist/manifest.js.map +1 -0
- package/dist/pack.d.ts +35 -0
- package/dist/pack.js +84 -0
- package/dist/pack.js.map +1 -0
- package/dist/plugin-api.generated.d.ts +4263 -0
- package/dist/plugin-api.generated.js +1019 -0
- package/dist/plugin-api.generated.js.map +1 -0
- package/dist/server.d.ts +75 -0
- package/dist/server.js +408 -0
- package/dist/server.js.map +1 -0
- package/dist/testing.d.ts +116 -0
- package/dist/testing.js +386 -0
- package/dist/testing.js.map +1 -0
- package/dist/tokens.d.ts +161 -0
- package/dist/tokens.js +215 -0
- package/dist/tokens.js.map +1 -0
- package/dist/validate.d.ts +86 -0
- package/dist/validate.js +997 -0
- package/dist/validate.js.map +1 -0
- package/dist/widget.d.ts +235 -0
- package/dist/widget.js +26 -0
- package/dist/widget.js.map +1 -0
- package/examples/minimal/README.md +48 -0
- package/examples/minimal/assets/avatar.png +0 -0
- package/examples/minimal/package.json +22 -0
- package/examples/minimal/src/plugin.ts +77 -0
- package/examples/minimal/src/widgets/open-issues.ts +11 -0
- package/examples/minimal/test/fixtures/issues-statistics.json +9 -0
- package/examples/minimal/test/issue-counts.test.ts +48 -0
- package/examples/minimal/tsconfig.json +14 -0
- package/manifest.contract.json +1886 -0
- package/package.json +92 -0
- package/schemas/plugin-manifest.json +1747 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initiative, as a plug-in reaches it.
|
|
3
|
+
*
|
|
4
|
+
* A plug-in authenticates with its own key (`private_key_jwt`, RFC 7523) at
|
|
5
|
+
* `POST {baseUrl}/plugin-platform/oauth/token` and acts with one of two tokens:
|
|
6
|
+
*
|
|
7
|
+
* - an **installation token** (`client_credentials` + `installation`), acting as
|
|
8
|
+
* the community that installed the plug-in, with the scopes it granted;
|
|
9
|
+
* - a **member token** (the JWT-bearer grant, RFC 7523 §2.1), acting for one
|
|
10
|
+
* member, within what that member consented to.
|
|
11
|
+
*
|
|
12
|
+
* Either can be narrowed to one initiative the plug-in is placed in (RFC 8707) and
|
|
13
|
+
* to fewer scopes (RFC 6749 §3.3). {@link Initiative.asInstallation} and
|
|
14
|
+
* {@link Initiative.asMember} each give a {@link Client} acting that way; a
|
|
15
|
+
* handler is handed one already acting for its call. {@link Client.api} holds
|
|
16
|
+
* a typed method for every route Initiative's plug-in API describes, generated
|
|
17
|
+
* from that description.
|
|
18
|
+
*
|
|
19
|
+
* Tokens are opaque and never read. The token response says how long each
|
|
20
|
+
* lives and which scopes it holds: a call needing a scope the token does not
|
|
21
|
+
* hold fails before it is sent, naming the scope. Tokens are cached until 30
|
|
22
|
+
* seconds before they expire, concurrent callers share one request, and a
|
|
23
|
+
* call answered 401 is sent once more on a fresh token.
|
|
24
|
+
*/
|
|
25
|
+
import { randomUUID } from "node:crypto";
|
|
26
|
+
import { PluginApi, pluginApiOperations, } from "./plugin-api.generated.js";
|
|
27
|
+
import { signJwt } from "./keys.js";
|
|
28
|
+
export { generatePluginKeys, jwkThumbprint, loadPrivateKey, publicJwks, } from "./keys.js";
|
|
29
|
+
const CLIENT_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
|
|
30
|
+
const JWT_BEARER_GRANT = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
31
|
+
const ASSERTION_LIFETIME_SECONDS = 60;
|
|
32
|
+
const TOKEN_EXPIRY_SKEW_SECONDS = 30;
|
|
33
|
+
/**
|
|
34
|
+
* Community routes are addressed `/c/{community}/…`. With a plug-in's token the
|
|
35
|
+
* community is the token's and the segment is not read, so the client always
|
|
36
|
+
* writes `0` there.
|
|
37
|
+
*/
|
|
38
|
+
const COMMUNITY_PREFIX = "/c/0";
|
|
39
|
+
/** The token endpoint refused (RFC 6749 §5.2). */
|
|
40
|
+
export class InitiativeAuthError extends Error {
|
|
41
|
+
error;
|
|
42
|
+
errorDescription;
|
|
43
|
+
status;
|
|
44
|
+
constructor(
|
|
45
|
+
/** `invalid_client`, `invalid_grant`, `invalid_scope`, … */
|
|
46
|
+
error, errorDescription, status) {
|
|
47
|
+
super(errorDescription ? `${error}: ${errorDescription}` : error);
|
|
48
|
+
this.error = error;
|
|
49
|
+
this.errorDescription = errorDescription;
|
|
50
|
+
this.status = status;
|
|
51
|
+
this.name = "InitiativeAuthError";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** The member has not consented to this purpose, or no longer can be acted for. */
|
|
55
|
+
export class ConsentRequiredError extends InitiativeAuthError {
|
|
56
|
+
constructor(errorDescription, status) {
|
|
57
|
+
super("consent_required", errorDescription, status);
|
|
58
|
+
this.name = "ConsentRequiredError";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** A call to Initiative answered with an error status. */
|
|
62
|
+
export class InitiativeApiError extends Error {
|
|
63
|
+
status;
|
|
64
|
+
detail;
|
|
65
|
+
constructor(status,
|
|
66
|
+
/** Initiative's machine-readable `detail`, when the body carried one. */
|
|
67
|
+
detail) {
|
|
68
|
+
super(`Initiative answered ${status}${typeof detail === "string" ? `: ${detail}` : ""}`);
|
|
69
|
+
this.status = status;
|
|
70
|
+
this.detail = detail;
|
|
71
|
+
this.name = "InitiativeApiError";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* A call needs a scope the token does not hold. Nothing was sent. When any one
|
|
76
|
+
* of several would do, `scope` lists them, separated by spaces.
|
|
77
|
+
*/
|
|
78
|
+
export class MissingScopeError extends Error {
|
|
79
|
+
scope;
|
|
80
|
+
constructor(scope) {
|
|
81
|
+
super(`this call needs ${scope.includes(" ") ? `one of ${scope}` : scope}, which the token does not hold`);
|
|
82
|
+
this.scope = scope;
|
|
83
|
+
this.name = "MissingScopeError";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Whether `held` covers `scope`. Writing implies reading. */
|
|
87
|
+
export function grants(held, scope) {
|
|
88
|
+
if (held.includes(scope))
|
|
89
|
+
return true;
|
|
90
|
+
return scope.endsWith(":read") && held.includes(`${scope.slice(0, -":read".length)}:write`);
|
|
91
|
+
}
|
|
92
|
+
/** Issues, caches and spends the plug-in's tokens. */
|
|
93
|
+
class Tokens {
|
|
94
|
+
options;
|
|
95
|
+
baseUrl;
|
|
96
|
+
endpoint;
|
|
97
|
+
cache = new Map();
|
|
98
|
+
inflight = new Map();
|
|
99
|
+
fetch;
|
|
100
|
+
now;
|
|
101
|
+
constructor(options) {
|
|
102
|
+
this.options = options;
|
|
103
|
+
if (!options.publicId)
|
|
104
|
+
throw new TypeError("publicId is the plug-in's public id");
|
|
105
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
106
|
+
this.endpoint = `${this.baseUrl}/plugin-platform/oauth/token`;
|
|
107
|
+
this.fetch = options.fetch ?? fetch;
|
|
108
|
+
this.now = options.now ?? Date.now;
|
|
109
|
+
}
|
|
110
|
+
/** A token for the grant, from the cache while it is fresh. */
|
|
111
|
+
token(grant) {
|
|
112
|
+
const key = JSON.stringify(grant);
|
|
113
|
+
const hit = this.cache.get(key);
|
|
114
|
+
if (hit && this.now() < hit.expiresAt - TOKEN_EXPIRY_SKEW_SECONDS * 1000)
|
|
115
|
+
return Promise.resolve(hit);
|
|
116
|
+
const pending = this.inflight.get(key);
|
|
117
|
+
if (pending)
|
|
118
|
+
return pending;
|
|
119
|
+
const request = this.issue(grant)
|
|
120
|
+
.then((token) => {
|
|
121
|
+
this.cache.set(key, token);
|
|
122
|
+
return token;
|
|
123
|
+
})
|
|
124
|
+
.finally(() => this.inflight.delete(key));
|
|
125
|
+
this.inflight.set(key, request);
|
|
126
|
+
return request;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* `fetch` against the API on the grant's token. A 401 drops the token and the
|
|
130
|
+
* call is sent once more on a fresh one.
|
|
131
|
+
*/
|
|
132
|
+
async send(grant, url, init) {
|
|
133
|
+
for (let attempt = 0;; attempt += 1) {
|
|
134
|
+
const { token } = await this.token(grant);
|
|
135
|
+
const headers = new Headers(init.headers);
|
|
136
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
137
|
+
const response = await this.fetch(url.startsWith("http") ? url : `${this.baseUrl}${url}`, { ...init, headers });
|
|
138
|
+
if (response.status !== 401 || attempt > 0)
|
|
139
|
+
return response;
|
|
140
|
+
this.cache.delete(JSON.stringify(grant));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async issue(grant) {
|
|
144
|
+
const form = [];
|
|
145
|
+
if (grant?.member !== undefined) {
|
|
146
|
+
form.push(["grant_type", JWT_BEARER_GRANT], [
|
|
147
|
+
"assertion",
|
|
148
|
+
this.assertion(grant.member, {
|
|
149
|
+
installation: grant.installation,
|
|
150
|
+
...(grant.purpose !== undefined ? { purpose: grant.purpose } : {}),
|
|
151
|
+
}),
|
|
152
|
+
]);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
form.push(["grant_type", "client_credentials"], ["client_assertion_type", CLIENT_ASSERTION_TYPE], ["client_assertion", this.assertion(this.options.publicId, {})]);
|
|
156
|
+
if (grant)
|
|
157
|
+
form.push(["installation", grant.installation]);
|
|
158
|
+
}
|
|
159
|
+
if (grant?.scopes.length)
|
|
160
|
+
form.push(["scope", grant.scopes.join(" ")]);
|
|
161
|
+
if (grant?.initiative !== undefined)
|
|
162
|
+
form.push(["resource", `urn:initiative:initiative:${grant.initiative}`]);
|
|
163
|
+
if (grant?.level !== undefined)
|
|
164
|
+
form.push(["level", grant.level]);
|
|
165
|
+
const issuedAt = this.now();
|
|
166
|
+
const response = await this.fetch(this.endpoint, {
|
|
167
|
+
method: "POST",
|
|
168
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json" },
|
|
169
|
+
body: new URLSearchParams(form).toString(),
|
|
170
|
+
});
|
|
171
|
+
const body = (await readJson(response));
|
|
172
|
+
if (!response.ok) {
|
|
173
|
+
const error = typeof body?.error === "string" ? body.error : "invalid_response";
|
|
174
|
+
const description = typeof body?.error_description === "string"
|
|
175
|
+
? body.error_description
|
|
176
|
+
: typeof body?.error === "string"
|
|
177
|
+
? undefined
|
|
178
|
+
: `token endpoint answered ${response.status}`;
|
|
179
|
+
if (error === "consent_required")
|
|
180
|
+
throw new ConsentRequiredError(description, response.status);
|
|
181
|
+
throw new InitiativeAuthError(error, description, response.status);
|
|
182
|
+
}
|
|
183
|
+
if (typeof body?.access_token !== "string" || !body.access_token) {
|
|
184
|
+
throw new InitiativeAuthError("invalid_response", "token response carried no access_token", response.status);
|
|
185
|
+
}
|
|
186
|
+
if (typeof body.token_type === "string" && body.token_type.toLowerCase() !== "bearer") {
|
|
187
|
+
throw new InitiativeAuthError("invalid_response", `unexpected token_type ${body.token_type}`, response.status);
|
|
188
|
+
}
|
|
189
|
+
const lifetime = typeof body.expires_in === "number" && body.expires_in > 0 ? body.expires_in : 0;
|
|
190
|
+
return {
|
|
191
|
+
token: body.access_token,
|
|
192
|
+
scopes: typeof body.scope === "string" ? body.scope.split(" ").filter(Boolean) : [...(grant?.scopes ?? [])],
|
|
193
|
+
expiresAt: issuedAt + lifetime * 1000,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/** A signed assertion addressed to the token endpoint. */
|
|
197
|
+
assertion(subject, extra) {
|
|
198
|
+
const iat = Math.floor(this.now() / 1000);
|
|
199
|
+
return signJwt(this.options.key, {
|
|
200
|
+
iss: this.options.publicId,
|
|
201
|
+
sub: subject,
|
|
202
|
+
aud: this.endpoint,
|
|
203
|
+
jti: randomUUID(),
|
|
204
|
+
iat,
|
|
205
|
+
exp: iat + ASSERTION_LIFETIME_SECONDS,
|
|
206
|
+
...extra,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/** Initiative, for one plug-in on one deployment. */
|
|
211
|
+
export class Initiative {
|
|
212
|
+
tokens;
|
|
213
|
+
constructor(options) {
|
|
214
|
+
this.tokens = new Tokens(options);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Every community that has installed the plug-in, following Initiative's
|
|
218
|
+
* `Link` pages to the end. One that is gone is not listed.
|
|
219
|
+
*/
|
|
220
|
+
async installations() {
|
|
221
|
+
const installations = [];
|
|
222
|
+
let url = `${this.tokens.baseUrl}/plugin-platform/installations`;
|
|
223
|
+
while (url !== null) {
|
|
224
|
+
const response = await this.tokens.send(null, url, { headers: { Accept: "application/json" } });
|
|
225
|
+
const body = await readJson(response);
|
|
226
|
+
if (!response.ok)
|
|
227
|
+
throw new InitiativeApiError(response.status, detailOf(body));
|
|
228
|
+
if (!Array.isArray(body))
|
|
229
|
+
throw new InitiativeApiError(response.status, "installations: expected an array");
|
|
230
|
+
for (const item of body) {
|
|
231
|
+
installations.push({ installation: String(item.installation ?? ""), active: item.active !== false });
|
|
232
|
+
}
|
|
233
|
+
const next = nextLink(response.headers.get("link"));
|
|
234
|
+
url = next === null ? null : new URL(next, url).toString();
|
|
235
|
+
}
|
|
236
|
+
return installations;
|
|
237
|
+
}
|
|
238
|
+
/** The plug-in acting as the community that installed it. */
|
|
239
|
+
asInstallation(installation, options = {}) {
|
|
240
|
+
const grant = grantOf(installation, options);
|
|
241
|
+
if (options.level === undefined)
|
|
242
|
+
return new Client(this.tokens, grant);
|
|
243
|
+
if ((options.level === "moderator") !== (grant.initiative !== undefined)) {
|
|
244
|
+
throw new TypeError(options.level === "moderator"
|
|
245
|
+
? "a moderator token is narrowed to one initiative"
|
|
246
|
+
: "a community_admin token is not narrowed to an initiative");
|
|
247
|
+
}
|
|
248
|
+
return new Client(this.tokens, { ...grant, level: options.level });
|
|
249
|
+
}
|
|
250
|
+
/** The plug-in acting for one member, within what they consented to. */
|
|
251
|
+
asMember(installation, member, options = {}) {
|
|
252
|
+
if (!member)
|
|
253
|
+
throw new TypeError("member is required");
|
|
254
|
+
return new Client(this.tokens, {
|
|
255
|
+
...grantOf(installation, options),
|
|
256
|
+
member,
|
|
257
|
+
...(options.purpose !== undefined ? { purpose: options.purpose } : {}),
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function grantOf(installation, narrowing) {
|
|
262
|
+
if (!installation)
|
|
263
|
+
throw new TypeError("installation is required");
|
|
264
|
+
const initiative = narrowing.initiative;
|
|
265
|
+
if (initiative !== undefined && (!Number.isInteger(initiative) || initiative <= 0)) {
|
|
266
|
+
throw new TypeError(`an initiative id is a positive whole number, not ${initiative}`);
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
installation,
|
|
270
|
+
scopes: [...new Set(narrowing.scopes ?? [])].sort(),
|
|
271
|
+
...(initiative !== undefined ? { initiative } : {}),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Initiative, acting as one actor in one installation.
|
|
276
|
+
*
|
|
277
|
+
* Content calls ({@link Client.request}, {@link Client.callPlugin}) go on the
|
|
278
|
+
* actor's own token. The installation's own configuration, connections, status
|
|
279
|
+
* and events go on the installation's token, narrowed to the same initiative.
|
|
280
|
+
*/
|
|
281
|
+
export class Client {
|
|
282
|
+
tokens;
|
|
283
|
+
grant;
|
|
284
|
+
pluginApi;
|
|
285
|
+
constructor(tokens, grant) {
|
|
286
|
+
this.tokens = tokens;
|
|
287
|
+
this.grant = grant;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Every route Initiative's plug-in API describes, as a typed method on the
|
|
291
|
+
* actor's token: `client.api.updateTask({ path: { task_id: 7 }, body })`.
|
|
292
|
+
* Each is checked against the token's scopes before it is sent, like
|
|
293
|
+
* {@link Client.request}.
|
|
294
|
+
*/
|
|
295
|
+
get api() {
|
|
296
|
+
return (this.pluginApi ??= new PluginApi((operation, args) => this.operation(operation, args)));
|
|
297
|
+
}
|
|
298
|
+
get installation() {
|
|
299
|
+
return this.grant.installation;
|
|
300
|
+
}
|
|
301
|
+
get actor() {
|
|
302
|
+
return this.grant.member === undefined
|
|
303
|
+
? { kind: "installation" }
|
|
304
|
+
: { kind: "member", member: this.grant.member };
|
|
305
|
+
}
|
|
306
|
+
get initiative() {
|
|
307
|
+
return this.grant.initiative ?? null;
|
|
308
|
+
}
|
|
309
|
+
/** The scopes the actor's token holds. */
|
|
310
|
+
async scopes() {
|
|
311
|
+
return (await this.tokens.token(this.grant)).scopes;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* One call to a community route, the path after `/c/{community}`, on the actor's
|
|
315
|
+
* token. It is not sent unless the token holds `scope`. Answers the parsed
|
|
316
|
+
* JSON body (a `Blob` when the answer is not JSON), or throws
|
|
317
|
+
* {@link InitiativeApiError}.
|
|
318
|
+
*/
|
|
319
|
+
async request(method, path, options) {
|
|
320
|
+
return (await this.call(method, `${COMMUNITY_PREFIX}${path.startsWith("/") ? path : `/${path}`}`, options));
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Call another plug-in's public endpoint through Initiative, as this actor. Needs
|
|
324
|
+
* `plugins:<publicId>`. A write is sent once and never retried by Initiative.
|
|
325
|
+
*/
|
|
326
|
+
async callPlugin(publicId, endpointId, params = {}) {
|
|
327
|
+
const path = `/plugin-platform/plugins/${encodeURIComponent(publicId)}/endpoints/${encodeURIComponent(endpointId)}`;
|
|
328
|
+
const body = await this.call("POST", path, { scope: `plugins:${publicId}`, body: { params } });
|
|
329
|
+
if (!isRecord(body) || !isRecord(body.result)) {
|
|
330
|
+
throw new InitiativeApiError(200, "call: the plug-in answered without a result");
|
|
331
|
+
}
|
|
332
|
+
return body;
|
|
333
|
+
}
|
|
334
|
+
/** The installation's configuration. */
|
|
335
|
+
async config() {
|
|
336
|
+
const body = (await this.installationCall("GET", "/config"));
|
|
337
|
+
return {
|
|
338
|
+
communityRef: String(body.community_ref ?? ""),
|
|
339
|
+
installId: Number(body.install_id),
|
|
340
|
+
listingUid: String(body.listing_uid ?? ""),
|
|
341
|
+
listingVersion: String(body.listing_version ?? ""),
|
|
342
|
+
enabled: body.enabled === true,
|
|
343
|
+
configState: String(body.config_state ?? "unverified"),
|
|
344
|
+
configStateDetail: nullableString(body.config_state_detail),
|
|
345
|
+
needsConfig: body.needs_config === true,
|
|
346
|
+
connections: isRecord(body.connections) ? body.connections : {},
|
|
347
|
+
connectionRefs: isRecord(body.connection_refs)
|
|
348
|
+
? Object.fromEntries(Object.entries(body.connection_refs).filter((entry) => typeof entry[1] === "string"))
|
|
349
|
+
: {},
|
|
350
|
+
memberConnections: Array.isArray(body.member_connections)
|
|
351
|
+
? body.member_connections.map((raw) => ({
|
|
352
|
+
connectionId: String(raw.connection_id ?? ""),
|
|
353
|
+
connectionRef: String(raw.connection_ref ?? ""),
|
|
354
|
+
status: String(raw.status ?? ""),
|
|
355
|
+
values: isRecord(raw.values) ? raw.values : {},
|
|
356
|
+
}))
|
|
357
|
+
: [],
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
/** The installation's member connections: which handles are live, with no values. */
|
|
361
|
+
async connections() {
|
|
362
|
+
const body = (await this.installationCall("GET", "/connections"));
|
|
363
|
+
return Array.isArray(body.items)
|
|
364
|
+
? body.items.map((item) => ({
|
|
365
|
+
connectionId: String(item.connection_id ?? ""),
|
|
366
|
+
connectionRef: String(item.connection_ref ?? ""),
|
|
367
|
+
status: String(item.status ?? ""),
|
|
368
|
+
blocked: item.blocked === true,
|
|
369
|
+
accountLabel: nullableString(item.account_label),
|
|
370
|
+
createdAt: String(item.created_at ?? ""),
|
|
371
|
+
updatedAt: String(item.updated_at ?? ""),
|
|
372
|
+
}))
|
|
373
|
+
: [];
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* A usable vendor access token for one connection, by its handle. Initiative
|
|
377
|
+
* refreshes it, or mints it for a `jwt_bearer` connection. Ask each time.
|
|
378
|
+
*/
|
|
379
|
+
async connectionToken(connectionRef) {
|
|
380
|
+
if (!connectionRef)
|
|
381
|
+
throw new TypeError("connectionRef is required");
|
|
382
|
+
const body = (await this.installationCall("POST", `/connections/${encodeURIComponent(connectionRef)}/token`));
|
|
383
|
+
if (typeof body.access_token !== "string" || !body.access_token) {
|
|
384
|
+
throw new InitiativeApiError(200, "connection token: no access_token");
|
|
385
|
+
}
|
|
386
|
+
return {
|
|
387
|
+
accessToken: body.access_token,
|
|
388
|
+
expiresAt: typeof body.expires_at === "number" ? body.expires_at * 1000 : null,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
/** Tell Initiative whether the configuration the plug-in was handed works. */
|
|
392
|
+
async reportConfigStatus(report) {
|
|
393
|
+
const body = (await this.installationCall("POST", "/config-status", {
|
|
394
|
+
state: report.state,
|
|
395
|
+
...(report.detail !== undefined ? { detail: report.detail } : {}),
|
|
396
|
+
}));
|
|
397
|
+
return {
|
|
398
|
+
communityRef: String(body.community_ref ?? ""),
|
|
399
|
+
installId: Number(body.install_id),
|
|
400
|
+
configState: String(body.config_state ?? ""),
|
|
401
|
+
configStateDetail: nullableString(body.config_state_detail),
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
/** Emit one of the plug-in's declared events, for Initiative to keep and deliver. */
|
|
405
|
+
async emitEvent(event) {
|
|
406
|
+
await this.installationCall("POST", "/events", {
|
|
407
|
+
event_type: event.eventType,
|
|
408
|
+
payload: event.payload ?? {},
|
|
409
|
+
...(event.initiativeId === undefined ? {} : { initiative_id: event.initiativeId }),
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
/** Ask a member to let the plug-in act for them, on Initiative's own consent screen. */
|
|
413
|
+
async requestConsent(request) {
|
|
414
|
+
const body = await this.send(this.installationGrant(), "POST", "/plugin-platform/consent-requests", {
|
|
415
|
+
member: request.member,
|
|
416
|
+
label: request.label,
|
|
417
|
+
access: request.access,
|
|
418
|
+
...(request.purpose !== undefined ? { purpose: request.purpose } : {}),
|
|
419
|
+
...(request.initiativeId !== undefined ? { initiative_id: request.initiativeId } : {}),
|
|
420
|
+
});
|
|
421
|
+
return (body ?? {});
|
|
422
|
+
}
|
|
423
|
+
/** One operation of the plug-in API, its scope resolved from the operations table. */
|
|
424
|
+
async operation(id, args = {}) {
|
|
425
|
+
const operation = pluginApiOperations[id];
|
|
426
|
+
const { method, path, scope } = operation;
|
|
427
|
+
const values = args.path ?? {};
|
|
428
|
+
let needs;
|
|
429
|
+
if (typeof scope === "string") {
|
|
430
|
+
needs = scope;
|
|
431
|
+
}
|
|
432
|
+
else if ("by" in scope) {
|
|
433
|
+
const value = String(values[scope.by]);
|
|
434
|
+
const picked = scope.scopes[value];
|
|
435
|
+
if (picked === undefined) {
|
|
436
|
+
throw new TypeError(`${id}: ${scope.by} is one of ${Object.keys(scope.scopes).join(", ")}, not ${value}`);
|
|
437
|
+
}
|
|
438
|
+
needs = picked;
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
// Initiative checks each item; the token needs at least one of them.
|
|
442
|
+
const held = await this.scopes();
|
|
443
|
+
const found = scope.any_of.find((one) => grants(held, one));
|
|
444
|
+
if (found === undefined)
|
|
445
|
+
throw new MissingScopeError(scope.any_of.join(" "));
|
|
446
|
+
needs = found;
|
|
447
|
+
}
|
|
448
|
+
const filled = path.replace(/\{(\w+)\}/g, (_, name) => {
|
|
449
|
+
if (values[name] === undefined)
|
|
450
|
+
throw new TypeError(`${id} needs ${name}`);
|
|
451
|
+
return encodeURIComponent(String(values[name]));
|
|
452
|
+
});
|
|
453
|
+
return this.request(method, `${filled}${queryOf(args.query, operation.json)}`, { scope: needs, body: args.body });
|
|
454
|
+
}
|
|
455
|
+
installationGrant() {
|
|
456
|
+
const { member: _member, purpose: _purpose, ...installation } = this.grant;
|
|
457
|
+
return { ...installation, scopes: [] };
|
|
458
|
+
}
|
|
459
|
+
async installationCall(method, path, payload) {
|
|
460
|
+
return (await this.send(this.installationGrant(), method, `/plugin-platform/installation${path}`, payload)) ?? {};
|
|
461
|
+
}
|
|
462
|
+
async call(method, path, options) {
|
|
463
|
+
const { scopes } = await this.tokens.token(this.grant);
|
|
464
|
+
if (!grants(scopes, options.scope))
|
|
465
|
+
throw new MissingScopeError(options.scope);
|
|
466
|
+
return this.send(this.grant, method, path, options.body);
|
|
467
|
+
}
|
|
468
|
+
async send(grant, method, path, payload) {
|
|
469
|
+
const headers = { Accept: "application/json" };
|
|
470
|
+
if (payload !== undefined)
|
|
471
|
+
headers["Content-Type"] = "application/json";
|
|
472
|
+
const response = await this.tokens.send(grant, path, {
|
|
473
|
+
method,
|
|
474
|
+
headers,
|
|
475
|
+
...(payload !== undefined ? { body: JSON.stringify(payload) } : {}),
|
|
476
|
+
});
|
|
477
|
+
const type = response.headers.get("content-type");
|
|
478
|
+
if (response.ok && type && !/json/i.test(type))
|
|
479
|
+
return response.blob();
|
|
480
|
+
const body = await readJson(response);
|
|
481
|
+
if (!response.ok)
|
|
482
|
+
throw new InitiativeApiError(response.status, detailOf(body));
|
|
483
|
+
return body;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function isRecord(value) {
|
|
487
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* A query string as the operation describes it: a parameter it takes as JSON
|
|
491
|
+
* is sent as one JSON string, a list of values repeats its key, and an absent
|
|
492
|
+
* value is left out.
|
|
493
|
+
*/
|
|
494
|
+
function queryOf(query = {}, json = []) {
|
|
495
|
+
const params = new URLSearchParams();
|
|
496
|
+
for (const [key, value] of Object.entries(query)) {
|
|
497
|
+
if (value === undefined || value === null)
|
|
498
|
+
continue;
|
|
499
|
+
if (json.includes(key)) {
|
|
500
|
+
params.append(key, JSON.stringify(value));
|
|
501
|
+
}
|
|
502
|
+
else if (Array.isArray(value)) {
|
|
503
|
+
for (const item of value)
|
|
504
|
+
params.append(key, String(item));
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
params.append(key, String(value));
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
const text = params.toString();
|
|
511
|
+
return text ? `?${text}` : "";
|
|
512
|
+
}
|
|
513
|
+
function nullableString(value) {
|
|
514
|
+
return typeof value === "string" ? value : null;
|
|
515
|
+
}
|
|
516
|
+
/** The `rel="next"` target of a `Link` header (RFC 8288), or null. */
|
|
517
|
+
function nextLink(header) {
|
|
518
|
+
for (const part of (header ?? "").split(",")) {
|
|
519
|
+
const match = /^\s*<([^>]*)>\s*;\s*rel="?next"?\s*$/i.exec(part);
|
|
520
|
+
if (match)
|
|
521
|
+
return match[1] ?? null;
|
|
522
|
+
}
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
async function readJson(response) {
|
|
526
|
+
const text = await response.text();
|
|
527
|
+
if (!text)
|
|
528
|
+
return null;
|
|
529
|
+
try {
|
|
530
|
+
return JSON.parse(text);
|
|
531
|
+
}
|
|
532
|
+
catch {
|
|
533
|
+
return null;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
function detailOf(body) {
|
|
537
|
+
return isRecord(body) && "detail" in body ? body.detail : body;
|
|
538
|
+
}
|
|
539
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|