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.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +656 -0
  3. package/dist/build.d.ts +52 -0
  4. package/dist/build.js +229 -0
  5. package/dist/build.js.map +1 -0
  6. package/dist/cli.d.ts +24 -0
  7. package/dist/cli.js +160 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/client.d.ts +288 -0
  10. package/dist/client.js +539 -0
  11. package/dist/client.js.map +1 -0
  12. package/dist/contract.d.ts +1247 -0
  13. package/dist/contract.js +167 -0
  14. package/dist/contract.js.map +1 -0
  15. package/dist/define.d.ts +336 -0
  16. package/dist/define.js +120 -0
  17. package/dist/define.js.map +1 -0
  18. package/dist/dev.d.ts +28 -0
  19. package/dist/dev.js +147 -0
  20. package/dist/dev.js.map +1 -0
  21. package/dist/expression.d.ts +28 -0
  22. package/dist/expression.js +67 -0
  23. package/dist/expression.js.map +1 -0
  24. package/dist/init.d.ts +14 -0
  25. package/dist/init.js +52 -0
  26. package/dist/init.js.map +1 -0
  27. package/dist/keys.d.ts +85 -0
  28. package/dist/keys.js +109 -0
  29. package/dist/keys.js.map +1 -0
  30. package/dist/manifest.d.ts +8 -0
  31. package/dist/manifest.js +8 -0
  32. package/dist/manifest.js.map +1 -0
  33. package/dist/pack.d.ts +35 -0
  34. package/dist/pack.js +84 -0
  35. package/dist/pack.js.map +1 -0
  36. package/dist/plugin-api.generated.d.ts +4263 -0
  37. package/dist/plugin-api.generated.js +1019 -0
  38. package/dist/plugin-api.generated.js.map +1 -0
  39. package/dist/server.d.ts +75 -0
  40. package/dist/server.js +408 -0
  41. package/dist/server.js.map +1 -0
  42. package/dist/testing.d.ts +116 -0
  43. package/dist/testing.js +386 -0
  44. package/dist/testing.js.map +1 -0
  45. package/dist/tokens.d.ts +161 -0
  46. package/dist/tokens.js +215 -0
  47. package/dist/tokens.js.map +1 -0
  48. package/dist/validate.d.ts +86 -0
  49. package/dist/validate.js +997 -0
  50. package/dist/validate.js.map +1 -0
  51. package/dist/widget.d.ts +235 -0
  52. package/dist/widget.js +26 -0
  53. package/dist/widget.js.map +1 -0
  54. package/examples/minimal/README.md +48 -0
  55. package/examples/minimal/assets/avatar.png +0 -0
  56. package/examples/minimal/package.json +22 -0
  57. package/examples/minimal/src/plugin.ts +77 -0
  58. package/examples/minimal/src/widgets/open-issues.ts +11 -0
  59. package/examples/minimal/test/fixtures/issues-statistics.json +9 -0
  60. package/examples/minimal/test/issue-counts.test.ts +48 -0
  61. package/examples/minimal/tsconfig.json +14 -0
  62. package/manifest.contract.json +1886 -0
  63. package/package.json +92 -0
  64. package/schemas/plugin-manifest.json +1747 -0
@@ -0,0 +1,116 @@
1
+ /**
2
+ * `initiative-plugin-sdk/testing`: a declarative plug-in's requests and mappings,
3
+ * run against recorded vendor answers, with no server and no network.
4
+ *
5
+ * Each runner renders the requests the way Initiative makes them (method,
6
+ * address with its query, headers, body), answers them from `responses` in
7
+ * order, and maps the answers. It returns every request it rendered beside
8
+ * what the run answered:
9
+ *
10
+ * - `{ result }`: the mapped answer;
11
+ * - `{ unavailable, detail? }`: a code, from an `errors` rule, the defaults,
12
+ * the map itself, `range-too-large` from paging, or `mapping-failed` when an
13
+ * expression fails or a rendered address is not https on one of the plug-in's
14
+ * hosts (`detail` says which);
15
+ * - `{ transient: true }`: a passing failure, which Initiative answers as one
16
+ * to retry;
17
+ * - `{ refused }`: an `after_connect` that refused the connection.
18
+ *
19
+ * A rendered request carries no credential: Initiative adds the one its
20
+ * `connection` names, as the plug-in's `auth` says. A predicate (`when`, `more`,
21
+ * `refuse_when`) holds when JSONata's `$boolean` of its answer is true.
22
+ *
23
+ * A run fails, rather than answering, on a mistake in the test or the plug-in: a
24
+ * request with no recorded response left for it, a recorded response nothing
25
+ * asked for, or a mapped answer that does not fit the declared returns.
26
+ */
27
+ import type { ConnectionState } from "./contract.js";
28
+ import type { AnyPlugin } from "./define.js";
29
+ export { evaluate, ExpressionError, parseExpression } from "./expression.js";
30
+ /** One answer the vendor gave, as a test records it. Status 200 and no headers when left out. */
31
+ export interface RecordedResponse {
32
+ status?: number;
33
+ headers?: Record<string, string>;
34
+ body?: unknown;
35
+ }
36
+ /** One request as Initiative sends it, less the credential. */
37
+ export interface RenderedRequest {
38
+ method: string;
39
+ url: string;
40
+ headers: Record<string, string>;
41
+ body?: unknown;
42
+ /** The connection whose credential Initiative would add. */
43
+ connection?: string;
44
+ }
45
+ /** What a run made and what it answered. */
46
+ export type Run<T> = {
47
+ requests: RenderedRequest[];
48
+ } & ({
49
+ result: T;
50
+ } | {
51
+ unavailable: string;
52
+ detail?: string;
53
+ } | {
54
+ transient: true;
55
+ } | {
56
+ refused: string;
57
+ });
58
+ export interface Recorded {
59
+ /** The vendor's answers, in the order the requests are made. */
60
+ responses: RecordedResponse[];
61
+ /** The time of the call: `now`, and what `$now()` and `$millis()` answer. Default: the present. */
62
+ now?: Date | string | number;
63
+ }
64
+ /**
65
+ * One declarative endpoint: its request or steps rendered from `params`, the
66
+ * `connections`' non-secret fields (keyed by connection id) and `now`, answered
67
+ * from `responses`, and its map held to the declared returns. An expression
68
+ * reads `connection`, the fields of the connection its request names, and
69
+ * `connections`, the fields of each connection the endpoint's `requires` names
70
+ * that `connections` holds, by id. The call has no actor: who may run it, and
71
+ * on whose credential, is Initiative's to decide.
72
+ */
73
+ export declare function runEndpoint(plugin: AnyPlugin, name: string, call: Recorded & {
74
+ params?: Record<string, unknown>;
75
+ connections?: Record<string, Record<string, unknown>>;
76
+ }): Promise<Run<Record<string, unknown>>>;
77
+ /**
78
+ * A declarative `after_connect`: its request or steps made with the flow's
79
+ * `params`, mapped, and refused when it says. The map and `refuse_when` read
80
+ * the last answer as `response` and, with steps, each one's as `steps.<name>`.
81
+ */
82
+ export declare function runAfterConnect(plugin: AnyPlugin, connection: string, call: Recorded & {
83
+ params?: Record<string, string>;
84
+ }): Promise<Run<{
85
+ values?: Record<string, unknown>;
86
+ account_label?: string;
87
+ }>>;
88
+ /** A connection's health check: its request made with the connection's non-secret `fields`, and the state it reads. */
89
+ export declare function runHealth(plugin: AnyPlugin, connection: string, call: Recorded & {
90
+ fields?: Record<string, unknown>;
91
+ }): Promise<Run<ConnectionState>>;
92
+ /** What one delivery emits, and the connection state it sets. */
93
+ export interface WebhookRun {
94
+ event?: {
95
+ emit: string;
96
+ payload: Record<string, unknown>;
97
+ };
98
+ status?: {
99
+ connection: string;
100
+ state: ConnectionState;
101
+ };
102
+ }
103
+ /**
104
+ * One webhook delivery, as a declarative plug-in maps it: the event the first
105
+ * matching `events` row emits (by the emit endpoint's key, its payload held to
106
+ * that endpoint's returns), and the state the first matching `status` row
107
+ * sets. A delivery nothing matches answers neither. An expression that fails
108
+ * throws {@link ExpressionError}.
109
+ */
110
+ export declare function runWebhook(plugin: AnyPlugin, delivery: {
111
+ headers?: Record<string, string>;
112
+ payload: unknown;
113
+ /** The routed connection's non-secret fields. */
114
+ connection?: Record<string, unknown>;
115
+ now?: Date | string | number;
116
+ }): Promise<WebhookRun>;
@@ -0,0 +1,386 @@
1
+ /**
2
+ * `initiative-plugin-sdk/testing`: a declarative plug-in's requests and mappings,
3
+ * run against recorded vendor answers, with no server and no network.
4
+ *
5
+ * Each runner renders the requests the way Initiative makes them (method,
6
+ * address with its query, headers, body), answers them from `responses` in
7
+ * order, and maps the answers. It returns every request it rendered beside
8
+ * what the run answered:
9
+ *
10
+ * - `{ result }`: the mapped answer;
11
+ * - `{ unavailable, detail? }`: a code, from an `errors` rule, the defaults,
12
+ * the map itself, `range-too-large` from paging, or `mapping-failed` when an
13
+ * expression fails or a rendered address is not https on one of the plug-in's
14
+ * hosts (`detail` says which);
15
+ * - `{ transient: true }`: a passing failure, which Initiative answers as one
16
+ * to retry;
17
+ * - `{ refused }`: an `after_connect` that refused the connection.
18
+ *
19
+ * A rendered request carries no credential: Initiative adds the one its
20
+ * `connection` names, as the plug-in's `auth` says. A predicate (`when`, `more`,
21
+ * `refuse_when`) holds when JSONata's `$boolean` of its answer is true.
22
+ *
23
+ * A run fails, rather than answering, on a mistake in the test or the plug-in: a
24
+ * request with no recorded response left for it, a recorded response nothing
25
+ * asked for, or a mapped answer that does not fit the declared returns.
26
+ */
27
+ import { PLATFORM_CODES } from "./contract.js";
28
+ import { evaluate, ExpressionError } from "./expression.js";
29
+ export { evaluate, ExpressionError, parseExpression } from "./expression.js";
30
+ /** A run's answer, thrown from wherever it is decided. */
31
+ class Outcome {
32
+ answer;
33
+ constructor(answer) {
34
+ this.answer = answer;
35
+ }
36
+ }
37
+ class Context {
38
+ hosts;
39
+ rules;
40
+ requests = [];
41
+ now;
42
+ clock;
43
+ responses;
44
+ constructor(hosts, recorded,
45
+ /** The endpoint's own rules, and whether an answer outside 2xx fails the run. */
46
+ rules) {
47
+ this.hosts = hosts;
48
+ this.rules = rules;
49
+ this.clock = recorded.now ?? new Date();
50
+ this.now = new Date(this.clock).toISOString();
51
+ this.responses = [...recorded.responses];
52
+ }
53
+ async value(text, document, where) {
54
+ try {
55
+ return await evaluate(text, document, { now: this.clock });
56
+ }
57
+ catch (error) {
58
+ if (!(error instanceof ExpressionError))
59
+ throw error;
60
+ throw new Outcome({ unavailable: "mapping-failed", detail: `${where}: ${error.message}` });
61
+ }
62
+ }
63
+ async holds(text, document, where) {
64
+ return (await evaluate("$boolean($)", await this.value(text, document, where))) === true;
65
+ }
66
+ answer(request) {
67
+ const recorded = this.responses.shift();
68
+ if (!recorded)
69
+ throw new Error(`no recorded response is left for ${request.method} ${request.url}`);
70
+ return {
71
+ status: recorded.status ?? 200,
72
+ headers: Object.fromEntries(Object.entries(recorded.headers ?? {}).map(([name, value]) => [name.toLowerCase(), value])),
73
+ body: recorded.body === undefined ? undefined : JSON.parse(JSON.stringify(recorded.body)),
74
+ };
75
+ }
76
+ async run(work) {
77
+ let answered;
78
+ try {
79
+ answered = await work();
80
+ }
81
+ catch (error) {
82
+ if (!(error instanceof Outcome))
83
+ throw error;
84
+ answered = error.answer;
85
+ }
86
+ if (this.responses.length) {
87
+ throw new Error(`${this.responses.length} recorded response(s) were not asked for`);
88
+ }
89
+ return { requests: this.requests, ...answered };
90
+ }
91
+ }
92
+ const matches = (status, actual) => typeof status === "number" ? status === actual : status[0] === String(actual)[0];
93
+ /** What an answer outside 2xx means when no rule says. */
94
+ function byDefault(status) {
95
+ if (status === 401 || status === 403)
96
+ return { unavailable: "not-authorized" };
97
+ if (status === 404)
98
+ return { unavailable: "not-found" };
99
+ if (status !== 429 && status >= 400 && status < 500)
100
+ return { unavailable: "invalid" };
101
+ return { transient: true };
102
+ }
103
+ function onHost(url, hosts) {
104
+ if (url.protocol !== "https:" || url.port !== "" || url.username || url.password)
105
+ return false;
106
+ return hosts.some((host) => {
107
+ if (!host.startsWith("*."))
108
+ return url.hostname === host;
109
+ const label = url.hostname.slice(0, -(host.length - 1));
110
+ return url.hostname.endsWith(host.slice(1)) && label.length > 0 && !label.includes(".");
111
+ });
112
+ }
113
+ /** The address a Link header gives as `rel="next"`, if any. */
114
+ function nextLink(header, base) {
115
+ for (const link of (header ?? "").split(",")) {
116
+ const [, target, rest] = /^\s*<([^>]*)>(.*)$/.exec(link) ?? [];
117
+ const rel = /;\s*rel="?([^";]*)"?/i.exec(rest ?? "")?.[1];
118
+ if (target !== undefined && rel?.split(/\s+/).includes("next"))
119
+ return new URL(target, base).toString();
120
+ }
121
+ return undefined;
122
+ }
123
+ const text = (value) => (typeof value === "string" ? value : JSON.stringify(value));
124
+ async function render(request, document, context, where, page) {
125
+ const address = page.url ?? (await context.value(request.url, document, `${where}/url`));
126
+ let url;
127
+ try {
128
+ url = new URL(String(address));
129
+ }
130
+ catch {
131
+ throw new Outcome({ unavailable: "mapping-failed", detail: `${where}/url: ${text(address)} is not an address` });
132
+ }
133
+ if (page.url === undefined) {
134
+ for (const [name, expression] of Object.entries(request.query ?? {})) {
135
+ const value = await context.value(expression, document, `${where}/query/${name}`);
136
+ for (const one of Array.isArray(value) ? value : [value]) {
137
+ if (one !== undefined && one !== null)
138
+ url.searchParams.append(name, text(one));
139
+ }
140
+ }
141
+ }
142
+ const paging = request.paging;
143
+ if (paging?.kind === "page_number") {
144
+ url.searchParams.set(paging.page_param, String(page.number));
145
+ if (paging.per_page_param)
146
+ url.searchParams.set(paging.per_page_param, String(paging.per_page));
147
+ }
148
+ if (paging?.kind === "cursor" && paging.param && page.number > 1)
149
+ url.searchParams.set(paging.param, text(page.cursor));
150
+ if (!onHost(url, context.hosts)) {
151
+ throw new Outcome({
152
+ unavailable: "mapping-failed",
153
+ detail: `${where}: ${url} is not https on one of the plug-in's hosts (${context.hosts.join(", ")})`,
154
+ });
155
+ }
156
+ const headers = {};
157
+ for (const [name, expression] of Object.entries(request.headers ?? {})) {
158
+ const value = await context.value(expression, document, `${where}/headers/${name}`);
159
+ if (value !== undefined && value !== null)
160
+ headers[name] = text(value);
161
+ }
162
+ let body = request.body === undefined ? undefined : await context.value(request.body, document, `${where}/body`);
163
+ if (request.graphql) {
164
+ let variables = request.graphql.variables
165
+ ? await context.value(request.graphql.variables, document, `${where}/graphql/variables`)
166
+ : undefined;
167
+ if (paging?.kind === "cursor" && paging.variable && page.number > 1) {
168
+ variables = { ...variables, [paging.variable]: page.cursor };
169
+ }
170
+ body = { query: request.graphql.query, ...(variables === undefined ? {} : { variables }) };
171
+ }
172
+ return {
173
+ method: request.method,
174
+ url: url.toString(),
175
+ headers,
176
+ ...(body === undefined ? {} : { body }),
177
+ ...(request.connection ? { connection: request.connection } : {}),
178
+ };
179
+ }
180
+ /**
181
+ * One request, every page of it, as `response` then reads it. Each answer is
182
+ * held to the endpoint's rules and then the defaults, unless the context
183
+ * judges none (a health check, whose states do).
184
+ */
185
+ async function perform(request, document, context, where) {
186
+ const paging = request.paging;
187
+ const items = [];
188
+ const page = { number: 1 };
189
+ for (;;) {
190
+ const rendered = await render(request, document, context, where, page);
191
+ context.requests.push(rendered);
192
+ const answer = context.answer(rendered);
193
+ if (context.rules) {
194
+ const read = { ...document, response: answer };
195
+ for (const [index, rule] of context.rules.entries()) {
196
+ if (!matches(rule.status, answer.status))
197
+ continue;
198
+ if (rule.when !== undefined && !(await context.holds(rule.when, read, `errors/${index}/when`)))
199
+ continue;
200
+ throw new Outcome(rule.code === "transient" ? { transient: true } : { unavailable: rule.code });
201
+ }
202
+ if (answer.status < 200 || answer.status > 299)
203
+ throw new Outcome(byDefault(answer.status));
204
+ }
205
+ if (!paging)
206
+ return answer;
207
+ const read = { ...document, response: answer };
208
+ const got = paging.items === undefined ? answer.body : await context.value(paging.items, read, `${where}/paging/items`);
209
+ if (Array.isArray(got))
210
+ items.push(...got);
211
+ else if (got !== undefined)
212
+ items.push(got);
213
+ let more;
214
+ if (paging.kind === "page_number") {
215
+ more = (Array.isArray(got) ? got.length : got === undefined ? 0 : 1) >= paging.per_page;
216
+ }
217
+ else if (paging.kind === "link_header") {
218
+ page.url = nextLink(answer.headers.link, rendered.url);
219
+ more = page.url !== undefined;
220
+ }
221
+ else {
222
+ more = await context.holds(paging.more, read, `${where}/paging/more`);
223
+ page.cursor = await context.value(paging.next, read, `${where}/paging/next`);
224
+ }
225
+ if (more && page.number === paging.max_pages && paging.on_limit === "refuse") {
226
+ throw new Outcome({ unavailable: "range-too-large" });
227
+ }
228
+ if (!more || page.number === paging.max_pages)
229
+ return { ...answer, body: items };
230
+ page.number += 1;
231
+ }
232
+ }
233
+ /** Holds a mapped answer to the declared returns: declared names, of their declared types. */
234
+ function fits(answer, returns, where) {
235
+ if (!answer || typeof answer !== "object" || Array.isArray(answer)) {
236
+ throw new Error(`${where} answered ${text(answer)}, which is not an object of the declared returns`);
237
+ }
238
+ for (const [key, value] of Object.entries(answer)) {
239
+ const spec = returns?.[key];
240
+ if (spec === undefined)
241
+ throw new Error(`${where} answered '${key}', which is not a declared return`);
242
+ if (value === null)
243
+ continue;
244
+ const { type, list } = typeof spec === "string" ? { type: spec, list: false } : spec;
245
+ if (list && !Array.isArray(value)) {
246
+ throw new Error(`${where} answered '${key}' as ${text(value)}, and it is declared a list ` +
247
+ "(a JSONata path matching one item answers it alone: end the path with [] to keep a list)");
248
+ }
249
+ for (const one of list ? value : [value]) {
250
+ const ok = type === "int" ? Number.isInteger(one) : type === "bool" ? typeof one === "boolean" : typeof one === "string";
251
+ if (!ok)
252
+ throw new Error(`${where} answered '${key}' as ${text(one)}, which is not ${type}`);
253
+ }
254
+ }
255
+ return answer;
256
+ }
257
+ /**
258
+ * One declarative endpoint: its request or steps rendered from `params`, the
259
+ * `connections`' non-secret fields (keyed by connection id) and `now`, answered
260
+ * from `responses`, and its map held to the declared returns. An expression
261
+ * reads `connection`, the fields of the connection its request names, and
262
+ * `connections`, the fields of each connection the endpoint's `requires` names
263
+ * that `connections` holds, by id. The call has no actor: who may run it, and
264
+ * on whose credential, is Initiative's to decide.
265
+ */
266
+ export async function runEndpoint(plugin, name, call) {
267
+ const endpoint = plugin.endpoints?.[name];
268
+ if (!endpoint || !("map" in endpoint))
269
+ throw new TypeError(`'${name}' is not a declarative endpoint of this plug-in`);
270
+ const context = new Context(plugin.hosts ?? [], call, endpoint.errors ?? []);
271
+ return context.run(async () => {
272
+ const given = call.connections ?? {};
273
+ const required = [...(endpoint.requires?.all_of ?? []), ...(endpoint.requires?.any_of ?? [])];
274
+ const connections = Object.fromEntries(required.filter((id) => Object.hasOwn(given, id)).map((id) => [id, given[id]]));
275
+ const base = { params: call.params ?? {}, connections, now: context.now };
276
+ const steps = endpoint.steps ?? [{ name: "", request: endpoint.request }];
277
+ const answers = {};
278
+ let read = base;
279
+ for (const [index, step] of steps.entries()) {
280
+ read = {
281
+ ...base,
282
+ connection: call.connections?.[step.request.connection ?? ""] ?? {},
283
+ ...(endpoint.steps ? { steps: { ...answers } } : {}),
284
+ };
285
+ const where = endpoint.steps ? `steps/${index}/request` : "request";
286
+ const response = await perform(step.request, read, context, where);
287
+ if (endpoint.steps)
288
+ answers[step.name] = response;
289
+ read = { ...read, ...(endpoint.steps ? { steps: { ...answers } } : {}), response };
290
+ }
291
+ const answer = await context.value(endpoint.map, read, "map");
292
+ if (answer && typeof answer === "object" && "unavailable" in answer) {
293
+ const code = answer.unavailable;
294
+ if (typeof code !== "string" || ![...(endpoint.unavailable ?? []), ...PLATFORM_CODES].includes(code)) {
295
+ throw new Error(`map answered unavailable ${text(code)}, which is not one of this endpoint's codes`);
296
+ }
297
+ return { unavailable: code };
298
+ }
299
+ return { result: fits(answer, endpoint.returns, "map") };
300
+ });
301
+ }
302
+ /**
303
+ * A declarative `after_connect`: its request or steps made with the flow's
304
+ * `params`, mapped, and refused when it says. The map and `refuse_when` read
305
+ * the last answer as `response` and, with steps, each one's as `steps.<name>`.
306
+ */
307
+ export async function runAfterConnect(plugin, connection, call) {
308
+ const after = plugin.connections?.[connection]?.flow?.after_connect;
309
+ if (typeof after !== "object")
310
+ throw new TypeError(`'${connection}' has no declarative after_connect`);
311
+ const context = new Context(plugin.hosts ?? [], call, []);
312
+ return context.run(async () => {
313
+ const base = { params: call.params ?? {}, now: context.now };
314
+ const steps = after.steps ?? [{ name: "", request: after.request }];
315
+ const answers = {};
316
+ let read = base;
317
+ for (const [index, step] of steps.entries()) {
318
+ read = { ...base, ...(after.steps ? { steps: { ...answers } } : {}) };
319
+ const where = after.steps ? `after_connect/steps/${index}/request` : "after_connect/request";
320
+ const response = await perform(step.request, read, context, where);
321
+ if (after.steps)
322
+ answers[step.name] = response;
323
+ read = { ...base, ...(after.steps ? { steps: { ...answers } } : {}), response };
324
+ }
325
+ const result = await context.value(after.map, read, "after_connect/map");
326
+ if (!result || typeof result !== "object" || Array.isArray(result)) {
327
+ throw new Error(`after_connect/map answered ${text(result)}, which is not {values, account_label}`);
328
+ }
329
+ if (after.refuse_when && (await context.holds(after.refuse_when, { ...read, result }, "refuse_when"))) {
330
+ return { refused: after.code ?? "" };
331
+ }
332
+ return { result: result };
333
+ });
334
+ }
335
+ /** A connection's health check: its request made with the connection's non-secret `fields`, and the state it reads. */
336
+ export async function runHealth(plugin, connection, call) {
337
+ const health = plugin.connections?.[connection]?.health;
338
+ if (!health)
339
+ throw new TypeError(`'${connection}' declares no health check`);
340
+ const context = new Context(plugin.hosts ?? [], call, null);
341
+ return context.run(async () => {
342
+ const document = { params: {}, connection: call.fields ?? {}, now: context.now };
343
+ const response = await perform(health.request, document, context, "health/request");
344
+ for (const [index, row] of health.states.entries()) {
345
+ if (row.status !== undefined && !matches(row.status, response.status))
346
+ continue;
347
+ if (row.when !== undefined && !(await context.holds(row.when, { ...document, response }, `states/${index}/when`)))
348
+ continue;
349
+ return { result: row.state };
350
+ }
351
+ return { result: response.status >= 200 && response.status <= 299 ? "ok" : "unavailable" };
352
+ });
353
+ }
354
+ /**
355
+ * One webhook delivery, as a declarative plug-in maps it: the event the first
356
+ * matching `events` row emits (by the emit endpoint's key, its payload held to
357
+ * that endpoint's returns), and the state the first matching `status` row
358
+ * sets. A delivery nothing matches answers neither. An expression that fails
359
+ * throws {@link ExpressionError}.
360
+ */
361
+ export async function runWebhook(plugin, delivery) {
362
+ const clock = delivery.now ?? new Date();
363
+ const document = {
364
+ headers: Object.fromEntries(Object.entries(delivery.headers ?? {}).map(([name, value]) => [name.toLowerCase(), value])),
365
+ payload: delivery.payload,
366
+ connection: delivery.connection ?? {},
367
+ now: new Date(clock).toISOString(),
368
+ };
369
+ const holds = async (expression) => (await evaluate("$boolean($)", await evaluate(expression, document, { now: clock }))) === true;
370
+ const out = {};
371
+ for (const row of plugin.webhooks?.events ?? []) {
372
+ if (!(await holds(row.when)))
373
+ continue;
374
+ const payload = await evaluate(row.map, document, { now: clock });
375
+ out.event = { emit: row.emit, payload: fits(payload, plugin.endpoints?.[row.emit]?.returns, `the ${row.emit} event`) };
376
+ break;
377
+ }
378
+ for (const row of plugin.webhooks?.status ?? []) {
379
+ if (await holds(row.when)) {
380
+ out.status = { connection: row.connection, state: row.state };
381
+ break;
382
+ }
383
+ }
384
+ return out;
385
+ }
386
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}