@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.
Files changed (132) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +4 -2
  3. package/dist/algolia.d.ts +6 -0
  4. package/dist/algolia.js +151 -0
  5. package/dist/algolia.js.map +1 -0
  6. package/dist/clerk.d.ts +8 -0
  7. package/dist/clerk.js +107 -0
  8. package/dist/clerk.js.map +1 -0
  9. package/dist/cloudflare.d.ts +25 -0
  10. package/dist/cloudflare.js +310 -0
  11. package/dist/cloudflare.js.map +1 -0
  12. package/dist/common.d.ts +73 -0
  13. package/dist/common.js +140 -0
  14. package/dist/common.js.map +1 -0
  15. package/dist/digest.d.ts +46 -0
  16. package/dist/digest.js +129 -0
  17. package/dist/digest.js.map +1 -0
  18. package/dist/digitalocean.d.ts +5 -0
  19. package/dist/digitalocean.js +243 -0
  20. package/dist/digitalocean.js.map +1 -0
  21. package/dist/http-adapter-action.d.ts +63 -0
  22. package/dist/http-adapter-action.js +369 -0
  23. package/dist/http-adapter-action.js.map +1 -0
  24. package/dist/http-adapter-auth.d.ts +88 -0
  25. package/dist/http-adapter-auth.js +437 -0
  26. package/dist/http-adapter-auth.js.map +1 -0
  27. package/dist/http-adapter-client.d.ts +51 -0
  28. package/dist/http-adapter-client.js +156 -0
  29. package/dist/http-adapter-client.js.map +1 -0
  30. package/dist/http-adapter-graphql.d.ts +39 -0
  31. package/dist/http-adapter-graphql.js +157 -0
  32. package/dist/http-adapter-graphql.js.map +1 -0
  33. package/dist/http-adapter-list.d.ts +33 -0
  34. package/dist/http-adapter-list.js +421 -0
  35. package/dist/http-adapter-list.js.map +1 -0
  36. package/dist/http-adapter-resource.d.ts +29 -0
  37. package/dist/http-adapter-resource.js +462 -0
  38. package/dist/http-adapter-resource.js.map +1 -0
  39. package/dist/http-adapter-spec.d.ts +216 -0
  40. package/dist/http-adapter-spec.js +660 -0
  41. package/dist/http-adapter-spec.js.map +1 -0
  42. package/dist/http-adapter.d.ts +16 -0
  43. package/dist/http-adapter.js +28 -0
  44. package/dist/http-adapter.js.map +1 -0
  45. package/dist/http.d.ts +179 -0
  46. package/dist/http.js +352 -0
  47. package/dist/http.js.map +1 -0
  48. package/dist/index.d.ts +28 -0
  49. package/dist/index.js +45 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/launchdarkly.d.ts +15 -0
  52. package/dist/launchdarkly.js +337 -0
  53. package/dist/launchdarkly.js.map +1 -0
  54. package/dist/manual.d.ts +13 -0
  55. package/dist/manual.js +201 -0
  56. package/dist/manual.js.map +1 -0
  57. package/dist/neon.d.ts +8 -0
  58. package/dist/neon.js +167 -0
  59. package/dist/neon.js.map +1 -0
  60. package/dist/netlify.d.ts +18 -0
  61. package/dist/netlify.js +436 -0
  62. package/dist/netlify.js.map +1 -0
  63. package/dist/planetscale.d.ts +10 -0
  64. package/dist/planetscale.js +311 -0
  65. package/dist/planetscale.js.map +1 -0
  66. package/dist/providers.d.ts +26 -0
  67. package/dist/providers.js +36 -0
  68. package/dist/providers.js.map +1 -0
  69. package/dist/recipes.d.ts +167 -0
  70. package/dist/recipes.js +246 -0
  71. package/dist/recipes.js.map +1 -0
  72. package/dist/secrets.d.ts +72 -0
  73. package/dist/secrets.js +476 -0
  74. package/dist/secrets.js.map +1 -0
  75. package/dist/sigv4.d.ts +56 -0
  76. package/dist/sigv4.js +118 -0
  77. package/dist/sigv4.js.map +1 -0
  78. package/dist/supabase.d.ts +9 -0
  79. package/dist/supabase.js +385 -0
  80. package/dist/supabase.js.map +1 -0
  81. package/dist/vercel.d.ts +8 -0
  82. package/dist/vercel.js +475 -0
  83. package/dist/vercel.js.map +1 -0
  84. package/dist/xata.d.ts +8 -0
  85. package/dist/xata.js +142 -0
  86. package/dist/xata.js.map +1 -0
  87. package/dist/xml.d.ts +25 -0
  88. package/dist/xml.js +211 -0
  89. package/dist/xml.js.map +1 -0
  90. package/package.json +58 -3
  91. package/recipes/amplify.yaml +147 -0
  92. package/recipes/auth0.yaml +178 -0
  93. package/recipes/azure_swa.yaml +116 -0
  94. package/recipes/cloud_run.yaml +97 -0
  95. package/recipes/cloudflare.yaml +108 -0
  96. package/recipes/cockroachdb.yaml +132 -0
  97. package/recipes/configcat.yaml +123 -0
  98. package/recipes/datadog.yaml +136 -0
  99. package/recipes/firebase.yaml +84 -0
  100. package/recipes/flagsmith.yaml +98 -0
  101. package/recipes/fly.yaml +97 -0
  102. package/recipes/fly_machines.yaml +67 -0
  103. package/recipes/gcs.yaml +102 -0
  104. package/recipes/github.yaml +123 -0
  105. package/recipes/growthbook.yaml +124 -0
  106. package/recipes/heroku.yaml +98 -0
  107. package/recipes/honeycomb.yaml +89 -0
  108. package/recipes/inngest.yaml +97 -0
  109. package/recipes/kinde.yaml +120 -0
  110. package/recipes/mongodb_atlas.yaml +119 -0
  111. package/recipes/okta.yaml +177 -0
  112. package/recipes/posthog.yaml +127 -0
  113. package/recipes/postmark.yaml +105 -0
  114. package/recipes/postmark_server.yaml +93 -0
  115. package/recipes/prisma.yaml +150 -0
  116. package/recipes/qstash.yaml +134 -0
  117. package/recipes/railway.yaml +130 -0
  118. package/recipes/render.yaml +103 -0
  119. package/recipes/resend.yaml +130 -0
  120. package/recipes/s3.yaml +108 -0
  121. package/recipes/sendgrid.yaml +165 -0
  122. package/recipes/sentry.yaml +158 -0
  123. package/recipes/split.yaml +121 -0
  124. package/recipes/statsig.yaml +124 -0
  125. package/recipes/stripe.yaml +310 -0
  126. package/recipes/stytch.yaml +113 -0
  127. package/recipes/svix.yaml +109 -0
  128. package/recipes/turso.yaml +98 -0
  129. package/recipes/unleash.yaml +149 -0
  130. package/recipes/upstash.yaml +130 -0
  131. package/recipes/vercel.yaml +116 -0
  132. package/recipes/workos.yaml +70 -0
@@ -0,0 +1,311 @@
1
+ /**
2
+ * PlanetScale adapter (Vitess / MySQL databases): a development branch per scope, and a password for it whose
3
+ * plaintext PlanetScale shows only once. The API assumptions this relies on are numbered PS1… at the top of
4
+ * packages/sim/src/routes/planetscale.ts and checked in docs/api-verification.md.
5
+ */
6
+ import { setTimeout as sleep } from "node:timers/promises";
7
+ import { SponsonError, canonicalJson, markerKind, sha256 } from "@sponson/core";
8
+ import { ABSENT, assertNoPending, clientFor, deleteIgnoringNotFound, desiredSide, optionalEnv, paramError, requireEnv, requireProvider, stringParam } from "./common.js";
9
+ import { isProviderError, listAll, obj, records, ShapeError } from "./http.js";
10
+ const ADAPTER = "planetscale";
11
+ /**
12
+ * The environment PlanetScale reads; declared once, used by the code below and by the generated docs. A service
13
+ * token is two values, sent as `Authorization: <id>:<token>` (PS1).
14
+ */
15
+ const ABOUT = { credentialEnv: "PLANETSCALE_SERVICE_TOKEN", extraCredentialEnv: ["PLANETSCALE_SERVICE_TOKEN_ID"], baseUrlEnv: "PLANETSCALE_API_URL", title: "PlanetScale", category: "databases", detect: { deps: ["@planetscale/"], env: ["PLANETSCALE_*"], dbHosts: [".psdb.cloud"] } };
16
+ /** PlanetScale's API base URL; `PLANETSCALE_API_URL` overrides it (the sim and tests use that). */
17
+ export const PLANETSCALE_DEFAULT_API_URL = "https://api.planetscale.com/v1";
18
+ /** How often a new branch is polled until it is ready, and for how long at most; both overridable from the environment. */
19
+ const POLL_MS = { env: "SPONSON_PLANETSCALE_POLL_MS", fallback: 2000 };
20
+ const READY_TIMEOUT_MS = { env: "SPONSON_PLANETSCALE_READY_TIMEOUT_MS", fallback: 10 * 60 * 1000 };
21
+ /** The query a connection string ends with by default: the form PlanetScale documents for Node.js drivers. */
22
+ const DEFAULT_CONNECTION_PARAMS = 'ssl={"rejectUnauthorized":true}';
23
+ function client(actx) {
24
+ const id = requireEnv(actx.env, ABOUT.extraCredentialEnv[0], ADAPTER);
25
+ const secret = requireEnv(actx.env, ABOUT.credentialEnv, ADAPTER);
26
+ const organization = requireProvider(actx, "organization", ADAPTER);
27
+ const database = requireProvider(actx, "database", ADAPTER);
28
+ const api = clientFor(actx, ADAPTER, { baseUrl: optionalEnv(actx.env, ABOUT.baseUrlEnv) ?? PLANETSCALE_DEFAULT_API_URL, token: `${id}:${secret}`, authHeader: "header:authorization" });
29
+ return { api, base: `/organizations/${enc(organization)}/databases/${enc(database)}`, database };
30
+ }
31
+ function enc(s) {
32
+ return encodeURIComponent(s);
33
+ }
34
+ function msFromEnv(env, s) {
35
+ const raw = optionalEnv(env, s.env);
36
+ const n = Number(raw);
37
+ return raw !== undefined && Number.isFinite(n) && n >= 0 ? n : s.fallback;
38
+ }
39
+ /** `sponson-<env>-<scope>`, lowercase letters, digits and dashes only (PS14). */
40
+ function defaultName(ctx) {
41
+ return `sponson-${ctx.env}-${ctx.scope}`
42
+ .toLowerCase()
43
+ .replace(/[^a-z0-9-]+/g, "-")
44
+ .replace(/-{2,}/g, "-")
45
+ .replace(/^-|-$/g, "");
46
+ }
47
+ function parseBranch(v, what) {
48
+ const [b] = records([v], what, ["id", "name"]);
49
+ const parent = b.parent_branch;
50
+ if (parent !== undefined && parent !== null && typeof parent !== "string")
51
+ throw new ShapeError(`expected ${what}.parent_branch to be a string or null`);
52
+ return { id: b.id, name: b.name, parent_branch: parent ?? null, production: b.production === true, ready: b.ready === true };
53
+ }
54
+ /** One page of a PlanetScale list: `{ data, next_page }`, the next page being `?page=<next_page>` (PS3). */
55
+ function pageOf(body, parse) {
56
+ const o = obj(body, "the list");
57
+ if (!Array.isArray(o.data))
58
+ throw new ShapeError("expected `data` to be an array");
59
+ const items = o.data.map((v, i) => parse(v, `\`data\`[${i}]`));
60
+ return { items, next: typeof o.next_page === "number" ? { page: String(o.next_page) } : null };
61
+ }
62
+ /** The branch by name (PS2), or null when it does not exist. */
63
+ async function getBranch(c, name) {
64
+ try {
65
+ return await c.api.get(`${c.base}/branches/${enc(name)}`, (b) => parseBranch(b, "the branch"));
66
+ }
67
+ catch (e) {
68
+ if (isProviderError(e, "PROVIDER_NOT_FOUND"))
69
+ return null;
70
+ throw e;
71
+ }
72
+ }
73
+ /** Poll the branch until it reports `ready` (PS4). Reads only. */
74
+ async function waitReady(actx, c, name) {
75
+ const deadline = Date.now() + msFromEnv(actx.env, READY_TIMEOUT_MS);
76
+ for (;;) {
77
+ const b = await getBranch(c, name);
78
+ if (!b)
79
+ throw new SponsonError("PROVIDER_NOT_FOUND", `planetscale: branch ${name} disappeared while waiting for it to become ready`, { adapter: ADAPTER, branch: name });
80
+ if (b.ready)
81
+ return b;
82
+ if (Date.now() > deadline) {
83
+ throw new SponsonError("WAIT_TIMEOUT", `planetscale: branch ${name} is not ready after ${msFromEnv(actx.env, READY_TIMEOUT_MS)}ms (${READY_TIMEOUT_MS.env}); run again to keep waiting`, { adapter: ADAPTER, branch: name });
84
+ }
85
+ actx.log(`branch ${name} not ready yet`);
86
+ await sleep(msFromEnv(actx.env, POLL_MS));
87
+ }
88
+ }
89
+ const BRANCH_PREFIX = "branch:";
90
+ /** Identity hash: name and parent, the two things that define a branch for us (as `neon.branch`). */
91
+ function branchRecord(b) {
92
+ return { key: `${BRANCH_PREFIX}${b.name}`, id: b.id, hash: sha256(canonicalJson({ name: b.name, parent_branch: b.parent_branch })), label: `PlanetScale branch ${b.name}` };
93
+ }
94
+ function branchOutputs(b) {
95
+ return { name: b.name, branch_id: b.id };
96
+ }
97
+ /** Create the branch, or find it when it exists already (a lost answer of ours, or someone else's). */
98
+ async function createBranch(actx, c, name, parent) {
99
+ try {
100
+ await c.api.post(`${c.base}/branches`, { name, parent_branch: parent }, (b) => parseBranch(b, "the created branch"));
101
+ return { branch: await waitReady(actx, c, name), created: true };
102
+ }
103
+ catch (e) {
104
+ // PS5: a duplicate name answers 422 (perhaps 409). Whatever the wording, the branch existing is what matters.
105
+ if (!isProviderError(e, ["PROVIDER_CONFLICT", "PROVIDER_INVALID"]))
106
+ throw e;
107
+ const found = await getBranch(c, name);
108
+ if (!found)
109
+ throw e;
110
+ // Not created by this call; the engine claims it when an earlier intent of ours named it.
111
+ return { branch: found.ready ? found : await waitReady(actx, c, name), created: false };
112
+ }
113
+ }
114
+ const branch = {
115
+ outputs: {
116
+ name: { available: "immediate" },
117
+ branch_id: { available: "immediate" },
118
+ },
119
+ defaults(params, ctx) {
120
+ return { parent: "main", name: defaultName(ctx), ...params };
121
+ },
122
+ async read(actx, params) {
123
+ if (markerKind(params.name) !== null)
124
+ return null;
125
+ const c = client(actx);
126
+ const found = await getBranch(c, stringParam(params, "name", ADAPTER));
127
+ return found ? { resources: [branchRecord(found)], outputs: branchOutputs(found) } : null;
128
+ },
129
+ diff(live, params) {
130
+ const name = params.name;
131
+ if (markerKind(name) !== null)
132
+ return [{ key: `${BRANCH_PREFIX}(pending)`, kind: "create", label: "PlanetScale branch", before: ABSENT, after: desiredSide(name, false) }];
133
+ const key = `${BRANCH_PREFIX}${String(name)}`;
134
+ const current = live?.resources.find((r) => r.key === key);
135
+ // A branch's identity is its name; re-parenting is not possible, so an existing branch is unchanged whatever `parent` says.
136
+ if (current)
137
+ return [{ key, kind: "unchanged", label: current.label ?? key }];
138
+ return [{ key, kind: "create", label: `PlanetScale branch ${String(name)}`, before: ABSENT, after: desiredSide(name, false) }];
139
+ },
140
+ async apply(actx, params, live) {
141
+ assertNoPending(params, ADAPTER);
142
+ const name = stringParam(params, "name", ADAPTER);
143
+ const key = `${BRANCH_PREFIX}${name}`;
144
+ if (live?.resources.some((r) => r.key === key))
145
+ return { resources: live.resources, outputs: live.outputs, created: [] };
146
+ const c = client(actx);
147
+ const parent = stringParam(params, "parent", ADAPTER, "main");
148
+ if (!(await getBranch(c, parent)))
149
+ throw paramError(ADAPTER, `parent branch \`${parent}\` not found in database ${c.database}`, "parent");
150
+ await actx.intend([key]);
151
+ actx.log(`create branch ${name} from ${parent}`);
152
+ const r = await createBranch(actx, c, name, parent);
153
+ return { resources: [branchRecord(r.branch)], outputs: branchOutputs(r.branch), created: r.created ? [key] : [] };
154
+ },
155
+ /** Deletes by name (PS2), and only the branch the ledger recorded: one re-created under that name by someone else is left alone. */
156
+ async destroy(actx, resources) {
157
+ const c = client(actx);
158
+ for (const r of resources) {
159
+ const name = r.key.slice(BRANCH_PREFIX.length);
160
+ const live = await getBranch(c, name);
161
+ if (!live || (r.id && live.id !== r.id))
162
+ continue;
163
+ await deleteIgnoringNotFound(c.api, `${c.base}/branches/${enc(name)}`);
164
+ }
165
+ },
166
+ /** Every development branch: production branches are never a scope's. */
167
+ async listScope(actx) {
168
+ const c = client(actx);
169
+ const all = await listAll(c.api, `${c.base}/branches`, (body) => pageOf(body, parseBranch));
170
+ return all.filter((b) => !b.production).map(branchRecord);
171
+ },
172
+ /** One line per branch, naming it: the line then manages exactly that branch. */
173
+ adopt(resources) {
174
+ return resources.map((r) => {
175
+ const name = r.key.slice(BRANCH_PREFIX.length);
176
+ return { id: `db-${name}`, params: { name }, keys: [r.key] };
177
+ });
178
+ },
179
+ };
180
+ function parsePassword(v, what) {
181
+ const [p] = records([v], what, ["id", "role", "username", "access_host_url"]);
182
+ return { id: p.id, name: typeof p.name === "string" ? p.name : "", role: p.role, username: p.username, host: p.access_host_url };
183
+ }
184
+ /** The create answer: the password, and its plaintext, which no other answer carries (PS8). */
185
+ function parseCreatedPassword(v) {
186
+ const p = parsePassword(v, "the created password");
187
+ const plain = v.plain_text;
188
+ if (typeof plain !== "string" || plain === "")
189
+ throw new ShapeError("expected `plain_text` to be a non-empty string in the create answer");
190
+ return { ...p, plainText: plain };
191
+ }
192
+ const PASSWORD_PREFIX = "password:";
193
+ /** The branch is part of the key: two branches may each have a password of the same name. */
194
+ function passwordKey(branchName, name) {
195
+ return `${PASSWORD_PREFIX}${enc(branchName)}/${name}`;
196
+ }
197
+ function branchOfKey(key) {
198
+ const rest = key.slice(PASSWORD_PREFIX.length);
199
+ return decodeURIComponent(rest.slice(0, rest.indexOf("/")));
200
+ }
201
+ function passwordHash(name, role) {
202
+ return sha256(canonicalJson({ name, role }));
203
+ }
204
+ function passwordRecord(branchName, p) {
205
+ return { key: passwordKey(branchName, p.name), id: p.id, hash: passwordHash(p.name, p.role), label: `PlanetScale password ${p.name} on branch ${branchName}` };
206
+ }
207
+ function passwordOutputs(p) {
208
+ return { id: p.id, username: p.username, host: p.host, role: p.role };
209
+ }
210
+ /** The passwords of a branch named `name`; null when the branch does not exist. */
211
+ async function findPassword(c, branchName, name) {
212
+ let all;
213
+ try {
214
+ all = await listAll(c.api, `${c.base}/branches/${enc(branchName)}/passwords`, (body) => pageOf(body, parsePassword));
215
+ }
216
+ catch (e) {
217
+ if (isProviderError(e, "PROVIDER_NOT_FOUND"))
218
+ return null;
219
+ throw e;
220
+ }
221
+ const named = all.filter((p) => p.name === name);
222
+ // PS9: names are not unique. Guessing could hand a dependent the wrong credential's identity.
223
+ if (named.length > 1) {
224
+ throw new SponsonError("PROVIDER_CONFLICT", `planetscale: branch ${branchName} has ${named.length} passwords named ${name}; delete the extra ones in PlanetScale, then run again`, { adapter: ADAPTER, branch: branchName, name });
225
+ }
226
+ return named[0] ?? null;
227
+ }
228
+ function passwordParams(params) {
229
+ return { branch: stringParam(params, "branch", ADAPTER), name: stringParam(params, "name", ADAPTER), role: stringParam(params, "role", ADAPTER, "admin") };
230
+ }
231
+ /** `mysql://<username>:<plaintext>@<access host>/<database>?<params>`, as PlanetScale documents it (PS8). */
232
+ function connectionString(p, database, query) {
233
+ return `mysql://${enc(p.username)}:${enc(p.plainText)}@${p.host}/${enc(database)}${query ? `?${query}` : ""}`;
234
+ }
235
+ function roleChangeError(p, liveRole) {
236
+ return paramError(ADAPTER, `password ${p.name} on branch ${p.branch} has role ${liveRole}; PlanetScale cannot change a password's role in place, and Sponson does not replace a password on its own. ` +
237
+ `Give the line a new \`name\` to create a ${p.role} password (dependents then receive its value), or set \`role: ${liveRole}\`.`, "role");
238
+ }
239
+ const password = {
240
+ outputs: {
241
+ id: { available: "immediate" },
242
+ username: { available: "immediate" },
243
+ host: { available: "immediate" },
244
+ role: { available: "immediate" },
245
+ password: { available: "immediate", sensitive: true, once: true },
246
+ connection_string: { available: "immediate", sensitive: true, once: true },
247
+ },
248
+ defaults(params, ctx) {
249
+ return { name: defaultName(ctx), role: "admin", ...params };
250
+ },
251
+ async read(actx, params) {
252
+ if (markerKind(params.branch) !== null || markerKind(params.name) !== null)
253
+ return null;
254
+ const p = passwordParams(params);
255
+ const c = client(actx);
256
+ const found = await findPassword(c, p.branch, p.name);
257
+ // The plaintext is never readable (PS8): `password` and `connection_string` exist only in the run that creates it.
258
+ return found ? { resources: [passwordRecord(p.branch, found)], outputs: passwordOutputs(found) } : null;
259
+ },
260
+ diff(live, params) {
261
+ if (markerKind(params.branch) !== null || markerKind(params.name) !== null) {
262
+ return [{ key: `${PASSWORD_PREFIX}(pending)`, kind: "create", label: "PlanetScale password", before: ABSENT, after: desiredSide(params.name, false) }];
263
+ }
264
+ const p = passwordParams(params);
265
+ const key = passwordKey(p.branch, p.name);
266
+ const label = `PlanetScale password ${p.name} on branch ${p.branch}`;
267
+ const current = live?.resources.find((r) => r.key === key);
268
+ if (!current)
269
+ return [{ key, kind: "create", label, before: ABSENT, after: { state: "literal", value: p.role } }];
270
+ if (current.hash === passwordHash(p.name, p.role))
271
+ return [{ key, kind: "unchanged", label }];
272
+ // PS10: the only way to another role is a new password, and that is the plan's decision, never Sponson's.
273
+ throw roleChangeError(p, String(live?.outputs.role ?? "another role"));
274
+ },
275
+ async apply(actx, params, live) {
276
+ assertNoPending(params, ADAPTER);
277
+ const p = passwordParams(params);
278
+ const key = passwordKey(p.branch, p.name);
279
+ const current = live?.resources.find((r) => r.key === key);
280
+ if (current) {
281
+ if (current.hash !== passwordHash(p.name, p.role))
282
+ throw roleChangeError(p, String(live?.outputs.role ?? "another role"));
283
+ return { resources: live.resources, outputs: live.outputs, created: [] };
284
+ }
285
+ const c = client(actx);
286
+ if (!(await getBranch(c, p.branch)))
287
+ throw paramError(ADAPTER, `branch \`${p.branch}\` not found in database ${c.database}`, "branch");
288
+ // PS12: a password needs a ready branch; a branch an earlier run left provisioning is waited for here.
289
+ await waitReady(actx, c, p.branch);
290
+ await actx.intend([key]);
291
+ actx.log(`create password ${p.name} (${p.role}) on branch ${p.branch}`);
292
+ const created = await c.api.post(`${c.base}/branches/${enc(p.branch)}/passwords`, { name: p.name, role: p.role }, parseCreatedPassword);
293
+ const query = stringParam(params, "connection_params", ADAPTER, DEFAULT_CONNECTION_PARAMS);
294
+ const record = passwordRecord(p.branch, { ...created, name: p.name });
295
+ const outputs = { ...passwordOutputs(created), password: created.plainText, connection_string: connectionString(created, c.database, query) };
296
+ return { resources: [record], outputs, created: [key] };
297
+ },
298
+ async destroy(actx, resources) {
299
+ const c = client(actx);
300
+ for (const r of resources)
301
+ await deleteIgnoringNotFound(c.api, `${c.base}/branches/${enc(branchOfKey(r.key))}/passwords/${enc(r.id)}`);
302
+ },
303
+ };
304
+ /**
305
+ * PlanetScale (Vitess / MySQL databases): op `branch` creates a development branch per scope and waits until it
306
+ * is ready; op `password` creates a password on it whose `connection_string` and `password` outputs (sensitive)
307
+ * exist only in the run that creates it (`once`). Needs `PLANETSCALE_SERVICE_TOKEN_ID`,
308
+ * `PLANETSCALE_SERVICE_TOKEN` and `providers.planetscale.{organization,database}`.
309
+ */
310
+ export const planetscaleAdapter = { name: ADAPTER, ops: { branch, password }, about: ABOUT };
311
+ //# sourceMappingURL=planetscale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planetscale.js","sourceRoot":"","sources":["../src/planetscale.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Every provider a repository's files can show it uses, with what to detect it by: first-class adapters from their
3
+ * `about` (title, category, detect), recipe providers from their file's `detect` block. `sponson init` detects from
4
+ * this list and the provider catalog (docs/providers.md) is generated from it, so declaring `detect` on an adapter
5
+ * or in a recipe file is all it takes for both; neither keeps a list of providers of its own.
6
+ */
7
+ import type { ProviderDetect, Registry } from "@sponson/core";
8
+ import { type Recipe } from "./recipes.js";
9
+ /** A provider `sponson init` can detect: who manages it, what to detect it by, and the credential it reads. */
10
+ export interface DetectableProvider {
11
+ /** The adapter's name, or the recipe's provider: what `init` reports as the finding's id. */
12
+ id: string;
13
+ /** As people write it (Vercel, Stripe). */
14
+ title: string;
15
+ /** A docs/coverage.yaml category id. */
16
+ category: string;
17
+ /** Managed by a first-class adapter, or by recipes of the generic `http` adapter. */
18
+ via: "adapter" | "recipe";
19
+ detect: ProviderDetect;
20
+ /** The variables its credential is read from when Sponson runs (never written into a plan). */
21
+ credentials: string[];
22
+ /** For a recipe provider, its recipe. */
23
+ recipe?: Recipe;
24
+ }
25
+ /** The detectable providers: the registry's adapters in registration order, then the recipes by provider. */
26
+ export declare function detectableProviders(registry: Registry, recipes?: Recipe[]): DetectableProvider[];
@@ -0,0 +1,36 @@
1
+ import { loadRecipes, recipeCredentialEnv } from "./recipes.js";
2
+ /** The detectable providers: the registry's adapters in registration order, then the recipes by provider. */
3
+ export function detectableProviders(registry, recipes = loadRecipes()) {
4
+ const out = [];
5
+ for (const name of registry.adapterNames()) {
6
+ const about = registry.adapter(name).about;
7
+ if (!about?.detect)
8
+ continue;
9
+ out.push({
10
+ id: name,
11
+ title: about.title ?? name,
12
+ category: about.category ?? "other",
13
+ via: "adapter",
14
+ detect: about.detect,
15
+ credentials: [...(about.extraCredentialEnv ?? []), about.credentialEnv],
16
+ });
17
+ }
18
+ const taken = new Set(out.map((p) => p.id));
19
+ for (const recipe of recipes) {
20
+ const d = recipe.detect;
21
+ // A provider a first-class adapter already detects keeps the adapter's lines (its recipe adds ops beside them).
22
+ if (!d || taken.has(recipe.provider))
23
+ continue;
24
+ out.push({
25
+ id: recipe.provider,
26
+ title: recipe.title,
27
+ category: recipe.category,
28
+ via: "recipe",
29
+ detect: { ...(d.deps ? { deps: d.deps } : {}), ...(d.env ? { env: d.env } : {}), ...(d.files ? { files: d.files } : {}), ...(d.db_hosts ? { dbHosts: d.db_hosts } : {}) },
30
+ credentials: recipeCredentialEnv(recipe),
31
+ recipe,
32
+ });
33
+ }
34
+ return out;
35
+ }
36
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAe,MAAM,cAAc,CAAC;AAmB7E,6GAA6G;AAC7G,MAAM,UAAU,mBAAmB,CAAC,QAAkB,EAAE,UAAoB,WAAW,EAAE;IACvF,MAAM,GAAG,GAAyB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;QAC3C,IAAI,CAAC,KAAK,EAAE,MAAM;YAAE,SAAS;QAC7B,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAI;YACR,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;YAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,OAAO;YACnC,GAAG,EAAE,SAAS;YACd,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,WAAW,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;SACxE,CAAC,CAAC;IACL,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QACxB,gHAAgH;QAChH,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;YAAE,SAAS;QAC/C,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,MAAM,CAAC,QAAQ;YACnB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,GAAG,EAAE,QAAQ;YACb,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;YACzK,WAAW,EAAE,mBAAmB,CAAC,MAAM,CAAC;YACxC,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,167 @@
1
+ /** Where the shipped recipe files are, in the source tree and in the published package alike. */
2
+ export declare const RECIPES_DIR: string;
3
+ /** The value types a recipe param takes. */
4
+ export type RecipeParamType = "string" | "integer" | "number" | "boolean" | "list" | "map";
5
+ /** One param a recipe op takes from the plan line. */
6
+ export interface RecipeParam {
7
+ type: RecipeParamType;
8
+ description: string;
9
+ required?: boolean;
10
+ /** Used when the line leaves the param out. */
11
+ default?: unknown;
12
+ /** Allowed values. */
13
+ enum?: unknown[];
14
+ /** A regular expression concrete string values must match. */
15
+ pattern?: string;
16
+ /** The value the docs' example line and the recipe tests use. */
17
+ example?: unknown;
18
+ }
19
+ /** How the generic REST sim stands in for the provider in the recipe tests (`scenarios/recipes.test.ts`). */
20
+ export interface RecipeSimHints {
21
+ /** The body field a create chooses the object's id with (a database name), when the provider takes one. */
22
+ id_from?: string;
23
+ /** The provider's ids are integers. */
24
+ numeric_ids?: boolean;
25
+ /** Objects to seed by path (placeholders filled from the example params): a list item's parent. */
26
+ objects?: Record<string, Record<string, unknown>>;
27
+ /** Request headers a create or update stores as fields (header → field), for an API that takes settings in headers. */
28
+ header_fields?: Record<string, string>;
29
+ /** For a create at `<collection>/{+param}`: the field the sim stores that path suffix in (an upsert by chosen id). */
30
+ suffix_field?: string;
31
+ /** The query parameter the provider names one object with, when objects are keyed by a value (`url`). */
32
+ item_query?: string;
33
+ /**
34
+ * The collection a resource lives in, when its create is posted to another path (Statsig adds a rule with
35
+ * `POST /gates/{id}/rule` and lists them at `/gates/{id}/rules`). Default: the create's path.
36
+ */
37
+ collection?: string;
38
+ /**
39
+ * A first-class sim to run the op against instead of the generic REST sim, for an API the REST sim cannot stand
40
+ * in for (a GraphQL API: `railway`, `fly`). Then `seed` is that sim's seed, `present` a JSON pointer into its state
41
+ * that exists once the op applied (and not after destroy), and `drift` its drift keys (without the provider
42
+ * prefix) that edit a declared field (`changed`) and remove what the op made (`missing`).
43
+ */
44
+ provider?: string;
45
+ /** With `provider`: the path under the sim that the API's base URL stands for (default `/<provider>`). */
46
+ base_path?: string;
47
+ seed?: Record<string, unknown>;
48
+ present?: string;
49
+ drift?: {
50
+ changed?: Record<string, string>;
51
+ missing: Record<string, string>;
52
+ };
53
+ }
54
+ /** One operation of a recipe: an `http.resource`, `http.list_item` or `http.action` spec with typed params. */
55
+ export interface RecipeOp {
56
+ kind: "resource" | "list_item" | "action";
57
+ title: string;
58
+ summary: string;
59
+ /** The ids of the rows of docs/coverage.yaml this op covers. */
60
+ covers: string[];
61
+ params: Record<string, RecipeParam>;
62
+ /** The http op's params, minus `api`, `vars` and `destroy`; `{ param: <name> }` values and `{<name>}` placeholders. */
63
+ http: Record<string, unknown>;
64
+ /**
65
+ * What destroying a scope does with what the op made, when the line does not say (`destroy:`). Absent: delete it.
66
+ * `keep`: leave it (history shared beyond the scope, such as a release); a line may still say `destroy: delete`.
67
+ * `never`: the provider offers no way to delete it, so it is always left and `destroy: delete` is PARAM_INVALID.
68
+ */
69
+ destroy?: "keep" | "never";
70
+ sim?: RecipeSimHints;
71
+ /** For `pnpm test:live`: the environment variable supplying each param that has no usable example live. */
72
+ live?: {
73
+ params?: Record<string, string>;
74
+ };
75
+ }
76
+ /** One assumption a recipe makes about its provider's API, numbered, verified against a source or not. */
77
+ export interface RecipeAssumption {
78
+ id: string;
79
+ text: string;
80
+ verified: boolean;
81
+ source?: string;
82
+ }
83
+ /** One provider's recipe file. */
84
+ export interface Recipe {
85
+ provider: string;
86
+ title: string;
87
+ /** The id of a category of docs/coverage.yaml. */
88
+ category: string;
89
+ /** The date its API facts were checked against `docs`. */
90
+ verified_on: string;
91
+ docs: Array<{
92
+ title: string;
93
+ url: string;
94
+ }>;
95
+ assumptions: RecipeAssumption[];
96
+ /**
97
+ * The API block defaults: what `providers.http.<api>: { recipe: <provider> }` means. Absent for a recipe whose
98
+ * ops are all `http.action`s sent to an absolute `url` (the app's own endpoint): those use no API block.
99
+ */
100
+ api?: Record<string, unknown>;
101
+ /** For a per-account API (no default `base_url`): the base URL the docs' example block and the recipe tests use. */
102
+ base_url_example?: string;
103
+ /** How `sponson init` detects the provider, and the lines it writes for it (schema/recipe.schema.json, `detect`). */
104
+ detect?: RecipeDetect;
105
+ ops: Record<string, RecipeOp>;
106
+ }
107
+ /** A line `sponson init` writes for a detected recipe provider. */
108
+ export interface RecipeStarter {
109
+ op: string;
110
+ /** The param that takes the preview's URL, as a whole value (`{ from: <deploy line>.preview_url }`). */
111
+ preview_url?: string;
112
+ /** Values written for these params (usually built from `${ctx.*}`). */
113
+ values?: Record<string, unknown>;
114
+ }
115
+ /** A recipe's `detect` block: the signals of the provider (names and files only), and init's lines for it. */
116
+ export interface RecipeDetect {
117
+ deps?: string[];
118
+ env?: string[];
119
+ files?: string[];
120
+ db_hosts?: string[];
121
+ /** Default: one line for the first op. */
122
+ starter?: RecipeStarter[];
123
+ /** Where to find a param's value (`base_url` for a per-account API), by param name. */
124
+ where?: Record<string, string>;
125
+ }
126
+ /**
127
+ * The environment variables a recipe's API block reads its credential from, in the order the block names them.
128
+ * Empty for a recipe without an API block and for a token a command prints (`az`, `gcloud`: their own login).
129
+ */
130
+ export declare function recipeCredentialEnv(recipe: Pick<Recipe, "api">): string[];
131
+ /** The providers that have a recipe, sorted. */
132
+ export declare function recipeNames(): string[];
133
+ /**
134
+ * Make a recipe known for this process as if it were shipped, until the returned function is called. For tests of
135
+ * code that recipes drive (the adapter's own tests use it for a list item recipe); not exported by the package.
136
+ */
137
+ export declare function useRecipe(recipe: Recipe): () => void;
138
+ /** A provider's recipe; PARAM_INVALID naming the known ones when there is none. */
139
+ export declare function loadRecipe(provider: string, param?: string): Recipe;
140
+ /** Every shipped recipe. */
141
+ export declare function loadRecipes(): Recipe[];
142
+ /** A line's `recipe: <provider>.<op>`, located. */
143
+ export declare function recipeOp(ref: unknown): {
144
+ recipe: Recipe;
145
+ name: string;
146
+ op: RecipeOp;
147
+ };
148
+ /** The API a line uses: its `api`, or for a recipe line without one, the recipe's provider. */
149
+ export declare function lineApi(params: Record<string, unknown>): unknown;
150
+ /** The value of every param the line sets or the recipe defaults, checked; PARAM_INVALID naming the param otherwise. */
151
+ export declare function recipeValues(params: Record<string, unknown>): Record<string, unknown>;
152
+ /**
153
+ * `tpl` with every `{ param: <name> }` replaced by its value (a param without one removes its map key or list
154
+ * item) and every `{ join: [...] }` by its parts joined.
155
+ */
156
+ export declare function substitute(tpl: unknown, values: Record<string, unknown>): unknown;
157
+ /**
158
+ * A line's params as the `http.<kind>` op reads them: unchanged without `recipe`, else the recipe's spec with the
159
+ * line's values filled in (`vars` holds every value, for the `{<name>}` path placeholders).
160
+ */
161
+ export declare function expandRecipe(params: Record<string, unknown>, kind: RecipeOp["kind"]): Record<string, unknown>;
162
+ /**
163
+ * A `providers.http.<api>` block with `recipe:`, resolved: the recipe's API defaults, then the block's own keys
164
+ * over them. Blocks without `recipe:` are returned as they are. The result never names the recipe, so it (and with
165
+ * it the ledger identity) is the same as a hand-written block with the same values.
166
+ */
167
+ export declare function resolveRecipeApi(block: Record<string, unknown>, where: string): Record<string, unknown>;