@nifrajs/env 4.0.2 → 5.1.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.
- package/README.md +5 -1
- package/dist/define.d.ts +4 -2
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +15 -3
- package/dist/define.js.map +1 -1
- package/package.json +1 -1
- package/src/define.ts +16 -3
package/README.md
CHANGED
|
@@ -64,7 +64,11 @@ pass the request's bindings: `defineEnv(shape, { source: env })`.
|
|
|
64
64
|
## Secret safety
|
|
65
65
|
|
|
66
66
|
Error messages name the offending variable and the reason - **never its value** (it may be a
|
|
67
|
-
secret).
|
|
67
|
+
secret). A BYO validator such as valibot or zod may quote the value in its message, escaped or
|
|
68
|
+
cut short, so when it refuses a set value `defineEnv` reports the variable as invalid without the
|
|
69
|
+
validator's message. For an unset variable the message is shown, since there is no value to quote.
|
|
70
|
+
Use the `env.*` helpers when you want the reason as well. `defineEnv` returns a frozen object, so a
|
|
71
|
+
validated config can't be mutated downstream.
|
|
68
72
|
|
|
69
73
|
## For AI agents
|
|
70
74
|
|
package/dist/define.d.ts
CHANGED
|
@@ -32,8 +32,10 @@ export interface DefineEnvOptions {
|
|
|
32
32
|
* ```
|
|
33
33
|
*
|
|
34
34
|
* Errors name the offending variable and the reason - never its value (it may be a secret). BYO
|
|
35
|
-
* validators (`t`, zod, valibot) work too
|
|
36
|
-
*
|
|
35
|
+
* validators (`t`, zod, valibot) work too, but their messages may quote the value, so a set value
|
|
36
|
+
* they refuse is reported as invalid without their words; an unset one shows their message. Only the
|
|
37
|
+
* `env.*` helpers coerce from strings, so a plain `t.number()` would see the raw string - use
|
|
38
|
+
* `env.number()` for coercion.
|
|
37
39
|
*/
|
|
38
40
|
export declare function defineEnv<S extends EnvShape>(shape: S, options?: DefineEnvOptions): EnvResult<S>;
|
|
39
41
|
//# sourceMappingURL=define.d.ts.map
|
package/dist/define.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEhE,kCAAkC;AAClC,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;AAEvD,4EAA4E;AAC5E,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,QAAQ,IAAI;IAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAE1F,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CACrD;
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEhE,kCAAkC;AAClC,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;AAEvD,4EAA4E;AAC5E,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,QAAQ,IAAI;IAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAE1F,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CACrD;AAID;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC,CAAC,CAAC,CAuChG"}
|
package/dist/define.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const WITHHELD = "is invalid (the validator's message is withheld, since it may quote the value)";
|
|
1
2
|
/**
|
|
2
3
|
* Validate the environment against a schema and return a **frozen, typed** object - or throw at
|
|
3
4
|
* startup listing **every** problem at once (not just the first), so a misconfigured deploy fails
|
|
@@ -18,8 +19,10 @@
|
|
|
18
19
|
* ```
|
|
19
20
|
*
|
|
20
21
|
* Errors name the offending variable and the reason - never its value (it may be a secret). BYO
|
|
21
|
-
* validators (`t`, zod, valibot) work too
|
|
22
|
-
*
|
|
22
|
+
* validators (`t`, zod, valibot) work too, but their messages may quote the value, so a set value
|
|
23
|
+
* they refuse is reported as invalid without their words; an unset one shows their message. Only the
|
|
24
|
+
* `env.*` helpers coerce from strings, so a plain `t.number()` would see the raw string - use
|
|
25
|
+
* `env.number()` for coercion.
|
|
23
26
|
*/
|
|
24
27
|
export function defineEnv(shape, options) {
|
|
25
28
|
const source = options?.source ??
|
|
@@ -32,11 +35,20 @@ export function defineEnv(shape, options) {
|
|
|
32
35
|
const result = schema["~standard"].validate(source[key]);
|
|
33
36
|
if (result instanceof Promise) {
|
|
34
37
|
// Env validation must be synchronous (it runs once, at import) - an async validator is a
|
|
35
|
-
// configuration mistake, surfaced as a problem
|
|
38
|
+
// configuration mistake, surfaced as a problem. Its promise is observed so a rejection is not
|
|
39
|
+
// reported as unhandled after the caller catches the refusal.
|
|
40
|
+
result.catch(() => { });
|
|
36
41
|
problems.push(` ${key}: async validators are not supported in defineEnv`);
|
|
37
42
|
continue;
|
|
38
43
|
}
|
|
39
44
|
if (result.issues !== undefined) {
|
|
45
|
+
const raw = source[key];
|
|
46
|
+
// Only the `env.*` helpers promise value-free messages. Another validator may quote the value
|
|
47
|
+
// escaped, truncated or transformed, past any search-and-replace, so its words are not shown.
|
|
48
|
+
if (schema["~standard"].vendor !== "nifra-env" && raw !== undefined && raw !== "") {
|
|
49
|
+
problems.push(` ${key}: ${WITHHELD}`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
40
52
|
for (const i of result.issues)
|
|
41
53
|
problems.push(` ${key}: ${i.message}`);
|
|
42
54
|
}
|
package/dist/define.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAgBA
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAgBA,MAAM,QAAQ,GAAG,gFAAgF,CAAA;AAEjG;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,SAAS,CAAqB,KAAQ,EAAE,OAA0B;IAChF,MAAM,MAAM,GACV,OAAO,EAAE,MAAM;QACd,UAAyE,CAAC,OAAO,EAAE,GAAG;QACvF,EAAE,CAAA;IACJ,MAAM,GAAG,GAA4B,EAAE,CAAA;IACvC,MAAM,QAAQ,GAAa,EAAE,CAAA;IAE7B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAqB,CAAA;QAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QACxD,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;YAC9B,yFAAyF;YACzF,8FAA8F;YAC9F,8DAA8D;YAC9D,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACtB,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,mDAAmD,CAAC,CAAA;YAC1E,SAAQ;QACV,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;YACvB,8FAA8F;YAC9F,8FAA8F;YAC9F,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;gBAClF,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,QAAQ,EAAE,CAAC,CAAA;gBACtC,SAAQ;YACV,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM;gBAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACxE,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAA;QACzB,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,qCAAqC,QAAQ,CAAC,MAAM,iBAAiB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,4CAA4C,CACrI,CAAA;IACH,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAiB,CAAA;AAC3C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/env",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Typed, validated environment variables for nifra - define a schema, get a frozen typed object, fail loud at boot listing every problem. Coercing helpers (number/port/boolean/url/enum) + any Standard Schema. Dependency-free, edge-safe.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
package/src/define.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface DefineEnvOptions {
|
|
|
14
14
|
readonly source?: Record<string, string | undefined>
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
const WITHHELD = "is invalid (the validator's message is withheld, since it may quote the value)"
|
|
18
|
+
|
|
17
19
|
/**
|
|
18
20
|
* Validate the environment against a schema and return a **frozen, typed** object - or throw at
|
|
19
21
|
* startup listing **every** problem at once (not just the first), so a misconfigured deploy fails
|
|
@@ -34,8 +36,10 @@ export interface DefineEnvOptions {
|
|
|
34
36
|
* ```
|
|
35
37
|
*
|
|
36
38
|
* Errors name the offending variable and the reason - never its value (it may be a secret). BYO
|
|
37
|
-
* validators (`t`, zod, valibot) work too
|
|
38
|
-
*
|
|
39
|
+
* validators (`t`, zod, valibot) work too, but their messages may quote the value, so a set value
|
|
40
|
+
* they refuse is reported as invalid without their words; an unset one shows their message. Only the
|
|
41
|
+
* `env.*` helpers coerce from strings, so a plain `t.number()` would see the raw string - use
|
|
42
|
+
* `env.number()` for coercion.
|
|
39
43
|
*/
|
|
40
44
|
export function defineEnv<S extends EnvShape>(shape: S, options?: DefineEnvOptions): EnvResult<S> {
|
|
41
45
|
const source =
|
|
@@ -50,11 +54,20 @@ export function defineEnv<S extends EnvShape>(shape: S, options?: DefineEnvOptio
|
|
|
50
54
|
const result = schema["~standard"].validate(source[key])
|
|
51
55
|
if (result instanceof Promise) {
|
|
52
56
|
// Env validation must be synchronous (it runs once, at import) - an async validator is a
|
|
53
|
-
// configuration mistake, surfaced as a problem
|
|
57
|
+
// configuration mistake, surfaced as a problem. Its promise is observed so a rejection is not
|
|
58
|
+
// reported as unhandled after the caller catches the refusal.
|
|
59
|
+
result.catch(() => {})
|
|
54
60
|
problems.push(` ${key}: async validators are not supported in defineEnv`)
|
|
55
61
|
continue
|
|
56
62
|
}
|
|
57
63
|
if (result.issues !== undefined) {
|
|
64
|
+
const raw = source[key]
|
|
65
|
+
// Only the `env.*` helpers promise value-free messages. Another validator may quote the value
|
|
66
|
+
// escaped, truncated or transformed, past any search-and-replace, so its words are not shown.
|
|
67
|
+
if (schema["~standard"].vendor !== "nifra-env" && raw !== undefined && raw !== "") {
|
|
68
|
+
problems.push(` ${key}: ${WITHHELD}`)
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
58
71
|
for (const i of result.issues) problems.push(` ${key}: ${i.message}`)
|
|
59
72
|
} else {
|
|
60
73
|
out[key] = result.value
|