neonctl 2.28.0 → 2.29.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 +71 -71
- package/dist/analytics.js +35 -33
- package/dist/api.js +34 -34
- package/dist/auth.js +50 -44
- package/dist/cli.js +2 -2
- package/dist/commands/auth.js +58 -52
- package/dist/commands/bootstrap.js +115 -157
- package/dist/commands/branches.js +154 -147
- package/dist/commands/bucket.js +124 -118
- package/dist/commands/checkout.js +49 -49
- package/dist/commands/config.js +212 -88
- package/dist/commands/connection_string.js +62 -62
- package/dist/commands/data_api.js +96 -96
- package/dist/commands/databases.js +23 -23
- package/dist/commands/deploy.js +12 -12
- package/dist/commands/dev.js +114 -114
- package/dist/commands/env.js +43 -43
- package/dist/commands/functions.js +97 -98
- package/dist/commands/index.js +26 -26
- package/dist/commands/init.js +23 -22
- package/dist/commands/ip_allow.js +29 -29
- package/dist/commands/link.js +223 -166
- package/dist/commands/neon_auth.js +381 -363
- package/dist/commands/operations.js +11 -11
- package/dist/commands/orgs.js +8 -8
- package/dist/commands/projects.js +101 -99
- package/dist/commands/psql.js +31 -31
- package/dist/commands/roles.js +21 -21
- package/dist/commands/schema_diff.js +23 -23
- package/dist/commands/set_context.js +17 -17
- package/dist/commands/status.js +17 -17
- package/dist/commands/user.js +5 -5
- package/dist/commands/vpc_endpoints.js +50 -50
- package/dist/config.js +7 -7
- package/dist/config_format.js +5 -5
- package/dist/context.js +23 -16
- package/dist/current_branch_fast_path.js +6 -6
- package/dist/dev/env.js +34 -34
- package/dist/dev/functions.js +4 -4
- package/dist/dev/inputs.js +6 -6
- package/dist/dev/runtime.js +25 -25
- package/dist/env.js +14 -14
- package/dist/env_file.js +13 -13
- package/dist/errors.js +19 -19
- package/dist/functions_api.js +10 -10
- package/dist/help.js +15 -15
- package/dist/index.js +94 -92
- package/dist/log.js +2 -2
- package/dist/pkg.js +5 -5
- package/dist/psql/cli.js +4 -2
- package/dist/psql/command/cmd_cond.js +61 -61
- package/dist/psql/command/cmd_connect.js +159 -154
- package/dist/psql/command/cmd_copy.js +107 -97
- package/dist/psql/command/cmd_describe.js +368 -363
- package/dist/psql/command/cmd_format.js +276 -263
- package/dist/psql/command/cmd_io.js +269 -263
- package/dist/psql/command/cmd_lo.js +74 -66
- package/dist/psql/command/cmd_meta.js +148 -148
- package/dist/psql/command/cmd_misc.js +17 -17
- package/dist/psql/command/cmd_pipeline.js +142 -135
- package/dist/psql/command/cmd_restrict.js +25 -25
- package/dist/psql/command/cmd_show.js +183 -168
- package/dist/psql/command/dispatch.js +26 -26
- package/dist/psql/command/shared.js +14 -14
- package/dist/psql/complete/filenames.js +16 -16
- package/dist/psql/complete/index.js +4 -4
- package/dist/psql/complete/matcher.js +33 -32
- package/dist/psql/complete/psqlVars.js +173 -173
- package/dist/psql/complete/queries.js +5 -3
- package/dist/psql/complete/rules.js +900 -863
- package/dist/psql/core/common.js +136 -133
- package/dist/psql/core/help.js +343 -343
- package/dist/psql/core/mainloop.js +160 -153
- package/dist/psql/core/prompt.js +126 -123
- package/dist/psql/core/settings.js +111 -111
- package/dist/psql/core/sqlHelp.js +150 -150
- package/dist/psql/core/startup.js +211 -205
- package/dist/psql/core/syncVars.js +14 -14
- package/dist/psql/core/variables.js +24 -24
- package/dist/psql/describe/formatters.js +302 -289
- package/dist/psql/describe/processNamePattern.js +28 -28
- package/dist/psql/describe/queries.js +656 -651
- package/dist/psql/index.js +436 -411
- package/dist/psql/io/history.js +36 -36
- package/dist/psql/io/input.js +15 -15
- package/dist/psql/io/lineEditor/buffer.js +27 -25
- package/dist/psql/io/lineEditor/complete.js +15 -15
- package/dist/psql/io/lineEditor/filename.js +22 -22
- package/dist/psql/io/lineEditor/index.js +65 -62
- package/dist/psql/io/lineEditor/keymap.js +325 -318
- package/dist/psql/io/lineEditor/vt100.js +60 -60
- package/dist/psql/io/pgpass.js +18 -18
- package/dist/psql/io/pgservice.js +14 -14
- package/dist/psql/io/psqlrc.js +46 -46
- package/dist/psql/print/aligned.js +175 -166
- package/dist/psql/print/asciidoc.js +51 -51
- package/dist/psql/print/crosstab.js +34 -31
- package/dist/psql/print/csv.js +25 -22
- package/dist/psql/print/html.js +54 -54
- package/dist/psql/print/json.js +12 -12
- package/dist/psql/print/latex.js +118 -118
- package/dist/psql/print/pager.js +28 -26
- package/dist/psql/print/troff.js +48 -48
- package/dist/psql/print/unaligned.js +15 -14
- package/dist/psql/print/units.js +17 -17
- package/dist/psql/scanner/slash.js +48 -46
- package/dist/psql/scanner/sql.js +88 -84
- package/dist/psql/scanner/stringutils.js +21 -17
- package/dist/psql/types/index.js +7 -7
- package/dist/psql/types/scanner.js +8 -8
- package/dist/psql/wire/connection.js +341 -327
- package/dist/psql/wire/copy.js +7 -7
- package/dist/psql/wire/pipeline.js +26 -24
- package/dist/psql/wire/protocol.js +102 -102
- package/dist/psql/wire/sasl.js +62 -62
- package/dist/psql/wire/tls.js +79 -73
- package/dist/storage_api.js +15 -15
- package/dist/test_utils/fixtures.js +34 -31
- package/dist/test_utils/oauth_server.js +5 -5
- package/dist/utils/api_enums.js +13 -13
- package/dist/utils/branch_notice.js +5 -5
- package/dist/utils/branch_picker.js +26 -26
- package/dist/utils/compute_units.js +4 -4
- package/dist/utils/enrichers.js +20 -15
- package/dist/utils/esbuild.js +28 -28
- package/dist/utils/formats.js +1 -1
- package/dist/utils/middlewares.js +3 -3
- package/dist/utils/package_manager.js +68 -0
- package/dist/utils/point_in_time.js +12 -12
- package/dist/utils/psql.js +30 -30
- package/dist/utils/string.js +2 -2
- package/dist/utils/ui.js +9 -9
- package/dist/utils/zip.js +1 -1
- package/dist/writer.js +17 -17
- package/package.json +6 -7
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
import { EndpointType } from
|
|
2
|
-
import { branchIdFromProps, fillSingleProject } from
|
|
3
|
-
import {
|
|
4
|
-
import { psql } from
|
|
5
|
-
import {
|
|
1
|
+
import { EndpointType } from "../utils/api_enums.js";
|
|
2
|
+
import { branchIdFromProps, fillSingleProject } from "../utils/enrichers.js";
|
|
3
|
+
import { parsePITBranch } from "../utils/point_in_time.js";
|
|
4
|
+
import { psql } from "../utils/psql.js";
|
|
5
|
+
import { writer } from "../writer.js";
|
|
6
6
|
export const SSL_MODES = [
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
"require",
|
|
8
|
+
"verify-ca",
|
|
9
|
+
"verify-full",
|
|
10
|
+
"omit",
|
|
11
11
|
];
|
|
12
|
-
export const command =
|
|
13
|
-
export const aliases = [
|
|
14
|
-
export const describe =
|
|
12
|
+
export const command = "connection-string [branch]";
|
|
13
|
+
export const aliases = ["cs"];
|
|
14
|
+
export const describe = "Get connection string";
|
|
15
15
|
export const builder = (argv) => {
|
|
16
16
|
return argv
|
|
17
|
-
.usage(
|
|
18
|
-
.example(
|
|
19
|
-
.example(
|
|
20
|
-
.example(
|
|
21
|
-
.positional(
|
|
17
|
+
.usage("$0 connection-string [branch] [options]")
|
|
18
|
+
.example("$0 cs main", "Get connection string for the main branch")
|
|
19
|
+
.example("$0 cs main@2024-01-01T00:00:00Z", "Get connection string for the main branch at a specific point in time")
|
|
20
|
+
.example("$0 cs main@0/234235", "Get connection string for the main branch at a specific LSN")
|
|
21
|
+
.positional("branch", {
|
|
22
22
|
describe: `Branch name or id. Defaults to the default branch if omitted. Can be written in the point-in-time format: "branch@timestamp" or "branch@lsn"`,
|
|
23
|
-
type:
|
|
23
|
+
type: "string",
|
|
24
24
|
})
|
|
25
25
|
.options({
|
|
26
|
-
|
|
27
|
-
type:
|
|
28
|
-
describe:
|
|
26
|
+
"project-id": {
|
|
27
|
+
type: "string",
|
|
28
|
+
describe: "Project ID",
|
|
29
29
|
},
|
|
30
|
-
|
|
31
|
-
type:
|
|
32
|
-
describe:
|
|
30
|
+
"role-name": {
|
|
31
|
+
type: "string",
|
|
32
|
+
describe: "Role name",
|
|
33
33
|
},
|
|
34
|
-
|
|
35
|
-
type:
|
|
36
|
-
describe:
|
|
34
|
+
"database-name": {
|
|
35
|
+
type: "string",
|
|
36
|
+
describe: "Database name",
|
|
37
37
|
},
|
|
38
38
|
pooled: {
|
|
39
|
-
type:
|
|
40
|
-
describe:
|
|
39
|
+
type: "boolean",
|
|
40
|
+
describe: "Use pooled connection",
|
|
41
41
|
default: false,
|
|
42
42
|
},
|
|
43
43
|
prisma: {
|
|
44
|
-
type:
|
|
45
|
-
describe:
|
|
44
|
+
type: "boolean",
|
|
45
|
+
describe: "Use connection string for Prisma setup",
|
|
46
46
|
default: false,
|
|
47
47
|
},
|
|
48
|
-
|
|
49
|
-
type:
|
|
48
|
+
"endpoint-type": {
|
|
49
|
+
type: "string",
|
|
50
50
|
choices: Object.values(EndpointType),
|
|
51
|
-
describe:
|
|
51
|
+
describe: "Endpoint type",
|
|
52
52
|
},
|
|
53
53
|
extended: {
|
|
54
|
-
type:
|
|
55
|
-
describe:
|
|
54
|
+
type: "boolean",
|
|
55
|
+
describe: "Show extended information",
|
|
56
56
|
},
|
|
57
57
|
psql: {
|
|
58
|
-
type:
|
|
59
|
-
describe:
|
|
58
|
+
type: "boolean",
|
|
59
|
+
describe: "Connect to a database via psql using connection string",
|
|
60
60
|
default: false,
|
|
61
61
|
},
|
|
62
62
|
fallback: {
|
|
63
|
-
type:
|
|
64
|
-
describe:
|
|
63
|
+
type: "boolean",
|
|
64
|
+
describe: "Force the embedded TypeScript psql fallback (for testing)",
|
|
65
65
|
default: false,
|
|
66
66
|
hidden: true,
|
|
67
67
|
},
|
|
68
68
|
ssl: {
|
|
69
|
-
type:
|
|
69
|
+
type: "string",
|
|
70
70
|
choices: SSL_MODES,
|
|
71
|
-
default:
|
|
72
|
-
describe:
|
|
71
|
+
default: "require",
|
|
72
|
+
describe: "SSL mode",
|
|
73
73
|
},
|
|
74
74
|
})
|
|
75
75
|
.middleware(fillSingleProject);
|
|
@@ -78,7 +78,7 @@ export const handler = async (props) => {
|
|
|
78
78
|
const projectId = props.projectId;
|
|
79
79
|
const parsedPIT = props.branch
|
|
80
80
|
? parsePITBranch(props.branch)
|
|
81
|
-
: { tag:
|
|
81
|
+
: { tag: "head", branch: "" };
|
|
82
82
|
if (props.branch) {
|
|
83
83
|
props.branch = parsedPIT.branch;
|
|
84
84
|
}
|
|
@@ -90,7 +90,7 @@ export const handler = async (props) => {
|
|
|
90
90
|
endpoint = endpoints[0];
|
|
91
91
|
}
|
|
92
92
|
if (!endpoint) {
|
|
93
|
-
throw new Error(`No ${props.endpointType ??
|
|
93
|
+
throw new Error(`No ${props.endpointType ?? ""} endpoint found for the branch: ${branchId}`);
|
|
94
94
|
}
|
|
95
95
|
const role = props.roleName ||
|
|
96
96
|
(await props.apiClient
|
|
@@ -104,7 +104,7 @@ export const handler = async (props) => {
|
|
|
104
104
|
}
|
|
105
105
|
throw new Error(`Multiple roles found for the branch, please provide one with the --role-name option: ${data.roles
|
|
106
106
|
.map((r) => r.name)
|
|
107
|
-
.join(
|
|
107
|
+
.join(", ")}`);
|
|
108
108
|
}));
|
|
109
109
|
const { data: { databases: branchDatabases }, } = await props.apiClient.listProjectBranchDatabases(projectId, branchId);
|
|
110
110
|
const database = props.databaseName ||
|
|
@@ -117,7 +117,7 @@ export const handler = async (props) => {
|
|
|
117
117
|
}
|
|
118
118
|
throw new Error(`Multiple databases found for the branch, please provide one with the --database-name option: ${branchDatabases
|
|
119
119
|
.map((d) => d.name)
|
|
120
|
-
.join(
|
|
120
|
+
.join(", ")}`);
|
|
121
121
|
})();
|
|
122
122
|
if (!branchDatabases.find((d) => d.name === database)) {
|
|
123
123
|
throw new Error(`Database not found: ${database}`);
|
|
@@ -126,7 +126,7 @@ export const handler = async (props) => {
|
|
|
126
126
|
let host = props.pooled
|
|
127
127
|
? endpoint.host.replace(endpoint.id, `${endpoint.id}-pooler`)
|
|
128
128
|
: endpoint.host;
|
|
129
|
-
if (parsedPIT.tag !==
|
|
129
|
+
if (parsedPIT.tag !== "head") {
|
|
130
130
|
host = endpoint.host.replace(endpoint.id, endpoint.branch_id);
|
|
131
131
|
}
|
|
132
132
|
const connectionString = new URL(`postgresql://${host}`);
|
|
@@ -134,26 +134,26 @@ export const handler = async (props) => {
|
|
|
134
134
|
connectionString.username = role;
|
|
135
135
|
connectionString.password = password;
|
|
136
136
|
if (props.prisma) {
|
|
137
|
-
connectionString.searchParams.set(
|
|
137
|
+
connectionString.searchParams.set("connect_timeout", "30");
|
|
138
138
|
if (props.pooled) {
|
|
139
|
-
connectionString.searchParams.set(
|
|
140
|
-
connectionString.searchParams.set(
|
|
139
|
+
connectionString.searchParams.set("pool_timeout", "30");
|
|
140
|
+
connectionString.searchParams.set("pgbouncer", "true");
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
|
-
if (props.ssl !==
|
|
144
|
-
connectionString.searchParams.set(
|
|
145
|
-
connectionString.searchParams.set(
|
|
143
|
+
if (props.ssl !== "omit") {
|
|
144
|
+
connectionString.searchParams.set("sslmode", props.ssl);
|
|
145
|
+
connectionString.searchParams.set("channel_binding", "require");
|
|
146
146
|
}
|
|
147
|
-
if (parsedPIT.tag ===
|
|
148
|
-
connectionString.searchParams.set(
|
|
147
|
+
if (parsedPIT.tag === "lsn") {
|
|
148
|
+
connectionString.searchParams.set("options", `neon_lsn:${parsedPIT.lsn}`);
|
|
149
149
|
}
|
|
150
|
-
else if (parsedPIT.tag ===
|
|
151
|
-
connectionString.searchParams.set(
|
|
150
|
+
else if (parsedPIT.tag === "timestamp") {
|
|
151
|
+
connectionString.searchParams.set("options", `neon_timestamp:${parsedPIT.timestamp}`);
|
|
152
152
|
}
|
|
153
153
|
if (props.psql) {
|
|
154
|
-
const psqlArgs = props[
|
|
154
|
+
const psqlArgs = props["--"];
|
|
155
155
|
await psql(connectionString.toString(), psqlArgs, {
|
|
156
|
-
mode: props.fallback ?
|
|
156
|
+
mode: props.fallback ? "ts" : "auto",
|
|
157
157
|
});
|
|
158
158
|
}
|
|
159
159
|
else if (props.extended) {
|
|
@@ -164,9 +164,9 @@ export const handler = async (props) => {
|
|
|
164
164
|
password,
|
|
165
165
|
database,
|
|
166
166
|
options: connectionString.searchParams.toString(),
|
|
167
|
-
}, { fields: [
|
|
167
|
+
}, { fields: ["host", "role", "password", "database"] });
|
|
168
168
|
}
|
|
169
169
|
else {
|
|
170
|
-
process.stdout.write(connectionString.toString() +
|
|
170
|
+
process.stdout.write(connectionString.toString() + "\n");
|
|
171
171
|
}
|
|
172
172
|
};
|
|
@@ -1,141 +1,141 @@
|
|
|
1
|
-
import { isNeonApiError, retryOnLock } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { writer } from
|
|
1
|
+
import { isNeonApiError, retryOnLock } from "../api.js";
|
|
2
|
+
import { log } from "../log.js";
|
|
3
|
+
import { branchIdFromProps, fillSingleProject, resolveSingleDatabase, } from "../utils/enrichers.js";
|
|
4
|
+
import { writer } from "../writer.js";
|
|
5
5
|
const SETTINGS_FIELDS = [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
"db_aggregates_enabled",
|
|
7
|
+
"db_anon_role",
|
|
8
|
+
"db_extra_search_path",
|
|
9
|
+
"db_max_rows",
|
|
10
|
+
"db_schemas",
|
|
11
|
+
"jwt_role_claim_key",
|
|
12
|
+
"jwt_cache_max_lifetime",
|
|
13
|
+
"openapi_mode",
|
|
14
|
+
"server_cors_allowed_origins",
|
|
15
|
+
"server_timing_enabled",
|
|
16
16
|
];
|
|
17
17
|
const settingsFlags = {
|
|
18
|
-
|
|
19
|
-
type:
|
|
20
|
-
describe:
|
|
18
|
+
"db-aggregates-enabled": {
|
|
19
|
+
type: "boolean",
|
|
20
|
+
describe: "Enable aggregate functions in queries",
|
|
21
21
|
},
|
|
22
|
-
|
|
23
|
-
type:
|
|
24
|
-
describe:
|
|
22
|
+
"db-anon-role": {
|
|
23
|
+
type: "string",
|
|
24
|
+
describe: "Database role used for anonymous (unauthenticated) requests",
|
|
25
25
|
},
|
|
26
|
-
|
|
27
|
-
type:
|
|
28
|
-
describe:
|
|
26
|
+
"db-extra-search-path": {
|
|
27
|
+
type: "string",
|
|
28
|
+
describe: "Extra schemas appended to the search path",
|
|
29
29
|
},
|
|
30
|
-
|
|
31
|
-
type:
|
|
32
|
-
describe:
|
|
30
|
+
"db-max-rows": {
|
|
31
|
+
type: "number",
|
|
32
|
+
describe: "Maximum number of rows returned by a single request",
|
|
33
33
|
},
|
|
34
|
-
|
|
35
|
-
type:
|
|
36
|
-
describe:
|
|
34
|
+
"db-schemas": {
|
|
35
|
+
type: "string",
|
|
36
|
+
describe: "Comma-separated list of schemas exposed via the Data API",
|
|
37
37
|
},
|
|
38
|
-
|
|
39
|
-
type:
|
|
40
|
-
describe:
|
|
38
|
+
"jwt-role-claim-key": {
|
|
39
|
+
type: "string",
|
|
40
|
+
describe: "JWT claim path used to extract the role",
|
|
41
41
|
},
|
|
42
|
-
|
|
43
|
-
type:
|
|
44
|
-
describe:
|
|
42
|
+
"jwt-cache-max-lifetime": {
|
|
43
|
+
type: "number",
|
|
44
|
+
describe: "Maximum JWT cache lifetime in seconds",
|
|
45
45
|
},
|
|
46
|
-
|
|
47
|
-
type:
|
|
48
|
-
choices: [
|
|
49
|
-
describe:
|
|
46
|
+
"openapi-mode": {
|
|
47
|
+
type: "string",
|
|
48
|
+
choices: ["ignore-privileges", "disabled"],
|
|
49
|
+
describe: "OpenAPI mode",
|
|
50
50
|
},
|
|
51
|
-
|
|
52
|
-
type:
|
|
53
|
-
describe:
|
|
51
|
+
"server-cors-allowed-origins": {
|
|
52
|
+
type: "string",
|
|
53
|
+
describe: "CORS allowed origins",
|
|
54
54
|
},
|
|
55
|
-
|
|
56
|
-
type:
|
|
57
|
-
describe:
|
|
55
|
+
"server-timing-enabled": {
|
|
56
|
+
type: "boolean",
|
|
57
|
+
describe: "Enable Server-Timing response headers",
|
|
58
58
|
},
|
|
59
59
|
};
|
|
60
|
-
export const command =
|
|
61
|
-
export const describe =
|
|
60
|
+
export const command = "data-api";
|
|
61
|
+
export const describe = "Manage the Neon Data API for a database";
|
|
62
62
|
export const builder = (argv) => argv
|
|
63
|
-
.usage(
|
|
63
|
+
.usage("$0 data-api <sub-command> [options]")
|
|
64
64
|
.options({
|
|
65
|
-
|
|
66
|
-
describe:
|
|
67
|
-
type:
|
|
65
|
+
"project-id": {
|
|
66
|
+
describe: "Project ID",
|
|
67
|
+
type: "string",
|
|
68
68
|
},
|
|
69
69
|
branch: {
|
|
70
|
-
describe:
|
|
71
|
-
type:
|
|
70
|
+
describe: "Branch ID or name",
|
|
71
|
+
type: "string",
|
|
72
72
|
},
|
|
73
73
|
database: {
|
|
74
|
-
describe:
|
|
75
|
-
type:
|
|
74
|
+
describe: "Database name",
|
|
75
|
+
type: "string",
|
|
76
76
|
},
|
|
77
77
|
})
|
|
78
78
|
.middleware(fillSingleProject)
|
|
79
|
-
.command(
|
|
80
|
-
|
|
81
|
-
type:
|
|
82
|
-
choices: [
|
|
83
|
-
describe:
|
|
79
|
+
.command("create", "Provision the Neon Data API for a database", (yargs) => yargs.options({
|
|
80
|
+
"auth-provider": {
|
|
81
|
+
type: "string",
|
|
82
|
+
choices: ["neon_auth", "external"],
|
|
83
|
+
describe: "Authentication provider",
|
|
84
84
|
},
|
|
85
|
-
|
|
86
|
-
type:
|
|
87
|
-
describe:
|
|
85
|
+
"jwks-url": {
|
|
86
|
+
type: "string",
|
|
87
|
+
describe: "URL that lists the JWKS (used with external auth)",
|
|
88
88
|
},
|
|
89
|
-
|
|
90
|
-
type:
|
|
91
|
-
describe:
|
|
89
|
+
"provider-name": {
|
|
90
|
+
type: "string",
|
|
91
|
+
describe: "Name of the auth provider (e.g. Clerk, Stytch, Auth0)",
|
|
92
92
|
},
|
|
93
|
-
|
|
94
|
-
type:
|
|
95
|
-
describe:
|
|
93
|
+
"jwt-audience": {
|
|
94
|
+
type: "string",
|
|
95
|
+
describe: "Expected JWT audience claim",
|
|
96
96
|
},
|
|
97
|
-
|
|
98
|
-
type:
|
|
99
|
-
describe:
|
|
97
|
+
"add-default-grants": {
|
|
98
|
+
type: "boolean",
|
|
99
|
+
describe: "Grant all permissions on tables in the public schema to authenticated users",
|
|
100
100
|
},
|
|
101
|
-
|
|
102
|
-
type:
|
|
103
|
-
describe:
|
|
101
|
+
"skip-auth-schema": {
|
|
102
|
+
type: "boolean",
|
|
103
|
+
describe: "Skip creating the auth schema and RLS functions",
|
|
104
104
|
},
|
|
105
105
|
...settingsFlags,
|
|
106
106
|
}), (args) => create(args))
|
|
107
|
-
.command(
|
|
108
|
-
.command(
|
|
107
|
+
.command("get", "Show the Neon Data API status and settings", (yargs) => yargs, (args) => get(args))
|
|
108
|
+
.command("update", "Update Neon Data API settings (merges with current settings by default)", (yargs) => yargs.options({
|
|
109
109
|
replace: {
|
|
110
|
-
type:
|
|
110
|
+
type: "boolean",
|
|
111
111
|
default: false,
|
|
112
|
-
describe:
|
|
112
|
+
describe: "Replace settings with only the flags provided. Omitted settings revert to server defaults.",
|
|
113
113
|
},
|
|
114
114
|
...settingsFlags,
|
|
115
115
|
}), (args) => update(args))
|
|
116
|
-
.command(
|
|
117
|
-
.command(
|
|
116
|
+
.command("refresh-schema", "Refresh the Data API schema cache without changing settings", (yargs) => yargs, (args) => refreshSchema(args))
|
|
117
|
+
.command("delete", "Tear down the Neon Data API for a database", (yargs) => yargs, (args) => deleteDataApi(args));
|
|
118
118
|
export const handler = (args) => {
|
|
119
119
|
return args;
|
|
120
120
|
};
|
|
121
121
|
const TOP_LEVEL_CREATE_FIELDS = [
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
"auth_provider",
|
|
123
|
+
"jwks_url",
|
|
124
|
+
"provider_name",
|
|
125
|
+
"jwt_audience",
|
|
126
|
+
"add_default_grants",
|
|
127
|
+
"skip_auth_schema",
|
|
128
128
|
];
|
|
129
|
-
const argKey = (snake) => snake.replace(/_/g,
|
|
129
|
+
const argKey = (snake) => snake.replace(/_/g, "-");
|
|
130
130
|
const buildSettings = (args) => {
|
|
131
131
|
const settings = {};
|
|
132
132
|
for (const field of SETTINGS_FIELDS) {
|
|
133
133
|
const value = args[argKey(field)];
|
|
134
134
|
if (value === undefined)
|
|
135
135
|
continue;
|
|
136
|
-
if (field ===
|
|
136
|
+
if (field === "db_schemas" && typeof value === "string") {
|
|
137
137
|
settings[field] = value
|
|
138
|
-
.split(
|
|
138
|
+
.split(",")
|
|
139
139
|
.map((s) => s.trim())
|
|
140
140
|
.filter(Boolean);
|
|
141
141
|
}
|
|
@@ -169,9 +169,9 @@ const create = async (props) => {
|
|
|
169
169
|
});
|
|
170
170
|
const body = buildCreateBody(props);
|
|
171
171
|
const { data } = await retryOnLock(() => props.apiClient.createProjectBranchDataApi(props.projectId, branchId, database, body));
|
|
172
|
-
writer(props).end(data, { fields: [
|
|
172
|
+
writer(props).end(data, { fields: ["url"] });
|
|
173
173
|
};
|
|
174
|
-
const GET_FIELDS = [
|
|
174
|
+
const GET_FIELDS = ["url", "status", "db_schemas"];
|
|
175
175
|
const get = async (props) => {
|
|
176
176
|
const branchId = await branchIdFromProps(props);
|
|
177
177
|
const database = await resolveSingleDatabase({
|
|
@@ -188,11 +188,11 @@ const get = async (props) => {
|
|
|
188
188
|
const tableRow = {
|
|
189
189
|
url: publicData.url,
|
|
190
190
|
status: publicData.status,
|
|
191
|
-
db_schemas: (publicData.settings?.db_schemas ?? []).join(
|
|
191
|
+
db_schemas: (publicData.settings?.db_schemas ?? []).join(", "),
|
|
192
192
|
};
|
|
193
|
-
if (props.output ===
|
|
193
|
+
if (props.output === "json" || props.output === "yaml") {
|
|
194
194
|
writer(props).end(publicData, {
|
|
195
|
-
fields: [
|
|
195
|
+
fields: ["url", "status", "settings"],
|
|
196
196
|
});
|
|
197
197
|
return;
|
|
198
198
|
}
|
|
@@ -208,7 +208,7 @@ const update = async (props) => {
|
|
|
208
208
|
});
|
|
209
209
|
const userSettings = buildSettings(props);
|
|
210
210
|
if (!userSettings) {
|
|
211
|
-
throw new Error(
|
|
211
|
+
throw new Error("No settings flags provided. Pass at least one setting flag to update, or use `data-api refresh-schema` to refresh the schema cache without changing settings.");
|
|
212
212
|
}
|
|
213
213
|
let settings;
|
|
214
214
|
if (props.replace) {
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { retryOnLock } from
|
|
2
|
-
import { branchIdFromProps, fillSingleProject } from
|
|
3
|
-
import { writer } from
|
|
4
|
-
export const DATABASE_FIELDS = [
|
|
5
|
-
export const command =
|
|
6
|
-
export const describe =
|
|
7
|
-
export const aliases = [
|
|
1
|
+
import { retryOnLock } from "../api.js";
|
|
2
|
+
import { branchIdFromProps, fillSingleProject } from "../utils/enrichers.js";
|
|
3
|
+
import { writer } from "../writer.js";
|
|
4
|
+
export const DATABASE_FIELDS = ["name", "owner_name", "created_at"];
|
|
5
|
+
export const command = "databases";
|
|
6
|
+
export const describe = "Manage databases";
|
|
7
|
+
export const aliases = ["database", "db"];
|
|
8
8
|
export const builder = (argv) => argv
|
|
9
|
-
.usage(
|
|
9
|
+
.usage("$0 databases <sub-command> [options]")
|
|
10
10
|
.options({
|
|
11
|
-
|
|
12
|
-
describe:
|
|
13
|
-
type:
|
|
11
|
+
"project-id": {
|
|
12
|
+
describe: "Project ID",
|
|
13
|
+
type: "string",
|
|
14
14
|
},
|
|
15
15
|
branch: {
|
|
16
|
-
describe:
|
|
17
|
-
type:
|
|
16
|
+
describe: "Branch ID or name",
|
|
17
|
+
type: "string",
|
|
18
18
|
},
|
|
19
19
|
})
|
|
20
20
|
.middleware(fillSingleProject)
|
|
21
|
-
.command(
|
|
22
|
-
.command(
|
|
21
|
+
.command("list", "List databases", (yargs) => yargs, (args) => list(args))
|
|
22
|
+
.command("create", "Create a database", (yargs) => yargs.options({
|
|
23
23
|
name: {
|
|
24
|
-
describe:
|
|
25
|
-
type:
|
|
24
|
+
describe: "Database name",
|
|
25
|
+
type: "string",
|
|
26
26
|
demandOption: true,
|
|
27
27
|
},
|
|
28
|
-
|
|
29
|
-
describe:
|
|
30
|
-
type:
|
|
28
|
+
"owner-name": {
|
|
29
|
+
describe: "Owner name",
|
|
30
|
+
type: "string",
|
|
31
31
|
},
|
|
32
32
|
}), (args) => create(args))
|
|
33
|
-
.command(
|
|
33
|
+
.command("delete <database>", "Delete a database", (yargs) => yargs, (args) => deleteDb(args));
|
|
34
34
|
export const handler = (args) => {
|
|
35
35
|
return args;
|
|
36
36
|
};
|
|
@@ -53,12 +53,12 @@ export const create = async (props) => {
|
|
|
53
53
|
if (data.roles.length > 1) {
|
|
54
54
|
throw new Error(`More than one role found in branch ${branchId}. Please specify the owner name. Roles: ${data.roles
|
|
55
55
|
.map((r) => r.name)
|
|
56
|
-
.join(
|
|
56
|
+
.join(", ")}`);
|
|
57
57
|
}
|
|
58
58
|
return data.roles[0].name;
|
|
59
59
|
}));
|
|
60
60
|
if (!owner) {
|
|
61
|
-
throw new Error(
|
|
61
|
+
throw new Error("No owner found");
|
|
62
62
|
}
|
|
63
63
|
const { data } = await retryOnLock(() => props.apiClient.createProjectBranchDatabase(props.projectId, branchId, {
|
|
64
64
|
database: {
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { fillSingleProject } from
|
|
2
|
-
import { applyCmd, applyFlags, envFlag, envPullFlag, } from
|
|
3
|
-
export const command =
|
|
4
|
-
export const describe =
|
|
1
|
+
import { fillSingleProject } from "../utils/enrichers.js";
|
|
2
|
+
import { applyCmd, applyFlags, envFlag, envPullFlag, } from "./config.js";
|
|
3
|
+
export const command = "deploy";
|
|
4
|
+
export const describe = "Apply a neon.ts policy to a branch (alias for `config apply`)";
|
|
5
5
|
export const builder = (argv) => argv
|
|
6
|
-
.usage(
|
|
6
|
+
.usage("$0 deploy [options]")
|
|
7
7
|
.options({
|
|
8
|
-
|
|
9
|
-
describe:
|
|
10
|
-
type:
|
|
8
|
+
"project-id": {
|
|
9
|
+
describe: "Project ID",
|
|
10
|
+
type: "string",
|
|
11
11
|
},
|
|
12
12
|
branch: {
|
|
13
|
-
describe:
|
|
14
|
-
type:
|
|
13
|
+
describe: "Branch ID or name",
|
|
14
|
+
type: "string",
|
|
15
15
|
},
|
|
16
16
|
config: {
|
|
17
|
-
describe:
|
|
18
|
-
type:
|
|
17
|
+
describe: "Path to a neon.ts policy (defaults to walking up from cwd)",
|
|
18
|
+
type: "string",
|
|
19
19
|
},
|
|
20
20
|
...envFlag,
|
|
21
21
|
...applyFlags,
|