@devdogsuga/devtools 0.1.26 → 0.1.28
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 +72 -11
- package/bin/devtools.mjs +4 -4
- package/dist/cli-CZKkNHK5.js +6619 -0
- package/dist/failure-log-BBPGejQv.js +256 -0
- package/dist/launch.js +267 -281
- package/dist/local-env-D8HC2JK_.js +351 -0
- package/dist/local-env-DrBCXqD8.js +2 -0
- package/dist/menu-CQBsQRgH.js +1684 -0
- package/dist/peer-redirect-hooks.js +15 -0
- package/dist/peers-RBplwovA.js +229 -0
- package/dist/root-C2OmZDwD.js +94 -0
- package/dist/stack-Bx-55oi_.js +2 -0
- package/dist/stack-BynCgRVS.js +181 -0
- package/dist/supabase-project-0knM0mqd.js +426 -0
- package/dist/telemetry-C4foD8MD.js +249 -0
- package/dist/telemetry.js +2 -148
- package/package.json +10 -29
- package/bin/devtools-ci-bare.mjs +0 -48
- package/bin/devtools-ci.mjs +0 -31
- package/dist/args.d.ts +0 -26
- package/dist/args.js +0 -78
- package/dist/bws/bw.d.ts +0 -18
- package/dist/bws/bw.js +0 -70
- package/dist/bws/client.d.ts +0 -43
- package/dist/bws/client.js +0 -363
- package/dist/bws/environments.d.ts +0 -96
- package/dist/bws/environments.js +0 -111
- package/dist/bws/pace.d.ts +0 -25
- package/dist/bws/pace.js +0 -43
- package/dist/bws/retry.d.ts +0 -12
- package/dist/bws/retry.js +0 -39
- package/dist/bws/store.d.ts +0 -1
- package/dist/bws/store.js +0 -32
- package/dist/bws/token.d.ts +0 -31
- package/dist/bws/token.js +0 -88
- package/dist/bws/vault.d.ts +0 -29
- package/dist/bws/vault.js +0 -200
- package/dist/catalog.d.ts +0 -57
- package/dist/catalog.js +0 -57
- package/dist/cf/build.d.ts +0 -13
- package/dist/cf/build.js +0 -65
- package/dist/cf/commands.d.ts +0 -1
- package/dist/cf/commands.js +0 -172
- package/dist/cf/local-env.d.ts +0 -58
- package/dist/cf/local-env.js +0 -177
- package/dist/ci.d.ts +0 -1
- package/dist/ci.js +0 -328
- package/dist/cli.d.ts +0 -11
- package/dist/cli.js +0 -1094
- package/dist/commands.d.ts +0 -261
- package/dist/commands.js +0 -1318
- package/dist/completions.d.ts +0 -4
- package/dist/completions.js +0 -110
- package/dist/cron/commands.d.ts +0 -47
- package/dist/cron/commands.js +0 -372
- package/dist/cron/discovery.d.ts +0 -55
- package/dist/cron/discovery.js +0 -85
- package/dist/cron/schema.d.ts +0 -45
- package/dist/cron/schema.js +0 -35
- package/dist/db/config-push.d.ts +0 -8
- package/dist/db/config-push.js +0 -11
- package/dist/db/connection.d.ts +0 -79
- package/dist/db/connection.js +0 -114
- package/dist/db/exec.d.ts +0 -1
- package/dist/db/exec.js +0 -11
- package/dist/db/generate-types.d.ts +0 -1
- package/dist/db/generate-types.js +0 -4
- package/dist/db/generated-env.d.ts +0 -69
- package/dist/db/generated-env.js +0 -113
- package/dist/db/introspect.d.ts +0 -1
- package/dist/db/introspect.js +0 -122
- package/dist/db/local-env.d.ts +0 -65
- package/dist/db/local-env.js +0 -23
- package/dist/db/new-migration.d.ts +0 -8
- package/dist/db/new-migration.js +0 -69
- package/dist/db/pooler.d.ts +0 -23
- package/dist/db/pooler.js +0 -55
- package/dist/db/run.d.ts +0 -68
- package/dist/db/run.js +0 -156
- package/dist/db/seed-buckets.d.ts +0 -2
- package/dist/db/seed-buckets.js +0 -4
- package/dist/db/seed-production.d.ts +0 -8
- package/dist/db/seed-production.js +0 -79
- package/dist/db/seed-roles.d.ts +0 -7
- package/dist/db/seed-roles.js +0 -33
- package/dist/db/session-refresh.d.ts +0 -43
- package/dist/db/session-refresh.js +0 -40
- package/dist/deploy/migrations.d.ts +0 -20
- package/dist/deploy/migrations.js +0 -68
- package/dist/deploy/orphans.d.ts +0 -20
- package/dist/deploy/orphans.js +0 -177
- package/dist/deploy/preflight.d.ts +0 -53
- package/dist/deploy/preflight.js +0 -189
- package/dist/deploy/report.d.ts +0 -26
- package/dist/deploy/report.js +0 -70
- package/dist/deploy/require-planner.d.ts +0 -2
- package/dist/deploy/require-planner.js +0 -60
- package/dist/deploy/require-token.d.ts +0 -15
- package/dist/deploy/require-token.js +0 -78
- package/dist/deploy/secrets-file.d.ts +0 -17
- package/dist/deploy/secrets-file.js +0 -166
- package/dist/deploy/write-env.d.ts +0 -40
- package/dist/deploy/write-env.js +0 -395
- package/dist/docs/index-pages.d.ts +0 -38
- package/dist/docs/index-pages.js +0 -186
- package/dist/emails/commands.d.ts +0 -15
- package/dist/emails/commands.js +0 -130
- package/dist/emails/email-types.d.ts +0 -13
- package/dist/emails/email-types.js +0 -1
- package/dist/emails/fixtures.d.ts +0 -20
- package/dist/emails/fixtures.js +0 -20
- package/dist/env/audit.d.ts +0 -206
- package/dist/env/audit.js +0 -436
- package/dist/env/cloudflare.d.ts +0 -21
- package/dist/env/cloudflare.js +0 -61
- package/dist/env/commands.d.ts +0 -99
- package/dist/env/commands.js +0 -613
- package/dist/env/discovery.d.ts +0 -15
- package/dist/env/discovery.js +0 -239
- package/dist/env/document.d.ts +0 -119
- package/dist/env/document.js +0 -323
- package/dist/env/example.d.ts +0 -68
- package/dist/env/example.js +0 -605
- package/dist/env/selection.d.ts +0 -105
- package/dist/env/selection.js +0 -228
- package/dist/env-entry.d.ts +0 -49
- package/dist/env-entry.js +0 -204
- package/dist/environment-doctor.d.ts +0 -45
- package/dist/environment-doctor.js +0 -429
- package/dist/environment.d.ts +0 -92
- package/dist/environment.js +0 -185
- package/dist/fingerprint.d.ts +0 -10
- package/dist/fingerprint.js +0 -18
- package/dist/gen/campus-map.d.ts +0 -1
- package/dist/gen/campus-map.js +0 -473
- package/dist/gen/commands.d.ts +0 -1
- package/dist/gen/commands.js +0 -25
- package/dist/gen/hypno.d.ts +0 -1
- package/dist/gen/hypno.js +0 -134
- package/dist/gh/client.d.ts +0 -80
- package/dist/gh/client.js +0 -259
- package/dist/gh/environments.d.ts +0 -83
- package/dist/gh/environments.js +0 -178
- package/dist/gh/rulesets/actors.d.ts +0 -14
- package/dist/gh/rulesets/actors.js +0 -69
- package/dist/gh/rulesets/api.d.ts +0 -15
- package/dist/gh/rulesets/api.js +0 -104
- package/dist/gh/rulesets/commands.d.ts +0 -3
- package/dist/gh/rulesets/commands.js +0 -203
- package/dist/gh/rulesets/desired.d.ts +0 -112
- package/dist/gh/rulesets/desired.js +0 -271
- package/dist/gh/rulesets/diff.d.ts +0 -65
- package/dist/gh/rulesets/diff.js +0 -170
- package/dist/gh/rulesets/types.d.ts +0 -76
- package/dist/gh/rulesets/types.js +0 -13
- package/dist/gh/settings/api.d.ts +0 -40
- package/dist/gh/settings/api.js +0 -180
- package/dist/gh/settings/commands.d.ts +0 -1
- package/dist/gh/settings/commands.js +0 -254
- package/dist/gh/settings/desired.d.ts +0 -53
- package/dist/gh/settings/desired.js +0 -43
- package/dist/gh/settings/diff.d.ts +0 -57
- package/dist/gh/settings/diff.js +0 -161
- package/dist/gh/settings/types.d.ts +0 -92
- package/dist/gh/settings/types.js +0 -11
- package/dist/gh/settings/workflows.d.ts +0 -41
- package/dist/gh/settings/workflows.js +0 -128
- package/dist/grantRoot.d.ts +0 -42
- package/dist/grantRoot.js +0 -89
- package/dist/help.d.ts +0 -18
- package/dist/help.js +0 -169
- package/dist/images/commands.d.ts +0 -32
- package/dist/images/commands.js +0 -231
- package/dist/images/events.d.ts +0 -47
- package/dist/images/events.js +0 -116
- package/dist/images/graphics.d.ts +0 -70
- package/dist/images/graphics.js +0 -234
- package/dist/images/open-graph-types.d.ts +0 -75
- package/dist/images/open-graph-types.js +0 -1
- package/dist/images/prompts.d.ts +0 -34
- package/dist/images/prompts.js +0 -100
- package/dist/images/render.d.ts +0 -21
- package/dist/images/render.js +0 -61
- package/dist/images/select.d.ts +0 -64
- package/dist/images/select.js +0 -96
- package/dist/instance.d.ts +0 -69
- package/dist/instance.js +0 -102
- package/dist/invocation.d.ts +0 -49
- package/dist/invocation.js +0 -78
- package/dist/launch-ci.d.ts +0 -1
- package/dist/launch-ci.js +0 -90
- package/dist/launch.d.ts +0 -18
- package/dist/menu.d.ts +0 -43
- package/dist/menu.js +0 -300
- package/dist/moderation.d.ts +0 -70
- package/dist/moderation.js +0 -128
- package/dist/oauth/browser.d.ts +0 -1
- package/dist/oauth/browser.js +0 -13
- package/dist/oauth/config.d.ts +0 -24
- package/dist/oauth/config.js +0 -24
- package/dist/oauth/connect-url.d.ts +0 -17
- package/dist/oauth/connect-url.js +0 -23
- package/dist/oauth/db.d.ts +0 -37
- package/dist/oauth/db.js +0 -108
- package/dist/oauth/device.d.ts +0 -93
- package/dist/oauth/device.js +0 -198
- package/dist/oauth/discovery.d.ts +0 -28
- package/dist/oauth/discovery.js +0 -54
- package/dist/oauth/env-file.d.ts +0 -6
- package/dist/oauth/env-file.js +0 -35
- package/dist/oauth/exchange.d.ts +0 -43
- package/dist/oauth/exchange.js +0 -93
- package/dist/oauth/label.d.ts +0 -1
- package/dist/oauth/label.js +0 -25
- package/dist/oauth/loopback.d.ts +0 -52
- package/dist/oauth/loopback.js +0 -168
- package/dist/oauth/pkce.d.ts +0 -6
- package/dist/oauth/pkce.js +0 -34
- package/dist/oauth/target.d.ts +0 -54
- package/dist/oauth/target.js +0 -102
- package/dist/oauth/transport.d.ts +0 -41
- package/dist/oauth/transport.js +0 -32
- package/dist/oauth/wizard.d.ts +0 -40
- package/dist/oauth/wizard.js +0 -578
- package/dist/persona.d.ts +0 -18
- package/dist/persona.js +0 -221
- package/dist/pick.d.ts +0 -6
- package/dist/pick.js +0 -64
- package/dist/pipes.d.ts +0 -1
- package/dist/pipes.js +0 -25
- package/dist/planner/checks.d.ts +0 -26
- package/dist/planner/checks.js +0 -104
- package/dist/planner/commands.d.ts +0 -10
- package/dist/planner/commands.js +0 -367
- package/dist/planner/db.d.ts +0 -15
- package/dist/planner/db.js +0 -33
- package/dist/planner/role.d.ts +0 -33
- package/dist/planner/role.js +0 -68
- package/dist/repo/peer-redirect-hooks.d.ts +0 -16
- package/dist/repo/peer-redirect-hooks.js +0 -10
- package/dist/repo/peer-redirect.d.ts +0 -4
- package/dist/repo/peer-redirect.js +0 -26
- package/dist/repo/peers.d.ts +0 -39
- package/dist/repo/peers.js +0 -139
- package/dist/repo/resolve.d.ts +0 -41
- package/dist/repo/resolve.js +0 -152
- package/dist/repo/root.d.ts +0 -23
- package/dist/repo/root.js +0 -91
- package/dist/repo/source.d.ts +0 -14
- package/dist/repo/source.js +0 -54
- package/dist/repo/supabase-project.d.ts +0 -60
- package/dist/repo/supabase-project.js +0 -124
- package/dist/repo/tsx-loader.d.ts +0 -6
- package/dist/repo/tsx-loader.js +0 -41
- package/dist/run/pick.d.ts +0 -90
- package/dist/run/pick.js +0 -664
- package/dist/setup.d.ts +0 -1
- package/dist/setup.js +0 -280
- package/dist/stack.d.ts +0 -48
- package/dist/stack.js +0 -403
- package/dist/telemetry.d.ts +0 -59
- package/dist/tier.d.ts +0 -40
- package/dist/tier.js +0 -96
- package/dist/ui.d.ts +0 -40
- package/dist/ui.js +0 -71
- package/dist/version.d.ts +0 -7
- package/dist/version.js +0 -17
- package/dist/workers.d.ts +0 -5
- package/dist/workers.js +0 -33
- package/dist/workflows/commands.d.ts +0 -54
- package/dist/workflows/commands.js +0 -763
package/dist/images/select.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { loadOpenGraph } from "../repo/source.js";
|
|
2
|
-
/**
|
|
3
|
-
* Resolves graphic patterns.
|
|
4
|
-
*
|
|
5
|
-
* Every graphic is `group/name`, and three shapes of pattern read against
|
|
6
|
-
* that: a lone star (or a star over a star) is everything, `group/` plus a star
|
|
7
|
-
* is a whole group, and anything else is an exact name. Deliberately not a
|
|
8
|
-
* general glob — `event/2026-` plus a star looks like it should work and would
|
|
9
|
-
* be one more thing to specify, and the picker covers the case where somebody
|
|
10
|
-
* does not know the exact name.
|
|
11
|
-
*
|
|
12
|
-
* A bare group is accepted as shorthand for `group/*`, because `images icons`
|
|
13
|
-
* is what people type and refusing it teaches nothing.
|
|
14
|
-
*/
|
|
15
|
-
export function matchGraphics(patterns, graphics) {
|
|
16
|
-
const matched = new Map();
|
|
17
|
-
const unmatched = [];
|
|
18
|
-
const groups = new Set(graphics.map((graphic) => graphic.group));
|
|
19
|
-
for (const pattern of patterns) {
|
|
20
|
-
const hits = graphics.filter((graphic) => {
|
|
21
|
-
if (pattern === "*" || pattern === "*/*")
|
|
22
|
-
return true;
|
|
23
|
-
if (pattern.endsWith("/*"))
|
|
24
|
-
return graphic.group === pattern.slice(0, -2);
|
|
25
|
-
if (groups.has(pattern))
|
|
26
|
-
return graphic.group === pattern;
|
|
27
|
-
return graphic.name === pattern;
|
|
28
|
-
});
|
|
29
|
-
if (hits.length === 0) {
|
|
30
|
-
unmatched.push(pattern);
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
for (const hit of hits)
|
|
34
|
-
matched.set(hit.name, hit);
|
|
35
|
-
}
|
|
36
|
-
return { matched: [...matched.values()], unmatched };
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Pairs each graphic with each requested format it actually supports.
|
|
40
|
-
*
|
|
41
|
-
* The matrix is sparse, and silently dropping a pair is the wrong answer in one
|
|
42
|
-
* direction only: asking for `*` at every format should quietly skip the
|
|
43
|
-
* combinations that do not exist, while asking for one graphic at one format it
|
|
44
|
-
* cannot do should say so. The caller decides which case it is; this reports
|
|
45
|
-
* both halves.
|
|
46
|
-
*/
|
|
47
|
-
export async function pair(graphics, formats) {
|
|
48
|
-
const { FORMATS } = await loadOpenGraph();
|
|
49
|
-
const selections = [];
|
|
50
|
-
const unsupported = [];
|
|
51
|
-
for (const graphic of graphics) {
|
|
52
|
-
for (const name of formats) {
|
|
53
|
-
const format = FORMATS[name];
|
|
54
|
-
if (!format)
|
|
55
|
-
continue;
|
|
56
|
-
if (graphic.formats.includes(name)) {
|
|
57
|
-
selections.push({ graphic, format });
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
unsupported.push({ graphic: graphic.name, format: name });
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return { selections, unsupported };
|
|
65
|
-
}
|
|
66
|
-
/** Every format any of these graphics can be drawn at, in registry order. */
|
|
67
|
-
export async function formatsFor(graphics) {
|
|
68
|
-
const { FORMATS } = await loadOpenGraph();
|
|
69
|
-
const names = new Set(graphics.flatMap((graphic) => graphic.formats));
|
|
70
|
-
return Object.values(FORMATS).filter((format) => names.has(format.name));
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Splits `--flag=value` into two tokens.
|
|
74
|
-
*
|
|
75
|
-
* The rest of this CLI reads flags as `--flag value`, and `positionals()`
|
|
76
|
-
* depends on that to tell a flag's value from a subcommand. `--format=a,b`
|
|
77
|
-
* arrives as one token, so it would be read as a positional — that is, as a
|
|
78
|
-
* graphic name — and `images --format=og` would try to render a graphic called
|
|
79
|
-
* `--format=og` and report nothing matched. Normalising here lets both spellings
|
|
80
|
-
* work without teaching the shared parser about either.
|
|
81
|
-
*/
|
|
82
|
-
export function normalizeArgv(argv) {
|
|
83
|
-
return argv.flatMap((token) => {
|
|
84
|
-
if (!token.startsWith("--"))
|
|
85
|
-
return [token];
|
|
86
|
-
const eq = token.indexOf("=");
|
|
87
|
-
return eq === -1 ? [token] : [token.slice(0, eq), token.slice(eq + 1)];
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
/** A comma-separated flag value, trimmed and emptied of blanks. */
|
|
91
|
-
export function commaList(value) {
|
|
92
|
-
return (value ?? "")
|
|
93
|
-
.split(",")
|
|
94
|
-
.map((part) => part.trim())
|
|
95
|
-
.filter(Boolean);
|
|
96
|
-
}
|
package/dist/instance.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { type DbConnection } from "./db/connection.js";
|
|
2
|
-
import { findRepoRoot } from "./repo/root.js";
|
|
3
|
-
/**
|
|
4
|
-
* The repo root, which is where `supabase/config.toml` lives.
|
|
5
|
-
*
|
|
6
|
-
* The Supabase CLI walks up from its working directory looking for that file,
|
|
7
|
-
* and falls back to `basename(cwd)` as the project name when it finds none, so
|
|
8
|
-
* running it from the wrong place fails with "No such container:
|
|
9
|
-
* supabase_db_<whatever directory you were in>". Resolved via `findRepoRoot()`
|
|
10
|
-
* (walking up from `process.cwd()`, not this source file — see `repo/root.ts`)
|
|
11
|
-
* so it does not matter where the contributor invoked the tool from.
|
|
12
|
-
*/
|
|
13
|
-
export { findRepoRoot };
|
|
14
|
-
/**
|
|
15
|
-
* Every client here goes through this one factory so they all share a type.
|
|
16
|
-
*
|
|
17
|
-
* supabase-js encodes the default schema in the client's type, so a `schema`
|
|
18
|
-
* parameter of type `string` produces a client that will not unify with a
|
|
19
|
-
* hand-written `SupabaseClient` annotation. Deriving `DevtoolsClient` from the
|
|
20
|
-
* factory sidesteps that.
|
|
21
|
-
*/
|
|
22
|
-
declare function makeClient(url: string, key: string, schema: string): import("@supabase/supabase-js").SupabaseClient<any, "public", string, any, any>;
|
|
23
|
-
export type DevtoolsClient = ReturnType<typeof makeClient>;
|
|
24
|
-
export interface Instance {
|
|
25
|
-
apiUrl: string;
|
|
26
|
-
publishableKey: string;
|
|
27
|
-
secretKey: string;
|
|
28
|
-
}
|
|
29
|
-
/** The built-in Root role, from `supabase/seed/production/01_roles.sql`. */
|
|
30
|
-
export declare const ROOT_ROLE_ID = "00000000-0000-0000-0000-000000000002";
|
|
31
|
-
export interface ResolvedInstance {
|
|
32
|
-
connection: DbConnection;
|
|
33
|
-
instance: Instance;
|
|
34
|
-
}
|
|
35
|
-
export interface ResolveInstanceOptions {
|
|
36
|
-
/** Stderr prefix, e.g. "devtools grant-root". */
|
|
37
|
-
label?: string;
|
|
38
|
-
/** Injectable for tests; defaults to `process.env`. */
|
|
39
|
-
env?: NodeJS.ProcessEnv;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Resolves the session's database AND the Supabase client credentials for it.
|
|
43
|
-
*
|
|
44
|
-
* Goes through `resolveDbConnection()` first — the exact check `db
|
|
45
|
-
* migrate`/`db reset` run, including the local-stack-offline and
|
|
46
|
-
* inherited-development-values guards — so a caller here refuses in exactly
|
|
47
|
-
* the same situations and with the same messages those commands already do.
|
|
48
|
-
* What this adds is reading `API_URL`/`PUBLISHABLE_KEY`/`SECRET_KEY` out of
|
|
49
|
-
* the same already-entered session env `DB_URL` came from (see this file's
|
|
50
|
-
* header), rather than shelling out to `supabase status` — which is what
|
|
51
|
-
* makes hosted tiers reachable here at all.
|
|
52
|
-
*
|
|
53
|
-
* Returns `null` after reporting the reason on stderr, same contract as
|
|
54
|
-
* `resolveDbConnection` — never throws for an expected failure.
|
|
55
|
-
*/
|
|
56
|
-
export declare function resolveInstance(opts?: ResolveInstanceOptions): Promise<ResolvedInstance | null>;
|
|
57
|
-
/** A service-role client. Bypasses RLS, so setup and teardown only. */
|
|
58
|
-
export declare function adminClient(instance: Instance, schema?: string): DevtoolsClient;
|
|
59
|
-
/**
|
|
60
|
-
* A client signed in with a real email/password, subject to RLS.
|
|
61
|
-
*
|
|
62
|
-
* Signs in for real rather than hand-signing a JWT, so the token path exercised
|
|
63
|
-
* is the one production uses, with whatever claims Supabase Auth actually puts
|
|
64
|
-
* in a token rather than the ones we assume. Takes the password explicitly —
|
|
65
|
-
* there is no fixed persona password any more (see `persona.ts` and
|
|
66
|
-
* `moderation.ts`'s `withTemporaryModerator`, both of which generate a fresh
|
|
67
|
-
* random one per account).
|
|
68
|
-
*/
|
|
69
|
-
export declare function signedInClient(instance: Instance, email: string, password: string, schema?: string): Promise<DevtoolsClient>;
|
package/dist/instance.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Finding the instance to work against, and signing in to it.
|
|
3
|
-
*
|
|
4
|
-
* `resolveInstance()` is the one entry point every command that needs a
|
|
5
|
-
* Supabase client — `db`'s own commands excepted, which only ever need a
|
|
6
|
-
* Postgres URL — should call. It goes through the SAME session
|
|
7
|
-
* (`resolveDbConnection()`, `db/connection.ts`) `db migrate`/`db reset` do,
|
|
8
|
-
* rather than a local-only `supabase status` probe: every session's env
|
|
9
|
-
* carries `API_URL`/`PUBLISHABLE_KEY`/`SECRET_KEY` alongside `DB_URL` (see
|
|
10
|
-
* `.env.example`), so whichever tier `--tier` named is exactly the instance
|
|
11
|
-
* this resolves to, local Docker included.
|
|
12
|
-
*
|
|
13
|
-
* This replaces `detectLocalInstance()`+`assertMigrated()`, which read
|
|
14
|
-
* `supabase status -o env` directly and therefore only ever found the Docker
|
|
15
|
-
* stack on this machine — the reason `moderation check` and `grant-root`
|
|
16
|
-
* used to be local-only long after `db reset`/`db migrate` moved onto the
|
|
17
|
-
* session system.
|
|
18
|
-
*/
|
|
19
|
-
import { createClient } from "@supabase/supabase-js";
|
|
20
|
-
import { resolveDbConnection } from "./db/connection.js";
|
|
21
|
-
import { findRepoRoot } from "./repo/root.js";
|
|
22
|
-
/**
|
|
23
|
-
* The repo root, which is where `supabase/config.toml` lives.
|
|
24
|
-
*
|
|
25
|
-
* The Supabase CLI walks up from its working directory looking for that file,
|
|
26
|
-
* and falls back to `basename(cwd)` as the project name when it finds none, so
|
|
27
|
-
* running it from the wrong place fails with "No such container:
|
|
28
|
-
* supabase_db_<whatever directory you were in>". Resolved via `findRepoRoot()`
|
|
29
|
-
* (walking up from `process.cwd()`, not this source file — see `repo/root.ts`)
|
|
30
|
-
* so it does not matter where the contributor invoked the tool from.
|
|
31
|
-
*/
|
|
32
|
-
export { findRepoRoot };
|
|
33
|
-
/**
|
|
34
|
-
* Every client here goes through this one factory so they all share a type.
|
|
35
|
-
*
|
|
36
|
-
* supabase-js encodes the default schema in the client's type, so a `schema`
|
|
37
|
-
* parameter of type `string` produces a client that will not unify with a
|
|
38
|
-
* hand-written `SupabaseClient` annotation. Deriving `DevtoolsClient` from the
|
|
39
|
-
* factory sidesteps that.
|
|
40
|
-
*/
|
|
41
|
-
function makeClient(url, key, schema) {
|
|
42
|
-
return createClient(url, key, {
|
|
43
|
-
db: { schema },
|
|
44
|
-
auth: { autoRefreshToken: false, persistSession: false },
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
/** The built-in Root role, from `supabase/seed/production/01_roles.sql`. */
|
|
48
|
-
export const ROOT_ROLE_ID = "00000000-0000-0000-0000-000000000002";
|
|
49
|
-
/**
|
|
50
|
-
* Resolves the session's database AND the Supabase client credentials for it.
|
|
51
|
-
*
|
|
52
|
-
* Goes through `resolveDbConnection()` first — the exact check `db
|
|
53
|
-
* migrate`/`db reset` run, including the local-stack-offline and
|
|
54
|
-
* inherited-development-values guards — so a caller here refuses in exactly
|
|
55
|
-
* the same situations and with the same messages those commands already do.
|
|
56
|
-
* What this adds is reading `API_URL`/`PUBLISHABLE_KEY`/`SECRET_KEY` out of
|
|
57
|
-
* the same already-entered session env `DB_URL` came from (see this file's
|
|
58
|
-
* header), rather than shelling out to `supabase status` — which is what
|
|
59
|
-
* makes hosted tiers reachable here at all.
|
|
60
|
-
*
|
|
61
|
-
* Returns `null` after reporting the reason on stderr, same contract as
|
|
62
|
-
* `resolveDbConnection` — never throws for an expected failure.
|
|
63
|
-
*/
|
|
64
|
-
export async function resolveInstance(opts = {}) {
|
|
65
|
-
const label = opts.label ?? "devtools";
|
|
66
|
-
const connection = await resolveDbConnection({ label: opts.label });
|
|
67
|
-
if (!connection)
|
|
68
|
-
return null;
|
|
69
|
-
const env = opts.env ?? process.env;
|
|
70
|
-
const apiUrl = env.API_URL;
|
|
71
|
-
const publishableKey = env.PUBLISHABLE_KEY;
|
|
72
|
-
const secretKey = env.SECRET_KEY;
|
|
73
|
-
if (!apiUrl || !publishableKey || !secretKey) {
|
|
74
|
-
process.stderr.write(`${label}: this session has a DB_URL but no API_URL/PUBLISHABLE_KEY/` +
|
|
75
|
-
"SECRET_KEY — run `pnpm devtools env pull` for this tier, or " +
|
|
76
|
-
"`pnpm devtools db start` for the local stack.\n");
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
return { connection, instance: { apiUrl, publishableKey, secretKey } };
|
|
80
|
-
}
|
|
81
|
-
/** A service-role client. Bypasses RLS, so setup and teardown only. */
|
|
82
|
-
export function adminClient(instance, schema = "platform") {
|
|
83
|
-
return makeClient(instance.apiUrl, instance.secretKey, schema);
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* A client signed in with a real email/password, subject to RLS.
|
|
87
|
-
*
|
|
88
|
-
* Signs in for real rather than hand-signing a JWT, so the token path exercised
|
|
89
|
-
* is the one production uses, with whatever claims Supabase Auth actually puts
|
|
90
|
-
* in a token rather than the ones we assume. Takes the password explicitly —
|
|
91
|
-
* there is no fixed persona password any more (see `persona.ts` and
|
|
92
|
-
* `moderation.ts`'s `withTemporaryModerator`, both of which generate a fresh
|
|
93
|
-
* random one per account).
|
|
94
|
-
*/
|
|
95
|
-
export async function signedInClient(instance, email, password, schema = "platform") {
|
|
96
|
-
const client = makeClient(instance.apiUrl, instance.publishableKey, schema);
|
|
97
|
-
const { error } = await client.auth.signInWithPassword({ email, password });
|
|
98
|
-
if (error) {
|
|
99
|
-
throw new Error(`Could not sign in as ${email}: ${error.message}.`);
|
|
100
|
-
}
|
|
101
|
-
return client;
|
|
102
|
-
}
|
package/dist/invocation.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Records the fully-resolved argv of the command being run, so the CLI can
|
|
3
|
-
* close by printing a copy-pasteable line — the same command with every prompt
|
|
4
|
-
* already answered — for anyone who reached it through the wizard or let a
|
|
5
|
-
* missing flag fall to a prompt.
|
|
6
|
-
*
|
|
7
|
-
* ## Why a module-level recorder rather than a return value
|
|
8
|
-
*
|
|
9
|
-
* A command's inputs arrive from two places that never meet: the wizard walks
|
|
10
|
-
* `commands.ts` and gathers the *declared* options into the argv it dispatches
|
|
11
|
-
* (see `menu.ts`), while a runner resolves anything it prompts for *itself* —
|
|
12
|
-
* `workflows run` picking a tier, `env init` picking projects — deep inside its
|
|
13
|
-
* own call stack, where the dispatched argv is long out of reach. Threading a
|
|
14
|
-
* return value back up through every runner would touch each one's signature;
|
|
15
|
-
* a recorder every layer can reach touches only the layers that actually
|
|
16
|
-
* prompt.
|
|
17
|
-
*
|
|
18
|
-
* The rule for a runner: whenever a prompt (not a flag the caller already
|
|
19
|
-
* passed) decides a value, `recordResolved` the flag form of that decision. A
|
|
20
|
-
* value that came in as a flag is already in the base argv, so recording it
|
|
21
|
-
* again would double it — only the prompt branch records.
|
|
22
|
-
*/
|
|
23
|
-
/**
|
|
24
|
-
* Start recording for one invocation.
|
|
25
|
-
*
|
|
26
|
-
* `base` is what the dispatcher received: the wizard's built argv, or the argv
|
|
27
|
-
* the user typed. `fromMenu` marks the wizard path, where every step was a
|
|
28
|
-
* prompt, so the rerun line is worth printing even if no runner records a
|
|
29
|
-
* thing. A typed command starts non-interactive and only earns the line if a
|
|
30
|
-
* runner resolves a missing flag from a prompt.
|
|
31
|
-
*/
|
|
32
|
-
export declare function beginInvocation(base: readonly string[], fromMenu: boolean): void;
|
|
33
|
-
/**
|
|
34
|
-
* Record the deploy tier the wizard entered up front, so the rerun line carries
|
|
35
|
-
* it. development is the ambient default, so a prefix for it would be noise and
|
|
36
|
-
* is dropped.
|
|
37
|
-
*/
|
|
38
|
-
export declare function recordEnteredTier(tier: string): void;
|
|
39
|
-
/**
|
|
40
|
-
* Append the flag form of a value a prompt just resolved, e.g.
|
|
41
|
-
* `recordResolved("--tier", "development")`.
|
|
42
|
-
*/
|
|
43
|
-
export declare function recordResolved(...fragment: string[]): void;
|
|
44
|
-
/**
|
|
45
|
-
* The command to print, or `null` when there is nothing worth printing —
|
|
46
|
-
* either no invocation ran, or the user typed a complete command and answered
|
|
47
|
-
* no prompts, so echoing it back would be noise.
|
|
48
|
-
*/
|
|
49
|
-
export declare function reproducibleCommand(): string | null;
|
package/dist/invocation.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Records the fully-resolved argv of the command being run, so the CLI can
|
|
3
|
-
* close by printing a copy-pasteable line — the same command with every prompt
|
|
4
|
-
* already answered — for anyone who reached it through the wizard or let a
|
|
5
|
-
* missing flag fall to a prompt.
|
|
6
|
-
*
|
|
7
|
-
* ## Why a module-level recorder rather than a return value
|
|
8
|
-
*
|
|
9
|
-
* A command's inputs arrive from two places that never meet: the wizard walks
|
|
10
|
-
* `commands.ts` and gathers the *declared* options into the argv it dispatches
|
|
11
|
-
* (see `menu.ts`), while a runner resolves anything it prompts for *itself* —
|
|
12
|
-
* `workflows run` picking a tier, `env init` picking projects — deep inside its
|
|
13
|
-
* own call stack, where the dispatched argv is long out of reach. Threading a
|
|
14
|
-
* return value back up through every runner would touch each one's signature;
|
|
15
|
-
* a recorder every layer can reach touches only the layers that actually
|
|
16
|
-
* prompt.
|
|
17
|
-
*
|
|
18
|
-
* The rule for a runner: whenever a prompt (not a flag the caller already
|
|
19
|
-
* passed) decides a value, `recordResolved` the flag form of that decision. A
|
|
20
|
-
* value that came in as a flag is already in the base argv, so recording it
|
|
21
|
-
* again would double it — only the prompt branch records.
|
|
22
|
-
*/
|
|
23
|
-
/** The base argv plus whatever prompts resolved; `null` until an invocation begins. */
|
|
24
|
-
let argv = null;
|
|
25
|
-
/** Did the wizard, or an in-command prompt, actually decide anything here? */
|
|
26
|
-
let interactive = false;
|
|
27
|
-
/**
|
|
28
|
-
* The deploy tier `src/launch.ts` resolved and entered for this session, or
|
|
29
|
-
* `null` for the development default. Reproduced as a leading `--tier <tier>`
|
|
30
|
-
* flag, the same global flag `launch.ts` strips off ANY invocation before
|
|
31
|
-
* `cli.ts` ever runs — see its header — so this reproduces the tier for
|
|
32
|
-
* EVERY command, `db` and `env` included, exactly as typing `--tier <tier>`
|
|
33
|
-
* up front would.
|
|
34
|
-
*/
|
|
35
|
-
let enteredTier = null;
|
|
36
|
-
/**
|
|
37
|
-
* Start recording for one invocation.
|
|
38
|
-
*
|
|
39
|
-
* `base` is what the dispatcher received: the wizard's built argv, or the argv
|
|
40
|
-
* the user typed. `fromMenu` marks the wizard path, where every step was a
|
|
41
|
-
* prompt, so the rerun line is worth printing even if no runner records a
|
|
42
|
-
* thing. A typed command starts non-interactive and only earns the line if a
|
|
43
|
-
* runner resolves a missing flag from a prompt.
|
|
44
|
-
*/
|
|
45
|
-
export function beginInvocation(base, fromMenu) {
|
|
46
|
-
argv = [...base];
|
|
47
|
-
interactive = fromMenu;
|
|
48
|
-
enteredTier = null;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Record the deploy tier the wizard entered up front, so the rerun line carries
|
|
52
|
-
* it. development is the ambient default, so a prefix for it would be noise and
|
|
53
|
-
* is dropped.
|
|
54
|
-
*/
|
|
55
|
-
export function recordEnteredTier(tier) {
|
|
56
|
-
enteredTier = tier === "development" ? null : tier;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Append the flag form of a value a prompt just resolved, e.g.
|
|
60
|
-
* `recordResolved("--tier", "development")`.
|
|
61
|
-
*/
|
|
62
|
-
export function recordResolved(...fragment) {
|
|
63
|
-
if (argv === null || fragment.length === 0)
|
|
64
|
-
return;
|
|
65
|
-
argv.push(...fragment);
|
|
66
|
-
interactive = true;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* The command to print, or `null` when there is nothing worth printing —
|
|
70
|
-
* either no invocation ran, or the user typed a complete command and answered
|
|
71
|
-
* no prompts, so echoing it back would be noise.
|
|
72
|
-
*/
|
|
73
|
-
export function reproducibleCommand() {
|
|
74
|
-
if (argv === null || !interactive || argv.length === 0)
|
|
75
|
-
return null;
|
|
76
|
-
const tierFlag = enteredTier ? ["--tier", enteredTier] : [];
|
|
77
|
-
return `pnpm devtools ${[...tierFlag, ...argv].join(" ")}`;
|
|
78
|
-
}
|
package/dist/launch-ci.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function launchCi(argv: readonly string[]): Promise<void>;
|
package/dist/launch-ci.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `devtools-ci`'s entry point, in the same shape as `src/launch.ts` (read
|
|
3
|
-
* that file's header first) — resolve the session's deploy tier and enter its
|
|
4
|
-
* environment BEFORE `ci.ts` is imported — but with one deliberate
|
|
5
|
-
* difference: this NEVER prompts.
|
|
6
|
-
*
|
|
7
|
-
* CI is never interactive — `process.stdin.isTTY` is `undefined` in every job
|
|
8
|
-
* this runs in — so `resolveSessionTier` would already refuse to prompt on
|
|
9
|
-
* its own `isTTY` check. No `prompt` function is injected anyway, making that
|
|
10
|
-
* doubly true rather than relying on the ambient TTY guess: a CI job that
|
|
11
|
-
* somehow got attached to a terminal must still refuse ambiguity outright
|
|
12
|
-
* instead of hanging on a question nobody in a workflow can answer.
|
|
13
|
-
*
|
|
14
|
-
* ## Which `devtools-ci` invocations reach this file at all
|
|
15
|
-
*
|
|
16
|
-
* Only `run ci:env` does. The bare `run ci` package script — used for
|
|
17
|
-
* `deploy write-env`, which CREATES the env file this module would otherwise
|
|
18
|
-
* insist on reading, and for the handful of steps that hold one narrow
|
|
19
|
-
* credential and compose no env file at all — still runs `ci.ts` directly
|
|
20
|
-
* through `tsx`, deliberately bypassing tier resolution entirely. See
|
|
21
|
-
* `.github/workflows/deploy.yaml`'s own header for the two entry points and
|
|
22
|
-
* why each step picked the one it did.
|
|
23
|
-
*
|
|
24
|
-
* A `deploy <app> --tier <t>` invocation's `--tier` is a command flag `ci.ts`
|
|
25
|
-
* parses for itself (see its `runDeployCommand`), not this module's global
|
|
26
|
-
* `--tier` — but they resolve to the same tier here: `stripTierFlag` pulls it
|
|
27
|
-
* off before `ci.ts` sees argv, `resolveSessionTier` resolves the identical
|
|
28
|
-
* value as `explicit`, and `ci.ts`'s own parse then falls back to
|
|
29
|
-
* `process.env.DEPLOY_ENV`, which `enterEnvironment` just set to it.
|
|
30
|
-
*/
|
|
31
|
-
import { findRepoRoot } from "./repo/root.js";
|
|
32
|
-
import { loadEnvLoad, loadEnvSession } from "./repo/peers.js";
|
|
33
|
-
import { stripTierFlag } from "./launch.js";
|
|
34
|
-
import { captureDevtoolsError, initDevtoolsTelemetry } from "./telemetry.js";
|
|
35
|
-
import { ignoreClosedPipes } from "./pipes.js";
|
|
36
|
-
export async function launchCi(argv) {
|
|
37
|
-
const { explicit, rest } = stripTierFlag(argv);
|
|
38
|
-
// See `launch.ts`'s matching call: early, so tier resolution and env entry
|
|
39
|
-
// are covered too. Same tag `ci.ts`'s `main()` would compute.
|
|
40
|
-
ignoreClosedPipes();
|
|
41
|
-
initDevtoolsTelemetry(rest.slice(0, 2).join(" ") || "help");
|
|
42
|
-
const envLoad = await loadEnvLoad();
|
|
43
|
-
const envSession = await loadEnvSession();
|
|
44
|
-
const resolution = await envSession.resolveSessionTier({
|
|
45
|
-
explicit,
|
|
46
|
-
deployEnv: process.env.DEPLOY_ENV,
|
|
47
|
-
available: await envSession.availableTiers(findRepoRoot()),
|
|
48
|
-
isTTY: false,
|
|
49
|
-
// No `prompt` — see this file's header. Ambiguity is always a refusal.
|
|
50
|
-
});
|
|
51
|
-
if (!resolution.ok) {
|
|
52
|
-
process.stderr.write(`devtools-ci: ${resolution.reason}\n`);
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
const tier = resolution.tier;
|
|
56
|
-
try {
|
|
57
|
-
const entered = await envSession.enterEnvironment(tier, {
|
|
58
|
-
override: false,
|
|
59
|
-
});
|
|
60
|
-
for (const warning of entered.warnings) {
|
|
61
|
-
process.stderr.write(`devtools-ci: ${warning}\n`);
|
|
62
|
-
}
|
|
63
|
-
process.stderr.write(`devtools-ci: loaded ${entered.files.length > 0 ? entered.files.join(", ") : "no env files"} (${tier})\n`);
|
|
64
|
-
}
|
|
65
|
-
catch (err) {
|
|
66
|
-
if (!(err instanceof envLoad.MissingEnvFileError))
|
|
67
|
-
throw err;
|
|
68
|
-
// A CI job that reaches `run ci:env` at all has already run `deploy
|
|
69
|
-
// write-env` (see this file's header), so a missing file here — for
|
|
70
|
-
// ANY tier, `development` included — is never a first-run story the way
|
|
71
|
-
// it is for a contributor's own machine. Always fatal.
|
|
72
|
-
process.stderr.write(`devtools-ci: ${err.message}\n`);
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
const { main } = await import("./ci.js");
|
|
76
|
-
try {
|
|
77
|
-
await main(rest);
|
|
78
|
-
}
|
|
79
|
-
catch (err) {
|
|
80
|
-
process.stderr.write(`devtools-ci: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
81
|
-
// Report BEFORE exiting — see `captureDevtoolsError`'s header.
|
|
82
|
-
await captureDevtoolsError(err);
|
|
83
|
-
process.exit(1);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// See `launch.ts`'s matching guard for why this checks `process.argv[1]`
|
|
87
|
-
// rather than self-invoking unconditionally.
|
|
88
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
89
|
-
await launchCi(process.argv.slice(2));
|
|
90
|
-
}
|
package/dist/launch.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pulls a global `--tier <t>` out of `argv`, wherever it sits, leaving every
|
|
3
|
-
* other argument untouched and in its original order. Exported for its own
|
|
4
|
-
* unit tests; `launch()` below is the only real caller.
|
|
5
|
-
*/
|
|
6
|
-
export declare function stripTierFlag(argv: readonly string[]): {
|
|
7
|
-
explicit: string | undefined;
|
|
8
|
-
rest: string[];
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Resolves the session's deploy tier, enters it (or defers entry to the
|
|
12
|
-
* menu — see this file's header), and hands off to `cli.ts`.
|
|
13
|
-
*
|
|
14
|
-
* Exits the process directly on a refusal from `resolveSessionTier` — there
|
|
15
|
-
* is no command dispatched yet for a caller to fall back to, so there is
|
|
16
|
-
* nothing this function could return that would mean anything.
|
|
17
|
-
*/
|
|
18
|
-
export declare function launch(argv: readonly string[]): Promise<void>;
|
package/dist/menu.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { type Environment } from "./environment.js";
|
|
2
|
-
/**
|
|
3
|
-
* The command path when argv names a group with subcommands but no subcommand
|
|
4
|
-
* token — what `devtools db` and `devtools db seed` are. Returns null for a
|
|
5
|
-
* leaf command, an unknown token, or a bare invocation (which the no-argument
|
|
6
|
-
* wizard already covers). The caller resumes the wizard at this node when
|
|
7
|
-
* stdin is a TTY; a non-TTY caller keeps the dispatcher's "which of …?" exit.
|
|
8
|
-
*/
|
|
9
|
-
export declare function bareGroupStartPath(argv: readonly string[]): string[] | null;
|
|
10
|
-
/**
|
|
11
|
-
* Runs the wizard, returning the `outro()` line its command earned.
|
|
12
|
-
*
|
|
13
|
-
* `dispatch` is the CLI's own argv handler, injected rather than imported so
|
|
14
|
-
* that `cli.ts` keeps a single definition of what each command does and the
|
|
15
|
-
* tests can watch what a walk produces without running it. Its return value
|
|
16
|
-
* passes straight through, the closing line or `null` for a failure already
|
|
17
|
-
* explained, so a command reached from the menu signs off exactly as it does
|
|
18
|
-
* from the command line.
|
|
19
|
-
*
|
|
20
|
-
* `options.startPath`, from `bareGroupStartPath`, skips straight to that
|
|
21
|
-
* node's subcommand screen — see `walk`'s `startPath` branch.
|
|
22
|
-
*
|
|
23
|
-
* The deploy tier is NOT asked here any more. `src/launch.ts` resolves it
|
|
24
|
-
* before `cli.ts` — and therefore this module — is even imported, and
|
|
25
|
-
* exports `DEPLOY_ENV`/`DEV_DB` right away, so by the time the wizard opens
|
|
26
|
-
* `process.env` already names the session exactly as if `--tier` had been
|
|
27
|
-
* typed. Recording it for the "run it directly next time" line only needs to
|
|
28
|
-
* read `process.env.DEPLOY_ENV` back.
|
|
29
|
-
*
|
|
30
|
-
* Entering that tier — loading its `.env.<tier>` file onto `process.env` —
|
|
31
|
-
* is what's deferred: `launch.ts` registers a hook (`env-entry.ts`'s
|
|
32
|
-
* `setMenuEnvHook`) instead of entering up front, so whatever changed while
|
|
33
|
-
* the reader was still walking the menu (the local stack coming up in
|
|
34
|
-
* another terminal, `.env.generated` being rewritten) is picked up rather
|
|
35
|
-
* than missed. `takeMenuEnvHook()` below runs it right before the chosen
|
|
36
|
-
* command dispatches — the ONE place in a menu walk an env value is ever
|
|
37
|
-
* actually read. `undefined` (no hook registered — a typed command entered
|
|
38
|
-
* already, or a test drives `runMenu` directly) just dispatches straight
|
|
39
|
-
* through, unchanged from before this existed.
|
|
40
|
-
*/
|
|
41
|
-
export declare function runMenu(dispatch: (argv: string[]) => Promise<string | null>, env?: Environment, options?: {
|
|
42
|
-
startPath?: string[];
|
|
43
|
-
}): Promise<string | null>;
|