neonctl 2.37.0 → 2.38.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 (160) hide show
  1. package/{LICENSE.md → LICENSE} +27 -3
  2. package/README.md +15 -700
  3. package/bin/cli.js +3 -0
  4. package/package.json +8 -75
  5. package/dist/analytics.js +0 -168
  6. package/dist/api.js +0 -720
  7. package/dist/auth.js +0 -125
  8. package/dist/callback.html +0 -51
  9. package/dist/cli.js +0 -9
  10. package/dist/commands/api.js +0 -278
  11. package/dist/commands/auth.js +0 -214
  12. package/dist/commands/bootstrap.js +0 -481
  13. package/dist/commands/branches.js +0 -488
  14. package/dist/commands/bucket.js +0 -549
  15. package/dist/commands/checkout.js +0 -321
  16. package/dist/commands/config.js +0 -626
  17. package/dist/commands/connection_string.js +0 -172
  18. package/dist/commands/data_api.js +0 -284
  19. package/dist/commands/databases.js +0 -82
  20. package/dist/commands/deploy.js +0 -26
  21. package/dist/commands/dev.js +0 -698
  22. package/dist/commands/diff.js +0 -222
  23. package/dist/commands/env.js +0 -189
  24. package/dist/commands/functions.js +0 -373
  25. package/dist/commands/index.js +0 -62
  26. package/dist/commands/init.js +0 -73
  27. package/dist/commands/inspect.js +0 -65
  28. package/dist/commands/ip_allow.js +0 -137
  29. package/dist/commands/link.js +0 -1121
  30. package/dist/commands/neon_auth.js +0 -1028
  31. package/dist/commands/operations.js +0 -28
  32. package/dist/commands/orgs.js +0 -24
  33. package/dist/commands/projects.js +0 -413
  34. package/dist/commands/psql.js +0 -62
  35. package/dist/commands/roles.js +0 -65
  36. package/dist/commands/schema_diff.js +0 -151
  37. package/dist/commands/set_context.js +0 -29
  38. package/dist/commands/snapshots.js +0 -455
  39. package/dist/commands/status.js +0 -40
  40. package/dist/commands/user.js +0 -15
  41. package/dist/commands/vpc_endpoints.js +0 -134
  42. package/dist/config.js +0 -11
  43. package/dist/config_format.js +0 -72
  44. package/dist/context.js +0 -231
  45. package/dist/current_branch_fast_path.js +0 -55
  46. package/dist/dev/env.js +0 -244
  47. package/dist/dev/functions.js +0 -70
  48. package/dist/dev/inputs.js +0 -63
  49. package/dist/dev/runtime.js +0 -146
  50. package/dist/env.js +0 -36
  51. package/dist/env_file.js +0 -159
  52. package/dist/errors.js +0 -80
  53. package/dist/functions_api.js +0 -48
  54. package/dist/help.js +0 -146
  55. package/dist/index.js +0 -240
  56. package/dist/log.js +0 -18
  57. package/dist/parameters.gen.js +0 -480
  58. package/dist/pkg.js +0 -25
  59. package/dist/psql/cli.js +0 -53
  60. package/dist/psql/command/cmd_cond.js +0 -437
  61. package/dist/psql/command/cmd_connect.js +0 -820
  62. package/dist/psql/command/cmd_copy.js +0 -1035
  63. package/dist/psql/command/cmd_describe.js +0 -1815
  64. package/dist/psql/command/cmd_format.js +0 -948
  65. package/dist/psql/command/cmd_io.js +0 -2193
  66. package/dist/psql/command/cmd_lo.js +0 -393
  67. package/dist/psql/command/cmd_meta.js +0 -969
  68. package/dist/psql/command/cmd_misc.js +0 -187
  69. package/dist/psql/command/cmd_pipeline.js +0 -1148
  70. package/dist/psql/command/cmd_restrict.js +0 -171
  71. package/dist/psql/command/cmd_show.js +0 -766
  72. package/dist/psql/command/dispatch.js +0 -343
  73. package/dist/psql/command/inputQueue.js +0 -42
  74. package/dist/psql/command/shared.js +0 -71
  75. package/dist/psql/complete/filenames.js +0 -139
  76. package/dist/psql/complete/index.js +0 -104
  77. package/dist/psql/complete/matcher.js +0 -315
  78. package/dist/psql/complete/psqlVars.js +0 -249
  79. package/dist/psql/complete/queries.js +0 -493
  80. package/dist/psql/complete/rules.js +0 -2424
  81. package/dist/psql/core/common.js +0 -1253
  82. package/dist/psql/core/help.js +0 -576
  83. package/dist/psql/core/mainloop.js +0 -1360
  84. package/dist/psql/core/prompt.js +0 -439
  85. package/dist/psql/core/settings.js +0 -686
  86. package/dist/psql/core/sqlHelp.js +0 -1066
  87. package/dist/psql/core/startup.js +0 -846
  88. package/dist/psql/core/syncVars.js +0 -116
  89. package/dist/psql/core/variables.js +0 -287
  90. package/dist/psql/describe/formatters.js +0 -1330
  91. package/dist/psql/describe/processNamePattern.js +0 -270
  92. package/dist/psql/describe/queries.js +0 -2452
  93. package/dist/psql/describe/versionGate.js +0 -44
  94. package/dist/psql/index.js +0 -2030
  95. package/dist/psql/io/history.js +0 -299
  96. package/dist/psql/io/input.js +0 -120
  97. package/dist/psql/io/lineEditor/buffer.js +0 -325
  98. package/dist/psql/io/lineEditor/complete.js +0 -227
  99. package/dist/psql/io/lineEditor/filename.js +0 -159
  100. package/dist/psql/io/lineEditor/index.js +0 -893
  101. package/dist/psql/io/lineEditor/keymap.js +0 -745
  102. package/dist/psql/io/lineEditor/vt100.js +0 -363
  103. package/dist/psql/io/pgpass.js +0 -202
  104. package/dist/psql/io/pgservice.js +0 -194
  105. package/dist/psql/io/psqlrc.js +0 -422
  106. package/dist/psql/print/aligned.js +0 -1748
  107. package/dist/psql/print/asciidoc.js +0 -230
  108. package/dist/psql/print/crosstab.js +0 -463
  109. package/dist/psql/print/csv.js +0 -76
  110. package/dist/psql/print/html.js +0 -240
  111. package/dist/psql/print/json.js +0 -96
  112. package/dist/psql/print/latex.js +0 -379
  113. package/dist/psql/print/pager.js +0 -267
  114. package/dist/psql/print/troff.js +0 -240
  115. package/dist/psql/print/unaligned.js +0 -99
  116. package/dist/psql/print/units.js +0 -188
  117. package/dist/psql/scanner/slash.js +0 -515
  118. package/dist/psql/scanner/sql.js +0 -914
  119. package/dist/psql/scanner/stringutils.js +0 -394
  120. package/dist/psql/types/backslash.js +0 -1
  121. package/dist/psql/types/connection.js +0 -1
  122. package/dist/psql/types/index.js +0 -7
  123. package/dist/psql/types/printer.js +0 -1
  124. package/dist/psql/types/repl.js +0 -1
  125. package/dist/psql/types/scanner.js +0 -24
  126. package/dist/psql/types/settings.js +0 -1
  127. package/dist/psql/types/variables.js +0 -1
  128. package/dist/psql/wire/connection.js +0 -2857
  129. package/dist/psql/wire/copy.js +0 -108
  130. package/dist/psql/wire/notify.js +0 -59
  131. package/dist/psql/wire/pipeline.js +0 -521
  132. package/dist/psql/wire/protocol.js +0 -466
  133. package/dist/psql/wire/sasl.js +0 -294
  134. package/dist/psql/wire/tls.js +0 -602
  135. package/dist/storage_api.js +0 -147
  136. package/dist/test_utils/fixtures.js +0 -121
  137. package/dist/test_utils/oauth_server.js +0 -9
  138. package/dist/types.js +0 -1
  139. package/dist/utils/ai_gateway_notice.js +0 -180
  140. package/dist/utils/api_enums.js +0 -33
  141. package/dist/utils/auth.js +0 -5
  142. package/dist/utils/branch_notice.js +0 -22
  143. package/dist/utils/branch_picker.js +0 -103
  144. package/dist/utils/compute_units.js +0 -28
  145. package/dist/utils/config_diff.js +0 -185
  146. package/dist/utils/enrichers.js +0 -161
  147. package/dist/utils/esbuild.js +0 -158
  148. package/dist/utils/formats.js +0 -18
  149. package/dist/utils/git_diff.js +0 -90
  150. package/dist/utils/inspect_db.js +0 -153
  151. package/dist/utils/inspect_queries.js +0 -372
  152. package/dist/utils/middlewares.js +0 -20
  153. package/dist/utils/openapi.js +0 -114
  154. package/dist/utils/package_manager.js +0 -68
  155. package/dist/utils/point_in_time.js +0 -56
  156. package/dist/utils/psql.js +0 -120
  157. package/dist/utils/string.js +0 -5
  158. package/dist/utils/ui.js +0 -59
  159. package/dist/utils/zip.js +0 -4
  160. 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
- };