@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
package/dist/sigv4.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS Signature Version 4 (header form), without an AWS SDK: the canonical request, the string to sign, the
|
|
3
|
+
* signing key and the `Authorization` header, as specified in
|
|
4
|
+
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html and checked against
|
|
5
|
+
* AWS's published test suite (sigv4.test.ts). Pure: the clock is a parameter.
|
|
6
|
+
*
|
|
7
|
+
* The generic `http` adapter signs every request of an API block that declares `auth: { aws_sigv4: … }` with it
|
|
8
|
+
* (http-adapter-auth.ts). Not supported: chunked (streaming) payloads, presigned URLs, SigV4a.
|
|
9
|
+
*/
|
|
10
|
+
import { createHash, createHmac } from "node:crypto";
|
|
11
|
+
const ALGORITHM = "AWS4-HMAC-SHA256";
|
|
12
|
+
function sha256Hex(s) {
|
|
13
|
+
return createHash("sha256").update(s).digest("hex");
|
|
14
|
+
}
|
|
15
|
+
function hmac(key, data) {
|
|
16
|
+
return createHmac("sha256", key).update(data, "utf8").digest();
|
|
17
|
+
}
|
|
18
|
+
/** RFC 3986 encoding as SigV4 wants it: unreserved characters as they are, every other UTF-8 byte as `%XX`. */
|
|
19
|
+
export function uriEncode(s) {
|
|
20
|
+
return encodeURIComponent(s).replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
21
|
+
}
|
|
22
|
+
function safeDecode(s) {
|
|
23
|
+
try {
|
|
24
|
+
return decodeURIComponent(s);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return s;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The canonical URI: each path segment encoded once (S3) or twice (every other service, as the AWS docs require),
|
|
32
|
+
* starting from the path as sent.
|
|
33
|
+
*/
|
|
34
|
+
export function canonicalUri(pathname, service) {
|
|
35
|
+
if (pathname === "" || pathname === "/")
|
|
36
|
+
return "/";
|
|
37
|
+
const twice = service !== "s3";
|
|
38
|
+
return pathname
|
|
39
|
+
.split("/")
|
|
40
|
+
.map((seg) => {
|
|
41
|
+
const once = uriEncode(safeDecode(seg));
|
|
42
|
+
return twice ? uriEncode(once) : once;
|
|
43
|
+
})
|
|
44
|
+
.join("/");
|
|
45
|
+
}
|
|
46
|
+
/** The canonical query string: every parameter encoded, sorted by name then value; `?cors` is `cors=`. */
|
|
47
|
+
export function canonicalQuery(search) {
|
|
48
|
+
const raw = search.startsWith("?") ? search.slice(1) : search;
|
|
49
|
+
if (raw === "")
|
|
50
|
+
return "";
|
|
51
|
+
const pairs = raw
|
|
52
|
+
.split("&")
|
|
53
|
+
.filter((p) => p !== "")
|
|
54
|
+
.map((p) => {
|
|
55
|
+
const eq = p.indexOf("=");
|
|
56
|
+
const k = eq < 0 ? p : p.slice(0, eq);
|
|
57
|
+
const v = eq < 0 ? "" : p.slice(eq + 1);
|
|
58
|
+
return [uriEncode(safeDecode(k)), uriEncode(safeDecode(v))];
|
|
59
|
+
});
|
|
60
|
+
pairs.sort(([ak, av], [bk, bv]) => (ak < bk ? -1 : ak > bk ? 1 : av < bv ? -1 : av > bv ? 1 : 0));
|
|
61
|
+
return pairs.map(([k, v]) => `${k}=${v}`).join("&");
|
|
62
|
+
}
|
|
63
|
+
/** `YYYYMMDDTHHMMSSZ` */
|
|
64
|
+
export function amzDate(d) {
|
|
65
|
+
return d.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}/, "");
|
|
66
|
+
}
|
|
67
|
+
/** The headers SigV4 adds before signing: date, host-independent payload hash and session token. */
|
|
68
|
+
function signingHeaders(req, creds, scope) {
|
|
69
|
+
const out = { "x-amz-date": amzDate(scope.date) };
|
|
70
|
+
if (scope.contentSha256Header !== false)
|
|
71
|
+
out["x-amz-content-sha256"] = sha256Hex(req.body);
|
|
72
|
+
if (creds.sessionToken)
|
|
73
|
+
out["x-amz-security-token"] = creds.sessionToken;
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
/** Canonical headers and the signed-headers list: names lower-cased and sorted, values trimmed, runs of spaces collapsed. */
|
|
77
|
+
function canonicalHeaders(headers) {
|
|
78
|
+
const entries = Object.entries(headers)
|
|
79
|
+
.map(([k, v]) => [k.toLowerCase(), v.trim().replace(/\s+/g, " ")])
|
|
80
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
81
|
+
return { canonical: entries.map(([k, v]) => `${k}:${v}\n`).join(""), signed: entries.map(([k]) => k).join(";") };
|
|
82
|
+
}
|
|
83
|
+
/** The canonical request, and the signed-headers list it names. `headers` must include `host`. */
|
|
84
|
+
export function canonicalRequest(req, service) {
|
|
85
|
+
const u = new URL(req.url);
|
|
86
|
+
const { canonical, signed } = canonicalHeaders(req.headers);
|
|
87
|
+
const payload = req.headers["x-amz-content-sha256"] ?? sha256Hex(req.body);
|
|
88
|
+
return { request: [req.method.toUpperCase(), canonicalUri(u.pathname, service), canonicalQuery(u.search), canonical, signed, payload].join("\n"), signedHeaders: signed };
|
|
89
|
+
}
|
|
90
|
+
/** `<date>/<region>/<service>/aws4_request` */
|
|
91
|
+
export function credentialScope(scope) {
|
|
92
|
+
return `${amzDate(scope.date).slice(0, 8)}/${scope.region}/${scope.service}/aws4_request`;
|
|
93
|
+
}
|
|
94
|
+
/** The string to sign for a canonical request. */
|
|
95
|
+
export function stringToSign(canonical, scope) {
|
|
96
|
+
return [ALGORITHM, amzDate(scope.date), credentialScope(scope), sha256Hex(canonical)].join("\n");
|
|
97
|
+
}
|
|
98
|
+
/** The hex signature of a string to sign. */
|
|
99
|
+
export function signature(secretAccessKey, scope, toSign) {
|
|
100
|
+
const day = amzDate(scope.date).slice(0, 8);
|
|
101
|
+
const key = hmac(hmac(hmac(hmac(`AWS4${secretAccessKey}`, day), scope.region), scope.service), "aws4_request");
|
|
102
|
+
return createHmac("sha256", key).update(toSign, "utf8").digest("hex");
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Sign a request: the headers to add to it (`x-amz-date`, `x-amz-content-sha256`, `x-amz-security-token` when the
|
|
106
|
+
* credentials are temporary, and `authorization`). Every header of `req` is signed, plus `host` from the URL.
|
|
107
|
+
*/
|
|
108
|
+
export function signRequest(req, creds, scope) {
|
|
109
|
+
const added = signingHeaders(req, creds, scope);
|
|
110
|
+
const headers = { ...lowerKeys(req.headers), ...added, host: new URL(req.url).host };
|
|
111
|
+
const { request, signedHeaders } = canonicalRequest({ ...req, headers }, scope.service);
|
|
112
|
+
const sig = signature(creds.secretAccessKey, scope, stringToSign(request, scope));
|
|
113
|
+
return { ...added, authorization: `${ALGORITHM} Credential=${creds.accessKeyId}/${credentialScope(scope)}, SignedHeaders=${signedHeaders}, Signature=${sig}` };
|
|
114
|
+
}
|
|
115
|
+
function lowerKeys(h) {
|
|
116
|
+
return Object.fromEntries(Object.entries(h).filter(([k]) => k.toLowerCase() !== "authorization").map(([k, v]) => [k.toLowerCase(), v]));
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=sigv4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sigv4.js","sourceRoot":"","sources":["../src/sigv4.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ResourceAdapter } from "@sponson/core";
|
|
2
|
+
/** The Supabase Management API's base URL. `SUPABASE_API_URL` overrides it; tests and scenarios point that at the sim. */
|
|
3
|
+
export declare const SUPABASE_DEFAULT_API_URL = "https://api.supabase.com/v1";
|
|
4
|
+
/**
|
|
5
|
+
* The Supabase adapter (`adapter: supabase` in a plan): op `branch` (a preview branch per scope, with its
|
|
6
|
+
* connection string as a sensitive output) and op `auth_redirect` (one URL in the project's Auth redirect
|
|
7
|
+
* allow-list). Needs `SUPABASE_ACCESS_TOKEN` and `providers.supabase.project` (the parent project's ref).
|
|
8
|
+
*/
|
|
9
|
+
export declare const supabaseAdapter: ResourceAdapter;
|
package/dist/supabase.js
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supabase adapter, over the Management API (https://api.supabase.com/v1) with one personal access token.
|
|
3
|
+
*
|
|
4
|
+
* branch a preview branch of the project per scope (Supabase Branching): created, waited for until its
|
|
5
|
+
* database is up, destroyed with the scope. Its outputs are the branch's own project ref, API URL
|
|
6
|
+
* and database connection string (sensitive).
|
|
7
|
+
* auth_redirect one URL in a project's Auth redirect allow-list (`uri_allow_list`, one comma-separated
|
|
8
|
+
* string), the parent's or (param `project`) a branch's own: read-modify-write of that string,
|
|
9
|
+
* never touching entries Sponson did not add.
|
|
10
|
+
*
|
|
11
|
+
* What the code assumes about the API is numbered S1–S9 at the top of packages/sim/src/routes/supabase.ts and
|
|
12
|
+
* checked in docs/api-verification.md.
|
|
13
|
+
*/
|
|
14
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
15
|
+
import { SponsonError, canonicalJson, isPendingMarker, markerKind, sha256 } from "@sponson/core";
|
|
16
|
+
import { ABSENT, assertNoPending, clientFor, deleteIgnoringNotFound, desiredSide, diffValue, optionalEnv, paramError, requireEnv, requireProvider, stringParam } from "./common.js";
|
|
17
|
+
import { ShapeError, isProviderError, isTransient, obj, records } from "./http.js";
|
|
18
|
+
const ADAPTER = "supabase";
|
|
19
|
+
/** The environment Supabase reads; declared once, used by the code below and by the generated docs (`about`). */
|
|
20
|
+
const ABOUT = { credentialEnv: "SUPABASE_ACCESS_TOKEN", baseUrlEnv: "SUPABASE_API_URL", title: "Supabase", category: "databases", detect: { deps: ["@supabase/"], env: ["SUPABASE_*"], files: ["supabase/config.toml", "supabase/.temp/project-ref"], dbHosts: [".supabase.co", ".supabase.com"] } };
|
|
21
|
+
/** The Supabase Management API's base URL. `SUPABASE_API_URL` overrides it; tests and scenarios point that at the sim. */
|
|
22
|
+
export const SUPABASE_DEFAULT_API_URL = "https://api.supabase.com/v1";
|
|
23
|
+
/** How long `branch` waits for a new branch to come up unless SPONSON_SUPABASE_TIMEOUT_MS says otherwise. */
|
|
24
|
+
const DEFAULT_READY_TIMEOUT_MS = 600_000;
|
|
25
|
+
/** Polling starts this fast and doubles up to the cap: the sim is ready at once, a real branch takes minutes. */
|
|
26
|
+
const POLL_FIRST_MS = 100;
|
|
27
|
+
const POLL_MAX_MS = 5_000;
|
|
28
|
+
/** Read-modify-write rounds of the allow-list before a concurrent writer is reported as a conflict. */
|
|
29
|
+
const LIST_ATTEMPTS = 3;
|
|
30
|
+
function client(actx) {
|
|
31
|
+
const token = requireEnv(actx.env, ABOUT.credentialEnv, ADAPTER);
|
|
32
|
+
const project = requireProvider(actx, "project", ADAPTER);
|
|
33
|
+
return { api: clientFor(actx, ADAPTER, { baseUrl: optionalEnv(actx.env, ABOUT.baseUrlEnv) ?? SUPABASE_DEFAULT_API_URL, token }), project };
|
|
34
|
+
}
|
|
35
|
+
const BRANCH_PREFIX = "branch:";
|
|
36
|
+
function branchKey(name) {
|
|
37
|
+
return `${BRANCH_PREFIX}${name}`;
|
|
38
|
+
}
|
|
39
|
+
/** Identity hash: the name, the one thing the plan controls. A branch recreated under the same name shows as a new id. */
|
|
40
|
+
function branchHash(name) {
|
|
41
|
+
return sha256(canonicalJson({ name }));
|
|
42
|
+
}
|
|
43
|
+
function branchRecord(b) {
|
|
44
|
+
return { key: branchKey(b.name), id: b.project_ref, hash: branchHash(b.name), label: `Supabase branch ${b.name}` };
|
|
45
|
+
}
|
|
46
|
+
/** BranchResponse items (assumptions S1, S2): `name` and `project_ref` are what the adapter consumes. */
|
|
47
|
+
function parseBranches(v, what) {
|
|
48
|
+
return records(v, what, ["name", "project_ref"]).map((b) => ({ name: b.name, project_ref: b.project_ref, is_default: b.is_default === true }));
|
|
49
|
+
}
|
|
50
|
+
async function listBranches(c) {
|
|
51
|
+
return c.api.get(`/projects/${encodeURIComponent(c.project)}/branches`, (body) => parseBranches(body, "the branch list"));
|
|
52
|
+
}
|
|
53
|
+
/** The branch named `name`, refusing the project's default branch: that is the project itself, never a preview. */
|
|
54
|
+
function findBranch(branches, name) {
|
|
55
|
+
const b = branches.find((x) => x.name === name);
|
|
56
|
+
if (b?.is_default)
|
|
57
|
+
throw paramError(ADAPTER, `branch \`${name}\` is the project's default branch; a supabase.branch line manages preview branches only`, "name");
|
|
58
|
+
return b;
|
|
59
|
+
}
|
|
60
|
+
/** BranchDetailResponse (assumptions S3, S4). */
|
|
61
|
+
function parseDetail(body) {
|
|
62
|
+
const o = obj(body, "the branch detail");
|
|
63
|
+
if (typeof o.status !== "string")
|
|
64
|
+
throw new ShapeError("expected `status` to be a string");
|
|
65
|
+
if (typeof o.db_host !== "string")
|
|
66
|
+
throw new ShapeError("expected `db_host` to be a string");
|
|
67
|
+
if (typeof o.db_port !== "number")
|
|
68
|
+
throw new ShapeError("expected `db_port` to be a number");
|
|
69
|
+
const str = (v) => (typeof v === "string" && v !== "" ? v : undefined);
|
|
70
|
+
const user = str(o.db_user);
|
|
71
|
+
const pass = str(o.db_pass);
|
|
72
|
+
return { status: o.status, db_host: o.db_host, db_port: o.db_port, ...(user ? { db_user: user } : {}), ...(pass ? { db_pass: pass } : {}) };
|
|
73
|
+
}
|
|
74
|
+
/** The API URL of a project ref (assumption S4). */
|
|
75
|
+
function apiUrl(ref) {
|
|
76
|
+
return `https://${ref}.supabase.co`;
|
|
77
|
+
}
|
|
78
|
+
/** Outputs known from the branch alone, before its database is up. */
|
|
79
|
+
function baseOutputs(ref) {
|
|
80
|
+
return { project_ref: ref, api_url: apiUrl(ref) };
|
|
81
|
+
}
|
|
82
|
+
/** Every output, from a ready branch's detail. The password is percent-encoded, as a connection URI requires. */
|
|
83
|
+
function readyOutputs(ref, d) {
|
|
84
|
+
if (!d.db_user || !d.db_pass) {
|
|
85
|
+
throw new SponsonError("PROVIDER_RESPONSE", `supabase: GET /branches/${ref} has no database credentials (db_user, db_pass); the access token may not be allowed to read them`, { adapter: ADAPTER, branch: ref });
|
|
86
|
+
}
|
|
87
|
+
const uri = `postgresql://${encodeURIComponent(d.db_user)}:${encodeURIComponent(d.db_pass)}@${d.db_host}:${d.db_port}/postgres`;
|
|
88
|
+
return { ...baseOutputs(ref), db_host: d.db_host, connection_string: uri };
|
|
89
|
+
}
|
|
90
|
+
const READY = "ACTIVE_HEALTHY";
|
|
91
|
+
/** Project states a new branch does not leave by itself: waiting longer cannot help. */
|
|
92
|
+
const FAILED_STATES = new Set(["INIT_FAILED", "REMOVED", "GOING_DOWN", "INACTIVE", "PAUSING", "PAUSE_FAILED", "RESTORE_FAILED"]);
|
|
93
|
+
/** The detail, or null while the branch is not there yet (a 404 or a transient failure right after the create). */
|
|
94
|
+
async function detailOrNull(c, ref) {
|
|
95
|
+
try {
|
|
96
|
+
return await c.api.get(`/branches/${encodeURIComponent(ref)}`, parseDetail);
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
if (isTransient(e) || isProviderError(e, "PROVIDER_NOT_FOUND"))
|
|
100
|
+
return null;
|
|
101
|
+
throw e;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Wait until the branch's project is `ACTIVE_HEALTHY` and return its outputs; WAIT_TIMEOUT after the deadline. */
|
|
105
|
+
async function untilReady(c, actx, b) {
|
|
106
|
+
const timeout = Number(actx.env.SPONSON_SUPABASE_TIMEOUT_MS ?? DEFAULT_READY_TIMEOUT_MS);
|
|
107
|
+
const deadline = Date.now() + timeout;
|
|
108
|
+
for (let delay = POLL_FIRST_MS;; delay = Math.min(POLL_MAX_MS, delay * 2)) {
|
|
109
|
+
const d = await detailOrNull(c, b.project_ref);
|
|
110
|
+
if (d?.status === READY)
|
|
111
|
+
return readyOutputs(b.project_ref, d);
|
|
112
|
+
if (d && FAILED_STATES.has(d.status))
|
|
113
|
+
throw new SponsonError("PROVIDER_INVALID", `supabase: branch ${b.name} (${b.project_ref}) is ${d.status} and will not come up by itself`, { adapter: ADAPTER, branch: b.project_ref, state: d.status });
|
|
114
|
+
const left = deadline - Date.now();
|
|
115
|
+
if (left <= 0)
|
|
116
|
+
throw new SponsonError("WAIT_TIMEOUT", `supabase: branch ${b.name} (${b.project_ref}) not ready after ${timeout}ms (still ${d?.status ?? "not found"}); run again to keep waiting`, { adapter: ADAPTER, branch: b.project_ref, state: d?.status ?? null });
|
|
117
|
+
actx.log(`waiting for branch ${b.name} (${d?.status ?? "not found yet"})`);
|
|
118
|
+
await sleep(Math.min(delay, left));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** What read reports: every output once the database is up; the ref and URL alone while it is coming up. */
|
|
122
|
+
async function currentOutputs(c, b) {
|
|
123
|
+
const d = await detailOrNull(c, b.project_ref);
|
|
124
|
+
return d?.status === READY ? readyOutputs(b.project_ref, d) : baseOutputs(b.project_ref);
|
|
125
|
+
}
|
|
126
|
+
/** After a refused create: the branch, when the refusal was "that name exists" (assumption S5); else the error. */
|
|
127
|
+
async function recoverCreate(c, name, e) {
|
|
128
|
+
const refused = isProviderError(e, "PROVIDER_INVALID") && (e.details.status === 400 || e.details.status === 422);
|
|
129
|
+
if (!isProviderError(e, "PROVIDER_CONFLICT") && !refused)
|
|
130
|
+
throw e;
|
|
131
|
+
const found = findBranch(await listBranches(c), name);
|
|
132
|
+
if (!found)
|
|
133
|
+
throw e;
|
|
134
|
+
return found;
|
|
135
|
+
}
|
|
136
|
+
const branch = {
|
|
137
|
+
outputs: {
|
|
138
|
+
project_ref: { available: "immediate" },
|
|
139
|
+
api_url: { available: "immediate" },
|
|
140
|
+
db_host: { available: "immediate" },
|
|
141
|
+
connection_string: { available: "immediate", sensitive: true },
|
|
142
|
+
},
|
|
143
|
+
defaults(params, ctx) {
|
|
144
|
+
return { name: `sponson-${ctx.env}-${ctx.scope}`, ...params };
|
|
145
|
+
},
|
|
146
|
+
async read(actx, params) {
|
|
147
|
+
if (isPendingMarker(params.name))
|
|
148
|
+
return null;
|
|
149
|
+
const c = client(actx);
|
|
150
|
+
const name = stringParam(params, "name", ADAPTER);
|
|
151
|
+
const found = findBranch(await listBranches(c), name);
|
|
152
|
+
if (!found)
|
|
153
|
+
return null;
|
|
154
|
+
return { resources: [branchRecord(found)], outputs: await currentOutputs(c, found) };
|
|
155
|
+
},
|
|
156
|
+
diff(live, params) {
|
|
157
|
+
const name = params.name;
|
|
158
|
+
if (isPendingMarker(name))
|
|
159
|
+
return [{ key: `${BRANCH_PREFIX}(pending)`, kind: "create", label: "Supabase branch", before: ABSENT, after: desiredSide(name, false) }];
|
|
160
|
+
const key = branchKey(String(name));
|
|
161
|
+
const current = live?.resources.find((r) => r.key === key);
|
|
162
|
+
if (current)
|
|
163
|
+
return [{ key, kind: "unchanged", label: current.label ?? key }];
|
|
164
|
+
return [{ key, kind: "create", label: `Supabase branch ${String(name)}`, before: ABSENT, after: desiredSide(name, false) }];
|
|
165
|
+
},
|
|
166
|
+
async apply(actx, params, live) {
|
|
167
|
+
assertNoPending(params, ADAPTER);
|
|
168
|
+
const c = client(actx);
|
|
169
|
+
const name = stringParam(params, "name", ADAPTER);
|
|
170
|
+
const key = branchKey(name);
|
|
171
|
+
const current = live?.resources.find((r) => r.key === key);
|
|
172
|
+
// Exists: no write, but wait for it, so a run that timed out waiting finishes the job and gets the outputs.
|
|
173
|
+
if (current)
|
|
174
|
+
return { resources: live.resources, outputs: await untilReady(c, actx, { name, project_ref: current.id, is_default: false }), created: [] };
|
|
175
|
+
// Announce the create before sending it: a crash or a lost response must not orphan the branch.
|
|
176
|
+
await actx.intend([key]);
|
|
177
|
+
actx.log(`create branch ${name} of project ${c.project}`);
|
|
178
|
+
let b;
|
|
179
|
+
let created = [key];
|
|
180
|
+
try {
|
|
181
|
+
b = await c.api.post(`/projects/${encodeURIComponent(c.project)}/branches`, { branch_name: name }, (body) => parseBranches([body], "the created branch")[0]);
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
// It exists already: someone else's, or ours from an attempt whose answer was lost. Not created by this
|
|
185
|
+
// call; the engine claims it when an earlier intent of ours named it.
|
|
186
|
+
b = await recoverCreate(c, name, e);
|
|
187
|
+
created = [];
|
|
188
|
+
}
|
|
189
|
+
return { resources: [branchRecord(b)], outputs: await untilReady(c, actx, b), created };
|
|
190
|
+
},
|
|
191
|
+
async destroy(actx, resources) {
|
|
192
|
+
const c = client(actx);
|
|
193
|
+
for (const r of resources) {
|
|
194
|
+
// Never the parent project itself, whatever a ledger says.
|
|
195
|
+
if (r.id === c.project)
|
|
196
|
+
continue;
|
|
197
|
+
await deleteIgnoringNotFound(c.api, `/branches/${encodeURIComponent(r.id)}`);
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
/** Every branch but the project's default one: anything else may be a preview branch some scope (or nobody) manages. */
|
|
201
|
+
async listScope(actx) {
|
|
202
|
+
return (await listBranches(client(actx))).filter((b) => !b.is_default).map(branchRecord);
|
|
203
|
+
},
|
|
204
|
+
/** One line per branch, naming it: the line then manages exactly that branch. */
|
|
205
|
+
adopt(resources) {
|
|
206
|
+
return resources.map((r) => {
|
|
207
|
+
const name = r.key.slice(BRANCH_PREFIX.length);
|
|
208
|
+
return { id: `db-${name}`, params: { name }, keys: [r.key] };
|
|
209
|
+
});
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
// auth_redirect
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
const REDIRECT_PREFIX = "redirect:";
|
|
216
|
+
function target(actx, params) {
|
|
217
|
+
const c = client(actx);
|
|
218
|
+
if (params.project === undefined || params.project === null || params.project === "")
|
|
219
|
+
return { c, explicit: false };
|
|
220
|
+
return { c: { ...c, project: stringParam(params, "project", ADAPTER) }, explicit: true };
|
|
221
|
+
}
|
|
222
|
+
/** `redirect:<url>` on the provider block's project; `redirect:<ref>:<url>` on a project the line names. */
|
|
223
|
+
function redirectKey(url, project) {
|
|
224
|
+
return project ? `${REDIRECT_PREFIX}${project}:${url}` : `${REDIRECT_PREFIX}${url}`;
|
|
225
|
+
}
|
|
226
|
+
/** The id carries the project (`<ref>:<url>`; a ref has no colon), so destroy knows whose list to edit. */
|
|
227
|
+
function redirectRecord(t, url) {
|
|
228
|
+
return { key: redirectKey(url, t.explicit ? t.c.project : undefined), id: `${t.c.project}:${url}`, hash: sha256(url), label: `Supabase Auth redirect ${url}` };
|
|
229
|
+
}
|
|
230
|
+
/** Destroy's input: the URLs to remove, grouped by project, from the records' ids. */
|
|
231
|
+
function byProject(resources) {
|
|
232
|
+
const out = new Map();
|
|
233
|
+
for (const r of resources) {
|
|
234
|
+
const i = r.id.indexOf(":");
|
|
235
|
+
const project = r.id.slice(0, i);
|
|
236
|
+
out.set(project, (out.get(project) ?? new Set()).add(r.id.slice(i + 1)));
|
|
237
|
+
}
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
const AUTH_CONFIG = (c) => `/projects/${encodeURIComponent(c.project)}/config/auth`;
|
|
241
|
+
/** `uri_allow_list` from the auth config (assumption S7): a nullable string; null means empty. */
|
|
242
|
+
function parseAllowList(body) {
|
|
243
|
+
const v = obj(body, "the auth config").uri_allow_list;
|
|
244
|
+
if (v === null || v === undefined)
|
|
245
|
+
return "";
|
|
246
|
+
if (typeof v !== "string")
|
|
247
|
+
throw new ShapeError(`expected \`uri_allow_list\` to be a string or null, got ${typeof v}`);
|
|
248
|
+
return v;
|
|
249
|
+
}
|
|
250
|
+
/** The entries of an allow-list string: comma-separated, whitespace around them ignored (assumption S8). */
|
|
251
|
+
function entriesOf(list) {
|
|
252
|
+
return list
|
|
253
|
+
.split(",")
|
|
254
|
+
.map((s) => s.trim())
|
|
255
|
+
.filter((s) => s !== "");
|
|
256
|
+
}
|
|
257
|
+
async function readAllowList(c) {
|
|
258
|
+
return c.api.get(AUTH_CONFIG(c), parseAllowList);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Replace the whole allow-list. PATCH carrying only `uri_allow_list` sets that one field (S7), so sending it twice
|
|
262
|
+
* is harmless: `idempotent` lets the client retry it after a dropped connection.
|
|
263
|
+
*/
|
|
264
|
+
async function writeAllowList(c, list) {
|
|
265
|
+
await c.api.patch(AUTH_CONFIG(c), { uri_allow_list: list }, (body) => obj(body, "the auth config"), { idempotent: true });
|
|
266
|
+
}
|
|
267
|
+
/** The URL param: one allow-list entry, so no comma (it would split into two) and no surrounding whitespace. */
|
|
268
|
+
function urlParam(params) {
|
|
269
|
+
const url = stringParam(params, "url", ADAPTER);
|
|
270
|
+
if (url.includes(","))
|
|
271
|
+
throw paramError(ADAPTER, `url \`${url}\` contains a comma; the allow-list is comma-separated`, "url");
|
|
272
|
+
if (url.trim() !== url)
|
|
273
|
+
throw paramError(ADAPTER, "url has leading or trailing whitespace", "url");
|
|
274
|
+
return url;
|
|
275
|
+
}
|
|
276
|
+
function conflict(c, what) {
|
|
277
|
+
return new SponsonError("PROVIDER_CONFLICT", `supabase: the Auth allow-list of project ${c.project} changed under every one of ${LIST_ATTEMPTS} attempts to ${what}; another writer is editing it`, { adapter: ADAPTER, project: c.project });
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Add `url` unless present: read, append, write, re-read. There is no precondition to make the write
|
|
281
|
+
* conditional (S7); Sponson's own writers are serialised by the parent lock (`lockOn`), so only a writer outside
|
|
282
|
+
* Sponson (the dashboard) can overwrite ours, and the re-read notices that and repeats the round.
|
|
283
|
+
* Returns whether this call wrote it.
|
|
284
|
+
*/
|
|
285
|
+
async function addEntry(c, actx, url) {
|
|
286
|
+
let wrote = false;
|
|
287
|
+
for (let attempt = 0;; attempt++) {
|
|
288
|
+
const list = await readAllowList(c);
|
|
289
|
+
if (entriesOf(list).includes(url))
|
|
290
|
+
return wrote;
|
|
291
|
+
if (attempt === LIST_ATTEMPTS)
|
|
292
|
+
throw conflict(c, `add ${url}`);
|
|
293
|
+
actx.log(`allow redirect ${url}`);
|
|
294
|
+
// Appending keeps every other entry exactly as written.
|
|
295
|
+
await writeAllowList(c, list.trim() === "" ? url : `${list.replace(/[\s,]+$/, "")},${url}`);
|
|
296
|
+
wrote = true;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/** Remove exactly `urls` (and nothing else) from the allow-list, then re-read to confirm. */
|
|
300
|
+
async function removeEntries(c, actx, urls) {
|
|
301
|
+
for (let attempt = 0;; attempt++) {
|
|
302
|
+
const entries = entriesOf(await readAllowList(c));
|
|
303
|
+
if (!entries.some((u) => urls.has(u)))
|
|
304
|
+
return;
|
|
305
|
+
if (attempt === LIST_ATTEMPTS)
|
|
306
|
+
throw conflict(c, "remove entries");
|
|
307
|
+
actx.log(`remove redirects ${[...urls].filter((u) => entries.includes(u)).join(", ")}`);
|
|
308
|
+
await writeAllowList(c, entries.filter((u) => !urls.has(u)).join(","));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* The allow-list is one field of one project's Auth config, written whole by every scope and environment that adds a
|
|
313
|
+
* URL to it: the engine serialises Sponson's writers with a lock on it (ADR 0019). Named by the project's ref only
|
|
314
|
+
* (`supabase:<ref>:auth-uri-allow-list`), never the token. Null while the project is not known yet.
|
|
315
|
+
*/
|
|
316
|
+
function authAllowListLock(params, provider) {
|
|
317
|
+
const explicit = params.project !== undefined && params.project !== null && params.project !== "";
|
|
318
|
+
const project = explicit ? params.project : provider.project;
|
|
319
|
+
if (typeof project !== "string" || project === "" || markerKind(project) !== null)
|
|
320
|
+
return null;
|
|
321
|
+
return `${ADAPTER}:${project}:auth-uri-allow-list`;
|
|
322
|
+
}
|
|
323
|
+
const auth_redirect = {
|
|
324
|
+
outputs: { url: { available: "immediate" } },
|
|
325
|
+
lockOn: authAllowListLock,
|
|
326
|
+
async read(actx, params) {
|
|
327
|
+
// The URL or the project may come from a line not applied yet: nothing to read.
|
|
328
|
+
if (isPendingMarker(params.url) || isPendingMarker(params.project))
|
|
329
|
+
return null;
|
|
330
|
+
const url = urlParam(params);
|
|
331
|
+
const t = target(actx, params);
|
|
332
|
+
if (!entriesOf(await readAllowList(t.c)).includes(url))
|
|
333
|
+
return null;
|
|
334
|
+
return { resources: [redirectRecord(t, url)], outputs: { url } };
|
|
335
|
+
},
|
|
336
|
+
diff(live, params) {
|
|
337
|
+
const { url, project } = params;
|
|
338
|
+
const pending = isPendingMarker(url) || isPendingMarker(project);
|
|
339
|
+
const key = pending ? `${REDIRECT_PREFIX}(pending)` : redirectKey(String(url), typeof project === "string" && project !== "" ? project : undefined);
|
|
340
|
+
const current = live?.resources.find((r) => r.key === key);
|
|
341
|
+
return [diffValue({ key, label: "Supabase Auth redirect", live: current, desired: url, sensitive: false, liveValue: String(url) })];
|
|
342
|
+
},
|
|
343
|
+
async apply(actx, params, live) {
|
|
344
|
+
assertNoPending(params, ADAPTER);
|
|
345
|
+
const url = urlParam(params);
|
|
346
|
+
const t = target(actx, params);
|
|
347
|
+
const record = redirectRecord(t, url);
|
|
348
|
+
if (live?.resources.some((r) => r.key === record.key))
|
|
349
|
+
return { resources: live.resources, outputs: live.outputs, created: [] };
|
|
350
|
+
await actx.intend([record.key]);
|
|
351
|
+
// Already listed (someone else's, or ours from a run whose answer was lost): not created by this call.
|
|
352
|
+
const wrote = await addEntry(t.c, actx, url);
|
|
353
|
+
const state = { resources: [record], outputs: { url } };
|
|
354
|
+
return { ...state, created: wrote ? [record.key] : [] };
|
|
355
|
+
},
|
|
356
|
+
async destroy(actx, resources) {
|
|
357
|
+
const base = client(actx);
|
|
358
|
+
for (const [project, urls] of byProject(resources)) {
|
|
359
|
+
try {
|
|
360
|
+
await removeEntries({ ...base, project }, actx, urls);
|
|
361
|
+
}
|
|
362
|
+
catch (e) {
|
|
363
|
+
// A branch's project deleted first takes its allow-list with it: already gone.
|
|
364
|
+
if (!isProviderError(e, "PROVIDER_NOT_FOUND"))
|
|
365
|
+
throw e;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
/** Every URL on the provider block's project's allow-list. */
|
|
370
|
+
async listScope(actx) {
|
|
371
|
+
const t = { c: client(actx), explicit: false };
|
|
372
|
+
return entriesOf(await readAllowList(t.c)).map((url) => redirectRecord(t, url));
|
|
373
|
+
},
|
|
374
|
+
/** One line per allowed URL. */
|
|
375
|
+
adopt(resources) {
|
|
376
|
+
return resources.map((r) => ({ id: "auth_redirect", params: { url: r.key.slice(REDIRECT_PREFIX.length) }, keys: [r.key] }));
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
/**
|
|
380
|
+
* The Supabase adapter (`adapter: supabase` in a plan): op `branch` (a preview branch per scope, with its
|
|
381
|
+
* connection string as a sensitive output) and op `auth_redirect` (one URL in the project's Auth redirect
|
|
382
|
+
* allow-list). Needs `SUPABASE_ACCESS_TOKEN` and `providers.supabase.project` (the parent project's ref).
|
|
383
|
+
*/
|
|
384
|
+
export const supabaseAdapter = { name: ADAPTER, ops: { branch, auth_redirect }, about: ABOUT };
|
|
385
|
+
//# sourceMappingURL=supabase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supabase.js","sourceRoot":"","sources":["../src/supabase.ts"],"names":[],"mappings":"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"}
|
package/dist/vercel.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ResourceAdapter } from "@sponson/core";
|
|
2
|
+
/** Vercel's API base URL; `VERCEL_API_URL` overrides it (the sim and tests use that). */
|
|
3
|
+
export declare const VERCEL_DEFAULT_API_URL = "https://api.vercel.com";
|
|
4
|
+
/**
|
|
5
|
+
* Vercel: op `env` manages environment variables per target and git branch; op `deploy` triggers or watches a
|
|
6
|
+
* deployment and outputs its `preview_url`. Needs `VERCEL_TOKEN` and `providers.vercel.project`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const vercelAdapter: ResourceAdapter;
|