@zh-moody/safe-env 0.3.8 → 0.4.1

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.en.md CHANGED
@@ -6,9 +6,9 @@
6
6
 
7
7
  [简体中文](./README.md) | English
8
8
 
9
- **Say goodbye to `undefined`! Intercept all configuration risks at the first line of your app.**
9
+ **Say goodbye to `undefined`! Intercept all configuration hazards on the first line of your app.**
10
10
 
11
- Whether you are writing Vue, React, or Node.js, environment variables are often a source of production incidents. `safe-env` ensures your app always runs on the expected configuration through strong-typed Schema validation and runtime protection.
11
+ Whether you're building with Vue, React, or Node.js, environment variables are often the root of production incidents. `safe-env` ensures your application always runs on top of expected configurations through strong schema validation and runtime protection.
12
12
 
13
13
  ---
14
14
 
@@ -16,14 +16,14 @@ Whether you are writing Vue, React, or Node.js, environment variables are often
16
16
 
17
17
  ---
18
18
 
19
- ### 🚀 Core Features
19
+ ### 🚀 Key Features
20
20
 
21
- - **Build-time Validation**: Provides a Vite plugin to intercept invalid configurations during development or build.
22
- - **Sensitive Data Masking**: Supports `.secret()` to ensure keys and passwords are masked as `********` in logs or error tables.
23
- - **Runtime Immutability**: Parsed config objects are deep-frozen with `Object.freeze` by default, preventing any illegal runtime modification.
24
- - **Monorepo Ready**: Supports `cwd` parameter to explicitly specify the `.env` directory, ideal for complex project architectures.
25
- - **IDE Enhancement**: Supports `.description()` to view variable usage and documentation directly via hover in your code.
26
- - **Rigorous Type Parsing**: Built-in `s.array()`, `s.boolean()` with enhanced conversion, and `.transform()` for chainable piping.
21
+ - **Build-time Pre-validation**: Vite plugin intercepts invalid configurations during dev startup or build.
22
+ - **Sensitive Data Masking**: Supports `.secret()` to ensure keys/tokens are masked in logs or error reports.
23
+ - **Runtime Lazy Protection**: **HPC Ready**. Powered by **Lazy Proxy**, achieving $O(1)$ startup latency and on-demand read-only protection.
24
+ - **Monorepo Ready**: Explicitly specify `.env` search directories via `cwd`, fitting complex architectures.
25
+ - **IDE Enhancement**: `.description()` allows you to view variable purposes/documentation via hover.
26
+ - **Robust Parsing**: Built-in `s.array()`, `s.boolean()` with intelligent conversion and `.transform()` pipe processing.
27
27
 
28
28
  ---
29
29
 
@@ -37,9 +37,15 @@ npm install @zh-moody/safe-env
37
37
 
38
38
  ### 🚀 Quick Start
39
39
 
40
- #### 🔹 [Vite / React / Vue]
40
+ Ensure you have a **`.env`** file in your project root before starting:
41
41
 
42
- For frontend projects, use the Vite plugin for **build-time validation**.
42
+ ```bash
43
+ # .env example
44
+ VITE_API_URL=https://api.example.com
45
+ VITE_PORT=8080
46
+ ```
47
+
48
+ #### 🔹 [Vite / React / Vue] Usage
43
49
 
44
50
  **1. Configure Vite Plugin (`vite.config.ts`):**
45
51
 
@@ -52,14 +58,14 @@ export default {
52
58
  };
53
59
  ```
54
60
 
55
- **2. Define and Export Config (`src/env.ts`):**
61
+ **2. Define and Export Schema (`src/env.ts`):**
56
62
 
57
63
  ```typescript
58
64
  import { safeEnv, s } from "@zh-moody/safe-env";
59
65
 
60
66
  export const schema = {
61
- VITE_API_URL: s.string().url().description("Backend API Base URL"),
62
- VITE_PORT: s.number(3000).description("Development Server Port"),
67
+ VITE_API_URL: s.string().url().description("Backend API endpoint"),
68
+ VITE_PORT: s.number(3000).description("Server port"),
63
69
  };
64
70
 
65
71
  export const env = safeEnv(schema, {
@@ -67,33 +73,22 @@ export const env = safeEnv(schema, {
67
73
  });
68
74
  ```
69
75
 
70
- > **💡 Best Practice: Prevent Vite Type Pollution**
71
- > To completely disable the insecure original `import.meta.env.XXX` hints, modify `src/vite-env.d.ts`:
72
- >
73
- > ```typescript
74
- > interface ImportMetaEnv {
75
- > [key: string]: never;
76
- > }
77
- > ```
78
-
79
76
  ---
80
77
 
81
- #### 🔸 [Node.js / Server-side]
78
+ #### 🔸 [Node.js / Server-side] Usage
82
79
 
83
- In Node.js, the library automatically looks for and parses `.env` files on disk.
84
-
85
- **1. Define Config (`src/config.ts`):**
80
+ **1. Define Configuration (`src/config.ts`):**
86
81
 
87
82
  ```typescript
88
83
  import { safeEnv, s } from "@zh-moody/safe-env";
89
84
 
90
85
  const config = safeEnv(
91
86
  {
92
- DB_PASSWORD: s.string().secret().description("Database Password"),
87
+ DB_PASSWORD: s.string().secret().description("Database password"),
93
88
  DB_PORT: s.number(5432).min(1).max(65535),
94
89
  },
95
90
  {
96
- // Explicitly specify the .env directory for Monorepo or specific deployments
91
+ // Explicitly specify .env root in Monorepo or deployment environments
97
92
  // cwd: '/path/to/project-root'
98
93
  },
99
94
  );
@@ -105,59 +100,47 @@ export default config;
105
100
 
106
101
  ### 🛠️ API Reference
107
102
 
108
- #### 1. Define Fields (`s.xxx`)
103
+ #### 1. Global Options (`safeEnv`)
104
+
105
+ `safeEnv(schema, options?)` accepts an optional object to control the parsing engine:
106
+
107
+ - **`useCache (boolean)`**: Enable global memoization (default `true`). Significantly improves performance for high-frequency calls.
108
+ - **`refreshCache (boolean)`**: Force flush and re-read disk/process variables (default `false`). Essential for HMR or switching envs in automated tests.
109
+ - **`cwd (string)`**: Specify the search root for `.env` files (Node.js).
110
+ - **`source (Record<string, any>)`**: Manually provide the data source (e.g., `import.meta.env`), skipping automatic file retrieval.
111
+ - **`prefix (string)`**: Filter prefix for env variables (default `VITE_`).
112
+
113
+ #### 2. Field Definitions (`s.xxx`)
109
114
 
110
- - `s.string(default?)`: String field. Required if no default value.
111
- - `s.number(default?)`: Automatically converted to `number` and validated.
112
- - `s.boolean(default?)`: Supports `"true"`, `"1"`, `"yes"`, `"on"` as `true`.
113
- - `s.array(default?, separator?)`: Splits string by separator (default `,`) into an array.
114
- - `s.enum(options, default?)`: Value must be one of the provided options.
115
+ - **`s.string(default?)`**:
116
+ - **Logic**: If no default is provided, it's marked as **Required**.
117
+ - **`s.number(default?)`**:
118
+ - **Logic**: Executes `Number(v)`. Aborts with an error if result is `NaN` (e.g., `VITE_PORT=abc`).
119
+ - **`s.boolean(default?)`**: Intelligent Boolean parsing.
120
+ - **Logic**:
121
+ - **`true`**: `true`, `"true"`, `"1"`, `"yes"`, `"on"`.
122
+ - **`false`**: `false`, `"false"`, `"0"`, `"no"`, `"off"`, or empty strings.
123
+ - **`s.array(default?, separator?)`**:
124
+ - **Logic**: Default separator is `,`. Supports custom ones like `s.array([], '|')`.
125
+ - **`s.enum(options, default?)`**:
126
+ - **Logic**: Input must be one of the `options`. Perfect for mode locking (`dev`, `prod`, `test`).
115
127
 
116
- #### 2. Validation & Enhancement (Chainable)
128
+ #### 3. Enhancements & Validation (Chaining)
117
129
 
118
- - **`.secret()`**: Masks the value as `********` in error reports.
119
- ```typescript
120
- PASSWORD: s.string().secret();
121
- ```
122
- - **`.url()` / `.email()`**: Built-in format validation.
123
- ```typescript
124
- API_URL: s.string().url();
125
- ```
130
+ - **`.secret()`**: Mask sensitive data in error reports (`********`).
131
+ - **`.url()` / `.email()`**: Common format validation.
126
132
  - **`.regex(pattern, msg?)`**: Custom regex validation.
127
- ```typescript
128
- VERSION: s.string().regex(/^v\d+\.\d+\.\d+$/, "Invalid format");
129
- ```
130
- - **`.description(text)`**: Adds a description for IDE hover hints.
131
- ```typescript
132
- PORT: s.number(3000).description("Server Port");
133
- ```
134
- - **`.transform(fn)`**: Custom data transformation, supports multi-level piping.
135
- ```typescript
136
- NAME: s.string()
137
- .transform((v) => v.trim())
138
- .transform((v) => v.toUpperCase());
139
- ```
140
- - **`.from(key)`**: Maps environment variable name (Alias).
141
- ```typescript
142
- port: s.number().from("VITE_SERVER_PORT");
143
- ```
144
- - **`.min(n)` / `.max(n)`**: Constraints for number values.
145
- ```typescript
146
- PORT: s.number().min(1024).max(65535);
147
- ```
148
- - **`.validate(fn, msg?)`**: Fully custom validation logic.
149
- ```typescript
150
- INTERNAL_URL: s.string().validate(
151
- (v) => v.endsWith(".internal.com"),
152
- "Must be internal",
153
- );
154
- ```
133
+ - **`.description(text)`**: Hover hints for IDEs.
134
+ - **`.transform(fn)`**: Custom data transformation (Multi-level pipe).
135
+ - **`.from(key)`**: Alias mapping (Environment key mapping).
136
+ - **`.min(n)` / `.max(n)`**: Number range constraints.
137
+ - **`.validate(fn, msg?)`**: Custom logic validation.
155
138
 
156
139
  ---
157
140
 
158
141
  ### 🎨 Error Reporting
159
142
 
160
- When validation fails, `safe-env` outputs a structured, adaptive table in the console showing: **Key / Error Reason / Current Value (Masked)**.
143
+ When validation fails, `safe-env` outputs an adaptive structured table showing: **Key / Error / Current Value (Masked)**.
161
144
 
162
145
  ---
163
146
 
package/README.md CHANGED
@@ -37,6 +37,14 @@ npm install @zh-moody/safe-env
37
37
 
38
38
  ### 🚀 快速上手
39
39
 
40
+ 在开始之前,请确保你的项目根目录下已有相应的 **`.env`** 配置文件:
41
+
42
+ ```bash
43
+ # .env 示例
44
+ VITE_API_URL=https://api.example.com
45
+ VITE_PORT=8080
46
+ ```
47
+
40
48
  #### 🔹 [Vite / React / Vue] 使用
41
49
 
42
50
  在前端,建议配合 Vite 插件实现**构建时校验**。
@@ -105,15 +113,33 @@ export default config;
105
113
 
106
114
  ### 🛠️ API 详解
107
115
 
108
- #### 1. 定义字段 (`s.xxx`)
109
-
110
- - `s.string(default?)`: 字符串。若无默认值则必填。
111
- - `s.number(default?)`: 数字。自动转换为 `number` 类型并校验合法性。
112
- - `s.boolean(default?)`: 布尔型。支持将 `"true"`, `"1"`, `"yes"`, `"on"` 解析为 `true`。
113
- - `s.array(default?, separator?)`: 数组型。支持将字符串按分隔符(默认 `,`)拆分为数组。
114
- - `s.enum(options, default?)`: 枚举。值必须在预设数组中。
115
-
116
- #### 2. 校验与增强 (链式调用)
116
+ #### 1. 全局配置与选项 (`safeEnv`)
117
+
118
+ `safeEnv(schema, options?)` 接收一个可选的配置对象,用于深度控制解析行为:
119
+
120
+ - **`useCache (boolean)`**: 是否启用全局缓存(默认 `true`)。开启后,后续调用将优先从内存获取已解析的配置,极大提升高频调用的性能。
121
+ - **`refreshCache (boolean)`**: 强制刷新并重新读取磁盘/进程变量(默认 `false`)。常用于开发环境下的热更新或自动化测试中切换不同的环境配置。
122
+ - **`cwd (string)`**: 显式指定 `.env` 文件的检索根目录(Node.js 环境)。
123
+ - **`source (Record<string, any>)`**: 手动指定数据源(如 `import.meta.env` 或 `process.env`),跳过自动文件检索。
124
+ - **`prefix (string)`**: 过滤环境变量的前缀(默认 `VITE_`)。
125
+
126
+ #### 2. 定义字段 (`s.xxx`)
127
+
128
+ - **`s.string(default?)`**: 字符串解析。
129
+ - **逻辑**: 如果不提供默认值,该字段将被标记为 **必填 (Required)**,若 `.env` 中缺失会触发报错。
130
+ - **`s.number(default?)`**: 数字解析。
131
+ - **逻辑**: 自动执行 `Number(v)`。若转换结果为 `NaN`(如 `VITE_PORT=abc`),解析会立即中止并报错。
132
+ - **`s.boolean(default?)`**: 增强布尔解析。
133
+ - **逻辑**: 支持多种真假语义的自动转换:
134
+ - **`true`**: `true`, `"true"`, `"1"`, `"yes"`, `"on"`。
135
+ - **`false`**: `false`, `"false"`, `"0"`, `"no"`, `"off"`, 以及空字符串。
136
+ - **`s.array(default?, separator?)`**: 数组解析。
137
+ - **逻辑**: 默认使用 `,` 作为分隔符。支持自定义,如 `s.array([], '|')`。
138
+ - **示例**: `VITE_MODS=auth,cache` ➡️ `['auth', 'cache']`。
139
+ - **`s.enum(options, default?)`**: 枚举约束。
140
+ - **逻辑**: 强制输入值必须在 `options` 数组中,否则报错。非常适用于多环境(`dev`, `prod`, `test`)的模式锁定。
141
+
142
+ #### 3. 校验与增强 (链式调用)
117
143
 
118
144
  每个字段都可以通过链式调用进行深度定制:
119
145
 
@@ -0,0 +1 @@
1
+ import u from"fs";import a from"path";function m(r){let n={},i=r.split(/\r?\n/);for(let d of i){let e=d.trim();if(!e||e.startsWith("#"))continue;let o=e.indexOf("=");if(o===-1)continue;let s=e.slice(0,o).trim(),t=e.slice(o+1).trim();if(!t){n[s]="";continue}let c=t[0];if(c==='"'||c==="'"){let l=t.indexOf(c,1);if(l!==-1){n[s]=t.slice(1,l);continue}}let f=t.indexOf("#");f!==-1&&(t=t.slice(0,f).trim()),n[s]=t}return n}function h(r=".env",n){try{let i=a.resolve(n||process.cwd(),r);if(u.existsSync(i))return m(u.readFileSync(i,"utf-8"))}catch{}return{}}export{m as a,h as b};
@@ -0,0 +1,9 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var F="development",P= exports.b ="serve",j= exports.c ="build",V= exports.d ="VITE_DEV_SERVER",R= exports.e ="VITE_";var k=typeof window<"u"&&typeof window.document<"u";function b(t,i=!0){if(k)return`SafeEnv Validation Failed: ${t.map(s=>`${s.key} (${s.error})`).join(", ")}`;let f={r:"\x1B[31m",g:"\x1B[32m",y:"\x1B[33m",b:"\x1B[1m",res:"\x1B[0m",d:"\x1B[2m",cy:"\x1B[36m"},r=(s,p)=>{let n=String(s),v=()=>n.length+(n.match(/[^\x00-\xff]/g)||[]).length;for(;v()>p;)n=n.slice(0,-1);return n+" ".repeat(p-v())},a=Math.max(80,(typeof process<"u"?process.stdout.columns:80)||80)-10,y=Math.floor(a*.3),E=Math.floor(a*.5),e=i?f:{r:"",g:"",y:"",b:"",res:"",d:"",cy:""},d=`
2
+ ${e.r}${e.b}\u274C SafeEnv Validation Failed${e.res}
3
+ `;return d+=` ${e.b}${r("Key",y)} \u2502 ${r("Error",E)} \u2502 Value${e.res}
4
+ `,d+=e.d+"\u2500".repeat(a+5)+e.res+`
5
+ `,t.forEach(s=>{let p=s.value===void 0?"undefined":s.isSecret?"********":`"${s.value}"`,n=s.value===void 0?e.d:s.isSecret?e.y:e.cy;d+=` ${e.y}${r(s.key,y)}${e.res} \u2502 ${e.r}${r(s.error,E)}${e.res} \u2502 ${n}${p}${e.res}
6
+ `}),d+=e.d+"\u2500".repeat(a+5)+e.res+`
7
+ `,d+=` ${e.g}\u{1F4A1} Tip: Check your .env files or schema definitions.${e.res}
8
+ `,d}function O(t){if(k){console.group("%c \u274C SafeEnv Validation Failed ","background: #fee2e2; color: #b91c1c; font-weight: bold; padding: 4px; border-radius: 2px;");let i=t.reduce((f,r)=>(f[r.key]={"Error Message":r.error,"Current Value":r.value===void 0?"undefined":r.isSecret?"********":r.value},f),{});console.table(i),console.log("%c \u{1F4A1} Tip: Check your .env files or schema definitions. ","color: #059669; font-style: italic;"),console.groupEnd()}else console.error(b(t,!0))}var u={},$=new WeakMap;function I(t){let i=b(t,!1);return new Proxy({},{get(f,r){if(r==="__isSafeEnvError")return!0;if(r==="toJSON")return()=>({error:"SafeEnv Validation Failed"});throw new Error(`[safe-env] Cannot access "${String(r)}" because validation failed:
9
+ ${i}`)},ownKeys(){return[]},getOwnPropertyDescriptor(){}})}var h="[safe-env] Cannot modify read-only environment variables.";function _(t){if($.has(t))return $.get(t);let i=new Proxy(t,{get(f,r){if(r==="__isSafeEnv")return!0;let a=Reflect.get(f,r);return a!==null&&typeof a=="object"&&!Object.isFrozen(a)?_(a):a},set(){throw new Error(h)},deleteProperty(){throw new Error(h)},defineProperty(){throw new Error(h)},setPrototypeOf(){throw new Error(h)}});return $.set(t,i),i}function q(t,i={}){let{loadProcessEnv:f=!0,prefix:r=R,cwd:a,useCache:y=!0,refreshCache:E=!1,envLoader:e}=i;if(E)for(let o in u)delete u[o];let d=typeof window<"u",s=typeof process<"u"&&(!!process.env.VITE||!!process.env[V]),p=d||s||"source"in i,n={};if("source"in i)n=i.source||{};else if(y&&!E&&Object.keys(u).length>0)n=u;else if(typeof process<"u"&&!d)try{let o=i.mode||process.env.NODE_ENV||F,c={};if(e)for(let g of[".env",`.env.${o}`,".env.local",`.env.${o}.local`])c={...c,...e(g,a)};n={...c,...f?process.env:{}}}catch (e2){n={}}y&&!E&&Object.keys(u).length>0?Object.keys(n).length===0?n=u:Object.assign(u,n):y&&Object.keys(n).length>0&&Object.assign(u,n);let v={},m=[];for(let o in t){let c=t[o],g=r&&!o.startsWith(r)?r+o:o,S=c.sourceKey||(n[g]!==void 0?g:n[o]!==void 0?o:g),x=n[S];try{if(x===void 0||x===""&&c.default!==void 0){if(c.required&&x===void 0)throw new Error("Missing required field");v[o]=c.default}else{let l=c.parse(x);if(l!==void 0&&c.metadata){let{min:w,max:D,validate:T}=c.metadata;if(typeof l=="number"){if(w!==void 0&&l<w)throw new Error(`Below min ${w}`);if(D!==void 0&&l>D)throw new Error(`Above max ${D}`)}if(T&&!T.fn(l))throw new Error(T.message)}v[o]=l}}catch(l){m.push({key:S,error:l.message,value:x,isSecret:_optionalChain([c, 'access', _2 => _2.metadata, 'optionalAccess', _3 => _3.isSecret])})}}if(m.length>0){if(i.throwOnError){let o=new Error(b(m,!0));throw o.plainMessage=b(m,!1),o}return O(m),typeof process<"u"&&process.exit&&!p&&process.exit(1),I(m)}return _(v)}exports.a = F; exports.b = P; exports.c = j; exports.d = V; exports.e = R; exports.f = b; exports.g = O; exports.h = q;
@@ -0,0 +1,9 @@
1
+ var F="development",P="serve",j="build",V="VITE_DEV_SERVER",R="VITE_";var k=typeof window<"u"&&typeof window.document<"u";function b(t,i=!0){if(k)return`SafeEnv Validation Failed: ${t.map(s=>`${s.key} (${s.error})`).join(", ")}`;let f={r:"\x1B[31m",g:"\x1B[32m",y:"\x1B[33m",b:"\x1B[1m",res:"\x1B[0m",d:"\x1B[2m",cy:"\x1B[36m"},r=(s,p)=>{let n=String(s),v=()=>n.length+(n.match(/[^\x00-\xff]/g)||[]).length;for(;v()>p;)n=n.slice(0,-1);return n+" ".repeat(p-v())},a=Math.max(80,(typeof process<"u"?process.stdout.columns:80)||80)-10,y=Math.floor(a*.3),E=Math.floor(a*.5),e=i?f:{r:"",g:"",y:"",b:"",res:"",d:"",cy:""},d=`
2
+ ${e.r}${e.b}\u274C SafeEnv Validation Failed${e.res}
3
+ `;return d+=` ${e.b}${r("Key",y)} \u2502 ${r("Error",E)} \u2502 Value${e.res}
4
+ `,d+=e.d+"\u2500".repeat(a+5)+e.res+`
5
+ `,t.forEach(s=>{let p=s.value===void 0?"undefined":s.isSecret?"********":`"${s.value}"`,n=s.value===void 0?e.d:s.isSecret?e.y:e.cy;d+=` ${e.y}${r(s.key,y)}${e.res} \u2502 ${e.r}${r(s.error,E)}${e.res} \u2502 ${n}${p}${e.res}
6
+ `}),d+=e.d+"\u2500".repeat(a+5)+e.res+`
7
+ `,d+=` ${e.g}\u{1F4A1} Tip: Check your .env files or schema definitions.${e.res}
8
+ `,d}function O(t){if(k){console.group("%c \u274C SafeEnv Validation Failed ","background: #fee2e2; color: #b91c1c; font-weight: bold; padding: 4px; border-radius: 2px;");let i=t.reduce((f,r)=>(f[r.key]={"Error Message":r.error,"Current Value":r.value===void 0?"undefined":r.isSecret?"********":r.value},f),{});console.table(i),console.log("%c \u{1F4A1} Tip: Check your .env files or schema definitions. ","color: #059669; font-style: italic;"),console.groupEnd()}else console.error(b(t,!0))}var u={},$=new WeakMap;function I(t){let i=b(t,!1);return new Proxy({},{get(f,r){if(r==="__isSafeEnvError")return!0;if(r==="toJSON")return()=>({error:"SafeEnv Validation Failed"});throw new Error(`[safe-env] Cannot access "${String(r)}" because validation failed:
9
+ ${i}`)},ownKeys(){return[]},getOwnPropertyDescriptor(){}})}var h="[safe-env] Cannot modify read-only environment variables.";function _(t){if($.has(t))return $.get(t);let i=new Proxy(t,{get(f,r){if(r==="__isSafeEnv")return!0;let a=Reflect.get(f,r);return a!==null&&typeof a=="object"&&!Object.isFrozen(a)?_(a):a},set(){throw new Error(h)},deleteProperty(){throw new Error(h)},defineProperty(){throw new Error(h)},setPrototypeOf(){throw new Error(h)}});return $.set(t,i),i}function q(t,i={}){let{loadProcessEnv:f=!0,prefix:r=R,cwd:a,useCache:y=!0,refreshCache:E=!1,envLoader:e}=i;if(E)for(let o in u)delete u[o];let d=typeof window<"u",s=typeof process<"u"&&(!!process.env.VITE||!!process.env[V]),p=d||s||"source"in i,n={};if("source"in i)n=i.source||{};else if(y&&!E&&Object.keys(u).length>0)n=u;else if(typeof process<"u"&&!d)try{let o=i.mode||process.env.NODE_ENV||F,c={};if(e)for(let g of[".env",`.env.${o}`,".env.local",`.env.${o}.local`])c={...c,...e(g,a)};n={...c,...f?process.env:{}}}catch{n={}}y&&!E&&Object.keys(u).length>0?Object.keys(n).length===0?n=u:Object.assign(u,n):y&&Object.keys(n).length>0&&Object.assign(u,n);let v={},m=[];for(let o in t){let c=t[o],g=r&&!o.startsWith(r)?r+o:o,S=c.sourceKey||(n[g]!==void 0?g:n[o]!==void 0?o:g),x=n[S];try{if(x===void 0||x===""&&c.default!==void 0){if(c.required&&x===void 0)throw new Error("Missing required field");v[o]=c.default}else{let l=c.parse(x);if(l!==void 0&&c.metadata){let{min:w,max:D,validate:T}=c.metadata;if(typeof l=="number"){if(w!==void 0&&l<w)throw new Error(`Below min ${w}`);if(D!==void 0&&l>D)throw new Error(`Above max ${D}`)}if(T&&!T.fn(l))throw new Error(T.message)}v[o]=l}}catch(l){m.push({key:S,error:l.message,value:x,isSecret:c.metadata?.isSecret})}}if(m.length>0){if(i.throwOnError){let o=new Error(b(m,!0));throw o.plainMessage=b(m,!1),o}return O(m),typeof process<"u"&&process.exit&&!p&&process.exit(1),I(m)}return _(v)}export{F as a,P as b,j as c,V as d,R as e,b as f,O as g,q as h};
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);var _path = require('path'); var _path2 = _interopRequireDefault(_path);function m(r){let n={},i=r.split(/\r?\n/);for(let d of i){let e=d.trim();if(!e||e.startsWith("#"))continue;let o=e.indexOf("=");if(o===-1)continue;let s=e.slice(0,o).trim(),t=e.slice(o+1).trim();if(!t){n[s]="";continue}let c=t[0];if(c==='"'||c==="'"){let l=t.indexOf(c,1);if(l!==-1){n[s]=t.slice(1,l);continue}}let f=t.indexOf("#");f!==-1&&(t=t.slice(0,f).trim()),n[s]=t}return n}function h(r=".env",n){try{let i=_path2.default.resolve(n||process.cwd(),r);if(_fs2.default.existsSync(i))return m(_fs2.default.readFileSync(i,"utf-8"))}catch (e2){}return{}}exports.a = m; exports.b = h;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});require('./chunk-D6WM53FN.cjs');function r(n=".env",t){return{}}exports.loadDotEnv = r;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});function r(n=".env",t){return{}}exports.loadDotEnv = r;
@@ -1 +1 @@
1
- import"./chunk-I7AUKTXE.js";function r(n=".env",t){return{}}export{r as loadDotEnv};
1
+ function r(n=".env",t){return{}}export{r as loadDotEnv};
package/dist/fs-node.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _chunkPLO26PP5cjs = require('./chunk-PLO26PP5.cjs');require('./chunk-D6WM53FN.cjs');var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);var _path = require('path'); var _path2 = _interopRequireDefault(_path);function p(e=".env",n){try{let r=_path2.default.resolve(n||process.cwd(),e);if(_fs2.default.existsSync(r))return _chunkPLO26PP5cjs.a.call(void 0, _fs2.default.readFileSync(r,"utf-8"))}catch (e2){}return{}}exports.loadDotEnv = p;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkTR6KYAQIcjs = require('./chunk-TR6KYAQI.cjs');exports.loadDotEnv = _chunkTR6KYAQIcjs.b;
package/dist/fs-node.js CHANGED
@@ -1 +1 @@
1
- import{a as t}from"./chunk-7CVG4I6F.js";import"./chunk-I7AUKTXE.js";import o from"fs";import s from"path";function p(e=".env",n){try{let r=s.resolve(n||process.cwd(),e);if(o.existsSync(r))return t(o.readFileSync(r,"utf-8"))}catch{}return{}}export{p as loadDotEnv};
1
+ import{b as a}from"./chunk-5KPNMU6R.js";export{a as loadDotEnv};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkPLO26PP5cjs = require('./chunk-PLO26PP5.cjs');var _chunkQKTQJTDScjs = require('./chunk-QKTQJTDS.cjs');require('./chunk-D6WM53FN.cjs');function a(r,e,n,s=[]){return{type:r,default:e,required:e===void 0,parse:n,metadata:s.length?{options:s}:{},from(t){return this.sourceKey=t,this},validate(t,i="Custom validation failed"){return this.metadata={...this.metadata,validate:{fn:t,message:i}},this},min(t){return this.metadata={...this.metadata,min:t},this},max(t){return this.metadata={...this.metadata,max:t},this},transform(t){let i=this.parse;return this.parse=o=>t(i(o)),this},secret(){return this.metadata={...this.metadata,isSecret:!0},this},url(){return this.validate(t=>{try{return new URL(String(t)),!0}catch (e2){return!1}},"Invalid URL format")},email(){return this.validate(t=>/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(String(t)),"Invalid email format")},regex(t,i="Value does not match pattern"){return this.validate(o=>t.test(String(o)),i)},description(t){return this.metadata={...this.metadata,description:t},this}}}var m={string:r=>a("string",r,e=>String(e)),number:r=>a("number",r,e=>{let n=Number(e);if(isNaN(n))throw new Error(`Invalid number: ${e}`);return n}),boolean:r=>a("boolean",r,e=>{if(typeof e=="boolean")return e;if(e===void 0||e==="")return!1;let n=String(e).toLowerCase().trim();if(["true","1","yes","on"].includes(n))return!0;if(["false","0","no","off"].includes(n))return!1;throw new Error(`Invalid boolean: ${e}`)}),enum:(r,e)=>a("enum",e,n=>{if(!r.includes(n))throw new Error(`Value "${n}" is not one of: ${r.join(", ")}`);return n},r),array:(r,e=",")=>a("array",r,n=>Array.isArray(n)?n:typeof n!="string"?[]:n.split(e).map(s=>s.trim()).filter(Boolean))};exports.BUILD = _chunkQKTQJTDScjs.c; exports.DEV = _chunkQKTQJTDScjs.a; exports.SERVE = _chunkQKTQJTDScjs.b; exports.VITE_DEV_FLAG = _chunkQKTQJTDScjs.d; exports.VITE_PREFIX = _chunkQKTQJTDScjs.e; exports.formatErrorReport = _chunkQKTQJTDScjs.f; exports.parseDotEnv = _chunkPLO26PP5cjs.a; exports.reportErrors = _chunkQKTQJTDScjs.g; exports.s = m; exports.safeEnv = _chunkQKTQJTDScjs.h;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkTR6KYAQIcjs = require('./chunk-TR6KYAQI.cjs');var _chunkDEDBPEC7cjs = require('./chunk-DEDBPEC7.cjs');function a(r,e,n,o=[]){return{type:r,default:e,required:e===void 0,parse:n,metadata:o.length?{options:o}:{},from(t){return this.sourceKey=t,this},validate(t,i="Custom validation failed"){return this.metadata={...this.metadata,validate:{fn:t,message:i}},this},min(t){return this.metadata={...this.metadata,min:t},this},max(t){return this.metadata={...this.metadata,max:t},this},transform(t){let i=this.parse;return this.parse=s=>t(i(s)),this},secret(){return this.metadata={...this.metadata,isSecret:!0},this},url(){return this.validate(t=>{try{return new URL(String(t)),!0}catch (e2){return!1}},"Invalid URL format")},email(){return this.validate(t=>/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(String(t)),"Invalid email format")},regex(t,i="Value does not match pattern"){return this.validate(s=>t.test(String(s)),i)},description(t){return this.metadata={...this.metadata,description:t},this}}}var h={string:r=>a("string",r,e=>String(e)),number:r=>a("number",r,e=>{let n=Number(e);if(isNaN(n))throw new Error(`Invalid number: ${e}`);return n}),boolean:r=>a("boolean",r,e=>{if(typeof e=="boolean")return e;if(e===void 0||e==="")return!1;let n=String(e).toLowerCase().trim();if(["true","1","yes","on"].includes(n))return!0;if(["false","0","no","off"].includes(n))return!1;throw new Error(`Invalid boolean: ${e}`)}),enum:(r,e)=>a("enum",e,n=>{if(!r.includes(n))throw new Error(`Value "${n}" is not one of: ${r.join(", ")}`);return n},r),array:(r,e=",")=>a("array",r,n=>Array.isArray(n)?n:typeof n!="string"?[]:n.split(e).map(o=>o.trim()).filter(Boolean))};function E(r,e={}){let n=typeof process<"u"&&(_optionalChain([process, 'access', _ => _.release, 'optionalAccess', _2 => _2.name])==="node"||!!_optionalChain([process, 'access', _3 => _3.versions, 'optionalAccess', _4 => _4.node]));return _chunkDEDBPEC7cjs.h.call(void 0, r,{...e,envLoader:n?_chunkTR6KYAQIcjs.b:void 0})}exports.BUILD = _chunkDEDBPEC7cjs.c; exports.DEV = _chunkDEDBPEC7cjs.a; exports.SERVE = _chunkDEDBPEC7cjs.b; exports.VITE_DEV_FLAG = _chunkDEDBPEC7cjs.d; exports.VITE_PREFIX = _chunkDEDBPEC7cjs.e; exports.formatErrorReport = _chunkDEDBPEC7cjs.f; exports.parseDotEnv = _chunkTR6KYAQIcjs.a; exports.reportErrors = _chunkDEDBPEC7cjs.g; exports.s = h; exports.safeEnv = E;
package/dist/index.d.cts CHANGED
@@ -1,11 +1,6 @@
1
- import { S as Schema, a as SafeEnvOptions, I as InferSchema, F as FieldDefinition, E as EnvError } from './types-Bx-JEkTH.cjs';
1
+ import { F as FieldDefinition, E as EnvError, S as Schema, a as SafeEnvOptions, I as InferSchema } from './types-Bx-JEkTH.cjs';
2
2
  export { B as BUILD, b as BaseType, D as DEV, c as SERVE, V as VITE_DEV_FLAG, d as VITE_PREFIX } from './types-Bx-JEkTH.cjs';
3
3
 
4
- declare function safeEnv<T extends Schema>(schema: T, options?: SafeEnvOptions & {
5
- throwOnError?: boolean;
6
- useCache?: boolean;
7
- }): Readonly<InferSchema<T>>;
8
-
9
4
  declare const s: {
10
5
  string: (d?: string) => FieldDefinition<string>;
11
6
  number: (d?: number) => FieldDefinition<number>;
@@ -23,4 +18,9 @@ declare function parseDotEnv(content: string): Record<string, string>;
23
18
  declare function formatErrorReport(errors: EnvError[], useColor?: boolean): string;
24
19
  declare function reportErrors(errors: EnvError[]): void;
25
20
 
21
+ declare function safeEnv<T extends Schema>(schema: T, options?: SafeEnvOptions & {
22
+ throwOnError?: boolean;
23
+ useCache?: boolean;
24
+ }): Readonly<InferSchema<T>>;
25
+
26
26
  export { EnvError, FieldDefinition, InferSchema, SafeEnvOptions, Schema, formatErrorReport, parseDotEnv, reportErrors, s, safeEnv };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,6 @@
1
- import { S as Schema, a as SafeEnvOptions, I as InferSchema, F as FieldDefinition, E as EnvError } from './types-Bx-JEkTH.js';
1
+ import { F as FieldDefinition, E as EnvError, S as Schema, a as SafeEnvOptions, I as InferSchema } from './types-Bx-JEkTH.js';
2
2
  export { B as BUILD, b as BaseType, D as DEV, c as SERVE, V as VITE_DEV_FLAG, d as VITE_PREFIX } from './types-Bx-JEkTH.js';
3
3
 
4
- declare function safeEnv<T extends Schema>(schema: T, options?: SafeEnvOptions & {
5
- throwOnError?: boolean;
6
- useCache?: boolean;
7
- }): Readonly<InferSchema<T>>;
8
-
9
4
  declare const s: {
10
5
  string: (d?: string) => FieldDefinition<string>;
11
6
  number: (d?: number) => FieldDefinition<number>;
@@ -23,4 +18,9 @@ declare function parseDotEnv(content: string): Record<string, string>;
23
18
  declare function formatErrorReport(errors: EnvError[], useColor?: boolean): string;
24
19
  declare function reportErrors(errors: EnvError[]): void;
25
20
 
21
+ declare function safeEnv<T extends Schema>(schema: T, options?: SafeEnvOptions & {
22
+ throwOnError?: boolean;
23
+ useCache?: boolean;
24
+ }): Readonly<InferSchema<T>>;
25
+
26
26
  export { EnvError, FieldDefinition, InferSchema, SafeEnvOptions, Schema, formatErrorReport, parseDotEnv, reportErrors, s, safeEnv };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{a as d}from"./chunk-7CVG4I6F.js";import{a as y,b as p,c as D,d as g,e as T,f,g as u,h as l}from"./chunk-5AAC43HE.js";import"./chunk-I7AUKTXE.js";function a(r,e,n,s=[]){return{type:r,default:e,required:e===void 0,parse:n,metadata:s.length?{options:s}:{},from(t){return this.sourceKey=t,this},validate(t,i="Custom validation failed"){return this.metadata={...this.metadata,validate:{fn:t,message:i}},this},min(t){return this.metadata={...this.metadata,min:t},this},max(t){return this.metadata={...this.metadata,max:t},this},transform(t){let i=this.parse;return this.parse=o=>t(i(o)),this},secret(){return this.metadata={...this.metadata,isSecret:!0},this},url(){return this.validate(t=>{try{return new URL(String(t)),!0}catch{return!1}},"Invalid URL format")},email(){return this.validate(t=>/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(String(t)),"Invalid email format")},regex(t,i="Value does not match pattern"){return this.validate(o=>t.test(String(o)),i)},description(t){return this.metadata={...this.metadata,description:t},this}}}var m={string:r=>a("string",r,e=>String(e)),number:r=>a("number",r,e=>{let n=Number(e);if(isNaN(n))throw new Error(`Invalid number: ${e}`);return n}),boolean:r=>a("boolean",r,e=>{if(typeof e=="boolean")return e;if(e===void 0||e==="")return!1;let n=String(e).toLowerCase().trim();if(["true","1","yes","on"].includes(n))return!0;if(["false","0","no","off"].includes(n))return!1;throw new Error(`Invalid boolean: ${e}`)}),enum:(r,e)=>a("enum",e,n=>{if(!r.includes(n))throw new Error(`Value "${n}" is not one of: ${r.join(", ")}`);return n},r),array:(r,e=",")=>a("array",r,n=>Array.isArray(n)?n:typeof n!="string"?[]:n.split(e).map(s=>s.trim()).filter(Boolean))};export{D as BUILD,y as DEV,p as SERVE,g as VITE_DEV_FLAG,T as VITE_PREFIX,f as formatErrorReport,d as parseDotEnv,u as reportErrors,m as s,l as safeEnv};
1
+ import{a as u,b as d}from"./chunk-5KPNMU6R.js";import{a as c,b as y,c as T,d as D,e as g,f as l,g as m,h as f}from"./chunk-I6JAZ77H.js";function a(r,e,n,o=[]){return{type:r,default:e,required:e===void 0,parse:n,metadata:o.length?{options:o}:{},from(t){return this.sourceKey=t,this},validate(t,i="Custom validation failed"){return this.metadata={...this.metadata,validate:{fn:t,message:i}},this},min(t){return this.metadata={...this.metadata,min:t},this},max(t){return this.metadata={...this.metadata,max:t},this},transform(t){let i=this.parse;return this.parse=s=>t(i(s)),this},secret(){return this.metadata={...this.metadata,isSecret:!0},this},url(){return this.validate(t=>{try{return new URL(String(t)),!0}catch{return!1}},"Invalid URL format")},email(){return this.validate(t=>/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(String(t)),"Invalid email format")},regex(t,i="Value does not match pattern"){return this.validate(s=>t.test(String(s)),i)},description(t){return this.metadata={...this.metadata,description:t},this}}}var h={string:r=>a("string",r,e=>String(e)),number:r=>a("number",r,e=>{let n=Number(e);if(isNaN(n))throw new Error(`Invalid number: ${e}`);return n}),boolean:r=>a("boolean",r,e=>{if(typeof e=="boolean")return e;if(e===void 0||e==="")return!1;let n=String(e).toLowerCase().trim();if(["true","1","yes","on"].includes(n))return!0;if(["false","0","no","off"].includes(n))return!1;throw new Error(`Invalid boolean: ${e}`)}),enum:(r,e)=>a("enum",e,n=>{if(!r.includes(n))throw new Error(`Value "${n}" is not one of: ${r.join(", ")}`);return n},r),array:(r,e=",")=>a("array",r,n=>Array.isArray(n)?n:typeof n!="string"?[]:n.split(e).map(o=>o.trim()).filter(Boolean))};function E(r,e={}){let n=typeof process<"u"&&(process.release?.name==="node"||!!process.versions?.node);return f(r,{...e,envLoader:n?d:void 0})}export{T as BUILD,c as DEV,y as SERVE,D as VITE_DEV_FLAG,g as VITE_PREFIX,l as formatErrorReport,u as parseDotEnv,m as reportErrors,h as s,E as safeEnv};
package/dist/vite.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkQKTQJTDScjs = require('./chunk-QKTQJTDS.cjs');require('./chunk-D6WM53FN.cjs');var _vite = require('vite');function g(v,f={}){let n=null,o=!1;return{name:"vite-plugin-safe-env",configResolved(e){o=e.command===_chunkQKTQJTDScjs.b,process.env[_chunkQKTQJTDScjs.d]=o?"true":"";let{envDir:t=e.root,prefix:r=e.envPrefix||_chunkQKTQJTDScjs.e}=f,p=_vite.loadEnv.call(void 0, e.mode,t,r);try{_chunkQKTQJTDScjs.h.call(void 0, v,{source:p,prefix:Array.isArray(r)?r[0]:r,loadProcessEnv:!1,throwOnError:!0}),n=null}catch(s){n=s,o?e.logger.error(s.message):(console.error(s.message),console.error(`\x1B[31m[safe-env] Fatal: Environment validation failed during build. Exiting...\x1B[0m
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkDEDBPEC7cjs = require('./chunk-DEDBPEC7.cjs');var _vite = require('vite');function g(v,f={}){let n=null,o=!1;return{name:"vite-plugin-safe-env",configResolved(e){o=e.command===_chunkDEDBPEC7cjs.b,process.env[_chunkDEDBPEC7cjs.d]=o?"true":"";let{envDir:t=e.root,prefix:r=e.envPrefix||_chunkDEDBPEC7cjs.e}=f,p=_vite.loadEnv.call(void 0, e.mode,t,r);try{_chunkDEDBPEC7cjs.h.call(void 0, v,{source:p,prefix:Array.isArray(r)?r[0]:r,loadProcessEnv:!1,throwOnError:!0}),n=null}catch(s){n=s,o?e.logger.error(s.message):(console.error(s.message),console.error(`\x1B[31m[safe-env] Fatal: Environment validation failed during build. Exiting...\x1B[0m
2
2
  `),process.exit(1))}},transform(e,t){if(o&&n&&(e.includes("import.meta.env")||e.includes("safeEnv"))){let r=new Error(n.plainMessage||n.message);throw r.stack="",r}return null}}}exports.viteSafeEnv = g;
package/dist/vite.js CHANGED
@@ -1,2 +1,2 @@
1
- import{b as a,d as i,e as l,h as m}from"./chunk-5AAC43HE.js";import"./chunk-I7AUKTXE.js";import{loadEnv as u}from"vite";function g(v,f={}){let n=null,o=!1;return{name:"vite-plugin-safe-env",configResolved(e){o=e.command===a,process.env[i]=o?"true":"";let{envDir:t=e.root,prefix:r=e.envPrefix||l}=f,p=u(e.mode,t,r);try{m(v,{source:p,prefix:Array.isArray(r)?r[0]:r,loadProcessEnv:!1,throwOnError:!0}),n=null}catch(s){n=s,o?e.logger.error(s.message):(console.error(s.message),console.error(`\x1B[31m[safe-env] Fatal: Environment validation failed during build. Exiting...\x1B[0m
1
+ import{b as a,d as i,e as l,h as m}from"./chunk-I6JAZ77H.js";import{loadEnv as u}from"vite";function g(v,f={}){let n=null,o=!1;return{name:"vite-plugin-safe-env",configResolved(e){o=e.command===a,process.env[i]=o?"true":"";let{envDir:t=e.root,prefix:r=e.envPrefix||l}=f,p=u(e.mode,t,r);try{m(v,{source:p,prefix:Array.isArray(r)?r[0]:r,loadProcessEnv:!1,throwOnError:!0}),n=null}catch(s){n=s,o?e.logger.error(s.message):(console.error(s.message),console.error(`\x1B[31m[safe-env] Fatal: Environment validation failed during build. Exiting...\x1B[0m
2
2
  `),process.exit(1))}},transform(e,t){if(o&&n&&(e.includes("import.meta.env")||e.includes("safeEnv"))){let r=new Error(n.plainMessage||n.message);throw r.stack="",r}return null}}}export{g as viteSafeEnv};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zh-moody/safe-env",
3
- "version": "0.3.8",
3
+ "version": "0.4.1",
4
4
  "description": "Type-safe environment variables for Node.js and Browser with schema validation.",
5
5
  "author": "Moody",
6
6
  "license": "MIT",
@@ -64,5 +64,6 @@
64
64
  "typescript": "^5.9.3",
65
65
  "vite": "^6.2.0",
66
66
  "vitest": "^4.1.2"
67
- }
67
+ },
68
+ "sideEffects": false
68
69
  }
@@ -1,9 +0,0 @@
1
- import{a as R}from"./chunk-I7AUKTXE.js";var $="development",_="serve",j="build",S="VITE_DEV_SERVER",F="VITE_";var V=typeof window<"u"&&typeof window.document<"u";function x(i,s=!0){if(V)return`SafeEnv Validation Failed: ${i.map(t=>`${t.key} (${t.error})`).join(", ")}`;let c={r:"\x1B[31m",g:"\x1B[32m",y:"\x1B[33m",b:"\x1B[1m",res:"\x1B[0m",d:"\x1B[2m",cy:"\x1B[36m"},e=(t,o)=>{let f=String(t),E=()=>f.length+(f.match(/[^\x00-\xff]/g)||[]).length;for(;E()>o;)f=f.slice(0,-1);return f+" ".repeat(o-E())},y=Math.max(80,(typeof process<"u"?process.stdout.columns:80)||80)-10,v=Math.floor(y*.3),g=Math.floor(y*.5),r=s?c:{r:"",g:"",y:"",b:"",res:"",d:"",cy:""},d=`
2
- ${r.r}${r.b}\u274C SafeEnv Validation Failed${r.res}
3
- `;return d+=` ${r.b}${e("Key",v)} \u2502 ${e("Error",g)} \u2502 Value${r.res}
4
- `,d+=r.d+"\u2500".repeat(y+5)+r.res+`
5
- `,i.forEach(t=>{let o=t.value===void 0?"undefined":t.isSecret?"********":`"${t.value}"`,f=t.value===void 0?r.d:t.isSecret?r.y:r.cy;d+=` ${r.y}${e(t.key,v)}${r.res} \u2502 ${r.r}${e(t.error,g)}${r.res} \u2502 ${f}${o}${r.res}
6
- `}),d+=r.d+"\u2500".repeat(y+5)+r.res+`
7
- `,d+=` ${r.g}\u{1F4A1} Tip: Check your .env files or schema definitions.${r.res}
8
- `,d}function k(i){if(V){console.group("%c \u274C SafeEnv Validation Failed ","background: #fee2e2; color: #b91c1c; font-weight: bold; padding: 4px; border-radius: 2px;");let s=i.reduce((c,e)=>(c[e.key]={"Error Message":e.error,"Current Value":e.value===void 0?"undefined":e.isSecret?"********":e.value},c),{});console.table(s),console.log("%c \u{1F4A1} Tip: Check your .env files or schema definitions. ","color: #059669; font-style: italic;"),console.groupEnd()}else console.error(x(i,!0))}var p={};function I(i){let s=x(i,!1);return new Proxy({},{get(c,e){if(e==="__isSafeEnvError")return!0;if(e==="toJSON")return()=>({error:"SafeEnv Validation Failed"});throw new Error(`[safe-env] Cannot access "${String(e)}" because validation failed:
9
- ${s}`)},ownKeys(){return[]},getOwnPropertyDescriptor(){}})}function O(i){let s=Object.getOwnPropertyNames(i);for(let c of s){let e=i[c];e&&typeof e=="object"&&!Object.isFrozen(e)&&O(e)}return Object.freeze(i)}function z(i,s={}){let{loadProcessEnv:c=!0,prefix:e=F,cwd:y,useCache:v=!0,refreshCache:g=!1}=s;if(g)for(let n in p)delete p[n];let r=typeof window<"u",d=typeof process<"u"&&(!!process.env.VITE||!!process.env[S]),t=r||d||"source"in s,o={};if("source"in s)o=s.source||{};else if(v&&!g&&Object.keys(p).length>0)o=p;else if(typeof process<"u"&&!r)try{let n=s.mode||process.env.NODE_ENV||$,{loadDotEnv:a}=R("./fs-node.cjs"),u={};for(let h of[".env",`.env.${n}`,".env.local",`.env.${n}.local`])u={...u,...a(h,y)};o={...u,...c?process.env:{}}}catch{o={}}let f=Object.keys(o).length;if(v&&(f>0?Object.assign(p,o):Object.keys(p).length>0&&(o=p)),t&&Object.keys(o).length===0)return{};let E={},m=[];for(let n in i){let a=i[n],u=e&&!n.startsWith(e)?e+n:n,h=a.sourceKey||(o[u]!==void 0?u:o[n]!==void 0?n:u),b=o[h];try{if(b===void 0||b===""&&a.default!==void 0){if(a.required&&b===void 0)throw new Error("Missing required field");E[n]=a.default}else{let l=a.parse(b);if(l!==void 0&&a.metadata){let{min:D,max:w,validate:T}=a.metadata;if(typeof l=="number"){if(D!==void 0&&l<D)throw new Error(`Below min ${D}`);if(w!==void 0&&l>w)throw new Error(`Above max ${w}`)}if(T&&!T.fn(l))throw new Error(T.message)}E[n]=l}}catch(l){m.push({key:h,error:l.message,value:b,isSecret:a.metadata?.isSecret})}}if(m.length>0){if(s.throwOnError){let n=new Error(x(m,!0));throw n.plainMessage=x(m,!1),n}return k(m),typeof process<"u"&&process.exit&&!t&&process.exit(1),I(m)}return O(E)}export{$ as a,_ as b,j as c,S as d,F as e,x as f,k as g,z as h};
@@ -1 +0,0 @@
1
- function u(f){let t={},l=f.split(/\r?\n/);for(let d of l){let i=d.trim();if(!i||i.startsWith("#"))continue;let e=i.indexOf("=");if(e===-1)continue;let s=i.slice(0,e).trim(),n=i.slice(e+1).trim();if(!n){t[s]="";continue}let o=n[0];if(o==='"'||o==="'"){let r=n.indexOf(o,1);if(r!==-1){t[s]=n.slice(1,r);continue}}let c=n.indexOf("#");c!==-1&&(n=n.slice(0,c).trim()),t[s]=n}return t}export{u as a};
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var d=(a=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(a,{get:(b,c)=>(typeof require<"u"?require:b)[c]}):a)(function(a){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});exports.a = d;
@@ -1 +0,0 @@
1
- var d=(a=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(a,{get:(b,c)=>(typeof require<"u"?require:b)[c]}):a)(function(a){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});export{d as a};
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});function u(f){let t={},l=f.split(/\r?\n/);for(let d of l){let i=d.trim();if(!i||i.startsWith("#"))continue;let e=i.indexOf("=");if(e===-1)continue;let s=i.slice(0,e).trim(),n=i.slice(e+1).trim();if(!n){t[s]="";continue}let o=n[0];if(o==='"'||o==="'"){let r=n.indexOf(o,1);if(r!==-1){t[s]=n.slice(1,r);continue}}let c=n.indexOf("#");c!==-1&&(n=n.slice(0,c).trim()),t[s]=n}return t}exports.a = u;
@@ -1,9 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkD6WM53FNcjs = require('./chunk-D6WM53FN.cjs');var $="development",_= exports.b ="serve",j= exports.c ="build",S= exports.d ="VITE_DEV_SERVER",F= exports.e ="VITE_";var V=typeof window<"u"&&typeof window.document<"u";function x(i,s=!0){if(V)return`SafeEnv Validation Failed: ${i.map(t=>`${t.key} (${t.error})`).join(", ")}`;let c={r:"\x1B[31m",g:"\x1B[32m",y:"\x1B[33m",b:"\x1B[1m",res:"\x1B[0m",d:"\x1B[2m",cy:"\x1B[36m"},e=(t,o)=>{let f=String(t),E=()=>f.length+(f.match(/[^\x00-\xff]/g)||[]).length;for(;E()>o;)f=f.slice(0,-1);return f+" ".repeat(o-E())},y=Math.max(80,(typeof process<"u"?process.stdout.columns:80)||80)-10,v=Math.floor(y*.3),g=Math.floor(y*.5),r=s?c:{r:"",g:"",y:"",b:"",res:"",d:"",cy:""},d=`
2
- ${r.r}${r.b}\u274C SafeEnv Validation Failed${r.res}
3
- `;return d+=` ${r.b}${e("Key",v)} \u2502 ${e("Error",g)} \u2502 Value${r.res}
4
- `,d+=r.d+"\u2500".repeat(y+5)+r.res+`
5
- `,i.forEach(t=>{let o=t.value===void 0?"undefined":t.isSecret?"********":`"${t.value}"`,f=t.value===void 0?r.d:t.isSecret?r.y:r.cy;d+=` ${r.y}${e(t.key,v)}${r.res} \u2502 ${r.r}${e(t.error,g)}${r.res} \u2502 ${f}${o}${r.res}
6
- `}),d+=r.d+"\u2500".repeat(y+5)+r.res+`
7
- `,d+=` ${r.g}\u{1F4A1} Tip: Check your .env files or schema definitions.${r.res}
8
- `,d}function k(i){if(V){console.group("%c \u274C SafeEnv Validation Failed ","background: #fee2e2; color: #b91c1c; font-weight: bold; padding: 4px; border-radius: 2px;");let s=i.reduce((c,e)=>(c[e.key]={"Error Message":e.error,"Current Value":e.value===void 0?"undefined":e.isSecret?"********":e.value},c),{});console.table(s),console.log("%c \u{1F4A1} Tip: Check your .env files or schema definitions. ","color: #059669; font-style: italic;"),console.groupEnd()}else console.error(x(i,!0))}var p={};function I(i){let s=x(i,!1);return new Proxy({},{get(c,e){if(e==="__isSafeEnvError")return!0;if(e==="toJSON")return()=>({error:"SafeEnv Validation Failed"});throw new Error(`[safe-env] Cannot access "${String(e)}" because validation failed:
9
- ${s}`)},ownKeys(){return[]},getOwnPropertyDescriptor(){}})}function O(i){let s=Object.getOwnPropertyNames(i);for(let c of s){let e=i[c];e&&typeof e=="object"&&!Object.isFrozen(e)&&O(e)}return Object.freeze(i)}function z(i,s={}){let{loadProcessEnv:c=!0,prefix:e=F,cwd:y,useCache:v=!0,refreshCache:g=!1}=s;if(g)for(let n in p)delete p[n];let r=typeof window<"u",d=typeof process<"u"&&(!!process.env.VITE||!!process.env[S]),t=r||d||"source"in s,o={};if("source"in s)o=s.source||{};else if(v&&!g&&Object.keys(p).length>0)o=p;else if(typeof process<"u"&&!r)try{let n=s.mode||process.env.NODE_ENV||$,{loadDotEnv:a}=_chunkD6WM53FNcjs.a.call(void 0, "./fs-node.cjs"),u={};for(let h of[".env",`.env.${n}`,".env.local",`.env.${n}.local`])u={...u,...a(h,y)};o={...u,...c?process.env:{}}}catch (e2){o={}}let f=Object.keys(o).length;if(v&&(f>0?Object.assign(p,o):Object.keys(p).length>0&&(o=p)),t&&Object.keys(o).length===0)return{};let E={},m=[];for(let n in i){let a=i[n],u=e&&!n.startsWith(e)?e+n:n,h=a.sourceKey||(o[u]!==void 0?u:o[n]!==void 0?n:u),b=o[h];try{if(b===void 0||b===""&&a.default!==void 0){if(a.required&&b===void 0)throw new Error("Missing required field");E[n]=a.default}else{let l=a.parse(b);if(l!==void 0&&a.metadata){let{min:D,max:w,validate:T}=a.metadata;if(typeof l=="number"){if(D!==void 0&&l<D)throw new Error(`Below min ${D}`);if(w!==void 0&&l>w)throw new Error(`Above max ${w}`)}if(T&&!T.fn(l))throw new Error(T.message)}E[n]=l}}catch(l){m.push({key:h,error:l.message,value:b,isSecret:_optionalChain([a, 'access', _2 => _2.metadata, 'optionalAccess', _3 => _3.isSecret])})}}if(m.length>0){if(s.throwOnError){let n=new Error(x(m,!0));throw n.plainMessage=x(m,!1),n}return k(m),typeof process<"u"&&process.exit&&!t&&process.exit(1),I(m)}return O(E)}exports.a = $; exports.b = _; exports.c = j; exports.d = S; exports.e = F; exports.f = x; exports.g = k; exports.h = z;