@philkrpp/phase-loader 0.1.2 → 0.1.3
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.
- package/README.md +3 -1
- package/dist/cli.js +25 -6
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1 -1
- package/dist/{run-QGYeawST.js → run-CkwwrycO.js} +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,7 +32,8 @@ secrets: host, app ids, paths and keyring account names only.
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"require": ["DATABASE_URL"],
|
|
35
|
-
"allowLiteral": []
|
|
35
|
+
"allowLiteral": [],
|
|
36
|
+
"external": ["WORKER_TIER"]
|
|
36
37
|
}
|
|
37
38
|
```
|
|
38
39
|
|
|
@@ -45,6 +46,7 @@ secrets: host, app ids, paths and keyring account names only.
|
|
|
45
46
|
| `targets.<name>.personal.account` | Optional keyring account holding a personal app id or name; exported last (path `/`). |
|
|
46
47
|
| `require` | Keys the merged export must contain; otherwise loading fails and lists the missing names. |
|
|
47
48
|
| `allowLiteral` | Keys whose value may start with `${`. Any other value starting with `${` is an unresolved Phase reference and fails the load. |
|
|
49
|
+
| `external` | Names set or read outside the Phase `dev` export: Coolify-only values, CI, runtime, variables read by libraries (`OTEL_*`). `example --write` lists them in their own section; `check` never reports them. |
|
|
48
50
|
|
|
49
51
|
## Tokens
|
|
50
52
|
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as KEYRING_SERVICE, c as loadConfig, l as PhaseLoaderError, n as fetchLayers, s as writeKeyring, t as run } from "./run-
|
|
2
|
+
import { a as KEYRING_SERVICE, c as loadConfig, l as PhaseLoaderError, n as fetchLayers, s as writeKeyring, t as run } from "./run-CkwwrycO.js";
|
|
3
3
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { execFileSync } from "node:child_process";
|
|
@@ -35,7 +35,14 @@ function exampleNames(text) {
|
|
|
35
35
|
* Returns the text to print; values are never read into the output.
|
|
36
36
|
*/
|
|
37
37
|
async function example(opts = {}) {
|
|
38
|
-
const
|
|
38
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
39
|
+
const { dir, sections: phase } = await phaseNames(cwd);
|
|
40
|
+
const inPhase = new Set(phase.flatMap((s) => s.names));
|
|
41
|
+
const external = [...new Set(loadConfig(cwd).external)].filter((n) => !inPhase.has(n)).sort();
|
|
42
|
+
const sections = [...phase, {
|
|
43
|
+
label: "external (not loaded from Phase: Coolify, CI, runtime, libraries)",
|
|
44
|
+
names: external
|
|
45
|
+
}];
|
|
39
46
|
const text = sections.filter((s) => s.names.length > 0).map((s) => `# ${s.label}\n${s.names.map((n) => `${n}=`).join("\n")}\n`).join("\n");
|
|
40
47
|
const file = join(dir, EXAMPLE_FILE);
|
|
41
48
|
if (opts.write) {
|
|
@@ -73,7 +80,17 @@ const BUILT_IN = /* @__PURE__ */ new Set([
|
|
|
73
80
|
"SSR",
|
|
74
81
|
"BASE_URL",
|
|
75
82
|
"CI",
|
|
76
|
-
"PHASE_ENV_LOADED"
|
|
83
|
+
"PHASE_ENV_LOADED",
|
|
84
|
+
"VITEST",
|
|
85
|
+
"PATH",
|
|
86
|
+
"HOME",
|
|
87
|
+
"USER",
|
|
88
|
+
"LOGNAME",
|
|
89
|
+
"SHELL",
|
|
90
|
+
"PWD",
|
|
91
|
+
"TMPDIR",
|
|
92
|
+
"TZ",
|
|
93
|
+
"LANG"
|
|
77
94
|
]);
|
|
78
95
|
function trackedFiles(dir) {
|
|
79
96
|
try {
|
|
@@ -114,15 +131,17 @@ function usedNames(dir) {
|
|
|
114
131
|
* Online: also against the key names in Phase (`dev`). Names only, never values. `ok` is false on any finding.
|
|
115
132
|
*/
|
|
116
133
|
async function check(opts = {}) {
|
|
117
|
-
const
|
|
134
|
+
const config = loadConfig(opts.cwd ?? process.cwd());
|
|
135
|
+
const dir = config.dir;
|
|
118
136
|
const file = join(dir, EXAMPLE_FILE);
|
|
119
137
|
if (!existsSync(file)) throw new PhaseLoaderError(`${EXAMPLE_FILE} not found in ${dir} (create it with "phase-loader example --write").`);
|
|
138
|
+
const external = new Set(config.external);
|
|
120
139
|
const documented = new Set(exampleNames(readFileSync(file, "utf8")));
|
|
121
140
|
const { used, quoted } = usedNames(dir);
|
|
122
|
-
const findings = [[`Used in code but undocumented in ${EXAMPLE_FILE}:`, [...used].filter((n) => !documented.has(n))], [`Orphan in ${EXAMPLE_FILE} (never read in tracked code):`, [...documented].filter((n) => !used.has(n) && !quoted.has(n))]];
|
|
141
|
+
const findings = [[`Used in code but undocumented in ${EXAMPLE_FILE}:`, [...used].filter((n) => !documented.has(n) && !external.has(n))], [`Orphan in ${EXAMPLE_FILE} (never read in tracked code):`, [...documented].filter((n) => !used.has(n) && !quoted.has(n) && !external.has(n))]];
|
|
123
142
|
if (!opts.offline) {
|
|
124
143
|
const inPhase = new Set((await phaseNames(opts.cwd ?? process.cwd())).sections.flatMap((s) => s.names));
|
|
125
|
-
findings.push([`In ${EXAMPLE_FILE} but not in Phase:`, [...documented].filter((n) => !inPhase.has(n))], [`In Phase but not in ${EXAMPLE_FILE}:`, [...inPhase].filter((n) => !documented.has(n))]);
|
|
144
|
+
findings.push([`In ${EXAMPLE_FILE} but not in Phase:`, [...documented].filter((n) => !inPhase.has(n) && !external.has(n))], [`In Phase but not in ${EXAMPLE_FILE}:`, [...inPhase].filter((n) => !documented.has(n))]);
|
|
126
145
|
}
|
|
127
146
|
const lines = findings.filter(([, names]) => names.length > 0).flatMap(([title, names]) => [title, ` ${names.sort().join(", ")}`]);
|
|
128
147
|
return lines.length > 0 ? {
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,11 @@ interface PhaseConfig {
|
|
|
26
26
|
require: string[];
|
|
27
27
|
/** Keys whose value may start with `${` (not a Phase reference). */
|
|
28
28
|
allowLiteral: string[];
|
|
29
|
+
/**
|
|
30
|
+
* Names read or set outside the Phase `dev` export (Coolify-only values, CI, runtime, libraries such as OTEL_*):
|
|
31
|
+
* listed in their own `.env.example` section and never reported by `check`.
|
|
32
|
+
*/
|
|
33
|
+
external: string[];
|
|
29
34
|
}
|
|
30
35
|
/** Finds the nearest `phase.config.json` from `cwd` upwards, validates and returns it. */
|
|
31
36
|
export declare function loadConfig(cwd: string): PhaseConfig;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { l as PhaseLoaderError, c as loadConfig, r as loadPhaseEnv, i as loadPhaseEnvSync, o as readToken, t as run } from "./run-
|
|
1
|
+
export { l as PhaseLoaderError, c as loadConfig, r as loadPhaseEnv, i as loadPhaseEnvSync, o as readToken, t as run } from "./run-CkwwrycO.js";
|
|
@@ -84,7 +84,8 @@ function parseConfig(file, dir) {
|
|
|
84
84
|
host,
|
|
85
85
|
targets,
|
|
86
86
|
require: keys(raw.require, "require"),
|
|
87
|
-
allowLiteral: keys(raw.allowLiteral, "allowLiteral")
|
|
87
|
+
allowLiteral: keys(raw.allowLiteral, "allowLiteral"),
|
|
88
|
+
external: keys(raw.external, "external")
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
91
|
function isObject$1(value) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@philkrpp/phase-loader",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Load env values from a self-hosted Phase secrets manager into a child process or the current process, with layered apps/paths and OS keyring tokens.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|