neon 8.14.0 → 8.15.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.
- package/README.md +4 -2
- package/dist/_chunks/{auth-DPSDYYtG.js → auth-rup6nemJ.js} +38 -1
- package/dist/_chunks/{checkout-C6VMMgY6.js → checkout-BpOcFaAi.js} +2 -2
- package/dist/_chunks/{config-7SIE_C5O.js → config-BjCm5cfr.js} +56 -4
- package/dist/_chunks/{deploy-DmKZcAnR.js → deploy-DmEEhux0.js} +1 -1
- package/dist/_chunks/{dev-Dv0HKcFF.js → dev-DlUJFzRs.js} +1 -1
- package/dist/_chunks/{docs-CClmgj_Z.js → docs-BpLiSTmm.js} +1 -1
- package/dist/_chunks/{git-Dxw9w9dK.js → git-j6xSVo3e.js} +2 -2
- package/dist/_chunks/{init-BOOGv-mD.js → init-CcVJb492.js} +1 -1
- package/dist/_chunks/{link-CcwTXRny.js → link-nAiuWKfg.js} +1 -1
- package/dist/_chunks/{plugins-CKOcBuuP.js → plugins-B2Gym8Lw.js} +2 -2
- package/dist/_chunks/{profile-H0d7gFrX.js → profile-BAlM625e.js} +1 -1
- package/dist/_chunks/{status-DS_yUXFo.js → status-BC4XXuuE.js} +1 -1
- package/dist/analytics.js +4 -2
- package/dist/api.js +2 -2
- package/dist/auth_recovery.js +1 -1
- package/dist/commands/auth.js +1 -1
- package/dist/commands/checkout.js +1 -1
- package/dist/commands/config.js +1 -1
- package/dist/commands/deploy.js +1 -1
- package/dist/commands/dev.js +1 -1
- package/dist/commands/docs.js +1 -1
- package/dist/commands/functions_new.js +3 -4
- package/dist/commands/git.js +1 -1
- package/dist/commands/index.js +12 -12
- package/dist/commands/init.js +1 -1
- package/dist/commands/link.js +1 -1
- package/dist/commands/plugins.js +1 -1
- package/dist/commands/profile.js +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/config_format.js +9 -1
- package/dist/config_template.js +36 -9
- package/dist/env.js +19 -4
- package/dist/index.js +1 -1
- package/dist/init/auth.js +23 -2
- package/dist/init/copy.js +3 -2
- package/dist/init/link.js +2 -2
- package/dist/init/run.js +49 -18
- package/dist/init/tooling.js +1 -1
- package/dist/init/wizard.js +5 -5
- package/dist/plugins/child_env.js +10 -0
- package/dist/plugins/plan.js +14 -14
- package/dist/plugins/run.js +2 -8
- package/dist/plugins/targets.js +129 -11
- package/dist/update_notifier.js +7 -4
- package/dist/utils/service_picker.js +1 -1
- package/package.json +6 -6
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
|
|
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) ›
|
|
@@ -1056,6 +1056,8 @@ On a TTY the command asks which agents, then installs. Detected agents start sel
|
|
|
1056
1056
|
|
|
1057
1057
|
Default scope is `project`. `--global` is `user`. On macOS and Linux, Cursor and Claude Code store the plugin cache under `~/.claude/plugins`; on Windows, Cursor installs into Cursor extensions. `project` vs `user` is the scope field the plugins CLI records, not a directory in the repo. VS Code, GitHub Copilot CLI, and Grok Build only install user-level: they are skipped at the default scope with a warning, and a VS Code-only project fails if nothing else is selected. Pass `--global` for those.
|
|
1058
1058
|
|
|
1059
|
+
GitHub Copilot CLI and Grok Build install through their own CLIs (`copilot`, `grok`), so `neon plugins` runs `copilot --version` or `grok --version` first. A command that is missing, fails, or (for Copilot) is older than 0.0.400 is skipped with a warning under `-y`, fails an explicit `--agent`, and in `neon init` gets Neon skills and MCP instead of the plugin. The other agents install by writing files, so their detected config directory is enough.
|
|
1060
|
+
|
|
1059
1061
|
Supported agents with a plugins mapping: `claude-code`, `claude-desktop`, `codex`, `cursor`, `github-copilot-cli`, `grok-build`, `vscode`. `claude-desktop` installs as Claude Code; detecting both produces one install and lists both names in the table. `mcporter` is a known MCP name that is then skipped.
|
|
1060
1062
|
|
|
1061
1063
|
The plugins CLI installs every plugin it finds in the Neon plugin package. Today that is `neon-postgres` from `neondatabase/agent-skills`. It includes the Neon MCP server (`https://mcp.neon.tech/mcp`) and these skills: `neon`, `neon-ai-gateway`, `neon-auth`, `neon-functions`, `neon-object-storage`, `neon-postgres`, `neon-postgres-branches`, `neon-postgres-egress-optimizer`, `neon-realtime`. It does not include `neon-postgres-agent-platforms`.
|
|
@@ -1122,7 +1124,7 @@ Without a template, a terminal asks which one to use; anything else exits with t
|
|
|
1122
1124
|
|
|
1123
1125
|
A template's `layout` decides what you get. `router` writes one module per operation plus a generated `index.ts` that dispatches on the URL path, and declares one function. `separate` declares each operation as its own function under the slug the template gives it. Without `--operation` or `--all-operations`, a TTY asks which operations to include and anything else uses the template's recommended ones.
|
|
1124
1126
|
|
|
1125
|
-
Variables a template needs are declared on each function in `neon.ts` (`env: { API_KEY: process.env.API_KEY! }`) and added, without values, to `.env.example` next to it. Values are never written to `.env` or `.env.local` for you: a blank placeholder there would deploy as an empty string and delete the live value. Put the real value in the file `env pull` uses and deploy with `neon config apply --env .env.local`. `neon dev`
|
|
1127
|
+
Variables a template needs are declared on each function in `neon.ts` (`env: { API_KEY: process.env.API_KEY! }`) and added, without values, to `.env.example` next to it. Values are never written to `.env` or `.env.local` for you: a blank placeholder there would deploy as an empty string and delete the live value. Put the real value in the file `env pull` uses and deploy with `neon config apply --env .env.local`. `neon dev` loads it automatically.
|
|
1126
1128
|
|
|
1127
1129
|
Nothing is written until every check passes: a file that already exists with different contents needs `--force`, and a slug `neon.ts` already declares needs `--slug`, `--force`, or `--no-add-to-config`. A `separate` template sets its own slugs, so `--slug` only changes its directory; remove the existing declarations from `neon.ts`, or use `--force` or `--no-add-to-config`.
|
|
1128
1130
|
|
|
@@ -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,
|
|
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-
|
|
16
|
-
import { i as handler$1 } from "./link-
|
|
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
|
-
|
|
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.
|
|
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-
|
|
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-
|
|
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";
|
|
@@ -128,7 +128,7 @@ function siteSearchHeaders(opts) {
|
|
|
128
128
|
"Content-Type": "application/json",
|
|
129
129
|
"User-Agent": `neon/${opts.version}`,
|
|
130
130
|
"x-caller-source": "cli",
|
|
131
|
-
...opts.agent ? { "x-caller-client": encodeURIComponent(opts.agent) } : {},
|
|
131
|
+
...opts.analytics && opts.agent ? { "x-caller-client": encodeURIComponent(opts.agent) } : {},
|
|
132
132
|
...opts.analytics ? {} : { "x-caller-analytics": "off" }
|
|
133
133
|
};
|
|
134
134
|
}
|
|
@@ -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-
|
|
9
|
-
import { o as handler$1 } from "./checkout-
|
|
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-
|
|
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";
|
|
@@ -5,7 +5,7 @@ import { helpCsv, helpEpilogue } from "../utils/help_text.js";
|
|
|
5
5
|
import { getAgentDisplayName } from "../mcp/agents.js";
|
|
6
6
|
import { NEON_MCP_URL } from "../mcp/install.js";
|
|
7
7
|
import "../init/agents.js";
|
|
8
|
-
import { pluginsInstallableAgents } from "../plugins/targets.js";
|
|
8
|
+
import { pluginsCommandProblemText, pluginsInstallableAgents } from "../plugins/targets.js";
|
|
9
9
|
import { writer } from "../writer.js";
|
|
10
10
|
import { noPassthrough } from "../utils/flags.js";
|
|
11
11
|
import { AGENT_PLUGIN_SKIP_MESSAGE } from "../init/copy.js";
|
|
@@ -77,7 +77,7 @@ const installPlugins = async (options) => {
|
|
|
77
77
|
});
|
|
78
78
|
for (const agent of plan.skipped) log.warning("Skipping %s: no plugins mapping.", getAgentDisplayName(agent));
|
|
79
79
|
for (const agent of plan.userScopeSkipped) log.warning("Skipping %s: plugins are user-level. Pass --global.", getAgentDisplayName(agent));
|
|
80
|
-
for (const
|
|
80
|
+
for (const row of plan.unusableCommands) log.warning("Skipping %s: the plugin installs through \"%s\", which %s.", getAgentDisplayName(row.agent), row.command.name, pluginsCommandProblemText(row));
|
|
81
81
|
const rows = [];
|
|
82
82
|
const failed = [];
|
|
83
83
|
const scope = scopeLabel(plan.scope);
|
|
@@ -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 {
|
|
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-
|
|
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/analytics.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as OAUTH, t as storeFor } from "./_chunks/credential_io-DbeSh3Pl.js";
|
|
2
|
-
import { getCliAgent, getGithubEnvVars, isCi } from "./env.js";
|
|
2
|
+
import { getCliAgent, getGithubEnvVars, getTty, isCi } from "./env.js";
|
|
3
3
|
import { log } from "./log.js";
|
|
4
4
|
import { getOrCreateAnonymousId } from "./anonymous_id.js";
|
|
5
5
|
import pkg_default from "./pkg.js";
|
|
@@ -248,7 +248,8 @@ const settleErrorReports = async (deadline) => {
|
|
|
248
248
|
const getErrorAnalyticsEventContext = (_args) => ({
|
|
249
249
|
version: pkg_default.version,
|
|
250
250
|
ci: isCi(),
|
|
251
|
-
agent: getCliAgent(process.env)
|
|
251
|
+
agent: getCliAgent(process.env),
|
|
252
|
+
tty: getTty()
|
|
252
253
|
});
|
|
253
254
|
const CREDENTIAL_TOKEN_ID = /\bnak_live_[0-9a-f]+\b/gi;
|
|
254
255
|
const redactCredentialTokenIds = (text) => text.replace(CREDENTIAL_TOKEN_ID, "nak_live_<redacted>");
|
|
@@ -353,6 +354,7 @@ const getAnalyticsEventProperties = (args) => ({
|
|
|
353
354
|
flags: { output: args.output },
|
|
354
355
|
ci: isCi(),
|
|
355
356
|
agent: getCliAgent(process.env),
|
|
357
|
+
tty: getTty(),
|
|
356
358
|
githubEnvVars: getGithubEnvVars(process.env)
|
|
357
359
|
});
|
|
358
360
|
export { analyticsIdentity, analyticsMiddleware, closeAnalytics, commandSuccessProperties, getAnalyticsEventProperties, getErrorAnalyticsEventProperties, initAnalyticsClientMiddleware, isAnalyticsActive, recordCommandSuccessExtras, recordScaffoldedTemplate, redactCredentialTokenIds, sendError, storedCredentialAttribution, takeCommandSuccessExtras, telemetryCredential, trackCommandSuccess, trackEvent, useAnalyticsClientForTests };
|
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 ??
|
|
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 };
|
package/dist/auth_recovery.js
CHANGED
|
@@ -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 {
|
|
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;
|
package/dist/commands/auth.js
CHANGED
|
@@ -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
|
|
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-
|
|
1
|
+
export { t as builder, r as command, i as describe, a as formatCheckoutPolicyFailure, o as handler } from "../_chunks/checkout-BpOcFaAi.js";
|
package/dist/commands/config.js
CHANGED
|
@@ -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-
|
|
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";
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as builder, n as command, i as describe, a as handler } from "../_chunks/deploy-
|
|
1
|
+
export { t as builder, n as command, i as describe, a as handler } from "../_chunks/deploy-DmEEhux0.js";
|
package/dist/commands/dev.js
CHANGED
|
@@ -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-
|
|
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";
|
package/dist/commands/docs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as DEFAULT_SITE_SEARCH_URL, n as MAX_LIMIT, r as MAX_QUERY_LENGTH, i as SITE_SEARCH_CATEGORIES, a as builder, o as command, s as describe, l as formatSearchResults, u as parseSearchHits, d as resolveSiteSearchUrl, f as siteSearchHeaders } from "../_chunks/docs-
|
|
1
|
+
export { t as DEFAULT_SITE_SEARCH_URL, n as MAX_LIMIT, r as MAX_QUERY_LENGTH, i as SITE_SEARCH_CATEGORIES, a as builder, o as command, s as describe, l as formatSearchResults, u as parseSearchHits, d as resolveSiteSearchUrl, f as siteSearchHeaders } from "../_chunks/docs-BpLiSTmm.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-
|
|
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";
|
|
@@ -169,9 +169,8 @@ const scaffoldFromTemplate = async (options) => {
|
|
|
169
169
|
const envFile = displayPath(resolveEnvFilePath(location), cwd);
|
|
170
170
|
const names = environment.join(", ");
|
|
171
171
|
if (variables && register) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
next.push(`Set ${names} in ${envFile}, and export ${them} for ${cli} dev`);
|
|
172
|
+
nextSteps.push(`Set ${variables} in ${envFile} (\`${cli} dev\` loads it automatically).`);
|
|
173
|
+
next.push(`Set ${names} in ${envFile} (${cli} dev loads it automatically)`);
|
|
175
174
|
} else if (variables) {
|
|
176
175
|
nextSteps.push(`Set ${variables} in your shell.`);
|
|
177
176
|
next.push(`Set ${names} in your shell`);
|
package/dist/commands/git.js
CHANGED
|
@@ -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-
|
|
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";
|
package/dist/commands/index.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import { r as auth_exports } from "../_chunks/auth-
|
|
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-
|
|
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-
|
|
8
|
+
import { a as link_exports } from "../_chunks/link-nAiuWKfg.js";
|
|
9
9
|
import { o as mcp_exports } from "../_chunks/mcp-BznTRK3w.js";
|
|
10
|
-
import { c as plugins_exports } from "../_chunks/plugins-
|
|
10
|
+
import { c as plugins_exports } from "../_chunks/plugins-B2Gym8Lw.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-
|
|
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-
|
|
22
|
-
import { s as dev_exports } from "../_chunks/dev-
|
|
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
|
-
import { c as docs_exports } from "../_chunks/docs-
|
|
24
|
+
import { c as docs_exports } from "../_chunks/docs-BpLiSTmm.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-
|
|
28
|
-
import { a as init_exports } from "../_chunks/init-
|
|
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-
|
|
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-
|
|
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";
|
package/dist/commands/init.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as builder, n as command, r as describe, i as handler } from "../_chunks/init-
|
|
1
|
+
export { t as builder, n as command, r as describe, i as handler } from "../_chunks/init-CcVJb492.js";
|
package/dist/commands/link.js
CHANGED
|
@@ -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-
|
|
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";
|
package/dist/commands/plugins.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as aliases, n as builder, r as command, i as describe, a as handler, o as installPlugins, s as pluginsInstallError, l as reportPluginsInstall } from "../_chunks/plugins-
|
|
1
|
+
export { t as aliases, n as builder, r as command, i as describe, a as handler, o as installPlugins, s as pluginsInstallError, l as reportPluginsInstall } from "../_chunks/plugins-B2Gym8Lw.js";
|
package/dist/commands/profile.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as aliases, n as builder, r as command, i as describe, a as handler } from "../_chunks/profile-
|
|
1
|
+
export { t as aliases, n as builder, r as command, i as describe, a as handler } from "../_chunks/profile-BAlM625e.js";
|
package/dist/commands/status.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as builder, n as command, r as describe, i as handler } from "../_chunks/status-
|
|
1
|
+
export { t as builder, n as command, r as describe, i as handler } from "../_chunks/status-BC4XXuuE.js";
|
package/dist/config_format.js
CHANGED
|
@@ -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 =
|
|
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 = {};
|
package/dist/config_template.js
CHANGED
|
@@ -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
|
|
22
|
-
*
|
|
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
|
|
74
|
-
*
|
|
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
|
|
78
|
-
const
|
|
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 ?
|
|
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 };
|