@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,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LaunchDarkly adapter: op `flag_target` serves one variation of a feature flag to one individual target (a context
|
|
3
|
+
* key of a context kind, such as a preview URL or `pr-42`) in one environment, and removes exactly that target on
|
|
4
|
+
* destroy. Writes are LaunchDarkly semantic patches (`addTargets` / `removeTargets`); the API assumptions are
|
|
5
|
+
* numbered LD1… at the top of packages/sim/src/routes/launchdarkly.ts and checked in docs/api-verification.md.
|
|
6
|
+
*/
|
|
7
|
+
import { SponsonError, canonicalJson, markerKind, sha256 } from "@sponson/core";
|
|
8
|
+
import { assertNoPending, clientFor, desiredSide, optionalEnv, paramError, requireEnv, requireProvider, stringParam } from "./common.js";
|
|
9
|
+
import { ShapeError, isObject, isProviderError, obj, records } from "./http.js";
|
|
10
|
+
const ADAPTER = "launchdarkly";
|
|
11
|
+
/** The environment LaunchDarkly reads; declared once, used by the code below and by the generated docs (`about`). */
|
|
12
|
+
const ABOUT = { credentialEnv: "LAUNCHDARKLY_ACCESS_TOKEN", baseUrlEnv: "LAUNCHDARKLY_API_URL", title: "LaunchDarkly", category: "flags", detect: { deps: ["@launchdarkly/", "launchdarkly-node-server-sdk", "launchdarkly-js-client-sdk", "launchdarkly-react-client-sdk"], env: ["LAUNCHDARKLY_*"] } };
|
|
13
|
+
/** LaunchDarkly's REST API base URL (LD1). `LAUNCHDARKLY_API_URL` overrides it: the sim, or a federal or EU instance. */
|
|
14
|
+
export const LAUNCHDARKLY_DEFAULT_API_URL = "https://app.launchdarkly.com/api/v2";
|
|
15
|
+
/** The media type that makes a PATCH body a semantic patch rather than a JSON patch (LD4). */
|
|
16
|
+
const SEMANTIC_PATCH = "application/json; domain-model=launchdarkly.semanticpatch";
|
|
17
|
+
/** A concurrent change answers 409, to be retried (LD6); the instructions are idempotent, so they are re-sent. */
|
|
18
|
+
const CONFLICT_ATTEMPTS = 3;
|
|
19
|
+
/** The context kind of a target when the line does not name one, as in LaunchDarkly itself (LD5). */
|
|
20
|
+
const DEFAULT_CONTEXT_KIND = "user";
|
|
21
|
+
function api(actx) {
|
|
22
|
+
const token = requireEnv(actx.env, ABOUT.credentialEnv, ADAPTER);
|
|
23
|
+
// LD1: the token is the whole Authorization value, no `Bearer`.
|
|
24
|
+
return clientFor(actx, ADAPTER, { baseUrl: optionalEnv(actx.env, ABOUT.baseUrlEnv) ?? LAUNCHDARKLY_DEFAULT_API_URL, token, authHeader: "header:authorization" });
|
|
25
|
+
}
|
|
26
|
+
function targetOf(actx, params) {
|
|
27
|
+
return {
|
|
28
|
+
project: requireProvider(actx, "project", ADAPTER),
|
|
29
|
+
environment: requireProvider(actx, "environment", ADAPTER),
|
|
30
|
+
flag: stringParam(params, "flag", ADAPTER),
|
|
31
|
+
contextKind: stringParam(params, "context_kind", ADAPTER, DEFAULT_CONTEXT_KIND),
|
|
32
|
+
key: stringParam(params, "key", ADAPTER),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const KEY_PREFIX = "target:";
|
|
36
|
+
/**
|
|
37
|
+
* `target:<flag>:<contextKind>:<key>`. The project and environment are not repeated: they are the provider block
|
|
38
|
+
* (`providers.launchdarkly`), which the ledger already keys every resource by, and `diff` (which must name the key
|
|
39
|
+
* of a target that does not exist yet) only sees the line's params. LaunchDarkly flag keys and context kinds never
|
|
40
|
+
* contain `:`, so the context key (a URL may) is everything after the second separator.
|
|
41
|
+
*/
|
|
42
|
+
function resourceKey(t) {
|
|
43
|
+
return `${KEY_PREFIX}${t.flag}:${t.contextKind}:${t.key}`;
|
|
44
|
+
}
|
|
45
|
+
function parseKey(key) {
|
|
46
|
+
if (!key.startsWith(KEY_PREFIX))
|
|
47
|
+
return null;
|
|
48
|
+
const [flag, contextKind, ...rest] = key.slice(KEY_PREFIX.length).split(":");
|
|
49
|
+
if (!flag || !contextKind || rest.length === 0)
|
|
50
|
+
return null;
|
|
51
|
+
return { flag, contextKind, key: rest.join(":") };
|
|
52
|
+
}
|
|
53
|
+
function flagPath(t) {
|
|
54
|
+
return `/flags/${encodeURIComponent(t.project)}/${encodeURIComponent(t.flag)}`;
|
|
55
|
+
}
|
|
56
|
+
function targetId(contextKind, key) {
|
|
57
|
+
return `${contextKind}\u0000${key}`;
|
|
58
|
+
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Reading a flag (LD2, LD3)
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
function parseVariations(v) {
|
|
63
|
+
return records(v, "`variations`", ["_id"]).map((x) => ({ _id: x._id, value: x.value, ...(typeof x.name === "string" ? { name: x.name } : {}) }));
|
|
64
|
+
}
|
|
65
|
+
/** `targets` and `contextTargets` of one environment, merged; empty placeholder entries carry nothing (LD3). */
|
|
66
|
+
function parseTargets(env, variations) {
|
|
67
|
+
const out = new Map();
|
|
68
|
+
for (const field of ["targets", "contextTargets"]) {
|
|
69
|
+
const list = env[field] ?? [];
|
|
70
|
+
if (!Array.isArray(list))
|
|
71
|
+
throw new ShapeError(`expected \`${field}\` to be an array`);
|
|
72
|
+
list.forEach((item, i) => {
|
|
73
|
+
const t = obj(item, `${field}[${i}]`);
|
|
74
|
+
const kind = typeof t.contextKind === "string" && t.contextKind !== "" ? t.contextKind : DEFAULT_CONTEXT_KIND;
|
|
75
|
+
if (!Array.isArray(t.values) || t.values.some((v) => typeof v !== "string"))
|
|
76
|
+
throw new ShapeError(`expected ${field}[${i}].values to be a list of strings`);
|
|
77
|
+
if (typeof t.variation !== "number" || !Number.isInteger(t.variation) || t.variation < 0 || t.variation >= variations)
|
|
78
|
+
throw new ShapeError(`expected ${field}[${i}].variation to index \`variations\``);
|
|
79
|
+
for (const key of t.values)
|
|
80
|
+
out.set(targetId(kind, key), t.variation);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
/** The flag with `environment`'s targets; an environment the answer lacks is not found (LD2). */
|
|
86
|
+
function flagShape(environment, flagKey) {
|
|
87
|
+
return (body) => {
|
|
88
|
+
const b = obj(body, "the flag");
|
|
89
|
+
const variations = parseVariations(b.variations);
|
|
90
|
+
const envs = obj(b.environments ?? {}, "`environments`");
|
|
91
|
+
const env = envs[environment];
|
|
92
|
+
if (env === undefined)
|
|
93
|
+
return { missingEnvironment: true };
|
|
94
|
+
if (!isObject(env))
|
|
95
|
+
throw new ShapeError(`expected environments.${environment} of flag ${flagKey} to be an object`);
|
|
96
|
+
return { variations, targets: parseTargets(env, variations.length) };
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function checkFlag(t, f) {
|
|
100
|
+
if ("missingEnvironment" in f)
|
|
101
|
+
throw new SponsonError("PROVIDER_NOT_FOUND", `${ADAPTER}: flag ${t.flag} in project ${t.project} has no environment ${t.environment}`, { adapter: ADAPTER, environment: t.environment });
|
|
102
|
+
return f;
|
|
103
|
+
}
|
|
104
|
+
async function loadFlag(client, t) {
|
|
105
|
+
return checkFlag(t, await client.get(`${flagPath(t)}?env=${encodeURIComponent(t.environment)}`, flagShape(t.environment, t.flag)));
|
|
106
|
+
}
|
|
107
|
+
function currentVariation(f, t) {
|
|
108
|
+
const i = f.targets.get(targetId(t.contextKind, t.key));
|
|
109
|
+
return i === undefined ? undefined : f.variations[i];
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Choosing a variation
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
/**
|
|
115
|
+
* Does `v` answer to the plan's `variation`? A string matches a variation's name; any value matches a variation
|
|
116
|
+
* whose value is equal (a string also matches the JSON spelling of a non-string value: `"true"`, `"42"`).
|
|
117
|
+
*/
|
|
118
|
+
function matches(v, wanted) {
|
|
119
|
+
if (typeof wanted === "string" && (v.name === wanted || (typeof v.value !== "string" && canonicalJson(v.value) === wanted)))
|
|
120
|
+
return true;
|
|
121
|
+
return canonicalJson(v.value) === canonicalJson(wanted);
|
|
122
|
+
}
|
|
123
|
+
function resolveVariation(f, t, wanted) {
|
|
124
|
+
const found = f.variations.filter((v) => matches(v, wanted));
|
|
125
|
+
if (found.length === 1)
|
|
126
|
+
return found[0];
|
|
127
|
+
const known = f.variations.map(describe).join(", ");
|
|
128
|
+
const why = found.length === 0 ? "has no variation" : "has several variations matching";
|
|
129
|
+
throw paramError(ADAPTER, `flag ${t.flag} ${why} ${canonicalJson(wanted)} (variations: ${known})`, "variation");
|
|
130
|
+
}
|
|
131
|
+
function describe(v) {
|
|
132
|
+
const value = canonicalJson(v.value);
|
|
133
|
+
return v.name ? `${v.name} (${value})` : value;
|
|
134
|
+
}
|
|
135
|
+
/** What the plan asks for; `true` when absent (turn a boolean flag on for the target). */
|
|
136
|
+
function wantedVariation(params) {
|
|
137
|
+
return params.variation ?? true;
|
|
138
|
+
}
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// Records and outputs
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
/**
|
|
143
|
+
* The hash covers the one field the plan controls: which variation the target is served, by its stable `_id`. The
|
|
144
|
+
* id is the target itself (not the variation), so a target moved to another variation is `changed` drift rather
|
|
145
|
+
* than "replaced".
|
|
146
|
+
*/
|
|
147
|
+
function record(t, v) {
|
|
148
|
+
return { key: resourceKey(t), id: `${t.contextKind}:${t.key}`, hash: sha256(canonicalJson({ variation: v._id })), label: `LaunchDarkly ${t.flag} → ${t.contextKind} ${t.key}` };
|
|
149
|
+
}
|
|
150
|
+
function outputsOf(v) {
|
|
151
|
+
return { variation_id: v._id, variation_name: v.name ?? "", variation_value: canonicalJson(v.value) };
|
|
152
|
+
}
|
|
153
|
+
function stateOf(t, v) {
|
|
154
|
+
return { resources: [record(t, v)], outputs: outputsOf(v) };
|
|
155
|
+
}
|
|
156
|
+
function instruction(kind, t, v) {
|
|
157
|
+
return { kind, contextKind: t.contextKind, values: [t.key], variationId: v._id };
|
|
158
|
+
}
|
|
159
|
+
/** One semantic patch. A 405 means the environment needs an approval request, which Sponson does not open (LD6). */
|
|
160
|
+
async function patch(actx, client, t, instructions) {
|
|
161
|
+
const body = { environmentKey: t.environment, instructions, comment: `sponson ${actx.ctx.scope}` };
|
|
162
|
+
try {
|
|
163
|
+
// Add and remove are set operations, so sending them twice is harmless (LD5): retried like a GET.
|
|
164
|
+
return checkFlag(t, await client.patch(flagPath(t), body, flagShape(t.environment, t.flag), { idempotent: true, contentType: SEMANTIC_PATCH }));
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
if (isProviderError(e) && e.details.status === 405) {
|
|
168
|
+
throw new SponsonError("PROVIDER_INVALID", `${ADAPTER}: environment ${t.environment} requires approval for changes to flag ${t.flag}; Sponson does not open approval requests. Use an environment without required approvals for previews.`, { ...e.details });
|
|
169
|
+
}
|
|
170
|
+
throw e;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/** Run `step` again when LaunchDarkly reports a concurrent change (409, LD6); each step re-reads the flag. */
|
|
174
|
+
async function retryingConflicts(step) {
|
|
175
|
+
for (let attempt = 1;; attempt++) {
|
|
176
|
+
try {
|
|
177
|
+
return await step();
|
|
178
|
+
}
|
|
179
|
+
catch (e) {
|
|
180
|
+
if (!isProviderError(e, "PROVIDER_CONFLICT") || attempt >= CONFLICT_ATTEMPTS)
|
|
181
|
+
throw e;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function confirm(t, after, desired) {
|
|
186
|
+
const now = currentVariation(after, t);
|
|
187
|
+
if ((desired === null && now === undefined) || (desired !== null && now?._id === desired._id))
|
|
188
|
+
return;
|
|
189
|
+
throw new SponsonError("PROVIDER_RESPONSE", `${ADAPTER}: PATCH ${flagPath(t)} succeeded but ${t.contextKind} ${t.key} is ${now ? `served ${describe(now)}` : "not targeted"} afterwards`, { adapter: ADAPTER });
|
|
190
|
+
}
|
|
191
|
+
// ---------------------------------------------------------------------------
|
|
192
|
+
// The op
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
function pending(params) {
|
|
195
|
+
return ["flag", "key", "context_kind"].some((p) => markerKind(params[p]) !== null);
|
|
196
|
+
}
|
|
197
|
+
function diffTarget(live, params) {
|
|
198
|
+
const t = { flag: part(params.flag), contextKind: part(params.context_kind) || DEFAULT_CONTEXT_KIND, key: part(params.key) };
|
|
199
|
+
const key = resourceKey(t);
|
|
200
|
+
const current = live?.resources.find((r) => r.key === key);
|
|
201
|
+
const wanted = wantedVariation(params);
|
|
202
|
+
const label = `LaunchDarkly ${t.flag} → ${t.contextKind} ${t.key}`;
|
|
203
|
+
const marker = markerKind(wanted);
|
|
204
|
+
if (marker === "keep") {
|
|
205
|
+
if (current)
|
|
206
|
+
return { key, kind: "unchanged", label };
|
|
207
|
+
throw paramError(ADAPTER, `${label} is declared \`variation: { keep: true }\` but is not targeted, so there is no variation to keep`, "variation");
|
|
208
|
+
}
|
|
209
|
+
const after = marker === null ? { state: "literal", value: canonicalJson(wanted) } : desiredSide(wanted, false);
|
|
210
|
+
if (!current || !live)
|
|
211
|
+
return { key, kind: "create", label, before: { state: "absent" }, after };
|
|
212
|
+
const liveVariation = { name: String(live.outputs.variation_name ?? "") || undefined, value: JSON.parse(String(live.outputs.variation_value)) };
|
|
213
|
+
if (marker === null && matches(liveVariation, wanted))
|
|
214
|
+
return { key, kind: "unchanged", label };
|
|
215
|
+
return { key, kind: "update", label, before: { state: "literal", value: describe(liveVariation) }, after };
|
|
216
|
+
}
|
|
217
|
+
function part(v) {
|
|
218
|
+
if (v === undefined || v === null || v === "")
|
|
219
|
+
return "";
|
|
220
|
+
return markerKind(v) !== null ? "(pending)" : String(v);
|
|
221
|
+
}
|
|
222
|
+
/** A LaunchDarkly environment key that names a production environment unless the block says otherwise. */
|
|
223
|
+
const PRODUCTION_KEY = /prod/i;
|
|
224
|
+
/**
|
|
225
|
+
* Whether the block's environment is production, for Sponson's approval gate: `production: true|false` when the block
|
|
226
|
+
* says, else whether the environment key looks like one (`production`, `prod`, `prod-eu`). A key that only looks like
|
|
227
|
+
* one (`preprod`) opts out with `production: false`. Only `providers.launchdarkly` decides; LaunchDarkly's own
|
|
228
|
+
* "critical environment" setting is not read, since the gate runs before any provider call.
|
|
229
|
+
*/
|
|
230
|
+
function writesEnvironment(_params, _ctx, provider = {}) {
|
|
231
|
+
const declared = provider.production;
|
|
232
|
+
if (declared !== undefined && typeof declared !== "boolean") {
|
|
233
|
+
throw new SponsonError("PLAN_INVALID", `${ADAPTER}: providers.launchdarkly.production must be true or false`, { adapter: ADAPTER, key: "providers.launchdarkly.production" });
|
|
234
|
+
}
|
|
235
|
+
const production = declared ?? (typeof provider.environment === "string" && PRODUCTION_KEY.test(provider.environment));
|
|
236
|
+
return production ? "production" : null;
|
|
237
|
+
}
|
|
238
|
+
const flag_target = {
|
|
239
|
+
outputs: { variation_id: { available: "immediate" }, variation_name: { available: "immediate" }, variation_value: { available: "immediate" } },
|
|
240
|
+
writesEnvironment,
|
|
241
|
+
/** The target key defaults to the scope (`pr-42`); the context kind to `user`; the variation to `true`. */
|
|
242
|
+
defaults(params, ctx) {
|
|
243
|
+
return { key: ctx.scope, context_kind: DEFAULT_CONTEXT_KIND, variation: true, ...params };
|
|
244
|
+
},
|
|
245
|
+
async read(actx, params) {
|
|
246
|
+
// The target key may come from a line not yet applied (a preview URL): nothing to read yet.
|
|
247
|
+
if (pending(params))
|
|
248
|
+
return null;
|
|
249
|
+
const t = targetOf(actx, params);
|
|
250
|
+
const f = await loadFlag(api(actx), t);
|
|
251
|
+
const wanted = wantedVariation(params);
|
|
252
|
+
// An unknown or ambiguous variation is a plan error, reported at plan time.
|
|
253
|
+
if (markerKind(wanted) === null)
|
|
254
|
+
resolveVariation(f, t, wanted);
|
|
255
|
+
const v = currentVariation(f, t);
|
|
256
|
+
return v ? stateOf(t, v) : null;
|
|
257
|
+
},
|
|
258
|
+
diff(live, params) {
|
|
259
|
+
return [diffTarget(live, params)];
|
|
260
|
+
},
|
|
261
|
+
async apply(actx, params) {
|
|
262
|
+
assertNoPending(params, ADAPTER);
|
|
263
|
+
const t = targetOf(actx, params);
|
|
264
|
+
const client = api(actx);
|
|
265
|
+
const wanted = wantedVariation(params);
|
|
266
|
+
return retryingConflicts(async () => {
|
|
267
|
+
// Always from a fresh read: `live` may be stale, and a target can only be in one variation at a time.
|
|
268
|
+
const f = await loadFlag(client, t);
|
|
269
|
+
const current = currentVariation(f, t);
|
|
270
|
+
const desired = markerKind(wanted) === "keep" ? current : resolveVariation(f, t, wanted);
|
|
271
|
+
if (!desired)
|
|
272
|
+
throw paramError(ADAPTER, `${t.contextKind} ${t.key} is declared \`variation: { keep: true }\` but flag ${t.flag} does not target it`, "variation");
|
|
273
|
+
if (current?._id === desired._id)
|
|
274
|
+
return { ...stateOf(t, current), created: [] };
|
|
275
|
+
const instructions = current ? [instruction("removeTargets", t, current), instruction("addTargets", t, desired)] : [instruction("addTargets", t, desired)];
|
|
276
|
+
// Announce the create before sending it: a crash or a lost response must not orphan the target.
|
|
277
|
+
if (!current)
|
|
278
|
+
await actx.intend([resourceKey(t)]);
|
|
279
|
+
actx.log(`${current ? "move" : "target"} ${t.contextKind} ${t.key} → ${describe(desired)} on ${t.flag}`);
|
|
280
|
+
confirm(t, await patch(actx, client, t, instructions), desired);
|
|
281
|
+
return { ...stateOf(t, desired), created: current ? [] : [resourceKey(t)] };
|
|
282
|
+
});
|
|
283
|
+
},
|
|
284
|
+
/** Removes exactly the recorded target, from whichever variation serves it now; a gone flag or target is success. */
|
|
285
|
+
async destroy(actx, resources) {
|
|
286
|
+
const client = api(actx);
|
|
287
|
+
for (const r of resources) {
|
|
288
|
+
const parsed = parseKey(r.key);
|
|
289
|
+
if (!parsed)
|
|
290
|
+
throw new SponsonError("INTERNAL", `${ADAPTER}: cannot destroy ${r.key}: not a flag_target key`, { adapter: ADAPTER, key: r.key });
|
|
291
|
+
const t = { project: requireProvider(actx, "project", ADAPTER), environment: requireProvider(actx, "environment", ADAPTER), ...parsed };
|
|
292
|
+
await retryingConflicts(async () => {
|
|
293
|
+
let f;
|
|
294
|
+
try {
|
|
295
|
+
f = await loadFlag(client, t);
|
|
296
|
+
}
|
|
297
|
+
catch (e) {
|
|
298
|
+
if (isProviderError(e, "PROVIDER_NOT_FOUND"))
|
|
299
|
+
return;
|
|
300
|
+
throw e;
|
|
301
|
+
}
|
|
302
|
+
const current = currentVariation(f, t);
|
|
303
|
+
if (!current)
|
|
304
|
+
return;
|
|
305
|
+
actx.log(`untarget ${t.contextKind} ${t.key} on ${t.flag}`);
|
|
306
|
+
confirm(t, await patch(actx, client, t, [instruction("removeTargets", t, current)]), null);
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
/** Every individual target of the line's flag in the environment, for drift (`unmanaged`) and `sponson init`. */
|
|
311
|
+
async listScope(actx, params) {
|
|
312
|
+
if (markerKind(params.flag) !== null)
|
|
313
|
+
return [];
|
|
314
|
+
const base = targetOf(actx, { ...params, key: "-" });
|
|
315
|
+
const f = await loadFlag(api(actx), base);
|
|
316
|
+
return [...f.targets].map(([id, i]) => {
|
|
317
|
+
const [contextKind, key] = id.split("\u0000");
|
|
318
|
+
return record({ ...base, contextKind, key }, f.variations[i]);
|
|
319
|
+
});
|
|
320
|
+
},
|
|
321
|
+
/** One line per target; the variation it is served now is kept, not copied. */
|
|
322
|
+
adopt(resources) {
|
|
323
|
+
return resources.flatMap((r) => {
|
|
324
|
+
const t = parseKey(r.key);
|
|
325
|
+
if (!t)
|
|
326
|
+
return [];
|
|
327
|
+
return [{ id: "flag_target", params: { flag: t.flag, key: t.key, context_kind: t.contextKind, variation: { keep: true } }, keys: [r.key] }];
|
|
328
|
+
});
|
|
329
|
+
},
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* The LaunchDarkly adapter (`adapter: launchdarkly` in a plan): op `flag_target` serves a flag variation to one
|
|
333
|
+
* context key (a preview URL, `pr-42`) in one environment. Registered in `createRegistry()`; needs
|
|
334
|
+
* `LAUNCHDARKLY_ACCESS_TOKEN` and `providers.launchdarkly.project` / `.environment`.
|
|
335
|
+
*/
|
|
336
|
+
export const launchdarklyAdapter = { name: ADAPTER, ops: { flag_target }, about: ABOUT };
|
|
337
|
+
//# sourceMappingURL=launchdarkly.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchdarkly.js","sourceRoot":"","sources":["../src/launchdarkly.ts"],"names":[],"mappings":"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"}
|
package/dist/manual.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The built-in `manual` adapter: op `step`, a change a person makes by hand because no API can (a Google OAuth web
|
|
3
|
+
* client's redirect URIs, a Clerk webhook endpoint, a Stripe sandbox). The plan line says what to do; the engine
|
|
4
|
+
* shows it as `todo` until a person confirms it (`apply --confirm <line>`) or its verify request sees it done, and
|
|
5
|
+
* records who confirmed it and when (ADR 0021, `OpSpec.manual`). Nothing is ever sent to a provider except the
|
|
6
|
+
* optional verify GET, made with the generic `http` adapter's client against an API block under `providers.manual`.
|
|
7
|
+
*/
|
|
8
|
+
import { type ResourceAdapter } from "@sponson/core";
|
|
9
|
+
/**
|
|
10
|
+
* The `manual` adapter (`adapter: manual` in a plan): op `step`, a change a person makes by hand, shown as a todo
|
|
11
|
+
* with its instructions until someone confirms it or its verify request sees it done (ADR 0021).
|
|
12
|
+
*/
|
|
13
|
+
export declare const manualAdapter: ResourceAdapter;
|
package/dist/manual.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The built-in `manual` adapter: op `step`, a change a person makes by hand because no API can (a Google OAuth web
|
|
3
|
+
* client's redirect URIs, a Clerk webhook endpoint, a Stripe sandbox). The plan line says what to do; the engine
|
|
4
|
+
* shows it as `todo` until a person confirms it (`apply --confirm <line>`) or its verify request sees it done, and
|
|
5
|
+
* records who confirmed it and when (ADR 0021, `OpSpec.manual`). Nothing is ever sent to a provider except the
|
|
6
|
+
* optional verify GET, made with the generic `http` adapter's client against an API block under `providers.manual`.
|
|
7
|
+
*/
|
|
8
|
+
import { SponsonError, canonicalJson, isFromRef, isKeepRef, isSecretRef, markerKind, sha256, walkParams } from "@sponson/core";
|
|
9
|
+
import { paramError } from "./common.js";
|
|
10
|
+
import { isObject } from "./http.js";
|
|
11
|
+
import { httpClient, failedWith } from "./http-adapter-client.js";
|
|
12
|
+
import { at, fillPath, parseApi, placeholders, pointerTokens } from "./http-adapter-spec.js";
|
|
13
|
+
const ADAPTER = "manual";
|
|
14
|
+
/** Where a verify request's API is configured; declared for the generated docs. Steps without `verify` need nothing. */
|
|
15
|
+
const ABOUT = { credentialEnv: "none (verify: providers.manual.<api>.auth, optional)", baseUrlEnv: "providers.manual.<api>.base_url_env" };
|
|
16
|
+
const PARAMS = ["title", "instructions", "undo", "vars", "verify"];
|
|
17
|
+
const VERIFY_KEYS = ["api", "path", "match", "absent_status"];
|
|
18
|
+
const KEY_PREFIX = "step:";
|
|
19
|
+
function fail(message, param) {
|
|
20
|
+
return paramError(ADAPTER, message, param);
|
|
21
|
+
}
|
|
22
|
+
function textParam(params, name, required) {
|
|
23
|
+
const v = params[name];
|
|
24
|
+
if (v === undefined || v === null) {
|
|
25
|
+
if (required)
|
|
26
|
+
throw fail(`\`${name}\` is required`, name);
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
// Before resolution a `{ from }` stands for text; after it, a pending marker does.
|
|
30
|
+
if (typeof v !== "string" && !isFromRef(v))
|
|
31
|
+
throw fail(`\`${name}\` must be text (Markdown), or a \`{ from }\` reference to text`, name);
|
|
32
|
+
if (typeof v === "string" && markerKind(v) === null && v.trim() === "")
|
|
33
|
+
throw fail(`\`${name}\` must not be blank`, name);
|
|
34
|
+
return v;
|
|
35
|
+
}
|
|
36
|
+
function parseVerify(v) {
|
|
37
|
+
if (v === undefined || v === null)
|
|
38
|
+
return undefined;
|
|
39
|
+
if (!isObject(v))
|
|
40
|
+
throw fail("`verify` must be a map: `{ api, path, match?, absent_status? }`", "verify");
|
|
41
|
+
const extra = Object.keys(v).find((k) => !VERIFY_KEYS.includes(k));
|
|
42
|
+
if (extra)
|
|
43
|
+
throw fail(`\`verify.${extra}\` is not a verify key (known: ${VERIFY_KEYS.join(", ")})`, `verify.${extra}`);
|
|
44
|
+
if (typeof v.api !== "string" || v.api === "")
|
|
45
|
+
throw fail("`verify.api` is required: an API block under `providers.manual`", "verify.api");
|
|
46
|
+
if (typeof v.path !== "string" || !v.path.startsWith("/"))
|
|
47
|
+
throw fail("`verify.path` must be a path starting with \"/\" (relative to the API's base_url)", "verify.path");
|
|
48
|
+
const match = v.match ?? {};
|
|
49
|
+
if (!isObject(match) || Object.keys(match).some((p) => !p.startsWith("/")))
|
|
50
|
+
throw fail("`verify.match` must map JSON pointers (\"/status\") to the values the answer must have", "verify.match");
|
|
51
|
+
const absent = v.absent_status ?? [];
|
|
52
|
+
if (!Array.isArray(absent) || !absent.every((s) => Number.isInteger(s) && s >= 400 && s <= 599))
|
|
53
|
+
throw fail("`verify.absent_status` must be a list of HTTP error statuses (400–599)", "verify.absent_status");
|
|
54
|
+
return { api: v.api, path: v.path, match, absentStatus: absent };
|
|
55
|
+
}
|
|
56
|
+
function varsOf(params) {
|
|
57
|
+
const v = params.vars ?? {};
|
|
58
|
+
if (!isObject(v))
|
|
59
|
+
throw fail("`vars` must be a map of name → value", "vars");
|
|
60
|
+
return v;
|
|
61
|
+
}
|
|
62
|
+
/** Every param checked; refuses unknown params and, before anything resolves them, secret references. */
|
|
63
|
+
function check(params) {
|
|
64
|
+
const extra = Object.keys(params).find((k) => !PARAMS.includes(k));
|
|
65
|
+
if (extra)
|
|
66
|
+
throw fail(`\`${extra}\` is not a parameter of manual.step (known: ${PARAMS.join(", ")})`, extra);
|
|
67
|
+
textParam(params, "title", true);
|
|
68
|
+
textParam(params, "instructions", true);
|
|
69
|
+
textParam(params, "undo", false);
|
|
70
|
+
const vars = varsOf(params);
|
|
71
|
+
const verify = parseVerify(params.verify);
|
|
72
|
+
for (const name of ["title", "instructions", "undo"]) {
|
|
73
|
+
const t = params[name];
|
|
74
|
+
if (typeof t === "string" && markerKind(t) === null)
|
|
75
|
+
usedVars(t, vars, name);
|
|
76
|
+
}
|
|
77
|
+
if (verify)
|
|
78
|
+
usedVars(verify.path, vars, "verify.path");
|
|
79
|
+
}
|
|
80
|
+
/** Placeholders `{name}` of a text must all be declared in `vars`, so a typo fails at plan time. */
|
|
81
|
+
function usedVars(text, vars, param) {
|
|
82
|
+
const unknown = placeholders(text).find((n) => !(n in vars));
|
|
83
|
+
if (unknown)
|
|
84
|
+
throw fail(`\`${param}\` uses \`{${unknown}}\`, which is not declared in \`vars\``, param);
|
|
85
|
+
}
|
|
86
|
+
/** `text` with every `{name}` replaced by its value from `vars`; undefined while a value is pending. */
|
|
87
|
+
function render(text, vars) {
|
|
88
|
+
const pending = placeholders(text).some((n) => markerKind(vars[n]) !== null);
|
|
89
|
+
if (pending)
|
|
90
|
+
return undefined;
|
|
91
|
+
return text.replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_m, n) => {
|
|
92
|
+
const v = vars[n];
|
|
93
|
+
if (typeof v === "object" && v !== null)
|
|
94
|
+
throw fail(`\`vars.${n}\` must be a single value to fill \`{${n}}\``, `vars.${n}`);
|
|
95
|
+
return String(v);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/** A text param rendered; undefined while it (or a value it uses) is still pending. */
|
|
99
|
+
function rendered(params, name, vars) {
|
|
100
|
+
const t = params[name];
|
|
101
|
+
if (t === undefined || markerKind(t) !== null)
|
|
102
|
+
return undefined;
|
|
103
|
+
return render(String(t), vars);
|
|
104
|
+
}
|
|
105
|
+
/** The step as a person sees it, or null while anything it shows is still pending. */
|
|
106
|
+
function stepOf(params) {
|
|
107
|
+
check(params);
|
|
108
|
+
const vars = varsOf(params);
|
|
109
|
+
const title = rendered(params, "title", vars);
|
|
110
|
+
const instructions = rendered(params, "instructions", vars);
|
|
111
|
+
const undo = params.undo === undefined ? undefined : rendered(params, "undo", vars);
|
|
112
|
+
if (title === undefined || instructions === undefined || (params.undo !== undefined && undo === undefined))
|
|
113
|
+
return null;
|
|
114
|
+
if (/[\r\n]/.test(title))
|
|
115
|
+
throw fail("`title` must be one line", "title");
|
|
116
|
+
return {
|
|
117
|
+
key: `${KEY_PREFIX}${title}`,
|
|
118
|
+
title,
|
|
119
|
+
instructions,
|
|
120
|
+
...(undo !== undefined ? { undo } : {}),
|
|
121
|
+
hash: sha256(canonicalJson({ title, instructions })),
|
|
122
|
+
observable: params.verify !== undefined && params.verify !== null,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** Whether the verify request sees the step done. A 404 (or an `absent_status`) means not yet. */
|
|
126
|
+
async function verified(actx, verify, vars) {
|
|
127
|
+
const path = fillPath(verify.path, vars);
|
|
128
|
+
if (path === undefined)
|
|
129
|
+
return false;
|
|
130
|
+
const api = httpClient(actx, {}, { where: `providers.manual.${verify.api}`, authOptional: true, adapter: ADAPTER });
|
|
131
|
+
let body;
|
|
132
|
+
try {
|
|
133
|
+
body = await api.get(path);
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
if (failedWith(e, "PROVIDER_NOT_FOUND", verify.absentStatus))
|
|
137
|
+
return false;
|
|
138
|
+
throw e;
|
|
139
|
+
}
|
|
140
|
+
return Object.entries(verify.match).every(([pointer, want]) => canonicalJson(at(body, pointerTokens(pointer)) ?? null) === canonicalJson(want));
|
|
141
|
+
}
|
|
142
|
+
/** `manual.step`: one change a person makes by hand, confirmed by a person or seen by a verify request. */
|
|
143
|
+
const step = {
|
|
144
|
+
outputs: {},
|
|
145
|
+
/**
|
|
146
|
+
* Checked before anything resolves: a secret has no place in instructions a person reads (and `plan` would show
|
|
147
|
+
* them masked), so a `{ secret }` reference is refused here, before any provider call.
|
|
148
|
+
*/
|
|
149
|
+
defaults(params) {
|
|
150
|
+
walkParams(params, [], (path, v) => {
|
|
151
|
+
const where = path.join(".");
|
|
152
|
+
if (isSecretRef(v))
|
|
153
|
+
throw fail(`\`${where}\` is a secret reference; a manual step's text is shown to people and kept in receipts, so it may not carry a secret`, where);
|
|
154
|
+
if (isKeepRef(v))
|
|
155
|
+
throw fail(`\`${where}\` is \`{ keep: true }\`; a manual step has no live value to keep`, where);
|
|
156
|
+
});
|
|
157
|
+
check(params);
|
|
158
|
+
return params;
|
|
159
|
+
},
|
|
160
|
+
/** The verify request's API block, `providers.manual.<verify.api>`; nothing for a step without one. */
|
|
161
|
+
providerFor(block, params) {
|
|
162
|
+
const verify = isObject(params.verify) ? params.verify : undefined;
|
|
163
|
+
if (!verify || typeof verify.api !== "string")
|
|
164
|
+
return {};
|
|
165
|
+
const cfg = block[verify.api];
|
|
166
|
+
if (!isObject(cfg)) {
|
|
167
|
+
const known = Object.keys(block);
|
|
168
|
+
throw new SponsonError("PLAN_INVALID", `${ADAPTER}: providers.manual.${verify.api}: no API \`${verify.api}\` is configured for the verify request (known: ${known.length ? known.join(", ") : "none"})`, { adapter: ADAPTER, key: `providers.manual.${verify.api}` });
|
|
169
|
+
}
|
|
170
|
+
parseApi(cfg, `providers.manual.${verify.api}`, { authOptional: true });
|
|
171
|
+
return cfg;
|
|
172
|
+
},
|
|
173
|
+
manual: (params) => stepOf(params),
|
|
174
|
+
/** Done, as far as an API can tell: only a step with `verify` is ever seen; any other is known done only by confirmation. */
|
|
175
|
+
async read(actx, params) {
|
|
176
|
+
const s = stepOf(params);
|
|
177
|
+
const verify = parseVerify(params.verify);
|
|
178
|
+
if (!s || !verify || !(await verified(actx, verify, varsOf(params))))
|
|
179
|
+
return null;
|
|
180
|
+
return { resources: [{ key: s.key, id: "manual", hash: s.hash, label: `manual step: ${s.title}` }], outputs: {} };
|
|
181
|
+
},
|
|
182
|
+
diff(live, params) {
|
|
183
|
+
const s = stepOf(params);
|
|
184
|
+
if (!s)
|
|
185
|
+
return [{ key: `${KEY_PREFIX}(pending)`, kind: "create", label: "manual step", before: { state: "absent" }, after: { state: "pending" } }];
|
|
186
|
+
const label = `manual step: ${s.title}`;
|
|
187
|
+
return [live ? { key: s.key, kind: "unchanged", label } : { key: s.key, kind: "create", label, before: { state: "absent" }, after: { state: "literal", value: s.title } }];
|
|
188
|
+
},
|
|
189
|
+
/** Never called: the engine records a manual step (OpSpec.manual). */
|
|
190
|
+
async apply() {
|
|
191
|
+
throw new SponsonError("INTERNAL", `${ADAPTER}: a manual step is done by a person and recorded by the engine; apply must not be called`, { adapter: ADAPTER });
|
|
192
|
+
},
|
|
193
|
+
/** Nothing to delete at any provider: undoing a step is a person's job (its `undo`), confirmed on destroy. */
|
|
194
|
+
async destroy() { },
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* The `manual` adapter (`adapter: manual` in a plan): op `step`, a change a person makes by hand, shown as a todo
|
|
198
|
+
* with its instructions until someone confirms it or its verify request sees it done (ADR 0021).
|
|
199
|
+
*/
|
|
200
|
+
export const manualAdapter = { name: ADAPTER, ops: { step }, about: ABOUT };
|
|
201
|
+
//# sourceMappingURL=manual.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual.js","sourceRoot":"","sources":["../src/manual.ts"],"names":[],"mappings":"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"}
|
package/dist/neon.js
CHANGED
|
@@ -2,7 +2,7 @@ import { canonicalJson, isPendingMarker, sha256 } from "@sponson/core";
|
|
|
2
2
|
import { ABSENT, assertNoPending, clientFor, deleteIgnoringNotFound, desiredSide, optionalEnv, paramError, requireEnv, requireProvider, stringParam } from "./common.js";
|
|
3
3
|
import { ShapeError, isProviderError, listAll, obj, records } from "./http.js";
|
|
4
4
|
/** The environment neon reads; declared once, used by the code below and by the generated docs. */
|
|
5
|
-
const ABOUT = { credentialEnv: "NEON_API_KEY", baseUrlEnv: "NEON_API_URL" };
|
|
5
|
+
const ABOUT = { credentialEnv: "NEON_API_KEY", baseUrlEnv: "NEON_API_URL", title: "Neon", category: "databases", detect: { deps: ["@neondatabase/", "@prisma/adapter-neon", "neonctl"], env: ["NEON_*"], files: [".neon"], dbHosts: [".neon.tech"] } };
|
|
6
6
|
/** Neon's API base URL; `NEON_API_URL` overrides it (the sim and tests use that). */
|
|
7
7
|
export const NEON_DEFAULT_API_URL = "https://console.neon.tech/api/v2";
|
|
8
8
|
function client(actx) {
|