neon 8.14.0 → 8.15.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.
Files changed (34) hide show
  1. package/README.md +1 -1
  2. package/dist/_chunks/{auth-DPSDYYtG.js → auth-rup6nemJ.js} +38 -1
  3. package/dist/_chunks/{checkout-C6VMMgY6.js → checkout-BpOcFaAi.js} +2 -2
  4. package/dist/_chunks/{config-7SIE_C5O.js → config-BjCm5cfr.js} +56 -4
  5. package/dist/_chunks/{deploy-DmKZcAnR.js → deploy-DmEEhux0.js} +1 -1
  6. package/dist/_chunks/{dev-Dv0HKcFF.js → dev-DlUJFzRs.js} +1 -1
  7. package/dist/_chunks/{git-Dxw9w9dK.js → git-j6xSVo3e.js} +2 -2
  8. package/dist/_chunks/{init-BOOGv-mD.js → init-CcVJb492.js} +1 -1
  9. package/dist/_chunks/{link-CcwTXRny.js → link-nAiuWKfg.js} +1 -1
  10. package/dist/_chunks/{profile-H0d7gFrX.js → profile-BAlM625e.js} +1 -1
  11. package/dist/_chunks/{status-DS_yUXFo.js → status-BC4XXuuE.js} +1 -1
  12. package/dist/api.js +2 -2
  13. package/dist/auth_recovery.js +1 -1
  14. package/dist/commands/auth.js +1 -1
  15. package/dist/commands/checkout.js +1 -1
  16. package/dist/commands/config.js +1 -1
  17. package/dist/commands/deploy.js +1 -1
  18. package/dist/commands/dev.js +1 -1
  19. package/dist/commands/functions_new.js +1 -1
  20. package/dist/commands/git.js +1 -1
  21. package/dist/commands/index.js +10 -10
  22. package/dist/commands/init.js +1 -1
  23. package/dist/commands/link.js +1 -1
  24. package/dist/commands/profile.js +1 -1
  25. package/dist/commands/status.js +1 -1
  26. package/dist/config_format.js +9 -1
  27. package/dist/config_template.js +36 -9
  28. package/dist/index.js +1 -1
  29. package/dist/init/auth.js +23 -2
  30. package/dist/init/link.js +2 -2
  31. package/dist/init/run.js +27 -5
  32. package/dist/init/wizard.js +1 -1
  33. package/dist/utils/service_picker.js +1 -1
  34. package/package.json +8 -8
package/README.md CHANGED
@@ -673,7 +673,7 @@ export default defineConfig({
673
673
 
674
674
  ### Getting a `neon.ts` (`config init`)
675
675
 
676
- `neon config init` scaffolds the policy and installs `@neon/config` / `@neon/env`, so a project can go straight to `plan` / `apply`. It is purely local — no auth, no API calls. In an interactive terminal it asks which services the policy should declare:
676
+ `neon config init` scaffolds the policy and installs `@neon/config` / `@neon/env`, so a project can go straight to `plan` / `apply`. It is local — no auth and no API calls — except `--services data-api`, which reads the linked branch's Data API with a credential already on hand (never a login) so the scaffold declares the right auth. In an interactive terminal it asks which services the policy should declare:
677
677
 
678
678
  ```
679
679
  ? Which Neon services should neon.ts declare? (space to toggle, enter to confirm) ›
@@ -28,6 +28,7 @@ var auth_exports = /* @__PURE__ */ __exportAll({
28
28
  deleteCredentialsAt: () => deleteCredentialsAt,
29
29
  describe: () => describe,
30
30
  ensureAuth: () => ensureAuth,
31
+ existingApiClient: () => existingApiClient,
31
32
  handler: () => handler,
32
33
  isAccessTokenUsable: () => isAccessTokenUsable,
33
34
  locationForAuth: () => locationForAuth,
@@ -288,6 +289,42 @@ const usableCredential = async (props, at) => {
288
289
  return null;
289
290
  }
290
291
  };
292
+ /**
293
+ * The API client for a credential this invocation already holds — the `--api-key` flag or
294
+ * `NEON_API_KEY`, or the selected profile's stored key or OAuth session, refreshed when
295
+ * expired — along with the key it uses. Never starts a login, so a read that only enriches a
296
+ * local file cannot interrupt it. Null when there is no such credential.
297
+ *
298
+ * Selection follows {@link ensureAuth} exactly; only the fallback differs. `ensureAuth` may
299
+ * log in, and a caller that is only reading a branch to improve a scaffold must not.
300
+ */
301
+ const existingApiClient = async (props) => {
302
+ const selection = selectCredential({
303
+ ...credentialInputs(),
304
+ profileFlag: props.profile
305
+ });
306
+ if (selection.source !== "profile") return {
307
+ apiKey: selection.apiKey,
308
+ apiClient: getApiClient({
309
+ apiKey: selection.apiKey,
310
+ apiHost: props.apiHost
311
+ })
312
+ };
313
+ const usable = await usableCredential({
314
+ configDir: props.configDir,
315
+ apiHost: props.apiHost,
316
+ oauthHost: props.oauthHost ?? process.env.NEON_OAUTH_HOST ?? "https://oauth2.neon.tech",
317
+ clientId: props.clientId ?? "neonctl"
318
+ }, locationForAuth(props.configDir, selection.profile));
319
+ if (usable === null) return null;
320
+ return {
321
+ apiKey: usable.apiKey,
322
+ apiClient: getApiClient({
323
+ apiKey: usable.apiKey,
324
+ apiHost: props.apiHost
325
+ })
326
+ };
327
+ };
291
328
  const ensureAuth = async (props) => {
292
329
  if (props._.length === 0 || props.help) return;
293
330
  if (isCurrentBranchProbe(props)) return;
@@ -491,4 +528,4 @@ const deleteCredentialsAt = (at, configDir) => {
491
528
  }
492
529
  };
493
530
  const md5hash = (s) => createHash("md5").update(s).digest("hex");
494
- export { command as a, ensureAuth as c, locationForAuth as d, refreshStoredCredentials as f, builder as i, handler as l, authFlow as n, deleteCredentialsAt as o, usableCredential as p, auth_exports as r, describe as s, aliases as t, isAccessTokenUsable as u };
531
+ export { command as a, ensureAuth as c, isAccessTokenUsable as d, locationForAuth as f, builder as i, existingApiClient as l, usableCredential as m, authFlow as n, deleteCredentialsAt as o, refreshStoredCredentials as p, auth_exports as r, describe as s, aliases as t, handler as u };
@@ -12,8 +12,8 @@ import { fillSingleProject, listAllProjectBranches } from "../utils/enrichers.js
12
12
  import { buildCheckoutEvent, readGitContext } from "../utils/git.js";
13
13
  import { buildHookBranch, loadHookConfig, resolveHookEnv, runCheckoutAfterHook, runCheckoutBeforeHook, runCreateAfterHook, runCreateBeforeHook } from "../utils/hooks.js";
14
14
  import { n as autoPullEnvAfterPin } from "./env-BOt9AZ1j.js";
15
- import { a as applyPolicyOnCreate, f as envFlag, l as createBranchFromPolicyOnCheckout } from "./config-7SIE_C5O.js";
16
- import { i as handler$1 } from "./link-CcwTXRny.js";
15
+ import { a as applyPolicyOnCreate, f as envFlag, l as createBranchFromPolicyOnCheckout } from "./config-BjCm5cfr.js";
16
+ import { i as handler$1 } from "./link-nAiuWKfg.js";
17
17
  import chalk from "chalk";
18
18
  import prompts from "prompts";
19
19
  // src/commands/checkout.ts
@@ -2,10 +2,13 @@ import { t as __exportAll } from "./rolldown-runtime-BJohB4LM.js";
2
2
  import { isCi, isInteractiveTerminal } from "../env.js";
3
3
  import { log } from "../log.js";
4
4
  import { getApiClient } from "../api.js";
5
+ import { r as defaultDir } from "./paths-B55ZfOg1.js";
6
+ import "../config.js";
5
7
  import { contextBranch, ensureDirectoryGitignored, readContextFile } from "../context.js";
6
8
  import { getCliName } from "../utils/cli_name.js";
9
+ import { l as existingApiClient } from "./auth-rup6nemJ.js";
7
10
  import { NEON_SERVICES, NEON_SERVICE_LABELS, deprecatedServiceMessage, servicesFlagValue, servicesOption } from "../neon_services.js";
8
- import { FUNCTION_FILENAME, FUNCTION_SLUG, FUNCTION_TEMPLATE, REQUIRED_PACKAGES, parseConfigInitServices, renderFunctionSource, renderNeonConfig, renderNeonConfigFromView } from "../config_template.js";
11
+ import { FUNCTION_FILENAME, FUNCTION_SLUG, FUNCTION_TEMPLATE, REQUIRED_PACKAGES, dataApiChoiceFromView, parseConfigInitServices, renderFunctionSource, renderNeonConfig, renderNeonConfigFromView } from "../config_template.js";
9
12
  import { TYPESCRIPT_EXTENSION, asRelativeModulePath, editNeonConfig } from "../config_edit.js";
10
13
  import { toNeonConfigView } from "../config_format.js";
11
14
  import { declaredNeonServices } from "../config_services.js";
@@ -208,6 +211,53 @@ const seedFromBranch = async (props) => {
208
211
  branchName: live.branch.name
209
212
  };
210
213
  };
214
+ /**
215
+ * Which `dataApi` entry to scaffold for `data-api`. A linked branch whose Data API already
216
+ * verifies an external IdP gets the external form, so the policy does not go on to enable
217
+ * Neon Auth over it on the first `neon deploy`. The read goes through {@link liveConfigView},
218
+ * the same path as `--from-branch`, so both agree on what the branch has.
219
+ *
220
+ * Anything short of a clear answer — no project to read, no credentials, a failed read, no
221
+ * Data API on the branch — falls back to today's Neon Auth scaffold. The read must never make
222
+ * `init` fail: a user without the Data API loses nothing, and one with it is told how to fix
223
+ * the file by hand.
224
+ */
225
+ const resolveInitDataApiChoice = async (props) => {
226
+ const { projectId } = props;
227
+ if (!projectId) return { kind: "neon" };
228
+ try {
229
+ const access = props.apiClient ? {
230
+ apiClient: props.apiClient,
231
+ apiKey: props.apiKey
232
+ } : await existingApiClient({
233
+ configDir: props.configDir ?? defaultDir,
234
+ apiHost: props.apiHost ?? "https://console.neon.tech/api/v2",
235
+ ...props.profile !== void 0 ? { profile: props.profile } : {},
236
+ ...props.oauthHost !== void 0 ? { oauthHost: props.oauthHost } : {},
237
+ ...props.clientId !== void 0 ? { clientId: props.clientId } : {}
238
+ });
239
+ if (access === null) {
240
+ log.warning("Not signed in, so the Data API on the linked branch could not be read; declaring it with Neon Auth. If it verifies an external identity provider, set dataApi.authProvider to \"external\" in neon.ts before deploying.");
241
+ return { kind: "neon" };
242
+ }
243
+ const ref = await resolveBranchRef({
244
+ apiClient: access.apiClient,
245
+ projectId,
246
+ ...props.branch !== void 0 ? { branch: props.branch } : {}
247
+ });
248
+ const { view } = await liveConfigView({
249
+ projectId,
250
+ branchId: ref.branchId,
251
+ ...access.apiKey ? { apiKey: access.apiKey } : {},
252
+ ...props.apiHost ? { apiHost: props.apiHost } : {},
253
+ ...props.runtimeApi ? { runtimeApi: props.runtimeApi } : {}
254
+ });
255
+ return view.dataApi === void 0 ? { kind: "neon" } : dataApiChoiceFromView(view.dataApi);
256
+ } catch (error) {
257
+ log.warning("Couldn't read the Data API on the linked branch (%s); declaring it with Neon Auth. If it verifies an external identity provider, set dataApi.authProvider to \"external\" in neon.ts before deploying.", error instanceof Error ? error.message : String(error));
258
+ return { kind: "neon" };
259
+ }
260
+ };
211
261
  /** The install command to print, prefixed with a `cd` when the project is not the cwd. */
212
262
  const installCommandFrom = (dir, pm, missing, options) => {
213
263
  const command = formatInstallCommand(pm, [...missing], options);
@@ -265,7 +315,8 @@ const initCmd = async (props) => {
265
315
  }
266
316
  } else {
267
317
  const services = await resolveServices(props);
268
- writeFileSync(join(cwd, "neon.ts"), renderNeonConfig(services));
318
+ const dataApi = services.includes("data-api") ? await resolveInitDataApiChoice(props) : void 0;
319
+ writeFileSync(join(cwd, "neon.ts"), renderNeonConfig(services, dataApi ? { dataApi } : {}));
269
320
  if (!props.silent) {
270
321
  if (services.length === 0) log.info("Created neon.ts with a starter policy.");
271
322
  else {
@@ -273,6 +324,7 @@ const initCmd = async (props) => {
273
324
  log.info("Created neon.ts declaring %s.", declared.join(", "));
274
325
  }
275
326
  }
327
+ if (dataApi?.kind === "external") log.info("The branch's Data API verifies an external identity provider%s, so neon.ts declares it with authProvider \"external\" and does not enable Neon Auth.", dataApi.providerName ? ` (${dataApi.providerName})` : "");
276
328
  if (services.includes("functions")) scaffoldFunction(cwd);
277
329
  }
278
330
  await ensureConfigPackages(cwd, props);
@@ -445,7 +497,7 @@ const builder = (argv) => argv.usage("$0 config <sub-command> [options]").option
445
497
  }), (args) => applyCmd(args)).command("add", "Add a service, function, or bucket to neon.ts (creates it if missing)", (yargs) => yargs.command("auth", "Enable Neon Auth (auth: true)", addSharedOptions, (args) => addCmd(addProps(args, {
446
498
  kind: "service",
447
499
  service: "auth"
448
- }))).command("data-api", "Enable the Data API (dataApi: true) and Neon Auth, which the default provider requires", addSharedOptions, (args) => addCmd(addProps(args, {
500
+ }))).command("data-api", "Enable the Data API (dataApi: true) and Neon Auth, which the default provider requires. For an external identity provider, set dataApi.authProvider to \"external\" instead", addSharedOptions, (args) => addCmd(addProps(args, {
449
501
  kind: "service",
450
502
  service: "data-api"
451
503
  }))).command("ai-gateway", "Enable the AI Gateway (aiGateway: true)", addSharedOptions, (args) => addCmd(addProps(args, {
@@ -502,7 +554,7 @@ const builder = (argv) => argv.usage("$0 config <sub-command> [options]").option
502
554
  also: "postgres alone writes the starter policy; every branch has Postgres. Omitted: pick interactively on a terminal, starter policy in CI or without a TTY."
503
555
  }),
504
556
  "from-branch": {
505
- describe: "Seed neon.ts from a branch's live Neon state instead of asking. Uses the branch pinned in .neon, or --branch <name|id>, or the project's default branch. The only mode of `config init` that calls the Neon API.",
557
+ describe: "Seed neon.ts from a branch's live Neon state instead of asking. Uses the branch pinned in .neon, or --branch <name|id>, or the project's default branch. Needs credentials and a project.",
506
558
  type: "boolean",
507
559
  conflicts: "services"
508
560
  }
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BJohB4LM.js";
2
2
  import { fillSingleProject } from "../utils/enrichers.js";
3
- import { f as envFlag, i as applyFlags, p as envPullFlag, r as applyCmd } from "./config-7SIE_C5O.js";
3
+ import { f as envFlag, i as applyFlags, p as envPullFlag, r as applyCmd } from "./config-BjCm5cfr.js";
4
4
  import { DEPLOY_COMMANDS_EPILOGUE } from "../commands/deploy_help.js";
5
5
  // src/commands/deploy.ts
6
6
  var deploy_exports = /* @__PURE__ */ __exportAll({
@@ -9,7 +9,7 @@ import { findConfigFunctionBySource, resolveFunctionsFromConfig } from "../dev/f
9
9
  import { resolveWatchInputs } from "../dev/inputs.js";
10
10
  import { branchIdResolve } from "../utils/enrichers.js";
11
11
  import { bundleEntry } from "../utils/esbuild.js";
12
- import { f as envFlag } from "./config-7SIE_C5O.js";
12
+ import { f as envFlag } from "./config-BjCm5cfr.js";
13
13
  import { existsSync, mkdirSync, rmSync, statSync, writeFileSync } from "node:fs";
14
14
  import { basename, dirname, join, relative, resolve } from "node:path";
15
15
  import { fileURLToPath } from "node:url";
@@ -5,8 +5,8 @@ import { CONTEXT_FILE, contextBranch, gitBranchMap, gitBranchMapping, isUnfollow
5
5
  import { writer } from "../writer.js";
6
6
  import { neonSafeBranchName } from "../utils/branch_name.js";
7
7
  import { currentGitBranch, gitPull, gitRepoRoot, hasUpstream, installPostCheckoutHook, isGitRepo, isManagedHook, localGitBranches, postCheckoutHookPath, readGitContext, removePostCheckoutHook } from "../utils/git.js";
8
- import { o as quoteFlagValue } from "./link-CcwTXRny.js";
9
- import { o as handler$1 } from "./checkout-C6VMMgY6.js";
8
+ import { o as quoteFlagValue } from "./link-nAiuWKfg.js";
9
+ import { o as handler$1 } from "./checkout-BpOcFaAi.js";
10
10
  import { existsSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  import chalk from "chalk";
@@ -53,7 +53,7 @@ const builder = (yargs) => yargs.usage("$0 init [options]").option("context-file
53
53
  key: "services",
54
54
  allowed: NEON_SERVICES,
55
55
  describe: "Services to declare in neon.ts",
56
- also: "postgres alone writes the starter policy; every branch has Postgres. Implies creating neon.ts. Cannot be combined with --no-config."
56
+ also: "postgres alone writes the starter policy; every branch has Postgres. data-api also declares auth unless the linked branch's Data API already uses an external identity provider. Implies creating neon.ts. Cannot be combined with --no-config."
57
57
  })).option("org-id", {
58
58
  describe: "Forwarded to link: organization ID to link to",
59
59
  type: "string"
@@ -14,7 +14,7 @@ import { createBranch, pickBranchInteractively } from "../utils/branch_picker.js
14
14
  import { looksLikeBranchId } from "../utils/formats.js";
15
15
  import { listAllProjectBranches } from "../utils/enrichers.js";
16
16
  import { n as autoPullEnvAfterPin } from "./env-BOt9AZ1j.js";
17
- import { h as initCmd } from "./config-7SIE_C5O.js";
17
+ import { h as initCmd } from "./config-BjCm5cfr.js";
18
18
  import { formatLinkSummary } from "../commands/link_output.js";
19
19
  import { r as REGIONS } from "./projects-a3X4OFEJ.js";
20
20
  import prompts from "prompts";
@@ -10,7 +10,7 @@ import { _ as upsertProfile, a as canDropProfilesFile, c as listProfiles, d as n
10
10
  import { auth, revokeToken } from "../auth.js";
11
11
  import { t as credentialInputs } from "./auth_selection-CwGLN9Qz.js";
12
12
  import { readOutgoingCredential, retirePreviousCredential, revokeTokenSet, withdrawKey } from "../retire_credential.js";
13
- import { n as authFlow, p as usableCredential } from "./auth-DPSDYYtG.js";
13
+ import { m as usableCredential, n as authFlow } from "./auth-rup6nemJ.js";
14
14
  import { identityFromAuthDetails, isApiKeyMethod, mintedKeyName, notAnApiKeyMessage } from "../profile_keys.js";
15
15
  import { writer } from "../writer.js";
16
16
  import { noPassthrough, single } from "../utils/flags.js";
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BJohB4LM.js";
2
2
  import { fillSingleProject } from "../utils/enrichers.js";
3
- import { y as status } from "./config-7SIE_C5O.js";
3
+ import { y as status } from "./config-BjCm5cfr.js";
4
4
  // src/commands/status.ts
5
5
  var status_exports = /* @__PURE__ */ __exportAll({
6
6
  builder: () => builder,
package/dist/api.js CHANGED
@@ -288,7 +288,7 @@ async function readJsonBody(response) {
288
288
  }
289
289
  }
290
290
  const getApiClient = ({ apiKey, apiHost, requestTimeoutMs = REQUEST_TIMEOUT_MS }) => {
291
- const baseUrl = apiHost ?? DEFAULT_API_HOST;
291
+ const baseUrl = apiHost ?? "https://console.neon.tech/api/v2";
292
292
  const fetchWithTimeout = makeTimedFetch(validateRequestTimeout(requestTimeoutMs));
293
293
  const client = createClient(createConfig({
294
294
  auth: () => apiKey,
@@ -1079,4 +1079,4 @@ const getApiClient = ({ apiKey, apiHost, requestTimeoutMs = REQUEST_TIMEOUT_MS }
1079
1079
  }))
1080
1080
  };
1081
1081
  };
1082
- export { ContentType, NeonApiError, UnreadableResponseError, codeFromBody, getApiClient, isNeonApiError, messageFromBody, retryOnLock };
1082
+ export { ContentType, DEFAULT_API_HOST, NeonApiError, UnreadableResponseError, codeFromBody, getApiClient, isNeonApiError, messageFromBody, retryOnLock };
@@ -2,7 +2,7 @@ import { t as storeFor } from "./_chunks/credential_io-DbeSh3Pl.js";
2
2
  import { log } from "./log.js";
3
3
  import { authFailureMessage, getAuthContext, locationFromContext } from "./auth_context.js";
4
4
  import { AuthRefreshError } from "./auth.js";
5
- import { f as refreshStoredCredentials, u as isAccessTokenUsable } from "./_chunks/auth-DPSDYYtG.js";
5
+ import { d as isAccessTokenUsable, p as refreshStoredCredentials } from "./_chunks/auth-rup6nemJ.js";
6
6
  // src/auth_recovery.ts
7
7
  const supersededOnDisk = (rejectedToken) => {
8
8
  if (rejectedToken === void 0) return false;
@@ -1 +1 @@
1
- export { t as aliases, n as authFlow, i as builder, a as command, o as deleteCredentialsAt, s as describe, c as ensureAuth, l as handler, u as isAccessTokenUsable, d as locationForAuth, f as refreshStoredCredentials, p as usableCredential } from "../_chunks/auth-DPSDYYtG.js";
1
+ export { t as aliases, n as authFlow, i as builder, a as command, o as deleteCredentialsAt, s as describe, c as ensureAuth, l as existingApiClient, u as handler, d as isAccessTokenUsable, f as locationForAuth, p as refreshStoredCredentials, m as usableCredential } from "../_chunks/auth-rup6nemJ.js";
@@ -1 +1 @@
1
- export { t as builder, r as command, i as describe, a as formatCheckoutPolicyFailure, o as handler } from "../_chunks/checkout-C6VMMgY6.js";
1
+ export { t as builder, r as command, i as describe, a as formatCheckoutPolicyFailure, o as handler } from "../_chunks/checkout-BpOcFaAi.js";
@@ -1 +1 @@
1
- export { t as ConfigInstallFailed, n as addCmd, r as applyCmd, i as applyFlags, a as applyPolicyOnCreate, o as builder, s as command, l as createBranchFromPolicyOnCheckout, u as describe, d as ensureConfigPackages, f as envFlag, p as envPullFlag, m as handler, h as initCmd, g as installCommandFrom, _ as missingDependencies, v as planCmd, y as status } from "../_chunks/config-7SIE_C5O.js";
1
+ export { t as ConfigInstallFailed, n as addCmd, r as applyCmd, i as applyFlags, a as applyPolicyOnCreate, o as builder, s as command, l as createBranchFromPolicyOnCheckout, u as describe, d as ensureConfigPackages, f as envFlag, p as envPullFlag, m as handler, h as initCmd, g as installCommandFrom, _ as missingDependencies, v as planCmd, y as status } from "../_chunks/config-BjCm5cfr.js";
@@ -1 +1 @@
1
- export { t as builder, n as command, i as describe, a as handler } from "../_chunks/deploy-DmKZcAnR.js";
1
+ export { t as builder, n as command, i as describe, a as handler } from "../_chunks/deploy-DmEEhux0.js";
@@ -1 +1 @@
1
- export { t as builder, n as captureShellEnv, r as command, i as describe, a as devBundleDir, o as devEnvContext, c as diffUnits, l as formatEnvFiles, u as formatEnvSummary, d as handler, f as loadDevEnvFiles, p as localFunctionUrlEnv, m as planFunctionsToUnits, h as reportDevCredential, g as sourceFunctionUrlOverlay } from "../_chunks/dev-Dv0HKcFF.js";
1
+ export { t as builder, n as captureShellEnv, r as command, i as describe, a as devBundleDir, o as devEnvContext, c as diffUnits, l as formatEnvFiles, u as formatEnvSummary, d as handler, f as loadDevEnvFiles, p as localFunctionUrlEnv, m as planFunctionsToUnits, h as reportDevCredential, g as sourceFunctionUrlOverlay } from "../_chunks/dev-DlUJFzRs.js";
@@ -8,7 +8,7 @@ import { writer } from "../writer.js";
8
8
  import { formatInitDone, printInitDone } from "../init/chrome.js";
9
9
  import { FUNCTION_SLUG_PATTERN, deriveFunctionSlug } from "../utils/function_slug.js";
10
10
  import { displayPath } from "./env_output.js";
11
- import { _ as missingDependencies, d as ensureConfigPackages, g as installCommandFrom } from "../_chunks/config-7SIE_C5O.js";
11
+ import { _ as missingDependencies, d as ensureConfigPackages, g as installCommandFrom } from "../_chunks/config-BjCm5cfr.js";
12
12
  import { recommendedOperations } from "../functions/registry.js";
13
13
  import { collidingFiles, operationsFromFlags, planConfigRegistration, planEnvExample, planScaffold, writeScaffold } from "../functions/scaffold.js";
14
14
  import { describeRegistrySource, openRegistry } from "../functions/source.js";
@@ -1 +1 @@
1
- export { t as aliases, n as builder, r as cleanup, i as command, a as describe, s as handler, c as install, l as partitionBranchesToPrune, u as status, d as sync, f as uninstall } from "../_chunks/git-Dxw9w9dK.js";
1
+ export { t as aliases, n as builder, r as cleanup, i as command, a as describe, s as handler, c as install, l as partitionBranchesToPrune, u as status, d as sync, f as uninstall } from "../_chunks/git-j6xSVo3e.js";
@@ -1,31 +1,31 @@
1
- import { r as auth_exports } from "../_chunks/auth-DPSDYYtG.js";
1
+ import { r as auth_exports } from "../_chunks/auth-rup6nemJ.js";
2
2
  import { t as api_exports } from "../_chunks/api-1MKsfpY3.js";
3
3
  import { n as api_keys_exports } from "../_chunks/api_keys-6Xnxl7a8.js";
4
4
  import { n as ask_exports } from "../_chunks/ask-Xlek1Pxh.js";
5
5
  import { o as env_exports } from "../_chunks/env-BOt9AZ1j.js";
6
- import { c as config_exports } from "../_chunks/config-7SIE_C5O.js";
6
+ import { c as config_exports } from "../_chunks/config-BjCm5cfr.js";
7
7
  import { u as projects_exports } from "../_chunks/projects-a3X4OFEJ.js";
8
- import { a as link_exports } from "../_chunks/link-CcwTXRny.js";
8
+ import { a as link_exports } from "../_chunks/link-nAiuWKfg.js";
9
9
  import { o as mcp_exports } from "../_chunks/mcp-BznTRK3w.js";
10
10
  import { c as plugins_exports } from "../_chunks/plugins-CKOcBuuP.js";
11
11
  import { l as skills_exports } from "../_chunks/skills-DKgafm65.js";
12
12
  import { t as bootstrap_exports } from "../_chunks/bootstrap-BDkvsAVJ.js";
13
13
  import { r as branches_exports } from "../_chunks/branches-Bp-5z1lM.js";
14
14
  import { n as bucket_exports } from "../_chunks/bucket-D06bvDSa.js";
15
- import { n as checkout_exports } from "../_chunks/checkout-C6VMMgY6.js";
15
+ import { n as checkout_exports } from "../_chunks/checkout-BpOcFaAi.js";
16
16
  import { o as claim_exports } from "../_chunks/claim-DlLZmcq0.js";
17
17
  import { a as connection_string_exports } from "../_chunks/connection_string-C9e7N4xk.js";
18
18
  import { a as credentials_exports } from "../_chunks/credentials-BMBNmW0t.js";
19
19
  import { r as data_api_exports } from "../_chunks/data_api-CHDwvMTG.js";
20
20
  import { o as databases_exports } from "../_chunks/databases-DC2h6IW2.js";
21
- import { r as deploy_exports } from "../_chunks/deploy-DmKZcAnR.js";
22
- import { s as dev_exports } from "../_chunks/dev-Dv0HKcFF.js";
21
+ import { r as deploy_exports } from "../_chunks/deploy-DmEEhux0.js";
22
+ import { s as dev_exports } from "../_chunks/dev-DlUJFzRs.js";
23
23
  import { i as diff_exports } from "../_chunks/diff-dnxneH0u.js";
24
24
  import { c as docs_exports } from "../_chunks/docs-CClmgj_Z.js";
25
25
  import { o as feedback_exports } from "../_chunks/feedback-mQmdTRFn.js";
26
26
  import { o as functions_exports } from "../_chunks/functions-3ypiRwZK.js";
27
- import { o as git_exports } from "../_chunks/git-Dxw9w9dK.js";
28
- import { a as init_exports } from "../_chunks/init-BOOGv-mD.js";
27
+ import { o as git_exports } from "../_chunks/git-j6xSVo3e.js";
28
+ import { a as init_exports } from "../_chunks/init-CcVJb492.js";
29
29
  import { o as inspect_exports } from "../_chunks/inspect-yFAb61qo.js";
30
30
  import { a as ip_allow_exports } from "../_chunks/ip_allow-DBdxNEUa.js";
31
31
  import { l as logs_exports } from "../_chunks/logs-BB4uvblR.js";
@@ -33,13 +33,13 @@ import { a as neon_auth_exports } from "../_chunks/neon_auth-Dw-ucM5Y.js";
33
33
  import { a as open_exports } from "../_chunks/open-T2nI89Oh.js";
34
34
  import { s as operations_exports } from "../_chunks/operations-CzaR_uqx.js";
35
35
  import { o as orgs_exports } from "../_chunks/orgs-Dpbr-K0A.js";
36
- import { o as profile_exports } from "../_chunks/profile-H0d7gFrX.js";
36
+ import { o as profile_exports } from "../_chunks/profile-BAlM625e.js";
37
37
  import { a as psql_exports } from "../_chunks/psql-Bce4X0NG.js";
38
38
  import { s as realtime_exports } from "../_chunks/realtime-BwtzYf5a.js";
39
39
  import { l as roles_exports } from "../_chunks/roles-xRuu0462.js";
40
40
  import { a as set_context_exports } from "../_chunks/set_context-ompB6d2D.js";
41
41
  import { s as snapshots_exports } from "../_chunks/snapshots-DxNhjcco.js";
42
- import { a as status_exports } from "../_chunks/status-DS_yUXFo.js";
42
+ import { a as status_exports } from "../_chunks/status-BC4XXuuE.js";
43
43
  import { d as triggers_exports } from "../_chunks/triggers-BfvyeJUC.js";
44
44
  import { s as user_exports } from "../_chunks/user-D9mC430O.js";
45
45
  import { i as vpc_endpoints_exports } from "../_chunks/vpc_endpoints-C-Y4WK2M.js";
@@ -1 +1 @@
1
- export { t as builder, n as command, r as describe, i as handler } from "../_chunks/init-BOOGv-mD.js";
1
+ export { t as builder, n as command, r as describe, i as handler } from "../_chunks/init-CcVJb492.js";
@@ -1 +1 @@
1
- export { t as builder, n as command, r as describe, i as handler, o as quoteFlagValue, s as runLink, c as shouldOfferConfigInit } from "../_chunks/link-CcwTXRny.js";
1
+ export { t as builder, n as command, r as describe, i as handler, o as quoteFlagValue, s as runLink, c as shouldOfferConfigInit } from "../_chunks/link-nAiuWKfg.js";
@@ -1 +1 @@
1
- export { t as aliases, n as builder, r as command, i as describe, a as handler } from "../_chunks/profile-H0d7gFrX.js";
1
+ export { t as aliases, n as builder, r as command, i as describe, a as handler } from "../_chunks/profile-BAlM625e.js";
@@ -1 +1 @@
1
- export { t as builder, n as command, r as describe, i as handler } from "../_chunks/status-DS_yUXFo.js";
1
+ export { t as builder, n as command, r as describe, i as handler } from "../_chunks/status-BC4XXuuE.js";
@@ -28,7 +28,7 @@ const formatDurationSeconds = (totalSeconds) => {
28
28
  const toNeonConfigView = (resolved, preview) => {
29
29
  const view = {};
30
30
  if (resolved.authEnabled) view.auth = true;
31
- if (resolved.dataApiEnabled) view.dataApi = true;
31
+ if (resolved.dataApiEnabled) view.dataApi = toDataApiView(resolved.dataApi);
32
32
  const previewView = toPreviewView(preview);
33
33
  if (previewView) view.preview = previewView;
34
34
  const branch = {};
@@ -39,6 +39,14 @@ const toNeonConfigView = (resolved, preview) => {
39
39
  if (Object.keys(branch).length > 0) view.branch = branch;
40
40
  return view;
41
41
  };
42
+ const toDataApiView = (dataApi) => {
43
+ if (dataApi?.authProvider !== "external") return true;
44
+ const view = { authProvider: "external" };
45
+ if (dataApi.jwksUrl !== void 0) view.jwksUrl = dataApi.jwksUrl;
46
+ if (dataApi.providerName !== void 0) view.providerName = dataApi.providerName;
47
+ if (dataApi.jwtAudience !== void 0) view.jwtAudience = dataApi.jwtAudience;
48
+ return view;
49
+ };
42
50
  const toPreviewView = (preview) => {
43
51
  if (!preview) return void 0;
44
52
  const out = {};
@@ -18,8 +18,9 @@ const REQUIRED_PACKAGES = [CONFIG_PACKAGE, ENV_PACKAGE];
18
18
  * from these names to the `neon.ts` fields (`aiGateway`, `functions`, `buckets`, `dataApi`).
19
19
  *
20
20
  * Postgres is absent because every branch has it, so there is nothing to declare. Selecting
21
- * `data-api` also writes `auth: true`: the default Data API provider requires Neon Auth, and
22
- * `defineConfig` type-errors the file without it.
21
+ * `data-api` also writes `auth: true` unless the caller says the Data API verifies an external
22
+ * provider (see {@link DataApiTemplateChoice}): the default Data API provider requires Neon
23
+ * Auth, and `defineConfig` type-errors the file without it.
23
24
  */
24
25
  const CONFIG_INIT_SERVICES = NEON_SERVICES.filter((service) => service !== "postgres");
25
26
  /**
@@ -64,18 +65,44 @@ const renderGaServices = (services) => {
64
65
  if (lines.length === 0) return "";
65
66
  return `${lines.join("\n")}\n`;
66
67
  };
68
+ /** The template choice for a view's `dataApi` entry (`config status` / `--from-branch`). */
69
+ const dataApiChoiceFromView = (dataApi) => {
70
+ if (dataApi === true) return { kind: "neon" };
71
+ const { authProvider: _provider, ...wiring } = dataApi;
72
+ return {
73
+ kind: "external",
74
+ ...wiring
75
+ };
76
+ };
77
+ /**
78
+ * The `dataApi` entry, ending in a newline. The external form carries whatever wiring is
79
+ * known; without a JWKS URL it still type-checks (the URL is optional) and still declares the
80
+ * Data API, so a comment says where the URL lives rather than inventing one.
81
+ */
82
+ const renderDataApiEntry = (choice) => {
83
+ if (choice.kind === "neon") return `${at(1, "dataApi: true,").join("\n")}\n`;
84
+ const fields = at(2, `authProvider: "external",`);
85
+ if (choice.jwksUrl === void 0) fields.push(...at(2, "// The JWKS URL is registered on the project; add `jwksUrl` to declare it here too."));
86
+ else fields.push(...at(2, `jwksUrl: ${renderScalar(choice.jwksUrl)},`));
87
+ if (choice.providerName !== void 0) fields.push(...at(2, `providerName: ${renderScalar(choice.providerName)},`));
88
+ if (choice.jwtAudience !== void 0) fields.push(...at(2, `jwtAudience: ${renderScalar(choice.jwtAudience)},`));
89
+ return `${block(1, "dataApi", fields).join("\n")}\n`;
90
+ };
67
91
  /**
68
92
  * Render the `neon.ts` policy `config init` writes. With no services this is the starter
69
93
  * policy — an explicit `auth: false`, no service keys beyond that, and a `branch` closure that gives
70
94
  * new non-default branches a 7-day TTL — so the picker's "skip everything" answer and a
71
95
  * non-interactive run produce the identical file.
72
96
  *
73
- * `data-api` writes `dataApi: true` and forces `auth: true`. The default provider is Neon
74
- * Auth; omitting auth is a `defineConfig` type error rather than a deploy-time surprise.
97
+ * `data-api` writes `dataApi: true` and forces `auth: true` unless `options.dataApi` says the
98
+ * branch's Data API verifies an external provider. The default provider is Neon Auth;
99
+ * omitting auth is a `defineConfig` type error rather than a deploy-time surprise.
75
100
  */
76
- const renderNeonConfig = (services) => {
77
- const auth = services.includes("auth") || services.includes("data-api");
78
- const dataApi = services.includes("data-api") ? " dataApi: true,\n" : "";
101
+ const renderNeonConfig = (services, options = {}) => {
102
+ const dataApiChoice = options.dataApi ?? { kind: "neon" };
103
+ const declaresDataApi = services.includes("data-api");
104
+ const auth = services.includes("auth") || declaresDataApi && dataApiChoice.kind !== "external";
105
+ const dataApi = declaresDataApi ? renderDataApiEntry(dataApiChoice) : "";
79
106
  const realtimeDeclaration = services.includes("realtime") ? " preview: {\n realtime: true,\n },\n" : "";
80
107
  return `import { defineConfig } from "${CONFIG_PACKAGE}/v1";
81
108
 
@@ -154,7 +181,7 @@ const renderSeededGaServices = (view, branchName) => {
154
181
  * than an empty `defineConfig({})`: seeding found nothing, and the caller says so.
155
182
  */
156
183
  const renderNeonConfigFromView = (view, branchName) => {
157
- const services = [view.auth ? " auth: true," : "", view.dataApi ? " dataApi: true," : ""].filter((line) => line !== "");
184
+ const services = [view.auth ? " auth: true," : "", view.dataApi ? renderDataApiEntry(dataApiChoiceFromView(view.dataApi)).trimEnd() : ""].filter((line) => line !== "");
158
185
  const gaServices = renderSeededGaServices(view, branchName);
159
186
  const branch = renderSeededBranch(view);
160
187
  if (services.length === 0 && gaServices === "" && branch === "") return {
@@ -202,4 +229,4 @@ const renderFunctionSource = (slug, language) => {
202
229
  `;
203
230
  };
204
231
  const FUNCTION_TEMPLATE = renderFunctionSource(FUNCTION_SLUG, "ts");
205
- export { BUCKET_NAME, CONFIG_INIT_SERVICES, CONFIG_PACKAGE, ENV_PACKAGE, FUNCTION_FILENAME, FUNCTION_NAME, FUNCTION_SLUG, FUNCTION_TEMPLATE, REQUIRED_PACKAGES, parseConfigInitServices, renderFunctionSource, renderKey, renderNeonConfig, renderNeonConfigFromView };
232
+ export { BUCKET_NAME, CONFIG_INIT_SERVICES, CONFIG_PACKAGE, ENV_PACKAGE, FUNCTION_FILENAME, FUNCTION_NAME, FUNCTION_SLUG, FUNCTION_TEMPLATE, REQUIRED_PACKAGES, dataApiChoiceFromView, parseConfigInitServices, renderFunctionSource, renderKey, renderNeonConfig, renderNeonConfigFromView };
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { NETWORK_ERROR_MESSAGE, isNetworkError, matchErrorCode } from "./errors.
9
9
  import { analyticsMiddleware, closeAnalytics, initAnalyticsClientMiddleware, isAnalyticsActive, recordCommandSuccessExtras, sendError, takeCommandSuccessExtras, trackCommandSuccess } from "./analytics.js";
10
10
  import { AuthRefreshError, defaultClientID } from "./auth.js";
11
11
  import { getCliName } from "./utils/cli_name.js";
12
- import { c as ensureAuth } from "./_chunks/auth-DPSDYYtG.js";
12
+ import { c as ensureAuth } from "./_chunks/auth-rup6nemJ.js";
13
13
  import { recoverFrom401 } from "./auth_recovery.js";
14
14
  import { UsageError, failOnUsageError, isBareParentCommand, showHelp, showUsageErrorHelp } from "./help.js";
15
15
  import { lazyCommands, preloadCommand } from "./commands/manifest.js";
package/dist/init/auth.js CHANGED
@@ -2,7 +2,7 @@ import { isNeonApiError } from "../api.js";
2
2
  import { r as defaultDir } from "../_chunks/paths-B55ZfOg1.js";
3
3
  import "../config.js";
4
4
  import "../auth.js";
5
- import { c as ensureAuth } from "../_chunks/auth-DPSDYYtG.js";
5
+ import { c as ensureAuth, l as existingApiClient } from "../_chunks/auth-rup6nemJ.js";
6
6
  import { recoverFrom401 } from "../auth_recovery.js";
7
7
  import { c as pull } from "../_chunks/env-BOt9AZ1j.js";
8
8
  import { c as setupNeonMcp } from "../_chunks/mcp-BznTRK3w.js";
@@ -54,6 +54,27 @@ const runAuthenticatedMcp = async (options) => {
54
54
  }
55
55
  };
56
56
  /**
57
+ * The client and key `neon config init` may read the linked branch with. Init calls this only
58
+ * after a link is verified, but a pin that was already in place can have no credentials on
59
+ * disk, so this never starts a login: with nothing usable it returns an empty result and the
60
+ * scaffold declares the Neon Auth default with a warning, as a failed read does.
61
+ */
62
+ const resolveInitConfigApi = async (options) => {
63
+ const access = await existingApiClient({
64
+ configDir: options.configDir ?? defaultDir,
65
+ apiHost: options.apiHost ?? "https://console.neon.tech/api/v2",
66
+ ...options.profile !== void 0 ? { profile: options.profile } : {},
67
+ ...options.oauthHost !== void 0 ? { oauthHost: options.oauthHost } : {},
68
+ ...options.clientId !== void 0 ? { clientId: options.clientId } : {}
69
+ });
70
+ if (access === null) return {};
71
+ return {
72
+ apiClient: access.apiClient,
73
+ apiKey: access.apiKey,
74
+ apiHost: options.apiHost
75
+ };
76
+ };
77
+ /**
57
78
  * Resolves Neon auth the same way a standalone `neon env pull` invocation would, then runs
58
79
  * `pull` — the same function `link`/`checkout` already call directly via
59
80
  * `autoPullEnvAfterPin` (see `commands/env.ts`).
@@ -77,4 +98,4 @@ const pullInitEnv = async (props) => {
77
98
  throw authenticationFailed();
78
99
  }
79
100
  };
80
- export { pullInitEnv, runAuthenticatedMcp };
101
+ export { pullInitEnv, resolveInitConfigApi, runAuthenticatedMcp };
package/dist/init/link.js CHANGED
@@ -2,9 +2,9 @@ import { isNeonApiError } from "../api.js";
2
2
  import { r as defaultDir } from "../_chunks/paths-B55ZfOg1.js";
3
3
  import "../config.js";
4
4
  import "../auth.js";
5
- import { c as ensureAuth } from "../_chunks/auth-DPSDYYtG.js";
5
+ import { c as ensureAuth } from "../_chunks/auth-rup6nemJ.js";
6
6
  import { recoverFrom401 } from "../auth_recovery.js";
7
- import { s as runLink } from "../_chunks/link-CcwTXRny.js";
7
+ import { s as runLink } from "../_chunks/link-nAiuWKfg.js";
8
8
  // src/init/link.ts
9
9
  const isUnauthorized = (error) => isNeonApiError(error) && error.status === 401;
10
10
  const authenticationFailed = () => /* @__PURE__ */ new Error("Authentication failed.");
package/dist/init/run.js CHANGED
@@ -17,11 +17,11 @@ import { FALLBACK_SKILLS_AGENTS, assertNamedAgentTooling, funnelAgentSetup, plan
17
17
  import { inferPackageManager, resolvePackageManager } from "../utils/package_manager.js";
18
18
  import { AGENTS_NOT_INSTALLED, CANCELLED_BODY, CLAIMABLE_ACCOUNT_FLAGS, CLAIMABLE_ALREADY_LINKED, CLAIMABLE_MCP_API_KEY, CLAIMABLE_NO_LINK, MCP_API_KEY_NEEDS_AUTH, MCP_SCOPED_NEEDS_PROJECT, NON_TTY_LINK_NEEDS_AUTH, NO_AGENTS_FALLBACK_STATUS, PROGRESS, PROJECT_PINNED_OFFLINE, claimableNext, claimableThenServicesNext, configInitNext, envPullFailedNext, existingConfigNext, installFailedNext, mcpAfterLinkNext, mcpConfigLocationSkipped, mcpConfigLocationUnavailable, mcpKeyFailedNext, namedAgentsUnavailable, newConfigNext, offlinePinNext, skippedLinkNext, toolingFailedNext, unattendedUnauthedNext } from "./copy.js";
19
19
  import { agentsRowValue, configRowValue, formatInitDone, headingForKind, printInitBanner, printInitDone, printInitProgress, projectRowValue, shouldPrintInitBanner } from "./chrome.js";
20
- import { h as initCmd, t as ConfigInstallFailed } from "../_chunks/config-7SIE_C5O.js";
21
- import { o as quoteFlagValue, s as runLink } from "../_chunks/link-CcwTXRny.js";
20
+ import { h as initCmd, t as ConfigInstallFailed } from "../_chunks/config-BjCm5cfr.js";
21
+ import { o as quoteFlagValue, s as runLink } from "../_chunks/link-nAiuWKfg.js";
22
22
  import { runAuthenticatedLink } from "./link.js";
23
23
  import { CannotMintApiKeyError } from "../mcp/mint.js";
24
- import { pullInitEnv } from "./auth.js";
24
+ import { pullInitEnv, resolveInitConfigApi } from "./auth.js";
25
25
  import { InitCancelled, raceSigint, restoreCursor } from "./cancelled.js";
26
26
  import { pickAgentSetupInteractively, pickInitAgentsInteractively, pickInitConfigInteractively, pickInitMcpAuthInteractively, pickInitMcpConfigLocationInteractively, pickInitModeInteractively, pickInitPackageManagerInteractively, pickInitProjectSetupInteractively, pickInitServicesInteractively, pickInitSkillsInteractively } from "./wizard.js";
27
27
  import { runToolingSteps, toolingStepCommandText } from "./tooling.js";
@@ -130,13 +130,28 @@ const pickOrDetectAgents = async (input) => {
130
130
  return detected;
131
131
  };
132
132
  const defaultInitConfig = async (input) => {
133
+ let project = {};
134
+ if (input.project) try {
135
+ project = {
136
+ ...await resolveInitConfigApi(input.project.auth),
137
+ projectId: input.project.projectId,
138
+ ...input.project.branch !== void 0 ? { branch: input.project.branch } : {},
139
+ ...input.project.auth.configDir !== void 0 ? { configDir: input.project.auth.configDir } : {},
140
+ ...input.project.auth.profile !== void 0 ? { profile: input.project.auth.profile } : {},
141
+ ...input.project.auth.oauthHost !== void 0 ? { oauthHost: input.project.auth.oauthHost } : {},
142
+ ...input.project.auth.clientId !== void 0 ? { clientId: input.project.auth.clientId } : {}
143
+ };
144
+ } catch (error) {
145
+ log.warning("Couldn't authenticate to read the Data API on the linked branch (%s); declaring it with Neon Auth.", error instanceof Error ? error.message : String(error));
146
+ }
133
147
  await initCmd({
134
148
  cwd: input.cwd,
135
149
  install: input.install,
136
150
  silent: true,
137
151
  requireInstall: true,
138
152
  ...input.services !== void 0 ? { services: input.services } : {},
139
- ...input.packageManager !== void 0 ? { packageManager: input.packageManager } : {}
153
+ ...input.packageManager !== void 0 ? { packageManager: input.packageManager } : {},
154
+ ...project
140
155
  });
141
156
  };
142
157
  const defaultCreateClaimable = async (input) => {
@@ -557,12 +572,19 @@ const runInit = async (props) => {
557
572
  }
558
573
  if (!existingConfig) printInitProgress(PROGRESS.config);
559
574
  printInitProgress(PROGRESS.install(pm));
575
+ const readableProject = funnel.link !== "skipped" && !pinnedOffline && declared.includes("data-api") ? readContextFile(contextFile) : void 0;
576
+ const readableBranch = readableProject !== void 0 ? contextBranch(readableProject) : void 0;
560
577
  try {
561
578
  await (props.initConfig ?? defaultInitConfig)({
562
579
  cwd,
563
580
  install: true,
564
581
  packageManager: pm,
565
- ...planned !== void 0 ? { services: planned } : {}
582
+ ...planned !== void 0 ? { services: planned } : {},
583
+ ...typeof readableProject?.projectId === "string" ? { project: {
584
+ projectId: readableProject.projectId,
585
+ ...readableBranch !== void 0 ? { branch: readableBranch } : {},
586
+ auth
587
+ } } : {}
566
588
  });
567
589
  } catch (error) {
568
590
  if (error instanceof ConfigInstallFailed) {
@@ -207,7 +207,7 @@ const pickInitServicesInteractively = async () => {
207
207
  {
208
208
  value: "data-api",
209
209
  title: "Data API",
210
- description: "Declare an HTTP API for Postgres. Also declares Managed Better Auth."
210
+ description: "Declare an HTTP API for Postgres. Also declares Managed Better Auth, unless the branch's Data API already uses an external identity provider."
211
211
  },
212
212
  {
213
213
  value: "functions",
@@ -36,7 +36,7 @@ const CHOICES = [
36
36
  {
37
37
  value: "data-api",
38
38
  title: "Data API",
39
- description: "PostgREST-compatible HTTP API. Also declares Auth; the default provider needs it."
39
+ description: "PostgREST-compatible HTTP API. Also declares Auth, which the default provider needs, unless the linked branch's Data API already uses an external identity provider."
40
40
  },
41
41
  {
42
42
  value: "functions",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neon",
3
- "version": "8.14.0",
3
+ "version": "8.15.0",
4
4
  "description": "CLI tool for Neon, the cloud backend primitives built around Lakebase Postgres",
5
5
  "keywords": [
6
6
  "neon",
@@ -72,10 +72,10 @@
72
72
  "yaml": "^2.9.0",
73
73
  "yargs": "17.7.2",
74
74
  "yoctocolors": "^2.1.2",
75
- "@neon/config": "1.9.6",
75
+ "@neon/config": "1.10.0",
76
+ "@neon/config-runtime": "1.11.0",
76
77
  "@neon/realtime": "0.1.2",
77
- "@neon/config-runtime": "1.10.5",
78
- "@neon/sdk": "7.6.1"
78
+ "@neon/sdk": "7.7.0"
79
79
  },
80
80
  "optionalDependencies": {
81
81
  "@napi-rs/keyring": "1.3.0",
@@ -111,11 +111,11 @@
111
111
  "tsx": "4.22.3",
112
112
  "typescript": "^5.9.0",
113
113
  "vitest": "^3.0.9",
114
- "@neon-internals/env-core": "0.0.37",
115
114
  "@neon-internals/cli-core": "0.0.0",
116
- "@neon/e2e-harness": "0.0.0",
117
- "@neon/env": "1.6.7",
118
- "@neon/functions": "0.11.0"
115
+ "@neon-internals/env-core": "0.0.38",
116
+ "@neon/env": "1.6.8",
117
+ "@neon/functions": "0.11.0",
118
+ "@neon/e2e-harness": "0.0.0"
119
119
  },
120
120
  "publishConfig": {
121
121
  "access": "public",