@sponson/adapters 0.4.0 → 0.5.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 +1 -1
- package/dist/algolia.d.ts +6 -0
- package/dist/algolia.js +151 -0
- package/dist/algolia.js.map +1 -0
- package/dist/clerk.js +1 -1
- package/dist/clerk.js.map +1 -1
- package/dist/cloudflare.d.ts +25 -0
- package/dist/cloudflare.js +310 -0
- package/dist/cloudflare.js.map +1 -0
- package/dist/common.d.ts +2 -6
- package/dist/common.js.map +1 -1
- package/dist/digest.d.ts +46 -0
- package/dist/digest.js +129 -0
- package/dist/digest.js.map +1 -0
- package/dist/digitalocean.d.ts +5 -0
- package/dist/digitalocean.js +243 -0
- package/dist/digitalocean.js.map +1 -0
- package/dist/http-adapter-action.d.ts +63 -0
- package/dist/http-adapter-action.js +369 -0
- package/dist/http-adapter-action.js.map +1 -0
- package/dist/http-adapter-auth.d.ts +88 -0
- package/dist/http-adapter-auth.js +437 -0
- package/dist/http-adapter-auth.js.map +1 -0
- package/dist/http-adapter-client.d.ts +51 -0
- package/dist/http-adapter-client.js +156 -0
- package/dist/http-adapter-client.js.map +1 -0
- package/dist/http-adapter-graphql.d.ts +39 -0
- package/dist/http-adapter-graphql.js +157 -0
- package/dist/http-adapter-graphql.js.map +1 -0
- package/dist/http-adapter-list.d.ts +33 -0
- package/dist/http-adapter-list.js +421 -0
- package/dist/http-adapter-list.js.map +1 -0
- package/dist/http-adapter-resource.d.ts +29 -0
- package/dist/http-adapter-resource.js +462 -0
- package/dist/http-adapter-resource.js.map +1 -0
- package/dist/http-adapter-spec.d.ts +216 -0
- package/dist/http-adapter-spec.js +660 -0
- package/dist/http-adapter-spec.js.map +1 -0
- package/dist/http-adapter.d.ts +16 -0
- package/dist/http-adapter.js +28 -0
- package/dist/http-adapter.js.map +1 -0
- package/dist/http.d.ts +61 -2
- package/dist/http.js +79 -18
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.js +24 -2
- package/dist/index.js.map +1 -1
- package/dist/launchdarkly.d.ts +15 -0
- package/dist/launchdarkly.js +337 -0
- package/dist/launchdarkly.js.map +1 -0
- package/dist/manual.d.ts +13 -0
- package/dist/manual.js +201 -0
- package/dist/manual.js.map +1 -0
- package/dist/neon.js +1 -1
- package/dist/neon.js.map +1 -1
- package/dist/netlify.d.ts +18 -0
- package/dist/netlify.js +436 -0
- package/dist/netlify.js.map +1 -0
- package/dist/planetscale.d.ts +10 -0
- package/dist/planetscale.js +311 -0
- package/dist/planetscale.js.map +1 -0
- package/dist/providers.d.ts +26 -0
- package/dist/providers.js +36 -0
- package/dist/providers.js.map +1 -0
- package/dist/recipes.d.ts +167 -0
- package/dist/recipes.js +246 -0
- package/dist/recipes.js.map +1 -0
- package/dist/secrets.d.ts +44 -0
- package/dist/secrets.js +279 -0
- package/dist/secrets.js.map +1 -1
- package/dist/sigv4.d.ts +56 -0
- package/dist/sigv4.js +118 -0
- package/dist/sigv4.js.map +1 -0
- package/dist/supabase.d.ts +9 -0
- package/dist/supabase.js +385 -0
- package/dist/supabase.js.map +1 -0
- package/dist/vercel.js +1 -1
- package/dist/vercel.js.map +1 -1
- package/dist/xata.d.ts +8 -0
- package/dist/xata.js +142 -0
- package/dist/xata.js.map +1 -0
- package/dist/xml.d.ts +25 -0
- package/dist/xml.js +211 -0
- package/dist/xml.js.map +1 -0
- package/package.json +11 -4
- package/recipes/amplify.yaml +147 -0
- package/recipes/auth0.yaml +178 -0
- package/recipes/azure_swa.yaml +116 -0
- package/recipes/cloud_run.yaml +97 -0
- package/recipes/cloudflare.yaml +108 -0
- package/recipes/cockroachdb.yaml +132 -0
- package/recipes/configcat.yaml +123 -0
- package/recipes/datadog.yaml +136 -0
- package/recipes/firebase.yaml +84 -0
- package/recipes/flagsmith.yaml +98 -0
- package/recipes/fly.yaml +97 -0
- package/recipes/fly_machines.yaml +67 -0
- package/recipes/gcs.yaml +102 -0
- package/recipes/github.yaml +123 -0
- package/recipes/growthbook.yaml +124 -0
- package/recipes/heroku.yaml +98 -0
- package/recipes/honeycomb.yaml +89 -0
- package/recipes/inngest.yaml +97 -0
- package/recipes/kinde.yaml +120 -0
- package/recipes/mongodb_atlas.yaml +119 -0
- package/recipes/okta.yaml +177 -0
- package/recipes/posthog.yaml +127 -0
- package/recipes/postmark.yaml +105 -0
- package/recipes/postmark_server.yaml +93 -0
- package/recipes/prisma.yaml +150 -0
- package/recipes/qstash.yaml +134 -0
- package/recipes/railway.yaml +130 -0
- package/recipes/render.yaml +103 -0
- package/recipes/resend.yaml +130 -0
- package/recipes/s3.yaml +108 -0
- package/recipes/sendgrid.yaml +165 -0
- package/recipes/sentry.yaml +158 -0
- package/recipes/split.yaml +121 -0
- package/recipes/statsig.yaml +124 -0
- package/recipes/stripe.yaml +310 -0
- package/recipes/stytch.yaml +113 -0
- package/recipes/svix.yaml +109 -0
- package/recipes/turso.yaml +98 -0
- package/recipes/unleash.yaml +149 -0
- package/recipes/upstash.yaml +130 -0
- package/recipes/vercel.yaml +116 -0
- package/recipes/workos.yaml +70 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `http.action`: one request (or GraphQL request) sent when the line's trigger changes, for side effects with
|
|
3
|
+
* nothing to read back or delete: an Inngest sync of a preview deployment, a cache purge, a deploy notification.
|
|
4
|
+
* See ADR 0022 and docs/plan-format.md#httpaction.
|
|
5
|
+
*
|
|
6
|
+
* The engine owns the line's state (`OpSpec.action`): the ledger key is `action:<line id>`, the hash the trigger's,
|
|
7
|
+
* and `apply` is called only to send it. This file parses the line, sends the request and checks the answer
|
|
8
|
+
* (status, `expect`), takes the declared outputs, and returns the record id that says how to undo it:
|
|
9
|
+
*
|
|
10
|
+
* - `FORGET`: no `undo`; destroy forgets the record;
|
|
11
|
+
* - `UNDO <canonical JSON request>`: the `undo` request with every value resolved when the action ran (references
|
|
12
|
+
* and outputs filled in, never a secret), so destroy needs nothing but the ledger.
|
|
13
|
+
*
|
|
14
|
+
* A request goes either to the line's API (`path`, or `graphql`; the `providers.http.<api>` block's base URL,
|
|
15
|
+
* credential and headers) or to an absolute `url` (the app's own endpoint, such as a preview deployment's
|
|
16
|
+
* `/api/inngest`), which gets no credential and no API headers: a URL resolved at run time never receives the
|
|
17
|
+
* API's credential. A `url` line has no `api` and its provider block (ledger identity) is empty.
|
|
18
|
+
*/
|
|
19
|
+
import { SponsonError, canonicalJson, sha256 } from "@sponson/core";
|
|
20
|
+
import { assertNoPending, clientFor, paramError } from "./common.js";
|
|
21
|
+
import { isObject, isProviderError } from "./http.js";
|
|
22
|
+
import { HEADER_NAME } from "./http-adapter-auth.js";
|
|
23
|
+
import { httpClient, literalOf } from "./http-adapter-client.js";
|
|
24
|
+
import { parseGraphql, graphqlRequest, rootField } from "./http-adapter-graphql.js";
|
|
25
|
+
import { ADAPTER, apiBlock, apiEnvironment, at, fillPath, firstMarker, placeholders, pointerTokens } from "./http-adapter-spec.js";
|
|
26
|
+
import { expandRecipe } from "./recipes.js";
|
|
27
|
+
const ACTION_PARAMS = ["api", "vars", "trigger", "request", "undo", "ok_status", "expect", "outputs"];
|
|
28
|
+
const REQUEST_KEYS = ["method", "path", "url", "body", "headers", "content_type", "graphql", "idempotency_key"];
|
|
29
|
+
const METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
30
|
+
function fail(message, param) {
|
|
31
|
+
return paramError(ADAPTER, message, param);
|
|
32
|
+
}
|
|
33
|
+
function mapParam(v, param) {
|
|
34
|
+
if (v === undefined || v === null)
|
|
35
|
+
return {};
|
|
36
|
+
if (!isObject(v))
|
|
37
|
+
throw fail(`\`${param}\` must be a map`, param);
|
|
38
|
+
return v;
|
|
39
|
+
}
|
|
40
|
+
function headersParam(v, param) {
|
|
41
|
+
const o = mapParam(v, param);
|
|
42
|
+
for (const k of Object.keys(o)) {
|
|
43
|
+
if (!HEADER_NAME.test(k))
|
|
44
|
+
throw fail(`\`${param}.${k}\` is not a header name`, `${param}.${k}`);
|
|
45
|
+
if (/^(authorization|accept|content-type|idempotency-key)$/i.test(k))
|
|
46
|
+
throw fail(`\`${param}.${k}\` is set by Sponson or the API block`, `${param}.${k}`);
|
|
47
|
+
}
|
|
48
|
+
return o;
|
|
49
|
+
}
|
|
50
|
+
function contentTypeParam(v, param) {
|
|
51
|
+
if (v === undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
if (typeof v !== "string" || !/^[\w.+-]+\/[\w.+-]+(\s*;.*)?$/.test(v))
|
|
54
|
+
throw fail(`\`${param}\` must be a media type such as application/json`, param);
|
|
55
|
+
return v;
|
|
56
|
+
}
|
|
57
|
+
/** Where a request goes: exactly one of `path`, `url` and `graphql`. */
|
|
58
|
+
function target(o, param) {
|
|
59
|
+
const given = ["path", "url", "graphql"].filter((k) => o[k] !== undefined);
|
|
60
|
+
if (given.length !== 1)
|
|
61
|
+
throw fail(`\`${param}\` needs exactly one of \`path\` (relative to the API's base_url), \`url\` (an absolute URL, sent without the API's credential) or \`graphql\``, param);
|
|
62
|
+
if (o.graphql !== undefined) {
|
|
63
|
+
const extra = Object.keys(o).find((k) => k !== "graphql" && k !== "idempotency_key");
|
|
64
|
+
if (extra)
|
|
65
|
+
throw fail(`\`${param}.${extra}\` does not apply to a GraphQL request (the query and its variables say everything)`, `${param}.${extra}`);
|
|
66
|
+
return { graphql: parseGraphql(o.graphql, `${param}.graphql`, false) };
|
|
67
|
+
}
|
|
68
|
+
if (o.path !== undefined) {
|
|
69
|
+
if (typeof o.path !== "string" || !o.path.startsWith("/"))
|
|
70
|
+
throw fail(`\`${param}.path\` must be a path starting with "/" (relative to the API's base_url)`, `${param}.path`);
|
|
71
|
+
return { path: o.path };
|
|
72
|
+
}
|
|
73
|
+
// A reference (pending, or written as `{ from }`) and an uninterpolated `${ctx.*}` are checked once resolved.
|
|
74
|
+
const known = typeof o.url === "string" && firstMarker(o.url) === undefined && !o.url.includes("${");
|
|
75
|
+
if (known && !/^https?:\/\/\S+$/.test(o.url))
|
|
76
|
+
throw fail(`\`${param}.url\` must be an absolute http(s) URL`, `${param}.url`);
|
|
77
|
+
return { url: o.url };
|
|
78
|
+
}
|
|
79
|
+
function parseRequest(v, param) {
|
|
80
|
+
if (!isObject(v))
|
|
81
|
+
throw fail(`\`${param}\` is required: \`{ method, path | url | graphql, body?, headers? }\``, param);
|
|
82
|
+
const extra = Object.keys(v).find((k) => !REQUEST_KEYS.includes(k));
|
|
83
|
+
if (extra)
|
|
84
|
+
throw fail(`\`${param}.${extra}\` is not known (known: ${REQUEST_KEYS.join(", ")})`, `${param}.${extra}`);
|
|
85
|
+
if (v.idempotency_key !== undefined && typeof v.idempotency_key !== "boolean")
|
|
86
|
+
throw fail(`\`${param}.idempotency_key\` must be true or false`, `${param}.idempotency_key`);
|
|
87
|
+
const where = target(v, param);
|
|
88
|
+
const method = where.graphql ? "POST" : methodOf(v.method, `${param}.method`);
|
|
89
|
+
if (method === "GET" && v.body !== undefined)
|
|
90
|
+
throw fail(`\`${param}.body\` cannot be sent with GET`, `${param}.body`);
|
|
91
|
+
const contentType = contentTypeParam(v.content_type, `${param}.content_type`);
|
|
92
|
+
return {
|
|
93
|
+
method,
|
|
94
|
+
...where,
|
|
95
|
+
...(v.body !== undefined ? { body: v.body } : {}),
|
|
96
|
+
headers: headersParam(v.headers, `${param}.headers`),
|
|
97
|
+
...(contentType ? { contentType } : {}),
|
|
98
|
+
idempotencyKey: v.idempotency_key === true,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function methodOf(v, param) {
|
|
102
|
+
if (v === undefined)
|
|
103
|
+
return "POST";
|
|
104
|
+
const m = typeof v === "string" ? v.toUpperCase() : "";
|
|
105
|
+
if (!METHODS.includes(m))
|
|
106
|
+
throw fail(`\`${param}\` must be one of ${METHODS.join(", ")}`, param);
|
|
107
|
+
return m;
|
|
108
|
+
}
|
|
109
|
+
function parseUndo(v) {
|
|
110
|
+
if (v === undefined || v === null)
|
|
111
|
+
return undefined;
|
|
112
|
+
const r = parseRequest(v, "undo");
|
|
113
|
+
if (r.idempotencyKey)
|
|
114
|
+
throw fail("`undo.idempotency_key` does not apply: an undo is sent once, by destroy", "undo.idempotency_key");
|
|
115
|
+
const { idempotencyKey: _unused, ...undo } = r;
|
|
116
|
+
return undo;
|
|
117
|
+
}
|
|
118
|
+
function parseOutputs(v) {
|
|
119
|
+
const out = {};
|
|
120
|
+
for (const [name, p] of Object.entries(mapParam(v, "outputs"))) {
|
|
121
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
|
|
122
|
+
throw fail(`output name \`${name}\` must be letters, digits and _`, `outputs.${name}`);
|
|
123
|
+
if (typeof p !== "string" || (p !== "" && !p.startsWith("/"))) {
|
|
124
|
+
throw fail(`\`outputs.${name}\` must be a JSON pointer into the answer, such as /data/id (an action's outputs are never sensitive: an unchanged line passes on the recorded ones)`, `outputs.${name}`);
|
|
125
|
+
}
|
|
126
|
+
out[name] = p;
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
function parseOkStatus(v) {
|
|
131
|
+
if (v === undefined)
|
|
132
|
+
return [];
|
|
133
|
+
const list = Array.isArray(v) ? v : [v];
|
|
134
|
+
if (!list.every((s) => Number.isInteger(s) && s >= 400 && s <= 499))
|
|
135
|
+
throw fail("`ok_status` must be a list of HTTP statuses 400–499 that also mean success (such as 409, already done)", "ok_status");
|
|
136
|
+
return list;
|
|
137
|
+
}
|
|
138
|
+
function parseExpect(v) {
|
|
139
|
+
const o = mapParam(v, "expect");
|
|
140
|
+
for (const p of Object.keys(o))
|
|
141
|
+
if (!p.startsWith("/"))
|
|
142
|
+
throw fail(`\`expect.${p}\` must be a JSON pointer into the answer, such as /data/status`, `expect.${p}`);
|
|
143
|
+
return o;
|
|
144
|
+
}
|
|
145
|
+
/** Path placeholders must be declared: in `vars`, or (in `undo`) an output of the action. */
|
|
146
|
+
function checkPlaceholders(req, param, known) {
|
|
147
|
+
for (const name of req?.path ? placeholders(req.path) : []) {
|
|
148
|
+
if (!known.includes(name))
|
|
149
|
+
throw fail(`\`${param}.path\` uses \`{${name}}\`, which is not declared in \`vars\`${param === "undo" ? " or `outputs`" : ""}`, `${param}.path`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** The request goes to the API (its block, credential and base URL), not to an absolute URL. */
|
|
153
|
+
function usesApi(req) {
|
|
154
|
+
return req.url === undefined;
|
|
155
|
+
}
|
|
156
|
+
/** `http.action` params, checked; PARAM_INVALID naming the field otherwise. */
|
|
157
|
+
export function parseAction(line) {
|
|
158
|
+
const params = expandRecipe(line, "action");
|
|
159
|
+
const extra = Object.keys(params).find((k) => !ACTION_PARAMS.includes(k));
|
|
160
|
+
if (extra)
|
|
161
|
+
throw fail(`\`${extra}\` is not a parameter of http.action (known: ${ACTION_PARAMS.join(", ")})`, extra);
|
|
162
|
+
const trigger = mapParam(params.trigger, "trigger");
|
|
163
|
+
if (Object.keys(trigger).length === 0)
|
|
164
|
+
throw fail("`trigger` is required: the values whose change makes the action run again, e.g. `{ sha: \"${ctx.git.sha}\", url: { from: web.preview_url } }`", "trigger");
|
|
165
|
+
const vars = mapParam(params.vars, "vars");
|
|
166
|
+
const request = parseRequest(params.request, "request");
|
|
167
|
+
const undo = parseUndo(params.undo);
|
|
168
|
+
const outputs = parseOutputs(params.outputs);
|
|
169
|
+
checkPlaceholders(request, "request", Object.keys(vars));
|
|
170
|
+
checkPlaceholders(undo, "undo", [...Object.keys(vars), ...Object.keys(outputs)]);
|
|
171
|
+
const api = typeof params.api === "string" && params.api !== "" ? params.api : undefined;
|
|
172
|
+
const needsApi = usesApi(request) || (undo !== undefined && usesApi(undo));
|
|
173
|
+
if (needsApi && !api)
|
|
174
|
+
throw fail("`api` is required for a `path` or `graphql` request: the name of an API configured under `providers.http`", "api");
|
|
175
|
+
if (!needsApi && line.api !== undefined)
|
|
176
|
+
throw fail("a `url` request is sent without the API's credential, so the line takes no `api`: remove it", "api");
|
|
177
|
+
return { ...(api && needsApi ? { api } : {}), vars, trigger, request, ...(undo ? { undo } : {}), okStatus: parseOkStatus(params.ok_status), expect: parseExpect(params.expect), outputs };
|
|
178
|
+
}
|
|
179
|
+
/** `OpSpec.providerFor`: the API block for a line that talks to its API; nothing for one that only calls a `url`. */
|
|
180
|
+
function actionProvider(block, params) {
|
|
181
|
+
const spec = parseAction(params);
|
|
182
|
+
return spec.api ? apiBlock(block, { ...params, api: spec.api }) : {};
|
|
183
|
+
}
|
|
184
|
+
function actionOutputs(params) {
|
|
185
|
+
return Object.fromEntries(Object.keys(parseAction(params).outputs).map((n) => [n, { available: "immediate" }]));
|
|
186
|
+
}
|
|
187
|
+
/** Where a request goes, for labels and errors: the API's path or GraphQL field, or the URL. */
|
|
188
|
+
function describe(spec, req, outputs = {}) {
|
|
189
|
+
if (req.graphql)
|
|
190
|
+
return `${spec.api} GraphQL ${rootField(req.graphql.query) ?? "operation"}`;
|
|
191
|
+
if (req.path)
|
|
192
|
+
return `${spec.api} ${req.method} ${fillPath(req.path, { ...outputs, ...spec.vars }) ?? req.path}`;
|
|
193
|
+
return `${req.method} ${typeof req.url === "string" && firstMarker(req.url) === undefined ? req.url : "(url pending)"}`;
|
|
194
|
+
}
|
|
195
|
+
/** The `Idempotency-Key`: one per action and trigger, so a run sent again after a crash is answered once. */
|
|
196
|
+
function idempotencyKey(actx, key, hash) {
|
|
197
|
+
return `sponson-${sha256(`${actx.ctx.env}|${actx.ctx.scope}|${key}|${hash}`).slice(0, 40)}`;
|
|
198
|
+
}
|
|
199
|
+
/** Header values as strings; PARAM_INVALID for one that is not a scalar. */
|
|
200
|
+
function headerValues(req, param) {
|
|
201
|
+
const out = {};
|
|
202
|
+
for (const [k, v] of Object.entries(req.headers)) {
|
|
203
|
+
if (typeof v !== "string" && typeof v !== "number" && typeof v !== "boolean")
|
|
204
|
+
throw fail(`\`${param}.headers.${k}\` must be a string, number or boolean`, `${param}.headers.${k}`);
|
|
205
|
+
out[k] = String(v);
|
|
206
|
+
}
|
|
207
|
+
return out;
|
|
208
|
+
}
|
|
209
|
+
/** The client a request goes through, and the path to send it to. A `url` request carries no credential. */
|
|
210
|
+
function clientOf(actx, req, headers, vars, param) {
|
|
211
|
+
const opts = { headers, ...(req.contentType ? { contentType: req.contentType } : {}) };
|
|
212
|
+
if (req.url !== undefined) {
|
|
213
|
+
if (typeof req.url !== "string" || !/^https?:\/\/\S+$/.test(req.url))
|
|
214
|
+
throw fail(`\`${param}.url\` must resolve to an absolute http(s) URL`, `${param}.url`);
|
|
215
|
+
// Named by its path in messages (`PUT /api/inngest → 500`); the origin is the client's base URL.
|
|
216
|
+
const url = new URL(req.url);
|
|
217
|
+
return { api: clientFor(actx, ADAPTER, { baseUrl: url.origin, token: "", authHeader: "none", encoding: "json", ...opts }), path: `${url.pathname}${url.search}` };
|
|
218
|
+
}
|
|
219
|
+
const path = req.path === undefined ? "" : fillPath(req.path, vars);
|
|
220
|
+
if (path === undefined)
|
|
221
|
+
throw fail(`\`${param}.path\`: a placeholder has no value`, `${param}.path`);
|
|
222
|
+
return { api: httpClient(actx, req.graphql ? { encoding: "json", headers } : opts), path };
|
|
223
|
+
}
|
|
224
|
+
/** Send one request; the answer, or undefined when it was a listed `ok_status` (nothing to read). */
|
|
225
|
+
async function send(actx, req, c, idempotent, okStatus) {
|
|
226
|
+
try {
|
|
227
|
+
if (req.graphql)
|
|
228
|
+
return await graphqlRequest(c.api, { ...req.graphql, idempotent }, undefined, actx.redact, true);
|
|
229
|
+
if (req.method === "GET")
|
|
230
|
+
return await c.api.get(c.path);
|
|
231
|
+
if (req.method === "DELETE")
|
|
232
|
+
return await c.api.delete(c.path);
|
|
233
|
+
if (req.method === "PUT")
|
|
234
|
+
return await c.api.put(c.path, req.body);
|
|
235
|
+
if (req.method === "PATCH")
|
|
236
|
+
return await c.api.patch(c.path, req.body, undefined, { idempotent });
|
|
237
|
+
return await c.api.post(c.path, req.body, undefined, { idempotent });
|
|
238
|
+
}
|
|
239
|
+
catch (e) {
|
|
240
|
+
const status = isProviderError(e) ? e.details.status : undefined;
|
|
241
|
+
if (status !== undefined && okStatus.includes(status))
|
|
242
|
+
return undefined;
|
|
243
|
+
// A 2xx answer that is not JSON (`OK`): accepted; there is just nothing to read.
|
|
244
|
+
if (isProviderError(e, "PROVIDER_RESPONSE") && status !== undefined && status >= 200 && status < 300)
|
|
245
|
+
return undefined;
|
|
246
|
+
throw e;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/** Every `expect` pointer holds its value in the answer, or the action failed (PROVIDER_RESPONSE). */
|
|
250
|
+
function checkExpect(spec, answer, what) {
|
|
251
|
+
for (const [pointer, want] of Object.entries(spec.expect)) {
|
|
252
|
+
const got = at(answer, pointerTokens(pointer));
|
|
253
|
+
if (canonicalJson(got ?? null) === canonicalJson(want))
|
|
254
|
+
continue;
|
|
255
|
+
const shown = got === undefined ? "nothing" : JSON.stringify(got).slice(0, 120);
|
|
256
|
+
throw new SponsonError("PROVIDER_RESPONSE", `${ADAPTER}: ${what}: the answer has ${shown} at ${pointer}, expected ${JSON.stringify(want)} (\`expect\`)`, { adapter: ADAPTER, param: `expect.${pointer}` });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function outputsOf(spec, answer) {
|
|
260
|
+
const out = {};
|
|
261
|
+
for (const [name, pointer] of Object.entries(spec.outputs)) {
|
|
262
|
+
const v = literalOf(at(answer, pointerTokens(pointer)));
|
|
263
|
+
if (v !== undefined)
|
|
264
|
+
out[name] = v;
|
|
265
|
+
}
|
|
266
|
+
return out;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* The record id: `FORGET`, or the undo request with everything resolved now (outputs fill its placeholders). Kept
|
|
270
|
+
* in receipts, so it may not carry a secret.
|
|
271
|
+
*/
|
|
272
|
+
function undoId(actx, spec, outputs) {
|
|
273
|
+
const u = spec.undo;
|
|
274
|
+
if (!u)
|
|
275
|
+
return "FORGET";
|
|
276
|
+
const path = u.path === undefined ? undefined : fillPath(u.path, { ...outputs, ...spec.vars });
|
|
277
|
+
if (u.path !== undefined && path === undefined)
|
|
278
|
+
throw new SponsonError("PROVIDER_RESPONSE", `${ADAPTER}: \`undo.path\` ${u.path}: the answer has no value for one of its placeholders`, { adapter: ADAPTER, param: "undo.path" });
|
|
279
|
+
const request = { method: u.method, ...(path !== undefined ? { path } : {}), ...(u.url !== undefined ? { url: u.url } : {}), ...(u.body !== undefined ? { body: u.body } : {}), ...(u.graphql ? { graphql: { query: u.graphql.query, variables: u.graphql.variables } } : {}), headers: headerValues(u, "undo") };
|
|
280
|
+
const id = `UNDO ${canonicalJson(request)}`;
|
|
281
|
+
if (actx.redact(id) !== id)
|
|
282
|
+
throw fail("`undo` may not hold a secret: it is kept in receipts so that destroy can send it", "undo");
|
|
283
|
+
return id;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* What the ledger knows a line's action by, as far as the line decides it: the key is the engine's
|
|
287
|
+
* (`action:<line id>`), the record id `FORGET` or the undo request (its placeholders filled when it runs). The
|
|
288
|
+
* recipe identity lock (recipes.test.ts) pins it per recipe op.
|
|
289
|
+
*/
|
|
290
|
+
export function actionIdentity(spec) {
|
|
291
|
+
const u = spec.undo;
|
|
292
|
+
if (!u)
|
|
293
|
+
return { key: "action:<line id>", id: "FORGET" };
|
|
294
|
+
const template = { method: u.method, path: u.path, url: u.url, body: u.body, graphql: u.graphql ? { query: u.graphql.query, variables: u.graphql.variables } : undefined };
|
|
295
|
+
return { key: "action:<line id>", id: `UNDO ${canonicalJson(JSON.parse(JSON.stringify(template)))}` };
|
|
296
|
+
}
|
|
297
|
+
/** The undo request a record id names; null for `FORGET`. */
|
|
298
|
+
function parseUndoId(id) {
|
|
299
|
+
if (id === "FORGET" || id === "")
|
|
300
|
+
return null;
|
|
301
|
+
const m = /^UNDO (\{.*\})$/s.exec(id);
|
|
302
|
+
const r = m ? JSON.parse(m[1]) : undefined;
|
|
303
|
+
if (!r || typeof r.method !== "string")
|
|
304
|
+
throw new SponsonError("INTERNAL", `${ADAPTER}: record id is not an action's undo request`, { adapter: ADAPTER });
|
|
305
|
+
const g = isObject(r.graphql) ? r.graphql : undefined;
|
|
306
|
+
return {
|
|
307
|
+
method: r.method,
|
|
308
|
+
...(typeof r.path === "string" ? { path: r.path } : {}),
|
|
309
|
+
...(r.url !== undefined ? { url: r.url } : {}),
|
|
310
|
+
...(r.body !== undefined ? { body: r.body } : {}),
|
|
311
|
+
headers: isObject(r.headers) ? r.headers : {},
|
|
312
|
+
...(g ? { graphql: { query: String(g.query), variables: isObject(g.variables) ? g.variables : {}, idempotent: true } } : {}),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
async function run(actx, params, key, hash) {
|
|
316
|
+
const spec = parseAction(params);
|
|
317
|
+
const req = spec.request;
|
|
318
|
+
const what = describe(spec, req);
|
|
319
|
+
const headers = { ...headerValues(req, "request"), ...(req.idempotencyKey ? { "Idempotency-Key": idempotencyKey(actx, key, hash) } : {}) };
|
|
320
|
+
actx.log(`run ${what}`);
|
|
321
|
+
const answer = await send(actx, req, clientOf(actx, req, headers, spec.vars, "request"), req.idempotencyKey, spec.okStatus);
|
|
322
|
+
checkExpect(spec, answer, what);
|
|
323
|
+
const outputs = outputsOf(spec, answer);
|
|
324
|
+
return { resources: [{ key, id: undoId(actx, spec, outputs), hash, label: what }], outputs, created: [] };
|
|
325
|
+
}
|
|
326
|
+
/** `http.action`: one request sent when the line's trigger changes; the engine records which trigger ran. */
|
|
327
|
+
export const action = {
|
|
328
|
+
outputs: {},
|
|
329
|
+
outputsFor: actionOutputs,
|
|
330
|
+
providerFor: actionProvider,
|
|
331
|
+
writesEnvironment: apiEnvironment,
|
|
332
|
+
action(params) {
|
|
333
|
+
const spec = parseAction(params);
|
|
334
|
+
if (firstMarker(spec.trigger) !== undefined)
|
|
335
|
+
return null;
|
|
336
|
+
return { trigger: spec.trigger, label: describe(spec, spec.request) };
|
|
337
|
+
},
|
|
338
|
+
async read() {
|
|
339
|
+
// The engine owns an action's state (OpSpec.action): there is nothing at the provider to read back.
|
|
340
|
+
return null;
|
|
341
|
+
},
|
|
342
|
+
diff() {
|
|
343
|
+
return [];
|
|
344
|
+
},
|
|
345
|
+
async apply(actx, params, live) {
|
|
346
|
+
assertNoPending(params, ADAPTER);
|
|
347
|
+
const r = live?.resources[0];
|
|
348
|
+
if (!r)
|
|
349
|
+
throw new SponsonError("INTERNAL", `${ADAPTER}: http.action is applied by the engine's action path, which passes its ledger key and trigger hash`, { adapter: ADAPTER });
|
|
350
|
+
return run(actx, params, r.key, r.hash);
|
|
351
|
+
},
|
|
352
|
+
async destroy(actx, resources) {
|
|
353
|
+
for (const r of resources) {
|
|
354
|
+
const undo = parseUndoId(r.id);
|
|
355
|
+
if (!undo)
|
|
356
|
+
continue;
|
|
357
|
+
actx.log(`undo ${r.label ?? r.key}`);
|
|
358
|
+
try {
|
|
359
|
+
await send(actx, undo, clientOf(actx, undo, headerValues(undo, "undo"), {}, "undo"), true, []);
|
|
360
|
+
}
|
|
361
|
+
catch (e) {
|
|
362
|
+
// Already undone (or never there): what destroy wanted.
|
|
363
|
+
if (!isProviderError(e, "PROVIDER_NOT_FOUND"))
|
|
364
|
+
throw e;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
//# sourceMappingURL=http-adapter-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-adapter-action.js","sourceRoot":"","sources":["../src/http-adapter-action.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { SponsonError, type AdapterContext } from "@sponson/core";
|
|
2
|
+
import { type RequestSigner } from "./http.js";
|
|
3
|
+
import { type Exec } from "./secrets.js";
|
|
4
|
+
/** How a token is sent to an OAuth2 token endpoint (RFC 6749 §2.3.1). */
|
|
5
|
+
export type ClientAuthMethod = "client_secret_post" | "client_secret_basic";
|
|
6
|
+
/** How the credential is sent. */
|
|
7
|
+
export type Auth = {
|
|
8
|
+
kind: "bearer";
|
|
9
|
+
env: string;
|
|
10
|
+
} | {
|
|
11
|
+
kind: "header";
|
|
12
|
+
header: string;
|
|
13
|
+
env: string;
|
|
14
|
+
prefix?: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: "headers";
|
|
17
|
+
headers: Array<{
|
|
18
|
+
header: string;
|
|
19
|
+
env: string;
|
|
20
|
+
prefix?: string;
|
|
21
|
+
}>;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "basic";
|
|
24
|
+
userEnv: string;
|
|
25
|
+
passwordEnv: string;
|
|
26
|
+
} | {
|
|
27
|
+
kind: "oauth2";
|
|
28
|
+
tokenUrl: string;
|
|
29
|
+
tokenUrlEnv?: string;
|
|
30
|
+
clientIdEnv: string;
|
|
31
|
+
clientSecretEnv: string;
|
|
32
|
+
audience?: string;
|
|
33
|
+
scope?: string;
|
|
34
|
+
extra: Record<string, string>;
|
|
35
|
+
method: ClientAuthMethod;
|
|
36
|
+
} | {
|
|
37
|
+
kind: "command";
|
|
38
|
+
argv: string[];
|
|
39
|
+
} | {
|
|
40
|
+
kind: "sigv4";
|
|
41
|
+
region: string;
|
|
42
|
+
service: string;
|
|
43
|
+
accessKeyIdEnv: string;
|
|
44
|
+
secretAccessKeyEnv: string;
|
|
45
|
+
sessionTokenEnv?: string;
|
|
46
|
+
} | {
|
|
47
|
+
kind: "digest";
|
|
48
|
+
userEnv: string;
|
|
49
|
+
passwordEnv: string;
|
|
50
|
+
}
|
|
51
|
+
/** No credential: only for a public endpoint a manual step's verify request reads (`parseApi(…, { authOptional })`). */
|
|
52
|
+
| {
|
|
53
|
+
kind: "none";
|
|
54
|
+
};
|
|
55
|
+
/** An HTTP header name (RFC 9110 token). */
|
|
56
|
+
export declare const HEADER_NAME: RegExp;
|
|
57
|
+
/** PLAN_INVALID naming where in the provider block the fault is. */
|
|
58
|
+
export declare function planError(message: string, where: string): SponsonError;
|
|
59
|
+
/** The NAME of an environment variable; a credential's name must be one the engine masks. */
|
|
60
|
+
export declare function envName(v: unknown, where: string, credential: boolean): string;
|
|
61
|
+
/**
|
|
62
|
+
* `providers.http.<api>.auth`, checked: PLAN_INVALID naming the key at fault otherwise. `base`: the block's
|
|
63
|
+
* `base_url`, which an OAuth2 `token_url` or `audience` written as a path is resolved against.
|
|
64
|
+
*/
|
|
65
|
+
export declare function parseAuth(v: unknown, where: string, base?: string): Auth;
|
|
66
|
+
/** What the run-time side depends on, injected in tests: how a command runs, and the clock. */
|
|
67
|
+
export interface AuthDeps {
|
|
68
|
+
exec: Exec;
|
|
69
|
+
now: () => number;
|
|
70
|
+
}
|
|
71
|
+
/** The real dependencies: commands from PATH, the system clock. */
|
|
72
|
+
export declare const DEFAULT_AUTH_DEPS: AuthDeps;
|
|
73
|
+
/** How a client authenticates: a static header (`token`, `authHeader`) or a signer, and the values to mask. */
|
|
74
|
+
export interface Credential {
|
|
75
|
+
token: string;
|
|
76
|
+
authHeader: "bearer" | "none" | `header:${string}`;
|
|
77
|
+
signer?: RequestSigner;
|
|
78
|
+
/** Values this adapter masks in its own error text, besides what the engine masks. */
|
|
79
|
+
masks: () => string[];
|
|
80
|
+
}
|
|
81
|
+
/** How long a command's token is used before the command runs again (CLIs print tokens valid for 5–60 minutes). */
|
|
82
|
+
export declare const COMMAND_TOKEN_TTL_MS: number;
|
|
83
|
+
/**
|
|
84
|
+
* The credential of an API block for this call; `line`, a line's own `credential`, replaces the variable of a bearer
|
|
85
|
+
* or header form (ADR 0017, "Line credentials"). Static forms read their variables now (PROVIDER_AUTH when one is
|
|
86
|
+
* unset); dynamic ones fetch or sign per request, through the run's cache.
|
|
87
|
+
*/
|
|
88
|
+
export declare function credentialFor(actx: AdapterContext, auth: Auth, deps: AuthDeps, redact: (t: string) => string, line?: string): Credential;
|