@devdogsuga/devtools 0.1.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 +44 -0
- package/bin/devtools-ci-bare.mjs +48 -0
- package/bin/devtools-ci.mjs +17 -0
- package/bin/devtools.mjs +27 -0
- package/dist/args.d.ts +26 -0
- package/dist/args.js +78 -0
- package/dist/bws/bw.d.ts +9 -0
- package/dist/bws/bw.js +49 -0
- package/dist/bws/client.d.ts +43 -0
- package/dist/bws/client.js +363 -0
- package/dist/bws/environments.d.ts +96 -0
- package/dist/bws/environments.js +111 -0
- package/dist/bws/pace.d.ts +27 -0
- package/dist/bws/pace.js +43 -0
- package/dist/bws/retry.d.ts +12 -0
- package/dist/bws/retry.js +39 -0
- package/dist/bws/store.d.ts +1 -0
- package/dist/bws/store.js +32 -0
- package/dist/bws/token.d.ts +31 -0
- package/dist/bws/token.js +88 -0
- package/dist/bws/vault.d.ts +29 -0
- package/dist/bws/vault.js +200 -0
- package/dist/catalog.d.ts +55 -0
- package/dist/catalog.js +81 -0
- package/dist/cf/commands.d.ts +1 -0
- package/dist/cf/commands.js +182 -0
- package/dist/cf/local-env.d.ts +44 -0
- package/dist/cf/local-env.js +148 -0
- package/dist/ci.d.ts +1 -0
- package/dist/ci.js +319 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +1077 -0
- package/dist/commands.d.ts +255 -0
- package/dist/commands.js +1279 -0
- package/dist/completions.d.ts +4 -0
- package/dist/completions.js +110 -0
- package/dist/cron/commands.d.ts +47 -0
- package/dist/cron/commands.js +372 -0
- package/dist/cron/discovery.d.ts +55 -0
- package/dist/cron/discovery.js +85 -0
- package/dist/cron/schema.d.ts +45 -0
- package/dist/cron/schema.js +35 -0
- package/dist/db/config-push.d.ts +8 -0
- package/dist/db/config-push.js +11 -0
- package/dist/db/connection.d.ts +79 -0
- package/dist/db/connection.js +114 -0
- package/dist/db/exec.d.ts +1 -0
- package/dist/db/exec.js +11 -0
- package/dist/db/generate-migration.d.ts +1 -0
- package/dist/db/generate-migration.js +67 -0
- package/dist/db/generate-types.d.ts +1 -0
- package/dist/db/generate-types.js +4 -0
- package/dist/db/introspect.d.ts +1 -0
- package/dist/db/introspect.js +113 -0
- package/dist/db/local-env.d.ts +65 -0
- package/dist/db/local-env.js +23 -0
- package/dist/db/new-migration.d.ts +1 -0
- package/dist/db/new-migration.js +8 -0
- package/dist/db/run.d.ts +70 -0
- package/dist/db/run.js +158 -0
- package/dist/db/seed-buckets.d.ts +2 -0
- package/dist/db/seed-buckets.js +4 -0
- package/dist/db/seed-production.d.ts +8 -0
- package/dist/db/seed-production.js +73 -0
- package/dist/db/seed-roles.d.ts +7 -0
- package/dist/db/seed-roles.js +31 -0
- package/dist/db/session-refresh.d.ts +43 -0
- package/dist/db/session-refresh.js +40 -0
- package/dist/deploy/migrations.d.ts +20 -0
- package/dist/deploy/migrations.js +68 -0
- package/dist/deploy/orphans.d.ts +20 -0
- package/dist/deploy/orphans.js +177 -0
- package/dist/deploy/preflight.d.ts +53 -0
- package/dist/deploy/preflight.js +189 -0
- package/dist/deploy/report.d.ts +26 -0
- package/dist/deploy/report.js +70 -0
- package/dist/deploy/require-planner.d.ts +2 -0
- package/dist/deploy/require-planner.js +60 -0
- package/dist/deploy/require-token.d.ts +15 -0
- package/dist/deploy/require-token.js +78 -0
- package/dist/deploy/secrets-file.d.ts +17 -0
- package/dist/deploy/secrets-file.js +167 -0
- package/dist/deploy/write-env.d.ts +40 -0
- package/dist/deploy/write-env.js +393 -0
- package/dist/docs/index-pages.d.ts +36 -0
- package/dist/docs/index-pages.js +184 -0
- package/dist/doctor.d.ts +62 -0
- package/dist/doctor.js +225 -0
- package/dist/emails/commands.d.ts +15 -0
- package/dist/emails/commands.js +130 -0
- package/dist/emails/email-types.d.ts +13 -0
- package/dist/emails/email-types.js +1 -0
- package/dist/emails/fixtures.d.ts +20 -0
- package/dist/emails/fixtures.js +20 -0
- package/dist/env/audit.d.ts +206 -0
- package/dist/env/audit.js +436 -0
- package/dist/env/cloudflare.d.ts +21 -0
- package/dist/env/cloudflare.js +61 -0
- package/dist/env/commands.d.ts +99 -0
- package/dist/env/commands.js +612 -0
- package/dist/env/discovery.d.ts +15 -0
- package/dist/env/discovery.js +226 -0
- package/dist/env/document.d.ts +119 -0
- package/dist/env/document.js +323 -0
- package/dist/env/example.d.ts +68 -0
- package/dist/env/example.js +603 -0
- package/dist/env/selection.d.ts +105 -0
- package/dist/env/selection.js +226 -0
- package/dist/environment.d.ts +92 -0
- package/dist/environment.js +206 -0
- package/dist/fingerprint.d.ts +10 -0
- package/dist/fingerprint.js +18 -0
- package/dist/gen/campus-map.d.ts +1 -0
- package/dist/gen/campus-map.js +473 -0
- package/dist/gen/commands.d.ts +1 -0
- package/dist/gen/commands.js +25 -0
- package/dist/gen/hypno.d.ts +1 -0
- package/dist/gen/hypno.js +134 -0
- package/dist/gh/client.d.ts +80 -0
- package/dist/gh/client.js +258 -0
- package/dist/gh/environments.d.ts +83 -0
- package/dist/gh/environments.js +178 -0
- package/dist/gh/rulesets/actors.d.ts +14 -0
- package/dist/gh/rulesets/actors.js +68 -0
- package/dist/gh/rulesets/api.d.ts +15 -0
- package/dist/gh/rulesets/api.js +99 -0
- package/dist/gh/rulesets/commands.d.ts +3 -0
- package/dist/gh/rulesets/commands.js +203 -0
- package/dist/gh/rulesets/desired.d.ts +112 -0
- package/dist/gh/rulesets/desired.js +247 -0
- package/dist/gh/rulesets/diff.d.ts +65 -0
- package/dist/gh/rulesets/diff.js +134 -0
- package/dist/gh/rulesets/types.d.ts +76 -0
- package/dist/gh/rulesets/types.js +13 -0
- package/dist/gh/settings/api.d.ts +40 -0
- package/dist/gh/settings/api.js +172 -0
- package/dist/gh/settings/commands.d.ts +1 -0
- package/dist/gh/settings/commands.js +245 -0
- package/dist/gh/settings/desired.d.ts +53 -0
- package/dist/gh/settings/desired.js +39 -0
- package/dist/gh/settings/diff.d.ts +57 -0
- package/dist/gh/settings/diff.js +156 -0
- package/dist/gh/settings/types.d.ts +92 -0
- package/dist/gh/settings/types.js +11 -0
- package/dist/gh/settings/workflows.d.ts +41 -0
- package/dist/gh/settings/workflows.js +124 -0
- package/dist/grantRoot.d.ts +42 -0
- package/dist/grantRoot.js +89 -0
- package/dist/help.d.ts +18 -0
- package/dist/help.js +169 -0
- package/dist/images/commands.d.ts +35 -0
- package/dist/images/commands.js +233 -0
- package/dist/images/events.d.ts +36 -0
- package/dist/images/events.js +152 -0
- package/dist/images/graphics.d.ts +70 -0
- package/dist/images/graphics.js +233 -0
- package/dist/images/open-graph-types.d.ts +75 -0
- package/dist/images/open-graph-types.js +1 -0
- package/dist/images/prompts.d.ts +34 -0
- package/dist/images/prompts.js +100 -0
- package/dist/images/render.d.ts +21 -0
- package/dist/images/render.js +57 -0
- package/dist/images/select.d.ts +64 -0
- package/dist/images/select.js +96 -0
- package/dist/instance.d.ts +67 -0
- package/dist/instance.js +129 -0
- package/dist/invocation.d.ts +49 -0
- package/dist/invocation.js +78 -0
- package/dist/launch-ci.d.ts +1 -0
- package/dist/launch-ci.js +86 -0
- package/dist/launch.d.ts +29 -0
- package/dist/launch.js +371 -0
- package/dist/menu.d.ts +31 -0
- package/dist/menu.js +277 -0
- package/dist/newsletter/commands.d.ts +16 -0
- package/dist/newsletter/commands.js +311 -0
- package/dist/newsletter/imap.d.ts +17 -0
- package/dist/newsletter/imap.js +127 -0
- package/dist/newsletter/loopback.d.ts +24 -0
- package/dist/newsletter/loopback.js +100 -0
- package/dist/newsletter/oauth.d.ts +26 -0
- package/dist/newsletter/oauth.js +130 -0
- package/dist/newsletter/smtp.d.ts +23 -0
- package/dist/newsletter/smtp.js +133 -0
- package/dist/oauth/browser.d.ts +1 -0
- package/dist/oauth/browser.js +13 -0
- package/dist/oauth/config.d.ts +24 -0
- package/dist/oauth/config.js +24 -0
- package/dist/oauth/connect-url.d.ts +17 -0
- package/dist/oauth/connect-url.js +23 -0
- package/dist/oauth/db.d.ts +37 -0
- package/dist/oauth/db.js +108 -0
- package/dist/oauth/device.d.ts +93 -0
- package/dist/oauth/device.js +190 -0
- package/dist/oauth/discovery.d.ts +28 -0
- package/dist/oauth/discovery.js +54 -0
- package/dist/oauth/env-file.d.ts +6 -0
- package/dist/oauth/env-file.js +35 -0
- package/dist/oauth/exchange.d.ts +43 -0
- package/dist/oauth/exchange.js +87 -0
- package/dist/oauth/label.d.ts +1 -0
- package/dist/oauth/label.js +25 -0
- package/dist/oauth/loopback.d.ts +52 -0
- package/dist/oauth/loopback.js +162 -0
- package/dist/oauth/pkce.d.ts +6 -0
- package/dist/oauth/pkce.js +34 -0
- package/dist/oauth/target.d.ts +54 -0
- package/dist/oauth/target.js +102 -0
- package/dist/oauth/transport.d.ts +41 -0
- package/dist/oauth/transport.js +32 -0
- package/dist/oauth/wizard.d.ts +33 -0
- package/dist/oauth/wizard.js +571 -0
- package/dist/pick.d.ts +6 -0
- package/dist/pick.js +64 -0
- package/dist/planner/checks.d.ts +26 -0
- package/dist/planner/checks.js +104 -0
- package/dist/planner/commands.d.ts +10 -0
- package/dist/planner/commands.js +367 -0
- package/dist/planner/db.d.ts +15 -0
- package/dist/planner/db.js +33 -0
- package/dist/planner/role.d.ts +33 -0
- package/dist/planner/role.js +68 -0
- package/dist/repo/peers.d.ts +24 -0
- package/dist/repo/peers.js +114 -0
- package/dist/repo/preflight.d.ts +109 -0
- package/dist/repo/preflight.js +266 -0
- package/dist/repo/resolve.d.ts +41 -0
- package/dist/repo/resolve.js +152 -0
- package/dist/repo/root.d.ts +23 -0
- package/dist/repo/root.js +91 -0
- package/dist/repo/source.d.ts +14 -0
- package/dist/repo/source.js +54 -0
- package/dist/repo/tsx-loader.d.ts +6 -0
- package/dist/repo/tsx-loader.js +41 -0
- package/dist/run/pick.d.ts +60 -0
- package/dist/run/pick.js +559 -0
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +152 -0
- package/dist/stack.d.ts +48 -0
- package/dist/stack.js +290 -0
- package/dist/telemetry.d.ts +34 -0
- package/dist/telemetry.js +93 -0
- package/dist/tier.d.ts +40 -0
- package/dist/tier.js +93 -0
- package/dist/tsconfig.typecheck.tsbuildinfo +1 -0
- package/dist/ui.d.ts +25 -0
- package/dist/ui.js +51 -0
- package/dist/workers.d.ts +5 -0
- package/dist/workers.js +35 -0
- package/dist/workflows/commands.d.ts +44 -0
- package/dist/workflows/commands.js +668 -0
- package/env.ts +158 -0
- package/package.json +80 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas for the two cron-trigger exports an app's
|
|
3
|
+
* `cloudflare/scheduled.ts` may declare: `CRON_ROUTES` (a schedule that fetches
|
|
4
|
+
* one or more of the app's own routes) and the optional `WORKFLOW_CRONS`
|
|
5
|
+
* (audit metadata for a native Cloudflare Workflow schedule).
|
|
6
|
+
*
|
|
7
|
+
* devtools enforces both at its import boundary (see `discovery.ts`): an app
|
|
8
|
+
* that drifts from the shape fails the audit and a conformance test, rather
|
|
9
|
+
* than reading as an empty (silently unaudited) map.
|
|
10
|
+
*
|
|
11
|
+
* Invariants, each a test rather than a hope:
|
|
12
|
+
* - Every route starts `/` and lives on the app's own origin.
|
|
13
|
+
* - `routes` is non-empty: a key that fires nothing is a config bug.
|
|
14
|
+
* - `label` is non-blank: the audit's English description; never empty.
|
|
15
|
+
* - Keyed by the cron expression exactly as wrangler carries it, so
|
|
16
|
+
* reconciliation is a set comparison, never a parse.
|
|
17
|
+
*/
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
declare const CronEntry: z.ZodObject<{
|
|
20
|
+
routes: z.ZodArray<z.ZodString>;
|
|
21
|
+
label: z.ZodString;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
export declare const CronRoutes: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
24
|
+
routes: z.ZodArray<z.ZodString>;
|
|
25
|
+
label: z.ZodString;
|
|
26
|
+
}, z.core.$strip>>;
|
|
27
|
+
export type CronRoutes = z.infer<typeof CronRoutes>;
|
|
28
|
+
export type CronEntry = z.infer<typeof CronEntry>;
|
|
29
|
+
/**
|
|
30
|
+
* A native workflow schedule. `binding` names the Workflows binding (e.g.
|
|
31
|
+
* `SCRAPE_WORKFLOW`); `cron list` reconciles the expression against that
|
|
32
|
+
* binding's `workflows[].schedules` in the tier's `wrangler.jsonc`. `label` is
|
|
33
|
+
* the audit's English description, same contract as routes.
|
|
34
|
+
*/
|
|
35
|
+
declare const WorkflowCronEntry: z.ZodObject<{
|
|
36
|
+
binding: z.ZodString;
|
|
37
|
+
label: z.ZodString;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
export declare const WorkflowCrons: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
40
|
+
binding: z.ZodString;
|
|
41
|
+
label: z.ZodString;
|
|
42
|
+
}, z.core.$strip>>;
|
|
43
|
+
export type WorkflowCrons = z.infer<typeof WorkflowCrons>;
|
|
44
|
+
export type WorkflowCronEntry = z.infer<typeof WorkflowCronEntry>;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas for the two cron-trigger exports an app's
|
|
3
|
+
* `cloudflare/scheduled.ts` may declare: `CRON_ROUTES` (a schedule that fetches
|
|
4
|
+
* one or more of the app's own routes) and the optional `WORKFLOW_CRONS`
|
|
5
|
+
* (audit metadata for a native Cloudflare Workflow schedule).
|
|
6
|
+
*
|
|
7
|
+
* devtools enforces both at its import boundary (see `discovery.ts`): an app
|
|
8
|
+
* that drifts from the shape fails the audit and a conformance test, rather
|
|
9
|
+
* than reading as an empty (silently unaudited) map.
|
|
10
|
+
*
|
|
11
|
+
* Invariants, each a test rather than a hope:
|
|
12
|
+
* - Every route starts `/` and lives on the app's own origin.
|
|
13
|
+
* - `routes` is non-empty: a key that fires nothing is a config bug.
|
|
14
|
+
* - `label` is non-blank: the audit's English description; never empty.
|
|
15
|
+
* - Keyed by the cron expression exactly as wrangler carries it, so
|
|
16
|
+
* reconciliation is a set comparison, never a parse.
|
|
17
|
+
*/
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
const CronRoute = z.string().startsWith("/");
|
|
20
|
+
const CronEntry = z.object({
|
|
21
|
+
routes: z.array(CronRoute).min(1),
|
|
22
|
+
label: z.string().min(1),
|
|
23
|
+
});
|
|
24
|
+
export const CronRoutes = z.record(z.string(), CronEntry);
|
|
25
|
+
/**
|
|
26
|
+
* A native workflow schedule. `binding` names the Workflows binding (e.g.
|
|
27
|
+
* `SCRAPE_WORKFLOW`); `cron list` reconciles the expression against that
|
|
28
|
+
* binding's `workflows[].schedules` in the tier's `wrangler.jsonc`. `label` is
|
|
29
|
+
* the audit's English description, same contract as routes.
|
|
30
|
+
*/
|
|
31
|
+
const WorkflowCronEntry = z.object({
|
|
32
|
+
binding: z.string().min(1),
|
|
33
|
+
label: z.string().min(1),
|
|
34
|
+
});
|
|
35
|
+
export const WorkflowCrons = z.record(z.string(), WorkflowCronEntry);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `config.toml` lives on a hosted project only — there is no local
|
|
3
|
+
* `--project-ref` to push to — so this takes the ref directly rather than a
|
|
4
|
+
* `Target`. The caller (`cli.ts`) resolves it from the tier, exactly like
|
|
5
|
+
* every other remote db operation now does, instead of letting the supabase
|
|
6
|
+
* CLI fall back to whatever project it has `--linked`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runConfigPush(projectRef: string): Promise<number>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { supabase } from "./run.js";
|
|
2
|
+
/**
|
|
3
|
+
* `config.toml` lives on a hosted project only — there is no local
|
|
4
|
+
* `--project-ref` to push to — so this takes the ref directly rather than a
|
|
5
|
+
* `Target`. The caller (`cli.ts`) resolves it from the tier, exactly like
|
|
6
|
+
* every other remote db operation now does, instead of letting the supabase
|
|
7
|
+
* CLI fall back to whatever project it has `--linked`.
|
|
8
|
+
*/
|
|
9
|
+
export async function runConfigPush(projectRef) {
|
|
10
|
+
return supabase("config", "push", "--project-ref", projectRef);
|
|
11
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the database a `db` command acts on — from the SESSION, never
|
|
3
|
+
* from a flag.
|
|
4
|
+
*
|
|
5
|
+
* There used to be two connection mechanisms here (`db/remote.ts`'s
|
|
6
|
+
* `--target remote` tier resolver, and `db/local-env.ts`'s "whatever this
|
|
7
|
+
* process entered"), joined by a `--target local|remote` flag that asked a
|
|
8
|
+
* question the launcher had already answered: `launch.ts` settles a session
|
|
9
|
+
* (`--tier development:local|development:remote|staging|production`, or the
|
|
10
|
+
* picker) and enters its env BEFORE any command dispatches, so
|
|
11
|
+
* `process.env.DB_URL` already names the one database this session means.
|
|
12
|
+
* This module reads that — the same `DB_URL` every app and script uses —
|
|
13
|
+
* and every mechanism-one caller now goes through it. `resolveLocalToolingEnv`
|
|
14
|
+
* remains for the two commands that hand a whole ENVIRONMENT to a child
|
|
15
|
+
* process rather than needing a connection of their own.
|
|
16
|
+
*
|
|
17
|
+
* What it adds over a raw `process.env.DB_URL` read is the two sanity
|
|
18
|
+
* guards a session can still violate:
|
|
19
|
+
*
|
|
20
|
+
* * development meaning the LOCAL stack, but `DB_URL` pointing somewhere
|
|
21
|
+
* that is not loopback — the stack went down after launch (the overlay
|
|
22
|
+
* is applied at entry; see `load.ts`'s probe table) or the degraded
|
|
23
|
+
* `db`-exempt entry ran without it. Refused with `db start`
|
|
24
|
+
* troubleshooting rather than letting `.env`'s hosted `DB_URL` answer
|
|
25
|
+
* for a command that asked for Docker.
|
|
26
|
+
* * a DEPLOYED tier whose `DB_URL` points AT loopback — the signature of
|
|
27
|
+
* inherited development values winning under `override: false` (see
|
|
28
|
+
* `launch.ts`). Refused rather than "migrating staging" against a local
|
|
29
|
+
* container.
|
|
30
|
+
*
|
|
31
|
+
* Reports the reason on stderr and returns `null` on every failure path —
|
|
32
|
+
* never throws for an expected failure — so a caller can stop without
|
|
33
|
+
* printing a second explanation of its own.
|
|
34
|
+
*
|
|
35
|
+
* ## `db connect` — plausibly vestigial
|
|
36
|
+
*
|
|
37
|
+
* `connectRemoteProject` (`stack.ts`) still runs `supabase link
|
|
38
|
+
* --project-ref <ref>`, the pre-session way of naming "the remote project",
|
|
39
|
+
* remembered by the supabase CLI on disk and read by nothing in this CLI:
|
|
40
|
+
* every operation here passes `--db-url`/`--project-ref` explicitly. It may
|
|
41
|
+
* still matter to someone driving the bare `supabase` CLI by hand, so
|
|
42
|
+
* removing it is a separate decision from this refactor.
|
|
43
|
+
*/
|
|
44
|
+
import type { DeployEnvironment } from "@devdogsuga/env";
|
|
45
|
+
import type { DevDatabase } from "@devdogsuga/env/load";
|
|
46
|
+
export declare function isLocalDbUrl(url: string): boolean;
|
|
47
|
+
/** The hostname for messages — never the URL itself, which carries the
|
|
48
|
+
* password. */
|
|
49
|
+
export declare function dbHost(url: string): string;
|
|
50
|
+
/** What the session resolved to: the one database every `db` data command
|
|
51
|
+
* in this process acts on. `projectRef` is only validated where it is
|
|
52
|
+
* actually needed (`seed buckets`, `config push`). */
|
|
53
|
+
export interface DbConnection {
|
|
54
|
+
tier: DeployEnvironment;
|
|
55
|
+
/** The session's development qualifier, when one was entered. */
|
|
56
|
+
devDatabase: DevDatabase | undefined;
|
|
57
|
+
dbUrl: string;
|
|
58
|
+
projectRef: string | undefined;
|
|
59
|
+
}
|
|
60
|
+
/** Whether this connection is the Docker stack on this machine — the one
|
|
61
|
+
* database whose erasure is routine rather than gated sternly. */
|
|
62
|
+
export declare function isLocalConnection(conn: DbConnection): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* How gates and reports name the target. Deliberately tier-and-host only —
|
|
65
|
+
* never the DB_URL, which carries the password — and "remote development"
|
|
66
|
+
* is spelled out because `staging`/`production` are also remote: the whole
|
|
67
|
+
* reason the session vocabulary qualifies development.
|
|
68
|
+
*/
|
|
69
|
+
export declare function describeDbTarget(conn: DbConnection): string;
|
|
70
|
+
export interface ResolveDbConnectionOptions {
|
|
71
|
+
/** Stderr prefix, e.g. "devtools db reset". */
|
|
72
|
+
label?: string;
|
|
73
|
+
/** Injectable for tests; defaults to `process.env`. */
|
|
74
|
+
env?: NodeJS.ProcessEnv;
|
|
75
|
+
/** Suppress the stderr reason — for callers like `db status` that treat
|
|
76
|
+
* "no resolvable database" as an answer, not a failure. */
|
|
77
|
+
quiet?: boolean;
|
|
78
|
+
}
|
|
79
|
+
export declare function resolveDbConnection(opts?: ResolveDbConnectionOptions): Promise<DbConnection | null>;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { loadEnv, loadEnvLoad } from "../repo/peers.js";
|
|
2
|
+
/**
|
|
3
|
+
* Hostnames that mean "the Docker stack on this machine". The same list
|
|
4
|
+
* `docs/index-pages.ts` keeps for its delete-acknowledgment; duplicated
|
|
5
|
+
* because that module answers a different question ("may I delete rows
|
|
6
|
+
* here without --target remote?") and coupling the two would let a change
|
|
7
|
+
* for one silently reshape the other.
|
|
8
|
+
*/
|
|
9
|
+
const LOCAL_DB_HOSTS = [
|
|
10
|
+
"localhost",
|
|
11
|
+
"127.0.0.1",
|
|
12
|
+
"[::1]",
|
|
13
|
+
"host.docker.internal",
|
|
14
|
+
];
|
|
15
|
+
export function isLocalDbUrl(url) {
|
|
16
|
+
try {
|
|
17
|
+
return LOCAL_DB_HOSTS.includes(new URL(url).hostname);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** The hostname for messages — never the URL itself, which carries the
|
|
24
|
+
* password. */
|
|
25
|
+
export function dbHost(url) {
|
|
26
|
+
try {
|
|
27
|
+
return new URL(url).hostname || "unknown host";
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return "unknown host";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Whether this connection is the Docker stack on this machine — the one
|
|
34
|
+
* database whose erasure is routine rather than gated sternly. */
|
|
35
|
+
export function isLocalConnection(conn) {
|
|
36
|
+
return conn.tier === "development" && isLocalDbUrl(conn.dbUrl);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* How gates and reports name the target. Deliberately tier-and-host only —
|
|
40
|
+
* never the DB_URL, which carries the password — and "remote development"
|
|
41
|
+
* is spelled out because `staging`/`production` are also remote: the whole
|
|
42
|
+
* reason the session vocabulary qualifies development.
|
|
43
|
+
*/
|
|
44
|
+
export function describeDbTarget(conn) {
|
|
45
|
+
if (conn.tier !== "development")
|
|
46
|
+
return `the ${conn.tier} database`;
|
|
47
|
+
if (isLocalDbUrl(conn.dbUrl))
|
|
48
|
+
return "your local database";
|
|
49
|
+
return `the remote development database at ${dbHost(conn.dbUrl)}`;
|
|
50
|
+
}
|
|
51
|
+
export async function resolveDbConnection(opts = {}) {
|
|
52
|
+
const { DEPLOY_ENVIRONMENTS, fileFor, isDeployEnvironment } = await loadEnv();
|
|
53
|
+
const { DEV_DB_ENV, isDevDatabase } = await loadEnvLoad();
|
|
54
|
+
const env = opts.env ?? process.env;
|
|
55
|
+
const label = opts.label ?? "devtools db";
|
|
56
|
+
const report = (message) => {
|
|
57
|
+
if (!opts.quiet)
|
|
58
|
+
process.stderr.write(message);
|
|
59
|
+
};
|
|
60
|
+
const rawTier = env.DEPLOY_ENV;
|
|
61
|
+
let tier;
|
|
62
|
+
if (rawTier === undefined || rawTier === "") {
|
|
63
|
+
tier = "development";
|
|
64
|
+
}
|
|
65
|
+
else if (isDeployEnvironment(rawTier)) {
|
|
66
|
+
tier = rawTier;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
report(`${label}: DEPLOY_ENV="${rawTier}" is not one of ${DEPLOY_ENVIRONMENTS.join(", ")}.\n`);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
let devDatabase;
|
|
73
|
+
const rawDevDb = env[DEV_DB_ENV];
|
|
74
|
+
if (tier === "development" && rawDevDb !== undefined && rawDevDb !== "") {
|
|
75
|
+
if (!isDevDatabase(rawDevDb)) {
|
|
76
|
+
report(`${label}: ${DEV_DB_ENV}="${rawDevDb}" is not one of: local, remote.\n`);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
devDatabase = rawDevDb;
|
|
80
|
+
}
|
|
81
|
+
const dbUrl = env.DB_URL;
|
|
82
|
+
if (dbUrl === undefined || dbUrl === "") {
|
|
83
|
+
if (tier !== "development") {
|
|
84
|
+
report(`${label}: ${fileFor(tier)} has no DB_URL.\n`);
|
|
85
|
+
}
|
|
86
|
+
else if (devDatabase === "remote") {
|
|
87
|
+
report(`${label}: this session targets the remote development database, but .env has no DB_URL.\n`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
report(`${label}: no DB_URL in this session — the local Supabase stack is ` +
|
|
91
|
+
"not running. Run `pnpm devtools db start`, or relaunch with " +
|
|
92
|
+
"`--tier development:remote` (or staging/production) to act on a " +
|
|
93
|
+
"hosted database.\n");
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
if (tier === "development" &&
|
|
98
|
+
devDatabase !== "remote" &&
|
|
99
|
+
!isLocalDbUrl(dbUrl)) {
|
|
100
|
+
report(`${label}: DB_URL points at ${dbHost(dbUrl)}, not the local stack — ` +
|
|
101
|
+
"it is offline (or .env.generated is stale). Run `pnpm devtools db " +
|
|
102
|
+
"start`, or relaunch with `--tier development:remote` if you mean " +
|
|
103
|
+
"that database.\n");
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
if (tier !== "development" && isLocalDbUrl(dbUrl)) {
|
|
107
|
+
report(`${label}: the session tier is ${tier} but DB_URL points at ` +
|
|
108
|
+
`${dbHost(dbUrl)} — a local address, the signature of inherited ` +
|
|
109
|
+
"development values. Relaunch with `pnpm devtools --tier " +
|
|
110
|
+
`${tier}\` from a clean shell.\n`);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
return { tier, devDatabase, dbUrl, projectRef: env.PROJECT_REF };
|
|
114
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runDbExec(args: string[]): Promise<number>;
|
package/dist/db/exec.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `db exec -- <args…>` — the escape hatch.
|
|
3
|
+
*
|
|
4
|
+
* Everything after `--` passes straight to the Supabase CLI, unmodified. Same
|
|
5
|
+
* stance as `bw` and `cf exec`: the wrapped CLI owns its own targeting and its
|
|
6
|
+
* own flags, so this declares no subcommands and does no parsing of its own.
|
|
7
|
+
*/
|
|
8
|
+
import { supabase } from "./run.js";
|
|
9
|
+
export async function runDbExec(args) {
|
|
10
|
+
return supabase(...args);
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runGenerateMigration(appSlug?: string): Promise<number>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `db migration generate [--app <slug>]` — draft a migration from an app's
|
|
3
|
+
* Drizzle schema drift.
|
|
4
|
+
*
|
|
5
|
+
* Absorbs schedule-builder's `db:generate` package script (`with-env
|
|
6
|
+
* drizzle-kit generate --config drizzle-migrations.config.ts`), the same way
|
|
7
|
+
* `db introspect` absorbed platform's `db:pull`. It touches no database: it
|
|
8
|
+
* diffs the schema files against drizzle-kit's own snapshot and writes SQL
|
|
9
|
+
* under the app's `drizzle-generated/`, a draft to be carried by hand into a
|
|
10
|
+
* real migration under `supabase/migrations/` — never something that runs on
|
|
11
|
+
* its own. `DB_URL` is still required because drizzle-kit's Postgres
|
|
12
|
+
* introspection needs a live connection to compare against, matching what
|
|
13
|
+
* `with-env` supplied before — sourced via `resolveLocalToolingEnv`, the
|
|
14
|
+
* tier this process already entered rather than a raw `.env` parse. See
|
|
15
|
+
* `db/local-env.ts`'s header.
|
|
16
|
+
*/
|
|
17
|
+
import { spawn } from "node:child_process";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { select } from "@clack/prompts";
|
|
20
|
+
import { findRepoRoot } from "../repo/root.js";
|
|
21
|
+
import { unwrap } from "../ui.js";
|
|
22
|
+
import { resolveLocalToolingEnv } from "./local-env.js";
|
|
23
|
+
// ── Per-app config ────────────────────────────────────────────────────────────
|
|
24
|
+
/** Apps whose Drizzle schema drafts migrations via `drizzle-kit generate`. */
|
|
25
|
+
const APP_CONFIGS = {
|
|
26
|
+
"schedule-builder": "drizzle-migrations.config.ts",
|
|
27
|
+
};
|
|
28
|
+
async function pickApp() {
|
|
29
|
+
const names = Object.keys(APP_CONFIGS);
|
|
30
|
+
if (names.length === 1)
|
|
31
|
+
return names[0];
|
|
32
|
+
return unwrap(await select({
|
|
33
|
+
message: "Whose schema drift should I draft a migration from?",
|
|
34
|
+
options: names.map((value) => ({ value, label: value })),
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
function runDrizzleGenerate(appDir, configFile, env) {
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
const child = spawn("pnpm", ["exec", "drizzle-kit", "generate", "--config", configFile], { stdio: "inherit", cwd: appDir, env });
|
|
40
|
+
child.on("exit", (code) => resolve(code ?? 1));
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// ── Entry ─────────────────────────────────────────────────────────────────────
|
|
44
|
+
export async function runGenerateMigration(appSlug) {
|
|
45
|
+
const app = appSlug ?? (await pickApp());
|
|
46
|
+
const configFile = APP_CONFIGS[app];
|
|
47
|
+
if (!configFile) {
|
|
48
|
+
const valid = Object.keys(APP_CONFIGS).join(", ");
|
|
49
|
+
process.stderr.write(`devtools db migration generate: unknown app "${app}". Expected: ${valid}.\n`);
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
const appDir = join(findRepoRoot(), "apps", app);
|
|
53
|
+
// Matching `db introspect`'s approach: `pnpm devtools` enters a tier into
|
|
54
|
+
// `process.env` before dispatch (`launch.ts`), but drizzle-kit here runs as
|
|
55
|
+
// its own child process in the app's directory, so that entered
|
|
56
|
+
// environment needs to be injected explicitly rather than inherited
|
|
57
|
+
// implicitly.
|
|
58
|
+
const env = await resolveLocalToolingEnv();
|
|
59
|
+
if (!env["DB_URL"]) {
|
|
60
|
+
process.stderr.write("devtools db migration generate: DB_URL is not set. Run " +
|
|
61
|
+
"`pnpm devtools db start` first (for local — its connection string " +
|
|
62
|
+
"lives in .env.generated once the stack is up), or set DB_URL in " +
|
|
63
|
+
"the deploy tier's env file this process entered.\n");
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
return runDrizzleGenerate(appDir, configFile, env);
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runGenerateTypes(dbUrl: string): Promise<number>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runIntrospect(app?: string): Promise<number>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `db introspect --app <slug>` — pull an app's live schema into its generated
|
|
3
|
+
* Drizzle files, then apply post-pull fixups.
|
|
4
|
+
*
|
|
5
|
+
* Replicates the old `db:pull` package script chain:
|
|
6
|
+
* 1. drizzle-kit pull --config drizzle-introspection.config.ts (auth/storage schemas)
|
|
7
|
+
* 2. drizzle-kit pull --config drizzle.config.ts (platform schema)
|
|
8
|
+
* 3. Post-pull fixups on the generated schema.ts:
|
|
9
|
+
* a. Delete relations.ts (we maintain hand-written relations)
|
|
10
|
+
* b. Re-inject the cross-schema FK-target import (auth.users etc.)
|
|
11
|
+
* c. Append InPlatform-suffix aliases so existing imports stay stable
|
|
12
|
+
*
|
|
13
|
+
* `DB_URL` comes from `resolveLocalToolingEnv` — the tier this process
|
|
14
|
+
* already entered (`launch.ts`, before `cli.ts` ever dispatched this
|
|
15
|
+
* command), `.env.generated` overlay included — and is injected into the
|
|
16
|
+
* subprocess environment. See `db/local-env.ts`'s header for why this is
|
|
17
|
+
* NOT a raw `.env` parse.
|
|
18
|
+
*/
|
|
19
|
+
import { spawn } from "node:child_process";
|
|
20
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { findRepoRoot } from "../repo/root.js";
|
|
23
|
+
import { resolveLocalToolingEnv } from "./local-env.js";
|
|
24
|
+
const APP_CONFIGS = {
|
|
25
|
+
platform: {
|
|
26
|
+
configs: ["drizzle-introspection.config.ts", "drizzle.config.ts"],
|
|
27
|
+
schemaFile: "src/server/db/schema/generated/schema.ts",
|
|
28
|
+
schemaSuffix: "InPlatform",
|
|
29
|
+
crossSchemaImport: 'import { usersInAuth as users, oauthClientsInAuth as oauthClients } from "~/supabase/drizzle/schema"',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
// ── drizzle-kit pull ──────────────────────────────────────────────────────────
|
|
33
|
+
function runDrizzlePull(appDir, configFile, env) {
|
|
34
|
+
return new Promise((resolve) => {
|
|
35
|
+
const child = spawn("pnpm", ["exec", "drizzle-kit", "pull", "--config", configFile], { stdio: "inherit", cwd: appDir, env });
|
|
36
|
+
child.on("exit", (code) => resolve(code ?? 1));
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// ── Post-pull fixups ──────────────────────────────────────────────────────────
|
|
40
|
+
function applyPostPullFixups(appDir, cfg) {
|
|
41
|
+
const schemaPath = join(appDir, cfg.schemaFile);
|
|
42
|
+
const relationsPath = join(appDir, cfg.schemaFile.replace("schema.ts", "relations.ts"));
|
|
43
|
+
// 1. Delete relations.ts
|
|
44
|
+
if (existsSync(relationsPath))
|
|
45
|
+
rmSync(relationsPath);
|
|
46
|
+
if (!existsSync(schemaPath))
|
|
47
|
+
return;
|
|
48
|
+
let src = readFileSync(schemaPath, "utf8");
|
|
49
|
+
// 2. Re-inject cross-schema FK-target import (idempotent)
|
|
50
|
+
const IMPORT_MARKER = "// Cross-schema FK targets";
|
|
51
|
+
if (cfg.crossSchemaImport && !src.includes(IMPORT_MARKER)) {
|
|
52
|
+
const lines = src.split("\n");
|
|
53
|
+
let insertAt = 0;
|
|
54
|
+
for (let i = 0; i < lines.length; i++) {
|
|
55
|
+
const line = lines[i] ?? "";
|
|
56
|
+
if (line.startsWith("import ") && line.includes("drizzle-orm")) {
|
|
57
|
+
insertAt = i + 1;
|
|
58
|
+
}
|
|
59
|
+
else if (line.trim() !== "" && !line.startsWith("import ")) {
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
lines.splice(insertAt, 0, `${IMPORT_MARKER} — re-injected by devtools db introspect after each drizzle-kit pull`, cfg.crossSchemaImport);
|
|
64
|
+
src = lines.join("\n");
|
|
65
|
+
}
|
|
66
|
+
// 3. Append base-name aliases for every `<name><suffix>` export (idempotent)
|
|
67
|
+
const ALIAS_MARKER = "// Schema-suffix aliases";
|
|
68
|
+
if (cfg.schemaSuffix && !src.includes(ALIAS_MARKER)) {
|
|
69
|
+
const names = new Set();
|
|
70
|
+
const re = new RegExp(`export const (\\w+)${cfg.schemaSuffix}\\b`, "g");
|
|
71
|
+
for (const m of src.matchAll(re))
|
|
72
|
+
if (m[1])
|
|
73
|
+
names.add(m[1]);
|
|
74
|
+
if (names.size > 0) {
|
|
75
|
+
const aliases = [...names]
|
|
76
|
+
.sort()
|
|
77
|
+
.map((n) => `export { ${n}${cfg.schemaSuffix} as ${n} };`)
|
|
78
|
+
.join("\n");
|
|
79
|
+
src = `${src.trimEnd()}\n\n${ALIAS_MARKER} — appended by devtools db introspect\n${aliases}\n`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
writeFileSync(schemaPath, src);
|
|
83
|
+
process.stdout.write(`[introspect] patched ${cfg.schemaFile}\n`);
|
|
84
|
+
}
|
|
85
|
+
// ── Entry ─────────────────────────────────────────────────────────────────────
|
|
86
|
+
export async function runIntrospect(app) {
|
|
87
|
+
if (!app) {
|
|
88
|
+
process.stderr.write("devtools db introspect: --app <slug> is required.\n");
|
|
89
|
+
return 1;
|
|
90
|
+
}
|
|
91
|
+
const cfg = APP_CONFIGS[app];
|
|
92
|
+
if (!cfg) {
|
|
93
|
+
const valid = Object.keys(APP_CONFIGS).join(", ");
|
|
94
|
+
process.stderr.write(`devtools db introspect: unknown app "${app}". Expected: ${valid}.\n`);
|
|
95
|
+
return 1;
|
|
96
|
+
}
|
|
97
|
+
const appDir = join(findRepoRoot(), "apps", app);
|
|
98
|
+
const env = await resolveLocalToolingEnv();
|
|
99
|
+
if (!env["DB_URL"]) {
|
|
100
|
+
process.stderr.write("devtools db introspect: DB_URL is not set. Run " +
|
|
101
|
+
"`pnpm devtools db start` first (for local — its connection string " +
|
|
102
|
+
"lives in .env.generated once the stack is up), or set DB_URL in " +
|
|
103
|
+
"the deploy tier's env file this process entered.\n");
|
|
104
|
+
return 1;
|
|
105
|
+
}
|
|
106
|
+
for (const configFile of cfg.configs) {
|
|
107
|
+
const code = await runDrizzlePull(appDir, configFile, env);
|
|
108
|
+
if (code !== 0)
|
|
109
|
+
return code;
|
|
110
|
+
}
|
|
111
|
+
applyPostPullFixups(appDir, cfg);
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The environment `db introspect` and `db migration generate` hand to the
|
|
3
|
+
* `drizzle-kit` child process they spawn.
|
|
4
|
+
*
|
|
5
|
+
* ## How this relates to `db/connection.ts`
|
|
6
|
+
*
|
|
7
|
+
* `db/connection.ts` resolves the session's one database CONNECTION (its
|
|
8
|
+
* `DB_URL`, with sanity guards) for commands that open one themselves. This
|
|
9
|
+
* is the other need: a whole ENVIRONMENT to hand a child process. Both read
|
|
10
|
+
* the same source — whatever THIS PROCESS already entered — `launch.ts`
|
|
11
|
+
* runs before
|
|
12
|
+
* `cli.ts`'s command dispatch even imports, and enters a tier (development,
|
|
13
|
+
* by default) into `process.env` via `@devdogsuga/env/session`'s
|
|
14
|
+
* `enterEnvironment`, applying `selectEnvFiles`'s overlay-plus-liveness-probe
|
|
15
|
+
* logic (`.env.generated`, the running local stack's connection block,
|
|
16
|
+
* ahead of `.env` — see `load.ts`'s probe table) along the way.
|
|
17
|
+
*
|
|
18
|
+
* These two commands used to bypass all of that: each parsed `.env` directly
|
|
19
|
+
* with raw `dotenv`, and merged it OVER `process.env`
|
|
20
|
+
* (`{...process.env, ...tierEnv}`). Two bugs followed from that shortcut:
|
|
21
|
+
*
|
|
22
|
+
* a. `.env.generated` — where the running local stack's `DB_URL` actually
|
|
23
|
+
* lives — was never read, so with the stack up these commands reported
|
|
24
|
+
* "DB_URL is not set in .env. Run `supabase start` first" (wrong
|
|
25
|
+
* command AND wrong file) or silently connected to a stale/hosted URL,
|
|
26
|
+
* while every other command in this CLI, going through `selectEnvFiles`,
|
|
27
|
+
* worked fine.
|
|
28
|
+
* b. The precedence was inverted: a raw `.env` parse merged OVER
|
|
29
|
+
* `process.env` clobbers whatever tier this process actually entered —
|
|
30
|
+
* backwards from the documented expectation (now `db/connection.ts`'s)
|
|
31
|
+
* that a command reads the tier the process is already running
|
|
32
|
+
* under rather than reimposing development on top of it.
|
|
33
|
+
*
|
|
34
|
+
* `resolveLocalToolingEnv` fixes both by returning `process.env` itself
|
|
35
|
+
* (fresh values, `.env.generated` included, whatever tier was entered)
|
|
36
|
+
* instead of re-deriving anything. The only case it still loads a tier
|
|
37
|
+
* itself is a caller that reaches these commands WITHOUT going through
|
|
38
|
+
* `launch.ts` first — `process.env.DEPLOY_ENV` unset is the tell, since
|
|
39
|
+
* `enterEnvironment` always sets it, even for `development` — and even then
|
|
40
|
+
* it falls back to `loadEnvironment("development")`, never a raw dotenv
|
|
41
|
+
* parse, so the overlay-plus-probe logic still applies.
|
|
42
|
+
*/
|
|
43
|
+
import type { LoadedEnvironment } from "@devdogsuga/env/load";
|
|
44
|
+
export interface ResolveLocalToolingEnvOptions {
|
|
45
|
+
/** Injectable for tests; defaults to `process.env`. */
|
|
46
|
+
processEnv?: NodeJS.ProcessEnv;
|
|
47
|
+
/** Injectable for tests; defaults to the real `loadEnvironment`. */
|
|
48
|
+
loadEnvironment?: (deployEnv?: string, options?: {
|
|
49
|
+
override?: boolean;
|
|
50
|
+
}) => Promise<LoadedEnvironment>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Returns the environment a local-tooling child process (`drizzle-kit`,
|
|
54
|
+
* spawned by `db introspect` / `db migration generate`) should inherit.
|
|
55
|
+
*
|
|
56
|
+
* Normal path (the process went through `launch.ts`, as `pnpm devtools`
|
|
57
|
+
* always does): returns `process.env` unchanged — it already carries
|
|
58
|
+
* whatever tier was entered, `.env.generated` overlay included.
|
|
59
|
+
*
|
|
60
|
+
* Fallback path (no tier was ever entered — a direct import, e.g. from a
|
|
61
|
+
* test, or a future caller that skips `launch.ts`): loads development
|
|
62
|
+
* through the shared `loadEnvironment`, which applies the same overlay and
|
|
63
|
+
* liveness probe `selectEnvFiles` always has, then returns that snapshot.
|
|
64
|
+
*/
|
|
65
|
+
export declare function resolveLocalToolingEnv(opts?: ResolveLocalToolingEnvOptions): Promise<NodeJS.ProcessEnv>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { loadEnvLoad } from "../repo/peers.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the environment a local-tooling child process (`drizzle-kit`,
|
|
4
|
+
* spawned by `db introspect` / `db migration generate`) should inherit.
|
|
5
|
+
*
|
|
6
|
+
* Normal path (the process went through `launch.ts`, as `pnpm devtools`
|
|
7
|
+
* always does): returns `process.env` unchanged — it already carries
|
|
8
|
+
* whatever tier was entered, `.env.generated` overlay included.
|
|
9
|
+
*
|
|
10
|
+
* Fallback path (no tier was ever entered — a direct import, e.g. from a
|
|
11
|
+
* test, or a future caller that skips `launch.ts`): loads development
|
|
12
|
+
* through the shared `loadEnvironment`, which applies the same overlay and
|
|
13
|
+
* liveness probe `selectEnvFiles` always has, then returns that snapshot.
|
|
14
|
+
*/
|
|
15
|
+
export async function resolveLocalToolingEnv(opts = {}) {
|
|
16
|
+
const processEnv = opts.processEnv ?? process.env;
|
|
17
|
+
if (processEnv.DEPLOY_ENV !== undefined && processEnv.DEPLOY_ENV !== "") {
|
|
18
|
+
return processEnv;
|
|
19
|
+
}
|
|
20
|
+
const load = opts.loadEnvironment ?? (await loadEnvLoad()).loadEnvironment;
|
|
21
|
+
const loaded = await load("development");
|
|
22
|
+
return loaded.env;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runNewMigration(name: string | undefined): Promise<number>;
|