neon 3.0.0 → 3.1.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 (207) hide show
  1. package/README.md +70 -5
  2. package/dist/_chunks/auth_selection-DGgq6ifc.js +83 -0
  3. package/dist/_chunks/cmd_pipeline-CUbBO9U_.js +2818 -0
  4. package/dist/_chunks/credentials-MYdHdKah.js +188 -0
  5. package/dist/_chunks/env-NbA61JR3.js +585 -0
  6. package/dist/_chunks/env_services-Tz9G4JeT.js +531 -0
  7. package/dist/_chunks/paths-DMq0Lt7a.js +151 -0
  8. package/dist/_chunks/profiles-Ir29rqns.js +217 -0
  9. package/dist/_chunks/psql-DWH-kc69.js +2169 -0
  10. package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
  11. package/dist/_chunks/secure_file-BucZj4yQ.js +39 -0
  12. package/dist/analytics.js +163 -207
  13. package/dist/api.js +815 -758
  14. package/dist/auth.js +121 -141
  15. package/dist/auth_context.js +39 -53
  16. package/dist/cli.js +4 -7
  17. package/dist/commands/api.js +220 -250
  18. package/dist/commands/api_keys.js +251 -314
  19. package/dist/commands/auth.js +283 -328
  20. package/dist/commands/bootstrap.js +372 -437
  21. package/dist/commands/branches.js +304 -455
  22. package/dist/commands/bucket.js +374 -514
  23. package/dist/commands/checkout.js +213 -298
  24. package/dist/commands/config.js +573 -690
  25. package/dist/commands/connection_string.js +137 -165
  26. package/dist/commands/data_api.js +238 -260
  27. package/dist/commands/databases.js +67 -76
  28. package/dist/commands/deploy.js +31 -25
  29. package/dist/commands/dev.js +639 -719
  30. package/dist/commands/diff.js +156 -200
  31. package/dist/commands/env.js +255 -305
  32. package/dist/commands/functions.js +275 -355
  33. package/dist/commands/index.js +70 -65
  34. package/dist/commands/init.js +84 -119
  35. package/dist/commands/inspect.js +55 -55
  36. package/dist/commands/ip_allow.js +88 -120
  37. package/dist/commands/link.js +874 -1019
  38. package/dist/commands/logs.js +291 -0
  39. package/dist/commands/neon_auth.js +725 -933
  40. package/dist/commands/operations.js +34 -25
  41. package/dist/commands/orgs.js +28 -18
  42. package/dist/commands/profile.js +615 -846
  43. package/dist/commands/projects.js +313 -373
  44. package/dist/commands/psql.js +60 -58
  45. package/dist/commands/roles.js +55 -58
  46. package/dist/commands/schema_diff.js +87 -131
  47. package/dist/commands/set_context.js +34 -26
  48. package/dist/commands/snapshots.js +288 -413
  49. package/dist/commands/status.js +41 -37
  50. package/dist/commands/user.js +21 -10
  51. package/dist/commands/vpc_endpoints.js +85 -113
  52. package/dist/config.js +7 -6
  53. package/dist/config_format.js +50 -66
  54. package/dist/config_template.js +128 -157
  55. package/dist/context.js +183 -235
  56. package/dist/current_branch_fast_path.js +40 -49
  57. package/dist/dev/env.js +2 -446
  58. package/dist/dev/functions.js +54 -68
  59. package/dist/dev/inputs.js +46 -58
  60. package/dist/dev/runtime.js +135 -164
  61. package/dist/dev/websocket.js +766 -959
  62. package/dist/env.js +27 -33
  63. package/dist/env_file.js +118 -132
  64. package/dist/env_services.js +2 -51
  65. package/dist/errors.js +57 -68
  66. package/dist/functions_api.js +45 -43
  67. package/dist/help.js +189 -140
  68. package/dist/index.js +182 -257
  69. package/dist/init/agents.js +137 -118
  70. package/dist/init/auth.js +58 -68
  71. package/dist/init/bootstrap.js +325 -396
  72. package/dist/init/build_config.js +4 -2
  73. package/dist/init/detect_agent.js +56 -101
  74. package/dist/init/editors.js +35 -52
  75. package/dist/init/enrich_output.js +51 -66
  76. package/dist/init/extension.js +134 -171
  77. package/dist/init/inspect.js +179 -266
  78. package/dist/init/interactive.js +510 -622
  79. package/dist/init/neonctl.js +117 -168
  80. package/dist/init/orchestrate.js +157 -173
  81. package/dist/init/phases/auth.js +188 -202
  82. package/dist/init/phases/cleanup.js +23 -23
  83. package/dist/init/phases/db.js +251 -277
  84. package/dist/init/phases/getting_started.js +213 -223
  85. package/dist/init/phases/mcp.js +174 -224
  86. package/dist/init/phases/migrations.js +247 -248
  87. package/dist/init/phases/neon_auth.js +114 -133
  88. package/dist/init/phases/setup.js +546 -703
  89. package/dist/init/phases/skills.js +75 -86
  90. package/dist/init/phases/status.js +72 -67
  91. package/dist/init/resolve_context.js +102 -99
  92. package/dist/init/route_command.js +91 -98
  93. package/dist/init/skills.js +174 -218
  94. package/dist/init/vsix.js +77 -99
  95. package/dist/log.js +17 -16
  96. package/dist/neon_services.js +104 -129
  97. package/dist/parameters.gen.js +481 -471
  98. package/dist/pkg.js +17 -19
  99. package/dist/profile_keys.js +44 -47
  100. package/dist/psql/cli.js +44 -47
  101. package/dist/psql/command/cmd_cond.js +231 -406
  102. package/dist/psql/command/cmd_connect.js +557 -764
  103. package/dist/psql/command/cmd_copy.js +728 -984
  104. package/dist/psql/command/cmd_describe.js +1499 -1688
  105. package/dist/psql/command/cmd_format.js +733 -905
  106. package/dist/psql/command/cmd_io.js +2 -2193
  107. package/dist/psql/command/cmd_lo.js +297 -359
  108. package/dist/psql/command/cmd_meta.js +727 -878
  109. package/dist/psql/command/cmd_misc.js +138 -172
  110. package/dist/psql/command/cmd_pipeline.js +2 -1148
  111. package/dist/psql/command/cmd_restrict.js +119 -155
  112. package/dist/psql/command/cmd_show.js +529 -688
  113. package/dist/psql/command/dispatch.js +260 -325
  114. package/dist/psql/command/inputQueue.js +35 -33
  115. package/dist/psql/command/shared.js +49 -63
  116. package/dist/psql/complete/filenames.js +90 -133
  117. package/dist/psql/complete/index.js +59 -97
  118. package/dist/psql/complete/matcher.js +236 -300
  119. package/dist/psql/complete/psqlVars.js +218 -223
  120. package/dist/psql/complete/queries.js +159 -177
  121. package/dist/psql/complete/rules.js +1493 -2299
  122. package/dist/psql/core/common.js +2 -1253
  123. package/dist/psql/core/help.js +456 -546
  124. package/dist/psql/core/mainloop.js +692 -1303
  125. package/dist/psql/core/prompt.js +391 -408
  126. package/dist/psql/core/settings.js +429 -644
  127. package/dist/psql/core/sqlHelp.js +480 -554
  128. package/dist/psql/core/startup.js +2 -846
  129. package/dist/psql/core/syncVars.js +67 -110
  130. package/dist/psql/core/variables.js +156 -278
  131. package/dist/psql/describe/formatters.js +884 -1285
  132. package/dist/psql/describe/processNamePattern.js +173 -260
  133. package/dist/psql/describe/queries.js +1368 -2403
  134. package/dist/psql/describe/versionGate.js +32 -41
  135. package/dist/psql/index.js +2 -2030
  136. package/dist/psql/io/history.js +232 -271
  137. package/dist/psql/io/input.js +103 -108
  138. package/dist/psql/io/lineEditor/buffer.js +238 -319
  139. package/dist/psql/io/lineEditor/complete.js +135 -213
  140. package/dist/psql/io/lineEditor/filename.js +139 -148
  141. package/dist/psql/io/lineEditor/index.js +653 -870
  142. package/dist/psql/io/lineEditor/keymap.js +544 -702
  143. package/dist/psql/io/lineEditor/vt100.js +294 -341
  144. package/dist/psql/io/pgpass.js +158 -187
  145. package/dist/psql/io/pgservice.js +146 -183
  146. package/dist/psql/io/psqlrc.js +328 -403
  147. package/dist/psql/print/aligned.js +1020 -1683
  148. package/dist/psql/print/asciidoc.js +180 -214
  149. package/dist/psql/print/crosstab.js +281 -442
  150. package/dist/psql/print/csv.js +48 -70
  151. package/dist/psql/print/html.js +195 -226
  152. package/dist/psql/print/json.js +75 -88
  153. package/dist/psql/print/latex.js +291 -364
  154. package/dist/psql/print/pager.js +171 -242
  155. package/dist/psql/print/troff.js +194 -226
  156. package/dist/psql/print/unaligned.js +69 -95
  157. package/dist/psql/print/units.js +167 -169
  158. package/dist/psql/scanner/slash.js +428 -483
  159. package/dist/psql/scanner/sql.js +445 -889
  160. package/dist/psql/scanner/stringutils.js +309 -379
  161. package/dist/psql/types/index.js +8 -7
  162. package/dist/psql/types/scanner.js +25 -22
  163. package/dist/psql/wire/connection.js +2042 -2803
  164. package/dist/psql/wire/copy.js +84 -100
  165. package/dist/psql/wire/notify.js +39 -59
  166. package/dist/psql/wire/pipeline.js +305 -518
  167. package/dist/psql/wire/protocol.js +349 -417
  168. package/dist/psql/wire/sasl.js +180 -265
  169. package/dist/psql/wire/tls.js +400 -561
  170. package/dist/storage_api.js +115 -129
  171. package/dist/test_utils/fixtures.js +94 -113
  172. package/dist/test_utils/oauth_server.js +10 -7
  173. package/dist/test_utils/project_dir.js +33 -0
  174. package/dist/utils/ai_gateway_notice.js +131 -162
  175. package/dist/utils/api_enums.js +21 -28
  176. package/dist/utils/auth.js +10 -4
  177. package/dist/utils/branch_notice.js +20 -19
  178. package/dist/utils/branch_picker.js +83 -89
  179. package/dist/utils/cli_name.js +15 -12
  180. package/dist/utils/compute_units.js +20 -27
  181. package/dist/utils/config_diff.js +127 -158
  182. package/dist/utils/enrichers.js +95 -148
  183. package/dist/utils/esbuild.js +130 -189
  184. package/dist/utils/flags.js +35 -47
  185. package/dist/utils/formats.js +8 -15
  186. package/dist/utils/git_diff.js +69 -80
  187. package/dist/utils/inspect_db.js +101 -143
  188. package/dist/utils/inspect_queries.js +179 -142
  189. package/dist/utils/middlewares.js +39 -45
  190. package/dist/utils/openapi.js +87 -99
  191. package/dist/utils/package_manager.js +312 -110
  192. package/dist/utils/point_in_time.js +49 -53
  193. package/dist/utils/psql.js +89 -106
  194. package/dist/utils/service_picker.js +55 -58
  195. package/dist/utils/string.js +5 -5
  196. package/dist/utils/ui.js +38 -55
  197. package/dist/utils/write_sync.js +26 -35
  198. package/dist/utils/zip.js +4 -3
  199. package/dist/writer.js +67 -87
  200. package/package.json +11 -6
  201. package/dist/_shared/auth_selection.js +0 -86
  202. package/dist/_shared/credentials.js +0 -209
  203. package/dist/_shared/env-core/env.js +0 -558
  204. package/dist/_shared/env-core/reuse-secrets.js +0 -223
  205. package/dist/_shared/paths.js +0 -148
  206. package/dist/_shared/profiles.js +0 -276
  207. package/dist/_shared/secure_file.js +0 -43
package/dist/init/vsix.js CHANGED
@@ -1,111 +1,89 @@
1
- /**
2
- * Shared VSIX download utilities for extension installation.
3
- * Supports corporate proxy via NEON_VSX_GALLERY_URL env var.
4
- */
1
+ import "./build_config.js";
5
2
  import { createWriteStream } from "node:fs";
6
- import { tmpdir } from "node:os";
7
3
  import { join } from "node:path";
4
+ import { tmpdir } from "node:os";
8
5
  import { pipeline } from "node:stream/promises";
9
- import { INTERNAL_VSX_GALLERY } from "./build_config.js";
10
- export const NEON_EXTENSION_ID = "databricks.neon-local-connect";
6
+ //#region src/init/vsix.ts
7
+ /**
8
+ * Shared VSIX download utilities for extension installation.
9
+ * Supports corporate proxy via NEON_VSX_GALLERY_URL env var.
10
+ */
11
+ const NEON_EXTENSION_ID = "databricks.neon-local-connect";
11
12
  const OPEN_VSX_API = "https://open-vsx.org/api";
12
13
  /**
13
- * Downloads a .vsix file for the Neon extension.
14
- *
15
- * Strategy:
16
- * 1. If NEON_VSX_GALLERY_URL is set, download from the corporate proxy gallery
17
- * 2. Otherwise, download from the public Open VSX API
18
- *
19
- * Returns the path to the temp .vsix file, or null on failure.
20
- */
21
- export async function downloadVsix() {
22
- // Runtime env var takes priority, then build-time baked value
23
- const proxyGallery = process.env.NEON_VSX_GALLERY_URL || INTERNAL_VSX_GALLERY || "";
24
- if (proxyGallery) {
25
- return downloadFromGallery(proxyGallery);
26
- }
27
- return downloadFromOpenVsx();
14
+ * Downloads a .vsix file for the Neon extension.
15
+ *
16
+ * Strategy:
17
+ * 1. If NEON_VSX_GALLERY_URL is set, download from the corporate proxy gallery
18
+ * 2. Otherwise, download from the public Open VSX API
19
+ *
20
+ * Returns the path to the temp .vsix file, or null on failure.
21
+ */
22
+ async function downloadVsix() {
23
+ const proxyGallery = process.env.NEON_VSX_GALLERY_URL || "";
24
+ if (proxyGallery) return downloadFromGallery(proxyGallery);
25
+ return downloadFromOpenVsx();
28
26
  }
29
27
  /**
30
- * Downloads from a VS Code marketplace-compatible gallery API (corporate proxy).
31
- * Uses the VS Code extensionquery POST API to find the VSIX download URL.
32
- */
28
+ * Downloads from a VS Code marketplace-compatible gallery API (corporate proxy).
29
+ * Uses the VS Code extensionquery POST API to find the VSIX download URL.
30
+ */
33
31
  async function downloadFromGallery(galleryUrl) {
34
- const [publisher, name] = NEON_EXTENSION_ID.split(".");
35
- const baseUrl = galleryUrl.replace(/\/+$/, "");
36
- const queryUrl = `${baseUrl}/extensionquery`;
37
- try {
38
- // Query the marketplace API for the extension
39
- const queryRes = await fetch(queryUrl, {
40
- method: "POST",
41
- headers: {
42
- "Content-Type": "application/json",
43
- Accept: "application/json;api-version=6.1-preview.1",
44
- },
45
- body: JSON.stringify({
46
- filters: [
47
- {
48
- criteria: [
49
- { filterType: 7, value: `${publisher}.${name}` },
50
- ],
51
- },
52
- ],
53
- flags: 914,
54
- }),
55
- signal: AbortSignal.timeout(15000),
56
- });
57
- if (!queryRes.ok)
58
- return null;
59
- const data = (await queryRes.json());
60
- // Find the VSIX download URL from the response
61
- const extension = data.results?.[0]?.extensions?.[0];
62
- const latestVersion = extension?.versions?.[0];
63
- const vsixFile = latestVersion?.files?.find((f) => f.assetType === "Microsoft.VisualStudio.Services.VSIXPackage");
64
- if (!vsixFile?.source)
65
- return null;
66
- // Download the VSIX
67
- const vsixRes = await fetch(vsixFile.source, {
68
- signal: AbortSignal.timeout(30000),
69
- redirect: "follow",
70
- });
71
- if (!vsixRes.ok || !vsixRes.body)
72
- return null;
73
- const tmpPath = join(tmpdir(), `${NEON_EXTENSION_ID}-proxy.vsix`);
74
- const fileStream = createWriteStream(tmpPath);
75
- await pipeline(vsixRes.body, fileStream);
76
- return tmpPath;
77
- }
78
- catch {
79
- return null;
80
- }
32
+ const [publisher, name] = NEON_EXTENSION_ID.split(".");
33
+ const queryUrl = `${galleryUrl.replace(/\/+$/, "")}/extensionquery`;
34
+ try {
35
+ const queryRes = await fetch(queryUrl, {
36
+ method: "POST",
37
+ headers: {
38
+ "Content-Type": "application/json",
39
+ Accept: "application/json;api-version=6.1-preview.1"
40
+ },
41
+ body: JSON.stringify({
42
+ filters: [{ criteria: [{
43
+ filterType: 7,
44
+ value: `${publisher}.${name}`
45
+ }] }],
46
+ flags: 914
47
+ }),
48
+ signal: AbortSignal.timeout(15e3)
49
+ });
50
+ if (!queryRes.ok) return null;
51
+ const vsixFile = (((await queryRes.json()).results?.[0]?.extensions?.[0])?.versions?.[0])?.files?.find((f) => f.assetType === "Microsoft.VisualStudio.Services.VSIXPackage");
52
+ if (!vsixFile?.source) return null;
53
+ const vsixRes = await fetch(vsixFile.source, {
54
+ signal: AbortSignal.timeout(3e4),
55
+ redirect: "follow"
56
+ });
57
+ if (!vsixRes.ok || !vsixRes.body) return null;
58
+ const tmpPath = join(tmpdir(), `${NEON_EXTENSION_ID}-proxy.vsix`);
59
+ const fileStream = createWriteStream(tmpPath);
60
+ await pipeline(vsixRes.body, fileStream);
61
+ return tmpPath;
62
+ } catch {
63
+ return null;
64
+ }
81
65
  }
82
66
  /**
83
- * Downloads from the public Open VSX API.
84
- */
67
+ * Downloads from the public Open VSX API.
68
+ */
85
69
  async function downloadFromOpenVsx() {
86
- const [publisher, name] = NEON_EXTENSION_ID.split(".");
87
- const metaUrl = `${OPEN_VSX_API}/${publisher}/${name}/latest`;
88
- try {
89
- const metaRes = await fetch(metaUrl, {
90
- signal: AbortSignal.timeout(10000),
91
- });
92
- if (!metaRes.ok)
93
- return null;
94
- const meta = (await metaRes.json());
95
- const downloadUrl = meta.files?.download;
96
- if (!downloadUrl)
97
- return null;
98
- const vsixRes = await fetch(downloadUrl, {
99
- signal: AbortSignal.timeout(30000),
100
- });
101
- if (!vsixRes.ok || !vsixRes.body)
102
- return null;
103
- const tmpPath = join(tmpdir(), `${NEON_EXTENSION_ID}-${meta.version ?? "latest"}.vsix`);
104
- const fileStream = createWriteStream(tmpPath);
105
- await pipeline(vsixRes.body, fileStream);
106
- return tmpPath;
107
- }
108
- catch {
109
- return null;
110
- }
70
+ const [publisher, name] = NEON_EXTENSION_ID.split(".");
71
+ const metaUrl = `${OPEN_VSX_API}/${publisher}/${name}/latest`;
72
+ try {
73
+ const metaRes = await fetch(metaUrl, { signal: AbortSignal.timeout(1e4) });
74
+ if (!metaRes.ok) return null;
75
+ const meta = await metaRes.json();
76
+ const downloadUrl = meta.files?.download;
77
+ if (!downloadUrl) return null;
78
+ const vsixRes = await fetch(downloadUrl, { signal: AbortSignal.timeout(3e4) });
79
+ if (!vsixRes.ok || !vsixRes.body) return null;
80
+ const tmpPath = join(tmpdir(), `${NEON_EXTENSION_ID}-${meta.version ?? "latest"}.vsix`);
81
+ const fileStream = createWriteStream(tmpPath);
82
+ await pipeline(vsixRes.body, fileStream);
83
+ return tmpPath;
84
+ } catch {
85
+ return null;
86
+ }
111
87
  }
88
+ //#endregion
89
+ export { NEON_EXTENSION_ID, downloadVsix };
package/dist/log.js CHANGED
@@ -1,18 +1,19 @@
1
- import { format } from "node:util";
2
1
  import { isDebug } from "./env.js";
3
- export const log = {
4
- debug: (...args) => {
5
- if (isDebug()) {
6
- process.stderr.write(`DEBUG: ${format(...args)}\n`);
7
- }
8
- },
9
- warning: (...args) => {
10
- process.stderr.write(`WARNING: ${format(...args)}\n`);
11
- },
12
- info: (...args) => {
13
- process.stderr.write(`INFO: ${format(...args)}\n`);
14
- },
15
- error: (...args) => {
16
- process.stderr.write(`ERROR: ${format(...args)}\n`);
17
- },
2
+ import { format } from "node:util";
3
+ //#region src/log.ts
4
+ const log = {
5
+ debug: (...args) => {
6
+ if (isDebug()) process.stderr.write(`DEBUG: ${format(...args)}\n`);
7
+ },
8
+ warning: (...args) => {
9
+ process.stderr.write(`WARNING: ${format(...args)}\n`);
10
+ },
11
+ info: (...args) => {
12
+ process.stderr.write(`INFO: ${format(...args)}\n`);
13
+ },
14
+ error: (...args) => {
15
+ process.stderr.write(`ERROR: ${format(...args)}\n`);
16
+ }
18
17
  };
18
+ //#endregion
19
+ export { log };
@@ -1,143 +1,118 @@
1
+ //#region src/neon_services.ts
1
2
  /**
2
- * Every Neon service a `--service` flag can name, spelled the way a user types it — one
3
- * vocabulary for the whole CLI.
4
- *
5
- * Kebab-case rather than the `neon.ts` field names (`aiGateway`, `buckets`) so a flag reads
6
- * like a flag, and the full product name rather than a shortening (`object-storage`, not
7
- * `storage`) so nothing is ambiguous when read on its own.
8
- *
9
- * Commands take a **subset** of this via {@link ParseServicesOptions.allowed} — `config init`
10
- * can only declare what a `neon.ts` has a field for, `env pull` can only pull what produces
11
- * env vars — but the spelling of a service never varies between them. The order here is the
12
- * canonical one: parsing sorts into it, so a command's output never depends on the order the
13
- * flags were typed in.
14
- *
15
- * Not to be confused with `NeonFeature` in `init/bootstrap.ts`, which is what a *template*
16
- * requires. That list comes from remote manifests (`neondatabase/examples/bootstrap.yaml`),
17
- * spells Postgres `database`, and is not ours to rename.
18
- */
19
- export const NEON_SERVICES = [
20
- "postgres",
21
- "auth",
22
- "data-api",
23
- "functions",
24
- "object-storage",
25
- "ai-gateway",
3
+ * Every Neon service a `--service` flag can name, spelled the way a user types it — one
4
+ * vocabulary for the whole CLI.
5
+ *
6
+ * Kebab-case rather than the `neon.ts` field names (`aiGateway`, `buckets`) so a flag reads
7
+ * like a flag, and the full product name rather than a shortening (`object-storage`, not
8
+ * `storage`) so nothing is ambiguous when read on its own.
9
+ *
10
+ * Commands take a **subset** of this via {@link ParseServicesOptions.allowed} — `config init`
11
+ * can only declare what a `neon.ts` has a field for, `env pull` can only pull what produces
12
+ * env vars — but the spelling of a service never varies between them. The order here is the
13
+ * canonical one: parsing sorts into it, so a command's output never depends on the order the
14
+ * flags were typed in.
15
+ *
16
+ * Not to be confused with `NeonFeature` in `init/bootstrap.ts`, which is what a *template*
17
+ * requires. That list comes from remote manifests (`neondatabase/examples/bootstrap.yaml`),
18
+ * spells Postgres `database`, and is not ours to rename.
19
+ */
20
+ const NEON_SERVICES = [
21
+ "postgres",
22
+ "auth",
23
+ "data-api",
24
+ "functions",
25
+ "object-storage",
26
+ "ai-gateway"
26
27
  ];
27
28
  /**
28
- * Spellings that used to be canonical, and the service they now mean. Accepted so a scripted
29
- * `--services storage` keeps working, warned about so it does not quietly become a second
30
- * vocabulary, and absent from help text, errors, and docs so nobody learns it fresh.
31
- */
32
- const DEPRECATED_SERVICE_ALIASES = {
33
- // `config init --services storage` shipped before the vocabulary was unified.
34
- storage: "object-storage",
35
- };
29
+ * Spellings that used to be canonical, and the service they now mean. Accepted so a scripted
30
+ * `--services storage` keeps working, warned about so it does not quietly become a second
31
+ * vocabulary, and absent from help text, errors, and docs so nobody learns it fresh.
32
+ */
33
+ const DEPRECATED_SERVICE_ALIASES = { storage: "object-storage" };
36
34
  /** An explicit empty selection, for commands where "declare nothing" is a real answer. */
37
- export const NO_SERVICES = "none";
35
+ const NO_SERVICES = "none";
38
36
  /**
39
- * What to tell someone still using a retired spelling. A message rather than a log call, so
40
- * the parser stays free of the CLI's writer and each command can surface it in its own voice.
41
- */
42
- export const deprecatedServiceMessage = (used, canonical) => `"${used}" is the old name for "${canonical}" and still works, but it will be removed. ` +
43
- `Use "${canonical}".`;
37
+ * What to tell someone still using a retired spelling. A message rather than a log call, so
38
+ * the parser stays free of the CLI's writer and each command can surface it in its own voice.
39
+ */
40
+ const deprecatedServiceMessage = (used, canonical) => `"${used}" is the old name for "${canonical}" and still works, but it will be removed. Use "${canonical}".`;
44
41
  /**
45
- * Parse the raw values of a services flag into a canonical selection.
46
- *
47
- * Accepts the flag repeated (`-s auth -s postgres`) and comma-separated
48
- * (`-s auth,postgres`), since both read naturally and users will try either. The result is
49
- * deduplicated and sorted into {@link NEON_SERVICES} order, so what a command does never
50
- * depends on typing order.
51
- *
52
- * An unrecognized name is rejected rather than dropped: a typo would otherwise act on
53
- * everything *except* the service that was asked for, and report success. A name that is a
54
- * real service but not one this command supports says so specifically — "functions has no env
55
- * variables" is a different problem from a typo, and has a different fix.
56
- */
57
- export const parseServices = (raw, options) => {
58
- const { allowed, flag, noneMeans, whyUnavailable = {}, onDeprecated, } = options;
59
- const supported = `Supported values: ${allowed.join(", ")}${noneMeans !== undefined ? `, ${NO_SERVICES}` : ""}.`;
60
- const names = raw
61
- .flatMap((value) => value.split(","))
62
- .map((name) => name.trim())
63
- .filter((name) => name !== "");
64
- if (names.length === 0) {
65
- throw new Error(`${flag} needs at least one service. ${supported}`);
66
- }
67
- if (noneMeans !== undefined && names.includes(NO_SERVICES)) {
68
- // Deduplicate before deciding it was combined with something: a repeated value is
69
- // a no-op everywhere else in this parser, so `-s none -s none` must be too.
70
- if (new Set(names).size > 1) {
71
- throw new Error(`${flag} ${NO_SERVICES} cannot be combined with other services.`);
72
- }
73
- return [];
74
- }
75
- // Canonicalize first and unconditionally, so a retired spelling is reported against the
76
- // service it means rather than as a word nobody recognizes.
77
- const deprecated = new Map();
78
- const resolved = names.map((name) => {
79
- const canonical = DEPRECATED_SERVICE_ALIASES[name];
80
- if (canonical === undefined)
81
- return name;
82
- deprecated.set(name, canonical);
83
- return canonical;
84
- });
85
- const unsupported = resolved.filter((name) => !allowed.some((service) => service === name));
86
- if (unsupported.length > 0) {
87
- throw new Error(`${unsupportedMessage(unsupported, flag, whyUnavailable)} ${supported}`);
88
- }
89
- // Warned only once the selection is valid: a run that fails validation should not also
90
- // carry a "still works" claim about a value that never took effect.
91
- for (const [used, canonical] of deprecated)
92
- onDeprecated?.(used, canonical);
93
- return NEON_SERVICES.filter((service) => allowed.includes(service) && resolved.includes(service));
42
+ * Parse the raw values of a services flag into a canonical selection.
43
+ *
44
+ * Accepts the flag repeated (`-s auth -s postgres`) and comma-separated
45
+ * (`-s auth,postgres`), since both read naturally and users will try either. The result is
46
+ * deduplicated and sorted into {@link NEON_SERVICES} order, so what a command does never
47
+ * depends on typing order.
48
+ *
49
+ * An unrecognized name is rejected rather than dropped: a typo would otherwise act on
50
+ * everything *except* the service that was asked for, and report success. A name that is a
51
+ * real service but not one this command supports says so specifically — "functions has no env
52
+ * variables" is a different problem from a typo, and has a different fix.
53
+ */
54
+ const parseServices = (raw, options) => {
55
+ const { allowed, flag, noneMeans, whyUnavailable = {}, onDeprecated } = options;
56
+ const supported = `Supported values: ${allowed.join(", ")}${noneMeans !== void 0 ? `, ${NO_SERVICES}` : ""}.`;
57
+ const names = raw.flatMap((value) => value.split(",")).map((name) => name.trim()).filter((name) => name !== "");
58
+ if (names.length === 0) throw new Error(`${flag} needs at least one service. ${supported}`);
59
+ if (noneMeans !== void 0 && names.includes("none")) {
60
+ if (new Set(names).size > 1) throw new Error(`${flag} ${NO_SERVICES} cannot be combined with other services.`);
61
+ return [];
62
+ }
63
+ const deprecated = /* @__PURE__ */ new Map();
64
+ const resolved = names.map((name) => {
65
+ const canonical = DEPRECATED_SERVICE_ALIASES[name];
66
+ if (canonical === void 0) return name;
67
+ deprecated.set(name, canonical);
68
+ return canonical;
69
+ });
70
+ const unsupported = resolved.filter((name) => !allowed.some((service) => service === name));
71
+ if (unsupported.length > 0) throw new Error(`${unsupportedMessage(unsupported, flag, whyUnavailable)} ${supported}`);
72
+ for (const [used, canonical] of deprecated) onDeprecated?.(used, canonical);
73
+ return NEON_SERVICES.filter((service) => allowed.includes(service) && resolved.includes(service));
94
74
  };
95
75
  /**
96
- * The sentences explaining why a selection was refused. A real Neon service this command
97
- * cannot act on is a different mistake from a typo — different cause, different fix — so the
98
- * two are never answered with the same word, and each service carries its reason where the
99
- * command supplied one.
100
- */
76
+ * The sentences explaining why a selection was refused. A real Neon service this command
77
+ * cannot act on is a different mistake from a typo — different cause, different fix — so the
78
+ * two are never answered with the same word, and each service carries its reason where the
79
+ * command supplied one.
80
+ */
101
81
  const unsupportedMessage = (unsupported, flag, whyUnavailable) => {
102
- const known = unsupported.filter((name) => NEON_SERVICES.some((service) => service === name));
103
- const unknown = unsupported.filter((name) => !known.some((service) => service === name));
104
- return [
105
- unknown.length > 0
106
- ? `Unknown service${unknown.length === 1 ? "" : "s"} ${unknown.join(", ")}.`
107
- : undefined,
108
- ...known.map((service) => {
109
- const why = whyUnavailable[service];
110
- return `${service} is not something ${flag} can select${why ? `: ${why}` : ""}.`;
111
- }),
112
- ]
113
- .filter((part) => part !== undefined)
114
- .join(" ");
82
+ const known = unsupported.filter((name) => NEON_SERVICES.some((service) => service === name));
83
+ const unknown = unsupported.filter((name) => !known.some((service) => service === name));
84
+ return [unknown.length > 0 ? `Unknown service${unknown.length === 1 ? "" : "s"} ${unknown.join(", ")}.` : void 0, ...known.map((service) => {
85
+ const why = whyUnavailable[service];
86
+ return `${service} is not something ${flag} can select${why ? `: ${why}` : ""}.`;
87
+ })].filter((part) => part !== void 0).join(" ");
115
88
  };
116
89
  /** Every spelling of the services flag, so a habit picked up on one command works on another. */
117
- const SERVICE_FLAG_NAMES = ["s", "service", "services"];
90
+ const SERVICE_FLAG_NAMES = [
91
+ "s",
92
+ "service",
93
+ "services"
94
+ ];
118
95
  /**
119
- * The yargs option for a services flag, so every command that has one accepts the same
120
- * spellings (`-s`, `--service`, `--services`) and the same value syntax. `key` is the name the
121
- * command reads off `argv`; the rest become aliases.
122
- */
123
- export const servicesOption = (params) => ({
124
- alias: SERVICE_FLAG_NAMES.filter((name) => name !== params.key),
125
- describe: [
126
- `${params.describe}: ${params.allowed.join(", ")}.`,
127
- params.noneMeans !== undefined
128
- ? `Pass "${NO_SERVICES}" for ${params.noneMeans}.`
129
- : undefined,
130
- "Repeat the flag or comma-separate.",
131
- params.also,
132
- ]
133
- .filter((part) => part !== undefined)
134
- .join(" "),
135
- type: "array",
136
- string: true,
96
+ * The yargs option for a services flag, so every command that has one accepts the same
97
+ * spellings (`-s`, `--service`, `--services`) and the same value syntax. `key` is the name the
98
+ * command reads off `argv`; the rest become aliases.
99
+ */
100
+ const servicesOption = (params) => ({
101
+ alias: SERVICE_FLAG_NAMES.filter((name) => name !== params.key),
102
+ describe: [
103
+ `${params.describe}: ${params.allowed.join(", ")}.`,
104
+ params.noneMeans !== void 0 ? `Pass "${NO_SERVICES}" for ${params.noneMeans}.` : void 0,
105
+ "Repeat the flag or comma-separate.",
106
+ params.also
107
+ ].filter((part) => part !== void 0).join(" "),
108
+ type: "array",
109
+ string: true
137
110
  });
138
111
  /**
139
- * Narrow a yargs value for a services flag to the raw strings, or `undefined` when the flag
140
- * was not given. `argv` is untyped at the handler, and `string: true` only guarantees the
141
- * element type when the flag was actually parsed as an array.
142
- */
143
- export const servicesFlagValue = (value) => Array.isArray(value) ? value.map(String) : undefined;
112
+ * Narrow a yargs value for a services flag to the raw strings, or `undefined` when the flag
113
+ * was not given. `argv` is untyped at the handler, and `string: true` only guarantees the
114
+ * element type when the flag was actually parsed as an array.
115
+ */
116
+ const servicesFlagValue = (value) => Array.isArray(value) ? value.map(String) : void 0;
117
+ //#endregion
118
+ export { NEON_SERVICES, NO_SERVICES, deprecatedServiceMessage, parseServices, servicesFlagValue, servicesOption };