@neondatabase/env 0.13.0 → 0.13.2
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.
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Resolve the Neon API key for a `neon-env` CLI invocation. Precedence (each wins over the
|
|
4
4
|
* next): `--api-key` flag → `NEON_API_KEY` → `access_token` from the Neon CLI's
|
|
5
|
-
* `credentials.json`.
|
|
5
|
+
* `credentials.json`, located by `@neon/config/paths`.
|
|
6
6
|
*
|
|
7
7
|
* The CLI owns this resolution — `@neon/config` and `@neon/env` are deliberately
|
|
8
8
|
* environment- and filesystem-agnostic and only ever accept an explicit `apiKey`, so the
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { resolveConfigFile } from "@neon/config/paths";
|
|
3
3
|
//#region src/lib/cli/resolve-api-key.ts
|
|
4
4
|
/**
|
|
5
5
|
* Resolve the Neon API key for a `neon-env` CLI invocation. Precedence (each wins over the
|
|
6
6
|
* next): `--api-key` flag → `NEON_API_KEY` → `access_token` from the Neon CLI's
|
|
7
|
-
* `credentials.json`.
|
|
7
|
+
* `credentials.json`, located by `@neon/config/paths`.
|
|
8
8
|
*
|
|
9
9
|
* The CLI owns this resolution — `@neon/config` and `@neon/env` are deliberately
|
|
10
10
|
* environment- and filesystem-agnostic and only ever accept an explicit `apiKey`, so the
|
|
@@ -19,18 +19,23 @@ function resolveApiKey(options) {
|
|
|
19
19
|
return nonEmpty(options.apiKey) ?? nonEmpty(env.NEON_API_KEY) ?? readStoredAccessToken(env);
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* Read `access_token` from the Neon CLI's credentials file
|
|
23
|
-
* precedence `neon auth` writes to: `NEONCTL_CONFIG_DIR` → `<home>/.config/neonctl`
|
|
24
|
-
* (`HOME`, falling back to `USERPROFILE` for Windows parity).
|
|
22
|
+
* Read `access_token` from the Neon CLI's credentials file.
|
|
25
23
|
*
|
|
26
|
-
*
|
|
24
|
+
* Location resolution is delegated to `@neon/config/paths` so this agrees with the `neon`
|
|
25
|
+
* CLI itself — `NEON_CONFIG_DIR` / `NEONCTL_CONFIG_DIR`, else `$XDG_CONFIG_HOME/neon`, else
|
|
26
|
+
* `~/.config/neon`, with an existing legacy `neonctl` directory still read. Rolling that
|
|
27
|
+
* lookup by hand here is how the two drifted in the first place: this file honoured the env
|
|
28
|
+
* var but not XDG, while the CLI honoured XDG but not the env var, so with
|
|
29
|
+
* `XDG_CONFIG_HOME` set they disagreed about where credentials lived.
|
|
30
|
+
*
|
|
31
|
+
* Reads only `DEFAULT` — a profile is a CLI-invocation concept, and `neon-env` has no
|
|
32
|
+
* `--profile` of its own to read one from.
|
|
33
|
+
*
|
|
34
|
+
* Never throws: a missing, unreadable, malformed, or token-less file is simply "no key",
|
|
27
35
|
* so this can sit in a resolution chain without try/catch noise.
|
|
28
36
|
*/
|
|
29
37
|
function readStoredAccessToken(env) {
|
|
30
|
-
const
|
|
31
|
-
const configDir = nonEmpty(env.NEONCTL_CONFIG_DIR) ?? (home ? resolve(home, ".config", "neonctl") : void 0);
|
|
32
|
-
if (!configDir) return void 0;
|
|
33
|
-
const credentialsPath = resolve(configDir, "credentials.json");
|
|
38
|
+
const { path: credentialsPath } = resolveConfigFile("credentials.json", { env });
|
|
34
39
|
if (!existsSync(credentialsPath)) return void 0;
|
|
35
40
|
let parsed;
|
|
36
41
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-api-key.js","names":[],"sources":["../../../src/lib/cli/resolve-api-key.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport {
|
|
1
|
+
{"version":3,"file":"resolve-api-key.js","names":[],"sources":["../../../src/lib/cli/resolve-api-key.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { resolveConfigFile } from \"@neon/config/paths\";\n\n/**\n * Resolve the Neon API key for a `neon-env` CLI invocation. Precedence (each wins over the\n * next): `--api-key` flag → `NEON_API_KEY` → `access_token` from the Neon CLI's\n * `credentials.json`, located by `@neon/config/paths`.\n *\n * The CLI owns this resolution — `@neon/config` and `@neon/env` are deliberately\n * environment- and filesystem-agnostic and only ever accept an explicit `apiKey`, so the\n * ambient sources a *user* expects have to be read here. This mirrors `resolveContext`,\n * which does the same for project and branch.\n *\n * Returns `undefined` rather than throwing when nothing provides a key: the caller passes\n * it straight through, and the library raises the uniform `PLATFORM_MISSING_API_KEY` error.\n */\nexport function resolveApiKey(options: {\n\tapiKey?: string;\n\tenv?: NodeJS.ProcessEnv;\n}): string | undefined {\n\tconst env = options.env ?? process.env;\n\treturn (\n\t\tnonEmpty(options.apiKey) ??\n\t\tnonEmpty(env.NEON_API_KEY) ??\n\t\treadStoredAccessToken(env)\n\t);\n}\n\n/**\n * Read `access_token` from the Neon CLI's credentials file.\n *\n * Location resolution is delegated to `@neon/config/paths` so this agrees with the `neon`\n * CLI itself — `NEON_CONFIG_DIR` / `NEONCTL_CONFIG_DIR`, else `$XDG_CONFIG_HOME/neon`, else\n * `~/.config/neon`, with an existing legacy `neonctl` directory still read. Rolling that\n * lookup by hand here is how the two drifted in the first place: this file honoured the env\n * var but not XDG, while the CLI honoured XDG but not the env var, so with\n * `XDG_CONFIG_HOME` set they disagreed about where credentials lived.\n *\n * Reads only `DEFAULT` — a profile is a CLI-invocation concept, and `neon-env` has no\n * `--profile` of its own to read one from.\n *\n * Never throws: a missing, unreadable, malformed, or token-less file is simply \"no key\",\n * so this can sit in a resolution chain without try/catch noise.\n */\nfunction readStoredAccessToken(env: NodeJS.ProcessEnv): string | undefined {\n\tconst { path: credentialsPath } = resolveConfigFile(\"credentials.json\", {\n\t\tenv,\n\t});\n\tif (!existsSync(credentialsPath)) return undefined;\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(readFileSync(credentialsPath, \"utf-8\"));\n\t} catch {\n\t\treturn undefined;\n\t}\n\n\tif (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed))\n\t\treturn undefined;\n\treturn nonEmpty((parsed as Record<string, unknown>).access_token as string);\n}\n\nfunction nonEmpty(value: string | undefined): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\tconst trimmed = value.trim();\n\treturn trimmed === \"\" ? undefined : trimmed;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,SAAgB,cAAc,SAGP;CACtB,MAAM,MAAM,QAAQ,OAAO,QAAQ;CACnC,OACC,SAAS,QAAQ,MAAM,KACvB,SAAS,IAAI,YAAY,KACzB,sBAAsB,GAAG;AAE3B;;;;;;;;;;;;;;;;;AAkBA,SAAS,sBAAsB,KAA4C;CAC1E,MAAM,EAAE,MAAM,oBAAoB,kBAAkB,oBAAoB,EACvE,IACD,CAAC;CACD,IAAI,CAAC,WAAW,eAAe,GAAG,OAAO,KAAA;CAEzC,IAAI;CACJ,IAAI;EACH,SAAS,KAAK,MAAM,aAAa,iBAAiB,OAAO,CAAC;CAC3D,QAAQ;EACP;CACD;CAEA,IAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GACxE,OAAO,KAAA;CACR,OAAO,SAAU,OAAmC,YAAsB;AAC3E;AAEA,SAAS,SAAS,OAA+C;CAChE,IAAI,OAAO,UAAU,UAAU,OAAO,KAAA;CACtC,MAAM,UAAU,MAAM,KAAK;CAC3B,OAAO,YAAY,KAAK,KAAA,IAAY;AACrC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neondatabase/env",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"description": "Resolve and inject Neon connection strings for the branch selected by your neon.ts policy. fetchEnv / parseEnv plus a `neon-env` CLI with `run` and `export`.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"neon",
|
|
@@ -51,12 +51,12 @@
|
|
|
51
51
|
"typescript": "^5.9.0",
|
|
52
52
|
"vitest": "^3.0.9",
|
|
53
53
|
"@neon/e2e-harness": "0.0.0",
|
|
54
|
-
"@neon/sdk": "1.4.
|
|
54
|
+
"@neon/sdk": "1.4.1"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"zod": "^4.4.3",
|
|
58
58
|
"yargs": "^18.0.0",
|
|
59
|
-
"@neon/config": "0.
|
|
59
|
+
"@neon/config": "0.13.1"
|
|
60
60
|
},
|
|
61
61
|
"engines": {
|
|
62
62
|
"node": ">=20.19.0"
|