import { Config, NeonApi, resolveConfig } from "@neon/config/v1"; //#region ../../internals/env-core/dist/env.d.ts //#region src/env.d.ts declare const NEON_ENV_VAR_KEYS: { /** * Branch identity. `NEON_BRANCH` carries the branch **name** and is injected into the * Neon Functions runtime on every branch (including the default) by default. `env pull` / * `neon dev` / `neon-env run` emit it too so local dev mirrors the deployed runtime. */ readonly branch: { readonly name: "NEON_BRANCH"; }; readonly postgres: { readonly databaseUrl: "DATABASE_URL"; readonly databaseUrlUnpooled: "DATABASE_URL_UNPOOLED"; }; readonly auth: { readonly baseUrl: "NEON_AUTH_BASE_URL"; readonly jwksUrl: "NEON_AUTH_JWKS_URL"; }; readonly dataApi: { readonly url: "NEON_DATA_API_URL"; }; /** * Object storage (Preview). The S3 SDKs read `AWS_*` from their standard config chain, so * a branch credential + `neon dev` / `env pull` makes object storage work from env alone. * `region` is injected under the SDK-standard `AWS_REGION`. */ readonly storage: { readonly accessKeyId: "AWS_ACCESS_KEY_ID"; readonly secretAccessKey: "AWS_SECRET_ACCESS_KEY"; readonly endpoint: "AWS_ENDPOINT_URL_S3"; readonly region: "AWS_REGION"; }; /** * AI Gateway (Preview). Exposed under the Neon-branded env vars the deployed Functions * runtime injects: `apiKey` is the minted credential's bearer (`NEON_AI_GATEWAY_TOKEN`) * and `baseUrl` is the bare branch gateway host (`NEON_AI_GATEWAY_BASE_URL`, * `scheme://host`, no path). Clients like `@neon/ai-sdk-provider` read these and append the * dialect route (`/v1`, `/openai/v1`, `/anthropic/v1`) themselves (https://github.com/vercel/ai/pull/15997). */ readonly aiGateway: { readonly apiKey: "NEON_AI_GATEWAY_TOKEN"; readonly baseUrl: "NEON_AI_GATEWAY_BASE_URL"; }; }; /** * Branch identity for the resolved branch. Always present on a `fetchEnv` result (the branch * name is always known); on a `parseEnv` result it's present only when `NEON_BRANCH` was * injected into `process.env` (the Functions runtime injects it by default, as do `neon dev` / * `neon-env run` / `env pull`). `name` is the branch **name** (e.g. `main`, `preview/foo`). */ interface NeonBranchEnv { name: string; } /** Per-namespace inner shapes. Exposed so consumers can name the parts independently. */ interface NeonPostgresEnv { /** * Pooled connection string (via Neon's PgBouncer pooler). The right default for * serverless drivers (`@neondatabase/serverless`, edge runtimes, Postgres.js, …). */ databaseUrl: string; /** * Direct (unpooled) connection string. Use this when you need session-level * features (`LISTEN`/`NOTIFY`, prepared statements across calls, transactions * spanning round-trips) that PgBouncer's transaction-mode pooling drops. */ databaseUrlUnpooled: string; } /** * Bits of a Neon Auth integration for the resolved branch. Only present on `NeonEnv` * when the branch policy enables `auth`. * * Neon Auth exposes the `baseUrl` (which doubles as the publishable client identifier) and * the `jwksUrl` used to verify tokens it issues. `fetchEnv` reads both from the live * integration; `parseEnv` reads them from `process.env` (`NEON_AUTH_BASE_URL` / * `NEON_AUTH_JWKS_URL`). */ interface NeonAuthEnv { baseUrl: string; /** JWKS URL for verifying tokens issued by Neon Auth (`NEON_AUTH_JWKS_URL`). */ jwksUrl: string; } /** Bits of a Neon Data API integration. Only present when the branch policy enables it. */ interface NeonDataApiEnv { url: string; } /** * S3-compatible object-storage access for the branch (Preview). Present on `NeonEnv` only * when the policy declares `preview.buckets`. Combines a minted branch credential's access * keys (`accessKeyId` = the credential's full token id, e.g. `nak_live_…`, which is what the * storage gateway authenticates against; `secretAccessKey` = its * `s3_secret_access_key`) with the branch's non-secret connection details * (`endpoint`/`region`, from `GET .../storage`). Projects to the AWS SDK's * standard config env (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_ENDPOINT_URL_S3`, * `AWS_REGION`) so the S3 client works from env alone. Neon's storage gateway always * requires path-style addressing, so set `forcePathStyle: true` on your S3 client. */ interface NeonStorageEnv { accessKeyId: string; secretAccessKey: string; /** S3-compatible endpoint URL for the branch. */ endpoint: string; /** AWS region string (e.g. `us-east-2`). Injected as `AWS_REGION`. */ region: string; } /** * AI Gateway access for the branch (Preview). Present on `NeonEnv` only when the policy * enables `preview.aiGateway`. `apiKey` is the minted credential's bearer (`api_token`); * `baseUrl` is the bare branch-scoped gateway host * (`https://-api.ai..…`, no path). Projects to the Neon-branded env * (`NEON_AI_GATEWAY_TOKEN`, `NEON_AI_GATEWAY_BASE_URL`); clients like `@neon/ai-sdk-provider` * append the dialect route (`/v1`, `/openai/v1`, `/anthropic/v1`) themselves. */ interface NeonAiGatewayEnv { apiKey: string; baseUrl: string; } /** * Empty record alias used as the "false" branch of the conditional namespace adds below. * `Record` is the no-op for intersection — the cleaner alternative to `{}`, * which biome rejects (it means "any non-null", not "empty object"). */ type NoNamespace = Record; /** * Resolve a **static** service toggle (the value of `config.auth` / `config.dataApi`) to a * type-level boolean. The whole-thing wrapping (`[T] extends […]`) turns off distribution * so a union/`undefined` is checked as one unit: * * - `false` / `{ enabled: false }` / `undefined` → `false` * - `true` / `{ enabled: true }` / any other object (`{}`, `{ enabled?: boolean }`) → `true` * (a present toggle defaults to enabled) * - the bare `boolean | ServiceToggle | undefined` (the default `Config` param, no literal * info) → `false`, so an untyped policy yields just `{ postgres }`. */ type ServiceOn = [T] extends [false] ? false : [T] extends [{ enabled: false; }] ? false : [T] extends [undefined] ? false : [T] extends [true] ? true : [T] extends [{ enabled: true; }] ? true : [T] extends [object] ? true : false; /** True when `T` has at least one known key; `false` for `{}` / `never`. */ type HasKeys = [keyof T] extends [never] ? false : true; /** * Whether the policy's **static** `preview` block declares at least one object-storage bucket * (`preview.buckets`). Drives whether {@link NeonEnv} carries the `storage` namespace. * * The leading `[never]` guard is load-bearing: when a policy has no `preview` at all, * `NonNullable` is `never`, and without the guard the `extends { … }` probe * below would vacuously match (everything extends `never`-derived shapes) and `HasKeys` * would resolve `true`, wrongly adding the namespace. The guard short-circuits to `false`. */ type HasBuckets = [NonNullable] extends [never] ? false : NonNullable extends { buckets: infer B; } ? HasKeys> : false; /** * Whether the policy's **static** `preview` block enables the AI Gateway * (`preview.aiGateway`). Drives whether {@link NeonEnv} carries the `aiGateway` namespace. * * The leading `[never]` guard is load-bearing for the same reason as {@link HasBuckets}: when * a policy has no `preview`, `NonNullable` is `never`, and a naked `never` in the * `extends` below would *distribute* (collapsing the result — and the whole `NeonEnv` * intersection — to `never`). The tuple-wrapped guard short-circuits that to `false`. */ type AiGatewayOn = [NonNullable] extends [never] ? false : NonNullable extends { aiGateway: infer A; } ? ServiceOn> : false; /** * Static, namespaced shape of `fetchEnv` / `parseEnv`'s return value. Generic over the * {@link Config} so the type system knows which optional namespaces are present. * * Because the secret-bearing toggles now live in the **static** top-level `config.auth` / * `config.dataApi` (not inside a per-branch closure), the namespace presence is a direct * read of those fields — no union-across-branches, no default-config escape hatch: * * - `postgres` is always present. * - `auth` is added iff `config.auth` is statically enabled. * - `dataApi` is added iff `config.dataApi` is statically enabled. * - `storage` is added iff `config.preview.buckets` declares at least one bucket. * - `aiGateway` is added iff `config.preview.aiGateway` is statically enabled. */ type NeonEnv = { postgres: NeonPostgresEnv; /** * Branch identity (`NEON_BRANCH`). Optional because `parseEnv` only surfaces it when the * var was injected; `fetchEnv` always populates it. */ branch?: NeonBranchEnv; } & (ServiceOn> extends true ? { auth: NeonAuthEnv; } : NoNamespace) & (ServiceOn> extends true ? { dataApi: NeonDataApiEnv; } : NoNamespace) & (HasBuckets extends true ? { storage: NeonStorageEnv; } : NoNamespace) & (AiGatewayOn extends true ? { aiGateway: NeonAiGatewayEnv; } : NoNamespace); /** * OS-level env-var keys grouped by the {@link NeonEnv} namespace they populate. Only the * **input** vars `parseEnv` validates are listed — the output-only aliases in * {@link NEON_ENV_VAR_KEYS} (`NEON_AI_GATEWAY_TOKEN`, …) are intentionally absent, so they * are not selectable in a `parseEnv(config, keys)` filter. Keep in sync with * {@link EnvKeyToProp}. */ interface EnvKeysByNamespace { postgres: "DATABASE_URL" | "DATABASE_URL_UNPOOLED"; branch: "NEON_BRANCH"; auth: "NEON_AUTH_BASE_URL" | "NEON_AUTH_JWKS_URL"; dataApi: "NEON_DATA_API_URL"; storage: "AWS_ACCESS_KEY_ID" | "AWS_SECRET_ACCESS_KEY" | "AWS_ENDPOINT_URL_S3" | "AWS_REGION"; aiGateway: "NEON_AI_GATEWAY_TOKEN" | "NEON_AI_GATEWAY_BASE_URL"; } /** The {@link NeonEnv} namespace interface backing each namespace key. */ interface NamespaceEnv { postgres: NeonPostgresEnv; branch: NeonBranchEnv; auth: NeonAuthEnv; dataApi: NeonDataApiEnv; storage: NeonStorageEnv; aiGateway: NeonAiGatewayEnv; } /** OS-level env-var key → the camelCase property it sets on its namespace object. */ interface EnvKeyToProp { DATABASE_URL: "databaseUrl"; DATABASE_URL_UNPOOLED: "databaseUrlUnpooled"; NEON_BRANCH: "name"; NEON_AUTH_BASE_URL: "baseUrl"; NEON_AUTH_JWKS_URL: "jwksUrl"; NEON_DATA_API_URL: "url"; AWS_ACCESS_KEY_ID: "accessKeyId"; AWS_SECRET_ACCESS_KEY: "secretAccessKey"; AWS_ENDPOINT_URL_S3: "endpoint"; AWS_REGION: "region"; NEON_AI_GATEWAY_TOKEN: "apiKey"; NEON_AI_GATEWAY_BASE_URL: "baseUrl"; } /** * The OS-level env-var keys selectable for a given policy: the union of input vars across * exactly the namespaces {@link NeonEnv} carries. Drives the typesafe autocomplete of the * `keys` filter — selecting a var from a namespace the policy does not enable is a type error * (e.g. `NEON_AUTH_BASE_URL` is only offered once the policy turns on `auth`). */ type SelectableEnvKey = EnvKeysByNamespace[keyof NeonEnv & keyof EnvKeysByNamespace]; /** * The result shape of a **filtered** `parseEnv(config, keys)` call: the namespaced * {@link NeonEnv} restricted to exactly the selected OS-level keys `K`. Namespaces with no * selected key are dropped, and within a kept namespace only the selected properties survive * — selecting just `["DATABASE_URL"]` yields `{ postgres: { databaseUrl: string } }`, with no * `databaseUrlUnpooled`. * * The policy gating lives on the `parseEnv` overload (which binds `K` to * {@link SelectableEnvKey}); this type only needs the selection, so it takes a bare * `K extends string` and filters with `Extract`. The outer mapped type's `as` clause drops * any namespace whose intersection with the selection is empty (`[…] extends [never]`, * tuple-wrapped to switch off distribution); the inner one re-keys each selected OS var to its * camelCase property and looks the value type up on the canonical namespace interface, so it * stays correct if a field ever stops being a plain `string`. */ type FilteredNeonEnv = { [N in keyof EnvKeysByNamespace as [Extract] extends [never] ? never : N]: { [P in Extract as EnvKeyToProp[P & keyof EnvKeyToProp]]: NamespaceEnv[N][EnvKeyToProp[P & keyof EnvKeyToProp] & keyof NamespaceEnv[N]] } }; /** * A filtered result when the exact runtime contents of a key array are unknown. Both the * namespace and its selected properties are optional because the array may omit any member of * its element union, or be empty. */ type OptionalFilteredNeonEnv = { [N in keyof EnvKeysByNamespace as [Extract] extends [never] ? never : N]?: { [P in Extract as EnvKeyToProp[P & keyof EnvKeyToProp]]?: NamespaceEnv[N][EnvKeyToProp[P & keyof EnvKeyToProp] & keyof NamespaceEnv[N]] } }; /** Whether `T` is a union rather than one concrete type. */ type IsUnion = T extends Whole ? [Whole] extends [T] ? false : true : never; /** Whether any fixed tuple position can hold more than one key at runtime. */ type TupleHasUnion = T extends readonly [] ? false : T extends readonly [infer Head, ...infer Tail extends readonly unknown[]] ? true extends IsUnion ? true : TupleHasUnion : true; /** * The sound result of selecting an array of OS-level env-var keys. * * Inline literal tuples remain exact. Widened arrays, rest tuples, and tuple positions whose * value is a union are conservative because their runtime contents may be any subset of the * element type. The leading conditional distributes unions of whole literal tuples, preserving * each exact alternative. */ type SelectedNeonEnv = Keys extends readonly string[] ? number extends Keys["length"] ? OptionalFilteredNeonEnv : TupleHasUnion extends true ? OptionalFilteredNeonEnv : FilteredNeonEnv : never; type StorageCredentialEnvKey = "AWS_ACCESS_KEY_ID" | "AWS_SECRET_ACCESS_KEY"; type StorageKeyPairError = { readonly "fetchEnv keys must include AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY together": never; }; type TupleDefinitelyContains = Keys extends readonly [infer Head extends string, ...infer Tail extends readonly string[]] ? [Head] extends [Key] ? true : TupleDefinitelyContains : false; type TupleDefinitelyContainsStoragePair = TupleDefinitelyContains extends true ? TupleDefinitelyContains extends true ? true : false : false; /** * Reject a fixed key tuple that contains only one half of the storage credential. Dynamic * arrays are checked at runtime because their contents are not known to TypeScript. */ type InvalidStorageKeyTuple = Keys extends unknown ? number extends Keys["length"] ? never : [Extract] extends [never] ? never : TupleDefinitelyContainsStoragePair extends true ? never : Keys : never; type StorageKeyPairConstraint = [InvalidStorageKeyTuple] extends [never] ? unknown : StorageKeyPairError; type FetchEnvKeysFromArgs = Args[0] extends { keys: infer Keys extends readonly string[]; } ? Keys : never; type StorageKeyPairArgsConstraint = StorageKeyPairConstraint>; /** Preserve the same pair rule for callers that explicitly provide the legacy `K` generic. */ type StorageKeyUnionConstraint = [Extract] extends [never] ? unknown : StorageCredentialEnvKey extends K ? unknown : StorageKeyPairError; interface FetchEnvOptions { /** * Neon project id. **Required** — the management API addresses branches through their * project. Resolve it in your CLI (e.g. neonctl) and pass it in. */ projectId: string; /** * Neon branch — its **name** (e.g. `main`) or its id (`br-…`). **Required** (or pass the * legacy {@link FetchEnvOptions.branchId}). Resolved against the project's branches by * id first, then by name, so either form works. */ branch?: string; /** * @deprecated Legacy id-only field. Prefer {@link FetchEnvOptions.branch}, which accepts * a branch name or id. Still honored for backward compatibility; ignored when `branch` * is set. */ branchId?: string; /** * Neon API key. Resolved via the standard chain (option → `NEON_API_KEY` → * `~/.config/neonctl/credentials.json`) when omitted. Ignored when a custom `api` * is supplied. */ apiKey?: string; /** * Neon **management** API base URL (not the Auth base URL). Falls back to * `NEON_API_HOST`, then production. Ignored when a custom `api` is supplied. */ apiHost?: string; /** * Inject a custom NeonApi adapter. Primarily used by tests; production callers can rely * on the default real adapter built from `apiKey`. */ api?: NeonApi; /** * Role name to fetch credentials for. When omitted, the connection role is auto-picked: * the only role on the branch, else Neon's default owner (`neondb_owner`), else the * single role left after dropping the managed Auth/Data API roles * (`authenticator`/`anonymous`/`authenticated`). Throws {@link PlatformError} with * `PLATFORM_AMBIGUOUS_BRANCH_AUTH` only when more than one app role remains. */ roleName?: string; /** * Database name. When omitted, it is auto-picked: Neon's default `neondb` if present, * else the only database on the branch. Throws {@link PlatformError} with * `PLATFORM_AMBIGUOUS_BRANCH_AUTH` when the branch has several databases and none is * `neondb` (pass `databaseName` to disambiguate), and `PLATFORM_BRANCH_NOT_FOUND` when * the branch has no databases or the requested `databaseName` does not exist. */ databaseName?: string; } /** * Resolve the project + branch this process should target, then fetch live Neon * connection strings for that branch over the network. Async — calls the Neon API. * * Use this from build scripts and the `neon-env run` command, where top-level await is * fine. For application code that needs a synchronous bootstrap (most frameworks: Drizzle * config, Next.js, Vite, etc.), inject env vars via `neon-env run -- ` and use * {@link parseEnv} instead — same {@link NeonEnv} shape, but a sync call against * `process.env`. * * Filesystem- and env-agnostic: pass `projectId` and the target `branch` (name or id) * explicitly (resolve them in your CLI, e.g. neonctl). * * ```ts * import config from "../neon"; * import { fetchEnv } from "@neon/env"; * * const env = await fetchEnv(config, { projectId: "patient-art-12345", branch: "main" }); * const db = drizzle(neon(env.postgres.databaseUrl), { schema }); * ``` * * Pass `keys` to fetch only some of them — see the overload below. * * The package does **not** read `process.env`, mutate it, or touch the filesystem. Everything * it returns comes from the Neon API, so a value the API cannot produce (a one-time secret * issued to a previous call) is minted afresh rather than recovered. Callers that hold * persisted secrets and want to keep them use {@link fetchEnvReusingSecrets}, which decides * what is still valid and narrows this call's `keys` accordingly. */ declare function fetchEnv[]; }]>(config: C, ...args: Args & StorageKeyPairArgsConstraint>): Promise>>>; declare function fetchEnv = never>(config: C, options: [NoInfer] extends [never] ? never : FetchEnvOptions & { keys: readonly NoInfer[]; } & StorageKeyUnionConstraint>): Promise>>; declare function fetchEnv(config: C, options: FetchEnvOptions & { keys?: never; }): Promise>; /** Diagnostic-only fallback: valid keyed calls resolve through the exact overload above. */ declare function fetchEnv[]>(config: C, options: FetchEnvOptions & { keys: Keys; } & StorageKeyPairError): Promise; /** * The {@link fetchEnv} body, with the key selection as a plain argument and no generic * narrowing. Exists for callers that compute the selection at runtime — notably * {@link fetchEnvReusingSecrets}, which decides which keys it still needs by checking the * branch — since the public overload's `keys` is bound to a literal union those callers cannot * produce without asserting. * * `keys === null` selects everything the policy enables. */ /** * Project a fully-resolved {@link NeonEnv} into the OS-level `{ KEY: value }` pairs used * for cross-process transport. Named after the web-platform `.entries()` convention * (`URLSearchParams` / `Headers` / `FormData`); returns a `Record` rather than an * iterator of tuples since that's the shape env injection needs (wrap with * `Object.entries(...)` if you want literal `[key, value]` pairs). Used by `neon-env run` * to inject the vars into a subprocess's `process.env`. * * Walks the value at runtime so it works for any `NeonEnv` regardless of which * conditional namespaces are present. */ declare function toEntries(env: ResolvedNeonEnv): Record; /** * Any resolved env {@link toEntries} can project: a full {@link NeonEnv}, or the narrowed * result of a `keys`-filtered {@link fetchEnv} / {@link parseEnv} call. Every namespace and * property is optional so a filtered result — which legitimately carries only what was asked * for — projects to exactly the vars it holds instead of failing to type-check. */ type ResolvedNeonEnv = { [N in keyof NamespaceEnv]?: Partial }; //#endregion //#endregion //#region src/lib/parse-env.d.ts /** The static `preview.functions` record of a config, or an empty record when absent. */ type PreviewFunctionsOf = NonNullable extends { functions: infer F; } ? F : Record; /** The declared function slugs of a config (record keys), as a string union. */ type FunctionSlugOf = Extract, string>; /** * Human-readable hint surfaced as the **expected type** of `parseEnv`'s `scope` argument when * the policy declares no functions at all. Without it the argument's expected type is the bare * `never` {@link FunctionSlugOf} yields, and TypeScript reports the opaque `Type '"x"' is not * assignable to type 'never'`; the literal turns that into a sentence naming the fix (and the * editor offers it as the single completion, so the empty completion list is explained rather * than just empty). Mirrors `NeonAuthRequiredHint` in `@neon/config`. */ type NoFunctionScopeHint = "this policy declares no `preview.functions`, so there is no function scope to read. Declare the function in `neon.ts` first, or omit the scope to read the branch env"; /** * The expected type of `parseEnv`'s function-slug `scope` argument: the caller's inferred slug * `S` normally, and the {@link NoFunctionScopeHint} message when the policy declares no * functions. Keeping `S` (rather than `FunctionSlugOf`) in the enabled branch is what makes * the returned `function` namespace exact — it stays the one function's env keys instead of * widening to every declared function's. */ type FunctionScopeField = [FunctionSlugOf] extends [never] ? NoFunctionScopeHint : S; /** The declared env-var keys of one function `S`, as a string union. */ type FunctionEnvKeysOf = S extends keyof PreviewFunctionsOf ? NonNullable[S]> extends { env: infer E; } ? Extract : never : never; /** * The extra `function` namespace added to `parseEnv`'s result when called with a function * slug scope: the declared env-var keys for that function, each resolved to a `string`. */ type NeonFunctionEnv = { function: Record, string>; }; /** * Synchronous, network-free counterpart to {@link fetchEnv}. Reads `process.env`, validates * the required Neon env vars with zod, and returns the same {@link NeonEnv} shape — so the * rest of your app touches `env.postgres.databaseUrl` instead of stringly-typed * `process.env.DATABASE_URL` lookups. * * Designed for the **"env-vars-already-injected"** path: * - You wrapped your dev command with `neon-env run -- ` or `neon dev`. * - Your platform (Vercel, Fly, Railway, …) injected the vars via its own integration. * - You are **inside a deployed Neon Function**, whose env was uploaded at `config apply`. * * Unlike the old API, `parseEnv` does **not** take a branch name: the secret set is now * static (top-level `config.auth` / `config.dataApi`), so it reads those directly without * evaluating the per-branch closure. * * The second argument is a **scope** or a **key filter**: * - omitted — *external* scope (app bootstrap, build scripts, your dev machine). Returns the * full `{ postgres, auth?, dataApi?, … }` the policy enables. * - a **function slug** (a key of `config.preview.functions`) — *function* scope: you are * running inside that function. Returns the same branch secrets **plus** a typed * `function` namespace with the function's declared env-var keys. The slug autocompletes * from the policy ({@link FunctionSlugOf}) and an undeclared one is a type error. * - an **array of OS-level env-var keys** (e.g. `["DATABASE_URL", "NEON_AUTH_BASE_URL"]`) — * *filtered* mode: only those vars are required and returned, as a narrowed namespaced * shape. The keys autocomplete from the policy ({@link SelectableEnvKey}), so you can only * pick vars the policy actually enables. Use this when a process needs just a subset (a * Next.js app that reads `DATABASE_URL` but not `DATABASE_URL_UNPOOLED`, say) and you don't * want `parseEnv` to throw over vars you never use. * * Throws `PlatformError(EnvNotInjected)` listing every missing/invalid var when the env * isn't fully populated, with a fix hint pointing back at `neon dev` / `neon-env run`. * * ```ts * import config from "../neon"; * import { parseEnv } from "@neon/env"; * * // External (app / build): * const env = parseEnv(config); * const db = drizzle(neon(env.postgres.databaseUrl), { schema }); * * // Inside the "hello" function: * const env = parseEnv(config, "hello"); * env.function.resendApiKey; // typed from hello's declared env keys * * // Filtered: only enforce + return the pooled URL. * const { postgres } = parseEnv(config, ["DATABASE_URL"]); * postgres.databaseUrl; // string — `databaseUrlUnpooled` is absent * ``` */ declare function parseEnv(config: C): NeonEnv; declare function parseEnv>(config: C, scope: FunctionScopeField): NeonEnv & NeonFunctionEnv; declare function parseEnv>(config: C, keys: readonly K[]): FilteredNeonEnv; //#endregion export { type FetchEnvOptions, type FilteredNeonEnv, type FunctionSlugOf, NEON_ENV_VAR_KEYS, type NeonAiGatewayEnv, type NeonAuthEnv, type NeonBranchEnv, type NeonDataApiEnv, type NeonEnv, type NeonFunctionEnv, type NeonPostgresEnv, type NeonStorageEnv, type ResolvedNeonEnv, type SelectableEnvKey, type SelectedNeonEnv, fetchEnv, parseEnv, toEntries }; //# sourceMappingURL=index.d.ts.map