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.
Files changed (198) hide show
  1. package/README.md +54 -0
  2. package/dist/_shared/auth_selection.js +76 -79
  3. package/dist/_shared/credentials.js +166 -187
  4. package/dist/_shared/env-core/env.js +395 -0
  5. package/dist/_shared/env-core/reuse-secrets.js +179 -0
  6. package/dist/_shared/paths.js +129 -126
  7. package/dist/_shared/profiles.js +192 -242
  8. package/dist/_shared/secure_file.js +36 -38
  9. package/dist/_virtual/_rolldown/runtime.js +13 -0
  10. package/dist/analytics.js +163 -207
  11. package/dist/api.js +815 -758
  12. package/dist/auth.js +121 -141
  13. package/dist/auth_context.js +39 -53
  14. package/dist/cli.js +4 -7
  15. package/dist/commands/api.js +220 -250
  16. package/dist/commands/api_keys.js +251 -314
  17. package/dist/commands/auth.js +283 -328
  18. package/dist/commands/bootstrap.js +372 -437
  19. package/dist/commands/branches.js +304 -455
  20. package/dist/commands/bucket.js +374 -514
  21. package/dist/commands/checkout.js +213 -298
  22. package/dist/commands/config.js +575 -658
  23. package/dist/commands/connection_string.js +137 -165
  24. package/dist/commands/data_api.js +238 -260
  25. package/dist/commands/databases.js +67 -76
  26. package/dist/commands/deploy.js +31 -25
  27. package/dist/commands/dev.js +642 -681
  28. package/dist/commands/diff.js +156 -200
  29. package/dist/commands/env.js +243 -303
  30. package/dist/commands/functions.js +275 -341
  31. package/dist/commands/index.js +70 -65
  32. package/dist/commands/init.js +84 -119
  33. package/dist/commands/inspect.js +55 -55
  34. package/dist/commands/ip_allow.js +88 -120
  35. package/dist/commands/link.js +874 -1019
  36. package/dist/commands/logs.js +291 -0
  37. package/dist/commands/neon_auth.js +725 -933
  38. package/dist/commands/operations.js +34 -25
  39. package/dist/commands/orgs.js +28 -18
  40. package/dist/commands/profile.js +614 -845
  41. package/dist/commands/projects.js +313 -373
  42. package/dist/commands/psql.js +60 -58
  43. package/dist/commands/roles.js +55 -58
  44. package/dist/commands/schema_diff.js +87 -131
  45. package/dist/commands/set_context.js +34 -26
  46. package/dist/commands/snapshots.js +288 -413
  47. package/dist/commands/status.js +41 -37
  48. package/dist/commands/user.js +21 -10
  49. package/dist/commands/vpc_endpoints.js +85 -113
  50. package/dist/config.js +7 -6
  51. package/dist/config_format.js +50 -66
  52. package/dist/config_template.js +128 -157
  53. package/dist/context.js +183 -235
  54. package/dist/current_branch_fast_path.js +40 -49
  55. package/dist/dev/env.js +313 -394
  56. package/dist/dev/functions.js +54 -64
  57. package/dist/dev/inputs.js +46 -58
  58. package/dist/dev/runtime.js +135 -164
  59. package/dist/dev/websocket.js +766 -959
  60. package/dist/env.js +27 -33
  61. package/dist/env_file.js +118 -132
  62. package/dist/env_services.js +36 -38
  63. package/dist/errors.js +57 -68
  64. package/dist/functions_api.js +45 -43
  65. package/dist/help.js +189 -140
  66. package/dist/index.js +182 -257
  67. package/dist/init/agents.js +137 -118
  68. package/dist/init/auth.js +58 -68
  69. package/dist/init/bootstrap.js +325 -396
  70. package/dist/init/build_config.js +4 -2
  71. package/dist/init/detect_agent.js +56 -101
  72. package/dist/init/editors.js +35 -52
  73. package/dist/init/enrich_output.js +51 -66
  74. package/dist/init/extension.js +134 -171
  75. package/dist/init/inspect.js +179 -266
  76. package/dist/init/interactive.js +510 -622
  77. package/dist/init/neonctl.js +117 -168
  78. package/dist/init/orchestrate.js +157 -173
  79. package/dist/init/phases/auth.js +188 -202
  80. package/dist/init/phases/cleanup.js +23 -23
  81. package/dist/init/phases/db.js +251 -277
  82. package/dist/init/phases/getting_started.js +213 -223
  83. package/dist/init/phases/mcp.js +174 -224
  84. package/dist/init/phases/migrations.js +247 -248
  85. package/dist/init/phases/neon_auth.js +114 -133
  86. package/dist/init/phases/setup.js +546 -703
  87. package/dist/init/phases/skills.js +75 -86
  88. package/dist/init/phases/status.js +72 -67
  89. package/dist/init/resolve_context.js +102 -99
  90. package/dist/init/route_command.js +91 -98
  91. package/dist/init/skills.js +174 -218
  92. package/dist/init/vsix.js +77 -99
  93. package/dist/log.js +17 -16
  94. package/dist/neon_services.js +104 -129
  95. package/dist/parameters.gen.js +481 -471
  96. package/dist/pkg.js +17 -19
  97. package/dist/profile_keys.js +44 -47
  98. package/dist/psql/cli.js +44 -47
  99. package/dist/psql/command/cmd_cond.js +231 -406
  100. package/dist/psql/command/cmd_connect.js +557 -764
  101. package/dist/psql/command/cmd_copy.js +727 -983
  102. package/dist/psql/command/cmd_describe.js +1499 -1688
  103. package/dist/psql/command/cmd_format.js +733 -905
  104. package/dist/psql/command/cmd_io.js +1293 -2082
  105. package/dist/psql/command/cmd_lo.js +297 -359
  106. package/dist/psql/command/cmd_meta.js +727 -878
  107. package/dist/psql/command/cmd_misc.js +138 -172
  108. package/dist/psql/command/cmd_pipeline.js +547 -1099
  109. package/dist/psql/command/cmd_restrict.js +119 -155
  110. package/dist/psql/command/cmd_show.js +529 -688
  111. package/dist/psql/command/dispatch.js +261 -325
  112. package/dist/psql/command/inputQueue.js +35 -33
  113. package/dist/psql/command/shared.js +49 -63
  114. package/dist/psql/complete/filenames.js +90 -133
  115. package/dist/psql/complete/index.js +59 -97
  116. package/dist/psql/complete/matcher.js +236 -300
  117. package/dist/psql/complete/psqlVars.js +218 -223
  118. package/dist/psql/complete/queries.js +159 -177
  119. package/dist/psql/complete/rules.js +1493 -2299
  120. package/dist/psql/core/common.js +762 -1180
  121. package/dist/psql/core/help.js +456 -546
  122. package/dist/psql/core/mainloop.js +692 -1302
  123. package/dist/psql/core/prompt.js +391 -408
  124. package/dist/psql/core/settings.js +429 -644
  125. package/dist/psql/core/sqlHelp.js +480 -554
  126. package/dist/psql/core/startup.js +626 -815
  127. package/dist/psql/core/syncVars.js +67 -110
  128. package/dist/psql/core/variables.js +156 -278
  129. package/dist/psql/describe/formatters.js +884 -1285
  130. package/dist/psql/describe/processNamePattern.js +173 -260
  131. package/dist/psql/describe/queries.js +1368 -2403
  132. package/dist/psql/describe/versionGate.js +32 -41
  133. package/dist/psql/index.js +1414 -1927
  134. package/dist/psql/io/history.js +232 -271
  135. package/dist/psql/io/input.js +103 -108
  136. package/dist/psql/io/lineEditor/buffer.js +238 -319
  137. package/dist/psql/io/lineEditor/complete.js +135 -213
  138. package/dist/psql/io/lineEditor/filename.js +139 -148
  139. package/dist/psql/io/lineEditor/index.js +653 -870
  140. package/dist/psql/io/lineEditor/keymap.js +544 -702
  141. package/dist/psql/io/lineEditor/vt100.js +294 -341
  142. package/dist/psql/io/pgpass.js +158 -187
  143. package/dist/psql/io/pgservice.js +146 -183
  144. package/dist/psql/io/psqlrc.js +328 -403
  145. package/dist/psql/print/aligned.js +1020 -1683
  146. package/dist/psql/print/asciidoc.js +180 -214
  147. package/dist/psql/print/crosstab.js +281 -442
  148. package/dist/psql/print/csv.js +48 -70
  149. package/dist/psql/print/html.js +195 -226
  150. package/dist/psql/print/json.js +75 -88
  151. package/dist/psql/print/latex.js +291 -364
  152. package/dist/psql/print/pager.js +171 -242
  153. package/dist/psql/print/troff.js +194 -226
  154. package/dist/psql/print/unaligned.js +69 -95
  155. package/dist/psql/print/units.js +167 -169
  156. package/dist/psql/scanner/slash.js +428 -483
  157. package/dist/psql/scanner/sql.js +445 -889
  158. package/dist/psql/scanner/stringutils.js +309 -379
  159. package/dist/psql/types/index.js +2 -7
  160. package/dist/psql/types/scanner.js +25 -22
  161. package/dist/psql/wire/connection.js +2042 -2803
  162. package/dist/psql/wire/copy.js +84 -100
  163. package/dist/psql/wire/notify.js +39 -59
  164. package/dist/psql/wire/pipeline.js +305 -518
  165. package/dist/psql/wire/protocol.js +349 -417
  166. package/dist/psql/wire/sasl.js +180 -265
  167. package/dist/psql/wire/tls.js +400 -561
  168. package/dist/storage_api.js +115 -129
  169. package/dist/test_utils/fixtures.js +94 -113
  170. package/dist/test_utils/oauth_server.js +10 -7
  171. package/dist/test_utils/project_dir.js +33 -0
  172. package/dist/utils/ai_gateway_notice.js +131 -162
  173. package/dist/utils/api_enums.js +21 -28
  174. package/dist/utils/auth.js +10 -4
  175. package/dist/utils/branch_notice.js +20 -19
  176. package/dist/utils/branch_picker.js +83 -89
  177. package/dist/utils/cli_name.js +15 -12
  178. package/dist/utils/compute_units.js +20 -27
  179. package/dist/utils/config_diff.js +127 -158
  180. package/dist/utils/enrichers.js +95 -148
  181. package/dist/utils/esbuild.js +133 -147
  182. package/dist/utils/flags.js +35 -47
  183. package/dist/utils/formats.js +8 -15
  184. package/dist/utils/git_diff.js +69 -80
  185. package/dist/utils/inspect_db.js +101 -143
  186. package/dist/utils/inspect_queries.js +179 -142
  187. package/dist/utils/middlewares.js +37 -44
  188. package/dist/utils/openapi.js +87 -99
  189. package/dist/utils/package_manager.js +312 -110
  190. package/dist/utils/point_in_time.js +49 -53
  191. package/dist/utils/psql.js +89 -106
  192. package/dist/utils/service_picker.js +55 -58
  193. package/dist/utils/string.js +5 -5
  194. package/dist/utils/ui.js +38 -55
  195. package/dist/utils/write_sync.js +26 -35
  196. package/dist/utils/zip.js +4 -3
  197. package/dist/writer.js +67 -87
  198. package/package.json +9 -7
@@ -1,19 +1,14 @@
1
- /**
2
- * Diagnostic SQL for `neon inspect db`. Each entry is a read-only query against
3
- * Postgres' own statistics/catalog views plus the output columns (in display
4
- * order) the table/json/yaml formatter should show.
5
- *
6
- * Most queries need no extra extension. The few that do (currently `outliers`
7
- * and `calls`, which read `pg_stat_statements`) declare it via
8
- * `requiresExtension`; the runner checks for it and fails with an actionable
9
- * hint when it's missing.
10
- */
11
- export const INSPECT_QUERIES = {
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
- "index-sizes": {
30
- describe: "Size of each index, largest first (pg_relation_size)",
31
- fields: ["schema", "name", "size"],
32
- emptyMessage: "No indexes found.",
33
- sql: /* sql */ `
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
- "unused-indexes": {
47
- describe: "Non-unique indexes with few scans — candidates for removal (pg_stat_user_indexes)",
48
- fields: ["table", "index", "index_size", "index_scans"],
49
- emptyMessage: "No unused indexes detected.",
50
- sql: /* sql */ `
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
- "seq-scans": {
65
- describe: "Number of sequential scans recorded against each table (pg_stat_user_tables)",
66
- fields: ["schema", "name", "count"],
67
- emptyMessage: "No user tables found.",
68
- sql: /* sql */ `
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
- "long-running-queries": {
78
- describe: "Queries running longer than 5 minutes (pg_stat_activity)",
79
- fields: ["pid", "duration", "state", "query"],
80
- emptyMessage: "No long-running queries.",
81
- sql: /* sql */ `
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
- locks: {
95
- describe: "Locks held with the acquiring query and its age (pg_locks + pg_stat_activity)",
96
- fields: [
97
- "pid",
98
- "relname",
99
- "mode",
100
- "locktype",
101
- "granted",
102
- "age",
103
- "query",
104
- ],
105
- emptyMessage: "No locks held.",
106
- sql: /* sql */ `
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
- outliers: {
124
- describe: "Queries taking the most cumulative execution time (needs pg_stat_statements)",
125
- fields: ["total_exec_time", "prop_exec_time", "ncalls", "query"],
126
- emptyMessage: "No statements recorded yet.",
127
- requiresExtension: "pg_stat_statements",
128
- sql: /* sql */ `
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
- calls: {
145
- describe: "Most frequently called queries (needs pg_stat_statements)",
146
- fields: ["ncalls", "total_exec_time", "prop_exec_time", "query"],
147
- emptyMessage: "No statements recorded yet.",
148
- requiresExtension: "pg_stat_statements",
149
- sql: /* sql */ `
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
- "lfc-hit-rate": {
166
- describe: "Local File Cache hit rate (needs neon extension)",
167
- fields: ["name", "ratio"],
168
- emptyMessage: "No LFC stats available.",
169
- requiresExtension: "neon",
170
- // Read the hit/miss counters from neon_get_lfc_stats() rather than the
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
- "working-set": {
191
- describe: "Estimated working set vs LFC size (needs neon extension)",
192
- fields: ["window", "working_set", "lfc_size", "exceeds_lfc"],
193
- emptyMessage: "No working-set estimate available.",
194
- requiresExtension: "neon",
195
- sql: /* sql */ `
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
- "vacuum-stats": {
217
- describe: "Autovacuum status per table: last (auto)vacuum, dead tuples, threshold",
218
- fields: [
219
- "schema",
220
- "table",
221
- "last_vacuum",
222
- "last_autovacuum",
223
- "rowcount",
224
- "dead_rowcount",
225
- "expect_autovacuum",
226
- ],
227
- emptyMessage: "No user tables found.",
228
- sql: /* sql */ `
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
- bloat: {
251
- describe: "Estimated table/index bloat (statistical estimate, no extension needed)",
252
- fields: ["type", "schema", "object_name", "bloat", "waste"],
253
- emptyMessage: "No bloat estimate available.",
254
- sql: /* sql */ `
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
- "replication-slots": {
306
- describe: "Replication slots: kind, status, client, restart/confirmed-flush LSNs, and lag (pg_replication_slots + pg_stat_replication)",
307
- fields: [
308
- "slot_name",
309
- "slot_type",
310
- "slot_kind",
311
- "status",
312
- "client_addr",
313
- "restart_lsn",
314
- "confirmed_flush_lsn",
315
- "replication_lag",
316
- ],
317
- emptyMessage: "No replication slots found.",
318
- sql: /* sql */ `
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
- subscriptions: {
351
- describe: "Per-table logical replication progress on this subscriber (pg_subscription_rel)",
352
- fields: ["subscription", "table_name", "status", "lsn"],
353
- emptyMessage: "No subscriptions found on this database.",
354
- sql: /* sql */ `
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
- * Resolves `--api-key` from `NEON_API_KEY` when the flag is absent, leaving it an
4
- * empty string when neither is set.
5
- *
6
- * This cannot be expressed as the option's yargs `default`, because yargs prints
7
- * defaults in help output and would print the key itself.
8
- *
9
- * This is also the one place that reads the credential environment, and it records what it saw
10
- * before folding anything together. Folding destroys the distinction the precedence rules turn
11
- * on — `--api-key` outranks `--profile` and an exported `NEON_API_KEY` does not, but once both
12
- * live in `args.apiKey` they are indistinguishable. The snapshot lives outside `args`
13
- * deliberately: a hidden yargs option would be a second, undocumented way to pass a
14
- * credential, and commands that call `.strict()` reject arguments the middleware invents.
15
- */
16
- export const resolveApiKeyFromEnv = (args) => {
17
- const fromFlag = typeof args.apiKey === "string" ? args.apiKey : "";
18
- const fromEnv = process.env.NEON_API_KEY ?? "";
19
- recordCredentialInputs({
20
- apiKeyFlag: fromFlag,
21
- apiKeyEnv: fromEnv,
22
- profileEnv: process.env.NEON_PROFILE ?? "",
23
- });
24
- if (fromFlag !== "") {
25
- return;
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
- * This middleware is needed to fill in the args for nested objects,
32
- * so that required arguments would work
33
- * otherwise yargs just throws an error
34
- */
35
- export const fillInArgs = (args, currentArgs = args, acc = []) => {
36
- Object.entries(currentArgs).forEach(([k, v]) => {
37
- if (k === "_" || k === "--") {
38
- return;
39
- }
40
- // check if the value is an Object
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 };