/** The port `supabase init` writes, used only to explain the file, never assumed. */ export declare const SUPABASE_DEFAULT_DB_PORT = 54322; /** * The environment variables that may hold a connection string, in the order * they win. Shared with `config.ts` so a name is looked for in a file under * exactly the same list, and the same precedence, as in the environment. */ export declare const ENV_CANDIDATES: string[]; /** * The dotenv files worth reading, most specific first. * * This is Next.js's own precedence, not alphabetical order: `.env.local` is the * file a developer's own machine-specific database lives in and `.env` is the * one that gets committed, so reversing them would mean preferring the shared * default over the local override — the opposite of what every other tool in * the directory does. `.env.example` is never read: it holds placeholders by * definition, and a placeholder that parses as a URL is worse than nothing. */ export declare const ENV_FILES: string[]; /** * A union rather than one shape with an optional `variable`: a dotenv file * always has a variable name and `supabase/config.toml` never does, and saying * that in the type is what stops the caller reaching for a `!`. */ export type DiscoveredDatabase = { kind: "supabase"; connectionString: string; /** The file, written the way a reader would type it from where they ran. */ file: string; } | { kind: "env-file"; connectionString: string; file: string; /** The variable the value was written under. */ variable: string; }; /** * The variables set by a dotenv file. * * Handles what these files really contain: `export ` prefixes, blank lines, * `#` comments, quoted and unquoted values. An unquoted value is cut at the * first whitespace, which is how `DATABASE_URL=postgres://… # local` yields the * URL and not the comment — and it is safe to do it that way round, because a * connection string cannot contain a raw space. A quoted value is taken whole, * so a password with a `#` in it survives. */ export declare function readEnvFile(text: string): Map; /** * One key from one TOML table, by exact table name. * * "Exact" is the whole point. A Supabase `config.toml` holds `port` three * times — under `[api]` (54321), under `[db]` (54322) and under `[db.pooler]` * (54329) — so a reader that matched the first `port =` line, or that treated * `[db.pooler]` as part of `[db]`, would connect to the wrong service and blame * the user for it. Commented-out lines are ignored, including the ones the * generated file ships with. */ export declare function tomlValue(text: string, table: string, key: string): string | undefined; /** * The connection string for the local stack a `supabase/config.toml` describes. * * Only the port comes from the file. Everything else is fixed by the CLI, and * `undefined` rather than a guess if the file has no readable `[db] port` — a * `config.toml` that has been edited into a shape we do not understand is a * reason to say nothing, not a reason to try 54322 and report whatever answers. */ export declare function supabaseLocalUrl(configToml: string): string | undefined; /** Whether a string is a connection string, rather than a name or a blank. */ export declare function isPostgresUrl(value: string): boolean; /** * Find a database in the project, or nothing. * * Directories are tried in this order: where the command was run, then upwards * out of it, then downwards into it. Upwards because `crossline` gets run from * `apps/web` in a monorepo whose `supabase/` sits at the root; downwards * because it gets run from that root while `.env.local` sits in `apps/web`. * Both directions are bounded — four levels up, two down, three hundred * directories in all — because an unbounded walk of somebody's home directory * is not a thing a test command should ever do. * * Within one directory, `supabase/config.toml` outranks the dotenv files. That * ordering is deliberate and is the safe one: the Supabase file can only ever * name a loopback port, whereas a `DATABASE_URL` sitting in a committed `.env` * is very often the hosted database. Where a project has both, preferring the * local stack risks a refused connection on a port nobody started, which is * loud and instantly fixable; preferring the other risks seeding rows into * production, which is neither. */ export declare function discoverDatabase(cwd: string): DiscoveredDatabase | undefined; /** A value found on disk, and the file it was found in. Never the two combined. */ export interface DiscoveredValue { value: string; /** The file, written the way a reader would type it from where they ran. */ file: string; } /** * The dotenv files an identity may be found in, most specific first. * * A superset of `ENV_FILES`, which the database walk uses: Next.js also loads * `.env.development.local`, and identity detection has always read it. The two * lists are separate rather than merged because widening the *database* search * is a different decision with a different worst case — a connection string * found in one more file is a database we might write to — while widening the * identity search only ever changes which key we log in with. */ export declare const IDENTITY_ENV_FILES: string[]; /** * Every variable the project's dotenv files set, and where each came from. * * Same directories, same order, same bounds as `discoverDatabase`: the * directory the command was run in first, then upwards to the repository root, * then downwards into it. That ordering is what makes this work from a monorepo * root, which is where `crossline` actually gets typed — the key is in * `apps/web/.env.local` and the founder is standing two levels above it. * * The first definition wins, so the nearest directory beats a further one and * `.env.local` beats `.env` within a directory. Callers must still let the * process environment outrank everything here; see `resolveConnectionString` * for why discovery is always the last word rather than the first. */ export declare function discoverEnvValues(cwd: string, files?: readonly string[]): Map; /** * Every dependency named by any `package.json` in the same directories. * * The walk exists for one shape: the monorepo root, where `package.json` holds * the workspace declaration and nothing else, and every dependency that names * the auth provider is a level down in `apps/web`. Read only from `cwd`, a run * from the root sees zero dependencies and reports that no provider was * recognised — which is true of the file it read and false of the repository. * * Widening this cannot invent a credential. A provider is still chosen only * when the material it needs is also present, so the worst case of finding a * package name in a sibling directory is that a strategy is considered and then * declines by name. */ export declare function discoverDependencies(cwd: string): Set; /** * One INI file, as `{section: {key: value}}`. * * Written by hand for the same reason the dotenv and TOML readers were: the * subset AWS actually writes is `[section]` headers and `key = value` lines * with `#` or `;` comments. Nested subsettings (`s3 =` followed by an indented * block) are the one shape this does not model, and it does not need to — * nothing nested is a credential. */ export declare function readIni(text: string): Map>; /** What a Cognito run needs from AWS, wherever AWS keeps it. */ export interface DiscoveredAwsProfile { accessKeyId?: DiscoveredValue; secretAccessKey?: DiscoveredValue; sessionToken?: DiscoveredValue; region?: DiscoveredValue; } /** * The static credentials in AWS's shared config, for the profile in force. * * The one place this search leaves the repository, and deliberately: AWS's own * convention is that credentials live in `~/.aws/credentials` and *not* in the * project, so a Cognito app's `.env.local` correctly contains the user pool id * and nothing to authenticate with. Every AWS SDK — including the one the * application itself imports — resolves credentials from exactly these two * files, under exactly this profile. Reading them is reading what the app * reads; refusing to would mean asking the founder to copy a credential out of * the file AWS put it in, into a file AWS tells them not to put it in. * * Only *static* credentials are returned. A profile configured for SSO, * `role_arn`, or `credential_process` needs a token exchange this does not do, * and a half-populated answer would surface as an inscrutable AWS error rather * than as the plain "nothing to sign in with" it actually is. Where ownership * of the credential cannot be established from the file, say nothing. * * Precedence within the two files is AWS's own, verified against the SDK * reference: environment variables outrank both (the caller enforces that), the * `credentials` file outranks the `config` file, and the profile is * `$AWS_PROFILE` or `default`. Section headers differ between the files — * `[name]` in `credentials`, `[profile name]` in `config`, `[default]` in both. */ export declare function discoverAwsProfile(env?: NodeJS.ProcessEnv, home?: string): DiscoveredAwsProfile; /** * `host:port/database` — enough to tell two databases apart, never enough to * log in. Printed on every run, so it must not carry the password. */ export declare function endpointOf(connectionString: string): string; /** * Whether a connection string points at this machine. * * Used for one decision only: whether a database Crossline found by itself may * be written to without being asked twice. Anything not plainly loopback counts * as somewhere else, including `0.0.0.0` and `host.docker.internal` — the cost * of being wrong in that direction is one flag, and in the other direction it * is a migration applied to production. */ export declare function isLoopback(connectionString: string): boolean;