@nifrajs/env 2.2.0 → 2.4.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 +8 -8
- package/dist/define.d.ts +6 -6
- package/dist/define.js +6 -6
- package/dist/helpers.d.ts +4 -4
- package/dist/helpers.js +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/schema.js +1 -1
- package/package.json +2 -2
- package/src/define.ts +8 -8
- package/src/helpers.ts +5 -5
- package/src/index.ts +1 -1
- package/src/schema.ts +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# @nifrajs/env
|
|
2
2
|
|
|
3
3
|
Typed, validated environment variables. Define a schema once at startup; get a **frozen, typed**
|
|
4
|
-
object
|
|
4
|
+
object - or a **loud boot-time failure listing every problem at once**, so a misconfigured deploy
|
|
5
5
|
fails immediately instead of erroring on the first request that touches a bad var. The config half
|
|
6
6
|
of nifra's "validate at every boundary" rule. Dependency-free, edge-safe.
|
|
7
7
|
|
|
8
8
|
```ts
|
|
9
|
-
// env.ts
|
|
9
|
+
// env.ts - imported once at startup
|
|
10
10
|
import { defineEnv, env } from "@nifrajs/env"
|
|
11
11
|
|
|
12
12
|
export const ENV = defineEnv({
|
|
@@ -27,7 +27,7 @@ export const ENV = defineEnv({
|
|
|
27
27
|
A missing/invalid var fails at import:
|
|
28
28
|
|
|
29
29
|
```
|
|
30
|
-
[nifra/env] invalid environment
|
|
30
|
+
[nifra/env] invalid environment - 2 problem(s):
|
|
31
31
|
DATABASE_URL: must be a valid URL
|
|
32
32
|
STRIPE_SECRET: is required
|
|
33
33
|
|
|
@@ -42,7 +42,7 @@ Every value in `process.env` is a `string | undefined`; these turn it into the v
|
|
|
42
42
|
| --- | --- | --- |
|
|
43
43
|
| `env.string({ default?, optional? })` | `string` | empty string counts as unset |
|
|
44
44
|
| `env.number({ default?, optional? })` | `number` | finite, coerced |
|
|
45
|
-
| `env.port({ default? })` | `number` | integer 1
|
|
45
|
+
| `env.port({ default? })` | `number` | integer 1-65535 |
|
|
46
46
|
| `env.boolean({ default? })` | `boolean` | `true`/`1`/`yes`/`on` vs `false`/`0`/`no`/`off`/empty |
|
|
47
47
|
| `env.enum([...], { default? })` | union | one of the listed values |
|
|
48
48
|
| `env.url({ default?, optional? })` | `string` | parses with WHATWG `URL`, returns the normalized href |
|
|
@@ -52,23 +52,23 @@ Every value in `process.env` is a `string | undefined`; these turn it into the v
|
|
|
52
52
|
## Bring your own validator
|
|
53
53
|
|
|
54
54
|
`defineEnv` accepts **any Standard Schema** (`t` from `@nifrajs/schema`, zod, valibot), not just the
|
|
55
|
-
`env.*` helpers
|
|
55
|
+
`env.*` helpers - handy for a shape the helpers don't cover. Only the `env.*` helpers coerce from
|
|
56
56
|
strings, though: a plain `t.number()` would see the raw string, so reach for `env.number()` when you
|
|
57
57
|
need coercion.
|
|
58
58
|
|
|
59
59
|
## Edge runtimes
|
|
60
60
|
|
|
61
|
-
`defineEnv` reads `process.env` by default (Bun/Node). Cloudflare Workers has no `process.env`
|
|
61
|
+
`defineEnv` reads `process.env` by default (Bun/Node). Cloudflare Workers has no `process.env` -
|
|
62
62
|
pass the request's bindings: `defineEnv(shape, { source: env })`.
|
|
63
63
|
|
|
64
64
|
## Secret safety
|
|
65
65
|
|
|
66
|
-
Error messages name the offending variable and the reason
|
|
66
|
+
Error messages name the offending variable and the reason - **never its value** (it may be a
|
|
67
67
|
secret). `defineEnv` returns a frozen object, so a validated config can't be mutated downstream.
|
|
68
68
|
|
|
69
69
|
## For AI agents
|
|
70
70
|
|
|
71
|
-
Start with [`LLM.md`](./LLM.md)
|
|
71
|
+
Start with [`LLM.md`](./LLM.md) - this package's contract card (the exports you call + its footguns),
|
|
72
72
|
one cheap read instead of the whole corpus. For the wider framework: the repo's
|
|
73
73
|
[`AGENTS.md`](../../AGENTS.md) is the copy-paste quick reference, and
|
|
74
74
|
[`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
|
package/dist/define.d.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import type { InferOutput, StandardSchemaV1 } from "./schema.js";
|
|
2
2
|
/** A schema per variable name. */
|
|
3
3
|
export type EnvShape = Record<string, StandardSchemaV1>;
|
|
4
|
-
/** The frozen, validated result
|
|
4
|
+
/** The frozen, validated result - each key typed by its schema's output. */
|
|
5
5
|
export type EnvResult<S extends EnvShape> = {
|
|
6
6
|
readonly [K in keyof S]: InferOutput<S[K]>;
|
|
7
7
|
};
|
|
8
8
|
export interface DefineEnvOptions {
|
|
9
9
|
/**
|
|
10
10
|
* Where to read variables from. Defaults to `process.env` (Bun/Node). On Cloudflare Workers there
|
|
11
|
-
* is no `process.env`
|
|
11
|
+
* is no `process.env` - pass the request's `env` bindings: `defineEnv(shape, { source: env })`.
|
|
12
12
|
*/
|
|
13
13
|
readonly source?: Record<string, string | undefined>;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Validate the environment against a schema and return a **frozen, typed** object
|
|
16
|
+
* Validate the environment against a schema and return a **frozen, typed** object - or throw at
|
|
17
17
|
* startup listing **every** problem at once (not just the first), so a misconfigured deploy fails
|
|
18
18
|
* loud and immediately instead of erroring on the first request that touches a bad var. This is the
|
|
19
19
|
* boot-time half of nifra's "validate at every boundary" rule, for config.
|
|
20
20
|
*
|
|
21
21
|
* ```ts
|
|
22
|
-
* // env.ts
|
|
22
|
+
* // env.ts - imported once at startup
|
|
23
23
|
* import { defineEnv, env } from "@nifrajs/env"
|
|
24
24
|
* export const ENV = defineEnv({
|
|
25
25
|
* DATABASE_URL: env.url(),
|
|
@@ -31,9 +31,9 @@ export interface DefineEnvOptions {
|
|
|
31
31
|
* // ENV.PORT: number, ENV.NODE_ENV: "development" | "production" | "test", … all validated.
|
|
32
32
|
* ```
|
|
33
33
|
*
|
|
34
|
-
* Errors name the offending variable and the reason
|
|
34
|
+
* Errors name the offending variable and the reason - never its value (it may be a secret). BYO
|
|
35
35
|
* validators (`t`, zod, valibot) work too; only the `env.*` helpers coerce from strings, so a plain
|
|
36
|
-
* `t.number()` would see the raw string
|
|
36
|
+
* `t.number()` would see the raw string - use `env.number()` for coercion.
|
|
37
37
|
*/
|
|
38
38
|
export declare function defineEnv<S extends EnvShape>(shape: S, options?: DefineEnvOptions): EnvResult<S>;
|
|
39
39
|
//# sourceMappingURL=define.d.ts.map
|
package/dist/define.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Validate the environment against a schema and return a **frozen, typed** object
|
|
2
|
+
* Validate the environment against a schema and return a **frozen, typed** object - or throw at
|
|
3
3
|
* startup listing **every** problem at once (not just the first), so a misconfigured deploy fails
|
|
4
4
|
* loud and immediately instead of erroring on the first request that touches a bad var. This is the
|
|
5
5
|
* boot-time half of nifra's "validate at every boundary" rule, for config.
|
|
6
6
|
*
|
|
7
7
|
* ```ts
|
|
8
|
-
* // env.ts
|
|
8
|
+
* // env.ts - imported once at startup
|
|
9
9
|
* import { defineEnv, env } from "@nifrajs/env"
|
|
10
10
|
* export const ENV = defineEnv({
|
|
11
11
|
* DATABASE_URL: env.url(),
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
* // ENV.PORT: number, ENV.NODE_ENV: "development" | "production" | "test", … all validated.
|
|
18
18
|
* ```
|
|
19
19
|
*
|
|
20
|
-
* Errors name the offending variable and the reason
|
|
20
|
+
* Errors name the offending variable and the reason - never its value (it may be a secret). BYO
|
|
21
21
|
* validators (`t`, zod, valibot) work too; only the `env.*` helpers coerce from strings, so a plain
|
|
22
|
-
* `t.number()` would see the raw string
|
|
22
|
+
* `t.number()` would see the raw string - use `env.number()` for coercion.
|
|
23
23
|
*/
|
|
24
24
|
export function defineEnv(shape, options) {
|
|
25
25
|
const source = options?.source ??
|
|
@@ -31,7 +31,7 @@ export function defineEnv(shape, options) {
|
|
|
31
31
|
const schema = shape[key];
|
|
32
32
|
const result = schema["~standard"].validate(source[key]);
|
|
33
33
|
if (result instanceof Promise) {
|
|
34
|
-
// Env validation must be synchronous (it runs once, at import)
|
|
34
|
+
// Env validation must be synchronous (it runs once, at import) - an async validator is a
|
|
35
35
|
// configuration mistake, surfaced as a problem rather than an unhandled promise.
|
|
36
36
|
problems.push(` ${key}: async validators are not supported in defineEnv`);
|
|
37
37
|
continue;
|
|
@@ -45,7 +45,7 @@ export function defineEnv(shape, options) {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
if (problems.length > 0) {
|
|
48
|
-
throw new Error(`[nifra/env] invalid environment
|
|
48
|
+
throw new Error(`[nifra/env] invalid environment - ${problems.length} problem(s):\n${problems.join("\n")}\n\nSet the variable(s) above and restart.`);
|
|
49
49
|
}
|
|
50
50
|
return Object.freeze(out);
|
|
51
51
|
}
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Coercing env validators. Every value in `process.env` is a `string | undefined`, so these turn
|
|
3
|
-
* that into the typed value you actually want
|
|
3
|
+
* that into the typed value you actually want - with defaults, optionality, and clear errors. Each
|
|
4
4
|
* is a Standard Schema, so they slot straight into {@link defineEnv} (and could be used anywhere a
|
|
5
5
|
* Standard Schema is accepted).
|
|
6
6
|
*
|
|
7
|
-
* Error messages are **value-free**
|
|
7
|
+
* Error messages are **value-free** - they say what was wrong, never echo the variable's value
|
|
8
8
|
* (it may be a secret). {@link defineEnv} prepends the variable name.
|
|
9
9
|
*/
|
|
10
10
|
import { type StandardSchemaV1 } from "./schema.js";
|
|
@@ -20,7 +20,7 @@ interface Optional {
|
|
|
20
20
|
export declare function string(opts?: Base<string> & Optional): StandardSchemaV1<string | undefined>;
|
|
21
21
|
/** A finite number, coerced from its decimal string. */
|
|
22
22
|
export declare function number(opts?: Base<number> & Optional): StandardSchemaV1<number | undefined>;
|
|
23
|
-
/** A TCP port: an integer in 1
|
|
23
|
+
/** A TCP port: an integer in 1-65535. */
|
|
24
24
|
export declare function port(opts?: Base<number>): StandardSchemaV1<number>;
|
|
25
25
|
/** A boolean: `true`/`1`/`yes`/`on` → true; `false`/`0`/`no`/`off`/empty → false (case-insensitive). */
|
|
26
26
|
export declare function boolean(opts?: Base<boolean>): StandardSchemaV1<boolean>;
|
|
@@ -28,7 +28,7 @@ export declare function boolean(opts?: Base<boolean>): StandardSchemaV1<boolean>
|
|
|
28
28
|
export declare function enumValue<const V extends readonly [string, ...string[]]>(values: V, opts?: Base<V[number]>): StandardSchemaV1<V[number]>;
|
|
29
29
|
/** A valid absolute URL (parses with the WHATWG `URL`). Returns the normalized href string. */
|
|
30
30
|
export declare function url(opts?: Base<string> & Optional): StandardSchemaV1<string | undefined>;
|
|
31
|
-
/** The coercing env validators, grouped
|
|
31
|
+
/** The coercing env validators, grouped - `env.string()`, `env.port()`, `env.enum([...])`, … */
|
|
32
32
|
export declare const env: {
|
|
33
33
|
string: typeof string;
|
|
34
34
|
number: typeof number;
|
package/dist/helpers.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Coercing env validators. Every value in `process.env` is a `string | undefined`, so these turn
|
|
3
|
-
* that into the typed value you actually want
|
|
3
|
+
* that into the typed value you actually want - with defaults, optionality, and clear errors. Each
|
|
4
4
|
* is a Standard Schema, so they slot straight into {@link defineEnv} (and could be used anywhere a
|
|
5
5
|
* Standard Schema is accepted).
|
|
6
6
|
*
|
|
7
|
-
* Error messages are **value-free**
|
|
7
|
+
* Error messages are **value-free** - they say what was wrong, never echo the variable's value
|
|
8
8
|
* (it may be a secret). {@link defineEnv} prepends the variable name.
|
|
9
9
|
*/
|
|
10
10
|
import { envSchema, issue } from "./schema.js";
|
|
@@ -38,7 +38,7 @@ export function number(opts = {}) {
|
|
|
38
38
|
return { value: n };
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
/** A TCP port: an integer in 1
|
|
41
|
+
/** A TCP port: an integer in 1-65535. */
|
|
42
42
|
export function port(opts = {}) {
|
|
43
43
|
return envSchema((raw) => {
|
|
44
44
|
if (isUnset(raw)) {
|
|
@@ -48,7 +48,7 @@ export function port(opts = {}) {
|
|
|
48
48
|
}
|
|
49
49
|
const n = Number(raw);
|
|
50
50
|
if (!Number.isInteger(n) || n < 1 || n > 65535) {
|
|
51
|
-
return issue("must be an integer port in 1
|
|
51
|
+
return issue("must be an integer port in 1-65535");
|
|
52
52
|
}
|
|
53
53
|
return { value: n };
|
|
54
54
|
});
|
|
@@ -103,7 +103,7 @@ export function url(opts = {}) {
|
|
|
103
103
|
}
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
|
-
/** The coercing env validators, grouped
|
|
106
|
+
/** The coercing env validators, grouped - `env.string()`, `env.port()`, `env.enum([...])`, … */
|
|
107
107
|
export const env = {
|
|
108
108
|
string,
|
|
109
109
|
number,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @nifrajs/env
|
|
2
|
+
* @nifrajs/env - typed, validated environment variables. Define a schema once at startup; get a
|
|
3
3
|
* frozen typed object, or a loud boot-time failure listing every problem. Coercing helpers
|
|
4
4
|
* (`env.number`/`port`/`boolean`/`url`/`enum`) turn `string | undefined` into the value you want;
|
|
5
5
|
* any Standard Schema (`t`, zod, valibot) is also accepted. Dependency-free, edge-safe.
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @nifrajs/env
|
|
2
|
+
* @nifrajs/env - typed, validated environment variables. Define a schema once at startup; get a
|
|
3
3
|
* frozen typed object, or a loud boot-time failure listing every problem. Coercing helpers
|
|
4
4
|
* (`env.number`/`port`/`boolean`/`url`/`enum`) turn `string | undefined` into the value you want;
|
|
5
5
|
* any Standard Schema (`t`, zod, valibot) is also accepted. Dependency-free, edge-safe.
|
package/dist/schema.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export interface StandardSchemaV1<Output = unknown> {
|
|
|
26
26
|
export type InferOutput<S extends StandardSchemaV1> = NonNullable<S["~standard"]["types"]>["output"];
|
|
27
27
|
/** Build an env validator: a Standard Schema whose `validate` coerces from `string | undefined`. */
|
|
28
28
|
export declare function envSchema<Output>(validate: (raw: string | undefined) => StandardResult<Output>): StandardSchemaV1<Output>;
|
|
29
|
-
/** A single issue. Messages NEVER include the variable's value
|
|
29
|
+
/** A single issue. Messages NEVER include the variable's value - it may be a secret. */
|
|
30
30
|
export declare const issue: (message: string) => {
|
|
31
31
|
readonly issues: ReadonlyArray<StandardIssue>;
|
|
32
32
|
};
|
package/dist/schema.js
CHANGED
|
@@ -15,7 +15,7 @@ export function envSchema(validate) {
|
|
|
15
15
|
},
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
/** A single issue. Messages NEVER include the variable's value
|
|
18
|
+
/** A single issue. Messages NEVER include the variable's value - it may be a secret. */
|
|
19
19
|
export const issue = (message) => ({
|
|
20
20
|
issues: [{ message }],
|
|
21
21
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/env",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Typed, validated environment variables for nifra
|
|
3
|
+
"version": "2.4.0",
|
|
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",
|
|
7
7
|
"typescript",
|
package/src/define.ts
CHANGED
|
@@ -3,25 +3,25 @@ import type { InferOutput, StandardSchemaV1 } from "./schema.ts"
|
|
|
3
3
|
/** A schema per variable name. */
|
|
4
4
|
export type EnvShape = Record<string, StandardSchemaV1>
|
|
5
5
|
|
|
6
|
-
/** The frozen, validated result
|
|
6
|
+
/** The frozen, validated result - each key typed by its schema's output. */
|
|
7
7
|
export type EnvResult<S extends EnvShape> = { readonly [K in keyof S]: InferOutput<S[K]> }
|
|
8
8
|
|
|
9
9
|
export interface DefineEnvOptions {
|
|
10
10
|
/**
|
|
11
11
|
* Where to read variables from. Defaults to `process.env` (Bun/Node). On Cloudflare Workers there
|
|
12
|
-
* is no `process.env`
|
|
12
|
+
* is no `process.env` - pass the request's `env` bindings: `defineEnv(shape, { source: env })`.
|
|
13
13
|
*/
|
|
14
14
|
readonly source?: Record<string, string | undefined>
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Validate the environment against a schema and return a **frozen, typed** object
|
|
18
|
+
* Validate the environment against a schema and return a **frozen, typed** object - or throw at
|
|
19
19
|
* startup listing **every** problem at once (not just the first), so a misconfigured deploy fails
|
|
20
20
|
* loud and immediately instead of erroring on the first request that touches a bad var. This is the
|
|
21
21
|
* boot-time half of nifra's "validate at every boundary" rule, for config.
|
|
22
22
|
*
|
|
23
23
|
* ```ts
|
|
24
|
-
* // env.ts
|
|
24
|
+
* // env.ts - imported once at startup
|
|
25
25
|
* import { defineEnv, env } from "@nifrajs/env"
|
|
26
26
|
* export const ENV = defineEnv({
|
|
27
27
|
* DATABASE_URL: env.url(),
|
|
@@ -33,9 +33,9 @@ export interface DefineEnvOptions {
|
|
|
33
33
|
* // ENV.PORT: number, ENV.NODE_ENV: "development" | "production" | "test", … all validated.
|
|
34
34
|
* ```
|
|
35
35
|
*
|
|
36
|
-
* Errors name the offending variable and the reason
|
|
36
|
+
* Errors name the offending variable and the reason - never its value (it may be a secret). BYO
|
|
37
37
|
* validators (`t`, zod, valibot) work too; only the `env.*` helpers coerce from strings, so a plain
|
|
38
|
-
* `t.number()` would see the raw string
|
|
38
|
+
* `t.number()` would see the raw string - use `env.number()` for coercion.
|
|
39
39
|
*/
|
|
40
40
|
export function defineEnv<S extends EnvShape>(shape: S, options?: DefineEnvOptions): EnvResult<S> {
|
|
41
41
|
const source =
|
|
@@ -49,7 +49,7 @@ export function defineEnv<S extends EnvShape>(shape: S, options?: DefineEnvOptio
|
|
|
49
49
|
const schema = shape[key] as StandardSchemaV1
|
|
50
50
|
const result = schema["~standard"].validate(source[key])
|
|
51
51
|
if (result instanceof Promise) {
|
|
52
|
-
// Env validation must be synchronous (it runs once, at import)
|
|
52
|
+
// Env validation must be synchronous (it runs once, at import) - an async validator is a
|
|
53
53
|
// configuration mistake, surfaced as a problem rather than an unhandled promise.
|
|
54
54
|
problems.push(` ${key}: async validators are not supported in defineEnv`)
|
|
55
55
|
continue
|
|
@@ -63,7 +63,7 @@ export function defineEnv<S extends EnvShape>(shape: S, options?: DefineEnvOptio
|
|
|
63
63
|
|
|
64
64
|
if (problems.length > 0) {
|
|
65
65
|
throw new Error(
|
|
66
|
-
`[nifra/env] invalid environment
|
|
66
|
+
`[nifra/env] invalid environment - ${problems.length} problem(s):\n${problems.join("\n")}\n\nSet the variable(s) above and restart.`,
|
|
67
67
|
)
|
|
68
68
|
}
|
|
69
69
|
return Object.freeze(out) as EnvResult<S>
|
package/src/helpers.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Coercing env validators. Every value in `process.env` is a `string | undefined`, so these turn
|
|
3
|
-
* that into the typed value you actually want
|
|
3
|
+
* that into the typed value you actually want - with defaults, optionality, and clear errors. Each
|
|
4
4
|
* is a Standard Schema, so they slot straight into {@link defineEnv} (and could be used anywhere a
|
|
5
5
|
* Standard Schema is accepted).
|
|
6
6
|
*
|
|
7
|
-
* Error messages are **value-free**
|
|
7
|
+
* Error messages are **value-free** - they say what was wrong, never echo the variable's value
|
|
8
8
|
* (it may be a secret). {@link defineEnv} prepends the variable name.
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -47,7 +47,7 @@ export function number(opts: Base<number> & Optional = {}): StandardSchemaV1<num
|
|
|
47
47
|
})
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
/** A TCP port: an integer in 1
|
|
50
|
+
/** A TCP port: an integer in 1-65535. */
|
|
51
51
|
export function port(opts: Base<number> = {}): StandardSchemaV1<number> {
|
|
52
52
|
return envSchema((raw) => {
|
|
53
53
|
if (isUnset(raw)) {
|
|
@@ -56,7 +56,7 @@ export function port(opts: Base<number> = {}): StandardSchemaV1<number> {
|
|
|
56
56
|
}
|
|
57
57
|
const n = Number(raw)
|
|
58
58
|
if (!Number.isInteger(n) || n < 1 || n > 65535) {
|
|
59
|
-
return issue("must be an integer port in 1
|
|
59
|
+
return issue("must be an integer port in 1-65535")
|
|
60
60
|
}
|
|
61
61
|
return { value: n }
|
|
62
62
|
}) as StandardSchemaV1<number>
|
|
@@ -111,7 +111,7 @@ export function url(opts: Base<string> & Optional = {}): StandardSchemaV1<string
|
|
|
111
111
|
})
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
/** The coercing env validators, grouped
|
|
114
|
+
/** The coercing env validators, grouped - `env.string()`, `env.port()`, `env.enum([...])`, … */
|
|
115
115
|
export const env = {
|
|
116
116
|
string,
|
|
117
117
|
number,
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @nifrajs/env
|
|
2
|
+
* @nifrajs/env - typed, validated environment variables. Define a schema once at startup; get a
|
|
3
3
|
* frozen typed object, or a loud boot-time failure listing every problem. Coercing helpers
|
|
4
4
|
* (`env.number`/`port`/`boolean`/`url`/`enum`) turn `string | undefined` into the value you want;
|
|
5
5
|
* any Standard Schema (`t`, zod, valibot) is also accepted. Dependency-free, edge-safe.
|
package/src/schema.ts
CHANGED
|
@@ -39,7 +39,7 @@ export function envSchema<Output>(
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
/** A single issue. Messages NEVER include the variable's value
|
|
42
|
+
/** A single issue. Messages NEVER include the variable's value - it may be a secret. */
|
|
43
43
|
export const issue = (message: string): { readonly issues: ReadonlyArray<StandardIssue> } => ({
|
|
44
44
|
issues: [{ message }],
|
|
45
45
|
})
|