neon 3.0.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 +354 -517
- package/dist/_shared/env-core/reuse-secrets.js +159 -203
- 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 +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 +243 -303
- 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 +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 -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 +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 +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 +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 +7 -5
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"table-sizes": {
|
|
13
|
-
describe: "Size of each table (including TOAST), largest first (pg_table_size)",
|
|
14
|
-
fields: ["schema", "name", "size"],
|
|
15
|
-
emptyMessage: "No user tables found.",
|
|
16
|
-
sql: /* sql */ `
|
|
1
|
+
//#region src/utils/inspect_queries.ts
|
|
2
|
+
const INSPECT_QUERIES = {
|
|
3
|
+
"table-sizes": {
|
|
4
|
+
describe: "Size of each table (including TOAST), largest first (pg_table_size)",
|
|
5
|
+
fields: [
|
|
6
|
+
"schema",
|
|
7
|
+
"name",
|
|
8
|
+
"size"
|
|
9
|
+
],
|
|
10
|
+
emptyMessage: "No user tables found.",
|
|
11
|
+
sql: `
|
|
17
12
|
SELECT
|
|
18
13
|
n.nspname AS schema,
|
|
19
14
|
c.relname AS name,
|
|
@@ -24,13 +19,17 @@ export const INSPECT_QUERIES = {
|
|
|
24
19
|
AND n.nspname !~ '^pg_toast'
|
|
25
20
|
AND c.relkind = 'r'
|
|
26
21
|
ORDER BY pg_table_size(c.oid) DESC;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
`
|
|
23
|
+
},
|
|
24
|
+
"index-sizes": {
|
|
25
|
+
describe: "Size of each index, largest first (pg_relation_size)",
|
|
26
|
+
fields: [
|
|
27
|
+
"schema",
|
|
28
|
+
"name",
|
|
29
|
+
"size"
|
|
30
|
+
],
|
|
31
|
+
emptyMessage: "No indexes found.",
|
|
32
|
+
sql: `
|
|
34
33
|
SELECT
|
|
35
34
|
n.nspname AS schema,
|
|
36
35
|
c.relname AS name,
|
|
@@ -41,13 +40,18 @@ export const INSPECT_QUERIES = {
|
|
|
41
40
|
AND n.nspname !~ '^pg_toast'
|
|
42
41
|
AND c.relkind = 'i'
|
|
43
42
|
ORDER BY pg_relation_size(c.oid) DESC;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
`
|
|
44
|
+
},
|
|
45
|
+
"unused-indexes": {
|
|
46
|
+
describe: "Non-unique indexes with few scans — candidates for removal (pg_stat_user_indexes)",
|
|
47
|
+
fields: [
|
|
48
|
+
"table",
|
|
49
|
+
"index",
|
|
50
|
+
"index_size",
|
|
51
|
+
"index_scans"
|
|
52
|
+
],
|
|
53
|
+
emptyMessage: "No unused indexes detected.",
|
|
54
|
+
sql: `
|
|
51
55
|
SELECT
|
|
52
56
|
s.schemaname || '.' || s.relname AS "table",
|
|
53
57
|
s.indexrelname AS index,
|
|
@@ -59,26 +63,35 @@ export const INSPECT_QUERIES = {
|
|
|
59
63
|
AND NOT i.indisprimary
|
|
60
64
|
AND s.idx_scan < 50
|
|
61
65
|
ORDER BY pg_relation_size(s.indexrelid) DESC, s.idx_scan ASC;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
`
|
|
67
|
+
},
|
|
68
|
+
"seq-scans": {
|
|
69
|
+
describe: "Number of sequential scans recorded against each table (pg_stat_user_tables)",
|
|
70
|
+
fields: [
|
|
71
|
+
"schema",
|
|
72
|
+
"name",
|
|
73
|
+
"count"
|
|
74
|
+
],
|
|
75
|
+
emptyMessage: "No user tables found.",
|
|
76
|
+
sql: `
|
|
69
77
|
SELECT
|
|
70
78
|
schemaname AS schema,
|
|
71
79
|
relname AS name,
|
|
72
80
|
seq_scan AS count
|
|
73
81
|
FROM pg_stat_user_tables
|
|
74
82
|
ORDER BY seq_scan DESC;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
`
|
|
84
|
+
},
|
|
85
|
+
"long-running-queries": {
|
|
86
|
+
describe: "Queries running longer than 5 minutes (pg_stat_activity)",
|
|
87
|
+
fields: [
|
|
88
|
+
"pid",
|
|
89
|
+
"duration",
|
|
90
|
+
"state",
|
|
91
|
+
"query"
|
|
92
|
+
],
|
|
93
|
+
emptyMessage: "No long-running queries.",
|
|
94
|
+
sql: `
|
|
82
95
|
SELECT
|
|
83
96
|
pid,
|
|
84
97
|
(now() - query_start)::text AS duration,
|
|
@@ -89,21 +102,21 @@ export const INSPECT_QUERIES = {
|
|
|
89
102
|
AND query NOT ILIKE '%pg_stat_activity%'
|
|
90
103
|
AND now() - query_start > interval '5 minutes'
|
|
91
104
|
ORDER BY now() - query_start DESC;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
`
|
|
106
|
+
},
|
|
107
|
+
locks: {
|
|
108
|
+
describe: "Locks held with the acquiring query and its age (pg_locks + pg_stat_activity)",
|
|
109
|
+
fields: [
|
|
110
|
+
"pid",
|
|
111
|
+
"relname",
|
|
112
|
+
"mode",
|
|
113
|
+
"locktype",
|
|
114
|
+
"granted",
|
|
115
|
+
"age",
|
|
116
|
+
"query"
|
|
117
|
+
],
|
|
118
|
+
emptyMessage: "No locks held.",
|
|
119
|
+
sql: `
|
|
107
120
|
SELECT
|
|
108
121
|
a.pid,
|
|
109
122
|
c.relname,
|
|
@@ -118,14 +131,19 @@ export const INSPECT_QUERIES = {
|
|
|
118
131
|
WHERE a.query <> '<insufficient privilege>'
|
|
119
132
|
AND l.pid <> pg_backend_pid()
|
|
120
133
|
ORDER BY a.query_start;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
`
|
|
135
|
+
},
|
|
136
|
+
outliers: {
|
|
137
|
+
describe: "Queries taking the most cumulative execution time (needs pg_stat_statements)",
|
|
138
|
+
fields: [
|
|
139
|
+
"total_exec_time",
|
|
140
|
+
"prop_exec_time",
|
|
141
|
+
"ncalls",
|
|
142
|
+
"query"
|
|
143
|
+
],
|
|
144
|
+
emptyMessage: "No statements recorded yet.",
|
|
145
|
+
requiresExtension: "pg_stat_statements",
|
|
146
|
+
sql: `
|
|
129
147
|
SELECT
|
|
130
148
|
(interval '1 millisecond' * total_exec_time)::text AS total_exec_time,
|
|
131
149
|
to_char(
|
|
@@ -139,14 +157,19 @@ export const INSPECT_QUERIES = {
|
|
|
139
157
|
WHERE d.datname = current_database()
|
|
140
158
|
ORDER BY total_exec_time DESC
|
|
141
159
|
LIMIT 25;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
160
|
+
`
|
|
161
|
+
},
|
|
162
|
+
calls: {
|
|
163
|
+
describe: "Most frequently called queries (needs pg_stat_statements)",
|
|
164
|
+
fields: [
|
|
165
|
+
"ncalls",
|
|
166
|
+
"total_exec_time",
|
|
167
|
+
"prop_exec_time",
|
|
168
|
+
"query"
|
|
169
|
+
],
|
|
170
|
+
emptyMessage: "No statements recorded yet.",
|
|
171
|
+
requiresExtension: "pg_stat_statements",
|
|
172
|
+
sql: `
|
|
150
173
|
SELECT
|
|
151
174
|
calls AS ncalls,
|
|
152
175
|
(interval '1 millisecond' * total_exec_time)::text AS total_exec_time,
|
|
@@ -160,18 +183,14 @@ export const INSPECT_QUERIES = {
|
|
|
160
183
|
WHERE d.datname = current_database()
|
|
161
184
|
ORDER BY calls DESC
|
|
162
185
|
LIMIT 25;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
// neon_lfc_stats / neon_stat_file_cache views: those views are owned by
|
|
172
|
-
// cloud_admin and are not always readable by end-user roles, whereas the
|
|
173
|
-
// function is EXECUTE-able by the default role.
|
|
174
|
-
sql: /* sql */ `
|
|
186
|
+
`
|
|
187
|
+
},
|
|
188
|
+
"lfc-hit-rate": {
|
|
189
|
+
describe: "Local File Cache hit rate (needs neon extension)",
|
|
190
|
+
fields: ["name", "ratio"],
|
|
191
|
+
emptyMessage: "No LFC stats available.",
|
|
192
|
+
requiresExtension: "neon",
|
|
193
|
+
sql: `
|
|
175
194
|
WITH lfc AS (
|
|
176
195
|
SELECT lfc_key AS k, lfc_value AS v
|
|
177
196
|
FROM neon_get_lfc_stats() t(lfc_key text, lfc_value bigint)
|
|
@@ -185,14 +204,19 @@ export const INSPECT_QUERIES = {
|
|
|
185
204
|
0
|
|
186
205
|
) AS ratio
|
|
187
206
|
FROM lfc;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
207
|
+
`
|
|
208
|
+
},
|
|
209
|
+
"working-set": {
|
|
210
|
+
describe: "Estimated working set vs LFC size (needs neon extension)",
|
|
211
|
+
fields: [
|
|
212
|
+
"window",
|
|
213
|
+
"working_set",
|
|
214
|
+
"lfc_size",
|
|
215
|
+
"exceeds_lfc"
|
|
216
|
+
],
|
|
217
|
+
emptyMessage: "No working-set estimate available.",
|
|
218
|
+
requiresExtension: "neon",
|
|
219
|
+
sql: `
|
|
196
220
|
SELECT
|
|
197
221
|
w.window,
|
|
198
222
|
pg_size_pretty(w.working_set_bytes) AS working_set,
|
|
@@ -211,21 +235,21 @@ export const INSPECT_QUERIES = {
|
|
|
211
235
|
FROM (VALUES ('1m'), ('5m'), ('15m'), ('1h')) AS t(x)
|
|
212
236
|
) w
|
|
213
237
|
ORDER BY working_set_bytes;
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
238
|
+
`
|
|
239
|
+
},
|
|
240
|
+
"vacuum-stats": {
|
|
241
|
+
describe: "Autovacuum status per table: last (auto)vacuum, dead tuples, threshold",
|
|
242
|
+
fields: [
|
|
243
|
+
"schema",
|
|
244
|
+
"table",
|
|
245
|
+
"last_vacuum",
|
|
246
|
+
"last_autovacuum",
|
|
247
|
+
"rowcount",
|
|
248
|
+
"dead_rowcount",
|
|
249
|
+
"expect_autovacuum"
|
|
250
|
+
],
|
|
251
|
+
emptyMessage: "No user tables found.",
|
|
252
|
+
sql: `
|
|
229
253
|
SELECT
|
|
230
254
|
n.nspname AS schema,
|
|
231
255
|
c.relname AS "table",
|
|
@@ -245,13 +269,19 @@ export const INSPECT_QUERIES = {
|
|
|
245
269
|
JOIN pg_class c ON psut.relid = c.oid
|
|
246
270
|
JOIN pg_namespace n ON c.relnamespace = n.oid
|
|
247
271
|
ORDER BY psut.n_dead_tup DESC;
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
272
|
+
`
|
|
273
|
+
},
|
|
274
|
+
bloat: {
|
|
275
|
+
describe: "Estimated table/index bloat (statistical estimate, no extension needed)",
|
|
276
|
+
fields: [
|
|
277
|
+
"type",
|
|
278
|
+
"schema",
|
|
279
|
+
"object_name",
|
|
280
|
+
"bloat",
|
|
281
|
+
"waste"
|
|
282
|
+
],
|
|
283
|
+
emptyMessage: "No bloat estimate available.",
|
|
284
|
+
sql: `
|
|
255
285
|
WITH constants AS (
|
|
256
286
|
SELECT current_setting('block_size')::numeric AS bs, 23 AS hdr, 8 AS ma
|
|
257
287
|
),
|
|
@@ -300,22 +330,22 @@ export const INSPECT_QUERIES = {
|
|
|
300
330
|
FROM table_bloat
|
|
301
331
|
ORDER BY (CASE WHEN relpages < otta THEN 0 ELSE bs * (relpages - otta) END) DESC
|
|
302
332
|
LIMIT 25;
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
333
|
+
`
|
|
334
|
+
},
|
|
335
|
+
"replication-slots": {
|
|
336
|
+
describe: "Replication slots: kind, status, client, restart/confirmed-flush LSNs, and lag (pg_replication_slots + pg_stat_replication)",
|
|
337
|
+
fields: [
|
|
338
|
+
"slot_name",
|
|
339
|
+
"slot_type",
|
|
340
|
+
"slot_kind",
|
|
341
|
+
"status",
|
|
342
|
+
"client_addr",
|
|
343
|
+
"restart_lsn",
|
|
344
|
+
"confirmed_flush_lsn",
|
|
345
|
+
"replication_lag"
|
|
346
|
+
],
|
|
347
|
+
emptyMessage: "No replication slots found.",
|
|
348
|
+
sql: `
|
|
319
349
|
SELECT
|
|
320
350
|
s.slot_name,
|
|
321
351
|
s.slot_type,
|
|
@@ -345,13 +375,18 @@ export const INSPECT_QUERIES = {
|
|
|
345
375
|
FROM pg_replication_slots s
|
|
346
376
|
LEFT JOIN pg_stat_replication r ON r.pid = s.active_pid
|
|
347
377
|
ORDER BY s.slot_name;
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
378
|
+
`
|
|
379
|
+
},
|
|
380
|
+
subscriptions: {
|
|
381
|
+
describe: "Per-table logical replication progress on this subscriber (pg_subscription_rel)",
|
|
382
|
+
fields: [
|
|
383
|
+
"subscription",
|
|
384
|
+
"table_name",
|
|
385
|
+
"status",
|
|
386
|
+
"lsn"
|
|
387
|
+
],
|
|
388
|
+
emptyMessage: "No subscriptions found on this database.",
|
|
389
|
+
sql: `
|
|
355
390
|
SELECT
|
|
356
391
|
sub.subname AS subscription,
|
|
357
392
|
sr.srrelid::regclass::text AS table_name,
|
|
@@ -367,6 +402,8 @@ export const INSPECT_QUERIES = {
|
|
|
367
402
|
FROM pg_subscription_rel sr
|
|
368
403
|
JOIN pg_subscription sub ON sub.oid = sr.srsubid
|
|
369
404
|
ORDER BY sub.subname, table_name;
|
|
370
|
-
|
|
371
|
-
|
|
405
|
+
`
|
|
406
|
+
}
|
|
372
407
|
};
|
|
408
|
+
//#endregion
|
|
409
|
+
export { INSPECT_QUERIES };
|
|
@@ -1,49 +1,42 @@
|
|
|
1
1
|
import { recordCredentialInputs } from "../_shared/auth_selection.js";
|
|
2
|
+
//#region src/utils/middlewares.ts
|
|
2
3
|
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
args.apiKey = fromEnv;
|
|
28
|
-
args["api-key"] = fromEnv;
|
|
4
|
+
* Resolves `--api-key` from `NEON_API_KEY` when the flag is absent, leaving it an
|
|
5
|
+
* empty string when neither is set.
|
|
6
|
+
*
|
|
7
|
+
* This cannot be expressed as the option's yargs `default`, because yargs prints
|
|
8
|
+
* defaults in help output and would print the key itself.
|
|
9
|
+
*
|
|
10
|
+
* This is also the one place that reads the credential environment, and it records what it saw
|
|
11
|
+
* before folding anything together. Folding destroys the distinction the precedence rules turn
|
|
12
|
+
* on — `--api-key` outranks `--profile` and an exported `NEON_API_KEY` does not, but once both
|
|
13
|
+
* live in `args.apiKey` they are indistinguishable. The snapshot lives outside `args`
|
|
14
|
+
* deliberately: a hidden yargs option would be a second, undocumented way to pass a
|
|
15
|
+
* credential, and commands that call `.strict()` reject arguments the middleware invents.
|
|
16
|
+
*/
|
|
17
|
+
const resolveApiKeyFromEnv = (args) => {
|
|
18
|
+
const fromFlag = typeof args.apiKey === "string" ? args.apiKey : "";
|
|
19
|
+
const fromEnv = process.env.NEON_API_KEY ?? "";
|
|
20
|
+
recordCredentialInputs({
|
|
21
|
+
apiKeyFlag: fromFlag,
|
|
22
|
+
apiKeyEnv: fromEnv,
|
|
23
|
+
profileEnv: process.env.NEON_PROFILE ?? ""
|
|
24
|
+
});
|
|
25
|
+
if (fromFlag !== "") return;
|
|
26
|
+
args.apiKey = fromEnv;
|
|
27
|
+
args["api-key"] = fromEnv;
|
|
29
28
|
};
|
|
30
29
|
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (typeof v === "object" && v !== null) {
|
|
42
|
-
fillInArgs(args, v, [...acc, k]);
|
|
43
|
-
}
|
|
44
|
-
else if (acc.length > 0) {
|
|
45
|
-
// if it's not an object, and we have a path, fill it in
|
|
46
|
-
args[acc.join(".") + "." + k] = v;
|
|
47
|
-
}
|
|
48
|
-
});
|
|
30
|
+
* This middleware is needed to fill in the args for nested objects,
|
|
31
|
+
* so that required arguments would work
|
|
32
|
+
* otherwise yargs just throws an error
|
|
33
|
+
*/
|
|
34
|
+
const fillInArgs = (args, currentArgs = args, acc = []) => {
|
|
35
|
+
Object.entries(currentArgs).forEach(([k, v]) => {
|
|
36
|
+
if (k === "_" || k === "--") return;
|
|
37
|
+
if (typeof v === "object" && v !== null) fillInArgs(args, v, [...acc, k]);
|
|
38
|
+
else if (acc.length > 0) args[acc.join(".") + "." + k] = v;
|
|
39
|
+
});
|
|
49
40
|
};
|
|
41
|
+
//#endregion
|
|
42
|
+
export { fillInArgs, resolveApiKeyFromEnv };
|