neon 3.1.0 → 3.1.1

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.
Files changed (67) hide show
  1. package/README.md +16 -5
  2. package/dist/{_shared/auth_selection.js → _chunks/auth_selection-DGgq6ifc.js} +3 -3
  3. package/dist/_chunks/cmd_pipeline-CUbBO9U_.js +2818 -0
  4. package/dist/{_shared/credentials.js → _chunks/credentials-MYdHdKah.js} +3 -3
  5. package/dist/_chunks/env-NbA61JR3.js +585 -0
  6. package/dist/{_shared/env-core/env.js → _chunks/env_services-Tz9G4JeT.js} +179 -43
  7. package/dist/{_shared/paths.js → _chunks/paths-DMq0Lt7a.js} +2 -2
  8. package/dist/{_shared/profiles.js → _chunks/profiles-Ir29rqns.js} +4 -13
  9. package/dist/_chunks/psql-DWH-kc69.js +2169 -0
  10. package/dist/{_virtual/_rolldown/runtime.js → _chunks/rolldown-runtime-D7D4PA-g.js} +1 -1
  11. package/dist/{_shared/secure_file.js → _chunks/secure_file-BucZj4yQ.js} +2 -4
  12. package/dist/analytics.js +2 -2
  13. package/dist/auth_context.js +1 -1
  14. package/dist/commands/api.js +2 -2
  15. package/dist/commands/api_keys.js +2 -2
  16. package/dist/commands/auth.js +6 -6
  17. package/dist/commands/bootstrap.js +3 -3
  18. package/dist/commands/branches.js +2 -2
  19. package/dist/commands/bucket.js +2 -2
  20. package/dist/commands/checkout.js +2 -2
  21. package/dist/commands/config.js +2 -2
  22. package/dist/commands/connection_string.js +2 -2
  23. package/dist/commands/data_api.js +2 -2
  24. package/dist/commands/databases.js +2 -2
  25. package/dist/commands/deploy.js +2 -2
  26. package/dist/commands/dev.js +3 -3
  27. package/dist/commands/diff.js +2 -2
  28. package/dist/commands/env.js +42 -32
  29. package/dist/commands/functions.js +2 -2
  30. package/dist/commands/index.js +33 -33
  31. package/dist/commands/init.js +3 -3
  32. package/dist/commands/inspect.js +2 -2
  33. package/dist/commands/ip_allow.js +2 -2
  34. package/dist/commands/link.js +2 -2
  35. package/dist/commands/logs.js +2 -2
  36. package/dist/commands/neon_auth.js +2 -2
  37. package/dist/commands/operations.js +2 -2
  38. package/dist/commands/orgs.js +2 -2
  39. package/dist/commands/profile.js +7 -7
  40. package/dist/commands/projects.js +2 -2
  41. package/dist/commands/psql.js +2 -2
  42. package/dist/commands/roles.js +2 -2
  43. package/dist/commands/set_context.js +2 -2
  44. package/dist/commands/snapshots.js +2 -2
  45. package/dist/commands/status.js +2 -2
  46. package/dist/commands/user.js +2 -2
  47. package/dist/commands/vpc_endpoints.js +2 -2
  48. package/dist/config.js +1 -1
  49. package/dist/dev/env.js +1 -364
  50. package/dist/env_services.js +2 -49
  51. package/dist/index.js +1 -1
  52. package/dist/init/auth.js +4 -4
  53. package/dist/psql/cli.js +1 -1
  54. package/dist/psql/command/cmd_copy.js +1 -1
  55. package/dist/psql/command/cmd_io.js +1 -1403
  56. package/dist/psql/command/cmd_pipeline.js +1 -595
  57. package/dist/psql/command/dispatch.js +1 -2
  58. package/dist/psql/core/common.js +1 -834
  59. package/dist/psql/core/mainloop.js +1 -2
  60. package/dist/psql/core/startup.js +1 -656
  61. package/dist/psql/index.js +1 -1516
  62. package/dist/psql/io/psqlrc.js +1 -1
  63. package/dist/psql/types/index.js +6 -0
  64. package/dist/utils/inspect_db.js +1 -1
  65. package/dist/utils/middlewares.js +2 -1
  66. package/package.json +6 -3
  67. package/dist/_shared/env-core/reuse-secrets.js +0 -179
@@ -1,15 +1,15 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
- import { writeSecretFile } from "../_shared/secure_file.js";
3
- import { API_KEY, OAUTH, apiKeyCredentials, credentialKind, describeScope, inspectCredentials, interpretCredentials, isSameCredential, readCredentials, scopeOf, writeCredentials } from "../_shared/credentials.js";
1
+ import { t as __exportAll } from "../_chunks/rolldown-runtime-D7D4PA-g.js";
2
+ import { t as writeSecretFile } from "../_chunks/secure_file-BucZj4yQ.js";
3
+ import { a as describeScope, c as isSameCredential, d as writeCredentials, i as credentialKind, l as readCredentials, n as OAUTH, o as inspectCredentials, r as apiKeyCredentials, s as interpretCredentials, t as API_KEY, u as scopeOf } from "../_chunks/credentials-MYdHdKah.js";
4
4
  import { isCi } from "../env.js";
5
5
  import { log } from "../log.js";
6
6
  import { getApiClient, isNeonApiError } from "../api.js";
7
- import { isInsideConfigDir } from "../_shared/paths.js";
7
+ import { i as isInsideConfigDir } from "../_chunks/paths-DMq0Lt7a.js";
8
8
  import "../config.js";
9
9
  import { setAuthContext } from "../auth_context.js";
10
10
  import { auth, revokeToken } from "../auth.js";
11
- import { assertProfilesUsable, assertValidProfileName, listProfiles, newProfileCredentialsPath, onlyDefaultRemains, profilesFilePath, readProfiles, resolveProfile, selectProfileName, upsertProfile } from "../_shared/profiles.js";
12
- import { credentialInputs } from "../_shared/auth_selection.js";
11
+ import { a as newProfileCredentialsPath, c as readProfiles, d as upsertProfile, i as listProfiles, l as resolveProfile, n as assertProfilesUsable, o as onlyDefaultRemains, r as assertValidProfileName, s as profilesFilePath, u as selectProfileName } from "../_chunks/profiles-Ir29rqns.js";
12
+ import { t as credentialInputs } from "../_chunks/auth_selection-DGgq6ifc.js";
13
13
  import { authFlow, credentialsPathForName, usableCredential } from "./auth.js";
14
14
  import { writer } from "../writer.js";
15
15
  import { noPassthrough, single } from "../utils/flags.js";
@@ -679,4 +679,4 @@ const revokeTokenSet = async (credentials, props) => {
679
679
  }, tokenSet);
680
680
  };
681
681
  //#endregion
682
- export { aliases, builder, command, describe, handler, profile_exports };
682
+ export { aliases, builder, command, describe, handler, profile_exports as t };
@@ -1,4 +1,4 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
1
+ import { t as __exportAll } from "../_chunks/rolldown-runtime-D7D4PA-g.js";
2
2
  import { isCi } from "../env.js";
3
3
  import { log } from "../log.js";
4
4
  import { isNeonApiError, messageFromBody } from "../api.js";
@@ -351,4 +351,4 @@ const onPromptState = (state) => {
351
351
  }
352
352
  };
353
353
  //#endregion
354
- export { PROJECT_FIELDS, REGIONS, aliases, builder, command, describe, handler, projects_exports };
354
+ export { PROJECT_FIELDS, REGIONS, aliases, builder, command, describe, handler, projects_exports as t };
@@ -1,4 +1,4 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
1
+ import { t as __exportAll } from "../_chunks/rolldown-runtime-D7D4PA-g.js";
2
2
  import { EndpointType } from "../utils/api_enums.js";
3
3
  import { fillSingleProject } from "../utils/enrichers.js";
4
4
  import { SSL_MODES, handler as handler$1 } from "./connection_string.js";
@@ -61,4 +61,4 @@ const handler = async (props) => {
61
61
  });
62
62
  };
63
63
  //#endregion
64
- export { builder, command, describe, handler, psql_exports };
64
+ export { builder, command, describe, handler, psql_exports as t };
@@ -1,4 +1,4 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
1
+ import { t as __exportAll } from "../_chunks/rolldown-runtime-D7D4PA-g.js";
2
2
  import { retryOnLock } from "../api.js";
3
3
  import { writer } from "../writer.js";
4
4
  import { branchIdFromProps, fillSingleProject } from "../utils/enrichers.js";
@@ -59,4 +59,4 @@ const deleteRole = async (props) => {
59
59
  if (data) writer(props).end(data.role, { fields: ROLES_FIELDS });
60
60
  };
61
61
  //#endregion
62
- export { aliases, builder, command, create, deleteRole, describe, handler, list, roles_exports };
62
+ export { aliases, builder, command, create, deleteRole, describe, handler, list, roles_exports as t };
@@ -1,4 +1,4 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
1
+ import { t as __exportAll } from "../_chunks/rolldown-runtime-D7D4PA-g.js";
2
2
  import { log } from "../log.js";
3
3
  import { applyContext } from "../context.js";
4
4
  import { getCliName } from "../utils/cli_name.js";
@@ -35,4 +35,4 @@ const handler = (props) => {
35
35
  applyContext(props.contextFile, context);
36
36
  };
37
37
  //#endregion
38
- export { builder, command, describe, handler, set_context_exports };
38
+ export { builder, command, describe, handler, set_context_exports as t };
@@ -1,4 +1,4 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
1
+ import { t as __exportAll } from "../_chunks/rolldown-runtime-D7D4PA-g.js";
2
2
  import { log } from "../log.js";
3
3
  import { retryOnLock } from "../api.js";
4
4
  import { writer } from "../writer.js";
@@ -327,4 +327,4 @@ const scheduleSet = async (props) => {
327
327
  });
328
328
  };
329
329
  //#endregion
330
- export { SNAPSHOT_FIELDS, aliases, builder, command, describe, handler, snapshots_exports };
330
+ export { SNAPSHOT_FIELDS, aliases, builder, command, describe, handler, snapshots_exports as t };
@@ -1,4 +1,4 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
1
+ import { t as __exportAll } from "../_chunks/rolldown-runtime-D7D4PA-g.js";
2
2
  import { fillSingleProject } from "../utils/enrichers.js";
3
3
  import { status } from "./config.js";
4
4
  //#region src/commands/status.ts
@@ -41,4 +41,4 @@ const builder = (argv) => argv.usage("$0 status [options]").options({
41
41
  }).middleware(fillSingleProject);
42
42
  const handler = (args) => status(args);
43
43
  //#endregion
44
- export { builder, command, describe, handler, status_exports };
44
+ export { builder, command, describe, handler, status_exports as t };
@@ -1,4 +1,4 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
1
+ import { t as __exportAll } from "../_chunks/rolldown-runtime-D7D4PA-g.js";
2
2
  import { writer } from "../writer.js";
3
3
  //#region src/commands/user.ts
4
4
  var user_exports = /* @__PURE__ */ __exportAll({
@@ -23,4 +23,4 @@ const me = async (props) => {
23
23
  ] });
24
24
  };
25
25
  //#endregion
26
- export { builder, command, describe, handler, user_exports };
26
+ export { builder, command, describe, handler, user_exports as t };
@@ -1,4 +1,4 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
1
+ import { t as __exportAll } from "../_chunks/rolldown-runtime-D7D4PA-g.js";
2
2
  import { log } from "../log.js";
3
3
  import { writer } from "../writer.js";
4
4
  import { fillSingleOrg, fillSingleProject } from "../utils/enrichers.js";
@@ -103,4 +103,4 @@ const removeProject = async (props) => {
103
103
  writer(props).end(data, { fields: [] });
104
104
  };
105
105
  //#endregion
106
- export { builder, command, describe, vpc_endpoints_exports };
106
+ export { builder, command, describe, vpc_endpoints_exports as t };
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { isCi } from "./env.js";
2
- import { CREDENTIALS_FILE, credentialsPath, defaultDir, isInsideConfigDir, isOwnedCredentialPath } from "./_shared/paths.js";
2
+ import { a as isOwnedCredentialPath, i as isInsideConfigDir, n as credentialsPath, r as defaultDir, t as CREDENTIALS_FILE } from "./_chunks/paths-DMq0Lt7a.js";
3
3
  import { existsSync, mkdirSync } from "node:fs";
4
4
  //#region src/config.ts
5
5
  const ensureConfigDir = ({ "config-dir": configDirArg, "force-auth": forceAuth }) => {
package/dist/dev/env.js CHANGED
@@ -1,365 +1,2 @@
1
- import { log } from "../log.js";
2
- import { getCliName } from "../utils/cli_name.js";
3
- import { NEON_ENV_VAR_KEYS } from "../_shared/env-core/env.js";
4
- import { formatInstallCommand, resolvePackageManager } from "../utils/package_manager.js";
5
- import { fetchEnvReusingSecrets } from "../_shared/env-core/reuse-secrets.js";
6
- import { createNeonApiFromOptions, loadConfigFromFile } from "@neon/config";
7
- import { plan, pullConfig } from "@neon/config-runtime";
8
- //#region src/dev/env.ts
9
- /** The API-targeting options every runtime call forwards from the context. */
10
- const apiOptions = (ctx) => ({
11
- ...ctx.apiKey ? { apiKey: ctx.apiKey } : {},
12
- ...ctx.apiHost ? { apiHost: ctx.apiHost } : {},
13
- ...ctx.api ? { api: ctx.api } : {}
14
- });
15
- /**
16
- * Thrown when a `neon.ts` policy declares a branch-level resource (Neon Auth,
17
- * Data API, a bucket, the AI Gateway) that the linked remote branch does not
18
- * have yet. Unlike every other failure in {@link resolveDevEnv} — which degrades
19
- * to "run without injection" — this is a hard stop: the user's intent (a policy)
20
- * cannot be honored, and silently dropping the secret would be more confusing
21
- * than refusing to start. The fix is to provision the resource first.
22
- */
23
- var DevEnvMismatchError = class extends Error {
24
- constructor(..._args) {
25
- super(..._args);
26
- this.name = "DevEnvMismatchError";
27
- }
28
- };
29
- /**
30
- * Signals that no project/branch context could be resolved, so there is nothing to
31
- * resolve env from. `resolveDevEnv` degrades on this (dev runs without injection);
32
- * `env pull` surfaces it (an explicit pull needs a branch).
33
- */
34
- var MissingBranchContextError = class extends Error {
35
- constructor(..._args2) {
36
- super(..._args2);
37
- this.name = "MissingBranchContextError";
38
- }
39
- };
40
- /**
41
- * Thrown when an explicit `--service` selection names a service the branch does not have.
42
- * Unlike the policy path — where the same situation is a {@link DevEnvMismatchError} pointing
43
- * at `deploy` — the user named the service on the command line, so the fix is to provision it
44
- * or drop it from the selection.
45
- */
46
- var ServiceNotOnBranchError = class extends Error {
47
- constructor(..._args3) {
48
- super(..._args3);
49
- this.name = "ServiceNotOnBranchError";
50
- }
51
- };
52
- /**
53
- * Resolve the branch's Neon env vars (pooled / direct `DATABASE_URL`, plus Auth /
54
- * Data API when enabled) into a `{ KEY: value }` map. Shared by `neon dev` (which
55
- * injects them) and `neon env pull` (which writes them to a `.env` file).
56
- *
57
- * Tiered:
58
- *
59
- * 0. {@link DevEnvContext.services} is set -> that selection *is* the policy, and any
60
- * `neon.ts` is ignored. See {@link resolveSelectedServices}.
61
- * 1. a `neon.ts` policy is found -> the policy is the source of truth. We first
62
- * check it against the branch's live state (`plan`); if it declares a resource
63
- * the branch is missing, we stop with a {@link DevEnvMismatchError} pointing at
64
- * `neonctl deploy`. Otherwise `fetchEnv` evaluates the policy.
65
- * 2. no `neon.ts`, but a project + branch are known -> `pullConfig` reads the
66
- * branch's live state (Auth / Data API enablement plus any object-storage
67
- * buckets) into a config, then `fetchEnv` resolves what is actually enabled —
68
- * so a branch with a bucket gets its `AWS_*` storage vars pulled with no policy.
69
- * With {@link DevEnvContext.implyAiGateway}, the AI Gateway is added on top, since
70
- * `pullConfig` cannot read it back.
71
- * 3. otherwise -> throw {@link MissingBranchContextError}.
72
- *
73
- * Unlike {@link resolveDevEnv}, this never swallows errors — callers decide how to
74
- * handle them.
75
- */
76
- const resolveNeonEnvVars = async (ctx) => {
77
- if (ctx.services) return await resolveSelectedServices(ctx, ctx.services);
78
- const config = await loadNeonConfig(ctx.cwd);
79
- if (config) {
80
- if (!ctx.projectId || !ctx.branchId) throw new MissingBranchContextError(`Found a neon.ts but could not resolve the project/branch. Run \`${getCliName()} link\` and \`${getCliName()} checkout <branch>\`, or pass --project-id / --branch.`);
81
- const envConfig = withoutPreviewFunctions(config);
82
- await assertPolicyMatchesBranch(envConfig, ctx);
83
- return await fetchAndProject(envConfig, ctx);
84
- }
85
- if (ctx.projectId && ctx.branchId) {
86
- const pulled = await pullConfig({
87
- projectId: ctx.projectId,
88
- branchId: ctx.branchId,
89
- ...apiOptions(ctx)
90
- });
91
- if (!ctx.implyAiGateway) return await fetchAndProject(pulled.config, ctx);
92
- return await resolveWithImpliedGateway(pulled.config, ctx, {
93
- projectId: ctx.projectId,
94
- branchId: ctx.branchId
95
- });
96
- }
97
- throw new MissingBranchContextError(`No project/branch context found. Link a branch (\`${getCliName()} link\` / \`${getCliName()} checkout\`) or pass --project-id and --branch.`);
98
- };
99
- /** The same config with the AI Gateway enabled, leaving any other `preview` entries intact. */
100
- const withAiGateway = (config) => ({
101
- ...config,
102
- preview: {
103
- ...config.preview,
104
- aiGateway: true
105
- }
106
- });
107
- /**
108
- * Tier-2 resolution with the AI Gateway added on top of the branch's read-back state.
109
- *
110
- * The gateway is not detectable — `pullConfig` reports no enabled flag for it — so it is
111
- * implied rather than observed. Nobody named it, so it must never be the reason the whole
112
- * resolve fails: a project outside the regions where branch credentials exist would otherwise
113
- * lose its `DATABASE_URL` too, and `neon dev` would start with no env at all.
114
- *
115
- * So the gateway is only added once its credential endpoint has been shown to answer, by
116
- * reading the branch's credentials first. A project that does not have them says so on a
117
- * read, before anything is minted — which is the whole question, since the gateway's env is a
118
- * credential and nothing else.
119
- *
120
- * Deciding this **before** resolving, rather than by catching and retrying, is what keeps it
121
- * honest. A retry re-runs every call the first attempt made, so it would blame the gateway for
122
- * a one-off failure in shared work, and — worse — a first attempt that minted a credential and
123
- * then failed would be papered over by a second that succeeds without one, swallowing the
124
- * error and stranding a secret nobody holds. Once the read succeeds, a later failure is a real
125
- * failure and propagates: the same thing already happens on a branch with object storage,
126
- * whose credential is minted whether or not the gateway is involved.
127
- */
128
- const resolveWithImpliedGateway = async (config, ctx, branch) => {
129
- const unreachable = await credentialsUnreachable(ctx, branch);
130
- if (unreachable === null) return await fetchAndProject(withAiGateway(config), ctx);
131
- log.warning(`Could not reach the AI Gateway's credentials, so %s were not resolved. Everything else was. Either this project does not have the AI Gateway, or the call failed — \`${getCliName()} env pull -s ai-gateway\` will say which.\nDetails: %s`, [NEON_ENV_VAR_KEYS.aiGateway.apiKey, NEON_ENV_VAR_KEYS.aiGateway.baseUrl].join(" and "), unreachable);
132
- return {
133
- ...await fetchAndProject(config, ctx),
134
- skipped: ["ai-gateway"]
135
- };
136
- };
137
- /**
138
- * Why the branch's credentials could not be read, or `null` when they could. A plain read: it
139
- * mints nothing, revokes nothing, and changes nothing, so asking is free of the side effects
140
- * that make a failed resolve ambiguous.
141
- */
142
- const credentialsUnreachable = async (ctx, branch) => {
143
- try {
144
- await apiFor(ctx).listCredentials(branch.projectId, branch.branchId);
145
- return null;
146
- } catch (err) {
147
- return err instanceof Error ? err.message : String(err);
148
- }
149
- };
150
- /** The adapter for direct branch reads: the injected one in tests, else built from options. */
151
- const apiFor = (ctx) => ctx.api ?? createNeonApiFromOptions("neon env", {
152
- ...ctx.apiKey ? { apiKey: ctx.apiKey } : {},
153
- ...ctx.apiHost ? { apiHost: ctx.apiHost } : {}
154
- });
155
- /**
156
- * Tier-0: resolve exactly the services `--service` named, with `neon.ts` out of the picture.
157
- *
158
- * The selection is checked against the branch's live state so a service that is named but not
159
- * provisioned fails by name, instead of quietly contributing no vars. `postgres` and the AI
160
- * Gateway are not checked: every branch has Postgres, and the gateway has no branch-level
161
- * state to check (an unavailable one surfaces when its credential is minted).
162
- */
163
- const resolveSelectedServices = async (ctx, services) => {
164
- const { projectId, branchId } = ctx;
165
- if (!projectId || !branchId) throw new MissingBranchContextError(`--service needs a project and branch to read from. Run \`${getCliName()} link\` and \`${getCliName()} checkout <branch>\`, or pass --project-id / --branch.`);
166
- const api = apiFor(ctx);
167
- const has = (service) => services.includes(service);
168
- const [auth, dataApiEnabled, buckets] = await Promise.all([
169
- has("auth") ? api.getNeonAuth(projectId, branchId) : null,
170
- has("data-api") ? readDataApiEnabled(api, projectId, branchId) : null,
171
- has("object-storage") ? api.listBranchBuckets(projectId, branchId) : null
172
- ]);
173
- const config = configForServices(services, branchId, {
174
- authEnabled: auth !== null,
175
- dataApiEnabled,
176
- buckets: buckets ?? []
177
- });
178
- return await fetchAndProject(config, ctx, { revokeSuperseded: false });
179
- };
180
- /**
181
- * Whether the branch has a Data API integration — or `null` when that cannot be determined.
182
- *
183
- * It is enabled per branch *and database*, so this has to probe the database `fetchEnv` will
184
- * resolve the URL from, or the two would disagree. That is Neon's default `neondb`, else the
185
- * only database; several databases with no `neondb` is a case `fetchEnv` refuses to auto-pick
186
- * at all. Reporting "no Data API integration" there would be a claim this read cannot support,
187
- * so it answers `null` and lets `fetchEnv` raise its own ambiguity error, which names the
188
- * databases and the fix.
189
- */
190
- const readDataApiEnabled = async (api, projectId, branchId) => {
191
- const databases = await api.listBranchDatabases(projectId, branchId);
192
- const database = databases.find((db) => db.name === NEON_DEFAULT_DATABASE) ?? (databases.length === 1 ? databases[0] : void 0);
193
- if (!database) return databases.length === 0 ? false : null;
194
- return await api.getNeonDataApi(projectId, branchId, database.name) !== null;
195
- };
196
- /** Neon's default database, and the one `fetchEnv` prefers when a branch has several. */
197
- const NEON_DEFAULT_DATABASE = "neondb";
198
- /**
199
- * Build the `Config` an explicit `--service` selection stands for, raising
200
- * {@link ServiceNotOnBranchError} for anything the branch does not have. Naming a service
201
- * that isn't there has to fail rather than contribute no vars, or a scoped pull would report
202
- * "no Neon env variables to pull" — which reads as a statement about the branch rather than
203
- * about the selection.
204
- */
205
- const configForServices = (services, branchId, branch) => {
206
- const provisionWith = {
207
- auth: `${getCliName()} neon-auth enable`,
208
- "data-api": `${getCliName()} data-api create`,
209
- "object-storage": `${getCliName()} buckets create <name>`
210
- };
211
- const notOnBranch = (service, what) => {
212
- throw new ServiceNotOnBranchError(`--service ${service}: branch ${branchId} has no ${what}, so there are no ${service} env vars to pull. Provision it first (\`${provisionWith[service]}\`, or in the Neon Console), or drop ${service} from --service.`);
213
- };
214
- const config = {};
215
- if (services.includes("auth")) {
216
- if (!branch.authEnabled) notOnBranch("auth", "Neon Auth integration");
217
- config.auth = true;
218
- }
219
- if (services.includes("data-api")) {
220
- if (branch.dataApiEnabled === false) notOnBranch("data-api", "Data API integration");
221
- config.dataApi = true;
222
- }
223
- const preview = {};
224
- if (services.includes("object-storage")) {
225
- if (branch.buckets.length === 0) notOnBranch("object-storage", "object-storage buckets");
226
- preview.buckets = Object.fromEntries(branch.buckets.map((bucket) => [bucket.name, { access: bucket.accessLevel }]));
227
- }
228
- if (services.includes("ai-gateway")) preview.aiGateway = true;
229
- if (Object.keys(preview).length > 0) config.preview = preview;
230
- return config;
231
- };
232
- /**
233
- * `neon dev`'s env resolver: {@link resolveNeonEnvVars} with graceful degradation.
234
- *
235
- * - Success → `{ vars }` (possibly just the always-present Postgres URLs).
236
- * - No linked branch / project → `{ vars: {}, skipped }` with a "link a branch" hint; the
237
- * function still runs locally, just without Neon env.
238
- * - Any other failure (offline, transient API error) → `{ vars: {}, skipped }` naming the
239
- * cause; again non-fatal.
240
- * - {@link DevEnvMismatchError} (policy declares a secret-bearing service the branch lacks)
241
- * is the one hard stop and is re-thrown for the caller to surface.
242
- */
243
- const resolveDevEnv = async (ctx) => {
244
- try {
245
- const { vars, credential } = await resolveNeonEnvVars(ctx);
246
- return {
247
- vars,
248
- credential
249
- };
250
- } catch (err) {
251
- if (err instanceof DevEnvMismatchError) throw err;
252
- if (err instanceof MissingBranchContextError) {
253
- log.debug("dev: %s; skipping env injection", err.message);
254
- return {
255
- vars: {},
256
- skipped: { reason: `no linked Neon branch — run \`${getCliName()} link\`, then \`${getCliName()} checkout <branch>\`, to inject DATABASE_URL and friends` }
257
- };
258
- }
259
- const detail = err instanceof Error ? err.message : String(err);
260
- log.debug("dev: env resolution failed: %s", detail);
261
- return {
262
- vars: {},
263
- skipped: { reason: `could not reach Neon (${detail}); running without Neon env` }
264
- };
265
- }
266
- };
267
- /**
268
- * Return the policy with its `preview.functions` removed, so the env path never enumerates
269
- * functions against the Neon API. Functions are local-source-bundled and produce no
270
- * branch-level secrets, so they are irrelevant to env resolution; probing them only risks
271
- * failing the whole resolve (undeployed function, or Functions Preview disabled on the
272
- * project). Buckets / AI Gateway and the top-level Auth / Data API toggles are preserved —
273
- * they DO carry env, so they must still be checked and resolved. Returns the config
274
- * unchanged when it declares no functions.
275
- */
276
- const withoutPreviewFunctions = (config) => {
277
- const preview = config.preview;
278
- if (!preview?.functions) return config;
279
- const previewWithoutFunctions = { ...preview };
280
- delete previewWithoutFunctions.functions;
281
- return {
282
- ...config,
283
- preview: previewWithoutFunctions
284
- };
285
- };
286
- /**
287
- * Tier-1 guard. Dry-run the policy against the branch's live state and stop if
288
- * it declares a branch-level resource the branch is missing. Built on `plan` so
289
- * it covers every present and future provisionable resource for free: any
290
- * `create` action is a resource `neonctl deploy` would provision.
291
- *
292
- * Called with functions already stripped (see {@link withoutPreviewFunctions}), so the
293
- * `plan` probe never enumerates the functions API — an undeployed function, or a project
294
- * without the Functions Preview, must never block local dev or sink env injection.
295
- */
296
- const assertPolicyMatchesBranch = async (config, ctx) => {
297
- const missing = (await plan(config, {
298
- projectId: ctx.projectId,
299
- branchId: ctx.branchId,
300
- ...apiOptions(ctx)
301
- })).applied.filter(isMissingResource);
302
- if (missing.length === 0) return;
303
- throw new DevEnvMismatchError(`Your neon.ts declares ${missing.map((change) => change.identifier).join(", ")} for branch ${ctx.branchId}, but the branch does not have it yet, so the matching env vars cannot be injected. Provision it first with \`${getCliName()} deploy\` (or \`${getCliName()} config apply\`), then re-run \`${getCliName()} dev\`.`);
304
- };
305
- /**
306
- * A planned change that provisions a branch-level resource the branch lacks: a
307
- * `create` on a service (Neon Auth, Data API, a bucket, the AI Gateway). Branch
308
- * setting drift (`update`) and `noop`s are ignored — they don't block local dev
309
- * — and functions are excluded (see {@link assertPolicyMatchesBranch}).
310
- */
311
- const isMissingResource = (change) => change.kind === "service" && change.action === "create" && !change.identifier.startsWith("function:");
312
- const fetchAndProject = async (config, ctx, opts = {}) => fetchEnvReusingSecrets(config, {
313
- projectId: ctx.projectId,
314
- branch: ctx.branchId,
315
- ...apiOptions(ctx),
316
- ...ctx.env ? { env: ctx.env } : {},
317
- ...opts.revokeSuperseded === false ? { revokeSuperseded: false } : {}
318
- });
319
- /**
320
- * Load a `neon.ts` policy if one exists on the path from `cwd` up to the repo
321
- * root. Returns `null` when there is none (the common "no config" case), and
322
- * surfaces real load errors (e.g. a syntax error in an existing file).
323
- */
324
- /**
325
- * Substrings that mark a module-resolution failure while loading `neon.ts` —
326
- * almost always because the project's dependencies aren't installed yet (the
327
- * config imports `@neon/config` & friends). Deliberately specific:
328
- * the generic "…or a missing dependency…" hint the loader always appends is
329
- * NOT in here, so a real syntax/runtime error doesn't get mislabeled.
330
- */
331
- const MISSING_DEPENDENCY_HINTS = [
332
- "cannot find module",
333
- "cannot find package",
334
- "err_module_not_found",
335
- "failed to resolve",
336
- "could not resolve",
337
- "module not found"
338
- ];
339
- /** Flatten an error and its `cause` chain to one lowercased string for matching. */
340
- const errorChainText = (err) => {
341
- const parts = [];
342
- let current = err;
343
- for (let depth = 0; current instanceof Error && depth < 6; depth++) {
344
- parts.push(current.message);
345
- current = current.cause;
346
- }
347
- return parts.join("\n").toLowerCase();
348
- };
349
- const looksLikeMissingDependency = (err) => {
350
- const text = errorChainText(err);
351
- return MISSING_DEPENDENCY_HINTS.some((hint) => text.includes(hint));
352
- };
353
- const loadNeonConfig = async (cwd) => {
354
- try {
355
- const { config } = await loadConfigFromFile({ cwd });
356
- return config;
357
- } catch (err) {
358
- const message = err instanceof Error ? err.message : String(err);
359
- if (/Could not find a Neon config file/i.test(message)) return null;
360
- if (looksLikeMissingDependency(err)) throw new Error(`Could not load neon.ts: a package it imports is not installed. Run \`${formatInstallCommand(resolvePackageManager(cwd))}\`, then try again.\nOriginal error: ${message}`);
361
- throw err;
362
- }
363
- };
364
- //#endregion
1
+ import { a as resolveNeonEnvVars, i as resolveDevEnv, n as MissingBranchContextError, r as ServiceNotOnBranchError, t as DevEnvMismatchError } from "../_chunks/env-NbA61JR3.js";
365
2
  export { DevEnvMismatchError, MissingBranchContextError, ServiceNotOnBranchError, resolveDevEnv, resolveNeonEnvVars };
@@ -1,49 +1,2 @@
1
- import { NEON_SERVICES } from "./neon_services.js";
2
- import { NEON_ENV_VAR_KEYS } from "./_shared/env-core/env.js";
3
- //#region src/env_services.ts
4
- /**
5
- * The services `env pull --service` can select: every Neon service that produces branch env
6
- * vars. `functions` is the one left out — a function's env comes from the local `neon.ts`,
7
- * never from the branch, so there is nothing to pull.
8
- */
9
- const ENV_PULL_SERVICES = NEON_SERVICES.filter((service) => service !== "functions");
10
- /** Why the services `env pull` leaves out are not selectable, for the refusal message. */
11
- const ENV_PULL_UNAVAILABLE = { functions: "a function's env comes from your neon.ts, not from the branch, so there is nothing to pull" };
12
- /** The OS-level env vars each service contributes to a pulled `.env`. */
13
- const SERVICE_ENV_KEYS = {
14
- postgres: Object.values(NEON_ENV_VAR_KEYS.postgres),
15
- auth: Object.values(NEON_ENV_VAR_KEYS.auth),
16
- "data-api": Object.values(NEON_ENV_VAR_KEYS.dataApi),
17
- "object-storage": Object.values(NEON_ENV_VAR_KEYS.storage),
18
- "ai-gateway": Object.values(NEON_ENV_VAR_KEYS.aiGateway),
19
- functions: []
20
- };
21
- /**
22
- * The subset of {@link SERVICE_ENV_KEYS} a pull *owns*, and so may prune from the target file
23
- * when the branch no longer has it. Object storage is deliberately absent: it is emitted under
24
- * the third-party `AWS_*` names, which collide with credentials a user may set by hand, so
25
- * `env pull` only ever writes them.
26
- */
27
- const SERVICE_OWNED_ENV_KEYS = {
28
- ...SERVICE_ENV_KEYS,
29
- "object-storage": []
30
- };
31
- /**
32
- * Branch identity. Not a service — every branch has a name — so a scoped pull refreshes it
33
- * alongside whatever services were selected.
34
- */
35
- const BRANCH_ENV_KEY = NEON_ENV_VAR_KEYS.branch.name;
36
- /** Every env var the selected services contribute, plus branch identity. */
37
- const envServiceKeys = (services) => {
38
- const keys = /* @__PURE__ */ new Set([BRANCH_ENV_KEY]);
39
- for (const service of services) for (const key of SERVICE_ENV_KEYS[service]) keys.add(key);
40
- return keys;
41
- };
42
- /**
43
- * The env vars a pull scoped to `services` may prune. Narrower than the unscoped set on
44
- * purpose: `env pull -s ai-gateway` says nothing about `DATABASE_URL`, so it must leave it
45
- * alone rather than treat its absence from this pull as "the branch no longer has it".
46
- */
47
- const ownedEnvServiceKeys = (services) => services.flatMap((service) => SERVICE_OWNED_ENV_KEYS[service]);
48
- //#endregion
49
- export { BRANCH_ENV_KEY, ENV_PULL_SERVICES, ENV_PULL_UNAVAILABLE, envServiceKeys, ownedEnvServiceKeys };
1
+ import { a as envKeysForSelection, c as ownedEnvServiceKeys, d as servicesForEnvKeys, i as ENV_PULL_UNAVAILABLE, l as parseEnvPullKeys, n as ENV_PULL_KEYS, o as envPullFlagValue, r as ENV_PULL_SERVICES, s as envServiceKeys, t as BRANCH_ENV_KEY, u as serviceForEnvKey } from "./_chunks/env_services-Tz9G4JeT.js";
2
+ export { BRANCH_ENV_KEY, ENV_PULL_KEYS, ENV_PULL_SERVICES, ENV_PULL_UNAVAILABLE, envKeysForSelection, envPullFlagValue, envServiceKeys, ownedEnvServiceKeys, parseEnvPullKeys, serviceForEnvKey, servicesForEnvKeys };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { log } from "./log.js";
2
2
  import pkg_default from "./pkg.js";
3
3
  import { isNeonApiError, messageFromBody } from "./api.js";
4
- import { defaultDir } from "./_shared/paths.js";
4
+ import { r as defaultDir } from "./_chunks/paths-DMq0Lt7a.js";
5
5
  import { ensureConfigDir } from "./config.js";
6
6
  import { authFailureMessage, credentialsToClearOn401, getAuthContext } from "./auth_context.js";
7
7
  import { currentContextFile, enrichFromContext } from "./context.js";
package/dist/init/auth.js CHANGED
@@ -1,6 +1,6 @@
1
- import { inspectCredentials, interpretCredentials } from "../_shared/credentials.js";
2
- import { resolveConfigFile } from "../_shared/paths.js";
3
- import { DEFAULT_PROFILE } from "../_shared/profiles.js";
1
+ import { o as inspectCredentials, s as interpretCredentials } from "../_chunks/credentials-MYdHdKah.js";
2
+ import { o as resolveConfigFile } from "../_chunks/paths-DMq0Lt7a.js";
3
+ import { t as DEFAULT_PROFILE } from "../_chunks/profiles-Ir29rqns.js";
4
4
  import { log } from "@clack/prompts";
5
5
  import { execa } from "execa";
6
6
  //#region src/init/auth.ts
@@ -43,7 +43,7 @@ async function isAuthenticated() {
43
43
  * Shares the reader with `neon` and `@neon/env` rather than keeping a copy — the inline path
44
44
  * resolution this replaced was the third implementation of "where is the config directory", and
45
45
  * it also looked only for `access_token`, so an account signed in with an API key read as not
46
- * authenticated and got sent to a browser. See `shared/cli-core/README.md`.
46
+ * authenticated and got sent to a browser. See `internals/cli-core/README.md`.
47
47
  *
48
48
  * `null` means *absent*, and only absent. A file that exists and cannot be read throws: this
49
49
  * value decides whether to start a browser sign-in, and a sign-in overwrites the file it could
package/dist/psql/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { looksLikeConnectionString, runPsql } from "./index.js";
2
+ import { i as looksLikeConnectionString, u as runPsql } from "../_chunks/psql-DWH-kc69.js";
3
3
  //#region src/psql/cli.ts
4
4
  /**
5
5
  * Standalone psql shim.
@@ -1,6 +1,6 @@
1
1
  import { writeErr, writeOut } from "./shared.js";
2
2
  import { pumpReadable } from "../wire/copy.js";
3
- import { getPipelineState } from "./cmd_pipeline.js";
3
+ import { m as getPipelineState } from "../../_chunks/cmd_pipeline-CUbBO9U_.js";
4
4
  import { createReadStream, createWriteStream, promises } from "node:fs";
5
5
  import { spawn } from "node:child_process";
6
6
  import { Buffer } from "node:buffer";