@sponson/sim 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 +5 -0
- package/dist/auth.d.ts +60 -0
- package/dist/auth.js +195 -0
- package/dist/auth.js.map +1 -0
- package/dist/bin.js +9 -14
- package/dist/bin.js.map +1 -1
- package/dist/chaos.d.ts +4 -0
- package/dist/chaos.js +2 -0
- package/dist/chaos.js.map +1 -1
- package/dist/cli.d.ts +29 -0
- package/dist/cli.js +99 -0
- package/dist/cli.js.map +1 -0
- package/dist/demo.d.ts +39 -0
- package/dist/demo.js +168 -0
- package/dist/demo.js.map +1 -0
- package/dist/graphql.d.ts +22 -0
- package/dist/graphql.js +36 -0
- package/dist/graphql.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/provider.d.ts +43 -4
- package/dist/provider.js +12 -6
- package/dist/provider.js.map +1 -1
- package/dist/routes/algolia.d.ts +37 -0
- package/dist/routes/algolia.js +83 -0
- package/dist/routes/algolia.js.map +1 -0
- package/dist/routes/aws.d.ts +43 -0
- package/dist/routes/aws.js +211 -0
- package/dist/routes/aws.js.map +1 -0
- package/dist/routes/cloudflare.d.ts +80 -0
- package/dist/routes/cloudflare.js +176 -0
- package/dist/routes/cloudflare.js.map +1 -0
- package/dist/routes/digitalocean.d.ts +58 -0
- package/dist/routes/digitalocean.js +158 -0
- package/dist/routes/digitalocean.js.map +1 -0
- package/dist/routes/fly.d.ts +22 -0
- package/dist/routes/fly.js +113 -0
- package/dist/routes/fly.js.map +1 -0
- package/dist/routes/launchdarkly.d.ts +98 -0
- package/dist/routes/launchdarkly.js +213 -0
- package/dist/routes/launchdarkly.js.map +1 -0
- package/dist/routes/netlify.d.ts +126 -0
- package/dist/routes/netlify.js +347 -0
- package/dist/routes/netlify.js.map +1 -0
- package/dist/routes/planetscale.d.ts +95 -0
- package/dist/routes/planetscale.js +234 -0
- package/dist/routes/planetscale.js.map +1 -0
- package/dist/routes/railway.d.ts +24 -0
- package/dist/routes/railway.js +112 -0
- package/dist/routes/railway.js.map +1 -0
- package/dist/routes/rest.d.ts +138 -0
- package/dist/routes/rest.js +462 -0
- package/dist/routes/rest.js.map +1 -0
- package/dist/routes/supabase.d.ts +103 -0
- package/dist/routes/supabase.js +234 -0
- package/dist/routes/supabase.js.map +1 -0
- package/dist/routes/xata.d.ts +57 -0
- package/dist/routes/xata.js +115 -0
- package/dist/routes/xata.js.map +1 -0
- package/dist/server.js +71 -12
- package/dist/server.js.map +1 -1
- package/dist/state.d.ts +12 -0
- package/dist/state.js +13 -1
- package/dist/state.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simulated Supabase Management API (https://api.supabase.com/v1): preview branches of a project, and the project's
|
|
3
|
+
* Auth redirect allow-list.
|
|
4
|
+
*
|
|
5
|
+
* Assumptions about the real API that this fake encodes, each marked with how far it is checked. "Verified" means
|
|
6
|
+
* against Supabase's published OpenAPI document (https://api.supabase.com/api/v1-json, fetched 2026-10-11; rendered
|
|
7
|
+
* at https://supabase.com/docs/reference/api/introduction) unless another source is named; see
|
|
8
|
+
* docs/api-verification.md:
|
|
9
|
+
* S1. POST /v1/projects/{ref}/branches takes `{ branch_name }` (required, the only required field) and answers
|
|
10
|
+
* 201 with a BranchResponse: `id` (uuid), `name` (= branch_name), `project_ref` (the branch's own project),
|
|
11
|
+
* `parent_project_ref`, `is_default`, `persistent`, `status`, `created_at` (verified: CreateBranchBody,
|
|
12
|
+
* BranchResponse). That `project_ref` is known in the 201 answer, before provisioning finishes, is implied by
|
|
13
|
+
* the schema (required) but unverified.
|
|
14
|
+
* S2. GET /v1/projects/{ref}/branches answers a bare array of BranchResponse, unpaged (verified: no page
|
|
15
|
+
* parameters, `type: array`). That the list includes the project's own default branch (`is_default: true`,
|
|
16
|
+
* `project_ref` = the parent) once branching is enabled is unverified; the adapter skips `is_default` either
|
|
17
|
+
* way and never manages it.
|
|
18
|
+
* S3. A branch is provisioned asynchronously: GET /v1/branches/{ref} answers BranchDetailResponse whose `status`
|
|
19
|
+
* (the project status enum) is `COMING_UP` until it is ready and `ACTIVE_HEALTHY` after (verified: schema and
|
|
20
|
+
* enum). Here this takes chaos `supabase_ready_ms` (default 0). That the detail answers 200 (not 404) while
|
|
21
|
+
* the branch is coming up, and that `ACTIVE_HEALTHY` is the right "ready" signal, are unverified: needs a
|
|
22
|
+
* live account. The BranchResponse `status` (CREATING_PROJECT, …) is deprecated in the spec and not used.
|
|
23
|
+
* S4. The detail carries `db_host`, `db_port` (required), `db_user` and `db_pass` (optional in the spec,
|
|
24
|
+
* verified). That `db_pass` is returned to a personal access token is unverified (pinned by the contract
|
|
25
|
+
* suite). The database is `postgres` (Supabase's default database name, verified in the connection docs,
|
|
26
|
+
* https://supabase.com/docs/guides/database/connecting-to-postgres) and the API URL is
|
|
27
|
+
* `https://<ref>.supabase.co` (verified: https://supabase.com/docs/guides/api).
|
|
28
|
+
* S5. Creating a branch whose name exists in the project answers 409. Unverified: the spec documents only 201,
|
|
29
|
+
* 401, 403, 429 and 500. The adapter re-reads the list after a 409, or a 400/422, before reporting it.
|
|
30
|
+
* S6. DELETE /v1/branches/{ref} answers 200 `{ message: "ok" }` and the branch is gone from the list at once
|
|
31
|
+
* (verified: BranchDeleteResponse; "by default, deletes immediately"). An unknown ref answers 404:
|
|
32
|
+
* unverified (the spec documents no 404).
|
|
33
|
+
* S7. GET /v1/projects/{ref}/config/auth answers the auth config with `uri_allow_list`, a nullable string
|
|
34
|
+
* (verified: AuthConfigResponse, required); PATCH with `{ uri_allow_list }` alone sets that field and
|
|
35
|
+
* leaves the others, answering the whole config (verified: UpdateAuthConfigBody has no required field).
|
|
36
|
+
* PATCH offers no precondition (no ETag or version), verified by its absence from the spec.
|
|
37
|
+
* S8. The allow-list is comma-separated URLs (verified: Supabase Auth's `URI_ALLOW_LIST`, "a comma separated
|
|
38
|
+
* list of URIs", https://github.com/supabase/auth#general-config). Whitespace around commas is ignored by
|
|
39
|
+
* Auth; whether the API stores the string verbatim (here: yes) is unverified.
|
|
40
|
+
* S9. A preview branch is a project with its own Auth config, read and written through the same
|
|
41
|
+
* /v1/projects/{ref}/config/auth with the branch's ref (`project_ref` is a "Project ref" in the spec,
|
|
42
|
+
* verified; branches have "their own Supabase instance and API credentials", verified in
|
|
43
|
+
* https://supabase.com/docs/guides/deployment/branching). That the endpoint accepts a branch's ref, and
|
|
44
|
+
* what the branch's allow-list starts as (here: empty), are unverified.
|
|
45
|
+
*/
|
|
46
|
+
import { Reply, route, router } from "../provider.js";
|
|
47
|
+
/** The parent project the default seed creates, a ref of 20 lowercase letters like Supabase's. */
|
|
48
|
+
export const SUPABASE_DEMO_PROJECT = "demoprojectrefabcdef";
|
|
49
|
+
/** The simulated Supabase Management API, registered in `PROVIDERS` (packages/sim/src/state.ts), served under `/supabase`. */
|
|
50
|
+
export const supabaseSim = {
|
|
51
|
+
env: { token: "SUPABASE_ACCESS_TOKEN", url: "SUPABASE_API_URL", testToken: "tok_supabase" },
|
|
52
|
+
defaultSeed: { projects: { [SUPABASE_DEMO_PROJECT]: { uri_allow_list: "http://localhost:3000/**" } } },
|
|
53
|
+
reset(core, seed) {
|
|
54
|
+
const projects = {};
|
|
55
|
+
for (const [ref, p] of Object.entries(seed?.projects ?? {})) {
|
|
56
|
+
const project = { branches: [], auth: { site_url: p.site_url ?? "http://localhost:3000", uri_allow_list: p.uri_allow_list ?? null } };
|
|
57
|
+
projects[ref] = project;
|
|
58
|
+
// With branching enabled the project itself is listed as its default branch (assumption S2).
|
|
59
|
+
project.branches.push({ ...newSupabaseBranch(core, ref, "main", "sim"), project_ref: ref, is_default: true });
|
|
60
|
+
for (const b of p.branches ?? [])
|
|
61
|
+
project.branches.push(newSupabaseBranch(core, ref, b.name, "sim"));
|
|
62
|
+
}
|
|
63
|
+
return { projects };
|
|
64
|
+
},
|
|
65
|
+
/**
|
|
66
|
+
* `branch.<name>`: "delete" | "recreate" (same name, new ref). `redirect.<url>`: "delete" | "add" — what a human
|
|
67
|
+
* in the Supabase dashboard would do. `supabase:<ref>.` limits either to one project.
|
|
68
|
+
*/
|
|
69
|
+
drift(core, state, { key, rest, value, only }) {
|
|
70
|
+
const projects = Object.entries(state.projects).filter(([ref]) => only === undefined || ref === only);
|
|
71
|
+
if (rest.startsWith("branch."))
|
|
72
|
+
return driftBranch(core, projects, key, rest.slice("branch.".length), value);
|
|
73
|
+
if (rest.startsWith("redirect."))
|
|
74
|
+
return driftRedirect(projects, key, rest.slice("redirect.".length), value);
|
|
75
|
+
return false;
|
|
76
|
+
},
|
|
77
|
+
routes(core, state, req) {
|
|
78
|
+
return routes(core, state, req);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
function driftBranch(core, projects, key, name, value) {
|
|
82
|
+
if (value !== "delete" && value !== "recreate")
|
|
83
|
+
throw new Error(`drift ${key}: only "delete" and "recreate" are supported`);
|
|
84
|
+
for (const [ref, p] of projects) {
|
|
85
|
+
const hit = p.branches.filter((b) => b.name === name && !b.is_default);
|
|
86
|
+
p.branches = p.branches.filter((b) => !hit.includes(b));
|
|
87
|
+
if (value === "recreate")
|
|
88
|
+
for (const b of hit)
|
|
89
|
+
p.branches.push(newSupabaseBranch(core, ref, b.name, "sim"));
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
function driftRedirect(projects, key, url, value) {
|
|
94
|
+
if (value !== "delete" && value !== "add")
|
|
95
|
+
throw new Error(`drift ${key}: only "delete" and "add" are supported`);
|
|
96
|
+
for (const [, p] of projects) {
|
|
97
|
+
const rest = supabaseAllowList(p).filter((u) => u !== url);
|
|
98
|
+
p.auth.uri_allow_list = (value === "add" ? [...rest, url] : rest).join(",");
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
/** The allow-list's entries: comma-separated, whitespace around them ignored (assumption S8). */
|
|
103
|
+
export function supabaseAllowList(p) {
|
|
104
|
+
return (p.auth.uri_allow_list ?? "")
|
|
105
|
+
.split(",")
|
|
106
|
+
.map((s) => s.trim())
|
|
107
|
+
.filter((s) => s !== "");
|
|
108
|
+
}
|
|
109
|
+
/** The Management API, one route per method and path. Errors are `{ message }`, as Supabase's are. */
|
|
110
|
+
const routes = router([
|
|
111
|
+
route("GET", "/projects/:ref/branches", ({ state, params }) => {
|
|
112
|
+
const p = state.projects[params.ref];
|
|
113
|
+
return p ? new Reply(200, p.branches.map(publicBranch)) : notFound("project");
|
|
114
|
+
}),
|
|
115
|
+
route("POST", "/projects/:ref/branches", ({ core, state, params, body }) => {
|
|
116
|
+
const p = state.projects[params.ref];
|
|
117
|
+
if (!p)
|
|
118
|
+
return notFound("project");
|
|
119
|
+
const name = (body ?? {}).branch_name;
|
|
120
|
+
if (typeof name !== "string" || name === "")
|
|
121
|
+
return new Reply(400, { message: "branch_name must be a non-empty string" });
|
|
122
|
+
if (p.branches.some((b) => b.name === name))
|
|
123
|
+
return new Reply(409, { message: `Branch ${name} already exists` });
|
|
124
|
+
const b = newSupabaseBranch(core, params.ref, name, "api");
|
|
125
|
+
b.readyAt = Date.now() + core.chaos.supabase_ready_ms;
|
|
126
|
+
p.branches.push(b);
|
|
127
|
+
return new Reply(201, publicBranch(b));
|
|
128
|
+
}),
|
|
129
|
+
route("GET", "/branches/:ref", ({ state, params }) => {
|
|
130
|
+
const b = branchByRef(state, params.ref);
|
|
131
|
+
return b ? new Reply(200, branchDetail(b)) : notFound("branch");
|
|
132
|
+
}),
|
|
133
|
+
route("DELETE", "/branches/:ref", ({ state, params }) => {
|
|
134
|
+
const b = branchByRef(state, params.ref);
|
|
135
|
+
if (!b)
|
|
136
|
+
return notFound("branch");
|
|
137
|
+
if (b.is_default)
|
|
138
|
+
return new Reply(400, { message: "the default branch cannot be deleted" });
|
|
139
|
+
const p = state.projects[b.parent_project_ref];
|
|
140
|
+
p.branches = p.branches.filter((x) => x !== b);
|
|
141
|
+
return new Reply(200, { message: "ok" });
|
|
142
|
+
}),
|
|
143
|
+
route("GET", "/projects/:ref/config/auth", ({ state, params }) => {
|
|
144
|
+
const a = authOf(state, params.ref);
|
|
145
|
+
return a ? new Reply(200, authConfig(a)) : notFound("project");
|
|
146
|
+
}),
|
|
147
|
+
route("PATCH", "/projects/:ref/config/auth", ({ state, params, body }) => {
|
|
148
|
+
const a = authOf(state, params.ref);
|
|
149
|
+
if (!a)
|
|
150
|
+
return notFound("project");
|
|
151
|
+
const b = (body ?? {});
|
|
152
|
+
if (b.uri_allow_list !== undefined && b.uri_allow_list !== null && typeof b.uri_allow_list !== "string")
|
|
153
|
+
return new Reply(400, { message: "uri_allow_list must be a string" });
|
|
154
|
+
if (b.uri_allow_list !== undefined)
|
|
155
|
+
a.uri_allow_list = b.uri_allow_list;
|
|
156
|
+
if (typeof b.site_url === "string")
|
|
157
|
+
a.site_url = b.site_url;
|
|
158
|
+
return new Reply(200, authConfig(a));
|
|
159
|
+
}),
|
|
160
|
+
], () => notFound("route"));
|
|
161
|
+
/** A branch by its own project ref, in any project. */
|
|
162
|
+
function branchByRef(state, ref) {
|
|
163
|
+
for (const p of Object.values(state.projects)) {
|
|
164
|
+
const b = p.branches.find((x) => x.project_ref === ref);
|
|
165
|
+
if (b)
|
|
166
|
+
return b;
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* A new (not yet added) branch of project `parent`, ready at once. Tests use it to seed "someone else's" branch.
|
|
172
|
+
* Refs are 20 lowercase letters, deterministic after a reset.
|
|
173
|
+
*/
|
|
174
|
+
export function newSupabaseBranch(core, parent, name, createdBy) {
|
|
175
|
+
const n = core.nextId("");
|
|
176
|
+
const ref = `br${[...n].map((d) => "abcdefghij"[Number(d)]).join("")}`.padEnd(20, "x");
|
|
177
|
+
return {
|
|
178
|
+
id: `00000000-0000-4000-8000-${n.padStart(12, "0")}`,
|
|
179
|
+
name,
|
|
180
|
+
project_ref: ref,
|
|
181
|
+
parent_project_ref: parent,
|
|
182
|
+
is_default: false,
|
|
183
|
+
readyAt: 0,
|
|
184
|
+
db_pass: `pw_${ref}`,
|
|
185
|
+
auth: { site_url: "http://localhost:3000", uri_allow_list: null },
|
|
186
|
+
created_at: new Date().toISOString(),
|
|
187
|
+
createdAt: Date.now(),
|
|
188
|
+
createdBy,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/** The connection string the adapter builds from a branch's detail (assumption S4). */
|
|
192
|
+
export function supabaseConnectionString(b) {
|
|
193
|
+
return `postgresql://postgres:${b.db_pass}@db.${b.project_ref}.supabase.co:5432/postgres`;
|
|
194
|
+
}
|
|
195
|
+
function publicBranch(b) {
|
|
196
|
+
const ready = Date.now() >= b.readyAt;
|
|
197
|
+
return {
|
|
198
|
+
id: b.id,
|
|
199
|
+
name: b.name,
|
|
200
|
+
project_ref: b.project_ref,
|
|
201
|
+
parent_project_ref: b.parent_project_ref,
|
|
202
|
+
is_default: b.is_default,
|
|
203
|
+
persistent: b.is_default,
|
|
204
|
+
status: ready ? "FUNCTIONS_DEPLOYED" : "CREATING_PROJECT",
|
|
205
|
+
preview_project_status: ready ? "ACTIVE_HEALTHY" : "COMING_UP",
|
|
206
|
+
with_data: false,
|
|
207
|
+
created_at: b.created_at,
|
|
208
|
+
updated_at: b.created_at,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function branchDetail(b) {
|
|
212
|
+
return {
|
|
213
|
+
ref: b.project_ref,
|
|
214
|
+
postgres_version: "17.4.1",
|
|
215
|
+
postgres_engine: "17",
|
|
216
|
+
release_channel: "ga",
|
|
217
|
+
status: Date.now() >= b.readyAt ? "ACTIVE_HEALTHY" : "COMING_UP",
|
|
218
|
+
db_host: `db.${b.project_ref}.supabase.co`,
|
|
219
|
+
db_port: 5432,
|
|
220
|
+
db_user: "postgres",
|
|
221
|
+
db_pass: b.db_pass,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/** The Auth config of a project ref: a parent project's, or a preview branch's own (assumption S9). */
|
|
225
|
+
function authOf(state, ref) {
|
|
226
|
+
return state.projects[ref]?.auth ?? branchByRef(state, ref)?.auth;
|
|
227
|
+
}
|
|
228
|
+
function authConfig(a) {
|
|
229
|
+
return { site_url: a.site_url, uri_allow_list: a.uri_allow_list, disable_signup: false, jwt_exp: 3600 };
|
|
230
|
+
}
|
|
231
|
+
function notFound(what) {
|
|
232
|
+
return new Reply(404, { message: `${what} not found` });
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=supabase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supabase.js","sourceRoot":"","sources":["../../src/routes/supabase.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simulated Xata (the Postgres platform): branches of projects, created as copy-on-write children of a parent.
|
|
3
|
+
*
|
|
4
|
+
* Assumptions about the real API this fake encodes, checked against the official OpenAPI document
|
|
5
|
+
* (https://api.xata.tech/openapi.json) and the docs (https://xata.io/docs) unless marked unverified. The critical
|
|
6
|
+
* ones are pinned in scenarios/contract.test.ts (`assumption XA…`).
|
|
7
|
+
* XA1. The API is served at `https://api.xata.tech`, authenticated with an API key as `Authorization: Bearer`;
|
|
8
|
+
* the CLI reads it from `XATA_API_KEY`. (verified: spec security scheme; https://xata.io/docs/cli)
|
|
9
|
+
* XA2. `POST /organizations/{org}/projects/{project}/branches` with `{ mode: "inherit", parentID, name }`
|
|
10
|
+
* creates a copy-on-write child of the parent branch (by id) and answers 201 with the branch, bare:
|
|
11
|
+
* `{ id, name, parentID, region, createdAt, … }`. (verified: spec)
|
|
12
|
+
* XA3. `GET` of the same path answers `{ branches: [{ id, name, parentID, … }] }`, unpaginated. Names are not
|
|
13
|
+
* documented as unique and the create documents no 409, so a lookup by name may find more than one.
|
|
14
|
+
* (verified: spec; uniqueness unverified)
|
|
15
|
+
* XA4. `GET …/branches/{branchID}` answers the branch with `status: { statusType, … }`, and 404 when it does
|
|
16
|
+
* not exist; `DELETE` on the same path removes it permanently (204; 404 when gone). (verified: spec)
|
|
17
|
+
* XA5. A new branch "takes a moment to come up"; it is ready when `statusType` is healthy and broken when it is
|
|
18
|
+
* a fault (`STATUS_TYPE_HEALTHY`, `STATUS_TYPE_FAULT`; the adapter matches the suffix). (verified: the CLI's
|
|
19
|
+
* `branch wait-ready`, https://xata.io/docs/cli/branch; the exact enum spelling is unverified)
|
|
20
|
+
* XA6. `GET …/branches/{branchID}/credentials?username=xata` answers `{ username, password, hostname, port,
|
|
21
|
+
* dbname, connectionString }`, readable at any time (not only after the create). (verified: spec and
|
|
22
|
+
* https://xata.io/docs/platform/branch; "any time" inferred from it being a plain GET)
|
|
23
|
+
* XA7. A branch is ready within minutes, usually seconds (unverified: the adapter waits up to
|
|
24
|
+
* SPONSON_XATA_READY_TIMEOUT_MS, ten minutes by default).
|
|
25
|
+
*/
|
|
26
|
+
import { type CreatedBy, type ProviderSim } from "../provider.js";
|
|
27
|
+
/** A branch as the simulated Xata stores it. */
|
|
28
|
+
export interface XataBranch {
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
parentID: string | null;
|
|
32
|
+
password: string;
|
|
33
|
+
/** GETs of the branch that still answer a transient status before it is healthy. */
|
|
34
|
+
pending: number;
|
|
35
|
+
createdBy: CreatedBy;
|
|
36
|
+
}
|
|
37
|
+
/** The simulated Xata's state: branches per `<org>/<project>`. */
|
|
38
|
+
export interface XataState {
|
|
39
|
+
projects: Record<string, {
|
|
40
|
+
branches: XataBranch[];
|
|
41
|
+
}>;
|
|
42
|
+
/** GETs of a new branch that answer a transient status (default 1). */
|
|
43
|
+
readyPolls: number;
|
|
44
|
+
}
|
|
45
|
+
/** What a scenario or test seeds the simulated Xata with (`seed: { xata: … }`). */
|
|
46
|
+
export interface XataSeed {
|
|
47
|
+
/** `<org>/<project>` → branches that exist already (unmanaged), by id and name. */
|
|
48
|
+
projects?: Record<string, Array<{
|
|
49
|
+
id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
}>>;
|
|
52
|
+
readyPolls?: number;
|
|
53
|
+
}
|
|
54
|
+
/** The simulated Xata API, registered in `PROVIDERS` (packages/sim/src/state.ts) and served under `/xata`. */
|
|
55
|
+
export declare const xataSim: ProviderSim<XataState, XataSeed>;
|
|
56
|
+
/** The connection string of a branch (XA6), as the sim makes it up. */
|
|
57
|
+
export declare function xataConnectionString(b: XataBranch): string;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simulated Xata (the Postgres platform): branches of projects, created as copy-on-write children of a parent.
|
|
3
|
+
*
|
|
4
|
+
* Assumptions about the real API this fake encodes, checked against the official OpenAPI document
|
|
5
|
+
* (https://api.xata.tech/openapi.json) and the docs (https://xata.io/docs) unless marked unverified. The critical
|
|
6
|
+
* ones are pinned in scenarios/contract.test.ts (`assumption XA…`).
|
|
7
|
+
* XA1. The API is served at `https://api.xata.tech`, authenticated with an API key as `Authorization: Bearer`;
|
|
8
|
+
* the CLI reads it from `XATA_API_KEY`. (verified: spec security scheme; https://xata.io/docs/cli)
|
|
9
|
+
* XA2. `POST /organizations/{org}/projects/{project}/branches` with `{ mode: "inherit", parentID, name }`
|
|
10
|
+
* creates a copy-on-write child of the parent branch (by id) and answers 201 with the branch, bare:
|
|
11
|
+
* `{ id, name, parentID, region, createdAt, … }`. (verified: spec)
|
|
12
|
+
* XA3. `GET` of the same path answers `{ branches: [{ id, name, parentID, … }] }`, unpaginated. Names are not
|
|
13
|
+
* documented as unique and the create documents no 409, so a lookup by name may find more than one.
|
|
14
|
+
* (verified: spec; uniqueness unverified)
|
|
15
|
+
* XA4. `GET …/branches/{branchID}` answers the branch with `status: { statusType, … }`, and 404 when it does
|
|
16
|
+
* not exist; `DELETE` on the same path removes it permanently (204; 404 when gone). (verified: spec)
|
|
17
|
+
* XA5. A new branch "takes a moment to come up"; it is ready when `statusType` is healthy and broken when it is
|
|
18
|
+
* a fault (`STATUS_TYPE_HEALTHY`, `STATUS_TYPE_FAULT`; the adapter matches the suffix). (verified: the CLI's
|
|
19
|
+
* `branch wait-ready`, https://xata.io/docs/cli/branch; the exact enum spelling is unverified)
|
|
20
|
+
* XA6. `GET …/branches/{branchID}/credentials?username=xata` answers `{ username, password, hostname, port,
|
|
21
|
+
* dbname, connectionString }`, readable at any time (not only after the create). (verified: spec and
|
|
22
|
+
* https://xata.io/docs/platform/branch; "any time" inferred from it being a plain GET)
|
|
23
|
+
* XA7. A branch is ready within minutes, usually seconds (unverified: the adapter waits up to
|
|
24
|
+
* SPONSON_XATA_READY_TIMEOUT_MS, ten minutes by default).
|
|
25
|
+
*/
|
|
26
|
+
import { Reply, route, router } from "../provider.js";
|
|
27
|
+
/** The simulated Xata API, registered in `PROVIDERS` (packages/sim/src/state.ts) and served under `/xata`. */
|
|
28
|
+
export const xataSim = {
|
|
29
|
+
env: { token: "XATA_API_KEY", url: "XATA_API_URL", testToken: "tok_xata" },
|
|
30
|
+
defaultSeed: { projects: { "acme/app": [{ id: "br_main", name: "main" }] } },
|
|
31
|
+
reset(core, seed) {
|
|
32
|
+
const projects = {};
|
|
33
|
+
for (const [key, list] of Object.entries(seed?.projects ?? {})) {
|
|
34
|
+
projects[key] = { branches: list.map((b) => ({ id: b.id, name: b.name, parentID: null, password: password(core), pending: 0, createdBy: "sim" })) };
|
|
35
|
+
}
|
|
36
|
+
return { projects, readyPolls: seed?.readyPolls ?? 1 };
|
|
37
|
+
},
|
|
38
|
+
/** `branch.<name>`: "delete" — what a human in the Xata console would do. */
|
|
39
|
+
drift(_core, state, { key, rest, value, only }) {
|
|
40
|
+
if (only !== undefined || !rest.startsWith("branch."))
|
|
41
|
+
return false;
|
|
42
|
+
const name = rest.slice("branch.".length);
|
|
43
|
+
if (value !== "delete")
|
|
44
|
+
throw new Error(`drift ${key}: only "delete" is supported`);
|
|
45
|
+
let hit = false;
|
|
46
|
+
for (const p of Object.values(state.projects)) {
|
|
47
|
+
const before = p.branches.length;
|
|
48
|
+
p.branches = p.branches.filter((b) => b.name !== name);
|
|
49
|
+
hit ||= p.branches.length < before;
|
|
50
|
+
}
|
|
51
|
+
if (!hit)
|
|
52
|
+
throw new Error(`drift ${key}: no branch ${name}`);
|
|
53
|
+
return true;
|
|
54
|
+
},
|
|
55
|
+
routes(core, state, req) {
|
|
56
|
+
return routes(core, state, req);
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
function password(core) {
|
|
60
|
+
return `xata_pw_sim_${core.nextId("")}`;
|
|
61
|
+
}
|
|
62
|
+
/** The connection string of a branch (XA6), as the sim makes it up. */
|
|
63
|
+
export function xataConnectionString(b) {
|
|
64
|
+
return `postgresql://xata:${b.password}@${b.id}.us-east-1.sim.xata.tech:5432/xata?sslmode=require`;
|
|
65
|
+
}
|
|
66
|
+
function publicBranch(b) {
|
|
67
|
+
return { id: b.id, name: b.name, parentID: b.parentID, region: "us-east-1", publicAccess: false };
|
|
68
|
+
}
|
|
69
|
+
function find(state, p) {
|
|
70
|
+
return state.projects[`${p.org}/${p.project}`]?.branches.find((b) => b.id === p.id);
|
|
71
|
+
}
|
|
72
|
+
const notFound = () => new Reply(404, { id: "not_found", message: "branch not found" });
|
|
73
|
+
const routes = router([
|
|
74
|
+
route("GET", "/organizations/:org/projects/:project/branches", ({ state, params }) => {
|
|
75
|
+
const p = state.projects[`${params.org}/${params.project}`];
|
|
76
|
+
return p ? new Reply(200, { branches: p.branches.map(publicBranch) }) : new Reply(404, { id: "not_found", message: "project not found" });
|
|
77
|
+
}),
|
|
78
|
+
route("POST", "/organizations/:org/projects/:project/branches", ({ core, state, params, body }) => {
|
|
79
|
+
const p = state.projects[`${params.org}/${params.project}`];
|
|
80
|
+
if (!p)
|
|
81
|
+
return new Reply(404, { id: "not_found", message: "project not found" });
|
|
82
|
+
const b = (body ?? {});
|
|
83
|
+
if (b.mode !== "inherit" || typeof b.name !== "string" || b.name === "" || typeof b.parentID !== "string")
|
|
84
|
+
return new Reply(400, { id: "bad_request", message: "mode inherit, parentID and name are required" });
|
|
85
|
+
if (!p.branches.some((x) => x.id === b.parentID))
|
|
86
|
+
return new Reply(404, { id: "not_found", message: "parent branch not found" });
|
|
87
|
+
const created = { id: core.nextId("br_"), name: b.name, parentID: b.parentID, password: password(core), pending: state.readyPolls, createdBy: "api" };
|
|
88
|
+
p.branches.push(created);
|
|
89
|
+
return new Reply(201, publicBranch(created));
|
|
90
|
+
}),
|
|
91
|
+
route("GET", "/organizations/:org/projects/:project/branches/:id", ({ state, params }) => {
|
|
92
|
+
const b = find(state, params);
|
|
93
|
+
if (!b)
|
|
94
|
+
return notFound();
|
|
95
|
+
const transient = b.pending > 0;
|
|
96
|
+
if (transient)
|
|
97
|
+
b.pending--;
|
|
98
|
+
return new Reply(200, { ...publicBranch(b), status: { statusType: transient ? "STATUS_TYPE_TRANSIENT" : "STATUS_TYPE_HEALTHY", instanceCount: 1, instanceReadyCount: transient ? 0 : 1 } });
|
|
99
|
+
}),
|
|
100
|
+
route("GET", "/organizations/:org/projects/:project/branches/:id/credentials", ({ state, params }) => {
|
|
101
|
+
const b = find(state, params);
|
|
102
|
+
if (!b)
|
|
103
|
+
return notFound();
|
|
104
|
+
return new Reply(200, { username: "xata", password: b.password, hostname: `${b.id}.us-east-1.sim.xata.tech`, port: 5432, dbname: "xata", connectionString: xataConnectionString(b) });
|
|
105
|
+
}),
|
|
106
|
+
route("DELETE", "/organizations/:org/projects/:project/branches/:id", ({ state, params }) => {
|
|
107
|
+
const p = state.projects[`${params.org}/${params.project}`];
|
|
108
|
+
const b = find(state, params);
|
|
109
|
+
if (!p || !b)
|
|
110
|
+
return notFound();
|
|
111
|
+
p.branches = p.branches.filter((x) => x !== b);
|
|
112
|
+
return new Reply(204, null);
|
|
113
|
+
}),
|
|
114
|
+
], notFound);
|
|
115
|
+
//# sourceMappingURL=xata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xata.js","sourceRoot":"","sources":["../../src/routes/xata.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -25,7 +25,12 @@ async function handle(state, req, res) {
|
|
|
25
25
|
const method = (req.method ?? "GET").toUpperCase();
|
|
26
26
|
const url = new URL(req.url ?? "/", "http://sim.local");
|
|
27
27
|
const raw = await readBody(req);
|
|
28
|
-
|
|
28
|
+
// Control endpoints take JSON whatever the client says: `curl -d '{…}'` labels a JSON body as a form.
|
|
29
|
+
const contentType = req.headers["content-type"] ?? "";
|
|
30
|
+
const form = !url.pathname.startsWith("/_") && contentType.startsWith("application/x-www-form-urlencoded");
|
|
31
|
+
// XML bodies reach the provider as text: only it knows the document.
|
|
32
|
+
const xml = !url.pathname.startsWith("/_") && /^[\w.+-]+\/([\w.-]+\+)?xml\b/.test(contentType);
|
|
33
|
+
const parsed = xml ? { body: raw } : form ? { body: parseForm(raw) } : parseJson(raw);
|
|
29
34
|
if (!parsed)
|
|
30
35
|
return send(res, 400, { error: "invalid json" });
|
|
31
36
|
const { body } = parsed;
|
|
@@ -33,17 +38,35 @@ async function handle(state, req, res) {
|
|
|
33
38
|
const r = control(state, state, { method, url, path: url.pathname, body });
|
|
34
39
|
return send(res, r.status, r.body);
|
|
35
40
|
}
|
|
36
|
-
// Any non-empty
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
// Any non-empty credential is accepted unless a provider's seed configures real ones; missing-token bugs must
|
|
42
|
+
// surface as 401.
|
|
43
|
+
const verdict = authorized(state, req.headers, { method, url, target: req.url ?? "/", raw });
|
|
44
|
+
if (verdict instanceof Reply)
|
|
45
|
+
return send(res, verdict.status, verdict.body, verdict.headers);
|
|
46
|
+
if (!verdict)
|
|
39
47
|
return send(res, 401, { error: "unauthorized" });
|
|
40
48
|
await serveProvider(state, req, res, { method, url, raw, body });
|
|
41
49
|
}
|
|
50
|
+
const WRITES = Object.fromEntries(providerEntries().flatMap(([name, p]) => (p.isWrite ? [[`/${name}`, (state, req) => p.isWrite(req, state.provider(name))]] : [])));
|
|
51
|
+
/** Whether a POST, PUT, PATCH or DELETE goes into the write log. */
|
|
52
|
+
function changesState(state, method, url, body) {
|
|
53
|
+
const prefix = url.pathname.match(/^\/[^/]+/)?.[0] ?? "";
|
|
54
|
+
const check = WRITES[prefix];
|
|
55
|
+
return check ? check(state, { method, path: url.pathname.slice(prefix.length) || "/", body }) : true;
|
|
56
|
+
}
|
|
57
|
+
/** `/<provider>` → how that provider takes its credential, when not as a bearer token. */
|
|
58
|
+
const AUTH = Object.fromEntries(providerEntries().flatMap(([name, p]) => (p.authorized ? [[`/${name}`, (state, h, req) => p.authorized(h, state.provider(name), req, state)]] : [])));
|
|
59
|
+
/** The credential check of the provider the path belongs to; a non-empty bearer token by default. */
|
|
60
|
+
function authorized(state, headers, req) {
|
|
61
|
+
const prefix = req.url.pathname.match(/^\/[^/]+/)?.[0] ?? "";
|
|
62
|
+
const check = AUTH[prefix];
|
|
63
|
+
return check ? check(state, headers, req) : /^Bearer\s+\S+$/.test(headers.authorization ?? "");
|
|
64
|
+
}
|
|
42
65
|
/** An authenticated provider request: latency, chaos, the write log, then the provider's routes. */
|
|
43
66
|
async function serveProvider(state, req, res, { method, url, raw, body }) {
|
|
44
67
|
if (state.chaos.latency_ms > 0)
|
|
45
68
|
await sleep(state.chaos.latency_ms);
|
|
46
|
-
const isWrite = WRITE_METHODS.has(method);
|
|
69
|
+
const isWrite = WRITE_METHODS.has(method) && changesState(state, method, url, body);
|
|
47
70
|
const action = state.chaosFor(method, url.pathname);
|
|
48
71
|
// Held: performed (and logged) only once released, like a request stuck in the provider's queue.
|
|
49
72
|
if (action?.kind === "hold")
|
|
@@ -60,7 +83,7 @@ async function serveProvider(state, req, res, { method, url, raw, body }) {
|
|
|
60
83
|
const logged = { ...entry };
|
|
61
84
|
if (isWrite)
|
|
62
85
|
state.writes.push(logged);
|
|
63
|
-
const r = dispatch(state, method, url, body);
|
|
86
|
+
const r = dispatch(state, method, url, body, headersOf(req));
|
|
64
87
|
// A refused write (409, 423, 404, …) did not change anything.
|
|
65
88
|
if (r.status >= 400)
|
|
66
89
|
logged.failed = true;
|
|
@@ -71,13 +94,13 @@ async function serveProvider(state, req, res, { method, url, raw, body }) {
|
|
|
71
94
|
}
|
|
72
95
|
send(res, r.status, r.body, r.headers);
|
|
73
96
|
}
|
|
74
|
-
/** `/<provider>/…` → that provider's routes, with the prefix stripped from the path. */
|
|
75
|
-
function dispatch(state, method, url, body) {
|
|
76
|
-
const prefix = url.pathname.match(/^\/[^/]+(
|
|
97
|
+
/** `/<provider>/…` → that provider's routes, with the prefix stripped from the path (`/<provider>` alone is `/`). */
|
|
98
|
+
function dispatch(state, method, url, body, headers) {
|
|
99
|
+
const prefix = url.pathname.match(/^\/[^/]+(?=\/|$)/)?.[0];
|
|
77
100
|
const routes = prefix === undefined ? undefined : ROUTES[prefix];
|
|
78
101
|
if (prefix === undefined || !routes)
|
|
79
102
|
return new Reply(404, { error: "not found" });
|
|
80
|
-
return routes(state, { method, url, path: url.pathname.slice(prefix.length), body });
|
|
103
|
+
return routes(state, { method, url, path: url.pathname.slice(prefix.length) || "/", body, headers });
|
|
81
104
|
}
|
|
82
105
|
/** The control endpoints tests and scenarios drive the sim with. */
|
|
83
106
|
const control = router([
|
|
@@ -100,7 +123,35 @@ const control = router([
|
|
|
100
123
|
return new Reply(200, { ok: true });
|
|
101
124
|
}),
|
|
102
125
|
], () => new Reply(404, { error: "not found" }));
|
|
126
|
+
/** The request's headers as strings (multi-valued ones joined with `, `). */
|
|
127
|
+
function headersOf(req) {
|
|
128
|
+
const out = {};
|
|
129
|
+
for (const [k, v] of Object.entries(req.headers))
|
|
130
|
+
if (v !== undefined)
|
|
131
|
+
out[k] = Array.isArray(v) ? v.join(", ") : v;
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
103
134
|
/** A request body: empty is `undefined`; null when it is not JSON. */
|
|
135
|
+
/**
|
|
136
|
+
* A form body (`application/x-www-form-urlencoded`) as the object it encodes, bracket-nested the way Stripe reads
|
|
137
|
+
* it: `a[b]=1&c[0]=x` is `{ a: { b: "1" }, c: ["x"] }`. Every value is a string.
|
|
138
|
+
*/
|
|
139
|
+
function parseForm(raw) {
|
|
140
|
+
const out = {};
|
|
141
|
+
for (const [name, value] of new URLSearchParams(raw)) {
|
|
142
|
+
const path = name.split(/\[|\]\[|\]/).filter((s) => s !== "");
|
|
143
|
+
let cur = out;
|
|
144
|
+
path.forEach((seg, i) => {
|
|
145
|
+
const last = i === path.length - 1;
|
|
146
|
+
const slot = cur;
|
|
147
|
+
if (last)
|
|
148
|
+
slot[seg] = value;
|
|
149
|
+
else
|
|
150
|
+
cur = (slot[seg] ??= /^\d+$/.test(path[i + 1]) ? [] : {});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
104
155
|
function parseJson(raw) {
|
|
105
156
|
if (raw.length === 0)
|
|
106
157
|
return { body: undefined };
|
|
@@ -120,8 +171,16 @@ function readBody(req) {
|
|
|
120
171
|
});
|
|
121
172
|
}
|
|
122
173
|
function send(res, status, body, headers = {}) {
|
|
123
|
-
|
|
124
|
-
|
|
174
|
+
if (status === 204) {
|
|
175
|
+
// No Content means no body, not the JSON `null`.
|
|
176
|
+
res.writeHead(204, headers);
|
|
177
|
+
res.end();
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
// A provider that answers in another format (S3's XML) sets its own content type and passes the text.
|
|
181
|
+
const raw = typeof body === "string" && headers["content-type"] !== undefined;
|
|
182
|
+
const text = raw ? body : JSON.stringify(body ?? null);
|
|
183
|
+
res.writeHead(status, { "content-type": "application/json", ...headers, "content-length": Buffer.byteLength(text) });
|
|
125
184
|
res.end(text);
|
|
126
185
|
}
|
|
127
186
|
function sha256(s) {
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAoF,MAAM,WAAW,CAAC;AAC3H,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAuC,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAmD,MAAM,YAAY,CAAC;AAK9F,qEAAqE;AACrE,MAAM,MAAM,GAA4B,MAAM,CAAC,WAAW,CACxD,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAClI,CAAC;AAEF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AAElE,2FAA2F;AAC3F,MAAM,UAAU,eAAe,CAAC,KAAe;IAC7C,OAAO,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC/B,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE;YAC3C,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,KAAe,EAAE,GAAoB,EAAE,GAAmB;IAC9E,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IACnD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChC,sGAAsG;IACtG,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IACtD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAC3G,qEAAqE;IACrE,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,8BAA8B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/F,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACtF,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;IAC9D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;IAExB,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,8GAA8G;IAC9G,kBAAkB;IAClB,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7F,IAAI,OAAO,YAAY,KAAK;QAAE,OAAO,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9F,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;IAC/D,MAAM,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AACnE,CAAC;AAID,MAAM,MAAM,GAA+B,MAAM,CAAC,WAAW,CAC3D,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAA+B,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,OAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAChK,CAAC;AAEF,oEAAoE;AACpE,SAAS,YAAY,CAAC,KAAe,EAAE,MAAc,EAAE,GAAQ,EAAE,IAAa;IAC5E,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACzD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvG,CAAC;AAID,0FAA0F;AAC1F,MAAM,IAAI,GAA8B,MAAM,CAAC,WAAW,CACxD,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAA8B,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,UAAW,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAClL,CAAC;AAEF,qGAAqG;AACrG,SAAS,UAAU,CAAC,KAAe,EAAE,OAA4B,EAAE,GAAgB;IACjF,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;AACjG,CAAC;AAED,oGAAoG;AACpG,KAAK,UAAU,aAAa,CAAC,KAAe,EAAE,GAAoB,EAAE,GAAmB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAA4D;IAC3K,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC;QAAE,MAAM,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAEpE,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACpF,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpD,iGAAiG;IACjG,IAAI,MAAM,EAAE,IAAI,KAAK,MAAM;QAAE,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,KAAK,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAClG,IAAI,MAAM,EAAE,IAAI,KAAK,MAAM,IAAI,MAAM,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;QACvD,8FAA8F;QAC9F,IAAI,OAAO;YAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;YAAE,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACzF,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAkB,EAAE,GAAG,KAAK,EAAE,CAAC;IAC3C,IAAI,OAAO;QAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEvC,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7D,8DAA8D;IAC9D,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG;QAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;IAC1C,IAAI,MAAM,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,8DAA8D;QAC9D,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,qHAAqH;AACrH,SAAS,QAAQ,CAAC,KAAe,EAAE,MAAc,EAAE,GAAQ,EAAE,IAAa,EAAE,OAA+B;IACzG,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjE,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IACnF,OAAO,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AACvG,CAAC;AAED,oEAAoE;AACpE,MAAM,OAAO,GAAG,MAAM,CACpB;IACE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;QAC3C,IAAI,CAAC;YACH,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,EAAE,CAAS,CAAC,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CAAC;IACF,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxE,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC;IACF,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACxF,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;QAC3C,KAAK,CAAC,KAAK,CAAC,IAAoC,CAAC,CAAC;QAClD,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC;CACH,EACD,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAC7C,CAAC;AAEF,6EAA6E;AAC7E,SAAS,SAAS,CAAC,GAAoB;IACrC,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,IAAI,CAAC,KAAK,SAAS;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpH,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sEAAsE;AACtE;;;GAGG;AACH,SAAS,SAAS,CAAC,GAAW;IAC5B,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9D,IAAI,GAAG,GAAwC,GAAG,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,GAA8B,CAAC;YAC5C,IAAI,IAAI;gBAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;;gBACvB,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAwC,CAAC;QACzG,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACjD,IAAI,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,EAAE,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,GAAoB;IACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrE,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,IAAI,CAAC,GAAmB,EAAE,MAAc,EAAE,IAAa,EAAE,UAAkC,EAAE;IACpG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,iDAAiD;QACjD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5B,GAAG,CAAC,GAAG,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IACD,sGAAsG;IACtG,MAAM,GAAG,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,KAAK,SAAS,CAAC;IAC9E,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IACvD,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,MAAM,CAAC,CAAS;IACvB,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC"}
|
package/dist/state.d.ts
CHANGED
|
@@ -12,6 +12,18 @@ export declare const PROVIDERS: {
|
|
|
12
12
|
vercel: ProviderSim<import("./routes/vercel.js").VercelState, import("./routes/vercel.js").VercelSeed>;
|
|
13
13
|
neon: ProviderSim<import("./routes/neon.js").NeonState, import("./routes/neon.js").NeonSeed>;
|
|
14
14
|
clerk: ProviderSim<import("./routes/clerk.js").ClerkState, import("./routes/clerk.js").ClerkSeed>;
|
|
15
|
+
planetscale: ProviderSim<import("./routes/planetscale.js").PlanetscaleState, import("./routes/planetscale.js").PlanetscaleSeed>;
|
|
16
|
+
launchdarkly: ProviderSim<import("./routes/launchdarkly.js").LaunchdarklyState, import("./routes/launchdarkly.js").LaunchdarklySeed>;
|
|
17
|
+
rest: ProviderSim<import("./routes/rest.js").RestState, import("./routes/rest.js").RestSeed>;
|
|
18
|
+
supabase: ProviderSim<import("./routes/supabase.js").SupabaseState, import("./routes/supabase.js").SupabaseSeed>;
|
|
19
|
+
netlify: ProviderSim<import("./routes/netlify.js").NetlifyState, import("./routes/netlify.js").NetlifySeed>;
|
|
20
|
+
cloudflare: ProviderSim<import("./routes/cloudflare.js").CloudflareState, import("./routes/cloudflare.js").CloudflareSeed>;
|
|
21
|
+
aws: ProviderSim<import("./routes/aws.js").AwsState, import("./routes/aws.js").AwsSeed>;
|
|
22
|
+
railway: ProviderSim<import("./routes/railway.js").RailwayState, import("./routes/railway.js").RailwaySeed>;
|
|
23
|
+
fly: ProviderSim<import("./routes/fly.js").FlyState, import("./routes/fly.js").FlySeed>;
|
|
24
|
+
algolia: ProviderSim<import("./routes/algolia.js").AlgoliaState, import("./routes/algolia.js").AlgoliaSeed>;
|
|
25
|
+
xata: ProviderSim<import("./routes/xata.js").XataState, import("./routes/xata.js").XataSeed>;
|
|
26
|
+
digitalocean: ProviderSim<import("./routes/digitalocean.js").DigitaloceanState, import("./routes/digitalocean.js").DigitaloceanSeed>;
|
|
15
27
|
};
|
|
16
28
|
type Providers = typeof PROVIDERS;
|
|
17
29
|
/** A simulated provider's name: its URL prefix, seed key and state key. */
|