@sponson/adapters 0.0.0-stage → 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/LICENSE +202 -0
- package/README.md +4 -2
- package/dist/algolia.d.ts +6 -0
- package/dist/algolia.js +151 -0
- package/dist/algolia.js.map +1 -0
- package/dist/clerk.d.ts +8 -0
- package/dist/clerk.js +107 -0
- package/dist/clerk.js.map +1 -0
- 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 +73 -0
- package/dist/common.js +140 -0
- package/dist/common.js.map +1 -0
- 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 +179 -0
- package/dist/http.js +352 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- 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.d.ts +8 -0
- package/dist/neon.js +167 -0
- package/dist/neon.js.map +1 -0
- 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 +72 -0
- package/dist/secrets.js +476 -0
- package/dist/secrets.js.map +1 -0
- 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.d.ts +8 -0
- package/dist/vercel.js +475 -0
- package/dist/vercel.js.map +1 -0
- 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 +58 -3
- 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,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare adapter. One op, `pages_env`: the variables of a Cloudflare Pages project's `preview` or `production`
|
|
3
|
+
* deployment config (`deployment_configs.<env>.env_vars`), plain text (`vars`) and secret (`secrets`).
|
|
4
|
+
*
|
|
5
|
+
* The variables are a map on the project, not objects of their own, so `apply` is read-modify-write: it PATCHes only
|
|
6
|
+
* the keys this line manages (Cloudflare merges the map; `null` deletes a key), as an idempotent PATCH, then re-reads
|
|
7
|
+
* the project to check that what it sent landed and that no other key went missing. API facts and their sources are
|
|
8
|
+
* the numbered assumptions (CF1…) at the top of packages/sim/src/routes/cloudflare.ts.
|
|
9
|
+
*
|
|
10
|
+
* Pages has one set of preview variables shared by every preview deployment (CF8): there are no per-branch values.
|
|
11
|
+
* A key is therefore one resource per environment, `env:<target>:<NAME>`, whatever scope wrote it; a second scope
|
|
12
|
+
* (another pull request) that declares the same key with another value is refused with OWNED_BY_OTHER_SCOPE.
|
|
13
|
+
*
|
|
14
|
+
* Secret values are write-only (CF3): a `secret_text` variable is compared by presence and type, never by value.
|
|
15
|
+
* See `secretHash` and docs/plan-format.md (`cloudflare.pages_env`).
|
|
16
|
+
*/
|
|
17
|
+
import { SponsonError, canonicalJson, markerKind, sha256 } from "@sponson/core";
|
|
18
|
+
import { ABSENT, SENSITIVE, assertNoPending, clientFor, desiredSide, optionalEnv, paramError, requireEnv, requireProvider, stringParam } from "./common.js";
|
|
19
|
+
import { ShapeError, isObject, isProviderError, obj } from "./http.js";
|
|
20
|
+
const ADAPTER = "cloudflare";
|
|
21
|
+
/** The environment Cloudflare reads; declared once, used by the code below and by the generated docs (`about`). */
|
|
22
|
+
const ABOUT = { credentialEnv: "CLOUDFLARE_API_TOKEN", baseUrlEnv: "CLOUDFLARE_API_URL", title: "Cloudflare Pages", category: "deploy", detect: { deps: ["wrangler", "@cloudflare/next-on-pages"], env: ["CLOUDFLARE_*"], files: ["wrangler.json", "wrangler.jsonc", "wrangler.toml"] } };
|
|
23
|
+
/** Cloudflare's API base URL (CF1). `CLOUDFLARE_API_URL` overrides it; tests and scenarios point that at the sim. */
|
|
24
|
+
export const CLOUDFLARE_DEFAULT_API_URL = "https://api.cloudflare.com/client/v4";
|
|
25
|
+
const TARGETS = ["preview", "production"];
|
|
26
|
+
/** The HTTP client and the project's path, from `providers.cloudflare.{account,project}`. */
|
|
27
|
+
function client(actx) {
|
|
28
|
+
const token = requireEnv(actx.env, ABOUT.credentialEnv, ADAPTER);
|
|
29
|
+
const account = requireProvider(actx, "account", ADAPTER);
|
|
30
|
+
const project = requireProvider(actx, "project", ADAPTER);
|
|
31
|
+
return {
|
|
32
|
+
api: clientFor(actx, ADAPTER, { baseUrl: optionalEnv(actx.env, ABOUT.baseUrlEnv) ?? CLOUDFLARE_DEFAULT_API_URL, token }),
|
|
33
|
+
path: `/accounts/${encodeURIComponent(account)}/pages/projects/${encodeURIComponent(project)}`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Response shape (CF2): { success, errors, messages, result: project }
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
/** One environment's `env_vars` (nullable in the schema) as a map. A secret's value is dropped whatever it says. */
|
|
40
|
+
function parseVars(v, what) {
|
|
41
|
+
const out = new Map();
|
|
42
|
+
if (v === null || v === undefined)
|
|
43
|
+
return out;
|
|
44
|
+
for (const [name, e] of Object.entries(obj(v, what))) {
|
|
45
|
+
if (e === null)
|
|
46
|
+
continue;
|
|
47
|
+
const entry = obj(e, `${what}.${name}`);
|
|
48
|
+
if (typeof entry.type !== "string")
|
|
49
|
+
throw new ShapeError(`expected ${what}.${name}.type to be a string`);
|
|
50
|
+
const readable = entry.type === "plain_text" && typeof entry.value === "string";
|
|
51
|
+
out.set(name, readable ? { type: entry.type, value: entry.value } : { type: entry.type });
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
function parseProject(body) {
|
|
56
|
+
const env = obj(body, "the response");
|
|
57
|
+
if (env.success !== true)
|
|
58
|
+
throw new ShapeError("expected `success` to be true");
|
|
59
|
+
const configs = obj(obj(env.result, "`result`").deployment_configs, "`result.deployment_configs`");
|
|
60
|
+
const of = (t) => {
|
|
61
|
+
const c = configs[t];
|
|
62
|
+
return c === null || c === undefined ? new Map() : parseVars(obj(c, `\`deployment_configs.${t}\``).env_vars, `\`deployment_configs.${t}.env_vars\``);
|
|
63
|
+
};
|
|
64
|
+
return { preview: of("preview"), production: of("production") };
|
|
65
|
+
}
|
|
66
|
+
async function readVars(c, target) {
|
|
67
|
+
return (await c.api.get(c.path, parseProject))[target];
|
|
68
|
+
}
|
|
69
|
+
/** PATCH a partial `env_vars` map (CF4): a value sets a key, `null` deletes it, keys not named are left alone. */
|
|
70
|
+
async function patchVars(c, target, vars) {
|
|
71
|
+
// Sets state rather than adding to it, so a dropped connection or a 5xx may be retried.
|
|
72
|
+
await c.api.patch(c.path, { deployment_configs: { [target]: { env_vars: vars } } }, undefined, { idempotent: true });
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Hashes: one canonical form for read, diff and apply
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
/** A plain-text variable: its type and value. */
|
|
78
|
+
function plainHash(value) {
|
|
79
|
+
return sha256(canonicalJson({ type: "plain_text", value }));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A secret: its type only. Cloudflare never returns a secret's value (CF3) and the adapter API offers no place to
|
|
83
|
+
* keep a fingerprint, so a secret is equal when it exists as `secret_text`. What that means: a value changed in the
|
|
84
|
+
* Cloudflare dashboard is not seen as drift; a changed value in the plan is not written unless the line sets
|
|
85
|
+
* `rewrite_secrets: true` (then every apply sends the secrets again). Deleting it, or turning it into plain text,
|
|
86
|
+
* is seen.
|
|
87
|
+
*/
|
|
88
|
+
function secretHash() {
|
|
89
|
+
return sha256(canonicalJson({ type: "secret_text" }));
|
|
90
|
+
}
|
|
91
|
+
function liveHash(v) {
|
|
92
|
+
if (v.type === "plain_text")
|
|
93
|
+
return plainHash(v.value ?? "");
|
|
94
|
+
if (v.type === "secret_text")
|
|
95
|
+
return secretHash();
|
|
96
|
+
return sha256(canonicalJson({ type: v.type }));
|
|
97
|
+
}
|
|
98
|
+
function mapParam(params, name) {
|
|
99
|
+
const v = params[name];
|
|
100
|
+
if (v === undefined || v === null)
|
|
101
|
+
return {};
|
|
102
|
+
if (!isObject(v))
|
|
103
|
+
throw paramError(ADAPTER, `param \`${name}\` must be an object of NAME → value`, name);
|
|
104
|
+
return v;
|
|
105
|
+
}
|
|
106
|
+
function envScope(params) {
|
|
107
|
+
const target = stringParam(params, "target", ADAPTER, "preview");
|
|
108
|
+
if (!TARGETS.includes(target))
|
|
109
|
+
throw paramError(ADAPTER, `param \`target\` must be one of ${TARGETS.join(", ")} (got ${JSON.stringify(target)})`, "target");
|
|
110
|
+
const rewrite = params.rewrite_secrets;
|
|
111
|
+
if (rewrite !== undefined && rewrite !== null && typeof rewrite !== "boolean")
|
|
112
|
+
throw paramError(ADAPTER, "param `rewrite_secrets` must be true or false", "rewrite_secrets");
|
|
113
|
+
const values = new Map();
|
|
114
|
+
for (const [name, value] of Object.entries(mapParam(params, "vars")))
|
|
115
|
+
values.set(name, { value, type: "plain_text" });
|
|
116
|
+
for (const [name, value] of Object.entries(mapParam(params, "secrets"))) {
|
|
117
|
+
if (values.has(name))
|
|
118
|
+
throw paramError(ADAPTER, `${name} is in both \`vars\` and \`secrets\`; a variable is either plain text or secret`, "secrets");
|
|
119
|
+
values.set(name, { value, type: "secret_text" });
|
|
120
|
+
}
|
|
121
|
+
for (const name of values.keys())
|
|
122
|
+
if (name === "")
|
|
123
|
+
throw paramError(ADAPTER, "a variable name must not be empty", "vars");
|
|
124
|
+
return { target: target, values, rewriteSecrets: rewrite === true };
|
|
125
|
+
}
|
|
126
|
+
/** The target a run writes by default: production under `--env production`, preview otherwise. */
|
|
127
|
+
function targetFor(ctx) {
|
|
128
|
+
return ctx.env === "production" ? "production" : "preview";
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Pages has exactly two variable sets, so the line must write the run's own environment. Ownership between scopes
|
|
132
|
+
* is decided among the scopes of one Sponson environment; a `target: production` line applied under `--env preview`
|
|
133
|
+
* would be invisible to the production scopes' ledgers (and a preview pull request's destroy would delete it).
|
|
134
|
+
*/
|
|
135
|
+
function assertRunEnvironment(scope, ctx) {
|
|
136
|
+
if (scope.target === ctx.env)
|
|
137
|
+
return;
|
|
138
|
+
throw paramError(ADAPTER, `this line writes the Pages \`${scope.target}\` variables but the run's environment is \`${ctx.env}\`. Pages variables are shared by every deployment of an environment, so Sponson only writes them from a run of that environment: run with \`--env ${scope.target}\`, or limit the line with \`environments: [${scope.target}]\`.`, "target");
|
|
139
|
+
}
|
|
140
|
+
/** Identity: the environment and the name. No branch or scope: every preview deployment shares the set (CF8). */
|
|
141
|
+
function varKey(target, name) {
|
|
142
|
+
return `env:${target}:${name}`;
|
|
143
|
+
}
|
|
144
|
+
/** Inverse of varKey. A target never contains `:`; a name may. */
|
|
145
|
+
function parseVarKey(key) {
|
|
146
|
+
const m = /^env:(preview|production):(.+)$/.exec(key);
|
|
147
|
+
if (!m)
|
|
148
|
+
throw new SponsonError("INTERNAL", `${ADAPTER}: \`${key}\` is not a pages_env key`, { adapter: ADAPTER, key });
|
|
149
|
+
return { target: m[1], name: m[2] };
|
|
150
|
+
}
|
|
151
|
+
const SECRET_LABEL = ", secret)";
|
|
152
|
+
function varLabel(target, name, type) {
|
|
153
|
+
return `${name} (Pages ${target}${type === "secret_text" ? SECRET_LABEL : ")"}`;
|
|
154
|
+
}
|
|
155
|
+
function varRecord(target, name, v) {
|
|
156
|
+
return { key: varKey(target, name), id: name, hash: liveHash(v), label: varLabel(target, name, v.type) };
|
|
157
|
+
}
|
|
158
|
+
/** One declared variable's diff against its live record. */
|
|
159
|
+
function diffVar(scope, name, desired, live) {
|
|
160
|
+
const key = varKey(scope.target, name);
|
|
161
|
+
const label = varLabel(scope.target, name, desired.type);
|
|
162
|
+
const secret = desired.type === "secret_text";
|
|
163
|
+
const marker = markerKind(desired.value);
|
|
164
|
+
if (marker === "keep") {
|
|
165
|
+
if (live)
|
|
166
|
+
return { key, kind: "unchanged", label };
|
|
167
|
+
throw paramError(ADAPTER, `${label} is declared \`{ keep: true }\` but does not exist, so there is no value to keep. Give it a value or remove it.`, secret ? "secrets" : "vars");
|
|
168
|
+
}
|
|
169
|
+
const after = desiredSide(desired.value, secret);
|
|
170
|
+
if (!live)
|
|
171
|
+
return { key, kind: "create", label, before: ABSENT, after };
|
|
172
|
+
if (marker === null && !(secret && scope.rewriteSecrets)) {
|
|
173
|
+
const want = secret ? secretHash() : plainHash(String(desired.value));
|
|
174
|
+
if (live.hash === want)
|
|
175
|
+
return { key, kind: "unchanged", label };
|
|
176
|
+
}
|
|
177
|
+
return { key, kind: "update", label, before: SENSITIVE, after };
|
|
178
|
+
}
|
|
179
|
+
/** After a write: every variable sent is there as sent, and every other variable that was there still is. */
|
|
180
|
+
function verifyWrite(c, target, sent, before, after) {
|
|
181
|
+
const wrong = [...sent].filter(([name, s]) => {
|
|
182
|
+
const v = after.get(name);
|
|
183
|
+
return !v || v.type !== s.type || (s.type === "plain_text" && v.value !== s.value);
|
|
184
|
+
});
|
|
185
|
+
const lost = [...before.keys()].filter((name) => !sent.has(name) && !after.has(name));
|
|
186
|
+
if (wrong.length === 0 && lost.length === 0)
|
|
187
|
+
return;
|
|
188
|
+
const parts = [
|
|
189
|
+
...(wrong.length ? [`does not show ${wrong.map(([n]) => n).join(", ")} as written`] : []),
|
|
190
|
+
...(lost.length ? [`no longer has ${lost.join(", ")}, which this write did not name (another writer removed them, or the PATCH replaced the map instead of merging it)`] : []),
|
|
191
|
+
];
|
|
192
|
+
throw new SponsonError("PROVIDER_RESPONSE", `${ADAPTER}: after PATCH ${c.path}, the ${target} env_vars ${parts.join("; ")}`, { adapter: ADAPTER, method: "PATCH", path: c.path, written: wrong.map(([n]) => n), lost });
|
|
193
|
+
}
|
|
194
|
+
const pagesEnv = {
|
|
195
|
+
outputs: {},
|
|
196
|
+
defaults(params, ctx) {
|
|
197
|
+
return { ...params, target: params.target ?? targetFor(ctx) };
|
|
198
|
+
},
|
|
199
|
+
writesEnvironment(params, ctx) {
|
|
200
|
+
return typeof params.target === "string" ? params.target : targetFor(ctx);
|
|
201
|
+
},
|
|
202
|
+
/**
|
|
203
|
+
* The environment's `env_vars` map is read-modify-write on one project object that every scope (and a run of the
|
|
204
|
+
* other environment, for the other map) writes, so the engine serialises writers with a parent lock (ADR 0019).
|
|
205
|
+
*/
|
|
206
|
+
lockOn(params, provider) {
|
|
207
|
+
const { account, project } = provider;
|
|
208
|
+
if (typeof account !== "string" || account === "" || typeof project !== "string" || project === "")
|
|
209
|
+
return null;
|
|
210
|
+
const target = typeof params.target === "string" && params.target !== "" ? params.target : "preview";
|
|
211
|
+
return `cloudflare:${account}:pages:${project}:${target}:env`;
|
|
212
|
+
},
|
|
213
|
+
async read(actx, params) {
|
|
214
|
+
const scope = envScope(params);
|
|
215
|
+
assertRunEnvironment(scope, actx.ctx);
|
|
216
|
+
const live = await readVars(client(actx), scope.target);
|
|
217
|
+
const resources = [];
|
|
218
|
+
for (const name of scope.values.keys()) {
|
|
219
|
+
const v = live.get(name);
|
|
220
|
+
if (v)
|
|
221
|
+
resources.push(varRecord(scope.target, name, v));
|
|
222
|
+
}
|
|
223
|
+
return resources.length ? { resources, outputs: {} } : null;
|
|
224
|
+
},
|
|
225
|
+
diff(live, params) {
|
|
226
|
+
const scope = envScope(params);
|
|
227
|
+
const byKey = new Map((live?.resources ?? []).map((r) => [r.key, r]));
|
|
228
|
+
return [...scope.values].map(([name, desired]) => diffVar(scope, name, desired, byKey.get(varKey(scope.target, name))));
|
|
229
|
+
},
|
|
230
|
+
async apply(actx, params, live) {
|
|
231
|
+
assertNoPending(params, ADAPTER);
|
|
232
|
+
const scope = envScope(params);
|
|
233
|
+
assertRunEnvironment(scope, actx.ctx);
|
|
234
|
+
const diffs = new Map(pagesEnv.diff(live, params).map((d) => [d.key, d.kind]));
|
|
235
|
+
const sent = new Map();
|
|
236
|
+
for (const [name, d] of scope.values)
|
|
237
|
+
if (diffs.get(varKey(scope.target, name)) !== "unchanged")
|
|
238
|
+
sent.set(name, { type: d.type, value: String(d.value) });
|
|
239
|
+
const created = [...sent.keys()].map((n) => varKey(scope.target, n)).filter((k) => diffs.get(k) === "create");
|
|
240
|
+
if (sent.size === 0)
|
|
241
|
+
return { resources: live?.resources ?? [], outputs: {}, created: [] };
|
|
242
|
+
const c = client(actx);
|
|
243
|
+
// Read-modify-write: the variables before the write, to check afterwards that no other key was lost.
|
|
244
|
+
const before = await readVars(c, scope.target);
|
|
245
|
+
if (created.length)
|
|
246
|
+
await actx.intend(created);
|
|
247
|
+
actx.log(`set ${sent.size} Pages ${scope.target} variable(s): ${[...sent.keys()].join(", ")}`);
|
|
248
|
+
await patchVars(c, scope.target, Object.fromEntries(sent));
|
|
249
|
+
const after = await readVars(c, scope.target);
|
|
250
|
+
verifyWrite(c, scope.target, sent, before, after);
|
|
251
|
+
// A declared variable missing now was not written by this call (verifyWrite checked those): it vanished meanwhile.
|
|
252
|
+
const resources = [...scope.values.keys()].flatMap((name) => {
|
|
253
|
+
const v = after.get(name);
|
|
254
|
+
return v ? [varRecord(scope.target, name, v)] : [];
|
|
255
|
+
});
|
|
256
|
+
return { resources, outputs: {}, created };
|
|
257
|
+
},
|
|
258
|
+
/** `null` for each key still present, per environment; a project or key already gone is success. */
|
|
259
|
+
async destroy(actx, resources) {
|
|
260
|
+
const c = client(actx);
|
|
261
|
+
const byTarget = new Map();
|
|
262
|
+
for (const r of resources) {
|
|
263
|
+
const { target, name } = parseVarKey(r.key);
|
|
264
|
+
byTarget.set(target, [...(byTarget.get(target) ?? []), name]);
|
|
265
|
+
}
|
|
266
|
+
for (const [target, names] of byTarget) {
|
|
267
|
+
let live;
|
|
268
|
+
try {
|
|
269
|
+
live = await readVars(c, target);
|
|
270
|
+
}
|
|
271
|
+
catch (e) {
|
|
272
|
+
if (isProviderError(e, "PROVIDER_NOT_FOUND"))
|
|
273
|
+
return;
|
|
274
|
+
throw e;
|
|
275
|
+
}
|
|
276
|
+
const present = names.filter((n) => live.has(n));
|
|
277
|
+
if (present.length)
|
|
278
|
+
await patchVars(c, target, Object.fromEntries(present.map((n) => [n, null])));
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
/** Every variable of the line's environment, for drift (`unmanaged`) and `sponson init`. */
|
|
282
|
+
async listScope(actx, params) {
|
|
283
|
+
const scope = envScope(params);
|
|
284
|
+
const live = await readVars(client(actx), scope.target);
|
|
285
|
+
return [...live].map(([name, v]) => varRecord(scope.target, name, v));
|
|
286
|
+
},
|
|
287
|
+
/** One line per environment; every variable `{ keep: true }` under `vars` or `secrets`, never its value. */
|
|
288
|
+
adopt(resources) {
|
|
289
|
+
const groups = new Map();
|
|
290
|
+
for (const r of resources) {
|
|
291
|
+
const { target, name } = parseVarKey(r.key);
|
|
292
|
+
const g = groups.get(target) ?? { vars: {}, secrets: {}, keys: [] };
|
|
293
|
+
(r.label?.endsWith(SECRET_LABEL) ? g.secrets : g.vars)[name] = { keep: true };
|
|
294
|
+
g.keys.push(r.key);
|
|
295
|
+
groups.set(target, g);
|
|
296
|
+
}
|
|
297
|
+
return [...groups].map(([target, g]) => ({
|
|
298
|
+
id: `pages-env-${target}`,
|
|
299
|
+
params: { target, ...(Object.keys(g.vars).length ? { vars: g.vars } : {}), ...(Object.keys(g.secrets).length ? { secrets: g.secrets } : {}) },
|
|
300
|
+
keys: g.keys,
|
|
301
|
+
}));
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* The Cloudflare adapter (`adapter: cloudflare` in a plan): op `pages_env` manages a Pages project's preview or
|
|
306
|
+
* production variables. Needs `CLOUDFLARE_API_TOKEN` (account permission "Cloudflare Pages Edit") and
|
|
307
|
+
* `providers.cloudflare.{account,project}`.
|
|
308
|
+
*/
|
|
309
|
+
export const cloudflareAdapter = { name: ADAPTER, ops: { pages_env: pagesEnv }, about: ABOUT };
|
|
310
|
+
//# sourceMappingURL=cloudflare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../src/cloudflare.ts"],"names":[],"mappings":"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"}
|
package/dist/common.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { SponsonError, type AdapterContext, type DiffSide, type ResolvedParams, type ResourceDiff, type ResourceRecord } from "@sponson/core";
|
|
2
|
+
import { type ApiClient, type ApiClientOptions } from "./http.js";
|
|
3
|
+
/**
|
|
4
|
+
* The adapter authoring API. These helpers are stable and exported from `@sponson/adapters`; third-party
|
|
5
|
+
* adapters should use them rather than re-implementing the contracts they encode:
|
|
6
|
+
*
|
|
7
|
+
* clientFor HTTP client with retry policy and redaction from the adapter context
|
|
8
|
+
* requireEnv a credential from the environment, PROVIDER_AUTH when missing
|
|
9
|
+
* optionalEnv an optional setting from the environment (a base URL override)
|
|
10
|
+
* requireProvider a `providers.<adapter>.<key>` value, PLAN_INVALID when missing
|
|
11
|
+
* stringParam/paramError a string param with a default, PARAM_INVALID otherwise
|
|
12
|
+
* desiredSide/diffValue the marker contract (pending / secret / keep) applied to one value's diff
|
|
13
|
+
* assertNoPending apply-time guard that the engine resolved every reference
|
|
14
|
+
* deleteIgnoringNotFound destroy's "already gone is success" rule
|
|
15
|
+
*
|
|
16
|
+
* The HTTP side of the authoring API (ApiClient, Page, Shape, ShapeError, isObject, obj, records, listAll,
|
|
17
|
+
* withQuery, isProviderError) lives in http.ts; packages/adapters/src/index.ts lists the whole API.
|
|
18
|
+
* Anything else in this file is internal and may change.
|
|
19
|
+
*/
|
|
20
|
+
/** A credential from the environment; PROVIDER_AUTH naming the variable when it is unset or blank. */
|
|
21
|
+
export declare function requireEnv(env: NodeJS.ProcessEnv, name: string, adapter: string): string;
|
|
22
|
+
/** An optional setting from the environment (a base URL override); blank counts as unset. Stable authoring API. */
|
|
23
|
+
export declare function optionalEnv(env: NodeJS.ProcessEnv, name: string): string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* A `providers.<adapter>.<key>` string from the plan; PLAN_INVALID when missing. Use it for project and team
|
|
26
|
+
* ids.
|
|
27
|
+
*/
|
|
28
|
+
export declare function requireProvider(actx: AdapterContext, key: string, adapter: string): string;
|
|
29
|
+
/** A `providers.<adapter>.<key>` string from the plan, or undefined. */
|
|
30
|
+
export declare function optionalProvider(actx: AdapterContext, key: string): string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* The HTTP client for an adapter call: the context's environment sets the policy and its redactor masks error text.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* // inside an op's read():
|
|
37
|
+
* const token = requireEnv(actx.env, "ACME_TOKEN", "acme");
|
|
38
|
+
* const api = clientFor(actx, "acme", { baseUrl: "https://api.acme.dev", token });
|
|
39
|
+
* // Retries, timeouts and classification happen inside: a 404 throws PROVIDER_NOT_FOUND, and so on.
|
|
40
|
+
* const site = await api.get(`/sites/${stringParam(params, "name", "acme")}`);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function clientFor(actx: AdapterContext, adapter: string, opts: Pick<ApiClientOptions, "baseUrl" | "token" | "authHeader" | "headers" | "encoding" | "contentType" | "accept" | "signer">): ApiClient;
|
|
44
|
+
/**
|
|
45
|
+
* The PARAM_INVALID error for a bad param, prefixed with the adapter name. Throw it from `diff`/`apply`
|
|
46
|
+
* validation.
|
|
47
|
+
*/
|
|
48
|
+
export declare function paramError(adapter: string, message: string, param: string): SponsonError;
|
|
49
|
+
/** The engine never passes a pending marker into apply; if one arrives, something upstream is wrong. */
|
|
50
|
+
export declare function assertNoPending(params: ResolvedParams, adapter: string): void;
|
|
51
|
+
export declare const ABSENT: DiffSide;
|
|
52
|
+
export declare const SENSITIVE: DiffSide;
|
|
53
|
+
/** A desired value as a diff side: pending markers name their reference (secret refs are URLs: `env://X`). */
|
|
54
|
+
export declare function desiredSide(v: unknown, sensitive: boolean): DiffSide;
|
|
55
|
+
/**
|
|
56
|
+
* Diff one desired value against the live record by hash. `liveValue` is what `before` shows for a non-sensitive
|
|
57
|
+
* value (the live record carries only a hash). Unchanged diffs carry no sides: there is nothing to show.
|
|
58
|
+
*/
|
|
59
|
+
export declare function diffValue(opts: {
|
|
60
|
+
key: string;
|
|
61
|
+
label: string;
|
|
62
|
+
live: ResourceRecord | undefined;
|
|
63
|
+
desired: unknown;
|
|
64
|
+
sensitive: boolean;
|
|
65
|
+
liveValue?: string;
|
|
66
|
+
}): ResourceDiff;
|
|
67
|
+
/**
|
|
68
|
+
* A string param, or `fallback` when absent or empty; PARAM_INVALID when missing without a fallback or not a
|
|
69
|
+
* string.
|
|
70
|
+
*/
|
|
71
|
+
export declare function stringParam(params: ResolvedParams, name: string, adapter: string, fallback?: string): string;
|
|
72
|
+
/** DELETE that treats 404 as success: the contract says a resource that is already gone is not an error. */
|
|
73
|
+
export declare function deleteIgnoringNotFound(api: ApiClient, path: string): Promise<void>;
|
package/dist/common.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { SponsonError, markerKind, pendingRef, sha256 } from "@sponson/core";
|
|
2
|
+
import { apiClient, isProviderError } from "./http.js";
|
|
3
|
+
/**
|
|
4
|
+
* The adapter authoring API. These helpers are stable and exported from `@sponson/adapters`; third-party
|
|
5
|
+
* adapters should use them rather than re-implementing the contracts they encode:
|
|
6
|
+
*
|
|
7
|
+
* clientFor HTTP client with retry policy and redaction from the adapter context
|
|
8
|
+
* requireEnv a credential from the environment, PROVIDER_AUTH when missing
|
|
9
|
+
* optionalEnv an optional setting from the environment (a base URL override)
|
|
10
|
+
* requireProvider a `providers.<adapter>.<key>` value, PLAN_INVALID when missing
|
|
11
|
+
* stringParam/paramError a string param with a default, PARAM_INVALID otherwise
|
|
12
|
+
* desiredSide/diffValue the marker contract (pending / secret / keep) applied to one value's diff
|
|
13
|
+
* assertNoPending apply-time guard that the engine resolved every reference
|
|
14
|
+
* deleteIgnoringNotFound destroy's "already gone is success" rule
|
|
15
|
+
*
|
|
16
|
+
* The HTTP side of the authoring API (ApiClient, Page, Shape, ShapeError, isObject, obj, records, listAll,
|
|
17
|
+
* withQuery, isProviderError) lives in http.ts; packages/adapters/src/index.ts lists the whole API.
|
|
18
|
+
* Anything else in this file is internal and may change.
|
|
19
|
+
*/
|
|
20
|
+
/** A credential from the environment; PROVIDER_AUTH naming the variable when it is unset or blank. */
|
|
21
|
+
export function requireEnv(env, name, adapter) {
|
|
22
|
+
const v = env[name];
|
|
23
|
+
if (!v)
|
|
24
|
+
throw new SponsonError("PROVIDER_AUTH", `${adapter}: environment variable ${name} is not set`, { adapter, variable: name });
|
|
25
|
+
return v;
|
|
26
|
+
}
|
|
27
|
+
/** An optional setting from the environment (a base URL override); blank counts as unset. Stable authoring API. */
|
|
28
|
+
export function optionalEnv(env, name) {
|
|
29
|
+
const v = env[name];
|
|
30
|
+
return v === undefined || v === "" ? undefined : v;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A `providers.<adapter>.<key>` string from the plan; PLAN_INVALID when missing. Use it for project and team
|
|
34
|
+
* ids.
|
|
35
|
+
*/
|
|
36
|
+
export function requireProvider(actx, key, adapter) {
|
|
37
|
+
const v = actx.provider[key];
|
|
38
|
+
if (typeof v !== "string" || v === "")
|
|
39
|
+
throw new SponsonError("PLAN_INVALID", `${adapter}: providers.${adapter}.${key} is required in the plan`, { adapter, key });
|
|
40
|
+
return v;
|
|
41
|
+
}
|
|
42
|
+
/** A `providers.<adapter>.<key>` string from the plan, or undefined. */
|
|
43
|
+
export function optionalProvider(actx, key) {
|
|
44
|
+
const v = actx.provider[key];
|
|
45
|
+
return typeof v === "string" && v !== "" ? v : undefined;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The HTTP client for an adapter call: the context's environment sets the policy and its redactor masks error text.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* // inside an op's read():
|
|
53
|
+
* const token = requireEnv(actx.env, "ACME_TOKEN", "acme");
|
|
54
|
+
* const api = clientFor(actx, "acme", { baseUrl: "https://api.acme.dev", token });
|
|
55
|
+
* // Retries, timeouts and classification happen inside: a 404 throws PROVIDER_NOT_FOUND, and so on.
|
|
56
|
+
* const site = await api.get(`/sites/${stringParam(params, "name", "acme")}`);
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function clientFor(actx, adapter, opts) {
|
|
60
|
+
return apiClient({ adapter, ...opts, redact: actx.redact, env: actx.env });
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The PARAM_INVALID error for a bad param, prefixed with the adapter name. Throw it from `diff`/`apply`
|
|
64
|
+
* validation.
|
|
65
|
+
*/
|
|
66
|
+
export function paramError(adapter, message, param) {
|
|
67
|
+
return new SponsonError("PARAM_INVALID", `${adapter}: ${message}`, { adapter, param });
|
|
68
|
+
}
|
|
69
|
+
/** The engine never passes a pending marker into apply; if one arrives, something upstream is wrong. */
|
|
70
|
+
export function assertNoPending(params, adapter) {
|
|
71
|
+
const walk = (v, path) => {
|
|
72
|
+
const marker = markerKind(v);
|
|
73
|
+
if (marker === "pending" || marker === "secret")
|
|
74
|
+
throw new SponsonError("INTERNAL", `${adapter}: param ${path} is still pending (${pendingRef(v)}); apply must not be called before its inputs resolve`, { adapter, param: path });
|
|
75
|
+
if (Array.isArray(v))
|
|
76
|
+
v.forEach((x, i) => walk(x, `${path}[${i}]`));
|
|
77
|
+
else if (v && typeof v === "object")
|
|
78
|
+
for (const [k, x] of Object.entries(v))
|
|
79
|
+
walk(x, path ? `${path}.${k}` : k);
|
|
80
|
+
};
|
|
81
|
+
walk(params, "");
|
|
82
|
+
}
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Diff sides: data only. Renderers turn them into text.
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
export const ABSENT = { state: "absent" };
|
|
87
|
+
export const SENSITIVE = { state: "sensitive" };
|
|
88
|
+
/** A desired value as a diff side: pending markers name their reference (secret refs are URLs: `env://X`). */
|
|
89
|
+
export function desiredSide(v, sensitive) {
|
|
90
|
+
const marker = markerKind(v);
|
|
91
|
+
if (marker === "pending" || marker === "secret")
|
|
92
|
+
return { state: marker, ref: pendingRef(v) };
|
|
93
|
+
return sensitive ? SENSITIVE : { state: "literal", value: String(v) };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Diff one desired value against the live record by hash. `liveValue` is what `before` shows for a non-sensitive
|
|
97
|
+
* value (the live record carries only a hash). Unchanged diffs carry no sides: there is nothing to show.
|
|
98
|
+
*/
|
|
99
|
+
export function diffValue(opts) {
|
|
100
|
+
const { key, label, live, desired, sensitive } = opts;
|
|
101
|
+
const marker = markerKind(desired);
|
|
102
|
+
if (marker === "keep") {
|
|
103
|
+
if (live)
|
|
104
|
+
return { key, kind: "unchanged", label };
|
|
105
|
+
throw new SponsonError("PARAM_INVALID", `${label} is declared \`{ keep: true }\` but does not exist, so there is no value to keep. Give it a value or remove it.`, { key });
|
|
106
|
+
}
|
|
107
|
+
const after = desiredSide(desired, sensitive);
|
|
108
|
+
if (!live)
|
|
109
|
+
return { key, kind: "create", label, before: ABSENT, after };
|
|
110
|
+
const before = sensitive || opts.liveValue === undefined ? SENSITIVE : { state: "literal", value: opts.liveValue };
|
|
111
|
+
if (marker === null && live.hash === sha256(String(desired)))
|
|
112
|
+
return { key, kind: "unchanged", label };
|
|
113
|
+
return { key, kind: "update", label, before, after };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* A string param, or `fallback` when absent or empty; PARAM_INVALID when missing without a fallback or not a
|
|
117
|
+
* string.
|
|
118
|
+
*/
|
|
119
|
+
export function stringParam(params, name, adapter, fallback) {
|
|
120
|
+
const v = params[name];
|
|
121
|
+
if (v === undefined || v === null || v === "") {
|
|
122
|
+
if (fallback !== undefined)
|
|
123
|
+
return fallback;
|
|
124
|
+
throw paramError(adapter, `param \`${name}\` is required`, name);
|
|
125
|
+
}
|
|
126
|
+
if (typeof v !== "string")
|
|
127
|
+
throw paramError(adapter, `param \`${name}\` must be a string`, name);
|
|
128
|
+
return v;
|
|
129
|
+
}
|
|
130
|
+
/** DELETE that treats 404 as success: the contract says a resource that is already gone is not an error. */
|
|
131
|
+
export async function deleteIgnoringNotFound(api, path) {
|
|
132
|
+
try {
|
|
133
|
+
await api.delete(path);
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
if (!isProviderError(e, "PROVIDER_NOT_FOUND"))
|
|
137
|
+
throw e;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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"}
|
package/dist/digest.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** The hash algorithms supported, as a challenge names them. */
|
|
2
|
+
export type DigestAlgorithm = "MD5" | "MD5-sess" | "SHA-256" | "SHA-256-sess";
|
|
3
|
+
/** One `Digest` challenge of a `WWW-Authenticate` header. */
|
|
4
|
+
export interface DigestChallenge {
|
|
5
|
+
realm: string;
|
|
6
|
+
nonce: string;
|
|
7
|
+
opaque?: string;
|
|
8
|
+
algorithm: DigestAlgorithm;
|
|
9
|
+
/** The `qop` values the server offers. */
|
|
10
|
+
qop: string[];
|
|
11
|
+
/** The previous nonce was merely stale: retry with the new one, the credentials were fine. */
|
|
12
|
+
stale: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** One auth scheme and its parameters, as written in a `WWW-Authenticate` header. */
|
|
15
|
+
interface RawChallenge {
|
|
16
|
+
scheme: string;
|
|
17
|
+
params: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
/** Every challenge in a `WWW-Authenticate` value (several headers arrive joined with `, `). */
|
|
20
|
+
export declare function parseChallenges(header: string): RawChallenge[];
|
|
21
|
+
/**
|
|
22
|
+
* The challenge to answer: a Digest one offering `qop=auth`, SHA-256 preferred over MD5. A reason when there is
|
|
23
|
+
* none Sponson can answer.
|
|
24
|
+
*/
|
|
25
|
+
export declare function pickChallenge(header: string | null): DigestChallenge | {
|
|
26
|
+
problem: string;
|
|
27
|
+
};
|
|
28
|
+
/** What an answer is computed from. `nc` counts the requests made with this nonce (1, 2, …). */
|
|
29
|
+
export interface DigestInput {
|
|
30
|
+
challenge: DigestChallenge;
|
|
31
|
+
username: string;
|
|
32
|
+
password: string;
|
|
33
|
+
method: string;
|
|
34
|
+
/** The request target as sent: path and query. */
|
|
35
|
+
uri: string;
|
|
36
|
+
nc: number;
|
|
37
|
+
/** The client nonce; random when absent. */
|
|
38
|
+
cnonce?: string;
|
|
39
|
+
}
|
|
40
|
+
/** The `response` value of RFC 7616 §3.4.1 for `qop=auth`. */
|
|
41
|
+
export declare function digestResponse(input: DigestInput & {
|
|
42
|
+
cnonce: string;
|
|
43
|
+
}): string;
|
|
44
|
+
/** The `Authorization` header value answering `challenge`. */
|
|
45
|
+
export declare function digestAuthorization(input: DigestInput): string;
|
|
46
|
+
export {};
|