neon 8.3.6 → 8.4.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.
@@ -0,0 +1,43 @@
1
+ //#region src/utils/repeated_flags.ts
2
+ const isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
3
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
4
+ /** The options yargs has declared for the command it is running. Not in `@types/yargs`. */
5
+ const declaredOptions = (cli) => {
6
+ if (!("getOptions" in cli) || typeof cli.getOptions !== "function") throw new Error("yargs no longer exposes getOptions(); update declaredOptions for the installed yargs");
7
+ const options = cli.getOptions();
8
+ if (!isRecord(options) || !isRecord(options.key) || !isRecord(options.alias) || !Object.values(options.alias).every(isStringArray) || !isStringArray(options.array) || !isStringArray(options.boolean) || !isStringArray(options.count)) throw new Error("yargs getOptions() changed shape; update declaredOptions for the installed yargs");
9
+ return {
10
+ key: options.key,
11
+ alias: Object.fromEntries(Object.entries(options.alias).filter((entry) => isStringArray(entry[1]))),
12
+ array: options.array,
13
+ boolean: options.boolean,
14
+ count: options.count
15
+ };
16
+ };
17
+ const camelCase = (name) => name.replace(/-+([a-z0-9])/g, (_, char) => char.toUpperCase());
18
+ /**
19
+ * yargs collects a repeated option into an array unless it is declared as one, so a handler
20
+ * written for one string receives several. Identical repeats collapse to one value; different
21
+ * values are an error, worded like `single()` in flags.ts. The values are not echoed, because
22
+ * `--api-key` is one of these flags.
23
+ */
24
+ const collapseRepeatedFlags = (argv, options) => {
25
+ const multiValued = /* @__PURE__ */ new Set([
26
+ ...options.array,
27
+ ...options.boolean,
28
+ ...options.count
29
+ ]);
30
+ const aliases = new Set(Object.values(options.alias).flat());
31
+ for (const name of Object.keys(options.key)) {
32
+ if (multiValued.has(name) || aliases.has(name)) continue;
33
+ const value = argv[name];
34
+ if (!Array.isArray(value) || value.length < 2) continue;
35
+ if (new Set(value).size > 1) throw new Error(`--${name} was given more than once. Pass it at most once.`);
36
+ for (const key of [name, ...options.alias[name] ?? []]) {
37
+ argv[key] = value[0];
38
+ argv[camelCase(key)] = value[0];
39
+ }
40
+ }
41
+ };
42
+ //#endregion
43
+ export { collapseRepeatedFlags, declaredOptions };
@@ -0,0 +1,49 @@
1
+ import { Parser, hideBin } from "yargs/helpers";
2
+ //#region src/utils/staging.ts
3
+ /**
4
+ * Staging-only features ship in a release before their API reaches production. The CLI
5
+ * exposes them only when the API host it sends requests to (`--api-host`, else
6
+ * `NEON_API_HOST`) is Neon's staging console; with production or no host set, they are
7
+ * hidden from help and fail with a "coming soon" message.
8
+ */
9
+ const STAGING_API_HOST = "https://console-stage.neon.build/api/v2";
10
+ const REALTIME_COMING_SOON = `Neon Realtime is coming soon! For now it only works on Neon's staging API: set NEON_API_HOST=${STAGING_API_HOST} or pass --api-host.`;
11
+ /** `NEON_STAGING_API_HOST` lets the CLI's tests treat their local mock API as staging. */
12
+ const stagingHostname = () => new URL(process.env.NEON_STAGING_API_HOST ?? "https://console-stage.neon.build/api/v2").hostname;
13
+ const isStagingApiHost = (apiHost) => apiHost !== void 0 && URL.canParse(apiHost) && new URL(apiHost).hostname === stagingHostname();
14
+ /** The API host this process was invoked with, read before or without yargs. */
15
+ const stagingFeaturesEnabledForArgv = (args = hideBin(process.argv)) => {
16
+ const { argv } = Parser.detailed([...args], {
17
+ string: ["api-host"],
18
+ alias: { "api-host": ["apiHost"] },
19
+ configuration: {
20
+ "populate--": true,
21
+ "parse-positional-numbers": false
22
+ }
23
+ });
24
+ const flag = argv["api-host"];
25
+ return isStagingApiHost(typeof flag === "string" ? flag : process.env.NEON_API_HOST);
26
+ };
27
+ /** `apiHost` is a command's resolved host; without one, the host this process was invoked with. */
28
+ const stagingFeaturesEnabled = (apiHost) => apiHost === void 0 ? stagingFeaturesEnabledForArgv() : isStagingApiHost(apiHost);
29
+ /** Service names to list in help: Realtime only on staging. */
30
+ const listedServices = (services) => stagingFeaturesEnabledForArgv() ? services : services.filter((service) => service !== "realtime");
31
+ /** A hard stop: callers that degrade other failures to warnings let this one through. */
32
+ var StagingOnlyError = class extends Error {
33
+ constructor(..._args) {
34
+ super(..._args);
35
+ this.name = "StagingOnlyError";
36
+ }
37
+ };
38
+ const assertRealtimeAvailable = (apiHost) => {
39
+ if (!stagingFeaturesEnabled(apiHost)) throw new StagingOnlyError(REALTIME_COMING_SOON);
40
+ };
41
+ /**
42
+ * A `neon.ts` with any `preview.realtime` value reads the Realtime API, which production
43
+ * does not serve. `false` reads it too, to disable Realtime on the branch.
44
+ */
45
+ const assertPolicyAvailable = (config, apiHost) => {
46
+ if (config.preview?.realtime !== void 0) assertRealtimeAvailable(apiHost);
47
+ };
48
+ //#endregion
49
+ export { REALTIME_COMING_SOON, STAGING_API_HOST, StagingOnlyError, assertPolicyAvailable, assertRealtimeAvailable, isStagingApiHost, listedServices, stagingFeaturesEnabled, stagingFeaturesEnabledForArgv };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neon",
3
- "version": "8.3.6",
3
+ "version": "8.4.1",
4
4
  "description": "CLI tool for Neon, the cloud backend primitives built around Lakebase Postgres",
5
5
  "keywords": [
6
6
  "neon",
@@ -55,6 +55,7 @@
55
55
  "fflate": "^0.8.3",
56
56
  "open": "^10.2.0",
57
57
  "openid-client": "6.8.1",
58
+ "pg-connection-string": "^2.14.1",
58
59
  "pg-protocol": "^1.14.0",
59
60
  "picocolors": "^1.1.1",
60
61
  "prompts": "2.4.2",
@@ -64,9 +65,10 @@
64
65
  "yaml": "^2.9.0",
65
66
  "yargs": "17.7.2",
66
67
  "yoctocolors": "^2.1.2",
67
- "@neon/config-runtime": "1.8.1",
68
- "@neon/sdk": "7.0.1",
69
- "@neon/config": "1.8.7"
68
+ "@neon/config": "1.9.1",
69
+ "@neon/config-runtime": "1.9.1",
70
+ "@neon/realtime": "0.0.1",
71
+ "@neon/sdk": "7.2.0"
70
72
  },
71
73
  "optionalDependencies": {
72
74
  "@napi-rs/keyring": "1.3.0",
@@ -101,7 +103,7 @@
101
103
  "typescript": "^5.9.0",
102
104
  "vitest": "^3.0.9",
103
105
  "@neon-internals/cli-core": "0.0.0",
104
- "@neon-internals/env-core": "0.0.30",
106
+ "@neon-internals/env-core": "0.0.32",
105
107
  "@neon/e2e-harness": "0.0.0",
106
108
  "@neon/functions": "0.11.0"
107
109
  },