neonctl 2.28.0 → 2.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -71
- package/dist/analytics.js +35 -33
- package/dist/api.js +34 -34
- package/dist/auth.js +50 -44
- package/dist/cli.js +2 -2
- package/dist/commands/auth.js +58 -52
- package/dist/commands/bootstrap.js +115 -157
- package/dist/commands/branches.js +154 -147
- package/dist/commands/bucket.js +124 -118
- package/dist/commands/checkout.js +49 -49
- package/dist/commands/config.js +212 -88
- package/dist/commands/connection_string.js +62 -62
- package/dist/commands/data_api.js +96 -96
- package/dist/commands/databases.js +23 -23
- package/dist/commands/deploy.js +12 -12
- package/dist/commands/dev.js +114 -114
- package/dist/commands/env.js +43 -43
- package/dist/commands/functions.js +97 -98
- package/dist/commands/index.js +26 -26
- package/dist/commands/init.js +23 -22
- package/dist/commands/ip_allow.js +29 -29
- package/dist/commands/link.js +223 -166
- package/dist/commands/neon_auth.js +381 -363
- package/dist/commands/operations.js +11 -11
- package/dist/commands/orgs.js +8 -8
- package/dist/commands/projects.js +101 -99
- package/dist/commands/psql.js +31 -31
- package/dist/commands/roles.js +21 -21
- package/dist/commands/schema_diff.js +23 -23
- package/dist/commands/set_context.js +17 -17
- package/dist/commands/status.js +17 -17
- package/dist/commands/user.js +5 -5
- package/dist/commands/vpc_endpoints.js +50 -50
- package/dist/config.js +7 -7
- package/dist/config_format.js +5 -5
- package/dist/context.js +23 -16
- package/dist/current_branch_fast_path.js +6 -6
- package/dist/dev/env.js +34 -34
- package/dist/dev/functions.js +4 -4
- package/dist/dev/inputs.js +6 -6
- package/dist/dev/runtime.js +25 -25
- package/dist/env.js +14 -14
- package/dist/env_file.js +13 -13
- package/dist/errors.js +19 -19
- package/dist/functions_api.js +10 -10
- package/dist/help.js +15 -15
- package/dist/index.js +94 -92
- package/dist/log.js +2 -2
- package/dist/pkg.js +5 -5
- package/dist/psql/cli.js +4 -2
- package/dist/psql/command/cmd_cond.js +61 -61
- package/dist/psql/command/cmd_connect.js +159 -154
- package/dist/psql/command/cmd_copy.js +107 -97
- package/dist/psql/command/cmd_describe.js +368 -363
- package/dist/psql/command/cmd_format.js +276 -263
- package/dist/psql/command/cmd_io.js +269 -263
- package/dist/psql/command/cmd_lo.js +74 -66
- package/dist/psql/command/cmd_meta.js +148 -148
- package/dist/psql/command/cmd_misc.js +17 -17
- package/dist/psql/command/cmd_pipeline.js +142 -135
- package/dist/psql/command/cmd_restrict.js +25 -25
- package/dist/psql/command/cmd_show.js +183 -168
- package/dist/psql/command/dispatch.js +26 -26
- package/dist/psql/command/shared.js +14 -14
- package/dist/psql/complete/filenames.js +16 -16
- package/dist/psql/complete/index.js +4 -4
- package/dist/psql/complete/matcher.js +33 -32
- package/dist/psql/complete/psqlVars.js +173 -173
- package/dist/psql/complete/queries.js +5 -3
- package/dist/psql/complete/rules.js +900 -863
- package/dist/psql/core/common.js +136 -133
- package/dist/psql/core/help.js +343 -343
- package/dist/psql/core/mainloop.js +160 -153
- package/dist/psql/core/prompt.js +126 -123
- package/dist/psql/core/settings.js +111 -111
- package/dist/psql/core/sqlHelp.js +150 -150
- package/dist/psql/core/startup.js +211 -205
- package/dist/psql/core/syncVars.js +14 -14
- package/dist/psql/core/variables.js +24 -24
- package/dist/psql/describe/formatters.js +302 -289
- package/dist/psql/describe/processNamePattern.js +28 -28
- package/dist/psql/describe/queries.js +656 -651
- package/dist/psql/index.js +436 -411
- package/dist/psql/io/history.js +36 -36
- package/dist/psql/io/input.js +15 -15
- package/dist/psql/io/lineEditor/buffer.js +27 -25
- package/dist/psql/io/lineEditor/complete.js +15 -15
- package/dist/psql/io/lineEditor/filename.js +22 -22
- package/dist/psql/io/lineEditor/index.js +65 -62
- package/dist/psql/io/lineEditor/keymap.js +325 -318
- package/dist/psql/io/lineEditor/vt100.js +60 -60
- package/dist/psql/io/pgpass.js +18 -18
- package/dist/psql/io/pgservice.js +14 -14
- package/dist/psql/io/psqlrc.js +46 -46
- package/dist/psql/print/aligned.js +175 -166
- package/dist/psql/print/asciidoc.js +51 -51
- package/dist/psql/print/crosstab.js +34 -31
- package/dist/psql/print/csv.js +25 -22
- package/dist/psql/print/html.js +54 -54
- package/dist/psql/print/json.js +12 -12
- package/dist/psql/print/latex.js +118 -118
- package/dist/psql/print/pager.js +28 -26
- package/dist/psql/print/troff.js +48 -48
- package/dist/psql/print/unaligned.js +15 -14
- package/dist/psql/print/units.js +17 -17
- package/dist/psql/scanner/slash.js +48 -46
- package/dist/psql/scanner/sql.js +88 -84
- package/dist/psql/scanner/stringutils.js +21 -17
- package/dist/psql/types/index.js +7 -7
- package/dist/psql/types/scanner.js +8 -8
- package/dist/psql/wire/connection.js +341 -327
- package/dist/psql/wire/copy.js +7 -7
- package/dist/psql/wire/pipeline.js +26 -24
- package/dist/psql/wire/protocol.js +102 -102
- package/dist/psql/wire/sasl.js +62 -62
- package/dist/psql/wire/tls.js +79 -73
- package/dist/storage_api.js +15 -15
- package/dist/test_utils/fixtures.js +34 -31
- package/dist/test_utils/oauth_server.js +5 -5
- package/dist/utils/api_enums.js +13 -13
- package/dist/utils/branch_notice.js +5 -5
- package/dist/utils/branch_picker.js +26 -26
- package/dist/utils/compute_units.js +4 -4
- package/dist/utils/enrichers.js +20 -15
- package/dist/utils/esbuild.js +28 -28
- package/dist/utils/formats.js +1 -1
- package/dist/utils/middlewares.js +3 -3
- package/dist/utils/package_manager.js +68 -0
- package/dist/utils/point_in_time.js +12 -12
- package/dist/utils/psql.js +30 -30
- package/dist/utils/string.js +2 -2
- package/dist/utils/ui.js +9 -9
- package/dist/utils/zip.js +1 -1
- package/dist/writer.js +17 -17
- package/package.json +6 -7
package/dist/psql/core/prompt.js
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
* and consumed by a subsequent PROMPT2 render via the optional
|
|
40
40
|
* `lastPrompt1Width` field on the context.
|
|
41
41
|
*/
|
|
42
|
-
import { execSync } from
|
|
42
|
+
import { execSync } from "node:child_process";
|
|
43
43
|
/**
|
|
44
44
|
* Test seam for the prompt-level backtick executor. The default
|
|
45
45
|
* implementation calls `execSync(cmd, { shell: '/bin/sh' })`; tests can
|
|
@@ -48,9 +48,9 @@ import { execSync } from 'node:child_process';
|
|
|
48
48
|
*/
|
|
49
49
|
export const PROMPT_BACKTICK_EXECUTOR = {
|
|
50
50
|
current: (cmd) => execSync(cmd, {
|
|
51
|
-
shell:
|
|
52
|
-
encoding:
|
|
53
|
-
stdio: [
|
|
51
|
+
shell: "/bin/sh",
|
|
52
|
+
encoding: "utf8",
|
|
53
|
+
stdio: ["ignore", "pipe", "inherit"],
|
|
54
54
|
// Keep prompt rendering responsive — a heavy backtick command should
|
|
55
55
|
// not be able to fill arbitrary memory or hang the prompt forever.
|
|
56
56
|
maxBuffer: 1 << 16,
|
|
@@ -63,15 +63,15 @@ export const PROMPT_BACKTICK_EXECUTOR = {
|
|
|
63
63
|
*/
|
|
64
64
|
const runPromptBacktick = (cmd) => {
|
|
65
65
|
if (cmd.length === 0)
|
|
66
|
-
return
|
|
66
|
+
return "";
|
|
67
67
|
try {
|
|
68
68
|
const out = PROMPT_BACKTICK_EXECUTOR.current(cmd);
|
|
69
|
-
return out.endsWith(
|
|
69
|
+
return out.endsWith("\n") ? out.slice(0, -1) : out;
|
|
70
70
|
}
|
|
71
71
|
catch (err) {
|
|
72
72
|
const msg = err instanceof Error ? err.message : String(err);
|
|
73
73
|
process.stderr.write(`psql: error: \\!: ${cmd}: ${msg}\n`);
|
|
74
|
-
return
|
|
74
|
+
return "";
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
/**
|
|
@@ -79,12 +79,12 @@ const runPromptBacktick = (cmd) => {
|
|
|
79
79
|
* `settings.prompt{1,2,3}` and delegates to the escape-walking core.
|
|
80
80
|
*/
|
|
81
81
|
export const renderPromptByName = (name, ctx) => {
|
|
82
|
-
const template = name ===
|
|
82
|
+
const template = name === "PROMPT1"
|
|
83
83
|
? ctx.settings.prompt1
|
|
84
|
-
: name ===
|
|
84
|
+
: name === "PROMPT2"
|
|
85
85
|
? ctx.settings.prompt2
|
|
86
86
|
: ctx.settings.prompt3;
|
|
87
|
-
const isPrompt1 = name ===
|
|
87
|
+
const isPrompt1 = name === "PROMPT1";
|
|
88
88
|
const out = renderPrompt(template, ctx);
|
|
89
89
|
if (isPrompt1) {
|
|
90
90
|
// Stash the visible width on the context so a subsequent PROMPT2 render
|
|
@@ -97,11 +97,11 @@ export const renderPromptByName = (name, ctx) => {
|
|
|
97
97
|
* Render an arbitrary prompt template. Pure function over `(template, ctx)`.
|
|
98
98
|
*/
|
|
99
99
|
export const renderPrompt = (template, ctx) => {
|
|
100
|
-
let out =
|
|
100
|
+
let out = "";
|
|
101
101
|
let i = 0;
|
|
102
102
|
while (i < template.length) {
|
|
103
103
|
const ch = template[i];
|
|
104
|
-
if (ch !==
|
|
104
|
+
if (ch !== "%") {
|
|
105
105
|
out += ch;
|
|
106
106
|
i += 1;
|
|
107
107
|
continue;
|
|
@@ -126,150 +126,153 @@ start, ctx) => {
|
|
|
126
126
|
const { settings } = ctx;
|
|
127
127
|
const db = settings.db;
|
|
128
128
|
switch (escape) {
|
|
129
|
-
case
|
|
130
|
-
return { text:
|
|
131
|
-
case
|
|
129
|
+
case "%":
|
|
130
|
+
return { text: "%", consumed: 1 };
|
|
131
|
+
case "/":
|
|
132
132
|
// Current database.
|
|
133
|
-
return { text: db ? currentDatabase(ctx) :
|
|
134
|
-
case
|
|
133
|
+
return { text: db ? currentDatabase(ctx) : "", consumed: 1 };
|
|
134
|
+
case "~": {
|
|
135
135
|
// Like %/, but "~" when current_db matches the user's default db.
|
|
136
136
|
// Upstream compares PQdb(pset.db) against PQuser(pset.db) and
|
|
137
137
|
// against $PGDATABASE.
|
|
138
138
|
if (!db)
|
|
139
|
-
return { text:
|
|
139
|
+
return { text: "", consumed: 1 };
|
|
140
140
|
const cdb = currentDatabase(ctx);
|
|
141
141
|
const user = currentUser(ctx);
|
|
142
142
|
const pgdb = process.env.PGDATABASE;
|
|
143
143
|
if (cdb === user || (pgdb !== undefined && pgdb === cdb)) {
|
|
144
|
-
return { text:
|
|
144
|
+
return { text: "~", consumed: 1 };
|
|
145
145
|
}
|
|
146
146
|
return { text: cdb, consumed: 1 };
|
|
147
147
|
}
|
|
148
|
-
case
|
|
149
|
-
case
|
|
148
|
+
case "M":
|
|
149
|
+
case "m":
|
|
150
150
|
return {
|
|
151
|
-
text: db ? hostString(ctx, escape ===
|
|
151
|
+
text: db ? hostString(ctx, escape === "m") : "",
|
|
152
152
|
consumed: 1,
|
|
153
153
|
};
|
|
154
|
-
case
|
|
155
|
-
return { text: db ? portString(ctx) :
|
|
156
|
-
case
|
|
157
|
-
return { text: db ? currentUser(ctx) :
|
|
158
|
-
case
|
|
154
|
+
case ">":
|
|
155
|
+
return { text: db ? portString(ctx) : "", consumed: 1 };
|
|
156
|
+
case "n":
|
|
157
|
+
return { text: db ? currentUser(ctx) : "", consumed: 1 };
|
|
158
|
+
case "p": {
|
|
159
159
|
if (!db)
|
|
160
|
-
return { text:
|
|
160
|
+
return { text: "", consumed: 1 };
|
|
161
161
|
const pid = backendPid(ctx);
|
|
162
|
-
return { text: pid !== null ? String(pid) :
|
|
162
|
+
return { text: pid !== null ? String(pid) : "", consumed: 1 };
|
|
163
163
|
}
|
|
164
|
-
case
|
|
164
|
+
case "P": {
|
|
165
165
|
if (!db)
|
|
166
|
-
return { text:
|
|
166
|
+
return { text: "", consumed: 1 };
|
|
167
167
|
// Upstream emits "off" / "on" / "abort" (no trailing 'ed').
|
|
168
|
-
const state = ctx.pipelineState ??
|
|
169
|
-
const text = state ===
|
|
168
|
+
const state = ctx.pipelineState ?? "off";
|
|
169
|
+
const text = state === "on" ? "on" : state === "aborted" ? "abort" : "off";
|
|
170
170
|
return { text, consumed: 1 };
|
|
171
171
|
}
|
|
172
|
-
case
|
|
172
|
+
case "i": {
|
|
173
173
|
// Hot-standby indicator. Upstream reads in_hot_standby GUC.
|
|
174
174
|
if (!db)
|
|
175
|
-
return { text:
|
|
176
|
-
const hs = parameterStatus(ctx,
|
|
175
|
+
return { text: "", consumed: 1 };
|
|
176
|
+
const hs = parameterStatus(ctx, "in_hot_standby");
|
|
177
177
|
if (hs === undefined)
|
|
178
|
-
return { text:
|
|
179
|
-
return { text: hs ===
|
|
178
|
+
return { text: "?", consumed: 1 };
|
|
179
|
+
return { text: hs === "on" ? "standby" : "primary", consumed: 1 };
|
|
180
180
|
}
|
|
181
|
-
case
|
|
181
|
+
case "s": {
|
|
182
182
|
// service name from psql var SERVICE (upstream prompt.c).
|
|
183
|
-
const svc = settings.vars.get(
|
|
184
|
-
return { text: svc ??
|
|
183
|
+
const svc = settings.vars.get("SERVICE");
|
|
184
|
+
return { text: svc ?? "", consumed: 1 };
|
|
185
185
|
}
|
|
186
|
-
case
|
|
186
|
+
case "S": {
|
|
187
187
|
// search_path; `?` when unavailable (older servers or no conn).
|
|
188
188
|
if (!db)
|
|
189
|
-
return { text:
|
|
190
|
-
const sp = parameterStatus(ctx,
|
|
191
|
-
return { text: sp ??
|
|
189
|
+
return { text: "?", consumed: 1 };
|
|
190
|
+
const sp = parameterStatus(ctx, "search_path");
|
|
191
|
+
return { text: sp ?? "?", consumed: 1 };
|
|
192
192
|
}
|
|
193
|
-
case
|
|
193
|
+
case "l":
|
|
194
194
|
return { text: String(ctx.lineNumber), consumed: 1 };
|
|
195
|
-
case
|
|
195
|
+
case "w": {
|
|
196
196
|
// Whitespace padding the width of the last PROMPT1 render.
|
|
197
197
|
const width = Math.max(0, ctx.lastPrompt1Width ?? 0);
|
|
198
|
-
return { text: db ?
|
|
198
|
+
return { text: db ? " ".repeat(width) : "", consumed: 1 };
|
|
199
199
|
}
|
|
200
|
-
case
|
|
200
|
+
case "a":
|
|
201
201
|
// Bell. Upstream falls into default, which is just literal 'a' (no
|
|
202
202
|
// bell handling in get_prompt). The WP-07 spec explicitly asks for
|
|
203
203
|
// ^G though, and emitting BEL is harmless. Honour the spec.
|
|
204
|
-
return { text:
|
|
205
|
-
case
|
|
204
|
+
return { text: "\x07", consumed: 1 };
|
|
205
|
+
case "R": {
|
|
206
206
|
const text = expandR(ctx);
|
|
207
207
|
return { text, consumed: 1 };
|
|
208
208
|
}
|
|
209
|
-
case
|
|
209
|
+
case "x": {
|
|
210
210
|
if (!db)
|
|
211
|
-
return { text:
|
|
212
|
-
const tx = ctx.inTransaction ??
|
|
213
|
-
if (tx ===
|
|
214
|
-
return { text:
|
|
215
|
-
if (tx ===
|
|
216
|
-
return { text:
|
|
217
|
-
if (tx ===
|
|
218
|
-
return { text:
|
|
219
|
-
return { text:
|
|
211
|
+
return { text: "?", consumed: 1 };
|
|
212
|
+
const tx = ctx.inTransaction ?? "idle";
|
|
213
|
+
if (tx === "in-block")
|
|
214
|
+
return { text: "*", consumed: 1 };
|
|
215
|
+
if (tx === "failed")
|
|
216
|
+
return { text: "!", consumed: 1 };
|
|
217
|
+
if (tx === "unknown")
|
|
218
|
+
return { text: "?", consumed: 1 };
|
|
219
|
+
return { text: "", consumed: 1 };
|
|
220
220
|
}
|
|
221
|
-
case
|
|
221
|
+
case "#": {
|
|
222
222
|
// Superuser indicator. Upstream calls is_superuser() which checks
|
|
223
223
|
// pset.vars["IS_SUPERUSER"] === "on".
|
|
224
|
-
const isSuper = settings.vars.get(
|
|
225
|
-
return { text: isSuper ?
|
|
224
|
+
const isSuper = settings.vars.get("IS_SUPERUSER") === "on";
|
|
225
|
+
return { text: isSuper ? "#" : ">", consumed: 1 };
|
|
226
226
|
}
|
|
227
|
-
case
|
|
227
|
+
case "?":
|
|
228
228
|
// Reserved by upstream ("not here yet"). Emit nothing.
|
|
229
|
-
return { text:
|
|
230
|
-
case
|
|
231
|
-
case
|
|
229
|
+
return { text: "", consumed: 1 };
|
|
230
|
+
case "[":
|
|
231
|
+
case "]":
|
|
232
232
|
// Readline non-printing markers. Strip — no terminal info embedded.
|
|
233
|
-
return { text:
|
|
234
|
-
case
|
|
233
|
+
return { text: "", consumed: 1 };
|
|
234
|
+
case "`": {
|
|
235
235
|
// Backtick command: read until the matching `` ` `` after the opening
|
|
236
236
|
// backtick, then run the body through `sh -c` and substitute its
|
|
237
237
|
// stdout. Upstream `get_prompt` re-runs the command on every render
|
|
238
238
|
// rather than caching, so we do the same — callers who want caching
|
|
239
239
|
// should stash the rendered prompt themselves.
|
|
240
|
-
const close = template.indexOf(
|
|
240
|
+
const close = template.indexOf("`", start + 1);
|
|
241
241
|
if (close === -1) {
|
|
242
242
|
// Unterminated — consume the rest defensively without spawning.
|
|
243
|
-
return { text:
|
|
243
|
+
return { text: "", consumed: template.length - start };
|
|
244
244
|
}
|
|
245
245
|
const body = template.slice(start + 1, close);
|
|
246
|
-
return {
|
|
246
|
+
return {
|
|
247
|
+
text: runPromptBacktick(body),
|
|
248
|
+
consumed: close - start + 1,
|
|
249
|
+
};
|
|
247
250
|
}
|
|
248
|
-
case
|
|
251
|
+
case ":": {
|
|
249
252
|
// Variable interpolation %:name:
|
|
250
|
-
const close = template.indexOf(
|
|
253
|
+
const close = template.indexOf(":", start + 1);
|
|
251
254
|
if (close === -1) {
|
|
252
|
-
return { text:
|
|
255
|
+
return { text: "", consumed: template.length - start };
|
|
253
256
|
}
|
|
254
257
|
const name = template.slice(start + 1, close);
|
|
255
258
|
const val = settings.vars.get(name);
|
|
256
|
-
return { text: val ??
|
|
259
|
+
return { text: val ?? "", consumed: close - start + 1 };
|
|
257
260
|
}
|
|
258
|
-
case
|
|
259
|
-
case
|
|
260
|
-
case
|
|
261
|
-
case
|
|
262
|
-
case
|
|
263
|
-
case
|
|
264
|
-
case
|
|
265
|
-
case
|
|
261
|
+
case "0":
|
|
262
|
+
case "1":
|
|
263
|
+
case "2":
|
|
264
|
+
case "3":
|
|
265
|
+
case "4":
|
|
266
|
+
case "5":
|
|
267
|
+
case "6":
|
|
268
|
+
case "7": {
|
|
266
269
|
// Octal byte value `%nnn`. Upstream uses strtol(p, &p, 8), which
|
|
267
270
|
// greedily consumes 1–3 octal digits.
|
|
268
271
|
let consumed = 1;
|
|
269
272
|
let body = escape;
|
|
270
273
|
while (consumed < 3 && start + consumed < template.length) {
|
|
271
274
|
const next = template[start + consumed];
|
|
272
|
-
if (next >=
|
|
275
|
+
if (next >= "0" && next <= "7") {
|
|
273
276
|
body += next;
|
|
274
277
|
consumed += 1;
|
|
275
278
|
}
|
|
@@ -304,32 +307,32 @@ start, ctx) => {
|
|
|
304
307
|
const expandR = (ctx) => {
|
|
305
308
|
const { promptStatus, cond, settings } = ctx;
|
|
306
309
|
switch (promptStatus) {
|
|
307
|
-
case
|
|
310
|
+
case "ready": {
|
|
308
311
|
if (!isConditionalActive(cond))
|
|
309
|
-
return
|
|
312
|
+
return "@";
|
|
310
313
|
if (!settings.db)
|
|
311
|
-
return
|
|
314
|
+
return "!";
|
|
312
315
|
if (!settings.singleline)
|
|
313
|
-
return
|
|
314
|
-
return
|
|
316
|
+
return "=";
|
|
317
|
+
return "^";
|
|
315
318
|
}
|
|
316
|
-
case
|
|
317
|
-
return
|
|
318
|
-
case
|
|
319
|
+
case "continue":
|
|
320
|
+
return "-";
|
|
321
|
+
case "continue-quote":
|
|
319
322
|
return "'";
|
|
320
|
-
case
|
|
323
|
+
case "continue-dquote":
|
|
321
324
|
return '"';
|
|
322
|
-
case
|
|
323
|
-
return
|
|
324
|
-
case
|
|
325
|
-
return
|
|
326
|
-
case
|
|
327
|
-
return
|
|
328
|
-
case
|
|
325
|
+
case "continue-dollar":
|
|
326
|
+
return "$";
|
|
327
|
+
case "comment":
|
|
328
|
+
return "*";
|
|
329
|
+
case "paren":
|
|
330
|
+
return "(";
|
|
331
|
+
case "copy":
|
|
329
332
|
// PROMPT3 / COPY path — upstream emits nothing for %R here.
|
|
330
|
-
return
|
|
333
|
+
return "";
|
|
331
334
|
default:
|
|
332
|
-
return
|
|
335
|
+
return "";
|
|
333
336
|
}
|
|
334
337
|
};
|
|
335
338
|
/**
|
|
@@ -342,7 +345,7 @@ const isConditionalActive = (cond) => {
|
|
|
342
345
|
const top = cond.top();
|
|
343
346
|
if (!top)
|
|
344
347
|
return true;
|
|
345
|
-
const inactive = [
|
|
348
|
+
const inactive = ["false", "else-false", "ignored"];
|
|
346
349
|
return !inactive.includes(top.state);
|
|
347
350
|
};
|
|
348
351
|
/**
|
|
@@ -354,8 +357,8 @@ const visibleWidth = (s) => {
|
|
|
354
357
|
// Strip CSI escapes (ESC `[` … letter). Conservative — only trims the
|
|
355
358
|
// common ANSI color form psql emits. Newlines reset the count.
|
|
356
359
|
// eslint-disable-next-line no-control-regex
|
|
357
|
-
const stripped = s.replace(/\x1b\[[0-9;]*[A-Za-z]/g,
|
|
358
|
-
const lastNl = stripped.lastIndexOf(
|
|
360
|
+
const stripped = s.replace(/\x1b\[[0-9;]*[A-Za-z]/g, "");
|
|
361
|
+
const lastNl = stripped.lastIndexOf("\n");
|
|
359
362
|
const tail = lastNl === -1 ? stripped : stripped.slice(lastNl + 1);
|
|
360
363
|
// Code-unit count — good enough for ASCII prompts; CJK / surrogate-pair
|
|
361
364
|
// width handling is a printer-WP concern.
|
|
@@ -364,39 +367,39 @@ const visibleWidth = (s) => {
|
|
|
364
367
|
const currentDatabase = (ctx) => {
|
|
365
368
|
const db = ctx.settings.db;
|
|
366
369
|
if (!db)
|
|
367
|
-
return
|
|
370
|
+
return "";
|
|
368
371
|
// Prefer a libpq-style accessor if the runtime Connection exposes one;
|
|
369
372
|
// otherwise fall back to the application's GUC view.
|
|
370
373
|
const meta = db;
|
|
371
|
-
if (typeof meta.database ===
|
|
374
|
+
if (typeof meta.database === "string" && meta.database.length > 0) {
|
|
372
375
|
return meta.database;
|
|
373
376
|
}
|
|
374
|
-
return parameterStatus(ctx,
|
|
377
|
+
return parameterStatus(ctx, "database") ?? "";
|
|
375
378
|
};
|
|
376
379
|
const currentUser = (ctx) => {
|
|
377
380
|
const db = ctx.settings.db;
|
|
378
381
|
if (!db)
|
|
379
|
-
return
|
|
382
|
+
return "";
|
|
380
383
|
const meta = db;
|
|
381
|
-
if (typeof meta.user ===
|
|
384
|
+
if (typeof meta.user === "string" && meta.user.length > 0) {
|
|
382
385
|
return meta.user;
|
|
383
386
|
}
|
|
384
|
-
return parameterStatus(ctx,
|
|
387
|
+
return parameterStatus(ctx, "session_authorization") ?? "";
|
|
385
388
|
};
|
|
386
389
|
const hostString = (ctx, short) => {
|
|
387
390
|
const db = ctx.settings.db;
|
|
388
391
|
if (!db)
|
|
389
|
-
return
|
|
392
|
+
return "";
|
|
390
393
|
const meta = db;
|
|
391
|
-
const host = typeof meta.host ===
|
|
392
|
-
if (host.length === 0 || host.startsWith(
|
|
394
|
+
const host = typeof meta.host === "string" ? meta.host : "";
|
|
395
|
+
if (host.length === 0 || host.startsWith("/")) {
|
|
393
396
|
// UNIX socket / unknown — upstream emits "[local]" or "[local:path]".
|
|
394
397
|
if (host.length === 0 || short)
|
|
395
|
-
return
|
|
398
|
+
return "[local]";
|
|
396
399
|
return `[local:${host}]`;
|
|
397
400
|
}
|
|
398
401
|
if (short) {
|
|
399
|
-
const dot = host.indexOf(
|
|
402
|
+
const dot = host.indexOf(".");
|
|
400
403
|
return dot === -1 ? host : host.slice(0, dot);
|
|
401
404
|
}
|
|
402
405
|
return host;
|
|
@@ -404,22 +407,22 @@ const hostString = (ctx, short) => {
|
|
|
404
407
|
const portString = (ctx) => {
|
|
405
408
|
const db = ctx.settings.db;
|
|
406
409
|
if (!db)
|
|
407
|
-
return
|
|
410
|
+
return "";
|
|
408
411
|
const meta = db;
|
|
409
|
-
if (typeof meta.port ===
|
|
412
|
+
if (typeof meta.port === "number" && Number.isFinite(meta.port)) {
|
|
410
413
|
return String(meta.port);
|
|
411
414
|
}
|
|
412
|
-
if (typeof meta.port ===
|
|
415
|
+
if (typeof meta.port === "string" && meta.port.length > 0) {
|
|
413
416
|
return meta.port;
|
|
414
417
|
}
|
|
415
|
-
return
|
|
418
|
+
return "";
|
|
416
419
|
};
|
|
417
420
|
const backendPid = (ctx) => {
|
|
418
421
|
const db = ctx.settings.db;
|
|
419
422
|
if (!db)
|
|
420
423
|
return null;
|
|
421
424
|
const meta = db;
|
|
422
|
-
if (typeof meta.pid ===
|
|
425
|
+
if (typeof meta.pid === "number" && Number.isFinite(meta.pid)) {
|
|
423
426
|
return meta.pid;
|
|
424
427
|
}
|
|
425
428
|
return null;
|