@specific.dev/spectest 0.45.0 → 0.46.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/dist/components/supabase-config.d.ts +89 -0
- package/dist/components/supabase-config.js +447 -0
- package/dist/components/supabase.d.ts +124 -84
- package/dist/components/supabase.js +395 -136
- package/package.json +1 -1
- package/src/components/supabase-config.test.ts +261 -0
- package/src/components/supabase-config.ts +543 -0
- package/src/components/supabase-dir.test.ts +287 -0
- package/src/components/supabase.ts +581 -230
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { type ServiceGroup, type ServicesMap } from "../index.js";
|
|
1
|
+
import { type ServiceDefinition, type ServiceGroup, type ServicesMap } from "../index.js";
|
|
2
2
|
import { type SqlClient } from "../sql.js";
|
|
3
3
|
import { type EmailHelpers } from "./email.js";
|
|
4
|
+
export type { MailTemplateId, MailTemplateSpec } from "./supabase-config.js";
|
|
4
5
|
export interface SupabaseOptions {
|
|
5
6
|
/**
|
|
6
7
|
* Key of the API-gateway service and the prefix for every other piece.
|
|
@@ -22,25 +23,16 @@ export interface SupabaseOptions {
|
|
|
22
23
|
* deterministically, so the warm-template cache stays stable.
|
|
23
24
|
*/
|
|
24
25
|
jwtSecret?: string;
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
auth?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* GoTrue auth. `false` drops it from the stack; an object configures the
|
|
28
|
+
* two settings that are **addresses in this environment** rather than
|
|
29
|
+
* behaviour — everything else about auth comes from your `config.toml`.
|
|
30
|
+
*/
|
|
31
|
+
auth?: boolean | SupabaseAuthOptions;
|
|
31
32
|
/** Include storage-api + imgproxy (`<name>-storage`, `<name>-imgproxy`). Default `true`. */
|
|
32
33
|
storage?: boolean;
|
|
33
34
|
/** Include Realtime (`<name>-realtime`). Default `true`. */
|
|
34
35
|
realtime?: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Include the Studio dashboard (`<name>-studio`) and its postgres-meta
|
|
37
|
-
* backend (`<name>-meta`). Off by default — Studio is a heavy Next.js image
|
|
38
|
-
* and is only useful for interactive `ctx.browser()` exploration, not
|
|
39
|
-
* automated backend assertions. Turning it on implies `meta`.
|
|
40
|
-
*/
|
|
41
|
-
studio?: boolean;
|
|
42
|
-
/** Include postgres-meta (`<name>-meta`). Defaults to whatever `studio` is. */
|
|
43
|
-
meta?: boolean;
|
|
44
36
|
/**
|
|
45
37
|
* Also serve the gateway over **HTTPS** at `https://<hostname>` via the
|
|
46
38
|
* daemon's CA-trusted TLS reverse proxy (in addition to the plain
|
|
@@ -83,75 +75,130 @@ export interface SupabaseOptions {
|
|
|
83
75
|
serviceRole?: string[];
|
|
84
76
|
};
|
|
85
77
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* restored in `setup`) never gets a second, surprising source of DDL.
|
|
91
|
-
*
|
|
92
|
-
* Every `*.sql` directly in the directory is applied in sorted filename
|
|
93
|
-
* order, then — the standard Supabase layout — the **`seed.sql` beside
|
|
94
|
-
* that directory**, if there is one:
|
|
78
|
+
* The project's Supabase folder, e.g. `"supabase"` (relative to the project
|
|
79
|
+
* root, or absolute) — the layout `supabase init` creates and the CLI
|
|
80
|
+
* requires. This is the **only** way to point the stack at your project, and
|
|
81
|
+
* everything in the folder is used the way the Supabase CLI uses it:
|
|
95
82
|
*
|
|
96
83
|
* ```
|
|
97
84
|
* supabase/
|
|
98
|
-
*
|
|
99
|
-
* migrations/
|
|
100
|
-
* seed.sql
|
|
85
|
+
* config.toml ← auth rules, mail templates, per-function JWT verification
|
|
86
|
+
* migrations/ ← applied in filename order once the stack is up
|
|
87
|
+
* seed.sql ← applied after them, if it's there
|
|
88
|
+
* functions/ ← one directory per function, served at /functions/v1/<name>
|
|
101
89
|
* ```
|
|
102
90
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* PostgREST's schema cache is reloaded afterwards.
|
|
91
|
+
* `config.json` is read in preference to `config.toml` where a newer CLI has
|
|
92
|
+
* written one. Nothing is derived unless you name the folder, and each piece
|
|
93
|
+
* is optional inside it — a folder with only a `config.toml` is fine.
|
|
107
94
|
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
95
|
+
* There is deliberately no per-piece path option and no way to configure
|
|
96
|
+
* mail, OTP, redirect or JWT behaviour here: those live in `config.toml`,
|
|
97
|
+
* where your project already declares them and where the Supabase CLI reads
|
|
98
|
+
* them too. One source of truth, and the environment matches the one you run
|
|
99
|
+
* locally.
|
|
112
100
|
*/
|
|
113
|
-
|
|
101
|
+
dir?: string;
|
|
114
102
|
/**
|
|
115
|
-
*
|
|
116
|
-
* `
|
|
117
|
-
* entrypoint the runtime can serve (`supabase/functions/hello/index.ts`).
|
|
103
|
+
* The `.env` of this environment — the values your `config.toml` reads with
|
|
104
|
+
* `env(...)`.
|
|
118
105
|
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* entirely, along with the gateway's `/functions/v1` route.
|
|
106
|
+
* ```toml
|
|
107
|
+
* # supabase/config.toml
|
|
108
|
+
* [edge_runtime.secrets]
|
|
109
|
+
* STRIPE_KEY = "env(STRIPE_SECRET_KEY)"
|
|
110
|
+
* FEATURE_X = "true"
|
|
125
111
|
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
112
|
+
* [auth.external.google]
|
|
113
|
+
* client_id = "env(GOOGLE_OAUTH_CLIENT_ID)"
|
|
114
|
+
* ```
|
|
115
|
+
* ```ts
|
|
116
|
+
* supabase({
|
|
117
|
+
* dir: "supabase",
|
|
118
|
+
* env: {
|
|
119
|
+
* STRIPE_SECRET_KEY: "sk_test_…",
|
|
120
|
+
* GOOGLE_OAUTH_CLIENT_ID: "1234.apps.googleusercontent.com",
|
|
121
|
+
* },
|
|
122
|
+
* })
|
|
123
|
+
* ```
|
|
124
|
+
*
|
|
125
|
+
* Keyed exactly as your `supabase/.env` is: by the name inside `env(...)`.
|
|
126
|
+
* That file is what the Supabase CLI resolves against — locally at `start`,
|
|
127
|
+
* and in CI at `config push` / `secrets set` — and it is excluded from the
|
|
128
|
+
* upload here, deliberately, since real credentials should not enter a test
|
|
129
|
+
* environment. This is its stand-in, holding test values.
|
|
130
|
+
*
|
|
131
|
+
* It covers every `env(...)` in the file, not only secrets: a provider's
|
|
132
|
+
* client id is a field on your project's auth settings rather than a named
|
|
133
|
+
* secret, and it reads from the same place.
|
|
128
134
|
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
135
|
+
* A value reaches your **functions** because `[edge_runtime.secrets]`
|
|
136
|
+
* declares it — `SECRET = "env(NAME)"` — not merely because it is here. A
|
|
137
|
+
* deployed project can have secrets its config never mentions (the dashboard
|
|
138
|
+
* and `supabase secrets set` write straight to the project's store), but
|
|
139
|
+
* declaring them is what makes the test environment's inputs reviewable in
|
|
140
|
+
* the project's own config rather than implicit in its test setup. A name
|
|
141
|
+
* passed here and referenced nowhere is called out in the boot log.
|
|
142
|
+
*
|
|
143
|
+
* A literal in the file needs nothing. An inline `encrypted:` ciphertext
|
|
144
|
+
* cannot be supplied this way at all — it names no variable, and decrypting
|
|
145
|
+
* it needs a `DOTENV_PRIVATE_KEY` a test environment has no business
|
|
146
|
+
* holding — so it is named in the boot log and left unset. Anything else
|
|
147
|
+
* left unresolved is reported the same way, and never passed through as the
|
|
148
|
+
* string `env(NAME)` or as base64.
|
|
131
149
|
*/
|
|
132
|
-
|
|
150
|
+
env?: Record<string, string>;
|
|
133
151
|
}
|
|
134
|
-
/** Tuning for
|
|
135
|
-
export interface
|
|
152
|
+
/** Tuning for {@link SupabaseOptions.auth}. */
|
|
153
|
+
export interface SupabaseAuthOptions {
|
|
136
154
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
155
|
+
* Where GoTrue sends a user when a flow finishes — the base of every
|
|
156
|
+
* emailed confirmation, recovery and invite link's `redirect_to`, and the
|
|
157
|
+
* fallback when a requested redirect is refused. Defaults to the gateway
|
|
158
|
+
* (`http://<name>:8000`).
|
|
159
|
+
*
|
|
160
|
+
* This is deliberately **not** read from `config.toml`. That file's
|
|
161
|
+
* `site_url` is the developer's own machine (`http://localhost:3000`),
|
|
162
|
+
* which inside a VM is the browser's own namespace rather than the app
|
|
163
|
+
* container — so honouring it would point every redirect at nothing. Set
|
|
164
|
+
* it to the app under test's address in *this* environment:
|
|
165
|
+
*
|
|
166
|
+
* ```ts
|
|
167
|
+
* supabase({ dir: "supabase", auth: { siteUrl: "https://app.test" } })
|
|
168
|
+
* ```
|
|
139
169
|
*/
|
|
140
|
-
|
|
170
|
+
siteUrl?: string;
|
|
141
171
|
/**
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
172
|
+
* Extra addresses a flow may redirect to, beyond `siteUrl` (which GoTrue
|
|
173
|
+
* always allows). Glob patterns, exactly as `config.toml` spells them:
|
|
174
|
+
* `["https://app.test/**"]`.
|
|
175
|
+
*
|
|
176
|
+
* **Redirect validation is off unless you set this.** GoTrue has no switch
|
|
177
|
+
* for it — an empty allow list is its *strictest* state, not its loosest,
|
|
178
|
+
* because a redirect is then refused unless it matches `siteUrl` — so the
|
|
179
|
+
* default here is the wildcard, and a suite is never rejected for a
|
|
180
|
+
* redirect it didn't declare. Set it to make the environment enforce what
|
|
181
|
+
* production enforces; the addresses are per-environment, so they belong
|
|
182
|
+
* here rather than in the config file.
|
|
146
183
|
*/
|
|
147
|
-
|
|
184
|
+
additionalRedirectUrls?: string[];
|
|
148
185
|
/**
|
|
149
|
-
*
|
|
150
|
-
* the
|
|
151
|
-
* `
|
|
152
|
-
*
|
|
186
|
+
* Provider components to serve the config's `[auth.external.*]` blocks
|
|
187
|
+
* with, keyed by the provider name GoTrue uses (`google`, `azure`,
|
|
188
|
+
* `github`, `apple`). **You do not normally need this**: a provider the
|
|
189
|
+
* config enables is stood up automatically with that component's defaults.
|
|
190
|
+
* Supply one to choose the accounts it offers, or to serve a provider this
|
|
191
|
+
* stack has no built-in emulator for:
|
|
192
|
+
*
|
|
193
|
+
* ```ts
|
|
194
|
+
* auth: {
|
|
195
|
+
* providers: {
|
|
196
|
+
* google: google({ users: [{ email: "alice@corp.test", name: "Alice" }] }),
|
|
197
|
+
* },
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
153
200
|
*/
|
|
154
|
-
|
|
201
|
+
providers?: Record<string, ServiceDefinition>;
|
|
155
202
|
}
|
|
156
203
|
/** Tuning for `SupabaseOptions.mail`. */
|
|
157
204
|
export interface SupabaseMailOptions {
|
|
@@ -160,26 +207,14 @@ export interface SupabaseMailOptions {
|
|
|
160
207
|
* services-map key) instead of adding one to the group — the way to keep a
|
|
161
208
|
* single global mailbox when the app under test sends mail too. Assumes
|
|
162
209
|
* the service's default ports (SMTP 1025, API 8025).
|
|
163
|
-
*/
|
|
164
|
-
service?: string;
|
|
165
|
-
/**
|
|
166
|
-
* Whether GoTrue confirms a signup without the emailed verification.
|
|
167
|
-
* **`true` by default**: signups complete in one step and send no
|
|
168
|
-
* confirmation mail, which keeps account creation a single call in the
|
|
169
|
-
* suites where it is setup rather than the thing under test.
|
|
170
210
|
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* go nowhere.
|
|
211
|
+
* This is the only mail option, deliberately. Everything else about mail —
|
|
212
|
+
* whether a signup is confirmed, the sender identity, custom templates and
|
|
213
|
+
* their subjects — is GoTrue behaviour your project already declares in
|
|
214
|
+
* `config.toml` (`[auth.email]`, `[auth.email.smtp]`,
|
|
215
|
+
* `[auth.email.template.*]`), and it is read from there.
|
|
177
216
|
*/
|
|
178
|
-
|
|
179
|
-
/** Sender address GoTrue mails from. Default `admin@example.com`. */
|
|
180
|
-
adminEmail?: string;
|
|
181
|
-
/** Sender display name. Default `Supabase`. */
|
|
182
|
-
senderName?: string;
|
|
217
|
+
service?: string;
|
|
183
218
|
}
|
|
184
219
|
/** Helpers the gateway service exposes on `ctx.svc.<name>`. */
|
|
185
220
|
export interface SupabaseHelpers {
|
|
@@ -188,6 +223,11 @@ export interface SupabaseHelpers {
|
|
|
188
223
|
* `postgres` superuser — every query lands on the test event log and its rows
|
|
189
224
|
* come back provenance-wrapped, so `expect(...)` on a read links to the
|
|
190
225
|
* query. Point of direct DB verification alongside the REST/auth surface.
|
|
226
|
+
*
|
|
227
|
+
* The same client the `postgres()` component exposes: a tagged template for
|
|
228
|
+
* ordinary queries, plus `unsafe(text, params?)` for what a template cannot
|
|
229
|
+
* carry — a whole `.sql` file, or a dynamic column list — which is recorded
|
|
230
|
+
* on the timeline just the same. See `spectest docs /components/postgres`.
|
|
191
231
|
*/
|
|
192
232
|
sql: SqlClient;
|
|
193
233
|
/** The gateway base URL the app uses as `SUPABASE_URL` (e.g. `http://supabase:8000`). */
|