neon 3.0.0 → 3.1.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 +70 -5
- package/dist/_chunks/auth_selection-DGgq6ifc.js +83 -0
- package/dist/_chunks/cmd_pipeline-CUbBO9U_.js +2818 -0
- package/dist/_chunks/credentials-MYdHdKah.js +188 -0
- package/dist/_chunks/env-NbA61JR3.js +585 -0
- package/dist/_chunks/env_services-Tz9G4JeT.js +531 -0
- package/dist/_chunks/paths-DMq0Lt7a.js +151 -0
- package/dist/_chunks/profiles-Ir29rqns.js +217 -0
- package/dist/_chunks/psql-DWH-kc69.js +2169 -0
- package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/_chunks/secure_file-BucZj4yQ.js +39 -0
- package/dist/analytics.js +163 -207
- package/dist/api.js +815 -758
- package/dist/auth.js +121 -141
- package/dist/auth_context.js +39 -53
- package/dist/cli.js +4 -7
- package/dist/commands/api.js +220 -250
- package/dist/commands/api_keys.js +251 -314
- package/dist/commands/auth.js +283 -328
- package/dist/commands/bootstrap.js +372 -437
- package/dist/commands/branches.js +304 -455
- package/dist/commands/bucket.js +374 -514
- package/dist/commands/checkout.js +213 -298
- package/dist/commands/config.js +573 -690
- package/dist/commands/connection_string.js +137 -165
- package/dist/commands/data_api.js +238 -260
- package/dist/commands/databases.js +67 -76
- package/dist/commands/deploy.js +31 -25
- package/dist/commands/dev.js +639 -719
- package/dist/commands/diff.js +156 -200
- package/dist/commands/env.js +255 -305
- package/dist/commands/functions.js +275 -355
- package/dist/commands/index.js +70 -65
- package/dist/commands/init.js +84 -119
- package/dist/commands/inspect.js +55 -55
- package/dist/commands/ip_allow.js +88 -120
- package/dist/commands/link.js +874 -1019
- package/dist/commands/logs.js +291 -0
- package/dist/commands/neon_auth.js +725 -933
- package/dist/commands/operations.js +34 -25
- package/dist/commands/orgs.js +28 -18
- package/dist/commands/profile.js +615 -846
- package/dist/commands/projects.js +313 -373
- package/dist/commands/psql.js +60 -58
- package/dist/commands/roles.js +55 -58
- package/dist/commands/schema_diff.js +87 -131
- package/dist/commands/set_context.js +34 -26
- package/dist/commands/snapshots.js +288 -413
- package/dist/commands/status.js +41 -37
- package/dist/commands/user.js +21 -10
- package/dist/commands/vpc_endpoints.js +85 -113
- package/dist/config.js +7 -6
- package/dist/config_format.js +50 -66
- package/dist/config_template.js +128 -157
- package/dist/context.js +183 -235
- package/dist/current_branch_fast_path.js +40 -49
- package/dist/dev/env.js +2 -446
- package/dist/dev/functions.js +54 -68
- package/dist/dev/inputs.js +46 -58
- package/dist/dev/runtime.js +135 -164
- package/dist/dev/websocket.js +766 -959
- package/dist/env.js +27 -33
- package/dist/env_file.js +118 -132
- package/dist/env_services.js +2 -51
- package/dist/errors.js +57 -68
- package/dist/functions_api.js +45 -43
- package/dist/help.js +189 -140
- package/dist/index.js +182 -257
- package/dist/init/agents.js +137 -118
- package/dist/init/auth.js +58 -68
- package/dist/init/bootstrap.js +325 -396
- package/dist/init/build_config.js +4 -2
- package/dist/init/detect_agent.js +56 -101
- package/dist/init/editors.js +35 -52
- package/dist/init/enrich_output.js +51 -66
- package/dist/init/extension.js +134 -171
- package/dist/init/inspect.js +179 -266
- package/dist/init/interactive.js +510 -622
- package/dist/init/neonctl.js +117 -168
- package/dist/init/orchestrate.js +157 -173
- package/dist/init/phases/auth.js +188 -202
- package/dist/init/phases/cleanup.js +23 -23
- package/dist/init/phases/db.js +251 -277
- package/dist/init/phases/getting_started.js +213 -223
- package/dist/init/phases/mcp.js +174 -224
- package/dist/init/phases/migrations.js +247 -248
- package/dist/init/phases/neon_auth.js +114 -133
- package/dist/init/phases/setup.js +546 -703
- package/dist/init/phases/skills.js +75 -86
- package/dist/init/phases/status.js +72 -67
- package/dist/init/resolve_context.js +102 -99
- package/dist/init/route_command.js +91 -98
- package/dist/init/skills.js +174 -218
- package/dist/init/vsix.js +77 -99
- package/dist/log.js +17 -16
- package/dist/neon_services.js +104 -129
- package/dist/parameters.gen.js +481 -471
- package/dist/pkg.js +17 -19
- package/dist/profile_keys.js +44 -47
- package/dist/psql/cli.js +44 -47
- package/dist/psql/command/cmd_cond.js +231 -406
- package/dist/psql/command/cmd_connect.js +557 -764
- package/dist/psql/command/cmd_copy.js +728 -984
- package/dist/psql/command/cmd_describe.js +1499 -1688
- package/dist/psql/command/cmd_format.js +733 -905
- package/dist/psql/command/cmd_io.js +2 -2193
- package/dist/psql/command/cmd_lo.js +297 -359
- package/dist/psql/command/cmd_meta.js +727 -878
- package/dist/psql/command/cmd_misc.js +138 -172
- package/dist/psql/command/cmd_pipeline.js +2 -1148
- package/dist/psql/command/cmd_restrict.js +119 -155
- package/dist/psql/command/cmd_show.js +529 -688
- package/dist/psql/command/dispatch.js +260 -325
- package/dist/psql/command/inputQueue.js +35 -33
- package/dist/psql/command/shared.js +49 -63
- package/dist/psql/complete/filenames.js +90 -133
- package/dist/psql/complete/index.js +59 -97
- package/dist/psql/complete/matcher.js +236 -300
- package/dist/psql/complete/psqlVars.js +218 -223
- package/dist/psql/complete/queries.js +159 -177
- package/dist/psql/complete/rules.js +1493 -2299
- package/dist/psql/core/common.js +2 -1253
- package/dist/psql/core/help.js +456 -546
- package/dist/psql/core/mainloop.js +692 -1303
- package/dist/psql/core/prompt.js +391 -408
- package/dist/psql/core/settings.js +429 -644
- package/dist/psql/core/sqlHelp.js +480 -554
- package/dist/psql/core/startup.js +2 -846
- package/dist/psql/core/syncVars.js +67 -110
- package/dist/psql/core/variables.js +156 -278
- package/dist/psql/describe/formatters.js +884 -1285
- package/dist/psql/describe/processNamePattern.js +173 -260
- package/dist/psql/describe/queries.js +1368 -2403
- package/dist/psql/describe/versionGate.js +32 -41
- package/dist/psql/index.js +2 -2030
- package/dist/psql/io/history.js +232 -271
- package/dist/psql/io/input.js +103 -108
- package/dist/psql/io/lineEditor/buffer.js +238 -319
- package/dist/psql/io/lineEditor/complete.js +135 -213
- package/dist/psql/io/lineEditor/filename.js +139 -148
- package/dist/psql/io/lineEditor/index.js +653 -870
- package/dist/psql/io/lineEditor/keymap.js +544 -702
- package/dist/psql/io/lineEditor/vt100.js +294 -341
- package/dist/psql/io/pgpass.js +158 -187
- package/dist/psql/io/pgservice.js +146 -183
- package/dist/psql/io/psqlrc.js +328 -403
- package/dist/psql/print/aligned.js +1020 -1683
- package/dist/psql/print/asciidoc.js +180 -214
- package/dist/psql/print/crosstab.js +281 -442
- package/dist/psql/print/csv.js +48 -70
- package/dist/psql/print/html.js +195 -226
- package/dist/psql/print/json.js +75 -88
- package/dist/psql/print/latex.js +291 -364
- package/dist/psql/print/pager.js +171 -242
- package/dist/psql/print/troff.js +194 -226
- package/dist/psql/print/unaligned.js +69 -95
- package/dist/psql/print/units.js +167 -169
- package/dist/psql/scanner/slash.js +428 -483
- package/dist/psql/scanner/sql.js +445 -889
- package/dist/psql/scanner/stringutils.js +309 -379
- package/dist/psql/types/index.js +8 -7
- package/dist/psql/types/scanner.js +25 -22
- package/dist/psql/wire/connection.js +2042 -2803
- package/dist/psql/wire/copy.js +84 -100
- package/dist/psql/wire/notify.js +39 -59
- package/dist/psql/wire/pipeline.js +305 -518
- package/dist/psql/wire/protocol.js +349 -417
- package/dist/psql/wire/sasl.js +180 -265
- package/dist/psql/wire/tls.js +400 -561
- package/dist/storage_api.js +115 -129
- package/dist/test_utils/fixtures.js +94 -113
- package/dist/test_utils/oauth_server.js +10 -7
- package/dist/test_utils/project_dir.js +33 -0
- package/dist/utils/ai_gateway_notice.js +131 -162
- package/dist/utils/api_enums.js +21 -28
- package/dist/utils/auth.js +10 -4
- package/dist/utils/branch_notice.js +20 -19
- package/dist/utils/branch_picker.js +83 -89
- package/dist/utils/cli_name.js +15 -12
- package/dist/utils/compute_units.js +20 -27
- package/dist/utils/config_diff.js +127 -158
- package/dist/utils/enrichers.js +95 -148
- package/dist/utils/esbuild.js +130 -189
- package/dist/utils/flags.js +35 -47
- package/dist/utils/formats.js +8 -15
- package/dist/utils/git_diff.js +69 -80
- package/dist/utils/inspect_db.js +101 -143
- package/dist/utils/inspect_queries.js +179 -142
- package/dist/utils/middlewares.js +39 -45
- package/dist/utils/openapi.js +87 -99
- package/dist/utils/package_manager.js +312 -110
- package/dist/utils/point_in_time.js +49 -53
- package/dist/utils/psql.js +89 -106
- package/dist/utils/service_picker.js +55 -58
- package/dist/utils/string.js +5 -5
- package/dist/utils/ui.js +38 -55
- package/dist/utils/write_sync.js +26 -35
- package/dist/utils/zip.js +4 -3
- package/dist/writer.js +67 -87
- package/package.json +11 -6
- package/dist/_shared/auth_selection.js +0 -86
- package/dist/_shared/credentials.js +0 -209
- package/dist/_shared/env-core/env.js +0 -558
- package/dist/_shared/env-core/reuse-secrets.js +0 -223
- package/dist/_shared/paths.js +0 -148
- package/dist/_shared/profiles.js +0 -276
- package/dist/_shared/secure_file.js +0 -43
package/dist/psql/io/psqlrc.js
CHANGED
|
@@ -1,422 +1,347 @@
|
|
|
1
|
-
|
|
2
|
-
* `.psqlrc` autoload.
|
|
3
|
-
*
|
|
4
|
-
* TypeScript port of `process_psqlrc()` / `process_psqlrc_file()` in
|
|
5
|
-
* `src/bin/psql/startup.c`. Two responsibilities:
|
|
6
|
-
*
|
|
7
|
-
* 1. `defaultPsqlrcPath(env?)` — pure function returning the path psql
|
|
8
|
-
* *would* read in the absence of a `$PSQLRC` override. Resolves to
|
|
9
|
-
* `$HOME/.psqlrc` on POSIX and `%APPDATA%/postgresql/psqlrc.conf` on
|
|
10
|
-
* Windows (the upstream layout).
|
|
11
|
-
*
|
|
12
|
-
* 2. `loadPsqlrc(ctx)` — discover and execute the rc files in upstream
|
|
13
|
-
* order:
|
|
14
|
-
* a. `$PGSYSCONFDIR/psqlrc-VERSION` and `$PGSYSCONFDIR/psqlrc`
|
|
15
|
-
* b. `$PSQLRC` if non-empty (overrides $HOME path)
|
|
16
|
-
* c. else `$HOME/.psqlrc-VERSION` then `$HOME/.psqlrc`
|
|
17
|
-
* Each existing file's contents are split into statements via the same
|
|
18
|
-
* `scanSql` boundary detector the mainloop uses, then dispatched
|
|
19
|
-
* through `connection.execSimple` (for SQL) or the backslash registry
|
|
20
|
-
* (for `\…` commands).
|
|
21
|
-
*
|
|
22
|
-
* Duplication note: we deliberately re-implement a minimal scan-and-dispatch
|
|
23
|
-
* loop here instead of routing through `core/mainloop.ts`. The mainloop is
|
|
24
|
-
* locked-down in WP-12 and adding an `executeInputString` helper to it would
|
|
25
|
-
* touch a file we can't modify in this WP. The two loops share `scanSql` and
|
|
26
|
-
* `dispatchBackslash` so the divergence is structural, not behavioural.
|
|
27
|
-
*
|
|
28
|
-
* Follow-up issue: refactor `mainloop.ts` to expose an `executeInputString`
|
|
29
|
-
* primitive and delete this duplication. Tracked TODO at the bottom of this
|
|
30
|
-
* file.
|
|
31
|
-
*/
|
|
32
|
-
import { promises as fs } from "node:fs";
|
|
33
|
-
import * as path from "node:path";
|
|
34
|
-
import { attachCondStack, COND_COMMAND_NAMES } from "../command/cmd_cond.js";
|
|
35
|
-
import { dispatchBackslash } from "../command/dispatch.js";
|
|
36
|
-
import { sendQuery } from "../core/common.js";
|
|
1
|
+
import { COND_COMMAND_NAMES, attachCondStack } from "../command/cmd_cond.js";
|
|
37
2
|
import { scanSlashArgs } from "../scanner/slash.js";
|
|
38
|
-
import {
|
|
3
|
+
import { U as sendQuery } from "../../_chunks/cmd_pipeline-CUbBO9U_.js";
|
|
4
|
+
import { dispatchBackslash } from "../command/dispatch.js";
|
|
39
5
|
import { initialScanState } from "../types/scanner.js";
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
6
|
+
import { scanSql } from "../scanner/sql.js";
|
|
7
|
+
import { promises } from "node:fs";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
//#region src/psql/io/psqlrc.ts
|
|
10
|
+
/**
|
|
11
|
+
* `.psqlrc` autoload.
|
|
12
|
+
*
|
|
13
|
+
* TypeScript port of `process_psqlrc()` / `process_psqlrc_file()` in
|
|
14
|
+
* `src/bin/psql/startup.c`. Two responsibilities:
|
|
15
|
+
*
|
|
16
|
+
* 1. `defaultPsqlrcPath(env?)` — pure function returning the path psql
|
|
17
|
+
* *would* read in the absence of a `$PSQLRC` override. Resolves to
|
|
18
|
+
* `$HOME/.psqlrc` on POSIX and `%APPDATA%/postgresql/psqlrc.conf` on
|
|
19
|
+
* Windows (the upstream layout).
|
|
20
|
+
*
|
|
21
|
+
* 2. `loadPsqlrc(ctx)` — discover and execute the rc files in upstream
|
|
22
|
+
* order:
|
|
23
|
+
* a. `$PGSYSCONFDIR/psqlrc-VERSION` and `$PGSYSCONFDIR/psqlrc`
|
|
24
|
+
* b. `$PSQLRC` if non-empty (overrides $HOME path)
|
|
25
|
+
* c. else `$HOME/.psqlrc-VERSION` then `$HOME/.psqlrc`
|
|
26
|
+
* Each existing file's contents are split into statements via the same
|
|
27
|
+
* `scanSql` boundary detector the mainloop uses, then dispatched
|
|
28
|
+
* through `connection.execSimple` (for SQL) or the backslash registry
|
|
29
|
+
* (for `\…` commands).
|
|
30
|
+
*
|
|
31
|
+
* Duplication note: we deliberately re-implement a minimal scan-and-dispatch
|
|
32
|
+
* loop here instead of routing through `core/mainloop.ts`. The mainloop is
|
|
33
|
+
* locked-down in WP-12 and adding an `executeInputString` helper to it would
|
|
34
|
+
* touch a file we can't modify in this WP. The two loops share `scanSql` and
|
|
35
|
+
* `dispatchBackslash` so the divergence is structural, not behavioural.
|
|
36
|
+
*
|
|
37
|
+
* Follow-up issue: refactor `mainloop.ts` to expose an `executeInputString`
|
|
38
|
+
* primitive and delete this duplication. Tracked TODO at the bottom of this
|
|
39
|
+
* file.
|
|
40
|
+
*/
|
|
43
41
|
const isWindows = process.platform === "win32";
|
|
44
42
|
const baseRcName = isWindows ? "psqlrc.conf" : ".psqlrc";
|
|
45
43
|
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const home = env.HOME ?? "";
|
|
59
|
-
return path.join(home, baseRcName);
|
|
44
|
+
* Return the default user-level psqlrc path. The path is *not* verified to
|
|
45
|
+
* exist — callers stat it lazily. The Windows layout follows upstream:
|
|
46
|
+
* `%APPDATA%/postgresql/psqlrc.conf`. On POSIX we use `$HOME/.psqlrc`.
|
|
47
|
+
*/
|
|
48
|
+
const defaultPsqlrcPath = (env = process.env) => {
|
|
49
|
+
if (isWindows) {
|
|
50
|
+
const appData = env.APPDATA;
|
|
51
|
+
if (appData && appData.length > 0) return path.join(appData, "postgresql", baseRcName);
|
|
52
|
+
return path.join(env.USERPROFILE ?? "", "postgresql", baseRcName);
|
|
53
|
+
}
|
|
54
|
+
const home = env.HOME ?? "";
|
|
55
|
+
return path.join(home, baseRcName);
|
|
60
56
|
};
|
|
61
57
|
const versionSuffix = (serverVersion) => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// `psqlrc-PG_VERSION` (major.minor) and `psqlrc-PG_MAJORVERSION`. We use
|
|
66
|
-
// the major (e.g. 17) — the bigger of the two backwards-compat targets.
|
|
67
|
-
const major = Math.floor(serverVersion / 10000);
|
|
68
|
-
return String(major);
|
|
58
|
+
if (!serverVersion || serverVersion <= 0) return null;
|
|
59
|
+
const major = Math.floor(serverVersion / 1e4);
|
|
60
|
+
return String(major);
|
|
69
61
|
};
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
description: "user psqlrc (versioned)",
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
out.push({
|
|
120
|
-
path: path.join(home, baseRcName),
|
|
121
|
-
description: "user psqlrc",
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
return out;
|
|
62
|
+
const psqlrcCandidates = (env, serverVersion) => {
|
|
63
|
+
const out = [];
|
|
64
|
+
const suffix = versionSuffix(serverVersion);
|
|
65
|
+
const sysDir = env.PGSYSCONFDIR;
|
|
66
|
+
if (sysDir && sysDir.length > 0) {
|
|
67
|
+
const sysBase = isWindows ? "psqlrc.conf" : "psqlrc";
|
|
68
|
+
if (suffix) out.push({
|
|
69
|
+
path: path.join(sysDir, `${sysBase}-${suffix}`),
|
|
70
|
+
description: "system psqlrc (versioned)"
|
|
71
|
+
});
|
|
72
|
+
out.push({
|
|
73
|
+
path: path.join(sysDir, sysBase),
|
|
74
|
+
description: "system psqlrc"
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const envRc = env.PSQLRC;
|
|
78
|
+
if (envRc !== void 0 && envRc !== "") {
|
|
79
|
+
out.push({
|
|
80
|
+
path: expandTilde(envRc, env),
|
|
81
|
+
description: "$PSQLRC"
|
|
82
|
+
});
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
const home = env.HOME ?? "";
|
|
86
|
+
if (isWindows) {
|
|
87
|
+
const appData = env.APPDATA;
|
|
88
|
+
const dir = appData && appData.length > 0 ? path.join(appData, "postgresql") : path.join(env.USERPROFILE ?? "", "postgresql");
|
|
89
|
+
if (suffix) out.push({
|
|
90
|
+
path: path.join(dir, `${baseRcName}-${suffix}`),
|
|
91
|
+
description: "user psqlrc (versioned)"
|
|
92
|
+
});
|
|
93
|
+
out.push({
|
|
94
|
+
path: path.join(dir, baseRcName),
|
|
95
|
+
description: "user psqlrc"
|
|
96
|
+
});
|
|
97
|
+
} else if (home.length > 0) {
|
|
98
|
+
if (suffix) out.push({
|
|
99
|
+
path: path.join(home, `${baseRcName}-${suffix}`),
|
|
100
|
+
description: "user psqlrc (versioned)"
|
|
101
|
+
});
|
|
102
|
+
out.push({
|
|
103
|
+
path: path.join(home, baseRcName),
|
|
104
|
+
description: "user psqlrc"
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
125
108
|
};
|
|
126
109
|
const expandTilde = (p, env) => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (p === "~" && env.HOME) {
|
|
131
|
-
return env.HOME;
|
|
132
|
-
}
|
|
133
|
-
return p;
|
|
110
|
+
if (p.startsWith("~/") && env.HOME) return path.join(env.HOME, p.slice(2));
|
|
111
|
+
if (p === "~" && env.HOME) return env.HOME;
|
|
112
|
+
return p;
|
|
134
113
|
};
|
|
135
|
-
// ---------------------------------------------------------------------------
|
|
136
|
-
// File read + dispatch.
|
|
137
|
-
// ---------------------------------------------------------------------------
|
|
138
114
|
const readIfExists = async (file) => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
// Permission / I/O errors propagate — they're worth surfacing because
|
|
147
|
-
// they signal a likely misconfiguration. Mirror upstream which prints
|
|
148
|
-
// a warning but doesn't abort the session; we use a noop for now.
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
115
|
+
try {
|
|
116
|
+
return await promises.readFile(file, "utf8");
|
|
117
|
+
} catch (err) {
|
|
118
|
+
const code = err.code;
|
|
119
|
+
if (code === "ENOENT" || code === "ENOTDIR") return null;
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
151
122
|
};
|
|
152
123
|
const makeBackslashContext = (ctx, cmdName, rawArgs, queryBuf) => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
attachCondStack(bctx, ctx.cond);
|
|
182
|
-
return bctx;
|
|
124
|
+
const varLookup = (name) => ctx.settings.vars.get(name);
|
|
125
|
+
const buffered = /* @__PURE__ */ new Map();
|
|
126
|
+
const cursors = /* @__PURE__ */ new Map();
|
|
127
|
+
const argsFor = (mode) => {
|
|
128
|
+
const cached = buffered.get(mode);
|
|
129
|
+
if (cached) return cached;
|
|
130
|
+
const parsed = scanSlashArgs(rawArgs, mode, varLookup);
|
|
131
|
+
buffered.set(mode, parsed);
|
|
132
|
+
return parsed;
|
|
133
|
+
};
|
|
134
|
+
const bctx = {
|
|
135
|
+
settings: ctx.settings,
|
|
136
|
+
cmdName,
|
|
137
|
+
queryBuf,
|
|
138
|
+
rawArgs,
|
|
139
|
+
nextArg(mode = "normal") {
|
|
140
|
+
const av = argsFor(mode);
|
|
141
|
+
const idx = cursors.get(mode) ?? 0;
|
|
142
|
+
if (idx >= av.length) return null;
|
|
143
|
+
cursors.set(mode, idx + 1);
|
|
144
|
+
return av[idx];
|
|
145
|
+
},
|
|
146
|
+
restOfLine() {
|
|
147
|
+
return rawArgs;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
attachCondStack(bctx, ctx.cond);
|
|
151
|
+
return bctx;
|
|
183
152
|
};
|
|
184
153
|
/**
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
working = "";
|
|
335
|
-
}
|
|
336
|
-
// Tail dispatch: if the file ended mid-statement (no trailing `;`), run
|
|
337
|
-
// the residue. This matches `process_file` behaviour in upstream.
|
|
338
|
-
const tail = queryBuf.trim();
|
|
339
|
-
if (tail.length > 0 && ctx.settings.db && ctx.cond.isActive()) {
|
|
340
|
-
if (print) {
|
|
341
|
-
const stats = await sendQuery(ctx, queryBuf);
|
|
342
|
-
// LATCH, same as the semicolon branch — a trailing statement (no `;`)
|
|
343
|
-
// that succeeds must not clear an earlier error, or `-c "bad; ok"`
|
|
344
|
-
// wrongly exits 0. The function's latch invariant applies
|
|
345
|
-
// to the tail path too.
|
|
346
|
-
if (stats.hadError)
|
|
347
|
-
hadError = true;
|
|
348
|
-
noteConnectionLost();
|
|
349
|
-
}
|
|
350
|
-
else {
|
|
351
|
-
try {
|
|
352
|
-
await ctx.settings.db.execSimple(queryBuf);
|
|
353
|
-
}
|
|
354
|
-
catch (err) {
|
|
355
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
356
|
-
ctx.stderr.write(`psql: ERROR: ${msg}\n`);
|
|
357
|
-
hadError = true;
|
|
358
|
-
noteConnectionLost();
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
return { hadError, stoppedOnError, connectionLost };
|
|
154
|
+
* Execute the supplied input string against the running REPL context. Used
|
|
155
|
+
* by `loadPsqlrc` (and exported for tests). This is a minimal cousin of
|
|
156
|
+
* `runMainLoop`'s processChunk — see the module header for the duplication
|
|
157
|
+
* rationale.
|
|
158
|
+
*
|
|
159
|
+
* Returns when EOF is reached; `\q` and other exit commands inside an rc
|
|
160
|
+
* file are treated as "stop reading this file" (the REPL itself continues).
|
|
161
|
+
*
|
|
162
|
+
* The returned outcome lets `runPsql`'s `-c`/`-f` loop apply upstream's
|
|
163
|
+
* per-switch exit-code semantics (see comment above).
|
|
164
|
+
*/
|
|
165
|
+
const executeInputString = async (input, ctx, opts = {}) => {
|
|
166
|
+
let working = input;
|
|
167
|
+
let queryBuf = "";
|
|
168
|
+
let scanState = initialScanState();
|
|
169
|
+
let hadError = false;
|
|
170
|
+
let stoppedOnError = false;
|
|
171
|
+
let connectionLost = false;
|
|
172
|
+
const print = opts.print ?? false;
|
|
173
|
+
const noteConnectionLost = () => {
|
|
174
|
+
if (ctx.settings.db?.isClosed()) {
|
|
175
|
+
ctx.stderr.write("psql: error: connection to server was lost\n");
|
|
176
|
+
connectionLost = true;
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
return false;
|
|
180
|
+
};
|
|
181
|
+
const sqlVarLookup = (name) => ctx.settings.vars.get(name);
|
|
182
|
+
while (working.length > 0) {
|
|
183
|
+
const r = scanSql(working, scanState, sqlVarLookup);
|
|
184
|
+
scanState = r.nextState;
|
|
185
|
+
if (r.kind === "semicolon") {
|
|
186
|
+
const sqlText = queryBuf + r.sql;
|
|
187
|
+
queryBuf = "";
|
|
188
|
+
working = working.slice(r.consumed);
|
|
189
|
+
scanState = initialScanState();
|
|
190
|
+
if (!ctx.cond.isActive()) continue;
|
|
191
|
+
if (sqlText.trim().length === 0) continue;
|
|
192
|
+
if (!ctx.settings.db) continue;
|
|
193
|
+
if (print) {
|
|
194
|
+
const stats = await sendQuery(ctx, sqlText);
|
|
195
|
+
if (stats.hadError) hadError = true;
|
|
196
|
+
if (noteConnectionLost()) return {
|
|
197
|
+
hadError,
|
|
198
|
+
stoppedOnError,
|
|
199
|
+
connectionLost
|
|
200
|
+
};
|
|
201
|
+
if (stats.hadError && ctx.settings.onErrorStop) {
|
|
202
|
+
stoppedOnError = true;
|
|
203
|
+
return {
|
|
204
|
+
hadError,
|
|
205
|
+
stoppedOnError,
|
|
206
|
+
connectionLost
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
} else try {
|
|
210
|
+
await ctx.settings.db.execSimple(sqlText);
|
|
211
|
+
} catch (err) {
|
|
212
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
213
|
+
ctx.stderr.write(`psql: ERROR: ${msg}\n`);
|
|
214
|
+
hadError = true;
|
|
215
|
+
if (noteConnectionLost()) return {
|
|
216
|
+
hadError,
|
|
217
|
+
stoppedOnError,
|
|
218
|
+
connectionLost
|
|
219
|
+
};
|
|
220
|
+
if (ctx.settings.onErrorStop) {
|
|
221
|
+
stoppedOnError = true;
|
|
222
|
+
return {
|
|
223
|
+
hadError,
|
|
224
|
+
stoppedOnError,
|
|
225
|
+
connectionLost
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (r.kind === "backslash") {
|
|
232
|
+
queryBuf += r.sql;
|
|
233
|
+
working = working.slice(r.consumed);
|
|
234
|
+
const cmdName = r.cmd;
|
|
235
|
+
if (COND_COMMAND_NAMES.has(cmdName)) continue;
|
|
236
|
+
if (!ctx.cond.isActive()) continue;
|
|
237
|
+
const bctx = makeBackslashContext(ctx, cmdName, r.rest, queryBuf);
|
|
238
|
+
let res;
|
|
239
|
+
try {
|
|
240
|
+
res = await dispatchBackslash(ctx.registry, cmdName, bctx);
|
|
241
|
+
} catch (err) {
|
|
242
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
243
|
+
ctx.stderr.write(`psql: ERROR: ${msg}\n`);
|
|
244
|
+
hadError = true;
|
|
245
|
+
if (ctx.settings.onErrorStop) {
|
|
246
|
+
stoppedOnError = true;
|
|
247
|
+
return {
|
|
248
|
+
hadError,
|
|
249
|
+
stoppedOnError,
|
|
250
|
+
connectionLost
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (res.status === "exit") return {
|
|
256
|
+
hadError,
|
|
257
|
+
stoppedOnError,
|
|
258
|
+
connectionLost
|
|
259
|
+
};
|
|
260
|
+
if (res.status === "reset-buf") {
|
|
261
|
+
queryBuf = res.newBuf ?? "";
|
|
262
|
+
scanState = initialScanState();
|
|
263
|
+
}
|
|
264
|
+
if (res.status === "error") {
|
|
265
|
+
queryBuf = "";
|
|
266
|
+
scanState = initialScanState();
|
|
267
|
+
}
|
|
268
|
+
if (res.status === "error") hadError = true;
|
|
269
|
+
if (noteConnectionLost()) return {
|
|
270
|
+
hadError,
|
|
271
|
+
stoppedOnError,
|
|
272
|
+
connectionLost
|
|
273
|
+
};
|
|
274
|
+
if (res.status === "error" && ctx.settings.onErrorStop) {
|
|
275
|
+
stoppedOnError = true;
|
|
276
|
+
return {
|
|
277
|
+
hadError,
|
|
278
|
+
stoppedOnError,
|
|
279
|
+
connectionLost
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
queryBuf += r.sql;
|
|
285
|
+
working = "";
|
|
286
|
+
}
|
|
287
|
+
if (queryBuf.trim().length > 0 && ctx.settings.db && ctx.cond.isActive()) if (print) {
|
|
288
|
+
if ((await sendQuery(ctx, queryBuf)).hadError) hadError = true;
|
|
289
|
+
noteConnectionLost();
|
|
290
|
+
} else try {
|
|
291
|
+
await ctx.settings.db.execSimple(queryBuf);
|
|
292
|
+
} catch (err) {
|
|
293
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
294
|
+
ctx.stderr.write(`psql: ERROR: ${msg}\n`);
|
|
295
|
+
hadError = true;
|
|
296
|
+
noteConnectionLost();
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
hadError,
|
|
300
|
+
stoppedOnError,
|
|
301
|
+
connectionLost
|
|
302
|
+
};
|
|
363
303
|
};
|
|
364
304
|
/**
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
try {
|
|
406
|
-
await executeInputString(content, ctx);
|
|
407
|
-
}
|
|
408
|
-
finally {
|
|
409
|
-
ctx.settings.curCmdSource = prevSource;
|
|
410
|
-
}
|
|
411
|
-
if (isSystem) {
|
|
412
|
-
systemDone = true; // consumed the system location; move to the user one
|
|
413
|
-
continue;
|
|
414
|
-
}
|
|
415
|
-
// First user / $PSQLRC match wins; nothing further to read.
|
|
416
|
-
return;
|
|
417
|
-
}
|
|
305
|
+
* Discover and execute `.psqlrc` files against `ctx`. Honors the `-X` flag
|
|
306
|
+
* via `opts.skip = true`. Safe to call before the connection is ready —
|
|
307
|
+
* commands that need `db` will simply no-op (see `executeInputString`).
|
|
308
|
+
*/
|
|
309
|
+
const loadPsqlrc = async (ctx, opts = {}) => {
|
|
310
|
+
if (opts.skip) return;
|
|
311
|
+
const env = opts.env ?? process.env;
|
|
312
|
+
if (opts.path !== void 0) {
|
|
313
|
+
const content = await readIfExists(opts.path);
|
|
314
|
+
if (content === null) return;
|
|
315
|
+
const prevSource = ctx.settings.curCmdSource;
|
|
316
|
+
ctx.settings.curCmdSource = "rcfile";
|
|
317
|
+
try {
|
|
318
|
+
await executeInputString(content, ctx);
|
|
319
|
+
} finally {
|
|
320
|
+
ctx.settings.curCmdSource = prevSource;
|
|
321
|
+
}
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
const serverVersion = ctx.settings.db?.serverVersion;
|
|
325
|
+
const candidates = psqlrcCandidates(env, serverVersion);
|
|
326
|
+
let systemDone = false;
|
|
327
|
+
for (const c of candidates) {
|
|
328
|
+
const isSystem = c.description.startsWith("system");
|
|
329
|
+
if (isSystem && systemDone) continue;
|
|
330
|
+
const content = await readIfExists(c.path);
|
|
331
|
+
if (content === null) continue;
|
|
332
|
+
const prevSource = ctx.settings.curCmdSource;
|
|
333
|
+
ctx.settings.curCmdSource = "rcfile";
|
|
334
|
+
try {
|
|
335
|
+
await executeInputString(content, ctx);
|
|
336
|
+
} finally {
|
|
337
|
+
ctx.settings.curCmdSource = prevSource;
|
|
338
|
+
}
|
|
339
|
+
if (isSystem) {
|
|
340
|
+
systemDone = true;
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
418
345
|
};
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
// instead of duplicating the scan-and-dispatch loop. The duplication today is
|
|
422
|
-
// roughly 60 LOC; the refactor would shrink this file by half.
|
|
346
|
+
//#endregion
|
|
347
|
+
export { defaultPsqlrcPath, executeInputString, loadPsqlrc, psqlrcCandidates };
|