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,11 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { createPatch } from "diff";
|
|
3
|
+
import { sendError } from "../analytics.js";
|
|
4
|
+
import { isNeonApiError, messageFromBody } from "../api.js";
|
|
5
|
+
import { log } from "../log.js";
|
|
6
|
+
import { branchIdFromProps } from "../utils/enrichers.js";
|
|
7
|
+
import { parsePointInTime, } from "../utils/point_in_time.js";
|
|
8
|
+
import { writer } from "../writer.js";
|
|
9
9
|
const COLORS = {
|
|
10
10
|
added: chalk.green,
|
|
11
11
|
removed: chalk.red,
|
|
@@ -22,10 +22,10 @@ export const schemaDiff = async (props) => {
|
|
|
22
22
|
api: props.apiClient,
|
|
23
23
|
});
|
|
24
24
|
// Swap base and compare points if comparing with parent branch
|
|
25
|
-
const comparingWithParent = props.compareSource.startsWith(
|
|
25
|
+
const comparingWithParent = props.compareSource.startsWith("^parent");
|
|
26
26
|
let baseBranchPoint = {
|
|
27
27
|
branchId: baseBranch,
|
|
28
|
-
tag:
|
|
28
|
+
tag: "head",
|
|
29
29
|
};
|
|
30
30
|
[baseBranchPoint, pointInTime] = comparingWithParent
|
|
31
31
|
? [pointInTime, baseBranchPoint]
|
|
@@ -65,11 +65,11 @@ const fetchSchema = async (pointInTime, database, props) => {
|
|
|
65
65
|
db_name: database.name,
|
|
66
66
|
...pointInTimeParams(pointInTime),
|
|
67
67
|
});
|
|
68
|
-
return response.data.sql ??
|
|
68
|
+
return response.data.sql ?? "";
|
|
69
69
|
}
|
|
70
70
|
catch (error) {
|
|
71
71
|
if (isNeonApiError(error)) {
|
|
72
|
-
sendError(error,
|
|
72
|
+
sendError(error, "API_ERROR");
|
|
73
73
|
throw new Error(messageFromBody(error.data) ??
|
|
74
74
|
`Error while fetching schema for branch ${pointInTime.branchId}`);
|
|
75
75
|
}
|
|
@@ -78,10 +78,10 @@ const fetchSchema = async (pointInTime, database, props) => {
|
|
|
78
78
|
};
|
|
79
79
|
const colorize = (patch) => {
|
|
80
80
|
return patch
|
|
81
|
-
.replace(/^([^\n]+)\n([^\n]+)\n/m,
|
|
82
|
-
.replace(/^-.*/gm, colorizer(
|
|
83
|
-
.replace(/^\+.*/gm, colorizer(
|
|
84
|
-
.replace(/^@@.+@@.*/gm, colorizer(
|
|
81
|
+
.replace(/^([^\n]+)\n([^\n]+)\n/m, "") // Remove first two lines
|
|
82
|
+
.replace(/^-.*/gm, colorizer("removed"))
|
|
83
|
+
.replace(/^\+.*/gm, colorizer("added"))
|
|
84
|
+
.replace(/^@@.+@@.*/gm, colorizer("section"));
|
|
85
85
|
};
|
|
86
86
|
const colorizer = (colorId) => {
|
|
87
87
|
const color = COLORS[colorId];
|
|
@@ -89,11 +89,11 @@ const colorizer = (colorId) => {
|
|
|
89
89
|
};
|
|
90
90
|
const pointInTimeParams = (pointInTime) => {
|
|
91
91
|
switch (pointInTime.tag) {
|
|
92
|
-
case
|
|
92
|
+
case "timestamp":
|
|
93
93
|
return {
|
|
94
94
|
timestamp: pointInTime.timestamp,
|
|
95
95
|
};
|
|
96
|
-
case
|
|
96
|
+
case "lsn":
|
|
97
97
|
return {
|
|
98
98
|
lsn: pointInTime.lsn ?? undefined,
|
|
99
99
|
};
|
|
@@ -104,9 +104,9 @@ const pointInTimeParams = (pointInTime) => {
|
|
|
104
104
|
const generateHeader = (pointInTime) => {
|
|
105
105
|
const header = `(Branch: ${pointInTime.branchId}`;
|
|
106
106
|
switch (pointInTime.tag) {
|
|
107
|
-
case
|
|
107
|
+
case "timestamp":
|
|
108
108
|
return `${header} at ${pointInTime.timestamp})`;
|
|
109
|
-
case
|
|
109
|
+
case "lsn":
|
|
110
110
|
return `${header} at ${pointInTime.lsn})`;
|
|
111
111
|
default:
|
|
112
112
|
return `${header})`;
|
|
@@ -133,7 +133,7 @@ export const parseSchemaDiffParams = async (props) => {
|
|
|
133
133
|
throw new Error(`No branch specified. Your context branch (${props.branch}) has no parent, so no comparison is possible.`);
|
|
134
134
|
}
|
|
135
135
|
log.info(`No branches specified. Comparing your context branch '${props.branch}' with its parent`);
|
|
136
|
-
props.compareSource =
|
|
136
|
+
props.compareSource = "^parent";
|
|
137
137
|
}
|
|
138
138
|
else {
|
|
139
139
|
const { data } = await props.apiClient.listProjectBranches({
|
|
@@ -141,10 +141,10 @@ export const parseSchemaDiffParams = async (props) => {
|
|
|
141
141
|
});
|
|
142
142
|
const defaultBranch = data.branches.find((b) => b.default);
|
|
143
143
|
if (defaultBranch?.parent_id == undefined) {
|
|
144
|
-
throw new Error(
|
|
144
|
+
throw new Error("No branch specified. Include a base branch or add a set-context branch to continue. Your default branch has no parent, so no comparison is possible.");
|
|
145
145
|
}
|
|
146
146
|
log.info(`No branches specified. Comparing default branch with its parent`);
|
|
147
|
-
props.compareSource =
|
|
147
|
+
props.compareSource = "^parent";
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
return props;
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { applyContext } from
|
|
2
|
-
import { log } from
|
|
3
|
-
export const command =
|
|
4
|
-
export const describe =
|
|
5
|
-
export const builder = (argv) => argv.usage(
|
|
6
|
-
|
|
7
|
-
describe:
|
|
8
|
-
type:
|
|
1
|
+
import { applyContext } from "../context.js";
|
|
2
|
+
import { log } from "../log.js";
|
|
3
|
+
export const command = "set-context";
|
|
4
|
+
export const describe = "Deprecated: use `neonctl link`. Set the .neon context (raw write).";
|
|
5
|
+
export const builder = (argv) => argv.usage("$0 set-context [options]").options({
|
|
6
|
+
"project-id": {
|
|
7
|
+
describe: "Project ID",
|
|
8
|
+
type: "string",
|
|
9
9
|
},
|
|
10
|
-
|
|
11
|
-
describe:
|
|
12
|
-
type:
|
|
10
|
+
"org-id": {
|
|
11
|
+
describe: "Organization ID",
|
|
12
|
+
type: "string",
|
|
13
13
|
},
|
|
14
|
-
|
|
15
|
-
describe:
|
|
16
|
-
type:
|
|
14
|
+
"branch-id": {
|
|
15
|
+
describe: "Branch ID",
|
|
16
|
+
type: "string",
|
|
17
17
|
},
|
|
18
18
|
});
|
|
19
19
|
export const handler = (props) => {
|
|
20
|
-
log.warning(
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
log.warning("`neonctl set-context` is deprecated and will be removed in a future release. " +
|
|
21
|
+
"Use `neonctl link` instead — it verifies inputs and infers the org for you " +
|
|
22
|
+
"(or `neonctl link --no-checks` for the same write-without-checks behavior).");
|
|
23
23
|
const context = {
|
|
24
24
|
projectId: props.projectId,
|
|
25
25
|
orgId: props.orgId,
|
package/dist/commands/status.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fillSingleProject } from
|
|
2
|
-
import { status } from
|
|
1
|
+
import { fillSingleProject } from "../utils/enrichers.js";
|
|
2
|
+
import { status } from "./config.js";
|
|
3
3
|
/**
|
|
4
4
|
* `neon status` is a top-level alias for `neon config status` — the most-reached-for
|
|
5
5
|
* config subcommand. It mirrors that command's options (including `--current-branch`,
|
|
@@ -9,30 +9,30 @@ import { status } from './config.js';
|
|
|
9
9
|
* `NO_SUBCOMMANDS_VERBS` (see index.ts) so the help-fallback middleware doesn't
|
|
10
10
|
* intercept a bare `neon status`.
|
|
11
11
|
*/
|
|
12
|
-
export const command =
|
|
12
|
+
export const command = "status";
|
|
13
13
|
export const describe = "Show the branch's live Neon state (alias of `config status`)";
|
|
14
14
|
export const builder = (argv) => argv
|
|
15
|
-
.usage(
|
|
15
|
+
.usage("$0 status [options]")
|
|
16
16
|
.options({
|
|
17
|
-
|
|
18
|
-
describe:
|
|
19
|
-
type:
|
|
17
|
+
"project-id": {
|
|
18
|
+
describe: "Project ID",
|
|
19
|
+
type: "string",
|
|
20
20
|
},
|
|
21
21
|
branch: {
|
|
22
|
-
describe:
|
|
23
|
-
type:
|
|
22
|
+
describe: "Branch ID or name",
|
|
23
|
+
type: "string",
|
|
24
24
|
},
|
|
25
|
-
|
|
25
|
+
"config-json": {
|
|
26
26
|
describe: "Print only the branch's live config as neon.ts-shaped JSON " +
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
type:
|
|
27
|
+
"(services + branch tuning + preview), to stdout. Useful for " +
|
|
28
|
+
"scripting or copying into a neon.ts.",
|
|
29
|
+
type: "boolean",
|
|
30
30
|
default: false,
|
|
31
31
|
},
|
|
32
|
-
|
|
33
|
-
describe:
|
|
34
|
-
|
|
35
|
-
type:
|
|
32
|
+
"current-branch": {
|
|
33
|
+
describe: "Print only the linked branch name from the local .neon file " +
|
|
34
|
+
"(no network). Exits non-zero when no branch is pinned.",
|
|
35
|
+
type: "boolean",
|
|
36
36
|
default: false,
|
|
37
37
|
},
|
|
38
38
|
})
|
package/dist/commands/user.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { writer } from
|
|
2
|
-
export const command =
|
|
3
|
-
export const describe =
|
|
4
|
-
export const builder = (yargs) => yargs.option(
|
|
1
|
+
import { writer } from "../writer.js";
|
|
2
|
+
export const command = "me";
|
|
3
|
+
export const describe = "Show current user";
|
|
4
|
+
export const builder = (yargs) => yargs.option("context-file", {
|
|
5
5
|
hidden: true,
|
|
6
6
|
});
|
|
7
7
|
export const handler = async (args) => {
|
|
@@ -10,6 +10,6 @@ export const handler = async (args) => {
|
|
|
10
10
|
const me = async (props) => {
|
|
11
11
|
const { data } = await props.apiClient.getCurrentUserInfo();
|
|
12
12
|
writer(props).end(data, {
|
|
13
|
-
fields: [
|
|
13
|
+
fields: ["login", "email", "name", "projects_limit"],
|
|
14
14
|
});
|
|
15
15
|
};
|
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
const VPC_ENDPOINT_FIELDS = [
|
|
1
|
+
import { log } from "../log.js";
|
|
2
|
+
import { fillSingleOrg, fillSingleProject } from "../utils/enrichers.js";
|
|
3
|
+
import { writer } from "../writer.js";
|
|
4
|
+
import { REGIONS } from "./projects.js";
|
|
5
|
+
const VPC_ENDPOINT_FIELDS = ["vpc_endpoint_id", "label"];
|
|
6
6
|
const VPC_ENDPOINT_DETAILS_FIELDS = [
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
"vpc_endpoint_id",
|
|
8
|
+
"label",
|
|
9
|
+
"state",
|
|
10
|
+
"num_restricted_projects",
|
|
11
|
+
"example_restricted_projects",
|
|
12
12
|
];
|
|
13
|
-
export const command =
|
|
14
|
-
export const describe =
|
|
13
|
+
export const command = "vpc";
|
|
14
|
+
export const describe = "Manage VPC endpoints and project VPC restrictions";
|
|
15
15
|
export const builder = (argv) => {
|
|
16
16
|
return argv
|
|
17
|
-
.usage(
|
|
18
|
-
.command(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
.usage("$0 vpc <sub-command> [options]")
|
|
18
|
+
.command("endpoint", "Manage VPC endpoints.\n" +
|
|
19
|
+
"See: https://neon.tech/docs/guides/neon-private-networking\n" +
|
|
20
|
+
"After adding an endpoint to an organization, client connections will be accepted\n" +
|
|
21
|
+
"from the corresponding VPC for all projects in the organization, unless overridden\n" +
|
|
22
|
+
"by a project-level VPC endpoint restriction.", (yargs) => {
|
|
23
23
|
return yargs
|
|
24
24
|
.options({
|
|
25
|
-
|
|
26
|
-
describe:
|
|
27
|
-
type:
|
|
25
|
+
"org-id": {
|
|
26
|
+
describe: "Organization ID",
|
|
27
|
+
type: "string",
|
|
28
28
|
},
|
|
29
|
-
|
|
30
|
-
describe: `The region ID. Possible values: ${REGIONS.join(
|
|
31
|
-
type:
|
|
29
|
+
"region-id": {
|
|
30
|
+
describe: `The region ID. Possible values: ${REGIONS.join(", ")}`,
|
|
31
|
+
type: "string",
|
|
32
32
|
demandOption: true,
|
|
33
33
|
},
|
|
34
34
|
})
|
|
35
35
|
.middleware(fillSingleOrg)
|
|
36
|
-
.command(
|
|
36
|
+
.command("list", "List configured VPC endpoints for this organization.", (yargs) => yargs, async (args) => {
|
|
37
37
|
await listOrg(args);
|
|
38
38
|
})
|
|
39
39
|
.command({
|
|
40
|
-
command:
|
|
41
|
-
aliases: [
|
|
42
|
-
describe:
|
|
43
|
-
|
|
40
|
+
command: "assign <id>",
|
|
41
|
+
aliases: ["update <id>", "add <id>"],
|
|
42
|
+
describe: "Add or update a VPC endpoint for this organization.\n" +
|
|
43
|
+
"Note: Azure regions are not yet supported.",
|
|
44
44
|
builder: (yargs) => yargs.options({
|
|
45
45
|
label: {
|
|
46
|
-
describe:
|
|
47
|
-
type:
|
|
46
|
+
describe: "An optional descriptive label for the VPC endpoint",
|
|
47
|
+
type: "string",
|
|
48
48
|
},
|
|
49
49
|
}),
|
|
50
50
|
handler: async (args) => {
|
|
51
51
|
await assignOrg(args);
|
|
52
52
|
},
|
|
53
53
|
})
|
|
54
|
-
.command(
|
|
54
|
+
.command("remove <id>", "Remove a VPC endpoint from this organization.", (yargs) => yargs, async (args) => {
|
|
55
55
|
await removeOrg(args);
|
|
56
56
|
})
|
|
57
|
-
.command(
|
|
57
|
+
.command("status <id>", "Get the status of a VPC endpoint for this organization.", (yargs) => yargs, async (args) => {
|
|
58
58
|
await statusOrg(args);
|
|
59
59
|
});
|
|
60
60
|
})
|
|
61
|
-
.command(
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
.command("project", "Manage project-level VPC endpoint restrictions.\n" +
|
|
62
|
+
"By default, connections are accepted from any VPC configured at the organization level.\n" +
|
|
63
|
+
"A project-level VPC endpoint restriction can be used to restrict connections to a specific VPC.", (yargs) => {
|
|
64
64
|
return yargs
|
|
65
65
|
.options({
|
|
66
|
-
|
|
67
|
-
describe:
|
|
68
|
-
type:
|
|
66
|
+
"project-id": {
|
|
67
|
+
describe: "Project ID",
|
|
68
|
+
type: "string",
|
|
69
69
|
},
|
|
70
70
|
})
|
|
71
71
|
.middleware(fillSingleProject)
|
|
72
|
-
.command(
|
|
72
|
+
.command("list", "List VPC endpoint restrictions for this project.", (yargs) => yargs, async (args) => {
|
|
73
73
|
await listProject(args);
|
|
74
74
|
})
|
|
75
75
|
.command({
|
|
76
|
-
command:
|
|
77
|
-
aliases: [
|
|
78
|
-
describe:
|
|
76
|
+
command: "restrict <id>",
|
|
77
|
+
aliases: ["update <id>"],
|
|
78
|
+
describe: "Configure or update a VPC endpoint restriction for this project.",
|
|
79
79
|
builder: (yargs) => yargs.options({
|
|
80
80
|
label: {
|
|
81
|
-
describe:
|
|
82
|
-
type:
|
|
81
|
+
describe: "An optional descriptive label for the VPC endpoint restriction",
|
|
82
|
+
type: "string",
|
|
83
83
|
},
|
|
84
84
|
}),
|
|
85
85
|
handler: async (args) => {
|
|
86
86
|
await assignProject(args);
|
|
87
87
|
},
|
|
88
88
|
})
|
|
89
|
-
.command(
|
|
89
|
+
.command("remove <id>", "Remove a VPC endpoint restriction from this project.", (yargs) => yargs, async (args) => {
|
|
90
90
|
await removeProject(args);
|
|
91
91
|
});
|
|
92
92
|
});
|
|
@@ -99,12 +99,12 @@ const listOrg = async (props) => {
|
|
|
99
99
|
};
|
|
100
100
|
const assignOrg = async (props) => {
|
|
101
101
|
const vpcEndpointAssignment = {
|
|
102
|
-
label: props.label ||
|
|
102
|
+
label: props.label || "",
|
|
103
103
|
};
|
|
104
104
|
const { data } = await props.apiClient.assignOrganizationVpcEndpoint(props.orgId, props.regionId, props.id, vpcEndpointAssignment);
|
|
105
105
|
writer(props).end(data, { fields: [] });
|
|
106
|
-
if (props.regionId.startsWith(
|
|
107
|
-
log.info(
|
|
106
|
+
if (props.regionId.startsWith("azure")) {
|
|
107
|
+
log.info("VPC endpoint configuration is not supported for Azure regions");
|
|
108
108
|
}
|
|
109
109
|
};
|
|
110
110
|
const removeOrg = async (props) => {
|
|
@@ -123,7 +123,7 @@ const listProject = async (props) => {
|
|
|
123
123
|
};
|
|
124
124
|
const assignProject = async (props) => {
|
|
125
125
|
const vpcEndpointAssignment = {
|
|
126
|
-
label: props.label ||
|
|
126
|
+
label: props.label || "",
|
|
127
127
|
};
|
|
128
128
|
const { data } = await props.apiClient.assignProjectVpcEndpoint(props.projectId, props.id, vpcEndpointAssignment);
|
|
129
129
|
writer(props).end(data, { fields: [] });
|
package/dist/config.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { homedir } from
|
|
3
|
-
import {
|
|
4
|
-
import { isCi } from
|
|
5
|
-
export const CREDENTIALS_FILE =
|
|
6
|
-
export const defaultDir = join(process.env.XDG_CONFIG_HOME || join(homedir(),
|
|
7
|
-
export const ensureConfigDir = ({
|
|
1
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { isCi } from "./env.js";
|
|
5
|
+
export const CREDENTIALS_FILE = "credentials.json";
|
|
6
|
+
export const defaultDir = join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "neonctl");
|
|
7
|
+
export const ensureConfigDir = ({ "config-dir": configDir, "force-auth": forceAuth, }) => {
|
|
8
8
|
if (!existsSync(configDir) && (!isCi() || forceAuth)) {
|
|
9
9
|
mkdirSync(configDir, { recursive: true });
|
|
10
10
|
}
|
package/dist/config_format.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Render a TTL in whole seconds back to the canonical `neon.ts` duration string (e.g.
|
|
3
3
|
* `604800` -> `"7d"`), falling back to seconds when no clean unit boundary matches. Mirrors
|
|
4
|
-
* the formatter `@
|
|
4
|
+
* the formatter `@neon/config` uses when it emits a TTL, so `config status` shows
|
|
5
5
|
* the same value a user would write in `neon.ts`.
|
|
6
6
|
*/
|
|
7
7
|
export const formatDurationSeconds = (totalSeconds) => {
|
|
8
8
|
const units = [
|
|
9
|
-
[
|
|
10
|
-
[
|
|
11
|
-
[
|
|
12
|
-
[
|
|
9
|
+
["w", 7 * 24 * 60 * 60],
|
|
10
|
+
["d", 24 * 60 * 60],
|
|
11
|
+
["h", 60 * 60],
|
|
12
|
+
["m", 60],
|
|
13
13
|
];
|
|
14
14
|
for (const [unit, perUnit] of units) {
|
|
15
15
|
if (totalSeconds % perUnit === 0)
|
package/dist/context.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { accessSync, existsSync, readFileSync, writeFileSync } from
|
|
2
|
-
import { homedir } from
|
|
3
|
-
import { dirname, normalize, resolve } from
|
|
4
|
-
import { log } from
|
|
1
|
+
import { accessSync, existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, normalize, resolve } from "node:path";
|
|
4
|
+
import { log } from "./log.js";
|
|
5
5
|
/**
|
|
6
6
|
* The branch pinned in a context, reading the current `branch` field and
|
|
7
7
|
* falling back to the legacy `branchId` so pre-migration `.neon` files keep
|
|
@@ -22,10 +22,17 @@ export const contextBranch = (context) => context.branch ?? context.branchId;
|
|
|
22
22
|
* `config status` (`_ = ['config', 'status']`).
|
|
23
23
|
*/
|
|
24
24
|
export const isCurrentBranchProbe = (args) => args.currentBranch === true &&
|
|
25
|
-
(args._[0] ===
|
|
26
|
-
(args._[0] ===
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
(args._[0] === "status" ||
|
|
26
|
+
(args._[0] === "config" && args._[1] === "status"));
|
|
27
|
+
/**
|
|
28
|
+
* `config init` only scaffolds a local `neon.ts` and installs npm packages — it
|
|
29
|
+
* never calls the Neon API. Gated on the exact command path so the global auth
|
|
30
|
+
* middleware and the single-project resolver can skip it (it runs with no API
|
|
31
|
+
* client), mirroring {@link isCurrentBranchProbe}.
|
|
32
|
+
*/
|
|
33
|
+
export const isConfigInit = (args) => args._[0] === "config" && args._[1] === "init";
|
|
34
|
+
const CONTEXT_FILE = ".neon";
|
|
35
|
+
const GITIGNORE_FILE = ".gitignore";
|
|
29
36
|
const wrapWithContextFile = (dir) => resolve(dir, CONTEXT_FILE);
|
|
30
37
|
/**
|
|
31
38
|
* Resolve the default `.neon` path for the current working directory.
|
|
@@ -47,7 +54,7 @@ const wrapWithContextFile = (dir) => resolve(dir, CONTEXT_FILE);
|
|
|
47
54
|
*/
|
|
48
55
|
export const currentContextFile = (cwd = process.cwd()) => {
|
|
49
56
|
let currentDir = cwd;
|
|
50
|
-
const root = normalize(
|
|
57
|
+
const root = normalize("/");
|
|
51
58
|
const home = homedir();
|
|
52
59
|
while (currentDir !== root && currentDir !== home) {
|
|
53
60
|
try {
|
|
@@ -57,13 +64,13 @@ export const currentContextFile = (cwd = process.cwd()) => {
|
|
|
57
64
|
catch {
|
|
58
65
|
// ignore
|
|
59
66
|
}
|
|
60
|
-
currentDir = resolve(currentDir,
|
|
67
|
+
currentDir = resolve(currentDir, "..");
|
|
61
68
|
}
|
|
62
69
|
return wrapWithContextFile(cwd);
|
|
63
70
|
};
|
|
64
71
|
export const readContextFile = (file) => {
|
|
65
72
|
try {
|
|
66
|
-
return JSON.parse(readFileSync(file,
|
|
73
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
67
74
|
}
|
|
68
75
|
catch {
|
|
69
76
|
return {};
|
|
@@ -73,7 +80,7 @@ export const enrichFromContext = (args) => {
|
|
|
73
80
|
// `link` and the deprecated `set-context` manage the context file themselves
|
|
74
81
|
// and must see the raw flags rather than values pre-filled from an existing
|
|
75
82
|
// `.neon`, so skip enrichment for both.
|
|
76
|
-
if (args._[0] ===
|
|
83
|
+
if (args._[0] === "link" || args._[0] === "set-context") {
|
|
77
84
|
return;
|
|
78
85
|
}
|
|
79
86
|
const context = readContextFile(args.contextFile);
|
|
@@ -148,17 +155,17 @@ export const ensureGitignored = (file) => {
|
|
|
148
155
|
writeFileSync(gitignorePath, `${entry}\n`);
|
|
149
156
|
return;
|
|
150
157
|
}
|
|
151
|
-
const current = readFileSync(gitignorePath,
|
|
158
|
+
const current = readFileSync(gitignorePath, "utf-8");
|
|
152
159
|
if (hasGitignoreEntry(current, entry)) {
|
|
153
160
|
return;
|
|
154
161
|
}
|
|
155
|
-
const needsLeadingNewline = current.length > 0 && !current.endsWith(
|
|
156
|
-
const addition = `${needsLeadingNewline ?
|
|
162
|
+
const needsLeadingNewline = current.length > 0 && !current.endsWith("\n");
|
|
163
|
+
const addition = `${needsLeadingNewline ? "\n" : ""}${entry}\n`;
|
|
157
164
|
writeFileSync(gitignorePath, current + addition);
|
|
158
165
|
}
|
|
159
166
|
catch (err) {
|
|
160
167
|
const message = err instanceof Error ? err.message : String(err);
|
|
161
|
-
log.debug(
|
|
168
|
+
log.debug("Failed to update .gitignore next to %s: %s", file, message);
|
|
162
169
|
}
|
|
163
170
|
};
|
|
164
171
|
const basenameOf = (file) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { contextBranch, currentContextFile, readContextFile } from
|
|
2
|
-
import { log } from
|
|
1
|
+
import { contextBranch, currentContextFile, readContextFile, } from "./context.js";
|
|
2
|
+
import { log } from "./log.js";
|
|
3
3
|
/**
|
|
4
4
|
* Offline fast path for `(config) status --current-branch` (used by shell prompts).
|
|
5
5
|
*
|
|
@@ -35,7 +35,7 @@ cwd = process.cwd()) => {
|
|
|
35
35
|
process.stdout.write(`${branch}\n`);
|
|
36
36
|
}
|
|
37
37
|
else {
|
|
38
|
-
log.info(
|
|
38
|
+
log.info("No branch pinned. Run `neonctl checkout <branch>` to pin a branch and pull its env vars.");
|
|
39
39
|
process.exitCode = 1;
|
|
40
40
|
}
|
|
41
41
|
return true;
|
|
@@ -46,10 +46,10 @@ cwd = process.cwd()) => {
|
|
|
46
46
|
* positional args) makes this false so the full CLI handles it.
|
|
47
47
|
*/
|
|
48
48
|
const isExactCurrentBranchInvocation = (args) => {
|
|
49
|
-
const rest = args[0] ===
|
|
49
|
+
const rest = args[0] === "status"
|
|
50
50
|
? args.slice(1)
|
|
51
|
-
: args[0] ===
|
|
51
|
+
: args[0] === "config" && args[1] === "status"
|
|
52
52
|
? args.slice(2)
|
|
53
53
|
: null;
|
|
54
|
-
return rest !== null && rest.length === 1 && rest[0] ===
|
|
54
|
+
return rest !== null && rest.length === 1 && rest[0] === "--current-branch";
|
|
55
55
|
};
|