neonctl 2.28.0 → 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 +2 -2
- 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 +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 +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
|
@@ -32,22 +32,22 @@
|
|
|
32
32
|
* - We do not eagerly read PSQLRC (the rc loader lives in a later WP).
|
|
33
33
|
* Instead we surface PSQLRC verbatim under the `PSQLRC` psql variable.
|
|
34
34
|
*/
|
|
35
|
-
export const DEFAULT_PROMPT1 =
|
|
36
|
-
export const DEFAULT_PROMPT2 =
|
|
37
|
-
export const DEFAULT_PROMPT3 =
|
|
38
|
-
export const DEFAULT_CSV_FIELD_SEP =
|
|
39
|
-
export const DEFAULT_FIELD_SEP =
|
|
40
|
-
export const DEFAULT_RECORD_SEP =
|
|
41
|
-
const DEFAULT_VERBOSITY =
|
|
42
|
-
const DEFAULT_SHOW_CONTEXT =
|
|
43
|
-
const DEFAULT_ECHO =
|
|
44
|
-
const DEFAULT_ECHO_HIDDEN =
|
|
45
|
-
const DEFAULT_ON_ERROR_ROLLBACK =
|
|
46
|
-
const DEFAULT_COMP_CASE =
|
|
47
|
-
const DEFAULT_SEND_MODE =
|
|
48
|
-
const DEFAULT_HIST_CONTROL =
|
|
35
|
+
export const DEFAULT_PROMPT1 = "%/%R%x%# ";
|
|
36
|
+
export const DEFAULT_PROMPT2 = "%/%R%x%# ";
|
|
37
|
+
export const DEFAULT_PROMPT3 = ">> ";
|
|
38
|
+
export const DEFAULT_CSV_FIELD_SEP = ",";
|
|
39
|
+
export const DEFAULT_FIELD_SEP = "|";
|
|
40
|
+
export const DEFAULT_RECORD_SEP = "\n";
|
|
41
|
+
const DEFAULT_VERBOSITY = "default";
|
|
42
|
+
const DEFAULT_SHOW_CONTEXT = "errors";
|
|
43
|
+
const DEFAULT_ECHO = "none";
|
|
44
|
+
const DEFAULT_ECHO_HIDDEN = "off";
|
|
45
|
+
const DEFAULT_ON_ERROR_ROLLBACK = "off";
|
|
46
|
+
const DEFAULT_COMP_CASE = "preserve-upper";
|
|
47
|
+
const DEFAULT_SEND_MODE = "extended-query";
|
|
48
|
+
const DEFAULT_HIST_CONTROL = "none";
|
|
49
49
|
/** Upstream `DEFAULT_WATCH_INTERVAL` from settings.h (psql 18). */
|
|
50
|
-
const DEFAULT_WATCH_INTERVAL =
|
|
50
|
+
const DEFAULT_WATCH_INTERVAL = "2";
|
|
51
51
|
/** Upstream `DEFAULT_WATCH_INTERVAL_MAX` (1e6 seconds). */
|
|
52
52
|
const WATCH_INTERVAL_MAX = 1000000;
|
|
53
53
|
/**
|
|
@@ -60,28 +60,28 @@ const WATCH_INTERVAL_MAX = 1000000;
|
|
|
60
60
|
*/
|
|
61
61
|
const buildDefaultPrintOpts = () => ({
|
|
62
62
|
topt: {
|
|
63
|
-
format:
|
|
64
|
-
expanded:
|
|
63
|
+
format: "aligned",
|
|
64
|
+
expanded: "off",
|
|
65
65
|
border: 1,
|
|
66
|
-
pager:
|
|
66
|
+
pager: "on",
|
|
67
67
|
pagerMinLines: 0,
|
|
68
68
|
tuplesOnly: false,
|
|
69
69
|
startTable: true,
|
|
70
70
|
stopTable: true,
|
|
71
71
|
defaultFooter: true,
|
|
72
72
|
prior: 0,
|
|
73
|
-
encoding:
|
|
73
|
+
encoding: "UTF8",
|
|
74
74
|
envColumns: 0,
|
|
75
75
|
columns: 0,
|
|
76
|
-
unicodeBorderLineStyle:
|
|
77
|
-
unicodeColumnLineStyle:
|
|
78
|
-
unicodeHeaderLineStyle:
|
|
76
|
+
unicodeBorderLineStyle: "ascii",
|
|
77
|
+
unicodeColumnLineStyle: "ascii",
|
|
78
|
+
unicodeHeaderLineStyle: "ascii",
|
|
79
79
|
// Upstream `popt.topt.unicode_{border,column,header}_linestyle` default
|
|
80
80
|
// to `UNICODE_LINESTYLE_SINGLE` (see `initialize_global_options` in
|
|
81
81
|
// `print.c`). Independent of `unicode*LineStyle` (ascii|unicode).
|
|
82
|
-
unicodeBorderStyle:
|
|
83
|
-
unicodeColumnStyle:
|
|
84
|
-
unicodeHeaderStyle:
|
|
82
|
+
unicodeBorderStyle: "single",
|
|
83
|
+
unicodeColumnStyle: "single",
|
|
84
|
+
unicodeHeaderStyle: "single",
|
|
85
85
|
fieldSep: DEFAULT_FIELD_SEP,
|
|
86
86
|
recordSep: DEFAULT_RECORD_SEP,
|
|
87
87
|
numericLocale: false,
|
|
@@ -90,14 +90,14 @@ const buildDefaultPrintOpts = () => ({
|
|
|
90
90
|
footers: null,
|
|
91
91
|
translateHeader: false,
|
|
92
92
|
translateColumns: null,
|
|
93
|
-
nullPrint:
|
|
93
|
+
nullPrint: "",
|
|
94
94
|
csvFieldSep: DEFAULT_CSV_FIELD_SEP,
|
|
95
95
|
// Upstream `pset.popt.topt.expanded_header_width_type =
|
|
96
96
|
// PRINT_XHEADER_FULL` — default rendered as the literal "full" in the
|
|
97
97
|
// bulk `\pset` view.
|
|
98
|
-
xheaderWidth:
|
|
98
|
+
xheaderWidth: "full",
|
|
99
99
|
},
|
|
100
|
-
nullPrint:
|
|
100
|
+
nullPrint: "",
|
|
101
101
|
title: null,
|
|
102
102
|
footers: null,
|
|
103
103
|
translateHeader: false,
|
|
@@ -123,7 +123,7 @@ export const defaultSettings = (varStore) => {
|
|
|
123
123
|
popt: buildDefaultPrintOpts(),
|
|
124
124
|
mainfile: null,
|
|
125
125
|
inputfile: null,
|
|
126
|
-
curCmdSource:
|
|
126
|
+
curCmdSource: "stdin",
|
|
127
127
|
restrictedKey: null,
|
|
128
128
|
prompt1: DEFAULT_PROMPT1,
|
|
129
129
|
prompt2: DEFAULT_PROMPT2,
|
|
@@ -147,29 +147,29 @@ export const defaultSettings = (varStore) => {
|
|
|
147
147
|
logfile: null,
|
|
148
148
|
timing: false,
|
|
149
149
|
lastErrorResult: null,
|
|
150
|
-
lastQuery:
|
|
150
|
+
lastQuery: "",
|
|
151
151
|
};
|
|
152
152
|
// Seed the PROMPT psql variables and wire them to the settings fields so
|
|
153
153
|
// `\set PROMPT1 …` is reflected in `settings.prompt1`. Upstream does this
|
|
154
154
|
// via assign hooks (prompt1_hook / prompt2_hook / prompt3_hook).
|
|
155
|
-
varStore.addHook(
|
|
156
|
-
settings.prompt1 = newValue ??
|
|
155
|
+
varStore.addHook("PROMPT1", (newValue) => {
|
|
156
|
+
settings.prompt1 = newValue ?? "";
|
|
157
157
|
return true;
|
|
158
158
|
});
|
|
159
|
-
varStore.addHook(
|
|
160
|
-
settings.prompt2 = newValue ??
|
|
159
|
+
varStore.addHook("PROMPT2", (newValue) => {
|
|
160
|
+
settings.prompt2 = newValue ?? "";
|
|
161
161
|
return true;
|
|
162
162
|
});
|
|
163
|
-
varStore.addHook(
|
|
164
|
-
settings.prompt3 = newValue ??
|
|
163
|
+
varStore.addHook("PROMPT3", (newValue) => {
|
|
164
|
+
settings.prompt3 = newValue ?? "";
|
|
165
165
|
return true;
|
|
166
166
|
});
|
|
167
|
-
varStore.set(
|
|
168
|
-
varStore.set(
|
|
169
|
-
varStore.set(
|
|
167
|
+
varStore.set("PROMPT1", DEFAULT_PROMPT1);
|
|
168
|
+
varStore.set("PROMPT2", DEFAULT_PROMPT2);
|
|
169
|
+
varStore.set("PROMPT3", DEFAULT_PROMPT3);
|
|
170
170
|
// Mirror upstream's small set of always-present session vars.
|
|
171
|
-
varStore.set(
|
|
172
|
-
varStore.set(
|
|
171
|
+
varStore.set("LAST_ERROR_MESSAGE", "");
|
|
172
|
+
varStore.set("LAST_ERROR_SQLSTATE", "00000");
|
|
173
173
|
// PIPELINE_SYNC_COUNT / PIPELINE_COMMAND_COUNT / PIPELINE_RESULT_COUNT —
|
|
174
174
|
// upstream `pset.piped_syncs` / `pset.piped_commands` / `pset.piped_results`
|
|
175
175
|
// are mirrored into psql variables of these names (used by `\echo
|
|
@@ -181,33 +181,33 @@ export const defaultSettings = (varStore) => {
|
|
|
181
181
|
// PIPELINE_SYNC_COUNT` actually drops the variable (verified empirically:
|
|
182
182
|
// `\echo :PIPELINE_SYNC_COUNT` then prints the literal `:NAME`). We
|
|
183
183
|
// mirror that here: plain seed, no hook.
|
|
184
|
-
varStore.set(
|
|
185
|
-
varStore.set(
|
|
186
|
-
varStore.set(
|
|
184
|
+
varStore.set("PIPELINE_SYNC_COUNT", "0");
|
|
185
|
+
varStore.set("PIPELINE_COMMAND_COUNT", "0");
|
|
186
|
+
varStore.set("PIPELINE_RESULT_COUNT", "0");
|
|
187
187
|
// SHOW_ALL_RESULTS defaults to 'on' — when off ('0' / 'off') the REPL only
|
|
188
188
|
// prints the final result set of a multi-statement `\;`-separated batch
|
|
189
189
|
// (upstream `pset.show_all_results`, set in startup.c).
|
|
190
|
-
varStore.set(
|
|
190
|
+
varStore.set("SHOW_ALL_RESULTS", "on");
|
|
191
191
|
// ENCODING tracks the server's client_encoding ParameterStatus. We seed
|
|
192
192
|
// with the connection-default UTF8 here; mainloop refreshes it after the
|
|
193
193
|
// connection is bound (and again whenever `SET client_encoding` flips the
|
|
194
194
|
// server value). Mirrors `pset.encoding` / `SetVariable("ENCODING", ...)`
|
|
195
195
|
// in upstream startup.c / common.c.
|
|
196
|
-
varStore.set(
|
|
196
|
+
varStore.set("ENCODING", "UTF8");
|
|
197
197
|
// WATCH_INTERVAL — upstream `watch_interval_substitute_hook` (null →
|
|
198
198
|
// DEFAULT_WATCH_INTERVAL "2") + `watch_interval_hook` which calls
|
|
199
199
|
// `ParseVariableDouble("WATCH_INTERVAL", ..., 0, DEFAULT_WATCH_INTERVAL_MAX)`.
|
|
200
200
|
// Empty value reaches ParseVariableDouble which short-circuits with
|
|
201
201
|
// "invalid input syntax for variable \"WATCH_INTERVAL\"" without
|
|
202
202
|
// substituting; the previous value is preserved by `trySet`.
|
|
203
|
-
varStore.addHook(
|
|
203
|
+
varStore.addHook("WATCH_INTERVAL", (newValue) => {
|
|
204
204
|
if (newValue === null) {
|
|
205
205
|
// `\unset WATCH_INTERVAL` re-seeds the default. The substitute also
|
|
206
206
|
// runs once on `addHook` registration so `\echo :WATCH_INTERVAL`
|
|
207
207
|
// prints "2" before the user touches it (no explicit seed needed).
|
|
208
208
|
return { substitute: DEFAULT_WATCH_INTERVAL };
|
|
209
209
|
}
|
|
210
|
-
if (newValue ===
|
|
210
|
+
if (newValue === "") {
|
|
211
211
|
return `invalid input syntax for variable "WATCH_INTERVAL"`;
|
|
212
212
|
}
|
|
213
213
|
const range = validateWatchInterval(newValue);
|
|
@@ -221,25 +221,25 @@ export const defaultSettings = (varStore) => {
|
|
|
221
221
|
// flag directly) and `--set ON_ERROR_STOP=1` (which only writes the
|
|
222
222
|
// variable) take effect. Empty value → "on" (substitute), non-boolean →
|
|
223
223
|
// reject with upstream's wording.
|
|
224
|
-
varStore.addHook(
|
|
224
|
+
varStore.addHook("ON_ERROR_STOP", makeBoolHook("ON_ERROR_STOP", (parsed) => {
|
|
225
225
|
settings.onErrorStop = parsed;
|
|
226
226
|
}));
|
|
227
227
|
// AUTOCOMMIT assign hook — upstream `bool_substitute_hook` +
|
|
228
228
|
// `autocommit_assign_hook`. Empty value → "on", non-boolean → reject
|
|
229
229
|
// with `unrecognized value "<value>" for "AUTOCOMMIT": Boolean expected`.
|
|
230
|
-
varStore.addHook(
|
|
230
|
+
varStore.addHook("AUTOCOMMIT", makeBoolHook("AUTOCOMMIT"));
|
|
231
231
|
// Seed AUTOCOMMIT to "on" (upstream default; pset.autocommit = true).
|
|
232
|
-
varStore.set(
|
|
232
|
+
varStore.set("AUTOCOMMIT", "on");
|
|
233
233
|
// FETCH_COUNT — upstream `fetch_count_substitute_hook` (null → "0") +
|
|
234
234
|
// `fetch_count_assign_hook` which delegates to `ParseVariableNum`. Empty
|
|
235
235
|
// `\set FETCH_COUNT` reaches ParseVariableNum which fails with
|
|
236
236
|
// `invalid value "" for "FETCH_COUNT": integer expected`, preserving
|
|
237
237
|
// the prior value. The substitute fires on addHook registration so
|
|
238
238
|
// `\echo :FETCH_COUNT` prints "0" before the user touches it.
|
|
239
|
-
varStore.addHook(
|
|
239
|
+
varStore.addHook("FETCH_COUNT", (newValue) => {
|
|
240
240
|
if (newValue === null) {
|
|
241
241
|
settings.fetchCount = 0;
|
|
242
|
-
return { substitute:
|
|
242
|
+
return { substitute: "0" };
|
|
243
243
|
}
|
|
244
244
|
const n = parseIntOrNull(newValue);
|
|
245
245
|
if (n === null) {
|
|
@@ -254,27 +254,27 @@ export const defaultSettings = (varStore) => {
|
|
|
254
254
|
// `unrecognized value "<value>" for "ON_ERROR_ROLLBACK"\nAvailable values
|
|
255
255
|
// are: on, off, interactive.`. The substitute on addHook seeds "off" so
|
|
256
256
|
// `\echo :ON_ERROR_ROLLBACK` works without explicit init.
|
|
257
|
-
varStore.addHook(
|
|
257
|
+
varStore.addHook("ON_ERROR_ROLLBACK", makeOnErrorRollbackHook((parsed) => {
|
|
258
258
|
settings.onErrorRollback = parsed;
|
|
259
259
|
}));
|
|
260
260
|
// VERBOSITY — upstream `verbosity_substitute_hook` (empty → "default")
|
|
261
261
|
// + `verbosity_assign_hook`. Accepts default | verbose | terse | sqlstate.
|
|
262
|
-
varStore.addHook(
|
|
262
|
+
varStore.addHook("VERBOSITY", makeEnumHook("VERBOSITY", ["default", "verbose", "terse", "sqlstate"], "default", (parsed) => {
|
|
263
263
|
settings.verbosity = parsed;
|
|
264
264
|
}));
|
|
265
265
|
// SHOW_CONTEXT — upstream `show_context_substitute_hook` (empty → "errors")
|
|
266
266
|
// + `show_context_assign_hook`. Accepts never | errors | always.
|
|
267
|
-
varStore.addHook(
|
|
267
|
+
varStore.addHook("SHOW_CONTEXT", makeEnumHook("SHOW_CONTEXT", ["never", "errors", "always"], "errors", (parsed) => {
|
|
268
268
|
settings.showContext = parsed;
|
|
269
269
|
}));
|
|
270
270
|
// ECHO — upstream `echo_substitute_hook` (empty → "none") +
|
|
271
271
|
// `echo_assign_hook`. Accepts none | errors | queries | all.
|
|
272
|
-
varStore.addHook(
|
|
272
|
+
varStore.addHook("ECHO", makeEnumHook("ECHO", ["none", "errors", "queries", "all"], "none", (parsed) => {
|
|
273
273
|
settings.echo = parsed;
|
|
274
274
|
}));
|
|
275
275
|
// ECHO_HIDDEN — upstream `bool_substitute_hook` +
|
|
276
276
|
// `echo_hidden_assign_hook`. Tri-state: on / off / noexec. Empty → "on".
|
|
277
|
-
varStore.addHook(
|
|
277
|
+
varStore.addHook("ECHO_HIDDEN", makeEchoHiddenHook((parsed) => {
|
|
278
278
|
settings.echoHidden = parsed;
|
|
279
279
|
}));
|
|
280
280
|
// COMP_KEYWORD_CASE assign hook. Upstream `assign_var_comp_keyword_case_hook`
|
|
@@ -284,44 +284,44 @@ export const defaultSettings = (varStore) => {
|
|
|
284
284
|
// diagnostic wording is `unrecognized value "<value>" for
|
|
285
285
|
// "COMP_KEYWORD_CASE"\nAvailable values are: lower, upper, preserve-lower,
|
|
286
286
|
// preserve-upper.`.
|
|
287
|
-
varStore.addHook(
|
|
287
|
+
varStore.addHook("COMP_KEYWORD_CASE", makeEnumHook("COMP_KEYWORD_CASE", ["lower", "upper", "preserve-lower", "preserve-upper"], DEFAULT_COMP_CASE, (parsed) => {
|
|
288
288
|
settings.compCase = parsed;
|
|
289
289
|
}));
|
|
290
290
|
// HISTCONTROL — upstream `histcontrol_substitute_hook` (empty → "none") +
|
|
291
291
|
// `histcontrol_assign_hook`. Accepts ignorespace | ignoredups | ignoreboth
|
|
292
292
|
// | none.
|
|
293
|
-
varStore.addHook(
|
|
293
|
+
varStore.addHook("HISTCONTROL", makeEnumHook("HISTCONTROL", ["none", "ignorespace", "ignoredups", "ignoreboth"], "none", (parsed) => {
|
|
294
294
|
settings.histControl = parsed;
|
|
295
295
|
}));
|
|
296
296
|
// SHOW_ALL_RESULTS — upstream `bool_substitute_hook` +
|
|
297
297
|
// `show_all_results_assign_hook`. Strict boolean; empty → "on".
|
|
298
|
-
varStore.addHook(
|
|
298
|
+
varStore.addHook("SHOW_ALL_RESULTS", makeBoolHook("SHOW_ALL_RESULTS"));
|
|
299
299
|
// QUIET — upstream `bool_substitute_hook` + `quiet_hook`. Mirrors into
|
|
300
300
|
// `pset.quiet`. Default ("off") matches the unset substitute, so addHook
|
|
301
301
|
// registration seeds it via the substitute.
|
|
302
|
-
varStore.addHook(
|
|
302
|
+
varStore.addHook("QUIET", makeBoolHook("QUIET", (parsed) => {
|
|
303
303
|
settings.quiet = parsed;
|
|
304
304
|
}));
|
|
305
305
|
// SINGLELINE — upstream `bool_substitute_hook` + `singleline_hook`.
|
|
306
306
|
// Mirrors into `pset.singleline`.
|
|
307
|
-
varStore.addHook(
|
|
307
|
+
varStore.addHook("SINGLELINE", makeBoolHook("SINGLELINE", (parsed) => {
|
|
308
308
|
settings.singleline = parsed;
|
|
309
309
|
}));
|
|
310
310
|
// SINGLESTEP — upstream `bool_substitute_hook` + `singlestep_hook`.
|
|
311
311
|
// Mirrors into `pset.singlestep`.
|
|
312
|
-
varStore.addHook(
|
|
312
|
+
varStore.addHook("SINGLESTEP", makeBoolHook("SINGLESTEP", (parsed) => {
|
|
313
313
|
settings.singlestep = parsed;
|
|
314
314
|
}));
|
|
315
315
|
// HIDE_TOAST_COMPRESSION — upstream `bool_substitute_hook` +
|
|
316
316
|
// `hide_compression_hook`. Mirrors into `pset.hide_compression` (our
|
|
317
317
|
// `settings.hideCompression`). Note: the upstream variable name is
|
|
318
318
|
// HIDE_TOAST_COMPRESSION, not HIDE_COMPRESSION.
|
|
319
|
-
varStore.addHook(
|
|
319
|
+
varStore.addHook("HIDE_TOAST_COMPRESSION", makeBoolHook("HIDE_TOAST_COMPRESSION", (parsed) => {
|
|
320
320
|
settings.hideCompression = parsed;
|
|
321
321
|
}));
|
|
322
322
|
// HIDE_TABLEAM — upstream `bool_substitute_hook` + `hide_tableam_hook`.
|
|
323
323
|
// Mirrors into `pset.hide_tableam` (our `settings.hideTableam`).
|
|
324
|
-
varStore.addHook(
|
|
324
|
+
varStore.addHook("HIDE_TABLEAM", makeBoolHook("HIDE_TABLEAM", (parsed) => {
|
|
325
325
|
settings.hideTableam = parsed;
|
|
326
326
|
}));
|
|
327
327
|
// HISTSIZE — upstream `histsize_substitute_hook` (null → "500") +
|
|
@@ -331,9 +331,9 @@ export const defaultSettings = (varStore) => {
|
|
|
331
331
|
// (readline isn't implemented), but we still install the hook so the
|
|
332
332
|
// variable surface matches vanilla: `\echo :HISTSIZE` prints "500" on
|
|
333
333
|
// startup, accepts integer values, rejects junk.
|
|
334
|
-
varStore.addHook(
|
|
334
|
+
varStore.addHook("HISTSIZE", (newValue) => {
|
|
335
335
|
if (newValue === null) {
|
|
336
|
-
return { substitute:
|
|
336
|
+
return { substitute: "500" };
|
|
337
337
|
}
|
|
338
338
|
const n = parseIntOrNull(newValue);
|
|
339
339
|
if (n === null) {
|
|
@@ -355,12 +355,12 @@ export const defaultSettings = (varStore) => {
|
|
|
355
355
|
// resubstitutes "0". This is the key behavior the regress/psql `\gset
|
|
356
356
|
// IGNORE` test relies on (it expects `:IGNOREEOF` to render "0" even
|
|
357
357
|
// though `\gset` rejected the assignment as specially-treated).
|
|
358
|
-
varStore.addHook(
|
|
358
|
+
varStore.addHook("IGNOREEOF", (newValue) => {
|
|
359
359
|
if (newValue === null) {
|
|
360
|
-
return { substitute:
|
|
360
|
+
return { substitute: "0" };
|
|
361
361
|
}
|
|
362
362
|
if (parseStrtolBase0OrNull(newValue) === null) {
|
|
363
|
-
return { substitute:
|
|
363
|
+
return { substitute: "10" };
|
|
364
364
|
}
|
|
365
365
|
return true;
|
|
366
366
|
});
|
|
@@ -386,13 +386,13 @@ const makeBoolHook = (name, apply) => {
|
|
|
386
386
|
// `:NAME` token. Verified empirically against vanilla psql 18:
|
|
387
387
|
// `\unset AUTOCOMMIT; \echo :AUTOCOMMIT` prints "off".
|
|
388
388
|
apply?.(false);
|
|
389
|
-
return { substitute:
|
|
389
|
+
return { substitute: "off" };
|
|
390
390
|
}
|
|
391
|
-
if (newValue ===
|
|
391
|
+
if (newValue === "") {
|
|
392
392
|
// `\set NAME` (empty value) substitutes "on". Verified empirically:
|
|
393
393
|
// `\set AUTOCOMMIT; \echo :AUTOCOMMIT` prints "on".
|
|
394
394
|
apply?.(true);
|
|
395
|
-
return { substitute:
|
|
395
|
+
return { substitute: "on" };
|
|
396
396
|
}
|
|
397
397
|
const parsed = parseOnOffBool(newValue);
|
|
398
398
|
if (parsed === null) {
|
|
@@ -418,7 +418,7 @@ const makeBoolHook = (name, apply) => {
|
|
|
418
418
|
* variable is set (including the default-on-null path).
|
|
419
419
|
*/
|
|
420
420
|
const makeEnumHook = (name, allowed, defaultValue, apply) => {
|
|
421
|
-
const list = allowed.join(
|
|
421
|
+
const list = allowed.join(", ");
|
|
422
422
|
return (newValue) => {
|
|
423
423
|
if (newValue === null) {
|
|
424
424
|
apply?.(defaultValue);
|
|
@@ -447,15 +447,15 @@ const makeOnErrorRollbackHook = (apply) => {
|
|
|
447
447
|
// — `\unset ON_ERROR_ROLLBACK` re-stores "off" so a follow-on
|
|
448
448
|
// `\echo :ON_ERROR_ROLLBACK` shows the default rather than the
|
|
449
449
|
// literal `:NAME` token.
|
|
450
|
-
apply(
|
|
451
|
-
return { substitute:
|
|
450
|
+
apply("off");
|
|
451
|
+
return { substitute: "off" };
|
|
452
452
|
}
|
|
453
|
-
if (newValue ===
|
|
454
|
-
apply(
|
|
455
|
-
return { substitute:
|
|
453
|
+
if (newValue === "") {
|
|
454
|
+
apply("on");
|
|
455
|
+
return { substitute: "on" };
|
|
456
456
|
}
|
|
457
457
|
const lower = newValue.toLowerCase();
|
|
458
|
-
if (lower ===
|
|
458
|
+
if (lower === "on" || lower === "off" || lower === "interactive") {
|
|
459
459
|
apply(lower);
|
|
460
460
|
return true;
|
|
461
461
|
}
|
|
@@ -474,23 +474,23 @@ const makeEchoHiddenHook = (apply) => {
|
|
|
474
474
|
if (newValue === null) {
|
|
475
475
|
// Match `bool_substitute_hook(NULL)` → "off". On addHook registration
|
|
476
476
|
// this seeds `\echo :ECHO_HIDDEN` → "off" (parity with vanilla).
|
|
477
|
-
apply(
|
|
478
|
-
return { substitute:
|
|
477
|
+
apply("off");
|
|
478
|
+
return { substitute: "off" };
|
|
479
479
|
}
|
|
480
|
-
if (newValue ===
|
|
481
|
-
apply(
|
|
482
|
-
return { substitute:
|
|
480
|
+
if (newValue === "") {
|
|
481
|
+
apply("on");
|
|
482
|
+
return { substitute: "on" };
|
|
483
483
|
}
|
|
484
484
|
const lower = newValue.toLowerCase();
|
|
485
|
-
if (lower ===
|
|
486
|
-
apply(
|
|
485
|
+
if (lower === "noexec") {
|
|
486
|
+
apply("noexec");
|
|
487
487
|
return true;
|
|
488
488
|
}
|
|
489
489
|
const parsed = parseOnOffBool(newValue);
|
|
490
490
|
if (parsed === null) {
|
|
491
491
|
return `unrecognized value "${newValue}" for "ECHO_HIDDEN"\nAvailable values are: on, off, noexec.`;
|
|
492
492
|
}
|
|
493
|
-
apply(parsed ?
|
|
493
|
+
apply(parsed ? "on" : "off");
|
|
494
494
|
return true;
|
|
495
495
|
};
|
|
496
496
|
};
|
|
@@ -525,26 +525,26 @@ const parseIntOrNull = (raw) => {
|
|
|
525
525
|
*/
|
|
526
526
|
const parseStrtolBase0OrNull = (raw) => {
|
|
527
527
|
// strtol skips leading whitespace; mirror that.
|
|
528
|
-
const trimmed = raw.replace(/^\s+/,
|
|
528
|
+
const trimmed = raw.replace(/^\s+/, "");
|
|
529
529
|
if (trimmed.length === 0)
|
|
530
530
|
return null;
|
|
531
531
|
let body = trimmed;
|
|
532
532
|
let sign = 1;
|
|
533
|
-
if (body.startsWith(
|
|
533
|
+
if (body.startsWith("+")) {
|
|
534
534
|
body = body.slice(1);
|
|
535
535
|
}
|
|
536
|
-
else if (body.startsWith(
|
|
536
|
+
else if (body.startsWith("-")) {
|
|
537
537
|
sign = -1;
|
|
538
538
|
body = body.slice(1);
|
|
539
539
|
}
|
|
540
540
|
if (body.length === 0)
|
|
541
541
|
return null;
|
|
542
542
|
let radix = 10;
|
|
543
|
-
if (body.startsWith(
|
|
543
|
+
if (body.startsWith("0x") || body.startsWith("0X")) {
|
|
544
544
|
radix = 16;
|
|
545
545
|
body = body.slice(2);
|
|
546
546
|
}
|
|
547
|
-
else if (body.length > 1 && body.startsWith(
|
|
547
|
+
else if (body.length > 1 && body.startsWith("0")) {
|
|
548
548
|
// Leading zero on a multi-char body → octal (matches strtol base 0).
|
|
549
549
|
radix = 8;
|
|
550
550
|
body = body.slice(1);
|
|
@@ -571,10 +571,10 @@ const parseStrtolBase0OrNull = (raw) => {
|
|
|
571
571
|
*/
|
|
572
572
|
const parseOnOffBool = (raw) => {
|
|
573
573
|
const v = raw.toLowerCase().trim();
|
|
574
|
-
if (v ===
|
|
574
|
+
if (v === "" || v === "on" || v === "true" || v === "yes" || v === "1") {
|
|
575
575
|
return true;
|
|
576
576
|
}
|
|
577
|
-
if (v ===
|
|
577
|
+
if (v === "off" || v === "false" || v === "no" || v === "0") {
|
|
578
578
|
return false;
|
|
579
579
|
}
|
|
580
580
|
return null;
|
|
@@ -645,37 +645,37 @@ const validateWatchInterval = (raw) => {
|
|
|
645
645
|
export const applyEnvOverrides = (settings, env = process.env) => {
|
|
646
646
|
const bridge = (envName, varName) => {
|
|
647
647
|
const value = env[envName];
|
|
648
|
-
if (value !== undefined && value !==
|
|
648
|
+
if (value !== undefined && value !== "") {
|
|
649
649
|
settings.vars.set(varName, value);
|
|
650
650
|
}
|
|
651
651
|
};
|
|
652
652
|
// Pager group: PSQL_PAGER takes precedence over PAGER in psql, so set
|
|
653
653
|
// PAGER first and let PSQL_PAGER overwrite it.
|
|
654
|
-
bridge(
|
|
655
|
-
bridge(
|
|
656
|
-
bridge(
|
|
654
|
+
bridge("PAGER", "PAGER");
|
|
655
|
+
bridge("PSQL_PAGER", "PAGER");
|
|
656
|
+
bridge("PSQL_WATCH_PAGER", "PSQL_WATCH_PAGER");
|
|
657
657
|
// Editor group: PSQL_EDITOR > VISUAL > EDITOR in psql. Set in
|
|
658
658
|
// lowest-to-highest precedence so the final wins.
|
|
659
|
-
bridge(
|
|
660
|
-
bridge(
|
|
661
|
-
bridge(
|
|
662
|
-
bridge(
|
|
659
|
+
bridge("EDITOR", "EDITOR");
|
|
660
|
+
bridge("VISUAL", "EDITOR");
|
|
661
|
+
bridge("PSQL_EDITOR", "EDITOR");
|
|
662
|
+
bridge("PSQL_EDITOR_LINENUMBER_ARG", "EDITOR_LINENUMBER_ARG");
|
|
663
663
|
// History group.
|
|
664
|
-
bridge(
|
|
665
|
-
bridge(
|
|
666
|
-
bridge(
|
|
664
|
+
bridge("PSQL_HISTORY", "HISTFILE");
|
|
665
|
+
bridge("PSQL_HISTSIZE", "HISTSIZE");
|
|
666
|
+
bridge("PSQL_HISTCONTROL", "HISTCONTROL");
|
|
667
667
|
// RC file path.
|
|
668
|
-
bridge(
|
|
668
|
+
bridge("PSQLRC", "PSQLRC");
|
|
669
669
|
// NO_COLOR — captured under a psql-style var name. The convention is
|
|
670
670
|
// "any non-empty value disables color". We store the raw value so the
|
|
671
671
|
// printer can decide via VarStore.asBool / its own check.
|
|
672
|
-
if (env.NO_COLOR !== undefined && env.NO_COLOR !==
|
|
673
|
-
settings.vars.set(
|
|
672
|
+
if (env.NO_COLOR !== undefined && env.NO_COLOR !== "") {
|
|
673
|
+
settings.vars.set("NO_COLOR", env.NO_COLOR);
|
|
674
674
|
}
|
|
675
675
|
// COLUMNS — feed into popt.topt.envColumns (upstream:
|
|
676
676
|
// pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(...) : 0).
|
|
677
677
|
const cols = env.COLUMNS;
|
|
678
|
-
if (cols !== undefined && cols !==
|
|
678
|
+
if (cols !== undefined && cols !== "") {
|
|
679
679
|
const parsed = parseInt(cols, 10);
|
|
680
680
|
if (Number.isFinite(parsed) && parsed >= 0) {
|
|
681
681
|
settings.popt.topt.envColumns = parsed;
|