@neondatabase/env 1.1.5 → 1.2.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 +17 -2
- package/dist/cli.js +20 -15
- package/dist/cli.js.map +1 -1
- package/dist/env.js +120 -7
- package/dist/env.js.map +1 -1
- package/dist/index.d.ts +37 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +64 -9
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/env.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ErrorCode, PlatformError, createNeonApiFromOptions, deriveCredentialScopes, resolveConfig } from "@neon/config/v1";
|
|
1
|
+
import { ErrorCode, PlatformError, createNeonApiFromOptions, deriveCredentialScopes, isPlatformError, resolveConfig } from "@neon/config/v1";
|
|
2
2
|
//#region ../../internals/env-core/dist/env.js
|
|
3
3
|
/**
|
|
4
4
|
* The Neon env core — resolving a branch's env from the Neon API, and projecting it into
|
|
@@ -83,6 +83,19 @@ const NEON_ENV_VAR_KEYS = {
|
|
|
83
83
|
baseUrl: "NEON_AI_GATEWAY_BASE_URL"
|
|
84
84
|
}
|
|
85
85
|
};
|
|
86
|
+
const FUNCTION_SLUG = /^[a-z0-9]{1,20}$/;
|
|
87
|
+
const FUNCTION_BASE_URL_KEY = /^NEON_FUNCTION_([A-Z0-9]{1,20})_BASE_URL$/;
|
|
88
|
+
function functionBaseUrlKey(slug) {
|
|
89
|
+
if (!FUNCTION_SLUG.test(slug)) throw new Error(`functionBaseUrlKey: ${JSON.stringify(slug)} is not a function slug ([a-z0-9]{1,20}).`);
|
|
90
|
+
return `NEON_FUNCTION_${slug.toUpperCase()}_BASE_URL`;
|
|
91
|
+
}
|
|
92
|
+
function parseFunctionBaseUrlKey(key) {
|
|
93
|
+
const match = FUNCTION_BASE_URL_KEY.exec(key);
|
|
94
|
+
return match ? match[1].toLowerCase() : null;
|
|
95
|
+
}
|
|
96
|
+
function isFunctionBaseUrlKey(key) {
|
|
97
|
+
return parseFunctionBaseUrlKey(key) !== null;
|
|
98
|
+
}
|
|
86
99
|
async function fetchEnv(config, options) {
|
|
87
100
|
if (options.keys) assertStorageCredentialKeyPair(options.keys);
|
|
88
101
|
return fetchEnvKeys(config, options, options.keys ?? null);
|
|
@@ -106,11 +119,15 @@ function requiredValue(value, description) {
|
|
|
106
119
|
* `keys === null` selects everything the policy enables.
|
|
107
120
|
*/
|
|
108
121
|
async function fetchEnvKeys(config, options, keys) {
|
|
122
|
+
return (await fetchEnvKeysState(config, options, keys)).env;
|
|
123
|
+
}
|
|
124
|
+
async function fetchEnvKeysState(config, options, keys) {
|
|
109
125
|
const api = options.api ?? createApiFromOptions(options);
|
|
110
126
|
const projectId = options.projectId;
|
|
111
127
|
const { branch, desired } = await resolveBranchPolicy(config, options, api);
|
|
112
128
|
const selection = keys ? new Set(keys) : null;
|
|
113
|
-
const
|
|
129
|
+
const omitted = new Set(options.omitKeys ?? []);
|
|
130
|
+
const wants = (key) => !omitted.has(key) && (selection === null || selection.has(key));
|
|
114
131
|
const result = {};
|
|
115
132
|
const K = NEON_ENV_VAR_KEYS;
|
|
116
133
|
const wantsPooled = wants(K.postgres.databaseUrl);
|
|
@@ -118,7 +135,17 @@ async function fetchEnvKeys(config, options, keys) {
|
|
|
118
135
|
const wantsAuth = desired.authEnabled && (wants(K.auth.baseUrl) || wants(K.auth.jwksUrl));
|
|
119
136
|
const wantsDataApi = desired.dataApiEnabled && wants(K.dataApi.url);
|
|
120
137
|
const gatewayEnabled = desired.preview?.aiGatewayEnabled ?? false;
|
|
121
|
-
const
|
|
138
|
+
const functionUrlMode = options.functionUrls ?? "policy";
|
|
139
|
+
const declaredSlugs = (desired.preview?.functions ?? []).map((fn) => fn.slug);
|
|
140
|
+
const selectedFunctionKeys = selection === null ? [] : [...selection].filter(isFunctionBaseUrlKey);
|
|
141
|
+
const constructSlugs = functionUrlSlugsToConstruct({
|
|
142
|
+
functionUrlMode,
|
|
143
|
+
selection,
|
|
144
|
+
declaredSlugs,
|
|
145
|
+
selectedFunctionKeys,
|
|
146
|
+
wants
|
|
147
|
+
});
|
|
148
|
+
const needsUnpooled = wantsUnpooled || gatewayEnabled && wants(K.aiGateway.baseUrl) || constructSlugs.length > 0;
|
|
122
149
|
const needsConnectionTarget = wantsPooled || needsUnpooled;
|
|
123
150
|
const needsDatabase = needsConnectionTarget || wantsDataApi;
|
|
124
151
|
const [roles, databases] = await Promise.all([needsConnectionTarget ? api.listBranchRoles(projectId, branch.id) : Promise.resolve([]), needsDatabase ? api.listBranchDatabases(projectId, branch.id) : Promise.resolve([])]);
|
|
@@ -207,7 +234,67 @@ async function fetchEnvKeys(config, options, keys) {
|
|
|
207
234
|
result.aiGateway = gateway;
|
|
208
235
|
}
|
|
209
236
|
}
|
|
210
|
-
|
|
237
|
+
const wantsAnyFunctionUrl = selection === null || selectedFunctionKeys.length > 0;
|
|
238
|
+
const functions = {};
|
|
239
|
+
let functionUrlsUnavailable = false;
|
|
240
|
+
if (functionUrlMode === "all-live" && wantsAnyFunctionUrl) {
|
|
241
|
+
const listed = options.listedFunctions === void 0 ? await listFunctionInvocationUrls(api, projectId, branch.id) : listedFromSnapshots(options.listedFunctions);
|
|
242
|
+
if (listed.status === "unavailable") {
|
|
243
|
+
if (selection === null) functionUrlsUnavailable = true;
|
|
244
|
+
} else for (const fn of listed.functions) {
|
|
245
|
+
if (!wants(functionBaseUrlKey(fn.slug))) continue;
|
|
246
|
+
functions[fn.slug] = { baseUrl: asEnvBaseUrl(fn.invocationUrl) };
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const missingConstructSlugs = constructSlugs.filter((slug) => functions[slug] === void 0);
|
|
250
|
+
if (missingConstructSlugs.length > 0) {
|
|
251
|
+
const uri = requiredValue(unpooled, "direct connection URI for function invocation URLs").uri;
|
|
252
|
+
for (const slug of missingConstructSlugs) functions[slug] = { baseUrl: functionInvocationUrl(branch.id, slug, uri) };
|
|
253
|
+
}
|
|
254
|
+
assertSelectedFunctionUrls(selectedFunctionKeys, functions);
|
|
255
|
+
if (Object.keys(functions).length > 0) result.functions = functions;
|
|
256
|
+
return {
|
|
257
|
+
env: result,
|
|
258
|
+
functionUrlsUnavailable
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function functionUrlSlugsToConstruct(args) {
|
|
262
|
+
const slugs = [];
|
|
263
|
+
if (args.functionUrlMode === "policy" && args.selection === null) {
|
|
264
|
+
for (const slug of args.declaredSlugs) if (args.wants(functionBaseUrlKey(slug))) slugs.push(slug);
|
|
265
|
+
return slugs;
|
|
266
|
+
}
|
|
267
|
+
for (const key of args.selectedFunctionKeys) {
|
|
268
|
+
const slug = parseFunctionBaseUrlKey(key);
|
|
269
|
+
if (slug !== null) slugs.push(slug);
|
|
270
|
+
}
|
|
271
|
+
return slugs;
|
|
272
|
+
}
|
|
273
|
+
function listedFromSnapshots(snapshots) {
|
|
274
|
+
return {
|
|
275
|
+
status: "ok",
|
|
276
|
+
functions: snapshots.filter((fn) => fn.invocationUrl !== "").map((fn) => ({
|
|
277
|
+
slug: fn.slug,
|
|
278
|
+
invocationUrl: fn.invocationUrl
|
|
279
|
+
})).sort((left, right) => left.slug.localeCompare(right.slug))
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function assertSelectedFunctionUrls(keys, functions) {
|
|
283
|
+
for (const key of keys) {
|
|
284
|
+
const slug = parseFunctionBaseUrlKey(key);
|
|
285
|
+
if (slug === null || functions[slug] === void 0) throw new Error(`fetchEnv: missing ${key}.`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async function listFunctionInvocationUrls(api, projectId, branchId) {
|
|
289
|
+
try {
|
|
290
|
+
return listedFromSnapshots(await api.listBranchFunctions(projectId, branchId));
|
|
291
|
+
} catch (error) {
|
|
292
|
+
if (isPlatformError(error) && error.code === ErrorCode.FeatureUnavailable) return {
|
|
293
|
+
status: "unavailable",
|
|
294
|
+
error
|
|
295
|
+
};
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
211
298
|
}
|
|
212
299
|
/**
|
|
213
300
|
* Resolve the target branch and evaluate the policy against it — the first thing any
|
|
@@ -309,15 +396,40 @@ async function mintBranchCredential(args) {
|
|
|
309
396
|
* `ep-x.c-3.us-east-2.aws.neon.tech` yields the gateway host
|
|
310
397
|
* `<branchId>-api.ai.c-3.us-east-2.aws.neon.tech`. The cell prefix is **load-bearing** —
|
|
311
398
|
* the gateway is cell-routed, so dropping `c-N.` resolves to the wrong (or no) host.
|
|
399
|
+
*
|
|
400
|
+
* Function invocation URLs use the same suffix: `<branchId>-<slug>.compute.<suffix>`.
|
|
312
401
|
*/
|
|
313
|
-
function
|
|
402
|
+
function connectionHostSuffix(connectionUri) {
|
|
314
403
|
let connectionHost = "";
|
|
315
404
|
try {
|
|
316
405
|
connectionHost = new URL(connectionUri).hostname;
|
|
317
406
|
} catch {
|
|
318
407
|
connectionHost = "";
|
|
319
408
|
}
|
|
320
|
-
return
|
|
409
|
+
return connectionHost.split(".").slice(1).join(".");
|
|
410
|
+
}
|
|
411
|
+
function aiGatewayHost(branchId, connectionUri) {
|
|
412
|
+
return `${branchId}-api.ai.${connectionHostSuffix(connectionUri)}`;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* The API's `invocation_url` ends with `/` so paths concatenate onto it. Neon `*_BASE_URL`
|
|
416
|
+
* vars are origin-only (`NEON_AUTH_BASE_URL`, `NEON_AI_GATEWAY_BASE_URL`).
|
|
417
|
+
*/
|
|
418
|
+
function asEnvBaseUrl(url) {
|
|
419
|
+
let parsed;
|
|
420
|
+
try {
|
|
421
|
+
parsed = new URL(url);
|
|
422
|
+
} catch {
|
|
423
|
+
throw new Error(`fetchEnv: function invocation URL is not a URL: ${JSON.stringify(url)}`);
|
|
424
|
+
}
|
|
425
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error(`fetchEnv: function invocation URL must be http(s): ${JSON.stringify(url)}`);
|
|
426
|
+
return parsed.origin;
|
|
427
|
+
}
|
|
428
|
+
/** Derived from the connection URI so undeployed functions have a cell-routed URL. */
|
|
429
|
+
function functionInvocationUrl(branchId, slug, connectionUri) {
|
|
430
|
+
const suffix = connectionHostSuffix(connectionUri);
|
|
431
|
+
if (suffix === "") throw new Error(`fetchEnv: cannot derive the invocation URL for function "${slug}": the direct connection URI has no host suffix.`);
|
|
432
|
+
return `https://${branchId}-${slug}.compute.${suffix}`;
|
|
321
433
|
}
|
|
322
434
|
/** The AI Gateway's bare base URL (`NEON_AI_GATEWAY_BASE_URL`) on the branch gateway host. */
|
|
323
435
|
function aiGatewayBaseUrl(branchId, connectionUri) {
|
|
@@ -410,9 +522,10 @@ function toEntries(env) {
|
|
|
410
522
|
put(K.storage.region, env.storage?.region);
|
|
411
523
|
put(K.aiGateway.apiKey, env.aiGateway?.apiKey);
|
|
412
524
|
put(K.aiGateway.baseUrl, env.aiGateway?.baseUrl);
|
|
525
|
+
if (env.functions) for (const slug of Object.keys(env.functions).sort()) put(functionBaseUrlKey(slug), env.functions[slug]?.baseUrl);
|
|
413
526
|
return out;
|
|
414
527
|
}
|
|
415
528
|
//#endregion
|
|
416
|
-
export { fetchEnv as a,
|
|
529
|
+
export { fetchEnv as a, isFunctionBaseUrlKey as c, previewCredentialScopes as d, resolveBranchPolicy as f, credentialName as i, parseFunctionBaseUrlKey as l, createApiFromOptions as n, fetchEnvKeysState as o, toEntries as p, credentialEnvKeys as r, functionBaseUrlKey as s, NEON_ENV_VAR_KEYS as t, policyEnvKeys as u };
|
|
417
530
|
|
|
418
531
|
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","names":[],"sources":["../../../internals/env-core/dist/env.js"],"sourcesContent":["import { ErrorCode, PlatformError, createNeonApiFromOptions, deriveCredentialScopes, resolveConfig } from \"@neon/config/v1\";\n//#region src/env.ts\n/**\n* The Neon env core — resolving a branch's env from the Neon API, and projecting it into\n* OS-level `{ KEY: value }` pairs.\n*\n* Private, and bundled into both consumers: `@neon/env` publishes it as `fetchEnv` /\n* `toEntries`, and the `neon` CLI needs the credential-reuse half in `reuse-secrets.ts`.\n* See `README.md` for why it is not published.\n*\n* The counterpart that reads `process.env` — `parseEnv` and its zod schemas — is not here. It\n* has no consumer outside `@neon/env`, so it stays in that package and imports this.\n*/\n/**\n* Mapping between the {@link NeonEnv} property paths and the OS-level env-var keys used\n* for cross-process transport (via `.env` files, `env run -- <cmd>`, or anything else\n* that talks to `process.env`).\n*\n* Each top-level key here is a {@link NeonEnv} namespace; the inner record maps the\n* camelCase property names exposed to TypeScript to the UPPER_SNAKE env-var names used\n* by the OS. Keep this in sync with {@link postgresEnvSchema} / {@link authEnvSchema} /\n* {@link dataApiEnvSchema}.\n*/\n/**\n* Neon's default branch owner role, created with every project. This is the role a\n* `DATABASE_URL` should connect as.\n*/\nconst NEON_DEFAULT_OWNER_ROLE = \"neondb_owner\";\n/**\n* Neon's default database, created with every project. When a branch has several databases\n* and none was requested, this is preferred for the `DATABASE_URL` so the common case (a\n* user added a second database next to `neondb`) auto-picks without asking.\n*/\nconst NEON_DEFAULT_DATABASE = \"neondb\";\n/**\n* Roles Neon provisions for the Auth / Data API (PostgREST) stack. They exist to back\n* RLS-scoped Data API requests authenticated by JWT — never to hold a `DATABASE_URL` —\n* so they're skipped when auto-picking the connection role. Enabling Neon Auth or the\n* Data API (`neon config apply`) adds these next to the owner role, which is why a plain\n* branch routinely reports more than one role.\n*/\nconst NEON_MANAGED_AUTH_ROLES = /* @__PURE__ */ new Set([\n\t\"authenticator\",\n\t\"anonymous\",\n\t\"authenticated\"\n]);\nconst NEON_ENV_VAR_KEYS = {\n\t/**\n\t* Branch identity. `NEON_BRANCH` carries the branch **name** and is injected into the\n\t* Neon Functions runtime on every branch (including the default) by default. `env pull` /\n\t* `neon dev` / `neon-env run` emit it too so local dev mirrors the deployed runtime.\n\t*/\n\tbranch: { name: \"NEON_BRANCH\" },\n\tpostgres: {\n\t\tdatabaseUrl: \"DATABASE_URL\",\n\t\tdatabaseUrlUnpooled: \"DATABASE_URL_UNPOOLED\"\n\t},\n\tauth: {\n\t\tbaseUrl: \"NEON_AUTH_BASE_URL\",\n\t\tjwksUrl: \"NEON_AUTH_JWKS_URL\"\n\t},\n\tdataApi: { url: \"NEON_DATA_API_URL\" },\n\t/**\n\t* Object storage (Preview). The S3 SDKs read `AWS_*` from their standard config chain, so\n\t* a branch credential + `neon dev` / `env pull` makes object storage work from env alone.\n\t* `region` is injected under the SDK-standard `AWS_REGION`.\n\t*/\n\tstorage: {\n\t\taccessKeyId: \"AWS_ACCESS_KEY_ID\",\n\t\tsecretAccessKey: \"AWS_SECRET_ACCESS_KEY\",\n\t\tendpoint: \"AWS_ENDPOINT_URL_S3\",\n\t\tregion: \"AWS_REGION\"\n\t},\n\t/**\n\t* AI Gateway (Preview). Exposed under the Neon-branded env vars the deployed Functions\n\t* runtime injects: `apiKey` is the minted credential's bearer (`NEON_AI_GATEWAY_TOKEN`)\n\t* and `baseUrl` is the bare branch gateway host (`NEON_AI_GATEWAY_BASE_URL`,\n\t* `scheme://host`, no path). Clients like `@neon/ai-sdk-provider` read these and append the\n\t* dialect route (`/v1`, `/openai/v1`, `/anthropic/v1`) themselves (https://github.com/vercel/ai/pull/15997).\n\t*/\n\taiGateway: {\n\t\tapiKey: \"NEON_AI_GATEWAY_TOKEN\",\n\t\tbaseUrl: \"NEON_AI_GATEWAY_BASE_URL\"\n\t}\n};\nasync function fetchEnv(config, options) {\n\tif (options.keys) assertStorageCredentialKeyPair(options.keys);\n\treturn fetchEnvKeys(config, options, options.keys ?? null);\n}\nfunction assertStorageCredentialKeyPair(keys) {\n\tif (keys.includes(NEON_ENV_VAR_KEYS.storage.accessKeyId) === keys.includes(NEON_ENV_VAR_KEYS.storage.secretAccessKey)) return;\n\tthrow new TypeError(\"fetchEnv: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be selected together. Pass both in `keys`, or omit both.\");\n}\n/** Fail loudly when selected-key dependency planning and execution disagree. */\nfunction requiredValue(value, description) {\n\tif (value === null) throw new Error(`fetchEnv: missing ${description}.`);\n\treturn value;\n}\n/**\n* The {@link fetchEnv} body, with the key selection as a plain argument and no generic\n* narrowing. Exists for callers that compute the selection at runtime — notably\n* {@link fetchEnvReusingSecrets}, which decides which keys it still needs by checking the\n* branch — since the public overload's `keys` is bound to a literal union those callers cannot\n* produce without asserting.\n*\n* `keys === null` selects everything the policy enables.\n*/\nasync function fetchEnvKeys(config, options, keys) {\n\tconst api = options.api ?? createApiFromOptions(options);\n\tconst projectId = options.projectId;\n\tconst { branch, desired } = await resolveBranchPolicy(config, options, api);\n\tconst selection = keys ? new Set(keys) : null;\n\tconst wants = (key) => selection === null || selection.has(key);\n\tconst result = {};\n\tconst K = NEON_ENV_VAR_KEYS;\n\tconst wantsPooled = wants(K.postgres.databaseUrl);\n\tconst wantsUnpooled = wants(K.postgres.databaseUrlUnpooled);\n\tconst wantsAuth = desired.authEnabled && (wants(K.auth.baseUrl) || wants(K.auth.jwksUrl));\n\tconst wantsDataApi = desired.dataApiEnabled && wants(K.dataApi.url);\n\tconst gatewayEnabled = desired.preview?.aiGatewayEnabled ?? false;\n\tconst needsUnpooled = wantsUnpooled || gatewayEnabled && wants(K.aiGateway.baseUrl);\n\tconst needsConnectionTarget = wantsPooled || needsUnpooled;\n\tconst needsDatabase = needsConnectionTarget || wantsDataApi;\n\tconst [roles, databases] = await Promise.all([needsConnectionTarget ? api.listBranchRoles(projectId, branch.id) : Promise.resolve([]), needsDatabase ? api.listBranchDatabases(projectId, branch.id) : Promise.resolve([])]);\n\tconst databaseName = needsDatabase ? pickDatabaseName(databases, branch, options.databaseName) : null;\n\tconst connectionTarget = needsConnectionTarget ? {\n\t\troleName: pickRoleName(roles, branch, options.roleName),\n\t\tdatabaseName: requiredValue(databaseName, \"database for a selected connection URI\")\n\t} : null;\n\tconst getConnectionUri = (pooled) => {\n\t\tconst target = requiredValue(connectionTarget, \"role and database for a selected connection URI\");\n\t\treturn api.getConnectionUri(projectId, {\n\t\t\tbranchId: branch.id,\n\t\t\t...target,\n\t\t\tpooled\n\t\t});\n\t};\n\tconst [pooled, unpooled, authSnapshot, dataApiSnapshot] = await Promise.all([\n\t\twantsPooled ? getConnectionUri(true) : Promise.resolve(null),\n\t\tneedsUnpooled ? getConnectionUri(false) : Promise.resolve(null),\n\t\twantsAuth ? api.getNeonAuth(projectId, branch.id) : Promise.resolve(null),\n\t\twantsDataApi ? api.getNeonDataApi(projectId, branch.id, requiredValue(databaseName, \"database for the selected Data API URL\")) : Promise.resolve(null)\n\t]);\n\tconst postgres = {};\n\tif (wantsPooled) postgres.databaseUrl = requiredValue(pooled, \"pooled connection URI response\").uri;\n\tif (wantsUnpooled) postgres.databaseUrlUnpooled = requiredValue(unpooled, \"direct connection URI response\").uri;\n\tif (Object.keys(postgres).length > 0) result.postgres = postgres;\n\tif (wants(K.branch.name)) result.branch = { name: branch.name };\n\tif (wantsAuth) {\n\t\tif (!authSnapshot) throw new PlatformError(ErrorCode.NotFound, [`fetchEnv: branch policy enables auth but no Neon Auth integration is enabled on branch ${branch.name} (${branch.id}).`, \"Enable it via `apply(config, { projectId, branchId })` (or `npx neon …`), in the Neon Console — then re-run fetchEnv. Or return auth.enabled=false.\"].join(\" \"), { details: {\n\t\t\tprojectId,\n\t\t\tbranchId: branch.id\n\t\t} });\n\t\tconst auth = {};\n\t\tif (wants(K.auth.baseUrl)) auth.baseUrl = authSnapshot.baseUrl ?? \"\";\n\t\tif (wants(K.auth.jwksUrl)) auth.jwksUrl = authSnapshot.jwksUrl ?? \"\";\n\t\tresult.auth = auth;\n\t}\n\tif (wantsDataApi) {\n\t\tif (!dataApiSnapshot) {\n\t\t\tconst selectedDatabase = requiredValue(databaseName, \"database for the selected Data API URL\");\n\t\t\tthrow new PlatformError(ErrorCode.NotFound, [`fetchEnv: branch policy enables dataApi but no Data API integration is enabled on branch ${branch.name} (${branch.id}) database ${selectedDatabase}.`, \"Enable it via `apply(config, { projectId, branchId })` or in the Neon Console — then re-run fetchEnv. Or return dataApi.enabled=false.\"].join(\" \"), { details: {\n\t\t\t\tprojectId,\n\t\t\t\tbranchId: branch.id,\n\t\t\t\tdatabaseName: selectedDatabase\n\t\t\t} });\n\t\t}\n\t\tresult.dataApi = { url: dataApiSnapshot.url };\n\t}\n\tconst storageEnabled = (desired.preview?.buckets.length ?? 0) > 0;\n\tconst wantsStorage = storageEnabled && (wants(K.storage.accessKeyId) || wants(K.storage.secretAccessKey) || wants(K.storage.endpoint) || wants(K.storage.region));\n\tconst wantsGateway = gatewayEnabled && (wants(K.aiGateway.apiKey) || wants(K.aiGateway.baseUrl));\n\tconst wantsStorageCredential = storageEnabled && (wants(K.storage.accessKeyId) || wants(K.storage.secretAccessKey));\n\tconst wantsGatewayCredential = gatewayEnabled && wants(K.aiGateway.apiKey);\n\tconst wantsCredential = wantsStorageCredential || wantsGatewayCredential;\n\tif (wantsStorage || wantsGateway) {\n\t\tlet storage = null;\n\t\tif (wantsStorage) {\n\t\t\tstorage = await api.getProjectBranchStorage(projectId, branch.id);\n\t\t\tif (!storage) throw new PlatformError(ErrorCode.NotFound, [`fetchEnv: branch policy declares object storage (preview.buckets) but storage is not enabled on branch ${branch.name} (${branch.id}).`, \"Enable it via `apply(config, { projectId, branchId })` (or in the Neon Console) — then re-run fetchEnv. Or remove preview.buckets.\"].join(\" \"), { details: {\n\t\t\t\tprojectId,\n\t\t\t\tbranchId: branch.id\n\t\t\t} });\n\t\t}\n\t\tconst secrets = wantsCredential ? await mintBranchCredential({\n\t\t\tapi,\n\t\t\tprojectId,\n\t\t\tbranchId: branch.id,\n\t\t\tbranchName: branch.name,\n\t\t\tscopes: previewCredentialScopes(desired.preview, {\n\t\t\t\tstorage: wantsStorageCredential,\n\t\t\t\taiGateway: wantsGatewayCredential\n\t\t\t})\n\t\t}) : null;\n\t\tif (storage) {\n\t\t\tconst storageEnv = {};\n\t\t\tif (secrets && wants(K.storage.accessKeyId)) storageEnv.accessKeyId = secrets.accessKeyId;\n\t\t\tif (secrets && wants(K.storage.secretAccessKey)) storageEnv.secretAccessKey = secrets.secretAccessKey;\n\t\t\tif (wants(K.storage.endpoint)) storageEnv.endpoint = storage.s3Endpoint;\n\t\t\tif (wants(K.storage.region)) storageEnv.region = storage.region;\n\t\t\tresult.storage = storageEnv;\n\t\t}\n\t\tif (wantsGateway) {\n\t\t\tconst gateway = {};\n\t\t\tif (secrets && wants(K.aiGateway.apiKey)) gateway.apiKey = secrets.apiToken;\n\t\t\tif (wants(K.aiGateway.baseUrl)) gateway.baseUrl = aiGatewayBaseUrl(branch.id, requiredValue(unpooled, \"direct connection URI for the selected AI Gateway base URL\").uri);\n\t\t\tresult.aiGateway = gateway;\n\t\t}\n\t}\n\treturn result;\n}\n/**\n* Resolve the target branch and evaluate the policy against it — the first thing any\n* branch-scoped operation needs. Shared by {@link fetchEnv} and {@link fetchEnvReusingSecrets}\n* so the two agree on which branch they're talking about and what it has enabled.\n*/\nasync function resolveBranchPolicy(config, options, api) {\n\tconst projectId = options.projectId;\n\tconst branches = await api.listBranches(projectId);\n\tif (branches.length === 0) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: project ${projectId} has no branches.`, \"Deploy your neon.ts policy (or create a branch) first, or pick a different project id.\"].join(\" \"), { details: { projectId } });\n\tconst branchRef = options.branch ?? options.branchId;\n\tif (!branchRef) throw new PlatformError(ErrorCode.BranchNotFound, [\"fetchEnv: no branch provided.\", \"Pass `branch` with a branch name (e.g. `main`) or id (`br-…`).\"].join(\" \"), { details: { projectId } });\n\tconst branch = resolveBranch(branchRef, branches);\n\treturn {\n\t\tbranch,\n\t\tdesired: resolveConfig(config, {\n\t\t\tname: branch.name,\n\t\t\tid: branch.id,\n\t\t\texists: true,\n\t\t\t...branch.parentId ? { parentId: branch.parentId } : {},\n\t\t\tisDefault: branch.isDefault,\n\t\t\tisProtected: branch.protected,\n\t\t\t...branch.expiresAt ? { expiresAt: branch.expiresAt } : {}\n\t\t})\n\t};\n}\n/**\n* Scopes the branch credential should carry for a resolved branch policy and optional key\n* selection. Only object storage and the AI Gateway *require* a credential; functions never\n* force one, but `functions:invoke` rides along when another selected feature mints one.\n*/\nfunction previewCredentialScopes(preview, selected) {\n\tif (!preview) return [];\n\tconst storage = preview.buckets.length > 0 && (selected?.storage ?? true);\n\tconst aiGateway = preview.aiGatewayEnabled && (selected?.aiGateway ?? true);\n\tif (!storage && !aiGateway) return [];\n\treturn deriveCredentialScopes({\n\t\tstorage,\n\t\taiGateway,\n\t\tfunctions: preview.functions.length > 0\n\t});\n}\n/** The `name` this tool stamps on every credential it mints, so it can recognize its own. */\nfunction credentialName(branchName) {\n\treturn `neon-env ${branchName}`;\n}\n/** The env-var keys a branch credential's secrets surface under, in emit order. */\nfunction credentialEnvKeys(flags) {\n\treturn [...flags.storage ? [NEON_ENV_VAR_KEYS.storage.accessKeyId, NEON_ENV_VAR_KEYS.storage.secretAccessKey] : [], ...flags.aiGateway ? [NEON_ENV_VAR_KEYS.aiGateway.apiKey] : []];\n}\n/**\n* Every OS-level env var a resolved branch policy produces, in emit order. Lets a caller\n* subtract the ones it already holds and pass the rest as {@link fetchEnv}'s `keys`, without\n* re-deriving which vars a policy implies.\n*/\nfunction policyEnvKeys(desired) {\n\tconst K = NEON_ENV_VAR_KEYS;\n\treturn [\n\t\tK.postgres.databaseUrl,\n\t\tK.postgres.databaseUrlUnpooled,\n\t\tK.branch.name,\n\t\t...desired.authEnabled ? [K.auth.baseUrl, K.auth.jwksUrl] : [],\n\t\t...desired.dataApiEnabled ? [K.dataApi.url] : [],\n\t\t...(desired.preview?.buckets.length ?? 0) > 0 ? [\n\t\t\tK.storage.accessKeyId,\n\t\t\tK.storage.secretAccessKey,\n\t\t\tK.storage.endpoint,\n\t\t\tK.storage.region\n\t\t] : [],\n\t\t...desired.preview?.aiGatewayEnabled ? [K.aiGateway.apiKey, K.aiGateway.baseUrl] : []\n\t];\n}\n/**\n* Mint the branch credential backing object storage / the AI Gateway.\n*\n* `api_token` and `s3_secret_access_key` come back **exactly once** — they are not stored\n* server-side and the list endpoint returns metadata only — so the caller's copy is the only\n* copy. That is why {@link fetchEnv} mints rather than fetches: there is nothing to fetch. A\n* caller that already holds a valid copy should leave the secret keys out of `keys` (see\n* {@link fetchEnvReusingSecrets}) instead of minting one it will discard.\n*/\nasync function mintBranchCredential(args) {\n\tconst minted = await args.api.createCredential(args.projectId, args.branchId, {\n\t\tscopes: args.scopes,\n\t\tprincipalType: \"user\",\n\t\tname: credentialName(args.branchName)\n\t});\n\treturn {\n\t\taccessKeyId: minted.tokenId,\n\t\tsecretAccessKey: minted.s3SecretAccessKey,\n\t\tapiToken: minted.apiToken\n\t};\n}\n/**\n* The AI Gateway is a **branch-scoped host** — `<branchId>-api.ai.<host-suffix>` — NOT the\n* control-plane API origin. Derive the suffix from the branch's own Postgres connection host\n* by dropping only the endpoint label (the first segment) and keeping everything after it,\n* including any infra cell prefix (`c-N.`): a connection host of\n* `ep-x.c-3.us-east-2.aws.neon.tech` yields the gateway host\n* `<branchId>-api.ai.c-3.us-east-2.aws.neon.tech`. The cell prefix is **load-bearing** —\n* the gateway is cell-routed, so dropping `c-N.` resolves to the wrong (or no) host.\n*/\nfunction aiGatewayHost(branchId, connectionUri) {\n\tlet connectionHost = \"\";\n\ttry {\n\t\tconnectionHost = new URL(connectionUri).hostname;\n\t} catch {\n\t\tconnectionHost = \"\";\n\t}\n\treturn `${branchId}-api.ai.${connectionHost.split(\".\").slice(1).join(\".\")}`;\n}\n/** The AI Gateway's bare base URL (`NEON_AI_GATEWAY_BASE_URL`) on the branch gateway host. */\nfunction aiGatewayBaseUrl(branchId, connectionUri) {\n\treturn `https://${aiGatewayHost(branchId, connectionUri)}`;\n}\nfunction createApiFromOptions(options) {\n\treturn createNeonApiFromOptions(\"fetchEnv\", {\n\t\t...options.apiKey ? { apiKey: options.apiKey } : {},\n\t\t...options.apiHost ? { apiHost: options.apiHost } : {}\n\t});\n}\n/**\n* Resolve a branch ref — a name or an id — to a concrete branch. Matches by id first\n* (exact `br-…`), then by name; both are unique within a project, so the lookup is\n* unambiguous. This lets `.neon` files written by `neonctl` (which pin the branch *name*)\n* and explicit `br-…` ids both work.\n*/\nfunction resolveBranch(branch, branches) {\n\tconst match = branches.find((b) => b.id === branch) ?? branches.find((b) => b.name === branch);\n\tif (match) return match;\n\tthrow new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: branch ${JSON.stringify(branch)} not found on project (matched by id or name).`, `Existing branches: ${branches.map((b) => `${b.name} (${b.id})`).join(\", \")}.`].join(\" \"), { details: {\n\t\tbranch,\n\t\tavailable: branches.map((b) => `${b.name} (${b.id})`)\n\t} });\n}\nfunction pickRoleName(roles, branch, requested) {\n\tif (requested) {\n\t\tif (!roles.some((r) => r.name === requested)) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: role \"${requested}\" not found on branch ${branch.name} (${branch.id}).`, `Existing roles: ${roles.map((r) => r.name).join(\", \") || \"(none)\"}.`].join(\" \"), { details: {\n\t\t\tbranchId: branch.id,\n\t\t\troleName: requested,\n\t\t\tavailableRoles: roles.map((r) => r.name)\n\t\t} });\n\t\treturn requested;\n\t}\n\tif (roles.length === 0) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: branch ${branch.name} (${branch.id}) has no roles.`, \"Create one via the Neon console or pass `roleName` explicitly.\"].join(\" \"), { details: { branchId: branch.id } });\n\tif (roles.length === 1) return roles[0].name;\n\tconst owner = roles.find((r) => r.name === NEON_DEFAULT_OWNER_ROLE);\n\tif (owner) return owner.name;\n\tconst appRoles = roles.filter((r) => !NEON_MANAGED_AUTH_ROLES.has(r.name));\n\tif (appRoles.length === 1) return appRoles[0].name;\n\tthrow new PlatformError(ErrorCode.AmbiguousBranchAuth, [`fetchEnv: branch ${branch.name} (${branch.id}) has ${roles.length} roles and none is \"${NEON_DEFAULT_OWNER_ROLE}\"; cannot auto-pick.`, `Pass \\`roleName\\` explicitly. Available: ${roles.map((r) => r.name).join(\", \")}.`].join(\" \"), { details: {\n\t\tbranchId: branch.id,\n\t\tavailableRoles: roles.map((r) => r.name)\n\t} });\n}\nfunction pickDatabaseName(databases, branch, requested) {\n\tif (requested) {\n\t\tif (!databases.some((d) => d.name === requested)) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: database \"${requested}\" not found on branch ${branch.name} (${branch.id}).`, `Existing databases: ${databases.map((d) => d.name).join(\", \") || \"(none)\"}.`].join(\" \"), { details: {\n\t\t\tbranchId: branch.id,\n\t\t\tdatabaseName: requested,\n\t\t\tavailableDatabases: databases.map((d) => d.name)\n\t\t} });\n\t\treturn requested;\n\t}\n\tif (databases.length === 0) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: branch ${branch.name} (${branch.id}) has no databases.`, \"Create one via the Neon console or pass `databaseName` explicitly.\"].join(\" \"), { details: { branchId: branch.id } });\n\tconst neondb = databases.find((d) => d.name === NEON_DEFAULT_DATABASE);\n\tif (neondb) return neondb.name;\n\tif (databases.length === 1) return databases[0].name;\n\tthrow new PlatformError(ErrorCode.AmbiguousBranchAuth, [`fetchEnv: branch ${branch.name} (${branch.id}) has ${databases.length} databases and none is named \"${NEON_DEFAULT_DATABASE}\"; cannot auto-pick.`, `Rename one to \"${NEON_DEFAULT_DATABASE}\" or keep a single database on the branch (or, when calling fetchEnv directly, pass \\`databaseName\\`). Available: ${databases.map((d) => d.name).join(\", \")}.`].join(\" \"), { details: {\n\t\tbranchId: branch.id,\n\t\tavailableDatabases: databases.map((d) => d.name)\n\t} });\n}\n/**\n* Project a fully-resolved {@link NeonEnv} into the OS-level `{ KEY: value }` pairs used\n* for cross-process transport. Named after the web-platform `.entries()` convention\n* (`URLSearchParams` / `Headers` / `FormData`); returns a `Record` rather than an\n* iterator of tuples since that's the shape env injection needs (wrap with\n* `Object.entries(...)` if you want literal `[key, value]` pairs). Used by `neon-env run`\n* to inject the vars into a subprocess's `process.env`.\n*\n* Walks the value at runtime so it works for any `NeonEnv<C>` regardless of which\n* conditional namespaces are present.\n*/\nfunction toEntries(env) {\n\tconst out = {};\n\tconst put = (key, value) => {\n\t\tif (value !== void 0) out[key] = value;\n\t};\n\tconst K = NEON_ENV_VAR_KEYS;\n\tput(K.postgres.databaseUrl, env.postgres?.databaseUrl);\n\tput(K.postgres.databaseUrlUnpooled, env.postgres?.databaseUrlUnpooled);\n\tput(K.branch.name, env.branch?.name);\n\tput(K.auth.baseUrl, env.auth?.baseUrl);\n\tput(K.auth.jwksUrl, env.auth?.jwksUrl);\n\tput(K.dataApi.url, env.dataApi?.url);\n\tput(K.storage.accessKeyId, env.storage?.accessKeyId);\n\tput(K.storage.secretAccessKey, env.storage?.secretAccessKey);\n\tput(K.storage.endpoint, env.storage?.endpoint);\n\tput(K.storage.region, env.storage?.region);\n\tput(K.aiGateway.apiKey, env.aiGateway?.apiKey);\n\tput(K.aiGateway.baseUrl, env.aiGateway?.baseUrl);\n\treturn out;\n}\n//#endregion\nexport { NEON_ENV_VAR_KEYS, createApiFromOptions, credentialEnvKeys, credentialName, fetchEnv, fetchEnvKeys, policyEnvKeys, previewCredentialScopes, resolveBranchPolicy, toEntries };\n\n//# sourceMappingURL=env.js.map"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"env.js","names":[],"sources":["../../../internals/env-core/dist/env.js"],"sourcesContent":["import { ErrorCode, PlatformError, createNeonApiFromOptions, deriveCredentialScopes, isPlatformError, resolveConfig } from \"@neon/config/v1\";\n//#region src/env.ts\n/**\n* The Neon env core — resolving a branch's env from the Neon API, and projecting it into\n* OS-level `{ KEY: value }` pairs.\n*\n* Private, and bundled into both consumers: `@neon/env` publishes it as `fetchEnv` /\n* `toEntries`, and the `neon` CLI needs the credential-reuse half in `reuse-secrets.ts`.\n* See `README.md` for why it is not published.\n*\n* The counterpart that reads `process.env` — `parseEnv` and its zod schemas — is not here. It\n* has no consumer outside `@neon/env`, so it stays in that package and imports this.\n*/\n/**\n* Mapping between the {@link NeonEnv} property paths and the OS-level env-var keys used\n* for cross-process transport (via `.env` files, `env run -- <cmd>`, or anything else\n* that talks to `process.env`).\n*\n* Each top-level key here is a {@link NeonEnv} namespace; the inner record maps the\n* camelCase property names exposed to TypeScript to the UPPER_SNAKE env-var names used\n* by the OS. Keep this in sync with {@link postgresEnvSchema} / {@link authEnvSchema} /\n* {@link dataApiEnvSchema}.\n*/\n/**\n* Neon's default branch owner role, created with every project. This is the role a\n* `DATABASE_URL` should connect as.\n*/\nconst NEON_DEFAULT_OWNER_ROLE = \"neondb_owner\";\n/**\n* Neon's default database, created with every project. When a branch has several databases\n* and none was requested, this is preferred for the `DATABASE_URL` so the common case (a\n* user added a second database next to `neondb`) auto-picks without asking.\n*/\nconst NEON_DEFAULT_DATABASE = \"neondb\";\n/**\n* Roles Neon provisions for the Auth / Data API (PostgREST) stack. They exist to back\n* RLS-scoped Data API requests authenticated by JWT — never to hold a `DATABASE_URL` —\n* so they're skipped when auto-picking the connection role. Enabling Neon Auth or the\n* Data API (`neon config apply`) adds these next to the owner role, which is why a plain\n* branch routinely reports more than one role.\n*/\nconst NEON_MANAGED_AUTH_ROLES = /* @__PURE__ */ new Set([\n\t\"authenticator\",\n\t\"anonymous\",\n\t\"authenticated\"\n]);\nconst NEON_ENV_VAR_KEYS = {\n\t/**\n\t* Branch identity. `NEON_BRANCH` carries the branch **name** and is injected into the\n\t* Neon Functions runtime on every branch (including the default) by default. `env pull` /\n\t* `neon dev` / `neon-env run` emit it too so local dev mirrors the deployed runtime.\n\t*/\n\tbranch: { name: \"NEON_BRANCH\" },\n\tpostgres: {\n\t\tdatabaseUrl: \"DATABASE_URL\",\n\t\tdatabaseUrlUnpooled: \"DATABASE_URL_UNPOOLED\"\n\t},\n\tauth: {\n\t\tbaseUrl: \"NEON_AUTH_BASE_URL\",\n\t\tjwksUrl: \"NEON_AUTH_JWKS_URL\"\n\t},\n\tdataApi: { url: \"NEON_DATA_API_URL\" },\n\t/**\n\t* Object storage (Preview). The S3 SDKs read `AWS_*` from their standard config chain, so\n\t* a branch credential + `neon dev` / `env pull` makes object storage work from env alone.\n\t* `region` is injected under the SDK-standard `AWS_REGION`.\n\t*/\n\tstorage: {\n\t\taccessKeyId: \"AWS_ACCESS_KEY_ID\",\n\t\tsecretAccessKey: \"AWS_SECRET_ACCESS_KEY\",\n\t\tendpoint: \"AWS_ENDPOINT_URL_S3\",\n\t\tregion: \"AWS_REGION\"\n\t},\n\t/**\n\t* AI Gateway (Preview). Exposed under the Neon-branded env vars the deployed Functions\n\t* runtime injects: `apiKey` is the minted credential's bearer (`NEON_AI_GATEWAY_TOKEN`)\n\t* and `baseUrl` is the bare branch gateway host (`NEON_AI_GATEWAY_BASE_URL`,\n\t* `scheme://host`, no path). Clients like `@neon/ai-sdk-provider` read these and append the\n\t* dialect route (`/v1`, `/openai/v1`, `/anthropic/v1`) themselves (https://github.com/vercel/ai/pull/15997).\n\t*/\n\taiGateway: {\n\t\tapiKey: \"NEON_AI_GATEWAY_TOKEN\",\n\t\tbaseUrl: \"NEON_AI_GATEWAY_BASE_URL\"\n\t}\n};\nconst FUNCTION_SLUG = /^[a-z0-9]{1,20}$/;\nconst FUNCTION_BASE_URL_KEY = /^NEON_FUNCTION_([A-Z0-9]{1,20})_BASE_URL$/;\nfunction functionBaseUrlKey(slug) {\n\tif (!FUNCTION_SLUG.test(slug)) throw new Error(`functionBaseUrlKey: ${JSON.stringify(slug)} is not a function slug ([a-z0-9]{1,20}).`);\n\treturn `NEON_FUNCTION_${slug.toUpperCase()}_BASE_URL`;\n}\nfunction parseFunctionBaseUrlKey(key) {\n\tconst match = FUNCTION_BASE_URL_KEY.exec(key);\n\treturn match ? match[1].toLowerCase() : null;\n}\nfunction isFunctionBaseUrlKey(key) {\n\treturn parseFunctionBaseUrlKey(key) !== null;\n}\nasync function fetchEnv(config, options) {\n\tif (options.keys) assertStorageCredentialKeyPair(options.keys);\n\treturn fetchEnvKeys(config, options, options.keys ?? null);\n}\nfunction assertStorageCredentialKeyPair(keys) {\n\tif (keys.includes(NEON_ENV_VAR_KEYS.storage.accessKeyId) === keys.includes(NEON_ENV_VAR_KEYS.storage.secretAccessKey)) return;\n\tthrow new TypeError(\"fetchEnv: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be selected together. Pass both in `keys`, or omit both.\");\n}\n/** Fail loudly when selected-key dependency planning and execution disagree. */\nfunction requiredValue(value, description) {\n\tif (value === null) throw new Error(`fetchEnv: missing ${description}.`);\n\treturn value;\n}\n/**\n* The {@link fetchEnv} body, with the key selection as a plain argument and no generic\n* narrowing. Exists for callers that compute the selection at runtime — notably\n* {@link fetchEnvReusingSecrets}, which decides which keys it still needs by checking the\n* branch — since the public overload's `keys` is bound to a literal union those callers cannot\n* produce without asserting.\n*\n* `keys === null` selects everything the policy enables.\n*/\nasync function fetchEnvKeys(config, options, keys) {\n\treturn (await fetchEnvKeysState(config, options, keys)).env;\n}\nasync function fetchEnvKeysState(config, options, keys) {\n\tconst api = options.api ?? createApiFromOptions(options);\n\tconst projectId = options.projectId;\n\tconst { branch, desired } = await resolveBranchPolicy(config, options, api);\n\tconst selection = keys ? new Set(keys) : null;\n\tconst omitted = new Set(options.omitKeys ?? []);\n\tconst wants = (key) => !omitted.has(key) && (selection === null || selection.has(key));\n\tconst result = {};\n\tconst K = NEON_ENV_VAR_KEYS;\n\tconst wantsPooled = wants(K.postgres.databaseUrl);\n\tconst wantsUnpooled = wants(K.postgres.databaseUrlUnpooled);\n\tconst wantsAuth = desired.authEnabled && (wants(K.auth.baseUrl) || wants(K.auth.jwksUrl));\n\tconst wantsDataApi = desired.dataApiEnabled && wants(K.dataApi.url);\n\tconst gatewayEnabled = desired.preview?.aiGatewayEnabled ?? false;\n\tconst functionUrlMode = options.functionUrls ?? \"policy\";\n\tconst declaredSlugs = (desired.preview?.functions ?? []).map((fn) => fn.slug);\n\tconst selectedFunctionKeys = selection === null ? [] : [...selection].filter(isFunctionBaseUrlKey);\n\tconst constructSlugs = functionUrlSlugsToConstruct({\n\t\tfunctionUrlMode,\n\t\tselection,\n\t\tdeclaredSlugs,\n\t\tselectedFunctionKeys,\n\t\twants\n\t});\n\tconst needsUnpooled = wantsUnpooled || gatewayEnabled && wants(K.aiGateway.baseUrl) || constructSlugs.length > 0;\n\tconst needsConnectionTarget = wantsPooled || needsUnpooled;\n\tconst needsDatabase = needsConnectionTarget || wantsDataApi;\n\tconst [roles, databases] = await Promise.all([needsConnectionTarget ? api.listBranchRoles(projectId, branch.id) : Promise.resolve([]), needsDatabase ? api.listBranchDatabases(projectId, branch.id) : Promise.resolve([])]);\n\tconst databaseName = needsDatabase ? pickDatabaseName(databases, branch, options.databaseName) : null;\n\tconst connectionTarget = needsConnectionTarget ? {\n\t\troleName: pickRoleName(roles, branch, options.roleName),\n\t\tdatabaseName: requiredValue(databaseName, \"database for a selected connection URI\")\n\t} : null;\n\tconst getConnectionUri = (pooled) => {\n\t\tconst target = requiredValue(connectionTarget, \"role and database for a selected connection URI\");\n\t\treturn api.getConnectionUri(projectId, {\n\t\t\tbranchId: branch.id,\n\t\t\t...target,\n\t\t\tpooled\n\t\t});\n\t};\n\tconst [pooled, unpooled, authSnapshot, dataApiSnapshot] = await Promise.all([\n\t\twantsPooled ? getConnectionUri(true) : Promise.resolve(null),\n\t\tneedsUnpooled ? getConnectionUri(false) : Promise.resolve(null),\n\t\twantsAuth ? api.getNeonAuth(projectId, branch.id) : Promise.resolve(null),\n\t\twantsDataApi ? api.getNeonDataApi(projectId, branch.id, requiredValue(databaseName, \"database for the selected Data API URL\")) : Promise.resolve(null)\n\t]);\n\tconst postgres = {};\n\tif (wantsPooled) postgres.databaseUrl = requiredValue(pooled, \"pooled connection URI response\").uri;\n\tif (wantsUnpooled) postgres.databaseUrlUnpooled = requiredValue(unpooled, \"direct connection URI response\").uri;\n\tif (Object.keys(postgres).length > 0) result.postgres = postgres;\n\tif (wants(K.branch.name)) result.branch = { name: branch.name };\n\tif (wantsAuth) {\n\t\tif (!authSnapshot) throw new PlatformError(ErrorCode.NotFound, [`fetchEnv: branch policy enables auth but no Neon Auth integration is enabled on branch ${branch.name} (${branch.id}).`, \"Enable it via `apply(config, { projectId, branchId })` (or `npx neon …`), in the Neon Console — then re-run fetchEnv. Or return auth.enabled=false.\"].join(\" \"), { details: {\n\t\t\tprojectId,\n\t\t\tbranchId: branch.id\n\t\t} });\n\t\tconst auth = {};\n\t\tif (wants(K.auth.baseUrl)) auth.baseUrl = authSnapshot.baseUrl ?? \"\";\n\t\tif (wants(K.auth.jwksUrl)) auth.jwksUrl = authSnapshot.jwksUrl ?? \"\";\n\t\tresult.auth = auth;\n\t}\n\tif (wantsDataApi) {\n\t\tif (!dataApiSnapshot) {\n\t\t\tconst selectedDatabase = requiredValue(databaseName, \"database for the selected Data API URL\");\n\t\t\tthrow new PlatformError(ErrorCode.NotFound, [`fetchEnv: branch policy enables dataApi but no Data API integration is enabled on branch ${branch.name} (${branch.id}) database ${selectedDatabase}.`, \"Enable it via `apply(config, { projectId, branchId })` or in the Neon Console — then re-run fetchEnv. Or return dataApi.enabled=false.\"].join(\" \"), { details: {\n\t\t\t\tprojectId,\n\t\t\t\tbranchId: branch.id,\n\t\t\t\tdatabaseName: selectedDatabase\n\t\t\t} });\n\t\t}\n\t\tresult.dataApi = { url: dataApiSnapshot.url };\n\t}\n\tconst storageEnabled = (desired.preview?.buckets.length ?? 0) > 0;\n\tconst wantsStorage = storageEnabled && (wants(K.storage.accessKeyId) || wants(K.storage.secretAccessKey) || wants(K.storage.endpoint) || wants(K.storage.region));\n\tconst wantsGateway = gatewayEnabled && (wants(K.aiGateway.apiKey) || wants(K.aiGateway.baseUrl));\n\tconst wantsStorageCredential = storageEnabled && (wants(K.storage.accessKeyId) || wants(K.storage.secretAccessKey));\n\tconst wantsGatewayCredential = gatewayEnabled && wants(K.aiGateway.apiKey);\n\tconst wantsCredential = wantsStorageCredential || wantsGatewayCredential;\n\tif (wantsStorage || wantsGateway) {\n\t\tlet storage = null;\n\t\tif (wantsStorage) {\n\t\t\tstorage = await api.getProjectBranchStorage(projectId, branch.id);\n\t\t\tif (!storage) throw new PlatformError(ErrorCode.NotFound, [`fetchEnv: branch policy declares object storage (preview.buckets) but storage is not enabled on branch ${branch.name} (${branch.id}).`, \"Enable it via `apply(config, { projectId, branchId })` (or in the Neon Console) — then re-run fetchEnv. Or remove preview.buckets.\"].join(\" \"), { details: {\n\t\t\t\tprojectId,\n\t\t\t\tbranchId: branch.id\n\t\t\t} });\n\t\t}\n\t\tconst secrets = wantsCredential ? await mintBranchCredential({\n\t\t\tapi,\n\t\t\tprojectId,\n\t\t\tbranchId: branch.id,\n\t\t\tbranchName: branch.name,\n\t\t\tscopes: previewCredentialScopes(desired.preview, {\n\t\t\t\tstorage: wantsStorageCredential,\n\t\t\t\taiGateway: wantsGatewayCredential\n\t\t\t})\n\t\t}) : null;\n\t\tif (storage) {\n\t\t\tconst storageEnv = {};\n\t\t\tif (secrets && wants(K.storage.accessKeyId)) storageEnv.accessKeyId = secrets.accessKeyId;\n\t\t\tif (secrets && wants(K.storage.secretAccessKey)) storageEnv.secretAccessKey = secrets.secretAccessKey;\n\t\t\tif (wants(K.storage.endpoint)) storageEnv.endpoint = storage.s3Endpoint;\n\t\t\tif (wants(K.storage.region)) storageEnv.region = storage.region;\n\t\t\tresult.storage = storageEnv;\n\t\t}\n\t\tif (wantsGateway) {\n\t\t\tconst gateway = {};\n\t\t\tif (secrets && wants(K.aiGateway.apiKey)) gateway.apiKey = secrets.apiToken;\n\t\t\tif (wants(K.aiGateway.baseUrl)) gateway.baseUrl = aiGatewayBaseUrl(branch.id, requiredValue(unpooled, \"direct connection URI for the selected AI Gateway base URL\").uri);\n\t\t\tresult.aiGateway = gateway;\n\t\t}\n\t}\n\tconst wantsAnyFunctionUrl = selection === null || selectedFunctionKeys.length > 0;\n\tconst functions = {};\n\tlet functionUrlsUnavailable = false;\n\tif (functionUrlMode === \"all-live\" && wantsAnyFunctionUrl) {\n\t\tconst listed = options.listedFunctions === void 0 ? await listFunctionInvocationUrls(api, projectId, branch.id) : listedFromSnapshots(options.listedFunctions);\n\t\tif (listed.status === \"unavailable\") {\n\t\t\tif (selection === null) functionUrlsUnavailable = true;\n\t\t} else for (const fn of listed.functions) {\n\t\t\tif (!wants(functionBaseUrlKey(fn.slug))) continue;\n\t\t\tfunctions[fn.slug] = { baseUrl: asEnvBaseUrl(fn.invocationUrl) };\n\t\t}\n\t}\n\tconst missingConstructSlugs = constructSlugs.filter((slug) => functions[slug] === void 0);\n\tif (missingConstructSlugs.length > 0) {\n\t\tconst uri = requiredValue(unpooled, \"direct connection URI for function invocation URLs\").uri;\n\t\tfor (const slug of missingConstructSlugs) functions[slug] = { baseUrl: functionInvocationUrl(branch.id, slug, uri) };\n\t}\n\tassertSelectedFunctionUrls(selectedFunctionKeys, functions);\n\tif (Object.keys(functions).length > 0) result.functions = functions;\n\treturn {\n\t\tenv: result,\n\t\tfunctionUrlsUnavailable\n\t};\n}\nfunction functionUrlSlugsToConstruct(args) {\n\tconst slugs = [];\n\tif (args.functionUrlMode === \"policy\" && args.selection === null) {\n\t\tfor (const slug of args.declaredSlugs) if (args.wants(functionBaseUrlKey(slug))) slugs.push(slug);\n\t\treturn slugs;\n\t}\n\tfor (const key of args.selectedFunctionKeys) {\n\t\tconst slug = parseFunctionBaseUrlKey(key);\n\t\tif (slug !== null) slugs.push(slug);\n\t}\n\treturn slugs;\n}\nfunction listedFromSnapshots(snapshots) {\n\treturn {\n\t\tstatus: \"ok\",\n\t\tfunctions: snapshots.filter((fn) => fn.invocationUrl !== \"\").map((fn) => ({\n\t\t\tslug: fn.slug,\n\t\t\tinvocationUrl: fn.invocationUrl\n\t\t})).sort((left, right) => left.slug.localeCompare(right.slug))\n\t};\n}\nfunction assertSelectedFunctionUrls(keys, functions) {\n\tfor (const key of keys) {\n\t\tconst slug = parseFunctionBaseUrlKey(key);\n\t\tif (slug === null || functions[slug] === void 0) throw new Error(`fetchEnv: missing ${key}.`);\n\t}\n}\nasync function listFunctionInvocationUrls(api, projectId, branchId) {\n\ttry {\n\t\treturn listedFromSnapshots(await api.listBranchFunctions(projectId, branchId));\n\t} catch (error) {\n\t\tif (isPlatformError(error) && error.code === ErrorCode.FeatureUnavailable) return {\n\t\t\tstatus: \"unavailable\",\n\t\t\terror\n\t\t};\n\t\tthrow error;\n\t}\n}\n/**\n* Resolve the target branch and evaluate the policy against it — the first thing any\n* branch-scoped operation needs. Shared by {@link fetchEnv} and {@link fetchEnvReusingSecrets}\n* so the two agree on which branch they're talking about and what it has enabled.\n*/\nasync function resolveBranchPolicy(config, options, api) {\n\tconst projectId = options.projectId;\n\tconst branches = await api.listBranches(projectId);\n\tif (branches.length === 0) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: project ${projectId} has no branches.`, \"Deploy your neon.ts policy (or create a branch) first, or pick a different project id.\"].join(\" \"), { details: { projectId } });\n\tconst branchRef = options.branch ?? options.branchId;\n\tif (!branchRef) throw new PlatformError(ErrorCode.BranchNotFound, [\"fetchEnv: no branch provided.\", \"Pass `branch` with a branch name (e.g. `main`) or id (`br-…`).\"].join(\" \"), { details: { projectId } });\n\tconst branch = resolveBranch(branchRef, branches);\n\treturn {\n\t\tbranch,\n\t\tdesired: resolveConfig(config, {\n\t\t\tname: branch.name,\n\t\t\tid: branch.id,\n\t\t\texists: true,\n\t\t\t...branch.parentId ? { parentId: branch.parentId } : {},\n\t\t\tisDefault: branch.isDefault,\n\t\t\tisProtected: branch.protected,\n\t\t\t...branch.expiresAt ? { expiresAt: branch.expiresAt } : {}\n\t\t})\n\t};\n}\n/**\n* Scopes the branch credential should carry for a resolved branch policy and optional key\n* selection. Only object storage and the AI Gateway *require* a credential; functions never\n* force one, but `functions:invoke` rides along when another selected feature mints one.\n*/\nfunction previewCredentialScopes(preview, selected) {\n\tif (!preview) return [];\n\tconst storage = preview.buckets.length > 0 && (selected?.storage ?? true);\n\tconst aiGateway = preview.aiGatewayEnabled && (selected?.aiGateway ?? true);\n\tif (!storage && !aiGateway) return [];\n\treturn deriveCredentialScopes({\n\t\tstorage,\n\t\taiGateway,\n\t\tfunctions: preview.functions.length > 0\n\t});\n}\n/** The `name` this tool stamps on every credential it mints, so it can recognize its own. */\nfunction credentialName(branchName) {\n\treturn `neon-env ${branchName}`;\n}\n/** The env-var keys a branch credential's secrets surface under, in emit order. */\nfunction credentialEnvKeys(flags) {\n\treturn [...flags.storage ? [NEON_ENV_VAR_KEYS.storage.accessKeyId, NEON_ENV_VAR_KEYS.storage.secretAccessKey] : [], ...flags.aiGateway ? [NEON_ENV_VAR_KEYS.aiGateway.apiKey] : []];\n}\n/**\n* Every OS-level env var a resolved branch policy produces, in emit order. Lets a caller\n* subtract the ones it already holds and pass the rest as {@link fetchEnv}'s `keys`, without\n* re-deriving which vars a policy implies.\n*/\nfunction policyEnvKeys(desired) {\n\tconst K = NEON_ENV_VAR_KEYS;\n\treturn [\n\t\tK.postgres.databaseUrl,\n\t\tK.postgres.databaseUrlUnpooled,\n\t\tK.branch.name,\n\t\t...desired.authEnabled ? [K.auth.baseUrl, K.auth.jwksUrl] : [],\n\t\t...desired.dataApiEnabled ? [K.dataApi.url] : [],\n\t\t...(desired.preview?.buckets.length ?? 0) > 0 ? [\n\t\t\tK.storage.accessKeyId,\n\t\t\tK.storage.secretAccessKey,\n\t\t\tK.storage.endpoint,\n\t\t\tK.storage.region\n\t\t] : [],\n\t\t...desired.preview?.aiGatewayEnabled ? [K.aiGateway.apiKey, K.aiGateway.baseUrl] : []\n\t];\n}\n/**\n* Mint the branch credential backing object storage / the AI Gateway.\n*\n* `api_token` and `s3_secret_access_key` come back **exactly once** — they are not stored\n* server-side and the list endpoint returns metadata only — so the caller's copy is the only\n* copy. That is why {@link fetchEnv} mints rather than fetches: there is nothing to fetch. A\n* caller that already holds a valid copy should leave the secret keys out of `keys` (see\n* {@link fetchEnvReusingSecrets}) instead of minting one it will discard.\n*/\nasync function mintBranchCredential(args) {\n\tconst minted = await args.api.createCredential(args.projectId, args.branchId, {\n\t\tscopes: args.scopes,\n\t\tprincipalType: \"user\",\n\t\tname: credentialName(args.branchName)\n\t});\n\treturn {\n\t\taccessKeyId: minted.tokenId,\n\t\tsecretAccessKey: minted.s3SecretAccessKey,\n\t\tapiToken: minted.apiToken\n\t};\n}\n/**\n* The AI Gateway is a **branch-scoped host** — `<branchId>-api.ai.<host-suffix>` — NOT the\n* control-plane API origin. Derive the suffix from the branch's own Postgres connection host\n* by dropping only the endpoint label (the first segment) and keeping everything after it,\n* including any infra cell prefix (`c-N.`): a connection host of\n* `ep-x.c-3.us-east-2.aws.neon.tech` yields the gateway host\n* `<branchId>-api.ai.c-3.us-east-2.aws.neon.tech`. The cell prefix is **load-bearing** —\n* the gateway is cell-routed, so dropping `c-N.` resolves to the wrong (or no) host.\n*\n* Function invocation URLs use the same suffix: `<branchId>-<slug>.compute.<suffix>`.\n*/\nfunction connectionHostSuffix(connectionUri) {\n\tlet connectionHost = \"\";\n\ttry {\n\t\tconnectionHost = new URL(connectionUri).hostname;\n\t} catch {\n\t\tconnectionHost = \"\";\n\t}\n\treturn connectionHost.split(\".\").slice(1).join(\".\");\n}\nfunction aiGatewayHost(branchId, connectionUri) {\n\treturn `${branchId}-api.ai.${connectionHostSuffix(connectionUri)}`;\n}\n/**\n* The API's `invocation_url` ends with `/` so paths concatenate onto it. Neon `*_BASE_URL`\n* vars are origin-only (`NEON_AUTH_BASE_URL`, `NEON_AI_GATEWAY_BASE_URL`).\n*/\nfunction asEnvBaseUrl(url) {\n\tlet parsed;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\tthrow new Error(`fetchEnv: function invocation URL is not a URL: ${JSON.stringify(url)}`);\n\t}\n\tif (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") throw new Error(`fetchEnv: function invocation URL must be http(s): ${JSON.stringify(url)}`);\n\treturn parsed.origin;\n}\n/** Derived from the connection URI so undeployed functions have a cell-routed URL. */\nfunction functionInvocationUrl(branchId, slug, connectionUri) {\n\tconst suffix = connectionHostSuffix(connectionUri);\n\tif (suffix === \"\") throw new Error(`fetchEnv: cannot derive the invocation URL for function \"${slug}\": the direct connection URI has no host suffix.`);\n\treturn `https://${branchId}-${slug}.compute.${suffix}`;\n}\n/** The AI Gateway's bare base URL (`NEON_AI_GATEWAY_BASE_URL`) on the branch gateway host. */\nfunction aiGatewayBaseUrl(branchId, connectionUri) {\n\treturn `https://${aiGatewayHost(branchId, connectionUri)}`;\n}\nfunction createApiFromOptions(options) {\n\treturn createNeonApiFromOptions(\"fetchEnv\", {\n\t\t...options.apiKey ? { apiKey: options.apiKey } : {},\n\t\t...options.apiHost ? { apiHost: options.apiHost } : {}\n\t});\n}\n/**\n* Resolve a branch ref — a name or an id — to a concrete branch. Matches by id first\n* (exact `br-…`), then by name; both are unique within a project, so the lookup is\n* unambiguous. This lets `.neon` files written by `neonctl` (which pin the branch *name*)\n* and explicit `br-…` ids both work.\n*/\nfunction resolveBranch(branch, branches) {\n\tconst match = branches.find((b) => b.id === branch) ?? branches.find((b) => b.name === branch);\n\tif (match) return match;\n\tthrow new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: branch ${JSON.stringify(branch)} not found on project (matched by id or name).`, `Existing branches: ${branches.map((b) => `${b.name} (${b.id})`).join(\", \")}.`].join(\" \"), { details: {\n\t\tbranch,\n\t\tavailable: branches.map((b) => `${b.name} (${b.id})`)\n\t} });\n}\nfunction pickRoleName(roles, branch, requested) {\n\tif (requested) {\n\t\tif (!roles.some((r) => r.name === requested)) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: role \"${requested}\" not found on branch ${branch.name} (${branch.id}).`, `Existing roles: ${roles.map((r) => r.name).join(\", \") || \"(none)\"}.`].join(\" \"), { details: {\n\t\t\tbranchId: branch.id,\n\t\t\troleName: requested,\n\t\t\tavailableRoles: roles.map((r) => r.name)\n\t\t} });\n\t\treturn requested;\n\t}\n\tif (roles.length === 0) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: branch ${branch.name} (${branch.id}) has no roles.`, \"Create one via the Neon console or pass `roleName` explicitly.\"].join(\" \"), { details: { branchId: branch.id } });\n\tif (roles.length === 1) return roles[0].name;\n\tconst owner = roles.find((r) => r.name === NEON_DEFAULT_OWNER_ROLE);\n\tif (owner) return owner.name;\n\tconst appRoles = roles.filter((r) => !NEON_MANAGED_AUTH_ROLES.has(r.name));\n\tif (appRoles.length === 1) return appRoles[0].name;\n\tthrow new PlatformError(ErrorCode.AmbiguousBranchAuth, [`fetchEnv: branch ${branch.name} (${branch.id}) has ${roles.length} roles and none is \"${NEON_DEFAULT_OWNER_ROLE}\"; cannot auto-pick.`, `Pass \\`roleName\\` explicitly. Available: ${roles.map((r) => r.name).join(\", \")}.`].join(\" \"), { details: {\n\t\tbranchId: branch.id,\n\t\tavailableRoles: roles.map((r) => r.name)\n\t} });\n}\nfunction pickDatabaseName(databases, branch, requested) {\n\tif (requested) {\n\t\tif (!databases.some((d) => d.name === requested)) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: database \"${requested}\" not found on branch ${branch.name} (${branch.id}).`, `Existing databases: ${databases.map((d) => d.name).join(\", \") || \"(none)\"}.`].join(\" \"), { details: {\n\t\t\tbranchId: branch.id,\n\t\t\tdatabaseName: requested,\n\t\t\tavailableDatabases: databases.map((d) => d.name)\n\t\t} });\n\t\treturn requested;\n\t}\n\tif (databases.length === 0) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: branch ${branch.name} (${branch.id}) has no databases.`, \"Create one via the Neon console or pass `databaseName` explicitly.\"].join(\" \"), { details: { branchId: branch.id } });\n\tconst neondb = databases.find((d) => d.name === NEON_DEFAULT_DATABASE);\n\tif (neondb) return neondb.name;\n\tif (databases.length === 1) return databases[0].name;\n\tthrow new PlatformError(ErrorCode.AmbiguousBranchAuth, [`fetchEnv: branch ${branch.name} (${branch.id}) has ${databases.length} databases and none is named \"${NEON_DEFAULT_DATABASE}\"; cannot auto-pick.`, `Rename one to \"${NEON_DEFAULT_DATABASE}\" or keep a single database on the branch (or, when calling fetchEnv directly, pass \\`databaseName\\`). Available: ${databases.map((d) => d.name).join(\", \")}.`].join(\" \"), { details: {\n\t\tbranchId: branch.id,\n\t\tavailableDatabases: databases.map((d) => d.name)\n\t} });\n}\n/**\n* Project a fully-resolved {@link NeonEnv} into the OS-level `{ KEY: value }` pairs used\n* for cross-process transport. Named after the web-platform `.entries()` convention\n* (`URLSearchParams` / `Headers` / `FormData`); returns a `Record` rather than an\n* iterator of tuples since that's the shape env injection needs (wrap with\n* `Object.entries(...)` if you want literal `[key, value]` pairs). Used by `neon-env run`\n* to inject the vars into a subprocess's `process.env`.\n*\n* Walks the value at runtime so it works for any `NeonEnv<C>` regardless of which\n* conditional namespaces are present.\n*/\nfunction toEntries(env) {\n\tconst out = {};\n\tconst put = (key, value) => {\n\t\tif (value !== void 0) out[key] = value;\n\t};\n\tconst K = NEON_ENV_VAR_KEYS;\n\tput(K.postgres.databaseUrl, env.postgres?.databaseUrl);\n\tput(K.postgres.databaseUrlUnpooled, env.postgres?.databaseUrlUnpooled);\n\tput(K.branch.name, env.branch?.name);\n\tput(K.auth.baseUrl, env.auth?.baseUrl);\n\tput(K.auth.jwksUrl, env.auth?.jwksUrl);\n\tput(K.dataApi.url, env.dataApi?.url);\n\tput(K.storage.accessKeyId, env.storage?.accessKeyId);\n\tput(K.storage.secretAccessKey, env.storage?.secretAccessKey);\n\tput(K.storage.endpoint, env.storage?.endpoint);\n\tput(K.storage.region, env.storage?.region);\n\tput(K.aiGateway.apiKey, env.aiGateway?.apiKey);\n\tput(K.aiGateway.baseUrl, env.aiGateway?.baseUrl);\n\tif (env.functions) for (const slug of Object.keys(env.functions).sort()) put(functionBaseUrlKey(slug), env.functions[slug]?.baseUrl);\n\treturn out;\n}\n//#endregion\nexport { NEON_ENV_VAR_KEYS, createApiFromOptions, credentialEnvKeys, credentialName, fetchEnv, fetchEnvKeys, fetchEnvKeysState, functionBaseUrlKey, isFunctionBaseUrlKey, parseFunctionBaseUrlKey, policyEnvKeys, previewCredentialScopes, resolveBranchPolicy, toEntries };\n\n//# sourceMappingURL=env.js.map"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -46,6 +46,12 @@ declare const NEON_ENV_VAR_KEYS: {
|
|
|
46
46
|
readonly baseUrl: "NEON_AI_GATEWAY_BASE_URL";
|
|
47
47
|
};
|
|
48
48
|
};
|
|
49
|
+
type FunctionBaseUrlKey<Slug extends string = string> = `NEON_FUNCTION_${Uppercase<Slug>}_BASE_URL`;
|
|
50
|
+
declare function functionBaseUrlKey<S extends string>(slug: S): FunctionBaseUrlKey<S>;
|
|
51
|
+
declare function parseFunctionBaseUrlKey(key: string): string | null;
|
|
52
|
+
declare function isFunctionBaseUrlKey(key: string): key is FunctionBaseUrlKey;
|
|
53
|
+
/** `all-live` lists deployed functions. Policy mode derives declared slugs from the connection host. */
|
|
54
|
+
|
|
49
55
|
/**
|
|
50
56
|
* Branch identity for the resolved branch. Always present on a `fetchEnv` result (the branch
|
|
51
57
|
* name is always known); on a `parseEnv` result it's present only when `NEON_BRANCH` was
|
|
@@ -118,6 +124,9 @@ interface NeonAiGatewayEnv {
|
|
|
118
124
|
apiKey: string;
|
|
119
125
|
baseUrl: string;
|
|
120
126
|
}
|
|
127
|
+
interface NeonFunctionUrlEnv {
|
|
128
|
+
baseUrl: string;
|
|
129
|
+
}
|
|
121
130
|
/**
|
|
122
131
|
* Empty record alias used as the "false" branch of the conditional namespace adds below.
|
|
123
132
|
* `Record<never, never>` is the no-op for intersection — the cleaner alternative to `{}`,
|
|
@@ -166,6 +175,16 @@ type HasBuckets<C extends Config> = [NonNullable<C["preview"]>] extends [never]
|
|
|
166
175
|
type AiGatewayOn<C extends Config> = [NonNullable<C["preview"]>] extends [never] ? false : NonNullable<C["preview"]> extends {
|
|
167
176
|
aiGateway: infer A;
|
|
168
177
|
} ? ServiceOn<NonNullable<A>> : false;
|
|
178
|
+
/** The tuple guard prevents a missing preview block from enabling functions. */
|
|
179
|
+
type HasFunctions<C extends Config> = [NonNullable<C["preview"]>] extends [never] ? false : NonNullable<C["preview"]> extends {
|
|
180
|
+
functions: infer F;
|
|
181
|
+
} ? HasKeys<NonNullable<F>> : false;
|
|
182
|
+
type PreviewFunctionsOfConfig<C extends Config> = [NonNullable<C["preview"]>] extends [never] ? Record<never, never> : NonNullable<C["preview"]> extends {
|
|
183
|
+
functions: infer F;
|
|
184
|
+
} ? F : Record<never, never>;
|
|
185
|
+
type FunctionSlugOfConfig<C extends Config> = Extract<keyof PreviewFunctionsOfConfig<C>, string>;
|
|
186
|
+
type NeonFunctionsEnv<C extends Config> = { [S in FunctionSlugOfConfig<C>]: NeonFunctionUrlEnv };
|
|
187
|
+
type FunctionBaseUrlKeyOf<C extends Config> = FunctionSlugOfConfig<C> extends infer S ? S extends string ? FunctionBaseUrlKey<S> : never : never;
|
|
169
188
|
/**
|
|
170
189
|
* Static, namespaced shape of `fetchEnv` / `parseEnv`'s return value. Generic over the
|
|
171
190
|
* {@link Config} so the type system knows which optional namespaces are present.
|
|
@@ -179,6 +198,7 @@ type AiGatewayOn<C extends Config> = [NonNullable<C["preview"]>] extends [never]
|
|
|
179
198
|
* - `dataApi` is added iff `config.dataApi` is statically enabled.
|
|
180
199
|
* - `storage` is added iff `config.preview.buckets` declares at least one bucket.
|
|
181
200
|
* - `aiGateway` is added iff `config.preview.aiGateway` is statically enabled.
|
|
201
|
+
* - `functions` is added iff `config.preview.functions` declares at least one slug.
|
|
182
202
|
*/
|
|
183
203
|
type NeonEnv<C extends Config = Config> = {
|
|
184
204
|
postgres: NeonPostgresEnv;
|
|
@@ -195,6 +215,8 @@ type NeonEnv<C extends Config = Config> = {
|
|
|
195
215
|
storage: NeonStorageEnv;
|
|
196
216
|
} : NoNamespace) & (AiGatewayOn<C> extends true ? {
|
|
197
217
|
aiGateway: NeonAiGatewayEnv;
|
|
218
|
+
} : NoNamespace) & (HasFunctions<C> extends true ? {
|
|
219
|
+
functions: NeonFunctionsEnv<C>;
|
|
198
220
|
} : NoNamespace);
|
|
199
221
|
/**
|
|
200
222
|
* OS-level env-var keys grouped by the {@link NeonEnv} namespace they populate. Only the
|
|
@@ -241,7 +263,7 @@ interface EnvKeyToProp {
|
|
|
241
263
|
* `keys` filter — selecting a var from a namespace the policy does not enable is a type error
|
|
242
264
|
* (e.g. `NEON_AUTH_BASE_URL` is only offered once the policy turns on `auth`).
|
|
243
265
|
*/
|
|
244
|
-
type SelectableEnvKey<C extends Config> = EnvKeysByNamespace[keyof NeonEnv<C> & keyof EnvKeysByNamespace]
|
|
266
|
+
type SelectableEnvKey<C extends Config> = EnvKeysByNamespace[keyof NeonEnv<C> & keyof EnvKeysByNamespace] | FunctionBaseUrlKeyOf<C>;
|
|
245
267
|
/**
|
|
246
268
|
* The result shape of a **filtered** `parseEnv(config, keys)` call: the namespaced
|
|
247
269
|
* {@link NeonEnv} restricted to exactly the selected OS-level keys `K`. Namespaces with no
|
|
@@ -257,13 +279,21 @@ type SelectableEnvKey<C extends Config> = EnvKeysByNamespace[keyof NeonEnv<C> &
|
|
|
257
279
|
* camelCase property and looks the value type up on the canonical namespace interface, so it
|
|
258
280
|
* stays correct if a field ever stops being a plain `string`.
|
|
259
281
|
*/
|
|
260
|
-
type
|
|
282
|
+
type SelectedFunctionKeys<K extends string> = Extract<K, FunctionBaseUrlKey>;
|
|
283
|
+
type FunctionSlugFromKey<K extends string> = K extends `NEON_FUNCTION_${infer S}_BASE_URL` ? Lowercase<S> : never;
|
|
284
|
+
type FunctionsFilteredEnv<K extends string> = [SelectedFunctionKeys<K>] extends [never] ? unknown : {
|
|
285
|
+
functions: { [P in SelectedFunctionKeys<K> as FunctionSlugFromKey<P>]: NeonFunctionUrlEnv };
|
|
286
|
+
};
|
|
287
|
+
type OptionalFunctionsFilteredEnv<K extends string> = [SelectedFunctionKeys<K>] extends [never] ? unknown : {
|
|
288
|
+
functions?: { [P in SelectedFunctionKeys<K> as FunctionSlugFromKey<P>]?: NeonFunctionUrlEnv };
|
|
289
|
+
};
|
|
290
|
+
type FilteredNeonEnv<K extends string> = { [N in keyof EnvKeysByNamespace as [Extract<K, EnvKeysByNamespace[N]>] extends [never] ? never : N]: { [P in Extract<K, EnvKeysByNamespace[N]> as EnvKeyToProp[P & keyof EnvKeyToProp]]: NamespaceEnv[N][EnvKeyToProp[P & keyof EnvKeyToProp] & keyof NamespaceEnv[N]] } } & FunctionsFilteredEnv<K>;
|
|
261
291
|
/**
|
|
262
292
|
* A filtered result when the exact runtime contents of a key array are unknown. Both the
|
|
263
293
|
* namespace and its selected properties are optional because the array may omit any member of
|
|
264
294
|
* its element union, or be empty.
|
|
265
295
|
*/
|
|
266
|
-
type OptionalFilteredNeonEnv<K extends string> = { [N in keyof EnvKeysByNamespace as [Extract<K, EnvKeysByNamespace[N]>] extends [never] ? never : N]?: { [P in Extract<K, EnvKeysByNamespace[N]> as EnvKeyToProp[P & keyof EnvKeyToProp]]?: NamespaceEnv[N][EnvKeyToProp[P & keyof EnvKeyToProp] & keyof NamespaceEnv[N]] } }
|
|
296
|
+
type OptionalFilteredNeonEnv<K extends string> = { [N in keyof EnvKeysByNamespace as [Extract<K, EnvKeysByNamespace[N]>] extends [never] ? never : N]?: { [P in Extract<K, EnvKeysByNamespace[N]> as EnvKeyToProp[P & keyof EnvKeyToProp]]?: NamespaceEnv[N][EnvKeyToProp[P & keyof EnvKeyToProp] & keyof NamespaceEnv[N]] } } & OptionalFunctionsFilteredEnv<K>;
|
|
267
297
|
/** Whether `T` is a union rather than one concrete type. */
|
|
268
298
|
type IsUnion<T, Whole = T> = T extends Whole ? [Whole] extends [T] ? false : true : never;
|
|
269
299
|
/** Whether any fixed tuple position can hold more than one key at runtime. */
|
|
@@ -433,7 +463,9 @@ declare function toEntries(env: ResolvedNeonEnv): Record<string, string>;
|
|
|
433
463
|
* property is optional so a filtered result — which legitimately carries only what was asked
|
|
434
464
|
* for — projects to exactly the vars it holds instead of failing to type-check.
|
|
435
465
|
*/
|
|
436
|
-
type ResolvedNeonEnv = { [N in keyof NamespaceEnv]?: Partial<NamespaceEnv[N]> }
|
|
466
|
+
type ResolvedNeonEnv = { [N in keyof NamespaceEnv]?: Partial<NamespaceEnv[N]> } & {
|
|
467
|
+
functions?: Record<string, NeonFunctionUrlEnv>;
|
|
468
|
+
};
|
|
437
469
|
//#endregion
|
|
438
470
|
//#endregion
|
|
439
471
|
//#region src/lib/parse-env.d.ts
|
|
@@ -524,5 +556,5 @@ declare function parseEnv<const C extends Config>(config: C): NeonEnv<C>;
|
|
|
524
556
|
declare function parseEnv<const C extends Config, const S extends FunctionSlugOf<C>>(config: C, scope: FunctionScopeField<C, S>): NeonEnv<C> & NeonFunctionEnv<C, S>;
|
|
525
557
|
declare function parseEnv<const C extends Config, const K extends SelectableEnvKey<C>>(config: C, keys: readonly K[]): FilteredNeonEnv<K>;
|
|
526
558
|
//#endregion
|
|
527
|
-
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 };
|
|
559
|
+
export { type FetchEnvOptions, type FilteredNeonEnv, type FunctionBaseUrlKey, type FunctionSlugOf, NEON_ENV_VAR_KEYS, type NeonAiGatewayEnv, type NeonAuthEnv, type NeonBranchEnv, type NeonDataApiEnv, type NeonEnv, type NeonFunctionEnv, type NeonFunctionUrlEnv, type NeonFunctionsEnv, type NeonPostgresEnv, type NeonStorageEnv, type ResolvedNeonEnv, type SelectableEnvKey, type SelectedNeonEnv, fetchEnv, functionBaseUrlKey, isFunctionBaseUrlKey, parseEnv, parseFunctionBaseUrlKey, toEntries };
|
|
528
560
|
//# sourceMappingURL=index.d.ts.map
|