neonctl 2.27.1 → 2.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -3
- package/dist/analytics.js +52 -34
- package/dist/api.js +643 -13
- package/dist/auth.js +50 -44
- package/dist/cli.js +8 -1
- package/dist/commands/auth.js +64 -51
- package/dist/commands/bootstrap.js +115 -157
- package/dist/commands/branches.js +160 -150
- package/dist/commands/bucket.js +183 -146
- package/dist/commands/checkout.js +51 -51
- package/dist/commands/config.js +228 -82
- package/dist/commands/connection_string.js +62 -62
- package/dist/commands/data_api.js +100 -101
- package/dist/commands/databases.js +29 -26
- 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 +101 -104
- package/dist/commands/index.js +27 -25
- package/dist/commands/init.js +23 -22
- package/dist/commands/ip_allow.js +29 -29
- package/dist/commands/link.js +232 -182
- package/dist/commands/neon_auth.js +385 -370
- package/dist/commands/operations.js +11 -11
- package/dist/commands/orgs.js +8 -8
- package/dist/commands/projects.js +103 -101
- package/dist/commands/psql.js +31 -31
- package/dist/commands/roles.js +27 -24
- package/dist/commands/schema_diff.js +25 -26
- package/dist/commands/set_context.js +17 -17
- package/dist/commands/status.js +40 -0
- 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 +37 -14
- package/dist/current_branch_fast_path.js +55 -0
- package/dist/dev/env.js +33 -33
- 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 +68 -5
- package/dist/functions_api.js +10 -10
- package/dist/help.js +15 -15
- package/dist/index.js +110 -107
- package/dist/log.js +2 -2
- package/dist/parameters.gen.js +14 -14
- 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 +22 -23
- package/dist/test_utils/fixtures.js +74 -41
- package/dist/test_utils/oauth_server.js +5 -5
- package/dist/utils/api_enums.js +33 -0
- 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 +28 -16
- 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 +10 -12
package/dist/help.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { consumeBlockIfMatches, consumeNextMatching, drawPointer, splitColumns, } from
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import cliui from "cliui";
|
|
3
|
+
import { consumeBlockIfMatches, consumeNextMatching, drawPointer, splitColumns, } from "./utils/ui.js";
|
|
4
4
|
// target width for the leftmost column
|
|
5
5
|
const SPACE_WIDTH = 20;
|
|
6
6
|
const formatHelp = (help) => {
|
|
7
|
-
const lines = help.split(
|
|
7
|
+
const lines = help.split("\n");
|
|
8
8
|
const result = [];
|
|
9
9
|
// full command, like `neonctl projects list`
|
|
10
10
|
const topLevelCommand = consumeNextMatching(lines, /^.*/);
|
|
11
11
|
if (topLevelCommand) {
|
|
12
|
-
result.push(chalk.bold(topLevelCommand.replace(
|
|
13
|
-
result.push(
|
|
12
|
+
result.push(chalk.bold(topLevelCommand.replace("[options]", chalk.reset.green("[options]"))));
|
|
13
|
+
result.push("");
|
|
14
14
|
}
|
|
15
15
|
// commands description block
|
|
16
16
|
// example command to see: neonctl projects
|
|
@@ -24,7 +24,7 @@ const formatHelp = (help) => {
|
|
|
24
24
|
commandsBlock.forEach((line) => {
|
|
25
25
|
if (/^\s{3,}/.exec(line)) {
|
|
26
26
|
ui.div({
|
|
27
|
-
text:
|
|
27
|
+
text: "",
|
|
28
28
|
width: SPACE_WIDTH,
|
|
29
29
|
padding: [0, 0, 0, 0],
|
|
30
30
|
}, { text: line.trim(), padding: [0, 0, 0, 0] });
|
|
@@ -44,7 +44,7 @@ const formatHelp = (help) => {
|
|
|
44
44
|
}, { text: description, padding: [0, 0, 0, 2] });
|
|
45
45
|
});
|
|
46
46
|
result.push(ui.toString());
|
|
47
|
-
result.push(
|
|
47
|
+
result.push("");
|
|
48
48
|
}
|
|
49
49
|
// positional args block
|
|
50
50
|
// example command to see: neonctl branches rename
|
|
@@ -67,14 +67,14 @@ const formatHelp = (help) => {
|
|
|
67
67
|
});
|
|
68
68
|
});
|
|
69
69
|
result.push(ui.toString());
|
|
70
|
-
result.push(
|
|
70
|
+
result.push("");
|
|
71
71
|
}
|
|
72
72
|
// command description
|
|
73
73
|
// example command to see: neonctl projects list
|
|
74
74
|
const descriptionBlock = consumeBlockIfMatches(lines, /^(?!.*options:)/i);
|
|
75
75
|
if (descriptionBlock.length > 0) {
|
|
76
76
|
result.push(...descriptionBlock);
|
|
77
|
-
result.push(
|
|
77
|
+
result.push("");
|
|
78
78
|
}
|
|
79
79
|
while (true) {
|
|
80
80
|
// there are two options blocks: global and specific
|
|
@@ -89,7 +89,7 @@ const formatHelp = (help) => {
|
|
|
89
89
|
const ui = cliui({
|
|
90
90
|
width: 0,
|
|
91
91
|
});
|
|
92
|
-
if (option.startsWith(
|
|
92
|
+
if (option.startsWith("-")) {
|
|
93
93
|
ui.div({
|
|
94
94
|
text: chalk.green(option),
|
|
95
95
|
padding: [0, 0, 0, 0],
|
|
@@ -99,14 +99,14 @@ const formatHelp = (help) => {
|
|
|
99
99
|
width: SPACE_WIDTH,
|
|
100
100
|
padding: [0, 2, 0, 0],
|
|
101
101
|
}, {
|
|
102
|
-
text: chalk.rgb(210, 210, 210)(description ??
|
|
102
|
+
text: chalk.rgb(210, 210, 210)(description ?? ""),
|
|
103
103
|
padding: [0, 0, 0, 0],
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
else {
|
|
107
107
|
ui.div({
|
|
108
108
|
padding: [0, 0, 0, 0],
|
|
109
|
-
text:
|
|
109
|
+
text: "",
|
|
110
110
|
width: SPACE_WIDTH,
|
|
111
111
|
}, {
|
|
112
112
|
text: chalk.rgb(210, 210, 210)(option),
|
|
@@ -115,7 +115,7 @@ const formatHelp = (help) => {
|
|
|
115
115
|
}
|
|
116
116
|
result.push(ui.toString());
|
|
117
117
|
});
|
|
118
|
-
result.push(
|
|
118
|
+
result.push("");
|
|
119
119
|
}
|
|
120
120
|
const exampleBlock = consumeBlockIfMatches(lines, /Examples:/);
|
|
121
121
|
if (exampleBlock.length > 0) {
|
|
@@ -141,6 +141,6 @@ const formatHelp = (help) => {
|
|
|
141
141
|
export const showHelp = async (argv) => {
|
|
142
142
|
// add wrap to ensure that there are no line breaks
|
|
143
143
|
const help = await argv.getHelp();
|
|
144
|
-
process.stderr.write(formatHelp(help).join(
|
|
144
|
+
process.stderr.write(formatHelp(help).join("\n") + "\n");
|
|
145
145
|
process.exit(0);
|
|
146
146
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,122 +1,111 @@
|
|
|
1
|
-
import { basename } from
|
|
2
|
-
import yargs from
|
|
3
|
-
import { hideBin } from
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
import { ensureAuth, deleteCredentials } from './commands/auth.js';
|
|
17
|
-
import { defaultDir, ensureConfigDir } from './config.js';
|
|
18
|
-
import { log } from './log.js';
|
|
19
|
-
import { defaultClientID } from './auth.js';
|
|
20
|
-
import { fillInArgs } from './utils/middlewares.js';
|
|
21
|
-
import pkg from './pkg.js';
|
|
22
|
-
import commands from './commands/index.js';
|
|
23
|
-
import { analyticsMiddleware, initAnalyticsClientMiddleware, closeAnalytics, getAnalyticsEventProperties, sendError, trackEvent, } from './analytics.js';
|
|
24
|
-
import { isAxiosError } from 'axios';
|
|
25
|
-
import { matchErrorCode } from './errors.js';
|
|
26
|
-
import { showHelp } from './help.js';
|
|
27
|
-
import { currentContextFile, enrichFromContext } from './context.js';
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
import yargs from "yargs";
|
|
3
|
+
import { hideBin } from "yargs/helpers";
|
|
4
|
+
import { analyticsMiddleware, closeAnalytics, getAnalyticsEventProperties, initAnalyticsClientMiddleware, sendError, trackEvent, } from "./analytics.js";
|
|
5
|
+
import { isNeonApiError, messageFromBody } from "./api.js";
|
|
6
|
+
import { defaultClientID } from "./auth.js";
|
|
7
|
+
import { deleteCredentials, ensureAuth } from "./commands/auth.js";
|
|
8
|
+
import commands from "./commands/index.js";
|
|
9
|
+
import { defaultDir, ensureConfigDir } from "./config.js";
|
|
10
|
+
import { currentContextFile, enrichFromContext } from "./context.js";
|
|
11
|
+
import { isNetworkError, matchErrorCode, NETWORK_ERROR_MESSAGE, } from "./errors.js";
|
|
12
|
+
import { showHelp } from "./help.js";
|
|
13
|
+
import { log } from "./log.js";
|
|
14
|
+
import pkg from "./pkg.js";
|
|
15
|
+
import { fillInArgs } from "./utils/middlewares.js";
|
|
28
16
|
const NO_SUBCOMMANDS_VERBS = [
|
|
29
17
|
// aliases
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// aliases
|
|
34
|
-
'cs',
|
|
35
|
-
'connection-string',
|
|
36
|
-
'psql',
|
|
37
|
-
'set-context',
|
|
38
|
-
'checkout',
|
|
39
|
-
'link',
|
|
40
|
-
'init',
|
|
41
|
-
'dev',
|
|
42
|
-
'deploy',
|
|
43
|
-
'bootstrap',
|
|
18
|
+
"auth",
|
|
19
|
+
"login",
|
|
20
|
+
"me",
|
|
44
21
|
// aliases
|
|
22
|
+
"cs",
|
|
23
|
+
"connection-string",
|
|
24
|
+
"psql",
|
|
25
|
+
"set-context",
|
|
26
|
+
"checkout",
|
|
27
|
+
"link",
|
|
28
|
+
"init",
|
|
29
|
+
"dev",
|
|
30
|
+
"deploy",
|
|
31
|
+
"bootstrap",
|
|
32
|
+
// alias of `config status`
|
|
33
|
+
"status",
|
|
45
34
|
];
|
|
46
35
|
let builder = yargs(hideBin(process.argv));
|
|
47
36
|
builder = builder
|
|
48
37
|
.scriptName(pkg.name)
|
|
49
|
-
.locale(
|
|
50
|
-
.usage(
|
|
38
|
+
.locale("en")
|
|
39
|
+
.usage("$0 <command> [options]")
|
|
51
40
|
.parserConfiguration({
|
|
52
|
-
|
|
41
|
+
"populate--": true,
|
|
53
42
|
})
|
|
54
43
|
.help()
|
|
55
|
-
.option(
|
|
56
|
-
alias:
|
|
57
|
-
group:
|
|
58
|
-
describe:
|
|
59
|
-
type:
|
|
60
|
-
choices: [
|
|
61
|
-
default:
|
|
44
|
+
.option("output", {
|
|
45
|
+
alias: "o",
|
|
46
|
+
group: "Global options:",
|
|
47
|
+
describe: "Set output format",
|
|
48
|
+
type: "string",
|
|
49
|
+
choices: ["json", "yaml", "table"],
|
|
50
|
+
default: "table",
|
|
62
51
|
})
|
|
63
|
-
.option(
|
|
64
|
-
describe:
|
|
52
|
+
.option("api-host", {
|
|
53
|
+
describe: "The API host",
|
|
65
54
|
hidden: true,
|
|
66
|
-
default: process.env.NEON_API_HOST ??
|
|
55
|
+
default: process.env.NEON_API_HOST ?? "https://console.neon.tech/api/v2",
|
|
67
56
|
})
|
|
68
57
|
// Setup config directory
|
|
69
|
-
.option(
|
|
70
|
-
describe:
|
|
71
|
-
group:
|
|
72
|
-
type:
|
|
58
|
+
.option("config-dir", {
|
|
59
|
+
describe: "Path to config directory",
|
|
60
|
+
group: "Global options:",
|
|
61
|
+
type: "string",
|
|
73
62
|
default: defaultDir,
|
|
74
63
|
})
|
|
75
|
-
.option(
|
|
76
|
-
describe:
|
|
77
|
-
type:
|
|
64
|
+
.option("force-auth", {
|
|
65
|
+
describe: "Force authentication",
|
|
66
|
+
type: "boolean",
|
|
78
67
|
hidden: true,
|
|
79
68
|
default: false,
|
|
80
69
|
})
|
|
81
70
|
.middleware(ensureConfigDir)
|
|
82
71
|
.options({
|
|
83
|
-
|
|
84
|
-
description:
|
|
72
|
+
"oauth-host": {
|
|
73
|
+
description: "URL to Neon OAuth host",
|
|
85
74
|
hidden: true,
|
|
86
|
-
default: process.env.NEON_OAUTH_HOST ??
|
|
75
|
+
default: process.env.NEON_OAUTH_HOST ?? "https://oauth2.neon.tech",
|
|
87
76
|
},
|
|
88
|
-
|
|
89
|
-
description:
|
|
77
|
+
"client-id": {
|
|
78
|
+
description: "OAuth client id",
|
|
90
79
|
hidden: true,
|
|
91
|
-
type:
|
|
80
|
+
type: "string",
|
|
92
81
|
default: defaultClientID,
|
|
93
82
|
},
|
|
94
|
-
|
|
95
|
-
describe:
|
|
96
|
-
group:
|
|
97
|
-
type:
|
|
98
|
-
default: process.env.NEON_API_KEY ??
|
|
83
|
+
"api-key": {
|
|
84
|
+
describe: "API key",
|
|
85
|
+
group: "Global options:",
|
|
86
|
+
type: "string",
|
|
87
|
+
default: process.env.NEON_API_KEY ?? "",
|
|
99
88
|
},
|
|
100
89
|
apiClient: {
|
|
101
90
|
hidden: true,
|
|
102
91
|
coerce: (v) => v,
|
|
103
92
|
default: null,
|
|
104
93
|
},
|
|
105
|
-
|
|
106
|
-
describe:
|
|
107
|
-
type:
|
|
94
|
+
"context-file": {
|
|
95
|
+
describe: "Context file",
|
|
96
|
+
type: "string",
|
|
108
97
|
default: currentContextFile,
|
|
109
98
|
},
|
|
110
99
|
color: {
|
|
111
|
-
group:
|
|
112
|
-
describe:
|
|
113
|
-
type:
|
|
100
|
+
group: "Global options:",
|
|
101
|
+
describe: "Colorize the output. Example: --no-color, --color false",
|
|
102
|
+
type: "boolean",
|
|
114
103
|
default: true,
|
|
115
104
|
},
|
|
116
105
|
analytics: {
|
|
117
|
-
describe:
|
|
118
|
-
group:
|
|
119
|
-
type:
|
|
106
|
+
describe: "Manage analytics. Example: --no-analytics, --analytics false",
|
|
107
|
+
group: "Global options:",
|
|
108
|
+
type: "boolean",
|
|
120
109
|
default: true,
|
|
121
110
|
},
|
|
122
111
|
})
|
|
@@ -125,13 +114,13 @@ builder = builder
|
|
|
125
114
|
}, true)
|
|
126
115
|
.middleware(initAnalyticsClientMiddleware, true)
|
|
127
116
|
.help(false)
|
|
128
|
-
.group(
|
|
129
|
-
.option(
|
|
130
|
-
describe:
|
|
131
|
-
type:
|
|
117
|
+
.group("help", "Global options:")
|
|
118
|
+
.option("help", {
|
|
119
|
+
describe: "Show help",
|
|
120
|
+
type: "boolean",
|
|
132
121
|
default: false,
|
|
133
122
|
})
|
|
134
|
-
.alias(
|
|
123
|
+
.alias("help", "h")
|
|
135
124
|
.middleware(async (args) => {
|
|
136
125
|
if (args.help ||
|
|
137
126
|
(args._.length === 1 &&
|
|
@@ -145,51 +134,65 @@ builder = builder
|
|
|
145
134
|
.command(commands)
|
|
146
135
|
.strictCommands()
|
|
147
136
|
.version(pkg.version)
|
|
148
|
-
.group(
|
|
149
|
-
.alias(
|
|
137
|
+
.group("version", "Global options:")
|
|
138
|
+
.alias("version", "v")
|
|
150
139
|
.completion()
|
|
151
|
-
.scriptName(basename(process.argv[1]) ===
|
|
152
|
-
.epilog(
|
|
140
|
+
.scriptName(basename(process.argv[1]) === "neon" ? "neon" : "neonctl")
|
|
141
|
+
.epilog("For more information, visit https://neon.com/docs/reference/neon-cli")
|
|
153
142
|
.wrap(null)
|
|
154
143
|
.fail(false);
|
|
155
144
|
async function handleError(msg, err) {
|
|
156
|
-
if (process.argv.some((arg) => arg ===
|
|
145
|
+
if (process.argv.some((arg) => arg === "--help" || arg === "-h")) {
|
|
157
146
|
await showHelp(builder);
|
|
158
147
|
process.exit(0);
|
|
159
148
|
}
|
|
160
149
|
// Log stack trace if available
|
|
161
150
|
if (err instanceof Error && err.stack) {
|
|
162
|
-
log.debug(
|
|
151
|
+
log.debug("Stack: %s", err.stack);
|
|
152
|
+
}
|
|
153
|
+
// A connection-level failure (no response ever reached us) reads as a cryptic
|
|
154
|
+
// `fetch failed` from the @neon/sdk / global `fetch` path. Detect it first and
|
|
155
|
+
// swap in one clear "check your connection" hint. We deliberately do not retry
|
|
156
|
+
// here: re-running the whole command could re-trigger a non-idempotent step
|
|
157
|
+
// (e.g. project create), so retries belong at the request layer.
|
|
158
|
+
if (isNetworkError(err)) {
|
|
159
|
+
log.error(NETWORK_ERROR_MESSAGE);
|
|
160
|
+
const error = err instanceof Error ? err : new Error(NETWORK_ERROR_MESSAGE);
|
|
161
|
+
sendError(error, "NETWORK_ERROR");
|
|
162
|
+
return false;
|
|
163
163
|
}
|
|
164
|
-
if (
|
|
165
|
-
if (err.code ===
|
|
166
|
-
log.error(
|
|
167
|
-
sendError(err,
|
|
164
|
+
if (isNeonApiError(err)) {
|
|
165
|
+
if (err.code === "ECONNABORTED") {
|
|
166
|
+
log.error("Request timed out");
|
|
167
|
+
sendError(err, "REQUEST_TIMEOUT");
|
|
168
168
|
return false;
|
|
169
169
|
}
|
|
170
|
-
else if (err.
|
|
171
|
-
sendError(err,
|
|
172
|
-
log.info(
|
|
170
|
+
else if (err.status === 401) {
|
|
171
|
+
sendError(err, "AUTH_FAILED");
|
|
172
|
+
log.info("Authentication failed, deleting credentials...");
|
|
173
173
|
try {
|
|
174
174
|
deleteCredentials(defaultDir);
|
|
175
175
|
return true; // Allow retry for auth failures
|
|
176
176
|
}
|
|
177
177
|
catch (deleteErr) {
|
|
178
|
-
log.debug(
|
|
178
|
+
log.debug("Failed to delete credentials: %s", deleteErr instanceof Error
|
|
179
|
+
? deleteErr.message
|
|
180
|
+
: "unknown error");
|
|
179
181
|
return false;
|
|
180
182
|
}
|
|
181
183
|
}
|
|
182
184
|
else {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
+
const serverMessage = messageFromBody(err.data);
|
|
186
|
+
if (serverMessage) {
|
|
187
|
+
log.error(serverMessage);
|
|
185
188
|
}
|
|
186
|
-
log.debug(
|
|
187
|
-
sendError(err,
|
|
189
|
+
log.debug("status: %d %s | path: %s", err.status, err.statusText, err.requestPath);
|
|
190
|
+
sendError(err, "API_ERROR");
|
|
188
191
|
return false;
|
|
189
192
|
}
|
|
190
193
|
}
|
|
191
194
|
else {
|
|
192
|
-
const error = err instanceof Error ? err : new Error(msg ||
|
|
195
|
+
const error = err instanceof Error ? err : new Error(msg || "Unknown error");
|
|
193
196
|
sendError(error, matchErrorCode(error.message));
|
|
194
197
|
log.error(error.message);
|
|
195
198
|
return false;
|
|
@@ -203,7 +206,7 @@ void (async () => {
|
|
|
203
206
|
try {
|
|
204
207
|
const args = await builder.argv;
|
|
205
208
|
// Send analytics for a successful attempt
|
|
206
|
-
trackEvent(
|
|
209
|
+
trackEvent("cli_command_success", {
|
|
207
210
|
...getAnalyticsEventProperties(args),
|
|
208
211
|
projectId: args.projectId,
|
|
209
212
|
branchId: args.branchId,
|
|
@@ -220,7 +223,7 @@ void (async () => {
|
|
|
220
223
|
}
|
|
221
224
|
catch (err) {
|
|
222
225
|
attempts++;
|
|
223
|
-
const shouldRetry = await handleError(
|
|
226
|
+
const shouldRetry = await handleError("", err);
|
|
224
227
|
if (!shouldRetry || attempts >= MAX_ATTEMPTS) {
|
|
225
228
|
await closeAnalytics();
|
|
226
229
|
process.exit(1);
|
package/dist/log.js
CHANGED
package/dist/parameters.gen.js
CHANGED
|
@@ -108,17 +108,17 @@ export const projectCreateRequest = {
|
|
|
108
108
|
},
|
|
109
109
|
'project.provisioner': {
|
|
110
110
|
type: "string",
|
|
111
|
-
description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
|
|
111
|
+
description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n* serverless-platform\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
|
|
112
112
|
demandOption: false,
|
|
113
113
|
},
|
|
114
114
|
'project.region_id': {
|
|
115
115
|
type: "string",
|
|
116
|
-
description: "The region identifier. Refer to our [Regions](https://neon.
|
|
116
|
+
description: "The region identifier. Refer to our [Regions](https://neon.com/docs/introduction/regions) documentation for supported regions. Values are specified in this format: `aws-us-east-1`\n",
|
|
117
117
|
demandOption: false,
|
|
118
118
|
},
|
|
119
119
|
'project.default_endpoint_settings.suspend_timeout_seconds': {
|
|
120
120
|
type: "number",
|
|
121
|
-
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.
|
|
121
|
+
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.com/docs/manage/endpoints#scale-to-zero-configuration).\n",
|
|
122
122
|
demandOption: false,
|
|
123
123
|
},
|
|
124
124
|
'project.pg_version': {
|
|
@@ -236,7 +236,7 @@ export const projectUpdateRequest = {
|
|
|
236
236
|
},
|
|
237
237
|
'project.default_endpoint_settings.suspend_timeout_seconds': {
|
|
238
238
|
type: "number",
|
|
239
|
-
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.
|
|
239
|
+
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.com/docs/manage/endpoints#scale-to-zero-configuration).\n",
|
|
240
240
|
demandOption: false,
|
|
241
241
|
},
|
|
242
242
|
'project.history_retention_seconds': {
|
|
@@ -311,12 +311,12 @@ export const branchCreateRequestEndpointOptions = {
|
|
|
311
311
|
},
|
|
312
312
|
'provisioner': {
|
|
313
313
|
type: "string",
|
|
314
|
-
description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
|
|
314
|
+
description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n* serverless-platform\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
|
|
315
315
|
demandOption: false,
|
|
316
316
|
},
|
|
317
317
|
'suspend_timeout_seconds': {
|
|
318
318
|
type: "number",
|
|
319
|
-
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.
|
|
319
|
+
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.com/docs/manage/endpoints#scale-to-zero-configuration).\n",
|
|
320
320
|
demandOption: false,
|
|
321
321
|
},
|
|
322
322
|
};
|
|
@@ -366,17 +366,17 @@ export const endpointCreateRequest = {
|
|
|
366
366
|
},
|
|
367
367
|
'endpoint.provisioner': {
|
|
368
368
|
type: "string",
|
|
369
|
-
description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
|
|
369
|
+
description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n* serverless-platform\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
|
|
370
370
|
demandOption: false,
|
|
371
371
|
},
|
|
372
372
|
'endpoint.pooler_enabled': {
|
|
373
373
|
type: "boolean",
|
|
374
|
-
description: "Whether to enable connection pooling for the compute endpoint\n",
|
|
374
|
+
description: "DEPRECATED. Whether to enable connection pooling for the compute endpoint.\nThe recommended way to enable connection pooling is to append `-pooler` to the endpoint ID in the connection string.\nSee [How to use connection pooling](https://neon.com/docs/connect/connection-pooling#how-to-use-connection-pooling)\n",
|
|
375
375
|
demandOption: false,
|
|
376
376
|
},
|
|
377
377
|
'endpoint.pooler_mode': {
|
|
378
378
|
type: "string",
|
|
379
|
-
description: "The connection pooler mode.
|
|
379
|
+
description: "DEPRECATED. The connection pooler mode. This field is deprecated and will be removed after 2026-06-20.\n",
|
|
380
380
|
demandOption: false,
|
|
381
381
|
choices: ["transaction"],
|
|
382
382
|
},
|
|
@@ -392,7 +392,7 @@ export const endpointCreateRequest = {
|
|
|
392
392
|
},
|
|
393
393
|
'endpoint.suspend_timeout_seconds': {
|
|
394
394
|
type: "number",
|
|
395
|
-
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.
|
|
395
|
+
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.com/docs/manage/endpoints#scale-to-zero-configuration).\n",
|
|
396
396
|
demandOption: false,
|
|
397
397
|
},
|
|
398
398
|
'endpoint.name': {
|
|
@@ -409,7 +409,7 @@ export const endpointUpdateRequest = {
|
|
|
409
409
|
},
|
|
410
410
|
'endpoint.provisioner': {
|
|
411
411
|
type: "string",
|
|
412
|
-
description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
|
|
412
|
+
description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n* serverless-platform\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
|
|
413
413
|
demandOption: false,
|
|
414
414
|
},
|
|
415
415
|
'endpoint.settings.preload_libraries.use_defaults': {
|
|
@@ -424,12 +424,12 @@ export const endpointUpdateRequest = {
|
|
|
424
424
|
},
|
|
425
425
|
'endpoint.pooler_enabled': {
|
|
426
426
|
type: "boolean",
|
|
427
|
-
description: "Whether to enable connection pooling for the compute endpoint\n",
|
|
427
|
+
description: "DEPRECATED. Whether to enable connection pooling for the compute endpoint.\nThe recommended way to enable connection pooling is to append `-pooler` to the endpoint ID in the connection string.\nSee [How to use connection pooling](https://neon.com/docs/connect/connection-pooling#how-to-use-connection-pooling)\n",
|
|
428
428
|
demandOption: false,
|
|
429
429
|
},
|
|
430
430
|
'endpoint.pooler_mode': {
|
|
431
431
|
type: "string",
|
|
432
|
-
description: "The connection pooler mode.
|
|
432
|
+
description: "DEPRECATED. The connection pooler mode. This field is deprecated and will be removed after 2026-06-20.\n",
|
|
433
433
|
demandOption: false,
|
|
434
434
|
choices: ["transaction"],
|
|
435
435
|
},
|
|
@@ -445,7 +445,7 @@ export const endpointUpdateRequest = {
|
|
|
445
445
|
},
|
|
446
446
|
'endpoint.suspend_timeout_seconds': {
|
|
447
447
|
type: "number",
|
|
448
|
-
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.
|
|
448
|
+
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Scale to zero configuration](https://neon.com/docs/manage/endpoints#scale-to-zero-configuration).\n",
|
|
449
449
|
demandOption: false,
|
|
450
450
|
},
|
|
451
451
|
'endpoint.name': {
|
package/dist/pkg.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { readFileSync } from
|
|
2
|
-
import { dirname, join } from
|
|
3
|
-
import { fileURLToPath } from
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
4
|
/**
|
|
5
5
|
* Load the CLI's package.json for version metadata. In the built CLI it sits right next to
|
|
6
6
|
* this module (the build copies it into `dist`); when running from source (tests, `tsx`) it
|
|
@@ -11,12 +11,12 @@ const loadPkg = () => {
|
|
|
11
11
|
let dir = dirname(fileURLToPath(import.meta.url));
|
|
12
12
|
for (;;) {
|
|
13
13
|
try {
|
|
14
|
-
return JSON.parse(readFileSync(join(dir,
|
|
14
|
+
return JSON.parse(readFileSync(join(dir, "package.json"), "utf-8"));
|
|
15
15
|
}
|
|
16
16
|
catch {
|
|
17
17
|
const parent = dirname(dir);
|
|
18
18
|
if (parent === dir) {
|
|
19
|
-
throw new Error(
|
|
19
|
+
throw new Error("Could not locate package.json for version detection.");
|
|
20
20
|
}
|
|
21
21
|
dir = parent;
|
|
22
22
|
}
|
package/dist/psql/cli.js
CHANGED
|
@@ -29,14 +29,16 @@
|
|
|
29
29
|
* EXIT_SUCCESS / EXIT_FAILURE / EXIT_USER / EXIT_BADCONN values; see
|
|
30
30
|
* `core/mainloop.ts`).
|
|
31
31
|
*/
|
|
32
|
-
import {
|
|
32
|
+
import { looksLikeConnectionString, runPsql } from "./index.js";
|
|
33
33
|
const main = async () => {
|
|
34
34
|
const raw = process.argv.slice(2);
|
|
35
35
|
// Detect whether the first arg is a connection URI/conninfo string.
|
|
36
36
|
// libpq's `recognized_connection_string()` covers both `postgres[ql]://…`
|
|
37
37
|
// URIs and bare `key=value` conninfo strings — `looksLikeConnectionString`
|
|
38
38
|
// mirrors that test.
|
|
39
|
-
const argv = raw.length > 0 && looksLikeConnectionString(raw[0])
|
|
39
|
+
const argv = raw.length > 0 && looksLikeConnectionString(raw[0])
|
|
40
|
+
? raw
|
|
41
|
+
: ["", ...raw];
|
|
40
42
|
const code = await runPsql(argv, {
|
|
41
43
|
stdin: process.stdin,
|
|
42
44
|
stdout: process.stdout,
|