neon 2.47.0 → 3.1.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 +54 -0
- package/dist/_shared/auth_selection.js +76 -79
- package/dist/_shared/credentials.js +166 -187
- package/dist/_shared/env-core/env.js +395 -0
- package/dist/_shared/env-core/reuse-secrets.js +179 -0
- package/dist/_shared/paths.js +129 -126
- package/dist/_shared/profiles.js +192 -242
- package/dist/_shared/secure_file.js +36 -38
- package/dist/_virtual/_rolldown/runtime.js +13 -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 +575 -658
- 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 +642 -681
- package/dist/commands/diff.js +156 -200
- package/dist/commands/env.js +243 -303
- package/dist/commands/functions.js +275 -341
- 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 +614 -845
- 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 +313 -394
- package/dist/dev/functions.js +54 -64
- 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 +36 -38
- 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 +727 -983
- 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 +1293 -2082
- 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 +547 -1099
- package/dist/psql/command/cmd_restrict.js +119 -155
- package/dist/psql/command/cmd_show.js +529 -688
- package/dist/psql/command/dispatch.js +261 -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 +762 -1180
- package/dist/psql/core/help.js +456 -546
- package/dist/psql/core/mainloop.js +692 -1302
- 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 +626 -815
- 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 +1414 -1927
- 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 +2 -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 +133 -147
- 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 +37 -44
- 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 +9 -7
package/dist/psql/io/pgpass.js
CHANGED
|
@@ -1,202 +1,173 @@
|
|
|
1
|
-
|
|
2
|
-
* `~/.pgpass` password-file support.
|
|
3
|
-
*
|
|
4
|
-
* TypeScript port of the relevant portion of `src/interfaces/libpq/fe-connect.c`
|
|
5
|
-
* (`passwordFromFile`) plus the path/permission rules described in upstream
|
|
6
|
-
* psql's docs (`doc/src/sgml/libpq.sgml`, "The Password File" chapter).
|
|
7
|
-
*
|
|
8
|
-
* On-disk format:
|
|
9
|
-
*
|
|
10
|
-
* host:port:database:user:password
|
|
11
|
-
*
|
|
12
|
-
* - One entry per line.
|
|
13
|
-
* - Comments start with `#` and run to the end of the line.
|
|
14
|
-
* - Any field may be `*` to match anything.
|
|
15
|
-
* - A literal `:` or `\` in any field must be escaped with `\` (so a password
|
|
16
|
-
* containing `:` is written `\:`, a literal `\` becomes `\\`). The escape
|
|
17
|
-
* applies after the `#` stripping but before field splitting — libpq itself
|
|
18
|
-
* only honours the escape during field tokenisation.
|
|
19
|
-
*
|
|
20
|
-
* Permission check (POSIX only):
|
|
21
|
-
*
|
|
22
|
-
* libpq refuses to read a .pgpass with group or world read/write bits set.
|
|
23
|
-
* The exact check is `(st.st_mode & (S_IRWXG | S_IRWXO))` — i.e. `0o077`
|
|
24
|
-
* masked against the mode. We mirror that: if any of those bits are set we
|
|
25
|
-
* skip the file and emit a single warning to stderr. Windows skips the check
|
|
26
|
-
* entirely (libpq does the same — `geteuid` / `S_IRWXG` aren't portable).
|
|
27
|
-
*/
|
|
28
|
-
import { promises as fs } from "node:fs";
|
|
29
|
-
import * as os from "node:os";
|
|
1
|
+
import { promises } from "node:fs";
|
|
30
2
|
import * as path from "node:path";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
//#region src/psql/io/pgpass.ts
|
|
5
|
+
/**
|
|
6
|
+
* `~/.pgpass` password-file support.
|
|
7
|
+
*
|
|
8
|
+
* TypeScript port of the relevant portion of `src/interfaces/libpq/fe-connect.c`
|
|
9
|
+
* (`passwordFromFile`) plus the path/permission rules described in upstream
|
|
10
|
+
* psql's docs (`doc/src/sgml/libpq.sgml`, "The Password File" chapter).
|
|
11
|
+
*
|
|
12
|
+
* On-disk format:
|
|
13
|
+
*
|
|
14
|
+
* host:port:database:user:password
|
|
15
|
+
*
|
|
16
|
+
* - One entry per line.
|
|
17
|
+
* - Comments start with `#` and run to the end of the line.
|
|
18
|
+
* - Any field may be `*` to match anything.
|
|
19
|
+
* - A literal `:` or `\` in any field must be escaped with `\` (so a password
|
|
20
|
+
* containing `:` is written `\:`, a literal `\` becomes `\\`). The escape
|
|
21
|
+
* applies after the `#` stripping but before field splitting — libpq itself
|
|
22
|
+
* only honours the escape during field tokenisation.
|
|
23
|
+
*
|
|
24
|
+
* Permission check (POSIX only):
|
|
25
|
+
*
|
|
26
|
+
* libpq refuses to read a .pgpass with group or world read/write bits set.
|
|
27
|
+
* The exact check is `(st.st_mode & (S_IRWXG | S_IRWXO))` — i.e. `0o077`
|
|
28
|
+
* masked against the mode. We mirror that: if any of those bits are set we
|
|
29
|
+
* skip the file and emit a single warning to stderr. Windows skips the check
|
|
30
|
+
* entirely (libpq does the same — `geteuid` / `S_IRWXG` aren't portable).
|
|
31
|
+
*/
|
|
31
32
|
const isWindows = process.platform === "win32";
|
|
32
33
|
/**
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// Fall through to homedir() if APPDATA isn't set — degrade gracefully on
|
|
52
|
-
// a minimally configured Windows session.
|
|
53
|
-
}
|
|
54
|
-
const home = env.HOME ?? os.homedir();
|
|
55
|
-
return path.join(home, ".pgpass");
|
|
34
|
+
* Return the default `.pgpass` path:
|
|
35
|
+
*
|
|
36
|
+
* - `$PGPASSFILE` if set and non-empty
|
|
37
|
+
* - `%APPDATA%\postgresql\pgpass.conf` on Windows
|
|
38
|
+
* - `$HOME/.pgpass` (falling back to `os.homedir()`) otherwise
|
|
39
|
+
*
|
|
40
|
+
* Pure function — `env` defaults to `process.env` but can be injected for
|
|
41
|
+
* tests.
|
|
42
|
+
*/
|
|
43
|
+
const defaultPgPassPath = (env = process.env) => {
|
|
44
|
+
const explicit = env.PGPASSFILE;
|
|
45
|
+
if (explicit !== void 0 && explicit.length > 0) return explicit;
|
|
46
|
+
if (isWindows) {
|
|
47
|
+
const appdata = env.APPDATA;
|
|
48
|
+
if (appdata !== void 0 && appdata.length > 0) return path.join(appdata, "postgresql", "pgpass.conf");
|
|
49
|
+
}
|
|
50
|
+
const home = env.HOME ?? os.homedir();
|
|
51
|
+
return path.join(home, ".pgpass");
|
|
56
52
|
};
|
|
57
53
|
/**
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
54
|
+
* Split a `.pgpass` line into its five fields, respecting `\:` and `\\`
|
|
55
|
+
* escapes. Returns `null` for lines that don't yield exactly five fields
|
|
56
|
+
* (malformed entries are silently ignored, matching libpq).
|
|
57
|
+
*
|
|
58
|
+
* Escape semantics (mirroring libpq's `passwordFromFile`):
|
|
59
|
+
* - `\X` for any X consumes the backslash and emits X literally; the only
|
|
60
|
+
* escapes intended for `.pgpass` are `\:` (literal colon) and `\\`
|
|
61
|
+
* (literal backslash), but libpq's decoder is lenient.
|
|
62
|
+
* - A trailing backslash at end-of-line is dropped.
|
|
63
|
+
*/
|
|
68
64
|
/** Un-escape `\X` → `X` (a trailing lone backslash is kept). */
|
|
69
65
|
const decodeBackslashes = (s) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
66
|
+
let out = "";
|
|
67
|
+
for (let i = 0; i < s.length; i++) {
|
|
68
|
+
if (s[i] === "\\" && i + 1 < s.length) {
|
|
69
|
+
out += s[i + 1];
|
|
70
|
+
i += 1;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
out += s[i];
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
80
76
|
};
|
|
81
77
|
const splitLine = (line) => {
|
|
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
|
-
return null;
|
|
108
|
-
return {
|
|
109
|
-
host: fields[0],
|
|
110
|
-
port: fields[1],
|
|
111
|
-
database: fields[2],
|
|
112
|
-
user: fields[3],
|
|
113
|
-
password: decodeBackslashes(fields[4]),
|
|
114
|
-
};
|
|
78
|
+
const fields = [];
|
|
79
|
+
let current = "";
|
|
80
|
+
for (let i = 0; i < line.length; i++) {
|
|
81
|
+
const ch = line[i];
|
|
82
|
+
if (ch === "\\" && i + 1 < line.length) {
|
|
83
|
+
current += "\\" + line[i + 1];
|
|
84
|
+
i += 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (ch === ":") {
|
|
88
|
+
fields.push(current);
|
|
89
|
+
current = "";
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
current += ch;
|
|
93
|
+
}
|
|
94
|
+
fields.push(current);
|
|
95
|
+
if (fields.length !== 5) return null;
|
|
96
|
+
return {
|
|
97
|
+
host: fields[0],
|
|
98
|
+
port: fields[1],
|
|
99
|
+
database: fields[2],
|
|
100
|
+
user: fields[3],
|
|
101
|
+
password: decodeBackslashes(fields[4])
|
|
102
|
+
};
|
|
115
103
|
};
|
|
116
104
|
/**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (trimmed.length === 0)
|
|
160
|
-
continue;
|
|
161
|
-
if (trimmed.startsWith("#"))
|
|
162
|
-
continue;
|
|
163
|
-
const entry = splitLine(trimmed);
|
|
164
|
-
if (entry !== null)
|
|
165
|
-
entries.push(entry);
|
|
166
|
-
}
|
|
167
|
-
return entries;
|
|
105
|
+
* Read and parse a `.pgpass` file. Resolves to `[]` for:
|
|
106
|
+
*
|
|
107
|
+
* - missing file (ENOENT / ENOTDIR)
|
|
108
|
+
* - empty file
|
|
109
|
+
* - permission gate failure on POSIX (a warning is written to `stderr`)
|
|
110
|
+
*
|
|
111
|
+
* Other I/O errors (EACCES on a directory we can stat, EIO, …) also resolve
|
|
112
|
+
* to `[]` since libpq treats `.pgpass` as best-effort: a missing or
|
|
113
|
+
* unreadable file just falls through to the next password source.
|
|
114
|
+
*/
|
|
115
|
+
const loadPgPass = async (filePath, opts) => {
|
|
116
|
+
const env = opts?.env ?? process.env;
|
|
117
|
+
const stderr = opts?.stderr ?? process.stderr;
|
|
118
|
+
const resolved = filePath ?? defaultPgPassPath(env);
|
|
119
|
+
let stat;
|
|
120
|
+
try {
|
|
121
|
+
stat = await promises.stat(resolved);
|
|
122
|
+
} catch (err) {
|
|
123
|
+
const code = err.code;
|
|
124
|
+
if (code === "ENOENT" || code === "ENOTDIR") return [];
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
if (!stat.isFile()) return [];
|
|
128
|
+
if (!isWindows && (stat.mode & 63) !== 0) {
|
|
129
|
+
stderr.write(`WARNING: password file "${resolved}" has group or world access; permissions should be u=rw (0600) or less\n`);
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
let raw;
|
|
133
|
+
try {
|
|
134
|
+
raw = await promises.readFile(resolved, "utf8");
|
|
135
|
+
} catch {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
const entries = [];
|
|
139
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
140
|
+
const trimmed = line.replace(/^\s+/, "");
|
|
141
|
+
if (trimmed.length === 0) continue;
|
|
142
|
+
if (trimmed.startsWith("#")) continue;
|
|
143
|
+
const entry = splitLine(trimmed);
|
|
144
|
+
if (entry !== null) entries.push(entry);
|
|
145
|
+
}
|
|
146
|
+
return entries;
|
|
168
147
|
};
|
|
169
148
|
/**
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const fieldMatches = (pattern, value) =>
|
|
173
|
-
// A bare `*` is the wildcard; `\*` decodes to a LITERAL `*` (review #21).
|
|
174
|
-
pattern === "*" || decodeBackslashes(pattern) === value;
|
|
149
|
+
* Match a single field. `*` matches anything; otherwise an exact comparison.
|
|
150
|
+
*/
|
|
151
|
+
const fieldMatches = (pattern, value) => pattern === "*" || decodeBackslashes(pattern) === value;
|
|
175
152
|
/**
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (!fieldMatches(e.user, target.user))
|
|
195
|
-
continue;
|
|
196
|
-
// The password field is returned literally (already decoded by
|
|
197
|
-
// splitLine). It may be empty — libpq still treats that as "found a
|
|
198
|
-
// match"; we mirror that.
|
|
199
|
-
return e.password;
|
|
200
|
-
}
|
|
201
|
-
return undefined;
|
|
153
|
+
* Look up a password entry for the given `target`. Returns the first matching
|
|
154
|
+
* entry's password, or `undefined` if nothing matches.
|
|
155
|
+
*
|
|
156
|
+
* Match semantics mirror libpq:
|
|
157
|
+
* - Fields are compared exactly (no wildcards beyond `*`).
|
|
158
|
+
* - `port` is compared as a string against the target's numeric port.
|
|
159
|
+
* - Entries are scanned top-to-bottom; the first match wins (so callers
|
|
160
|
+
* should write specific entries before generic ones).
|
|
161
|
+
*/
|
|
162
|
+
const lookupPgPass = (entries, target) => {
|
|
163
|
+
const portStr = String(target.port);
|
|
164
|
+
for (const e of entries) {
|
|
165
|
+
if (!fieldMatches(e.host, target.host)) continue;
|
|
166
|
+
if (!fieldMatches(e.port, portStr)) continue;
|
|
167
|
+
if (!fieldMatches(e.database, target.database)) continue;
|
|
168
|
+
if (!fieldMatches(e.user, target.user)) continue;
|
|
169
|
+
return e.password;
|
|
170
|
+
}
|
|
202
171
|
};
|
|
172
|
+
//#endregion
|
|
173
|
+
export { defaultPgPassPath, loadPgPass, lookupPgPass };
|