neonctl 2.37.1 → 2.38.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.
Files changed (159) hide show
  1. package/README.md +15 -700
  2. package/bin/cli.js +3 -0
  3. package/package.json +8 -75
  4. package/dist/analytics.js +0 -168
  5. package/dist/api.js +0 -720
  6. package/dist/auth.js +0 -125
  7. package/dist/callback.html +0 -60
  8. package/dist/cli.js +0 -9
  9. package/dist/commands/api.js +0 -278
  10. package/dist/commands/auth.js +0 -214
  11. package/dist/commands/bootstrap.js +0 -481
  12. package/dist/commands/branches.js +0 -488
  13. package/dist/commands/bucket.js +0 -549
  14. package/dist/commands/checkout.js +0 -321
  15. package/dist/commands/config.js +0 -626
  16. package/dist/commands/connection_string.js +0 -172
  17. package/dist/commands/data_api.js +0 -284
  18. package/dist/commands/databases.js +0 -82
  19. package/dist/commands/deploy.js +0 -26
  20. package/dist/commands/dev.js +0 -698
  21. package/dist/commands/diff.js +0 -222
  22. package/dist/commands/env.js +0 -189
  23. package/dist/commands/functions.js +0 -373
  24. package/dist/commands/index.js +0 -62
  25. package/dist/commands/init.js +0 -73
  26. package/dist/commands/inspect.js +0 -65
  27. package/dist/commands/ip_allow.js +0 -137
  28. package/dist/commands/link.js +0 -1121
  29. package/dist/commands/neon_auth.js +0 -1028
  30. package/dist/commands/operations.js +0 -28
  31. package/dist/commands/orgs.js +0 -24
  32. package/dist/commands/projects.js +0 -413
  33. package/dist/commands/psql.js +0 -62
  34. package/dist/commands/roles.js +0 -65
  35. package/dist/commands/schema_diff.js +0 -151
  36. package/dist/commands/set_context.js +0 -29
  37. package/dist/commands/snapshots.js +0 -455
  38. package/dist/commands/status.js +0 -40
  39. package/dist/commands/user.js +0 -15
  40. package/dist/commands/vpc_endpoints.js +0 -134
  41. package/dist/config.js +0 -11
  42. package/dist/config_format.js +0 -72
  43. package/dist/context.js +0 -231
  44. package/dist/current_branch_fast_path.js +0 -55
  45. package/dist/dev/env.js +0 -244
  46. package/dist/dev/functions.js +0 -70
  47. package/dist/dev/inputs.js +0 -63
  48. package/dist/dev/runtime.js +0 -146
  49. package/dist/env.js +0 -36
  50. package/dist/env_file.js +0 -159
  51. package/dist/errors.js +0 -80
  52. package/dist/functions_api.js +0 -48
  53. package/dist/help.js +0 -146
  54. package/dist/index.js +0 -240
  55. package/dist/log.js +0 -18
  56. package/dist/parameters.gen.js +0 -480
  57. package/dist/pkg.js +0 -25
  58. package/dist/psql/cli.js +0 -53
  59. package/dist/psql/command/cmd_cond.js +0 -437
  60. package/dist/psql/command/cmd_connect.js +0 -820
  61. package/dist/psql/command/cmd_copy.js +0 -1035
  62. package/dist/psql/command/cmd_describe.js +0 -1815
  63. package/dist/psql/command/cmd_format.js +0 -948
  64. package/dist/psql/command/cmd_io.js +0 -2193
  65. package/dist/psql/command/cmd_lo.js +0 -393
  66. package/dist/psql/command/cmd_meta.js +0 -969
  67. package/dist/psql/command/cmd_misc.js +0 -187
  68. package/dist/psql/command/cmd_pipeline.js +0 -1148
  69. package/dist/psql/command/cmd_restrict.js +0 -171
  70. package/dist/psql/command/cmd_show.js +0 -766
  71. package/dist/psql/command/dispatch.js +0 -343
  72. package/dist/psql/command/inputQueue.js +0 -42
  73. package/dist/psql/command/shared.js +0 -71
  74. package/dist/psql/complete/filenames.js +0 -139
  75. package/dist/psql/complete/index.js +0 -104
  76. package/dist/psql/complete/matcher.js +0 -315
  77. package/dist/psql/complete/psqlVars.js +0 -249
  78. package/dist/psql/complete/queries.js +0 -493
  79. package/dist/psql/complete/rules.js +0 -2424
  80. package/dist/psql/core/common.js +0 -1253
  81. package/dist/psql/core/help.js +0 -576
  82. package/dist/psql/core/mainloop.js +0 -1360
  83. package/dist/psql/core/prompt.js +0 -439
  84. package/dist/psql/core/settings.js +0 -686
  85. package/dist/psql/core/sqlHelp.js +0 -1066
  86. package/dist/psql/core/startup.js +0 -846
  87. package/dist/psql/core/syncVars.js +0 -116
  88. package/dist/psql/core/variables.js +0 -287
  89. package/dist/psql/describe/formatters.js +0 -1330
  90. package/dist/psql/describe/processNamePattern.js +0 -270
  91. package/dist/psql/describe/queries.js +0 -2452
  92. package/dist/psql/describe/versionGate.js +0 -44
  93. package/dist/psql/index.js +0 -2030
  94. package/dist/psql/io/history.js +0 -299
  95. package/dist/psql/io/input.js +0 -120
  96. package/dist/psql/io/lineEditor/buffer.js +0 -325
  97. package/dist/psql/io/lineEditor/complete.js +0 -227
  98. package/dist/psql/io/lineEditor/filename.js +0 -159
  99. package/dist/psql/io/lineEditor/index.js +0 -893
  100. package/dist/psql/io/lineEditor/keymap.js +0 -745
  101. package/dist/psql/io/lineEditor/vt100.js +0 -363
  102. package/dist/psql/io/pgpass.js +0 -202
  103. package/dist/psql/io/pgservice.js +0 -194
  104. package/dist/psql/io/psqlrc.js +0 -422
  105. package/dist/psql/print/aligned.js +0 -1748
  106. package/dist/psql/print/asciidoc.js +0 -230
  107. package/dist/psql/print/crosstab.js +0 -463
  108. package/dist/psql/print/csv.js +0 -76
  109. package/dist/psql/print/html.js +0 -240
  110. package/dist/psql/print/json.js +0 -96
  111. package/dist/psql/print/latex.js +0 -379
  112. package/dist/psql/print/pager.js +0 -267
  113. package/dist/psql/print/troff.js +0 -240
  114. package/dist/psql/print/unaligned.js +0 -99
  115. package/dist/psql/print/units.js +0 -188
  116. package/dist/psql/scanner/slash.js +0 -515
  117. package/dist/psql/scanner/sql.js +0 -914
  118. package/dist/psql/scanner/stringutils.js +0 -394
  119. package/dist/psql/types/backslash.js +0 -1
  120. package/dist/psql/types/connection.js +0 -1
  121. package/dist/psql/types/index.js +0 -7
  122. package/dist/psql/types/printer.js +0 -1
  123. package/dist/psql/types/repl.js +0 -1
  124. package/dist/psql/types/scanner.js +0 -24
  125. package/dist/psql/types/settings.js +0 -1
  126. package/dist/psql/types/variables.js +0 -1
  127. package/dist/psql/wire/connection.js +0 -2857
  128. package/dist/psql/wire/copy.js +0 -108
  129. package/dist/psql/wire/notify.js +0 -59
  130. package/dist/psql/wire/pipeline.js +0 -521
  131. package/dist/psql/wire/protocol.js +0 -466
  132. package/dist/psql/wire/sasl.js +0 -294
  133. package/dist/psql/wire/tls.js +0 -602
  134. package/dist/storage_api.js +0 -147
  135. package/dist/test_utils/fixtures.js +0 -121
  136. package/dist/test_utils/oauth_server.js +0 -9
  137. package/dist/types.js +0 -1
  138. package/dist/utils/ai_gateway_notice.js +0 -180
  139. package/dist/utils/api_enums.js +0 -33
  140. package/dist/utils/auth.js +0 -5
  141. package/dist/utils/branch_notice.js +0 -22
  142. package/dist/utils/branch_picker.js +0 -103
  143. package/dist/utils/compute_units.js +0 -28
  144. package/dist/utils/config_diff.js +0 -185
  145. package/dist/utils/enrichers.js +0 -161
  146. package/dist/utils/esbuild.js +0 -158
  147. package/dist/utils/formats.js +0 -18
  148. package/dist/utils/git_diff.js +0 -90
  149. package/dist/utils/inspect_db.js +0 -153
  150. package/dist/utils/inspect_queries.js +0 -372
  151. package/dist/utils/middlewares.js +0 -20
  152. package/dist/utils/openapi.js +0 -114
  153. package/dist/utils/package_manager.js +0 -68
  154. package/dist/utils/point_in_time.js +0 -56
  155. package/dist/utils/psql.js +0 -120
  156. package/dist/utils/string.js +0 -5
  157. package/dist/utils/ui.js +0 -59
  158. package/dist/utils/zip.js +0 -4
  159. package/dist/writer.js +0 -97
@@ -1,373 +0,0 @@
1
- import { existsSync, statSync } from "node:fs";
2
- import { join } from "node:path";
3
- import { isNeonApiError, retryOnLock } from "../api.js";
4
- import { createDeployment, deleteFunction, getFunction, listFunctions, } from "../functions_api.js";
5
- import { log } from "../log.js";
6
- import { branchIdFromProps, fillSingleProject } from "../utils/enrichers.js";
7
- import { bundleEntry } from "../utils/esbuild.js";
8
- import { zipBundle } from "../utils/zip.js";
9
- import { writer } from "../writer.js";
10
- const FUNCTION_FIELDS = [
11
- "slug",
12
- "name",
13
- "invocation_url",
14
- "created_at",
15
- ];
16
- const FUNCTIONS_LIST_LIMIT = 100;
17
- // Table columns for `functions list`. `status` is a derived field (the
18
- // table writer reads flat fields only): the current deployment's status.
19
- const LIST_TABLE_FIELDS = [
20
- "slug",
21
- "name",
22
- "status",
23
- "invocation_url",
24
- "created_at",
25
- ];
26
- const DEPLOYMENT_FIELDS = [
27
- "id",
28
- "status",
29
- "runtime",
30
- "memory_mib",
31
- "created_at",
32
- ];
33
- // Deploy emits the resolved deployment plus the function's invocation_url, so a
34
- // successful `functions deploy` tells the user exactly where to call the function.
35
- const DEPLOY_RESULT_FIELDS = [
36
- "id",
37
- "status",
38
- "invocation_url",
39
- "runtime",
40
- "memory_mib",
41
- "created_at",
42
- ];
43
- // In table mode a failed build's reason gets its own "deployment error"
44
- // section after the deployment table; json/yaml carry the raw `error` field.
45
- const writeDeploymentErrorSection = (out, dep) => {
46
- if (dep.status === "failed" && dep.error) {
47
- out.write({ reason: dep.error }, { fields: ["reason"], title: "deployment error" });
48
- }
49
- };
50
- const SLUG_PATTERN = /^[a-z0-9]{1,20}$/;
51
- const SLUG_HELP = "Use 1-20 lowercase letters and digits (no hyphens or other characters).";
52
- // Entry-point discovery order inside --src.
53
- const ENTRY_CANDIDATES = ["index.ts", "index.mjs", "index.js"];
54
- // Overridable so tests can poll fast; defaults to 2s in real use.
55
- const POLL_INTERVAL_MS = Number(process.env.NEON_FUNCTIONS_POLL_INTERVAL_MS) || 2000;
56
- // Upper bound on --wait polling so the CLI never hangs (e.g. if our deployment
57
- // never shows up as current_deployment). Overridable so tests can time out fast;
58
- // defaults to 10 minutes in real use.
59
- const POLL_TIMEOUT_MS = Number(process.env.NEON_FUNCTIONS_POLL_TIMEOUT_MS) || 600000;
60
- export const command = "functions";
61
- export const describe = "Manage Neon Functions";
62
- export const aliases = ["function"];
63
- export const builder = (argv) => argv
64
- .usage("$0 function <sub-command> [options]")
65
- .options({
66
- "project-id": {
67
- describe: "Project ID",
68
- type: "string",
69
- },
70
- branch: {
71
- describe: "Branch ID or name",
72
- type: "string",
73
- },
74
- })
75
- .middleware(fillSingleProject)
76
- .command("deploy <slug>", "Deploy a function from a local directory", (yargs) => yargs
77
- .positional("slug", {
78
- describe: "Function slug (1-20 lowercase letters and digits)",
79
- type: "string",
80
- demandOption: true,
81
- })
82
- .options({
83
- src: {
84
- describe: "Function source: a directory containing index.ts, index.mjs, or index.js, or a path to the entry file",
85
- type: "string",
86
- },
87
- // Removed flags, kept hidden so old invocations fail loudly instead
88
- // of being silently ignored (the CLI has no .strictOptions()).
89
- path: {
90
- type: "string",
91
- hidden: true,
92
- },
93
- entry: {
94
- type: "string",
95
- hidden: true,
96
- },
97
- runtime: {
98
- describe: "Function runtime",
99
- type: "string",
100
- choices: ["nodejs24"],
101
- },
102
- env: {
103
- describe: "Environment variable as KEY=VALUE (repeatable)",
104
- type: "string",
105
- array: true,
106
- },
107
- wait: {
108
- describe: "Wait for the deployment to finish building",
109
- type: "boolean",
110
- default: true,
111
- },
112
- }), (args) => deploy(args))
113
- .command("list", "List functions on the branch", (yargs) => yargs, (args) => list(args))
114
- .command("get <slug>", "Show a function's details", (yargs) => yargs
115
- .positional("slug", {
116
- describe: "Function slug",
117
- type: "string",
118
- demandOption: true,
119
- })
120
- .options({
121
- "list-env-variables": {
122
- describe: "List the environment variable names of the active deployment",
123
- type: "boolean",
124
- alias: "E",
125
- default: false,
126
- },
127
- }), (args) => get(args))
128
- .command("delete <slug>", "Delete a function on the branch", (yargs) => yargs.positional("slug", {
129
- describe: "Function slug",
130
- type: "string",
131
- demandOption: true,
132
- }), (args) => deleteFn(args));
133
- export const handler = (args) => {
134
- return args;
135
- };
136
- const parseEnv = (entries) => {
137
- if (!entries || entries.length === 0)
138
- return undefined;
139
- const map = {};
140
- for (const entry of entries) {
141
- const eq = entry.indexOf("=");
142
- if (eq <= 0) {
143
- throw new Error(`Invalid --env value "${entry}". Expected KEY=VALUE.`);
144
- }
145
- map[entry.slice(0, eq)] = entry.slice(eq + 1);
146
- }
147
- return JSON.stringify(map);
148
- };
149
- const statusHint = (slug, projectId, branchId) => `Check status with: neonctl function get ${slug} --project-id ${projectId} --branch ${branchId}`;
150
- // Emit the resolved deployment together with the function's invocation_url, so the
151
- // deploy output shows where the function is reachable (not just the deployment id).
152
- const emitDeployResult = (props, deployment, fn) => {
153
- const out = writer(props).write({ ...deployment, invocation_url: fn?.invocation_url }, { fields: DEPLOY_RESULT_FIELDS });
154
- if (props.output !== "json" && props.output !== "yaml") {
155
- writeDeploymentErrorSection(out, deployment);
156
- }
157
- out.end();
158
- };
159
- // A poll error worth retrying: a network error (no HTTP response), a 5xx, or a
160
- // 404 from eventual consistency. Anything else (e.g. 401/403) is surfaced.
161
- const isTransient = (err) => isNeonApiError(err) &&
162
- (err.status === undefined || err.status === 404 || err.status >= 500);
163
- const deploy = async (props) => {
164
- if (props.path !== undefined || props.entry !== undefined) {
165
- throw new Error("--path and --entry were removed. Use --src <dir>; the entry point " +
166
- "is discovered as index.ts, index.mjs, or index.js in that directory.");
167
- }
168
- // At least one deploy option must be passed (--wait is excluded: it controls
169
- // output, not what gets deployed).
170
- const hasOption = props.src !== undefined ||
171
- props.env !== undefined ||
172
- props.runtime !== undefined;
173
- if (!hasOption) {
174
- throw new Error("Provide at least one option to deploy, e.g. --src or --env. " +
175
- "See: neonctl function deploy --help.");
176
- }
177
- // Cheap, offline validation first - fail before any network round-trip.
178
- if (!SLUG_PATTERN.test(props.slug)) {
179
- throw new Error(`Invalid function slug "${props.slug}". ${SLUG_HELP}`);
180
- }
181
- const src = props.src ?? ".";
182
- const runtime = props.runtime ?? "nodejs24";
183
- const environment = parseEnv(props.env);
184
- const srcStat = statSync(src, { throwIfNoEntry: false });
185
- if (srcStat === undefined) {
186
- throw new Error(`--src path not found: ${src}.`);
187
- }
188
- // A file is used as the entry point directly; a directory triggers discovery.
189
- const source = srcStat.isFile()
190
- ? src
191
- : ENTRY_CANDIDATES.map((name) => join(src, name)).find((p) => existsSync(p));
192
- if (source === undefined) {
193
- throw new Error(`No entry file found in ${src}. Expected one of: ${ENTRY_CANDIDATES.join(", ")}.`);
194
- }
195
- // Bundle before any network round-trip so a bundling failure fails fast.
196
- const zip = zipBundle(await bundleEntry(source));
197
- const branchId = await branchIdFromProps(props);
198
- // Snapshot the current version before deploy so we can detect the new one
199
- // afterward. A missing function (404) or no deployment yet → undefined.
200
- let before;
201
- try {
202
- const fn = await getFunction(props.apiClient, props.projectId, branchId, props.slug);
203
- before = fn.current_deployment?.id;
204
- }
205
- catch (err) {
206
- if (!(isNeonApiError(err) && err.status === 404))
207
- throw err;
208
- }
209
- await retryOnLock(() => createDeployment(props.apiClient, props.projectId, branchId, props.slug, {
210
- zip,
211
- runtime,
212
- environment,
213
- }));
214
- log.info(`Function deployment triggered for function ${props.slug}.`);
215
- // Best-effort interrupt: a Ctrl-C lands at the next poll boundary. (No
216
- // automated test; mirrors the resolution branches below, verified manually.)
217
- let interrupted = false;
218
- const onSignal = () => {
219
- interrupted = true;
220
- };
221
- process.once("SIGINT", onSignal);
222
- process.once("SIGTERM", onSignal);
223
- // Poll until a NEW version appears (id greater than the snapshot, or
224
- // any version if there was none). --no-wait stops there; --wait stops at a
225
- // terminal status. Bounded by POLL_TIMEOUT_MS so it never hangs.
226
- let resolved;
227
- // The function carries the invocation_url; keep the whole record (not just its
228
- // current_deployment) so we can surface that URL on success.
229
- let resolvedFn;
230
- const deadline = Date.now() + POLL_TIMEOUT_MS;
231
- try {
232
- while (!interrupted && Date.now() < deadline) {
233
- await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
234
- if (interrupted)
235
- break;
236
- // The deploy already succeeded server-side; tolerate transient poll
237
- // failures and retry on the next interval. Surface anything else.
238
- let fn;
239
- try {
240
- fn = await getFunction(props.apiClient, props.projectId, branchId, props.slug);
241
- }
242
- catch (err) {
243
- if (isTransient(err))
244
- continue;
245
- throw err;
246
- }
247
- const dep = fn.current_deployment;
248
- const isNew = dep !== undefined && (before === undefined || dep.id > before);
249
- if (isNew && dep) {
250
- resolved = dep;
251
- resolvedFn = fn;
252
- if (!props.wait)
253
- break;
254
- if (dep.status === "completed" || dep.status === "failed")
255
- break;
256
- }
257
- }
258
- }
259
- finally {
260
- process.removeListener("SIGINT", onSignal);
261
- process.removeListener("SIGTERM", onSignal);
262
- }
263
- if (interrupted) {
264
- log.info(statusHint(props.slug, props.projectId, branchId));
265
- if (resolved)
266
- emitDeployResult(props, resolved, resolvedFn);
267
- return;
268
- }
269
- if (resolved === undefined) {
270
- log.info(statusHint(props.slug, props.projectId, branchId));
271
- throw new Error(`Timed out waiting for the deployment of ${props.slug} to start. It may still be in progress.`);
272
- }
273
- emitDeployResult(props, resolved, resolvedFn);
274
- if (!props.wait) {
275
- log.info(statusHint(props.slug, props.projectId, branchId));
276
- return;
277
- }
278
- if (resolved.status === "completed") {
279
- log.info(`Function deployment ${props.slug}/${resolved.id} completed.`);
280
- return;
281
- }
282
- if (resolved.status === "failed") {
283
- throw new Error(`Function deployment ${props.slug}/${resolved.id} failed.`);
284
- }
285
- // --wait, new version appeared but the deadline hit before it finished.
286
- log.info(statusHint(props.slug, props.projectId, branchId));
287
- throw new Error(`Timed out waiting for function deployment ${props.slug}/${resolved.id} to finish. It may still be building.`);
288
- };
289
- const get = async (props) => {
290
- const branchId = await branchIdFromProps(props);
291
- const fn = await getFunction(props.apiClient, props.projectId, branchId, props.slug);
292
- if (props.output === "json" || props.output === "yaml") {
293
- writer(props).end(fn, { fields: FUNCTION_FIELDS });
294
- return;
295
- }
296
- const out = writer(props).write(fn, {
297
- fields: FUNCTION_FIELDS,
298
- title: "function",
299
- });
300
- const current = fn.current_deployment;
301
- const active = fn.active_deployment;
302
- if (current && active && current.id === active.id) {
303
- out.write(current, {
304
- fields: DEPLOYMENT_FIELDS,
305
- title: "deployment (current, active)",
306
- });
307
- writeDeploymentErrorSection(out, current);
308
- }
309
- else {
310
- if (current) {
311
- out.write(current, {
312
- fields: DEPLOYMENT_FIELDS,
313
- title: "current deployment",
314
- });
315
- // The failure reason is shown only for the current deployment;
316
- // the active one completed successfully by definition.
317
- writeDeploymentErrorSection(out, current);
318
- }
319
- if (active) {
320
- out.write(active, {
321
- fields: DEPLOYMENT_FIELDS,
322
- title: "active deployment",
323
- });
324
- }
325
- }
326
- if (props.listEnvVariables) {
327
- out.write((fn.active_deployment?.environment ?? []).map((name) => ({ name })), {
328
- fields: ["name"],
329
- title: "environment",
330
- emptyMessage: "No environment variables on the active deployment.",
331
- });
332
- }
333
- out.end();
334
- };
335
- const deleteFn = async (props) => {
336
- const branchId = await branchIdFromProps(props);
337
- try {
338
- await retryOnLock(() => deleteFunction(props.apiClient, props.projectId, branchId, props.slug));
339
- }
340
- catch (err) {
341
- if (isNeonApiError(err) && err.status === 404) {
342
- throw new Error(`Function "${props.slug}" not found on branch ${branchId}.`);
343
- }
344
- throw err;
345
- }
346
- log.info(`Function ${props.slug} deleted from branch ${branchId}`);
347
- };
348
- const list = async (props) => {
349
- const branchId = await branchIdFromProps(props);
350
- const functions = [];
351
- let cursor;
352
- for (;;) {
353
- const page = await listFunctions(props.apiClient, props.projectId, branchId, { cursor, limit: FUNCTIONS_LIST_LIMIT });
354
- functions.push(...page.functions);
355
- log.debug("Got %d functions, next cursor: %s", page.functions.length, page.next);
356
- // A server echoing the same cursor would loop forever; treat it as
357
- // the end of the list.
358
- if (!page.next || page.next === cursor)
359
- break;
360
- cursor = page.next;
361
- }
362
- if (props.output === "json" || props.output === "yaml") {
363
- writer(props).end(functions, { fields: FUNCTION_FIELDS });
364
- return;
365
- }
366
- writer(props).end(functions.map((fn) => ({
367
- ...fn,
368
- status: fn.current_deployment?.status ?? "",
369
- })), {
370
- fields: LIST_TABLE_FIELDS,
371
- emptyMessage: "No functions found on this branch.",
372
- });
373
- };
@@ -1,62 +0,0 @@
1
- import * as api from "./api.js";
2
- import * as auth from "./auth.js";
3
- import * as bootstrap from "./bootstrap.js";
4
- import * as branches from "./branches.js";
5
- import * as bucket from "./bucket.js";
6
- import * as checkout from "./checkout.js";
7
- import * as config from "./config.js";
8
- import * as cs from "./connection_string.js";
9
- import * as dataApi from "./data_api.js";
10
- import * as databases from "./databases.js";
11
- import * as deploy from "./deploy.js";
12
- import * as dev from "./dev.js";
13
- import * as diff from "./diff.js";
14
- import * as env from "./env.js";
15
- import * as functions from "./functions.js";
16
- import * as init from "./init.js";
17
- import * as inspect from "./inspect.js";
18
- import * as ipAllow from "./ip_allow.js";
19
- import * as link from "./link.js";
20
- import * as neonAuth from "./neon_auth.js";
21
- import * as operations from "./operations.js";
22
- import * as orgs from "./orgs.js";
23
- import * as projects from "./projects.js";
24
- import * as psql from "./psql.js";
25
- import * as roles from "./roles.js";
26
- import * as setContext from "./set_context.js";
27
- import * as snapshots from "./snapshots.js";
28
- import * as status from "./status.js";
29
- import * as users from "./user.js";
30
- import * as vpcEndpoints from "./vpc_endpoints.js";
31
- export default [
32
- auth,
33
- api,
34
- users,
35
- orgs,
36
- projects,
37
- ipAllow,
38
- vpcEndpoints,
39
- neonAuth,
40
- branches,
41
- databases,
42
- roles,
43
- operations,
44
- snapshots,
45
- inspect,
46
- cs,
47
- psql,
48
- setContext,
49
- checkout,
50
- link,
51
- init,
52
- dataApi,
53
- functions,
54
- dev,
55
- diff,
56
- config,
57
- status,
58
- deploy,
59
- env,
60
- bucket,
61
- bootstrap,
62
- ];
@@ -1,73 +0,0 @@
1
- import { detectAgent, enrichResponse, interactiveInit, orchestrate, routeDataStep, } from "neon-init";
2
- import { sendError } from "../analytics.js";
3
- import { log } from "../log.js";
4
- export const command = "init";
5
- export const describe = "Initialize a project with Neon using your AI coding assistant";
6
- export const builder = (yargs) => yargs
7
- .option("context-file", {
8
- hidden: true,
9
- })
10
- .option("agent", {
11
- alias: "a",
12
- type: "boolean",
13
- default: false,
14
- describe: "Enable agent/JSON mode (agent type is auto-detected).",
15
- })
16
- .option("data", {
17
- type: "string",
18
- describe: 'JSON object with a "step" field to route to a specific phase and phase-specific options.',
19
- })
20
- .option("skip-migrations", {
21
- type: "boolean",
22
- default: false,
23
- describe: "Skip the migrations phase.",
24
- })
25
- .option("preview", {
26
- type: "boolean",
27
- default: false,
28
- describe: "Enable preview features (e.g. project bootstrapping from templates).",
29
- })
30
- .strict(false);
31
- export const handler = async (argv) => {
32
- try {
33
- // Auto-detect agent from environment. When --agent is explicitly passed,
34
- // always detect (the user asked for agent mode). Otherwise, require
35
- // non-TTY stdin to distinguish agent from human in terminal.
36
- const agent = (argv.agent || !process.stdin.isTTY ? detectAgent() : null) ||
37
- undefined;
38
- const isAgentMode = argv.agent || agent !== undefined;
39
- // --data with a "step" field routes to the appropriate phase
40
- if (argv.data && isAgentMode) {
41
- let data;
42
- try {
43
- data = JSON.parse(argv.data);
44
- }
45
- catch {
46
- log.error("Invalid JSON in --data flag. Expected a JSON object.");
47
- process.exit(1);
48
- return;
49
- }
50
- if (typeof data.step === "string") {
51
- const result = await routeDataStep(data, agent);
52
- log.info(JSON.stringify(enrichResponse(result), null, 2));
53
- return;
54
- }
55
- }
56
- if (isAgentMode) {
57
- const result = await orchestrate({
58
- agent,
59
- skipMigrations: argv.skipMigrations,
60
- preview: argv.preview,
61
- });
62
- log.info(JSON.stringify(enrichResponse(result), null, 2));
63
- }
64
- else {
65
- await interactiveInit({ preview: argv.preview });
66
- }
67
- }
68
- catch {
69
- const exitError = new Error(`failed to run neon-init`);
70
- sendError(exitError, "NEON_INIT_FAILED");
71
- process.exit(1);
72
- }
73
- };
@@ -1,65 +0,0 @@
1
- import { fillSingleProject } from "../utils/enrichers.js";
2
- import { resolveConnectionUri, runInspectQuery } from "../utils/inspect_db.js";
3
- import { INSPECT_QUERIES, } from "../utils/inspect_queries.js";
4
- import { writer } from "../writer.js";
5
- export const command = "inspect";
6
- export const describe = "Inspect a database's health and configuration";
7
- export const aliases = ["inspection"];
8
- /**
9
- * `fillSingleProject` hits the API to auto-resolve a project. When the user
10
- * passes `--db-url` we bypass the Neon API entirely, so skip it.
11
- */
12
- const fillSingleProjectUnlessDbUrl = async (props) => {
13
- if (props.dbUrl) {
14
- return props;
15
- }
16
- return fillSingleProject(props);
17
- };
18
- const runSubcommand = async (name, props) => {
19
- const query = INSPECT_QUERIES[name];
20
- const connectionUri = props.dbUrl ?? (await resolveConnectionUri(props)).connectionUri;
21
- const rows = await runInspectQuery(connectionUri, query.sql, {
22
- requiresExtension: query.requiresExtension,
23
- });
24
- writer(props).end(rows, {
25
- fields: query.fields,
26
- emptyMessage: query.emptyMessage,
27
- });
28
- };
29
- const dbBuilder = (argv) => {
30
- let builder = argv
31
- .usage("$0 inspect db <sub-command> [options]")
32
- .options({
33
- "project-id": {
34
- describe: "Project ID",
35
- type: "string",
36
- },
37
- branch: {
38
- describe: "Branch ID or name",
39
- type: "string",
40
- },
41
- "database-name": {
42
- describe: "Database name",
43
- type: "string",
44
- },
45
- "role-name": {
46
- describe: "Role name",
47
- type: "string",
48
- },
49
- "db-url": {
50
- describe: "Inspect any Postgres via a connection string, bypassing the Neon API (project/branch resolution is skipped)",
51
- type: "string",
52
- },
53
- })
54
- .middleware(fillSingleProjectUnlessDbUrl);
55
- for (const name of Object.keys(INSPECT_QUERIES)) {
56
- builder = builder.command(name, INSPECT_QUERIES[name].describe, (yargs) => yargs, (args) => runSubcommand(name, args));
57
- }
58
- return builder;
59
- };
60
- export const builder = (argv) => argv
61
- .usage("$0 inspect <sub-command> [options]")
62
- .command("db", "Run a diagnostic query against a branch's Postgres", dbBuilder);
63
- export const handler = (args) => {
64
- return args;
65
- };