@g14o/env-core 0.1.2 → 0.2.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 +52 -1
- package/dist/index.d.mts +12 -5
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,6 +88,9 @@ export const env = createEnv({
|
|
|
88
88
|
When your framework only inlines env vars you reference explicitly, use `runtimeEnvStrict`:
|
|
89
89
|
|
|
90
90
|
```ts
|
|
91
|
+
import { createEnv } from "@g14o/env-core";
|
|
92
|
+
import * as z from "zod";
|
|
93
|
+
|
|
91
94
|
export const env = createEnv({
|
|
92
95
|
server: { DATABASE_URL: z.url() },
|
|
93
96
|
clientPrefix: "NEXT_PUBLIC_",
|
|
@@ -99,6 +102,52 @@ export const env = createEnv({
|
|
|
99
102
|
});
|
|
100
103
|
```
|
|
101
104
|
|
|
105
|
+
### Overriding default error handler
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { createEnv } from "@g14o/env-core";
|
|
109
|
+
|
|
110
|
+
export const env = createEnv({
|
|
111
|
+
// ...
|
|
112
|
+
// Called when schema validation fails.
|
|
113
|
+
onValidationError: (issues) => {
|
|
114
|
+
console.error("Invalid environment variables:", issues);
|
|
115
|
+
throw new Error("Invalid environment variables");
|
|
116
|
+
},
|
|
117
|
+
// Called when a server variable is accessed on the client.
|
|
118
|
+
onInvalidAccess: (variable) => {
|
|
119
|
+
console.error("Invalid access to server variable:", variable);
|
|
120
|
+
throw new Error("Invalid access to server variable");
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Tell when we're in a server context
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { createEnv } from "@g14o/env-core";
|
|
129
|
+
|
|
130
|
+
export const env = createEnv({
|
|
131
|
+
// ...
|
|
132
|
+
// Tell when we're in a server context
|
|
133
|
+
isServer: typeof window === "undefined", // or straight up `true` or `false`
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Skip validation
|
|
138
|
+
|
|
139
|
+
`skipValidation` bypasses both schema validation and the client-access proxy. Only use it when exposing the picked keys acceptable for the current runtime.
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import { createEnv } from "@g14o/env-core";
|
|
143
|
+
|
|
144
|
+
export const env = createEnv({
|
|
145
|
+
// ...
|
|
146
|
+
// Tell the library to skip validation and return picked runtime values only
|
|
147
|
+
skipValidation: true,
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
102
151
|
## Options
|
|
103
152
|
|
|
104
153
|
| Option | Description |
|
|
@@ -110,7 +159,9 @@ export const env = createEnv({
|
|
|
110
159
|
| `runtimeEnvStrict` | Explicit per-key mapping; mutually exclusive with `runtimeEnv` |
|
|
111
160
|
| `emptyStringAsUndefined` | Treat `""` as `undefined` before validation |
|
|
112
161
|
| `isServer` | Override server detection (default: `typeof window === "undefined"`) |
|
|
113
|
-
| `
|
|
162
|
+
| `onValidationError` | Hook when schema validation fails; may throw custom error, otherwise default `InvalidEnvironmentVariablesError` is thrown |
|
|
163
|
+
| `onInvalidAccess` | Hook when a server key is accessed on the client; may throw custom error, otherwise default server-access error is thrown |
|
|
164
|
+
| `skipValidation` | Bypasses both schema validation and the client-access proxy. Only use it when exposing the picked keys acceptable for the current runtime (default: `false`) |
|
|
114
165
|
|
|
115
166
|
## Security
|
|
116
167
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/client-guard.d.ts
|
|
2
|
-
|
|
2
|
+
/** Called when a server key is read on the client. May throw a custom error; otherwise the default is thrown. */
|
|
3
|
+
type OnInvalidAccessHandler = (variable: string) => never;
|
|
3
4
|
//#endregion
|
|
4
5
|
//#region src/standard-schema.d.ts
|
|
5
6
|
/** @see https://standardschema.dev */
|
|
@@ -33,6 +34,10 @@ declare namespace StandardSchemaV1 {
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
//#endregion
|
|
37
|
+
//#region src/validate.d.ts
|
|
38
|
+
/** Called when schema validation fails. May throw a custom error; otherwise the default is thrown. */
|
|
39
|
+
type OnValidationErrorHandler = (issues: readonly StandardSchemaV1.Issue[]) => never;
|
|
40
|
+
//#endregion
|
|
36
41
|
//#region src/types.d.ts
|
|
37
42
|
/**
|
|
38
43
|
* Record mapping environment variable names to
|
|
@@ -159,8 +164,9 @@ type CreateEnvOptions<TServer extends SchemaShape | undefined = undefined, TClie
|
|
|
159
164
|
client?: TClient; /** Prefix every `client` key must use (enforced at compile time and runtime). */
|
|
160
165
|
clientPrefix?: TPrefix; /** Treat `""` as `undefined` before validation. Default `false`. */
|
|
161
166
|
emptyStringAsUndefined?: boolean; /** Override server detection. Default: no `window` on `globalThis`. */
|
|
162
|
-
isServer?: boolean; /** Called
|
|
163
|
-
onInvalidAccess?: OnInvalidAccessHandler; /**
|
|
167
|
+
isServer?: boolean; /** Called when a non-client key is read on the client. May throw a custom error; otherwise the default is thrown. */
|
|
168
|
+
onInvalidAccess?: OnInvalidAccessHandler; /** Called when schema validation fails. May throw a custom error; otherwise the default is thrown. */
|
|
169
|
+
onValidationError?: OnValidationErrorHandler; /** @internal Skip schema validation and return picked runtime values only. */
|
|
164
170
|
skipValidation?: boolean;
|
|
165
171
|
} & RuntimeEnvSource<TServer, TClient>;
|
|
166
172
|
/**
|
|
@@ -195,7 +201,8 @@ type CreateEnvOutput<TServer extends SchemaShape | undefined, TClient extends Sc
|
|
|
195
201
|
* @param options.runtimeEnvStrict - Explicit per-key mapping; mutually exclusive with `runtimeEnv`.
|
|
196
202
|
* @param options.emptyStringAsUndefined - Treat `""` as `undefined` before validation. Default `false`.
|
|
197
203
|
* @param options.isServer - Override server detection. Default: no `window` on `globalThis`.
|
|
198
|
-
* @param options.onInvalidAccess - Called
|
|
204
|
+
* @param options.onInvalidAccess - Called when a non-client key is read on the client. May throw a custom error; otherwise the default is thrown.
|
|
205
|
+
* @param options.onValidationError - Called when schema validation fails. May throw a custom error; otherwise the default is thrown.
|
|
199
206
|
* @param options.skipValidation - Skip schema validation and return picked runtime values only. Default `false`.
|
|
200
207
|
* @returns Readonly, frozen env object typed from inferred schema outputs; client reads are guarded by `Proxy`.
|
|
201
208
|
*
|
|
@@ -227,4 +234,4 @@ declare class InvalidEnvironmentVariablesError extends Error {
|
|
|
227
234
|
constructor(issues: readonly string[], scope: string);
|
|
228
235
|
}
|
|
229
236
|
//#endregion
|
|
230
|
-
export { type AssertValidClientPrefix, type CreateEnvOptions, type CreateEnvOutput, type InferSchemaOutput, type InferShapeOutput, type InvalidClientKeys, InvalidEnvironmentVariablesError, type OnInvalidAccessHandler, type PrefixedClientShape, type RuntimeEnvInput, type RuntimeEnvValue, type SchemaShape, type Simplify, type StandardSchemaV1, type StrictRuntimeEnv, createEnv };
|
|
237
|
+
export { type AssertValidClientPrefix, type CreateEnvOptions, type CreateEnvOutput, type InferSchemaOutput, type InferShapeOutput, type InvalidClientKeys, InvalidEnvironmentVariablesError, type OnInvalidAccessHandler, type OnValidationErrorHandler, type PrefixedClientShape, type RuntimeEnvInput, type RuntimeEnvValue, type SchemaShape, type Simplify, type StandardSchemaV1, type StrictRuntimeEnv, createEnv };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
var e=class extends Error{issues;constructor(e,t){super(`Invalid environment variables (${t}):\n${e.map(e=>` - ${e}`).join(`
|
|
2
|
-
`)}`),this.name=`InvalidEnvironmentVariablesError`,this.issues=e}};function t(e){return`${e.path&&e.path.length>0?`${e.path.map(e=>n(e)).join(`.`)}: `:``}${e.message}`}function n(e){return typeof e==`object`&&e&&`key`in e?String(e.key):String(e)}function r(e){return Error(`Attempted to access server environment variable(s) on the client: ${e}`)}const i=new Set([`__esModule`,`$$typeof`]);function a(e,t){let{isServer:n,clientKeys:a,onInvalidAccess:o}=t;return new Proxy(e,{get(e,t,
|
|
2
|
+
`)}`),this.name=`InvalidEnvironmentVariablesError`,this.issues=e}};function t(e){return`${e.path&&e.path.length>0?`${e.path.map(e=>n(e)).join(`.`)}: `:``}${e.message}`}function n(e){return typeof e==`object`&&e&&`key`in e?String(e.key):String(e)}function r(e){return Error(`Attempted to access server environment variable(s) on the client: ${e}`)}const i=new Set([`__esModule`,`$$typeof`]);function a(e,t){let{isServer:n,clientKeys:a,onInvalidAccess:o}=t,s=e=>{throw o&&o(e),r(e)};return new Proxy(e,{get(e,t,r){return typeof t==`string`?n||i.has(t)||a.has(t)?Reflect.get(e,t,r):s(t):Reflect.get(e,t,r)}})}function o(e,t,n){let r={};for(let i of e){let e=Object.hasOwn(t,i)?t[i]:void 0;n&&e===``&&(e=void 0),r[i]=e}return r}function s(e,t){let n=[];for(let r of e)Object.hasOwn(t,r)||n.push(r);if(n.length>0)throw Error(`runtimeEnvStrict is missing required keys: ${n.join(`, `)}`)}function c(e,t){if(e!==void 0){for(let n of t)if(!n.startsWith(e))throw Error(`Environment variable "${n}" must start with "${e}" to be exposed on the client`)}}function l(e,t){for(let n of e)if(t.includes(n))throw Error(`Environment variable "${n}" cannot be defined in both server and client`)}function u(e,t){return{message:t.message,path:[{key:e},...t.path??[]]}}function d(t,n,r,i){let a=Object.keys(t);if(a.length===0)return{};let o={},s=[],c=[],l=[];for(let e of a){let r=t[e];if(!r)continue;let i=r[`~standard`].validate(n[e]);if(i instanceof Promise){l.push({key:e,promise:i});continue}f(e,i,o,s,c)}if(l.length>0)throw Error(`Async Standard Schema validation is not supported in createEnv (${r}). Use synchronous validators.`);return c.length>0?(t=>{throw i&&i(t),console.error(`❌ Invalid environment variables:`,t),new e(s,r)})(c):o}function f(e,n,r,i,a){if(n.issues){for(let r of n.issues){let n=u(e,r);a.push(n),i.push(`${e}: ${t(r)}`)}return}r[e]=n.value}function p(e){return e===void 0?globalThis.window===void 0:e}function m(e){if(`runtimeEnvStrict`in e&&e.runtimeEnvStrict!==void 0)return e.runtimeEnvStrict;if(`runtimeEnv`in e&&e.runtimeEnv!==void 0)return e.runtimeEnv;throw Error(`createEnv requires either runtimeEnv or runtimeEnvStrict`)}function h(e,t){return{server:e??{},client:t??{}}}function g(e){let{server:t,client:n}=h(e.server,e.client),r=Object.keys(t),i=Object.keys(n),a=[...r,...i];l(r,i),c(e.clientPrefix,i);let o=m(e);return`runtimeEnvStrict`in e&&e.runtimeEnvStrict!==void 0&&s(a,o),{server:t,client:n,clientPrefix:e.clientPrefix,emptyStringAsUndefined:e.emptyStringAsUndefined??!1,isServer:p(e.isServer),onInvalidAccess:e.onInvalidAccess,onValidationError:e.onValidationError,skipValidation:e.skipValidation??!1,runtime:o}}function _(e){let t=g(e),n=Object.keys(t.server),r=Object.keys(t.client),i=[...n,...r],s=new Set(r),c=o(i,t.runtime,t.emptyStringAsUndefined);if(t.skipValidation)return Object.freeze({...c});let l=o(r,t.runtime,t.emptyStringAsUndefined),u=d(t.client,l,`client`,t.onValidationError),f={};if(t.isServer&&n.length>0){let e=o(n,t.runtime,t.emptyStringAsUndefined);f=d(t.server,e,`server`,t.onValidationError)}return a(Object.freeze(t.isServer?{...f,...u}:{...u}),{isServer:t.isServer,clientKeys:s,onInvalidAccess:t.onInvalidAccess})}export{e as InvalidEnvironmentVariablesError,_ as createEnv};
|