neon 8.3.3 → 8.3.5
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/dist/_chunks/{env-BWqJqBDJ.js → env-L2DPzDAK.js} +1 -1
- package/dist/_chunks/{env-HYNFtxu5.js → env-XsUZj_Ay.js} +3 -22
- package/dist/_chunks/roles-C3M4q9DS.js +27 -0
- package/dist/commands/connection_string.js +4 -2
- package/dist/commands/dev.js +2 -2
- package/dist/commands/env.js +2 -2
- package/dist/commands/env_output.js +1 -1
- package/dist/commands/inspect.js +1 -1
- package/dist/dev/env.js +1 -1
- package/dist/env_services.js +1 -1
- package/dist/utils/hooks.js +1 -1
- package/dist/utils/inspect_db.js +34 -24
- package/package.json +5 -5
|
@@ -2,7 +2,7 @@ import { log } from "../log.js";
|
|
|
2
2
|
import { getCliName } from "../utils/cli_name.js";
|
|
3
3
|
import { declaredNeonServices } from "../config_services.js";
|
|
4
4
|
import { loadProjectConfig } from "../project.js";
|
|
5
|
-
import { a as defaultAiGatewayCredential, c as fetchEnvKeysState, d as isLiveCredential, h as toEntries, i as credentialName, l as functionBaseUrlKey, m as resolveBranchPolicy, n as createApiFromOptions, o as defaultStorageCredential, p as policyEnvKeys, r as credentialEnvKeys, t as NEON_ENV_VAR_KEYS, u as isFunctionBaseUrlKey } from "./env-
|
|
5
|
+
import { a as defaultAiGatewayCredential, c as fetchEnvKeysState, d as isLiveCredential, h as toEntries, i as credentialName, l as functionBaseUrlKey, m as resolveBranchPolicy, n as createApiFromOptions, o as defaultStorageCredential, p as policyEnvKeys, r as credentialEnvKeys, t as NEON_ENV_VAR_KEYS, u as isFunctionBaseUrlKey } from "./env-XsUZj_Ay.js";
|
|
6
6
|
import { ENV_PULL_SERVICES, envKeysForSelection, serviceForEnvKey, servicesForEnvKeys } from "../env_services.js";
|
|
7
7
|
import { formatInstallCommand, resolvePackageManager } from "../utils/package_manager.js";
|
|
8
8
|
import { ErrorCode, createNeonApiFromOptions, isPlatformError } from "@neon/config";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { n as defaultConnectionRole, t as NEON_DEFAULT_OWNER_ROLE } from "./roles-C3M4q9DS.js";
|
|
1
2
|
import { ErrorCode, PlatformError, createNeonApiFromOptions, deriveCredentialScopes, isPlatformError, resolveConfig } from "@neon/config/v1";
|
|
2
3
|
//#region ../../internals/env-core/dist/env.js
|
|
3
4
|
/**
|
|
@@ -22,28 +23,11 @@ import { ErrorCode, PlatformError, createNeonApiFromOptions, deriveCredentialSco
|
|
|
22
23
|
* {@link dataApiEnvSchema}.
|
|
23
24
|
*/
|
|
24
25
|
/**
|
|
25
|
-
* Neon's default branch owner role, created with every project. This is the role a
|
|
26
|
-
* `DATABASE_URL` should connect as.
|
|
27
|
-
*/
|
|
28
|
-
const NEON_DEFAULT_OWNER_ROLE = "neondb_owner";
|
|
29
|
-
/**
|
|
30
26
|
* Neon's default database, created with every project. When a branch has several databases
|
|
31
27
|
* and none was requested, this is preferred for the `DATABASE_URL` so the common case (a
|
|
32
28
|
* user added a second database next to `neondb`) auto-picks without asking.
|
|
33
29
|
*/
|
|
34
30
|
const NEON_DEFAULT_DATABASE = "neondb";
|
|
35
|
-
/**
|
|
36
|
-
* Roles Neon provisions for the Auth / Data API (PostgREST) stack. They exist to back
|
|
37
|
-
* RLS-scoped Data API requests authenticated by JWT — never to hold a `DATABASE_URL` —
|
|
38
|
-
* so they're skipped when auto-picking the connection role. Enabling Neon Auth or the
|
|
39
|
-
* Data API (`neon config apply`) adds these next to the owner role, which is why a plain
|
|
40
|
-
* branch routinely reports more than one role.
|
|
41
|
-
*/
|
|
42
|
-
const NEON_MANAGED_AUTH_ROLES = /* @__PURE__ */ new Set([
|
|
43
|
-
"authenticator",
|
|
44
|
-
"anonymous",
|
|
45
|
-
"authenticated"
|
|
46
|
-
]);
|
|
47
31
|
const NEON_ENV_VAR_KEYS = {
|
|
48
32
|
/**
|
|
49
33
|
* Branch identity. `NEON_BRANCH` carries the branch **name** and is injected into the
|
|
@@ -540,11 +524,8 @@ function pickRoleName(roles, branch, requested) {
|
|
|
540
524
|
return requested;
|
|
541
525
|
}
|
|
542
526
|
if (roles.length === 0) throw new PlatformError(ErrorCode.BranchNotFound, [`fetchEnv: branch ${branch.name} (${branch.id}) has no roles.`, "Create one via the Neon console or pass `roleName` explicitly."].join(" "), { details: { branchId: branch.id } });
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
if (owner) return owner.name;
|
|
546
|
-
const appRoles = roles.filter((r) => !NEON_MANAGED_AUTH_ROLES.has(r.name));
|
|
547
|
-
if (appRoles.length === 1) return appRoles[0].name;
|
|
527
|
+
const picked = defaultConnectionRole(roles.map((r) => r.name));
|
|
528
|
+
if (picked) return picked;
|
|
548
529
|
throw new PlatformError(ErrorCode.AmbiguousBranchAuth, [`fetchEnv: branch ${branch.name} (${branch.id}) has ${roles.length} roles and none is "${NEON_DEFAULT_OWNER_ROLE}"; cannot auto-pick.`, `Pass \`roleName\` explicitly. Available: ${roles.map((r) => r.name).join(", ")}.`].join(" "), { details: {
|
|
549
530
|
branchId: branch.id,
|
|
550
531
|
availableRoles: roles.map((r) => r.name)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region ../../internals/env-core/dist/roles.js
|
|
2
|
+
/**
|
|
3
|
+
* Neon's default branch owner role, created with every project. This is the role a
|
|
4
|
+
* `DATABASE_URL` should connect as.
|
|
5
|
+
*/
|
|
6
|
+
const NEON_DEFAULT_OWNER_ROLE = "neondb_owner";
|
|
7
|
+
/**
|
|
8
|
+
* Roles Neon provisions for the Auth / Data API (PostgREST) stack. They exist to back
|
|
9
|
+
* RLS-scoped Data API requests authenticated by JWT — never to hold a `DATABASE_URL` —
|
|
10
|
+
* so they're skipped when auto-picking the connection role. Enabling Neon Auth or the
|
|
11
|
+
* Data API (`neon config apply`) adds these next to the owner role, which is why a plain
|
|
12
|
+
* branch routinely reports more than one role.
|
|
13
|
+
*/
|
|
14
|
+
const NEON_MANAGED_AUTH_ROLES = /* @__PURE__ */ new Set([
|
|
15
|
+
"authenticator",
|
|
16
|
+
"anonymous",
|
|
17
|
+
"authenticated"
|
|
18
|
+
]);
|
|
19
|
+
/** `undefined` when more than one app role remains (or none exist), so the caller has to ask. */
|
|
20
|
+
function defaultConnectionRole(roleNames) {
|
|
21
|
+
if (roleNames.length === 1) return roleNames[0];
|
|
22
|
+
if (roleNames.includes("neondb_owner")) return NEON_DEFAULT_OWNER_ROLE;
|
|
23
|
+
const appRoles = roleNames.filter((name) => !NEON_MANAGED_AUTH_ROLES.has(name));
|
|
24
|
+
return appRoles.length === 1 ? appRoles[0] : void 0;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { defaultConnectionRole as n, NEON_DEFAULT_OWNER_ROLE as t };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "../_chunks/rolldown-runtime-8H4AJuhK.js";
|
|
2
|
+
import { n as defaultConnectionRole } from "../_chunks/roles-C3M4q9DS.js";
|
|
2
3
|
import { writer } from "../writer.js";
|
|
3
4
|
import { EndpointType } from "../utils/api_enums.js";
|
|
4
5
|
import { branchIdFromProps, fillSingleProject } from "../utils/enrichers.js";
|
|
@@ -33,7 +34,7 @@ const builder = (argv) => {
|
|
|
33
34
|
},
|
|
34
35
|
"role-name": {
|
|
35
36
|
type: "string",
|
|
36
|
-
describe: "Role name"
|
|
37
|
+
describe: "Role name. Defaults to neondb_owner, else the only role besides the Data API and Neon Auth roles"
|
|
37
38
|
},
|
|
38
39
|
"database-name": {
|
|
39
40
|
type: "string",
|
|
@@ -100,7 +101,8 @@ const handler = async (props) => {
|
|
|
100
101
|
if (!endpoint) throw new Error(`No ${props.endpointType ?? ""} endpoint found for the branch: ${branchId}`);
|
|
101
102
|
const role = !rolesRequest ? props.roleName : await rolesRequest.then(({ data }) => {
|
|
102
103
|
if (data.roles.length === 0) throw new Error(`No roles found for the branch: ${branchId}`);
|
|
103
|
-
|
|
104
|
+
const picked = defaultConnectionRole(data.roles.map((r) => r.name));
|
|
105
|
+
if (picked) return picked;
|
|
104
106
|
throw new Error(`Multiple roles found for the branch, please provide one with the --role-name option: ${data.roles.map((r) => r.name).join(", ")}`);
|
|
105
107
|
});
|
|
106
108
|
const { data: { databases: branchDatabases } } = await databasesRequest;
|
package/dist/commands/dev.js
CHANGED
|
@@ -3,10 +3,10 @@ import { log } from "../log.js";
|
|
|
3
3
|
import { isClaimableEnvTarget } from "../claimable/state.js";
|
|
4
4
|
import { getCliName } from "../utils/cli_name.js";
|
|
5
5
|
import { readEnvFile, resolveEnvFilePath } from "../env_file.js";
|
|
6
|
-
import { l as functionBaseUrlKey } from "../_chunks/env-
|
|
6
|
+
import { l as functionBaseUrlKey } from "../_chunks/env-XsUZj_Ay.js";
|
|
7
7
|
import { branchIdResolve } from "../utils/enrichers.js";
|
|
8
8
|
import { bundleEntry } from "../utils/esbuild.js";
|
|
9
|
-
import { a as resolveDevEnv } from "../_chunks/env-
|
|
9
|
+
import { a as resolveDevEnv } from "../_chunks/env-L2DPzDAK.js";
|
|
10
10
|
import { findConfigFunctionBySource, resolveFunctionsFromConfig } from "../dev/functions.js";
|
|
11
11
|
import { resolveWatchInputs } from "../dev/inputs.js";
|
|
12
12
|
import { existsSync, mkdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
package/dist/commands/env.js
CHANGED
|
@@ -5,11 +5,11 @@ import { isClaimableEnvTarget } from "../claimable/state.js";
|
|
|
5
5
|
import { getCliName } from "../utils/cli_name.js";
|
|
6
6
|
import { deprecatedServiceMessage, parseServices, servicesFlagValue, servicesOption } from "../neon_services.js";
|
|
7
7
|
import { mergeEnvFile, readEnvFile, resolveEnvFilePath } from "../env_file.js";
|
|
8
|
-
import { t as NEON_ENV_VAR_KEYS, u as isFunctionBaseUrlKey } from "../_chunks/env-
|
|
8
|
+
import { t as NEON_ENV_VAR_KEYS, u as isFunctionBaseUrlKey } from "../_chunks/env-XsUZj_Ay.js";
|
|
9
9
|
import { ENV_PULL_KEY_HELP, ENV_PULL_SERVICES, envKeysForSelection, envPullFlagValue, ownedEnvServiceKeys, parseEnvPullKeys } from "../env_services.js";
|
|
10
10
|
import { fillSingleProject, resolveBranchRef } from "../utils/enrichers.js";
|
|
11
11
|
import { warnAiGateway } from "../utils/ai_gateway_notice.js";
|
|
12
|
-
import { i as dropClaimableUnsupported, o as resolveNeonEnvVars } from "../_chunks/env-
|
|
12
|
+
import { i as dropClaimableUnsupported, o as resolveNeonEnvVars } from "../_chunks/env-L2DPzDAK.js";
|
|
13
13
|
import { formatPulledEnv, pulledBranch } from "./env_output.js";
|
|
14
14
|
import { existsSync } from "node:fs";
|
|
15
15
|
import chalk from "chalk";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NEON_SERVICES, NEON_SERVICE_LABELS } from "../neon_services.js";
|
|
2
|
-
import { u as isFunctionBaseUrlKey } from "../_chunks/env-
|
|
2
|
+
import { u as isFunctionBaseUrlKey } from "../_chunks/env-XsUZj_Ay.js";
|
|
3
3
|
import { BRANCH_ENV_KEY, ENV_PULL_KEYS, serviceForEnvKey } from "../env_services.js";
|
|
4
4
|
import { isAbsolute, relative } from "node:path";
|
|
5
5
|
import { homedir } from "node:os";
|
package/dist/commands/inspect.js
CHANGED
package/dist/dev/env.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as resolveDevEnv, i as dropClaimableUnsupported, n as MissingBranchContextError, o as resolveNeonEnvVars, r as ServiceNotOnBranchError, t as DevEnvMismatchError } from "../_chunks/env-
|
|
1
|
+
import { a as resolveDevEnv, i as dropClaimableUnsupported, n as MissingBranchContextError, o as resolveNeonEnvVars, r as ServiceNotOnBranchError, t as DevEnvMismatchError } from "../_chunks/env-L2DPzDAK.js";
|
|
2
2
|
export { DevEnvMismatchError, MissingBranchContextError, ServiceNotOnBranchError, dropClaimableUnsupported, resolveDevEnv, resolveNeonEnvVars };
|
package/dist/env_services.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NEON_SERVICES } from "./neon_services.js";
|
|
2
|
-
import { f as parseFunctionBaseUrlKey, t as NEON_ENV_VAR_KEYS, u as isFunctionBaseUrlKey } from "./_chunks/env-
|
|
2
|
+
import { f as parseFunctionBaseUrlKey, t as NEON_ENV_VAR_KEYS, u as isFunctionBaseUrlKey } from "./_chunks/env-XsUZj_Ay.js";
|
|
3
3
|
//#region src/env_services.ts
|
|
4
4
|
const ENV_PULL_SERVICES = NEON_SERVICES;
|
|
5
5
|
const ENV_PULL_KEYS = [
|
package/dist/utils/hooks.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { log } from "../log.js";
|
|
2
2
|
import { loadProjectConfig } from "../project.js";
|
|
3
|
-
import { s as fetchEnvKeys } from "../_chunks/env-
|
|
3
|
+
import { s as fetchEnvKeys } from "../_chunks/env-XsUZj_Ay.js";
|
|
4
4
|
import { runHook } from "@neon/config-runtime";
|
|
5
5
|
//#region src/utils/hooks.ts
|
|
6
6
|
/**
|
package/dist/utils/inspect_db.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { n as defaultConnectionRole } from "../_chunks/roles-C3M4q9DS.js";
|
|
1
2
|
import { EndpointType } from "./api_enums.js";
|
|
2
3
|
import { branchIdFromProps } from "./enrichers.js";
|
|
3
4
|
import { parsePITBranch } from "./point_in_time.js";
|
|
@@ -48,20 +49,37 @@ const connectionUriForDatabase = (connectionUri, database) => {
|
|
|
48
49
|
url.pathname = `/${encodeURIComponent(database)}`;
|
|
49
50
|
return url.toString();
|
|
50
51
|
};
|
|
51
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Resolves the branch once and starts its endpoint, role, and database reads together.
|
|
54
|
+
* Callers read them in the order a sequential run would, so the first error is the same.
|
|
55
|
+
*/
|
|
56
|
+
const startBranchConnectionReads = async (props) => {
|
|
52
57
|
const projectId = props.projectId;
|
|
53
58
|
const parsedPIT = props.branch ? parsePITBranch(props.branch) : {
|
|
54
59
|
tag: "head",
|
|
55
60
|
branch: ""
|
|
56
61
|
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
if (props.branch) props.branch = parsedPIT.branch;
|
|
63
|
+
const branchId = await branchIdFromProps(props);
|
|
64
|
+
const endpoints = props.apiClient.listProjectBranchEndpoints(projectId, branchId).then(({ data }) => data.endpoints);
|
|
65
|
+
const role = props.roleName ? Promise.resolve(props.roleName) : props.apiClient.listProjectBranchRoles(projectId, branchId).then(({ data }) => {
|
|
66
|
+
if (data.roles.length === 0) throw new Error(`No roles found for the branch: ${branchId}`);
|
|
67
|
+
const picked = defaultConnectionRole(data.roles.map((r) => r.name));
|
|
68
|
+
if (picked) return picked;
|
|
69
|
+
throw new Error(`Multiple roles found for the branch, please provide one with the --role-name option: ${data.roles.map((r) => r.name).join(", ")}`);
|
|
60
70
|
});
|
|
61
|
-
const
|
|
71
|
+
const databases = props.apiClient.listProjectBranchDatabases(projectId, branchId).then(({ data }) => data.databases);
|
|
72
|
+
for (const read of [
|
|
73
|
+
endpoints,
|
|
74
|
+
role,
|
|
75
|
+
databases
|
|
76
|
+
]) read.catch(() => void 0);
|
|
62
77
|
return {
|
|
63
78
|
branchId,
|
|
64
|
-
|
|
79
|
+
parsedPIT,
|
|
80
|
+
endpoints,
|
|
81
|
+
role,
|
|
82
|
+
databases
|
|
65
83
|
};
|
|
66
84
|
};
|
|
67
85
|
/**
|
|
@@ -70,25 +88,16 @@ const listBranchDatabases = async (props) => {
|
|
|
70
88
|
* pooling, prisma tuning, and SSL mode). Mirrors how `connection-string`
|
|
71
89
|
* resolves a branch so `inspect db` connects the same way.
|
|
72
90
|
*/
|
|
73
|
-
const resolveConnectionUri = async (props) => {
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
branch: ""
|
|
78
|
-
};
|
|
79
|
-
if (props.branch) props.branch = parsedPIT.branch;
|
|
80
|
-
const branchId = await branchIdFromProps(props);
|
|
81
|
-
const { data: { endpoints } } = await props.apiClient.listProjectBranchEndpoints(projectId, branchId);
|
|
91
|
+
const resolveConnectionUri = async (props, started) => {
|
|
92
|
+
const reads = started ?? await startBranchConnectionReads(props);
|
|
93
|
+
const { branchId, parsedPIT } = reads;
|
|
94
|
+
const endpoints = await reads.endpoints;
|
|
82
95
|
const matchEndpointType = props.endpointType ?? EndpointType.ReadWrite;
|
|
83
96
|
let endpoint = endpoints.find((e) => e.type === matchEndpointType);
|
|
84
97
|
if (!endpoint && props.endpointType == null) endpoint = endpoints[0];
|
|
85
98
|
if (!endpoint) throw new Error(`No ${props.endpointType ?? ""} endpoint found for the branch: ${branchId}`);
|
|
86
|
-
const role =
|
|
87
|
-
|
|
88
|
-
if (data.roles.length === 1) return data.roles[0].name;
|
|
89
|
-
throw new Error(`Multiple roles found for the branch, please provide one with the --role-name option: ${data.roles.map((r) => r.name).join(", ")}`);
|
|
90
|
-
});
|
|
91
|
-
const { data: { databases: branchDatabases } } = await props.apiClient.listProjectBranchDatabases(projectId, branchId);
|
|
99
|
+
const role = await reads.role;
|
|
100
|
+
const branchDatabases = await reads.databases;
|
|
92
101
|
const database = props.databaseName || (() => {
|
|
93
102
|
if (branchDatabases.length === 0) throw new Error(`No databases found for the branch: ${branchId}`);
|
|
94
103
|
if (branchDatabases.length === 1) return branchDatabases[0].name;
|
|
@@ -158,8 +167,9 @@ const resolveInspectTargets = async (props, scope) => {
|
|
|
158
167
|
branchDatabaseCount: 1
|
|
159
168
|
};
|
|
160
169
|
}
|
|
161
|
-
const
|
|
162
|
-
|
|
170
|
+
const reads = await startBranchConnectionReads(props);
|
|
171
|
+
const names = (await reads.databases).map((d) => d.name);
|
|
172
|
+
if (names.length === 0) throw new Error(`No databases found for the branch: ${reads.branchId}`);
|
|
163
173
|
const selection = selectInspectTargets({
|
|
164
174
|
branchDatabases: names,
|
|
165
175
|
scope
|
|
@@ -167,7 +177,7 @@ const resolveInspectTargets = async (props, scope) => {
|
|
|
167
177
|
const first = await resolveConnectionUri({
|
|
168
178
|
...props,
|
|
169
179
|
databaseName: selection.databases[0]
|
|
170
|
-
});
|
|
180
|
+
}, reads);
|
|
171
181
|
return {
|
|
172
182
|
targets: selection.databases.map((database) => ({
|
|
173
183
|
database,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neon",
|
|
3
|
-
"version": "8.3.
|
|
3
|
+
"version": "8.3.5",
|
|
4
4
|
"description": "CLI tool for Neon, the cloud backend primitives built around Lakebase Postgres",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"neon",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"yargs": "17.7.2",
|
|
66
66
|
"yoctocolors": "^2.1.2",
|
|
67
67
|
"@neon/config": "1.8.6",
|
|
68
|
-
"@neon/
|
|
69
|
-
"@neon/
|
|
68
|
+
"@neon/sdk": "7.0.1",
|
|
69
|
+
"@neon/config-runtime": "1.8.0"
|
|
70
70
|
},
|
|
71
71
|
"optionalDependencies": {
|
|
72
72
|
"@napi-rs/keyring": "1.3.0",
|
|
@@ -101,9 +101,9 @@
|
|
|
101
101
|
"typescript": "^5.9.0",
|
|
102
102
|
"vitest": "^3.0.9",
|
|
103
103
|
"@neon-internals/cli-core": "0.0.0",
|
|
104
|
-
"@neon-internals/env-core": "0.0.29",
|
|
105
104
|
"@neon/e2e-harness": "0.0.0",
|
|
106
|
-
"@neon/functions": "0.11.0"
|
|
105
|
+
"@neon/functions": "0.11.0",
|
|
106
|
+
"@neon-internals/env-core": "0.0.29"
|
|
107
107
|
},
|
|
108
108
|
"publishConfig": {
|
|
109
109
|
"access": "public",
|