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.
Files changed (135) hide show
  1. package/README.md +71 -71
  2. package/dist/analytics.js +35 -33
  3. package/dist/api.js +34 -34
  4. package/dist/auth.js +50 -44
  5. package/dist/cli.js +2 -2
  6. package/dist/commands/auth.js +58 -52
  7. package/dist/commands/bootstrap.js +115 -157
  8. package/dist/commands/branches.js +154 -147
  9. package/dist/commands/bucket.js +124 -118
  10. package/dist/commands/checkout.js +49 -49
  11. package/dist/commands/config.js +212 -88
  12. package/dist/commands/connection_string.js +62 -62
  13. package/dist/commands/data_api.js +96 -96
  14. package/dist/commands/databases.js +23 -23
  15. package/dist/commands/deploy.js +12 -12
  16. package/dist/commands/dev.js +114 -114
  17. package/dist/commands/env.js +43 -43
  18. package/dist/commands/functions.js +97 -98
  19. package/dist/commands/index.js +26 -26
  20. package/dist/commands/init.js +23 -22
  21. package/dist/commands/ip_allow.js +29 -29
  22. package/dist/commands/link.js +223 -166
  23. package/dist/commands/neon_auth.js +381 -363
  24. package/dist/commands/operations.js +11 -11
  25. package/dist/commands/orgs.js +8 -8
  26. package/dist/commands/projects.js +101 -99
  27. package/dist/commands/psql.js +31 -31
  28. package/dist/commands/roles.js +21 -21
  29. package/dist/commands/schema_diff.js +23 -23
  30. package/dist/commands/set_context.js +17 -17
  31. package/dist/commands/status.js +17 -17
  32. package/dist/commands/user.js +5 -5
  33. package/dist/commands/vpc_endpoints.js +50 -50
  34. package/dist/config.js +7 -7
  35. package/dist/config_format.js +5 -5
  36. package/dist/context.js +23 -16
  37. package/dist/current_branch_fast_path.js +6 -6
  38. package/dist/dev/env.js +34 -34
  39. package/dist/dev/functions.js +4 -4
  40. package/dist/dev/inputs.js +6 -6
  41. package/dist/dev/runtime.js +25 -25
  42. package/dist/env.js +14 -14
  43. package/dist/env_file.js +13 -13
  44. package/dist/errors.js +19 -19
  45. package/dist/functions_api.js +10 -10
  46. package/dist/help.js +15 -15
  47. package/dist/index.js +94 -92
  48. package/dist/log.js +2 -2
  49. package/dist/pkg.js +5 -5
  50. package/dist/psql/cli.js +4 -2
  51. package/dist/psql/command/cmd_cond.js +61 -61
  52. package/dist/psql/command/cmd_connect.js +159 -154
  53. package/dist/psql/command/cmd_copy.js +107 -97
  54. package/dist/psql/command/cmd_describe.js +368 -363
  55. package/dist/psql/command/cmd_format.js +276 -263
  56. package/dist/psql/command/cmd_io.js +269 -263
  57. package/dist/psql/command/cmd_lo.js +74 -66
  58. package/dist/psql/command/cmd_meta.js +148 -148
  59. package/dist/psql/command/cmd_misc.js +17 -17
  60. package/dist/psql/command/cmd_pipeline.js +142 -135
  61. package/dist/psql/command/cmd_restrict.js +25 -25
  62. package/dist/psql/command/cmd_show.js +183 -168
  63. package/dist/psql/command/dispatch.js +26 -26
  64. package/dist/psql/command/shared.js +14 -14
  65. package/dist/psql/complete/filenames.js +16 -16
  66. package/dist/psql/complete/index.js +4 -4
  67. package/dist/psql/complete/matcher.js +33 -32
  68. package/dist/psql/complete/psqlVars.js +173 -173
  69. package/dist/psql/complete/queries.js +5 -3
  70. package/dist/psql/complete/rules.js +900 -863
  71. package/dist/psql/core/common.js +136 -133
  72. package/dist/psql/core/help.js +343 -343
  73. package/dist/psql/core/mainloop.js +160 -153
  74. package/dist/psql/core/prompt.js +126 -123
  75. package/dist/psql/core/settings.js +111 -111
  76. package/dist/psql/core/sqlHelp.js +150 -150
  77. package/dist/psql/core/startup.js +211 -205
  78. package/dist/psql/core/syncVars.js +14 -14
  79. package/dist/psql/core/variables.js +24 -24
  80. package/dist/psql/describe/formatters.js +302 -289
  81. package/dist/psql/describe/processNamePattern.js +28 -28
  82. package/dist/psql/describe/queries.js +656 -651
  83. package/dist/psql/index.js +436 -411
  84. package/dist/psql/io/history.js +36 -36
  85. package/dist/psql/io/input.js +15 -15
  86. package/dist/psql/io/lineEditor/buffer.js +27 -25
  87. package/dist/psql/io/lineEditor/complete.js +15 -15
  88. package/dist/psql/io/lineEditor/filename.js +22 -22
  89. package/dist/psql/io/lineEditor/index.js +65 -62
  90. package/dist/psql/io/lineEditor/keymap.js +325 -318
  91. package/dist/psql/io/lineEditor/vt100.js +60 -60
  92. package/dist/psql/io/pgpass.js +18 -18
  93. package/dist/psql/io/pgservice.js +14 -14
  94. package/dist/psql/io/psqlrc.js +46 -46
  95. package/dist/psql/print/aligned.js +175 -166
  96. package/dist/psql/print/asciidoc.js +51 -51
  97. package/dist/psql/print/crosstab.js +34 -31
  98. package/dist/psql/print/csv.js +25 -22
  99. package/dist/psql/print/html.js +54 -54
  100. package/dist/psql/print/json.js +12 -12
  101. package/dist/psql/print/latex.js +118 -118
  102. package/dist/psql/print/pager.js +28 -26
  103. package/dist/psql/print/troff.js +48 -48
  104. package/dist/psql/print/unaligned.js +15 -14
  105. package/dist/psql/print/units.js +17 -17
  106. package/dist/psql/scanner/slash.js +48 -46
  107. package/dist/psql/scanner/sql.js +88 -84
  108. package/dist/psql/scanner/stringutils.js +21 -17
  109. package/dist/psql/types/index.js +7 -7
  110. package/dist/psql/types/scanner.js +8 -8
  111. package/dist/psql/wire/connection.js +341 -327
  112. package/dist/psql/wire/copy.js +7 -7
  113. package/dist/psql/wire/pipeline.js +26 -24
  114. package/dist/psql/wire/protocol.js +102 -102
  115. package/dist/psql/wire/sasl.js +62 -62
  116. package/dist/psql/wire/tls.js +79 -73
  117. package/dist/storage_api.js +15 -15
  118. package/dist/test_utils/fixtures.js +34 -31
  119. package/dist/test_utils/oauth_server.js +5 -5
  120. package/dist/utils/api_enums.js +13 -13
  121. package/dist/utils/branch_notice.js +5 -5
  122. package/dist/utils/branch_picker.js +26 -26
  123. package/dist/utils/compute_units.js +4 -4
  124. package/dist/utils/enrichers.js +20 -15
  125. package/dist/utils/esbuild.js +28 -28
  126. package/dist/utils/formats.js +1 -1
  127. package/dist/utils/middlewares.js +3 -3
  128. package/dist/utils/package_manager.js +68 -0
  129. package/dist/utils/point_in_time.js +12 -12
  130. package/dist/utils/psql.js +30 -30
  131. package/dist/utils/string.js +2 -2
  132. package/dist/utils/ui.js +9 -9
  133. package/dist/utils/zip.js +1 -1
  134. package/dist/writer.js +17 -17
  135. 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 = '%/%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';
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 = '2';
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: 'aligned',
64
- expanded: 'off',
63
+ format: "aligned",
64
+ expanded: "off",
65
65
  border: 1,
66
- pager: 'on',
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: 'UTF8',
73
+ encoding: "UTF8",
74
74
  envColumns: 0,
75
75
  columns: 0,
76
- unicodeBorderLineStyle: 'ascii',
77
- unicodeColumnLineStyle: 'ascii',
78
- unicodeHeaderLineStyle: 'ascii',
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: 'single',
83
- unicodeColumnStyle: 'single',
84
- unicodeHeaderStyle: 'single',
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: 'full',
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: 'stdin',
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('PROMPT1', (newValue) => {
156
- settings.prompt1 = newValue ?? '';
155
+ varStore.addHook("PROMPT1", (newValue) => {
156
+ settings.prompt1 = newValue ?? "";
157
157
  return true;
158
158
  });
159
- varStore.addHook('PROMPT2', (newValue) => {
160
- settings.prompt2 = newValue ?? '';
159
+ varStore.addHook("PROMPT2", (newValue) => {
160
+ settings.prompt2 = newValue ?? "";
161
161
  return true;
162
162
  });
163
- varStore.addHook('PROMPT3', (newValue) => {
164
- settings.prompt3 = newValue ?? '';
163
+ varStore.addHook("PROMPT3", (newValue) => {
164
+ settings.prompt3 = newValue ?? "";
165
165
  return true;
166
166
  });
167
- varStore.set('PROMPT1', DEFAULT_PROMPT1);
168
- varStore.set('PROMPT2', DEFAULT_PROMPT2);
169
- varStore.set('PROMPT3', DEFAULT_PROMPT3);
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('LAST_ERROR_MESSAGE', '');
172
- varStore.set('LAST_ERROR_SQLSTATE', '00000');
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('PIPELINE_SYNC_COUNT', '0');
185
- varStore.set('PIPELINE_COMMAND_COUNT', '0');
186
- varStore.set('PIPELINE_RESULT_COUNT', '0');
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('SHOW_ALL_RESULTS', 'on');
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('ENCODING', 'UTF8');
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('WATCH_INTERVAL', (newValue) => {
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('ON_ERROR_STOP', makeBoolHook('ON_ERROR_STOP', (parsed) => {
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('AUTOCOMMIT', makeBoolHook('AUTOCOMMIT'));
230
+ varStore.addHook("AUTOCOMMIT", makeBoolHook("AUTOCOMMIT"));
231
231
  // Seed AUTOCOMMIT to "on" (upstream default; pset.autocommit = true).
232
- varStore.set('AUTOCOMMIT', 'on');
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('FETCH_COUNT', (newValue) => {
239
+ varStore.addHook("FETCH_COUNT", (newValue) => {
240
240
  if (newValue === null) {
241
241
  settings.fetchCount = 0;
242
- return { substitute: '0' };
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('ON_ERROR_ROLLBACK', makeOnErrorRollbackHook((parsed) => {
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('VERBOSITY', makeEnumHook('VERBOSITY', ['default', 'verbose', 'terse', 'sqlstate'], 'default', (parsed) => {
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('SHOW_CONTEXT', makeEnumHook('SHOW_CONTEXT', ['never', 'errors', 'always'], 'errors', (parsed) => {
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('ECHO', makeEnumHook('ECHO', ['none', 'errors', 'queries', 'all'], 'none', (parsed) => {
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('ECHO_HIDDEN', makeEchoHiddenHook((parsed) => {
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('COMP_KEYWORD_CASE', makeEnumHook('COMP_KEYWORD_CASE', ['lower', 'upper', 'preserve-lower', 'preserve-upper'], DEFAULT_COMP_CASE, (parsed) => {
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('HISTCONTROL', makeEnumHook('HISTCONTROL', ['none', 'ignorespace', 'ignoredups', 'ignoreboth'], 'none', (parsed) => {
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('SHOW_ALL_RESULTS', makeBoolHook('SHOW_ALL_RESULTS'));
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('QUIET', makeBoolHook('QUIET', (parsed) => {
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('SINGLELINE', makeBoolHook('SINGLELINE', (parsed) => {
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('SINGLESTEP', makeBoolHook('SINGLESTEP', (parsed) => {
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('HIDE_TOAST_COMPRESSION', makeBoolHook('HIDE_TOAST_COMPRESSION', (parsed) => {
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('HIDE_TABLEAM', makeBoolHook('HIDE_TABLEAM', (parsed) => {
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('HISTSIZE', (newValue) => {
334
+ varStore.addHook("HISTSIZE", (newValue) => {
335
335
  if (newValue === null) {
336
- return { substitute: '500' };
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('IGNOREEOF', (newValue) => {
358
+ varStore.addHook("IGNOREEOF", (newValue) => {
359
359
  if (newValue === null) {
360
- return { substitute: '0' };
360
+ return { substitute: "0" };
361
361
  }
362
362
  if (parseStrtolBase0OrNull(newValue) === null) {
363
- return { substitute: '10' };
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: 'off' };
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: 'on' };
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('off');
451
- return { substitute: 'off' };
450
+ apply("off");
451
+ return { substitute: "off" };
452
452
  }
453
- if (newValue === '') {
454
- apply('on');
455
- return { substitute: 'on' };
453
+ if (newValue === "") {
454
+ apply("on");
455
+ return { substitute: "on" };
456
456
  }
457
457
  const lower = newValue.toLowerCase();
458
- if (lower === 'on' || lower === 'off' || lower === 'interactive') {
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('off');
478
- return { substitute: 'off' };
477
+ apply("off");
478
+ return { substitute: "off" };
479
479
  }
480
- if (newValue === '') {
481
- apply('on');
482
- return { substitute: 'on' };
480
+ if (newValue === "") {
481
+ apply("on");
482
+ return { substitute: "on" };
483
483
  }
484
484
  const lower = newValue.toLowerCase();
485
- if (lower === 'noexec') {
486
- apply('noexec');
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 ? 'on' : 'off');
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('0x') || body.startsWith('0X')) {
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('0')) {
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 === '' || v === 'on' || v === 'true' || v === 'yes' || v === '1') {
574
+ if (v === "" || v === "on" || v === "true" || v === "yes" || v === "1") {
575
575
  return true;
576
576
  }
577
- if (v === 'off' || v === 'false' || v === 'no' || v === '0') {
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('PAGER', 'PAGER');
655
- bridge('PSQL_PAGER', 'PAGER');
656
- bridge('PSQL_WATCH_PAGER', 'PSQL_WATCH_PAGER');
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('EDITOR', 'EDITOR');
660
- bridge('VISUAL', 'EDITOR');
661
- bridge('PSQL_EDITOR', 'EDITOR');
662
- bridge('PSQL_EDITOR_LINENUMBER_ARG', 'EDITOR_LINENUMBER_ARG');
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('PSQL_HISTORY', 'HISTFILE');
665
- bridge('PSQL_HISTSIZE', 'HISTSIZE');
666
- bridge('PSQL_HISTCONTROL', 'HISTCONTROL');
664
+ bridge("PSQL_HISTORY", "HISTFILE");
665
+ bridge("PSQL_HISTSIZE", "HISTSIZE");
666
+ bridge("PSQL_HISTCONTROL", "HISTCONTROL");
667
667
  // RC file path.
668
- bridge('PSQLRC', 'PSQLRC');
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('NO_COLOR', env.NO_COLOR);
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;