@zh-moody/safe-env 0.3.4 → 0.3.6
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 +41 -27
- package/README.md +41 -27
- package/dist/chunk-5LT4H5GX.cjs +1 -0
- package/dist/chunk-D6WM53FN.cjs +1 -0
- package/dist/chunk-E625KLX5.js +9 -0
- package/dist/chunk-FBIIFJ67.js +1 -0
- package/dist/chunk-I7AUKTXE.js +1 -0
- package/dist/chunk-SHSPQLLU.cjs +9 -0
- package/dist/fs-browser.cjs +1 -1
- package/dist/fs-browser.js +1 -1
- package/dist/fs-node.cjs +1 -1
- package/dist/fs-node.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +13 -16
- package/dist/index.d.ts +13 -16
- package/dist/index.js +1 -1
- package/dist/{types-CFipqnoe.d.cts → types-C7kDNgjd.d.cts} +17 -15
- package/dist/{types-CFipqnoe.d.ts → types-C7kDNgjd.d.ts} +17 -15
- package/dist/vite.cjs +2 -1
- package/dist/vite.d.cts +2 -12
- package/dist/vite.d.ts +2 -12
- package/dist/vite.js +2 -1
- package/package.json +1 -1
- package/dist/chunk-MODJPD2X.cjs +0 -1
- package/dist/chunk-UONNQTFU.js +0 -3
- package/dist/chunk-WXZ32K3G.cjs +0 -3
- package/dist/chunk-WZTPUQ3S.js +0 -1
package/README.en.md
CHANGED
|
@@ -20,7 +20,6 @@ Whether you are writing Vue, React, or Node.js, environment variables are often
|
|
|
20
20
|
- **Monorepo Ready**: Supports `cwd` parameter to explicitly specify the `.env` directory, ideal for complex project architectures.
|
|
21
21
|
- **IDE Enhancement**: Supports `.description()` to view variable usage and documentation directly via hover in your code.
|
|
22
22
|
- **Rigorous Type Parsing**: Built-in `s.array()`, `s.boolean()` with enhanced conversion, and `.transform()` for chainable piping.
|
|
23
|
-
- **Ultra-lightweight**: Only **1.9 KB** after Gzip, with zero runtime dependencies.
|
|
24
23
|
|
|
25
24
|
---
|
|
26
25
|
|
|
@@ -35,36 +34,38 @@ npm install @zh-moody/safe-env
|
|
|
35
34
|
### 🚀 Quick Start
|
|
36
35
|
|
|
37
36
|
#### 🔹 [Vite / React / Vue]
|
|
37
|
+
|
|
38
38
|
For frontend projects, use the Vite plugin for **build-time validation**.
|
|
39
39
|
|
|
40
40
|
**1. Configure Vite Plugin (`vite.config.ts`):**
|
|
41
|
+
|
|
41
42
|
```typescript
|
|
42
|
-
import { viteSafeEnv } from
|
|
43
|
-
import { schema } from
|
|
43
|
+
import { viteSafeEnv } from "@zh-moody/safe-env/vite";
|
|
44
|
+
import { schema } from "./src/env";
|
|
44
45
|
|
|
45
46
|
export default {
|
|
46
|
-
plugins: [
|
|
47
|
-
|
|
48
|
-
]
|
|
49
|
-
}
|
|
47
|
+
plugins: [viteSafeEnv(schema)],
|
|
48
|
+
};
|
|
50
49
|
```
|
|
51
50
|
|
|
52
51
|
**2. Define and Export Config (`src/env.ts`):**
|
|
52
|
+
|
|
53
53
|
```typescript
|
|
54
|
-
import { safeEnv, s } from
|
|
54
|
+
import { safeEnv, s } from "@zh-moody/safe-env";
|
|
55
55
|
|
|
56
56
|
export const schema = {
|
|
57
57
|
VITE_API_URL: s.string().url().description("Backend API Base URL"),
|
|
58
58
|
VITE_PORT: s.number(3000).description("Development Server Port"),
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
export const env = safeEnv(schema, {
|
|
62
|
-
source: import.meta.env
|
|
61
|
+
export const env = safeEnv(schema, {
|
|
62
|
+
source: import.meta.env,
|
|
63
63
|
});
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
> **💡 Best Practice: Prevent Vite Type Pollution**
|
|
67
67
|
> To completely disable the insecure original `import.meta.env.XXX` hints, modify `src/vite-env.d.ts`:
|
|
68
|
+
>
|
|
68
69
|
> ```typescript
|
|
69
70
|
> interface ImportMetaEnv {
|
|
70
71
|
> [key: string]: never;
|
|
@@ -74,19 +75,24 @@ export const env = safeEnv(schema, {
|
|
|
74
75
|
---
|
|
75
76
|
|
|
76
77
|
#### 🔸 [Node.js / Server-side]
|
|
78
|
+
|
|
77
79
|
In Node.js, the library automatically looks for and parses `.env` files on disk.
|
|
78
80
|
|
|
79
81
|
**1. Define Config (`src/config.ts`):**
|
|
82
|
+
|
|
80
83
|
```typescript
|
|
81
|
-
import { safeEnv, s } from
|
|
82
|
-
|
|
83
|
-
const config = safeEnv(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
import { safeEnv, s } from "@zh-moody/safe-env";
|
|
85
|
+
|
|
86
|
+
const config = safeEnv(
|
|
87
|
+
{
|
|
88
|
+
DB_PASSWORD: s.string().secret().description("Database Password"),
|
|
89
|
+
DB_PORT: s.number(5432).min(1).max(65535),
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
// Explicitly specify the .env directory for Monorepo or specific deployments
|
|
93
|
+
// cwd: '/path/to/project-root'
|
|
94
|
+
},
|
|
95
|
+
);
|
|
90
96
|
|
|
91
97
|
export default config;
|
|
92
98
|
```
|
|
@@ -96,6 +102,7 @@ export default config;
|
|
|
96
102
|
### 🛠️ API Reference
|
|
97
103
|
|
|
98
104
|
#### 1. Define Fields (`s.xxx`)
|
|
105
|
+
|
|
99
106
|
- `s.string(default?)`: String field. Required if no default value.
|
|
100
107
|
- `s.number(default?)`: Automatically converted to `number` and validated.
|
|
101
108
|
- `s.boolean(default?)`: Supports `"true"`, `"1"`, `"yes"`, `"on"` as `true`.
|
|
@@ -106,43 +113,50 @@ export default config;
|
|
|
106
113
|
|
|
107
114
|
- **`.secret()`**: Masks the value as `********` in error reports.
|
|
108
115
|
```typescript
|
|
109
|
-
PASSWORD: s.string().secret()
|
|
116
|
+
PASSWORD: s.string().secret();
|
|
110
117
|
```
|
|
111
118
|
- **`.url()` / `.email()`**: Built-in format validation.
|
|
112
119
|
```typescript
|
|
113
|
-
API_URL: s.string().url()
|
|
120
|
+
API_URL: s.string().url();
|
|
114
121
|
```
|
|
115
122
|
- **`.regex(pattern, msg?)`**: Custom regex validation.
|
|
116
123
|
```typescript
|
|
117
|
-
VERSION: s.string().regex(/^v\d+\.\d+\.\d+$/, "Invalid format")
|
|
124
|
+
VERSION: s.string().regex(/^v\d+\.\d+\.\d+$/, "Invalid format");
|
|
118
125
|
```
|
|
119
126
|
- **`.description(text)`**: Adds a description for IDE hover hints.
|
|
120
127
|
```typescript
|
|
121
|
-
PORT: s.number(3000).description("Server Port")
|
|
128
|
+
PORT: s.number(3000).description("Server Port");
|
|
122
129
|
```
|
|
123
130
|
- **`.transform(fn)`**: Custom data transformation, supports multi-level piping.
|
|
124
131
|
```typescript
|
|
125
|
-
NAME: s.string()
|
|
132
|
+
NAME: s.string()
|
|
133
|
+
.transform((v) => v.trim())
|
|
134
|
+
.transform((v) => v.toUpperCase());
|
|
126
135
|
```
|
|
127
136
|
- **`.from(key)`**: Maps environment variable name (Alias).
|
|
128
137
|
```typescript
|
|
129
|
-
port: s.number().from(
|
|
138
|
+
port: s.number().from("VITE_SERVER_PORT");
|
|
130
139
|
```
|
|
131
140
|
- **`.min(n)` / `.max(n)`**: Constraints for number values.
|
|
132
141
|
```typescript
|
|
133
|
-
PORT: s.number().min(1024).max(65535)
|
|
142
|
+
PORT: s.number().min(1024).max(65535);
|
|
134
143
|
```
|
|
135
144
|
- **`.validate(fn, msg?)`**: Fully custom validation logic.
|
|
136
145
|
```typescript
|
|
137
|
-
INTERNAL_URL: s.string().validate(
|
|
146
|
+
INTERNAL_URL: s.string().validate(
|
|
147
|
+
(v) => v.endsWith(".internal.com"),
|
|
148
|
+
"Must be internal",
|
|
149
|
+
);
|
|
138
150
|
```
|
|
139
151
|
|
|
140
152
|
---
|
|
141
153
|
|
|
142
154
|
### 🎨 Error Reporting
|
|
155
|
+
|
|
143
156
|
When validation fails, `safe-env` outputs a structured, adaptive table in the console showing: **Key / Error Reason / Current Value (Masked)**.
|
|
144
157
|
|
|
145
158
|
---
|
|
146
159
|
|
|
147
160
|
### 📄 License
|
|
161
|
+
|
|
148
162
|
[MIT License](./LICENSE) - Copyright (c) 2026 Moody.
|
package/README.md
CHANGED
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
- **Monorepo 精准定位**:支持 `cwd` 参数,可显式指定配置文件检索目录,适配复杂的项目架构。
|
|
21
21
|
- **IDE 增强**:支持 `.description()`,在代码中通过悬停直接查看变量用途与文档。
|
|
22
22
|
- **严谨的类型解析**:内置 `s.array()`, `s.boolean()` 增强转换,支持 `.transform()` 链式 Pipe 处理。
|
|
23
|
-
- **极致轻量**:Gzip 压缩后仅 **1.9 KB**,零运行时依赖。
|
|
24
23
|
|
|
25
24
|
---
|
|
26
25
|
|
|
@@ -35,36 +34,38 @@ npm install @zh-moody/safe-env
|
|
|
35
34
|
### 🚀 快速上手
|
|
36
35
|
|
|
37
36
|
#### 🔹 [Vite / React / Vue] 使用
|
|
37
|
+
|
|
38
38
|
在前端,建议配合 Vite 插件实现**构建时校验**。
|
|
39
39
|
|
|
40
40
|
**1. 配置 Vite 插件 (`vite.config.ts`):**
|
|
41
|
+
|
|
41
42
|
```typescript
|
|
42
|
-
import { viteSafeEnv } from
|
|
43
|
-
import { schema } from
|
|
43
|
+
import { viteSafeEnv } from "@zh-moody/safe-env/vite";
|
|
44
|
+
import { schema } from "./src/env";
|
|
44
45
|
|
|
45
46
|
export default {
|
|
46
|
-
plugins: [
|
|
47
|
-
|
|
48
|
-
]
|
|
49
|
-
}
|
|
47
|
+
plugins: [viteSafeEnv(schema)],
|
|
48
|
+
};
|
|
50
49
|
```
|
|
51
50
|
|
|
52
51
|
**2. 定义配置并导出 (`src/env.ts`):**
|
|
52
|
+
|
|
53
53
|
```typescript
|
|
54
|
-
import { safeEnv, s } from
|
|
54
|
+
import { safeEnv, s } from "@zh-moody/safe-env";
|
|
55
55
|
|
|
56
56
|
export const schema = {
|
|
57
57
|
VITE_API_URL: s.string().url().description("后端 API 地址"),
|
|
58
58
|
VITE_PORT: s.number(3000).description("服务端口"),
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
export const env = safeEnv(schema, {
|
|
62
|
-
source: import.meta.env
|
|
61
|
+
export const env = safeEnv(schema, {
|
|
62
|
+
source: import.meta.env,
|
|
63
63
|
});
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
> **💡 最佳实践:防止 Vite 类型污染**
|
|
67
67
|
> 为彻底禁用 `import.meta.env.XXX` 的原生提示,建议修改 `src/vite-env.d.ts`:
|
|
68
|
+
>
|
|
68
69
|
> ```typescript
|
|
69
70
|
> interface ImportMetaEnv {
|
|
70
71
|
> [key: string]: never;
|
|
@@ -74,19 +75,24 @@ export const env = safeEnv(schema, {
|
|
|
74
75
|
---
|
|
75
76
|
|
|
76
77
|
#### 🔸 [Node.js / 服务端] 使用
|
|
78
|
+
|
|
77
79
|
在后端环境,库会自动检索并解析磁盘上的 `.env` 系列文件。
|
|
78
80
|
|
|
79
81
|
**1. 定义配置 (`src/config.ts`):**
|
|
82
|
+
|
|
80
83
|
```typescript
|
|
81
|
-
import { safeEnv, s } from
|
|
82
|
-
|
|
83
|
-
const config = safeEnv(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
import { safeEnv, s } from "@zh-moody/safe-env";
|
|
85
|
+
|
|
86
|
+
const config = safeEnv(
|
|
87
|
+
{
|
|
88
|
+
DB_PASSWORD: s.string().secret().description("数据库密码"),
|
|
89
|
+
DB_PORT: s.number(5432).min(1).max(65535),
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
// 在 Monorepo 或特定部署环境下,可显式指定 .env 所在目录
|
|
93
|
+
// cwd: '/path/to/project-root'
|
|
94
|
+
},
|
|
95
|
+
);
|
|
90
96
|
|
|
91
97
|
export default config;
|
|
92
98
|
```
|
|
@@ -96,6 +102,7 @@ export default config;
|
|
|
96
102
|
### 🛠️ API 详解
|
|
97
103
|
|
|
98
104
|
#### 1. 定义字段 (`s.xxx`)
|
|
105
|
+
|
|
99
106
|
- `s.string(default?)`: 字符串。若无默认值则必填。
|
|
100
107
|
- `s.number(default?)`: 数字。自动转换为 `number` 类型并校验合法性。
|
|
101
108
|
- `s.boolean(default?)`: 布尔型。支持将 `"true"`, `"1"`, `"yes"`, `"on"` 解析为 `true`。
|
|
@@ -108,43 +115,50 @@ export default config;
|
|
|
108
115
|
|
|
109
116
|
- **`.secret()`**: 标记敏感数据,报错时该值会以 `********` 遮罩显示。
|
|
110
117
|
```typescript
|
|
111
|
-
PASSWORD: s.string().secret()
|
|
118
|
+
PASSWORD: s.string().secret();
|
|
112
119
|
```
|
|
113
120
|
- **`.url()` / `.email()`**: 常用格式校验。
|
|
114
121
|
```typescript
|
|
115
|
-
API_URL: s.string().url()
|
|
122
|
+
API_URL: s.string().url();
|
|
116
123
|
```
|
|
117
124
|
- **`.regex(pattern, msg?)`**: 自定义正则校验。
|
|
118
125
|
```typescript
|
|
119
|
-
VERSION: s.string().regex(/^v\d+\.\d+\.\d+$/, "格式错误")
|
|
126
|
+
VERSION: s.string().regex(/^v\d+\.\d+\.\d+$/, "格式错误");
|
|
120
127
|
```
|
|
121
128
|
- **`.description(text)`**: 添加变量描述,映射到 IDE 悬停提示中。
|
|
122
129
|
```typescript
|
|
123
|
-
PORT: s.number(3000).description("服务端口")
|
|
130
|
+
PORT: s.number(3000).description("服务端口");
|
|
124
131
|
```
|
|
125
132
|
- **`.transform(fn)`**: 自定义数据转换,支持多级 Pipe。
|
|
126
133
|
```typescript
|
|
127
|
-
NAME: s.string()
|
|
134
|
+
NAME: s.string()
|
|
135
|
+
.transform((v) => v.trim())
|
|
136
|
+
.transform((v) => v.toUpperCase());
|
|
128
137
|
```
|
|
129
138
|
- **`.from(key)`**: 映射环境变量名(别名)。
|
|
130
139
|
```typescript
|
|
131
|
-
port: s.number().from(
|
|
140
|
+
port: s.number().from("VITE_SERVER_PORT");
|
|
132
141
|
```
|
|
133
142
|
- **`.min(n)` / `.max(n)`**: 限制数字取值范围。
|
|
134
143
|
```typescript
|
|
135
|
-
PORT: s.number().min(1024).max(65535)
|
|
144
|
+
PORT: s.number().min(1024).max(65535);
|
|
136
145
|
```
|
|
137
146
|
- **`.validate(fn, msg?)`**: 完全自定义的逻辑校验。
|
|
138
147
|
```typescript
|
|
139
|
-
INTERNAL_URL: s.string().validate(
|
|
148
|
+
INTERNAL_URL: s.string().validate(
|
|
149
|
+
(v) => v.endsWith(".internal.com"),
|
|
150
|
+
"Must be internal",
|
|
151
|
+
);
|
|
140
152
|
```
|
|
141
153
|
|
|
142
154
|
---
|
|
143
155
|
|
|
144
156
|
### 🎨 错误报告
|
|
157
|
+
|
|
145
158
|
当校验失败时,`safe-env` 会在控制台输出结构化的自适应表格,清晰展示:**Key / 错误原因 / 当前值(已脱敏)**。
|
|
146
159
|
|
|
147
160
|
---
|
|
148
161
|
|
|
149
162
|
### 📄 开源协议 (License)
|
|
163
|
+
|
|
150
164
|
[MIT License](./LICENSE) - Copyright (c) 2026 Moody.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});function l(e){let s={},r=e.split(/\r?\n/);for(let o of r){let i=o.trim();if(!i||i.startsWith("#"))continue;let n=i.indexOf("=");if(n==-1)continue;let c=i.slice(0,n).trim(),t=i.slice(n+1).trim();(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))&&(t=t.slice(1,-1)),s[c]=t}return s}exports.a = l;
|
|
@@ -0,0 +1 @@
|
|
|
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;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{a as k}from"./chunk-I7AUKTXE.js";var T="development",R="serve",I="build",$="VITE_DEV_SERVER",S="VITE_";var V=typeof window<"u"&&typeof window.document<"u";function g(s,t=!0){if(V)return`SafeEnv Validation Failed: ${s.map(e=>`${e.key} (${e.error})`).join(", ")}`;let l={r:"\x1B[31m",g:"\x1B[32m",y:"\x1B[33m",b:"\x1B[1m",res:"\x1B[0m",d:"\x1B[2m",cy:"\x1B[36m"},n=(e,p)=>{let i=String(e),d=()=>i.length+(i.match(/[^\x00-\xff]/g)||[]).length;for(;d()>p;)i=i.slice(0,-1);return i+" ".repeat(p-d())},E=Math.max(80,(typeof process<"u"?process.stdout.columns:80)||80)-10,y=Math.floor(E*.3),m=Math.floor(E*.5),r=t?l:{r:"",g:"",y:"",b:"",res:"",d:"",cy:""},c=`
|
|
2
|
+
${r.r}${r.b}\u274C SafeEnv Validation Failed${r.res}
|
|
3
|
+
`;return c+=` ${r.b}${n("Key",y)} \u2502 ${n("Error",m)} \u2502 Value${r.res}
|
|
4
|
+
`,c+=r.d+"\u2500".repeat(E+5)+r.res+`
|
|
5
|
+
`,s.forEach(e=>{let p=e.value===void 0?"undefined":e.isSecret?"********":`"${e.value}"`,i=e.value===void 0?r.d:e.isSecret?r.y:r.cy;c+=` ${r.y}${n(e.key,y)}${r.res} \u2502 ${r.r}${n(e.error,m)}${r.res} \u2502 ${i}${p}${r.res}
|
|
6
|
+
`}),c+=r.d+"\u2500".repeat(E+5)+r.res+`
|
|
7
|
+
`,c+=` ${r.g}\u{1F4A1} Tip: Check your .env files or schema definitions.${r.res}
|
|
8
|
+
`,c}function F(s){if(V){console.group("%c \u274C SafeEnv Validation Failed ","background: #fee2e2; color: #b91c1c; font-weight: bold; padding: 4px; border-radius: 2px;");let t=s.reduce((l,n)=>(l[n.key]={"Error Message":n.error,"Current Value":n.value===void 0?"undefined":n.isSecret?"********":n.value},l),{});console.table(t),console.log("%c \u{1F4A1} Tip: Check your .env files or schema definitions. ","color: #059669; font-style: italic;"),console.groupEnd()}else console.error(g(s,!0))}var x={};function O(s){let t=g(s,!1);return new Proxy({},{get(l,n){if(n==="__isSafeEnvError")return!0;if(n==="toJSON")return()=>({error:"SafeEnv Validation Failed"});throw new Error(`[safe-env] Cannot access "${String(n)}" because validation failed:
|
|
9
|
+
${t}`)},ownKeys(){return[]},getOwnPropertyDescriptor(){}})}function U(s,t={}){let{loadProcessEnv:l=!0,prefix:n=S,cwd:E,useCache:y=!0}=t,m=typeof window<"u",r=typeof process<"u"&&(!!process.env.VITE||!!process.env[$]),c=m||r||"source"in t,e={};if("source"in t)e=t.source||{};else if(y&&Object.keys(x).length>0)e=x;else if(typeof process<"u"&&!m)try{let o=t.mode||process.env.NODE_ENV||T,{loadDotEnv:a}=k("./fs-node.cjs"),u={};for(let b of[".env",`.env.${o}`,".env.local",`.env.${o}.local`])u={...u,...a(b,E)};e={...u,...l?process.env:{}}}catch{e={}}let p=Object.keys(e).length;if(y&&(p>0?Object.assign(x,e):Object.keys(x).length>0&&(e=x)),c&&Object.keys(e).length===0)return{};let i={},d=[];for(let o in s){let a=s[o],u=n&&!o.startsWith(n)?n+o:o,b=a.sourceKey||(e[u]!==void 0?u:e[o]!==void 0?o:u),v=e[b];try{if(v===void 0||v===""&&a.default!==void 0){if(a.required&&v===void 0)throw new Error("Missing required field");i[o]=a.default}else{let f=a.parse(v);if(f!==void 0&&a.metadata){let{min:h,max:D,validate:w}=a.metadata;if(typeof f=="number"){if(h!==void 0&&f<h)throw new Error(`Below min ${h}`);if(D!==void 0&&f>D)throw new Error(`Above max ${D}`)}if(w&&!w.fn(f))throw new Error(w.message)}i[o]=f}}catch(f){d.push({key:b,error:f.message,value:v,isSecret:a.metadata?.isSecret})}}if(d.length>0){if(t.throwOnError){let o=new Error(g(d,!0));throw o.plainMessage=g(d,!1),o}return F(d),typeof process<"u"&&process.exit&&!c&&process.exit(1),O(d)}return Object.freeze(i)}export{T as a,R as b,I as c,$ as d,S as e,g as f,F as g,U as h};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function l(e){let s={},r=e.split(/\r?\n/);for(let o of r){let i=o.trim();if(!i||i.startsWith("#"))continue;let n=i.indexOf("=");if(n==-1)continue;let c=i.slice(0,n).trim(),t=i.slice(n+1).trim();(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))&&(t=t.slice(1,-1)),s[c]=t}return s}export{l as a};
|
|
@@ -0,0 +1 @@
|
|
|
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};
|
|
@@ -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 _chunkD6WM53FNcjs = require('./chunk-D6WM53FN.cjs');var T="development",R= exports.b ="serve",I= exports.c ="build",$= exports.d ="VITE_DEV_SERVER",S= exports.e ="VITE_";var V=typeof window<"u"&&typeof window.document<"u";function g(s,t=!0){if(V)return`SafeEnv Validation Failed: ${s.map(e=>`${e.key} (${e.error})`).join(", ")}`;let l={r:"\x1B[31m",g:"\x1B[32m",y:"\x1B[33m",b:"\x1B[1m",res:"\x1B[0m",d:"\x1B[2m",cy:"\x1B[36m"},n=(e,p)=>{let i=String(e),d=()=>i.length+(i.match(/[^\x00-\xff]/g)||[]).length;for(;d()>p;)i=i.slice(0,-1);return i+" ".repeat(p-d())},E=Math.max(80,(typeof process<"u"?process.stdout.columns:80)||80)-10,y=Math.floor(E*.3),m=Math.floor(E*.5),r=t?l:{r:"",g:"",y:"",b:"",res:"",d:"",cy:""},c=`
|
|
2
|
+
${r.r}${r.b}\u274C SafeEnv Validation Failed${r.res}
|
|
3
|
+
`;return c+=` ${r.b}${n("Key",y)} \u2502 ${n("Error",m)} \u2502 Value${r.res}
|
|
4
|
+
`,c+=r.d+"\u2500".repeat(E+5)+r.res+`
|
|
5
|
+
`,s.forEach(e=>{let p=e.value===void 0?"undefined":e.isSecret?"********":`"${e.value}"`,i=e.value===void 0?r.d:e.isSecret?r.y:r.cy;c+=` ${r.y}${n(e.key,y)}${r.res} \u2502 ${r.r}${n(e.error,m)}${r.res} \u2502 ${i}${p}${r.res}
|
|
6
|
+
`}),c+=r.d+"\u2500".repeat(E+5)+r.res+`
|
|
7
|
+
`,c+=` ${r.g}\u{1F4A1} Tip: Check your .env files or schema definitions.${r.res}
|
|
8
|
+
`,c}function F(s){if(V){console.group("%c \u274C SafeEnv Validation Failed ","background: #fee2e2; color: #b91c1c; font-weight: bold; padding: 4px; border-radius: 2px;");let t=s.reduce((l,n)=>(l[n.key]={"Error Message":n.error,"Current Value":n.value===void 0?"undefined":n.isSecret?"********":n.value},l),{});console.table(t),console.log("%c \u{1F4A1} Tip: Check your .env files or schema definitions. ","color: #059669; font-style: italic;"),console.groupEnd()}else console.error(g(s,!0))}var x={};function O(s){let t=g(s,!1);return new Proxy({},{get(l,n){if(n==="__isSafeEnvError")return!0;if(n==="toJSON")return()=>({error:"SafeEnv Validation Failed"});throw new Error(`[safe-env] Cannot access "${String(n)}" because validation failed:
|
|
9
|
+
${t}`)},ownKeys(){return[]},getOwnPropertyDescriptor(){}})}function U(s,t={}){let{loadProcessEnv:l=!0,prefix:n=S,cwd:E,useCache:y=!0}=t,m=typeof window<"u",r=typeof process<"u"&&(!!process.env.VITE||!!process.env[$]),c=m||r||"source"in t,e={};if("source"in t)e=t.source||{};else if(y&&Object.keys(x).length>0)e=x;else if(typeof process<"u"&&!m)try{let o=t.mode||process.env.NODE_ENV||T,{loadDotEnv:a}=_chunkD6WM53FNcjs.a.call(void 0, "./fs-node.cjs"),u={};for(let b of[".env",`.env.${o}`,".env.local",`.env.${o}.local`])u={...u,...a(b,E)};e={...u,...l?process.env:{}}}catch (e2){e={}}let p=Object.keys(e).length;if(y&&(p>0?Object.assign(x,e):Object.keys(x).length>0&&(e=x)),c&&Object.keys(e).length===0)return{};let i={},d=[];for(let o in s){let a=s[o],u=n&&!o.startsWith(n)?n+o:o,b=a.sourceKey||(e[u]!==void 0?u:e[o]!==void 0?o:u),v=e[b];try{if(v===void 0||v===""&&a.default!==void 0){if(a.required&&v===void 0)throw new Error("Missing required field");i[o]=a.default}else{let f=a.parse(v);if(f!==void 0&&a.metadata){let{min:h,max:D,validate:w}=a.metadata;if(typeof f=="number"){if(h!==void 0&&f<h)throw new Error(`Below min ${h}`);if(D!==void 0&&f>D)throw new Error(`Above max ${D}`)}if(w&&!w.fn(f))throw new Error(w.message)}i[o]=f}}catch(f){d.push({key:b,error:f.message,value:v,isSecret:_optionalChain([a, 'access', _ => _.metadata, 'optionalAccess', _2 => _2.isSecret])})}}if(d.length>0){if(t.throwOnError){let o=new Error(g(d,!0));throw o.plainMessage=g(d,!1),o}return F(d),typeof process<"u"&&process.exit&&!c&&process.exit(1),O(d)}return Object.freeze(i)}exports.a = T; exports.b = R; exports.c = I; exports.d = $; exports.e = S; exports.f = g; exports.g = F; exports.h = U;
|
package/dist/fs-browser.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});function r(n=".env",t){return{}}exports.loadDotEnv = r;
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});require('./chunk-D6WM53FN.cjs');function r(n=".env",t){return{}}exports.loadDotEnv = r;
|
package/dist/fs-browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function r(n=".env",t){return{}}export{r as loadDotEnv};
|
|
1
|
+
import"./chunk-I7AUKTXE.js";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});var
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _chunk5LT4H5GXcjs = require('./chunk-5LT4H5GX.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 _chunk5LT4H5GXcjs.a.call(void 0, _fs2.default.readFileSync(r,"utf-8"))}catch (e2){}return{}}exports.loadDotEnv = p;
|
package/dist/fs-node.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{a as t}from"./chunk-FBIIFJ67.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};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunk5LT4H5GXcjs = require('./chunk-5LT4H5GX.cjs');var _chunkSHSPQLLUcjs = require('./chunk-SHSPQLLU.cjs');require('./chunk-D6WM53FN.cjs');function a(i,e,n,s=[]){return{type:i,default:e,required:e===void 0,parse:n,metadata:s.length?{options:s}:{},from(t){return this.sourceKey=t,this},validate(t,r="Custom validation failed"){return this.metadata={...this.metadata,validate:{fn:t,message:r}},this},min(t){return this.metadata={...this.metadata,min:t},this},max(t){return this.metadata={...this.metadata,max:t},this},transform(t){let r=this.parse;return this.parse=o=>t(r(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,r="Value does not match pattern"){return this.validate(o=>t.test(String(o)),r)},description(t){return this.metadata={...this.metadata,description:t},this}}}var p={string:i=>a("string",i,e=>String(e)),number:i=>a("number",i,e=>{let n=Number(e);if(isNaN(n))throw new Error(`Invalid number: ${e}`);return n}),boolean:i=>a("boolean",i,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:(i,e)=>a("enum",e,n=>{if(!i.includes(n))throw new Error(`Value "${n}" is not one of: ${i.join(", ")}`);return n},i),array:(i,e=",")=>a("array",i,n=>Array.isArray(n)?n:typeof n!="string"?[]:n.split(e).map(s=>s.trim()).filter(Boolean))};exports.BUILD = _chunkSHSPQLLUcjs.c; exports.DEV = _chunkSHSPQLLUcjs.a; exports.SERVE = _chunkSHSPQLLUcjs.b; exports.VITE_DEV_FLAG = _chunkSHSPQLLUcjs.d; exports.VITE_PREFIX = _chunkSHSPQLLUcjs.e; exports.formatErrorReport = _chunkSHSPQLLUcjs.f; exports.parseDotEnv = _chunk5LT4H5GXcjs.a; exports.reportErrors = _chunkSHSPQLLUcjs.g; exports.s = p; exports.safeEnv = _chunkSHSPQLLUcjs.h;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
|
-
import { F as FieldDefinition, S as Schema, I as InferSchema, E as EnvError } from './types-
|
|
2
|
-
export { B as BaseType } from './types-
|
|
1
|
+
import { F as FieldDefinition, S as Schema, a as SafeEnvOptions, I as InferSchema, E as EnvError } from './types-C7kDNgjd.cjs';
|
|
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-C7kDNgjd.cjs';
|
|
3
3
|
|
|
4
4
|
declare const s: {
|
|
5
|
-
string: (
|
|
6
|
-
number: (
|
|
7
|
-
boolean: (
|
|
8
|
-
enum: <T extends string>(
|
|
9
|
-
array: (
|
|
5
|
+
string: (d?: string) => FieldDefinition<string>;
|
|
6
|
+
number: (d?: number) => FieldDefinition<number>;
|
|
7
|
+
boolean: (d?: boolean) => FieldDefinition<boolean>;
|
|
8
|
+
enum: <T extends string>(o: T[], d?: T) => FieldDefinition<T>;
|
|
9
|
+
array: (d?: string[], sep?: string) => FieldDefinition<string[]>;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
prefix?: string;
|
|
17
|
-
cwd?: string;
|
|
18
|
-
}
|
|
19
|
-
declare function safeEnv<T extends Schema>(schema: T, options?: SafeEnvOptions): Readonly<InferSchema<T>>;
|
|
12
|
+
declare function safeEnv<T extends Schema>(schema: T, options?: SafeEnvOptions & {
|
|
13
|
+
throwOnError?: boolean;
|
|
14
|
+
useCache?: boolean;
|
|
15
|
+
}): Readonly<InferSchema<T>>;
|
|
20
16
|
|
|
21
17
|
/***
|
|
22
18
|
* 将 .env 内容字符串解析为对象
|
|
23
19
|
* */
|
|
24
20
|
declare function parseDotEnv(content: string): Record<string, string>;
|
|
25
21
|
|
|
22
|
+
declare function formatErrorReport(errors: EnvError[], useColor?: boolean): string;
|
|
26
23
|
declare function reportErrors(errors: EnvError[]): void;
|
|
27
24
|
|
|
28
|
-
export { EnvError, FieldDefinition, InferSchema, Schema, parseDotEnv, reportErrors, s, safeEnv };
|
|
25
|
+
export { EnvError, FieldDefinition, InferSchema, SafeEnvOptions, Schema, formatErrorReport, parseDotEnv, reportErrors, s, safeEnv };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
|
-
import { F as FieldDefinition, S as Schema, I as InferSchema, E as EnvError } from './types-
|
|
2
|
-
export { B as BaseType } from './types-
|
|
1
|
+
import { F as FieldDefinition, S as Schema, a as SafeEnvOptions, I as InferSchema, E as EnvError } from './types-C7kDNgjd.js';
|
|
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-C7kDNgjd.js';
|
|
3
3
|
|
|
4
4
|
declare const s: {
|
|
5
|
-
string: (
|
|
6
|
-
number: (
|
|
7
|
-
boolean: (
|
|
8
|
-
enum: <T extends string>(
|
|
9
|
-
array: (
|
|
5
|
+
string: (d?: string) => FieldDefinition<string>;
|
|
6
|
+
number: (d?: number) => FieldDefinition<number>;
|
|
7
|
+
boolean: (d?: boolean) => FieldDefinition<boolean>;
|
|
8
|
+
enum: <T extends string>(o: T[], d?: T) => FieldDefinition<T>;
|
|
9
|
+
array: (d?: string[], sep?: string) => FieldDefinition<string[]>;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
prefix?: string;
|
|
17
|
-
cwd?: string;
|
|
18
|
-
}
|
|
19
|
-
declare function safeEnv<T extends Schema>(schema: T, options?: SafeEnvOptions): Readonly<InferSchema<T>>;
|
|
12
|
+
declare function safeEnv<T extends Schema>(schema: T, options?: SafeEnvOptions & {
|
|
13
|
+
throwOnError?: boolean;
|
|
14
|
+
useCache?: boolean;
|
|
15
|
+
}): Readonly<InferSchema<T>>;
|
|
20
16
|
|
|
21
17
|
/***
|
|
22
18
|
* 将 .env 内容字符串解析为对象
|
|
23
19
|
* */
|
|
24
20
|
declare function parseDotEnv(content: string): Record<string, string>;
|
|
25
21
|
|
|
22
|
+
declare function formatErrorReport(errors: EnvError[], useColor?: boolean): string;
|
|
26
23
|
declare function reportErrors(errors: EnvError[]): void;
|
|
27
24
|
|
|
28
|
-
export { EnvError, FieldDefinition, InferSchema, Schema, parseDotEnv, reportErrors, s, safeEnv };
|
|
25
|
+
export { EnvError, FieldDefinition, InferSchema, SafeEnvOptions, Schema, formatErrorReport, parseDotEnv, reportErrors, s, safeEnv };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as u}from"./chunk-FBIIFJ67.js";import{a as l,b as f,c as m,d as h,e as y,f as g,g as D,h as T}from"./chunk-E625KLX5.js";import"./chunk-I7AUKTXE.js";function a(i,e,n,s=[]){return{type:i,default:e,required:e===void 0,parse:n,metadata:s.length?{options:s}:{},from(t){return this.sourceKey=t,this},validate(t,r="Custom validation failed"){return this.metadata={...this.metadata,validate:{fn:t,message:r}},this},min(t){return this.metadata={...this.metadata,min:t},this},max(t){return this.metadata={...this.metadata,max:t},this},transform(t){let r=this.parse;return this.parse=o=>t(r(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,r="Value does not match pattern"){return this.validate(o=>t.test(String(o)),r)},description(t){return this.metadata={...this.metadata,description:t},this}}}var p={string:i=>a("string",i,e=>String(e)),number:i=>a("number",i,e=>{let n=Number(e);if(isNaN(n))throw new Error(`Invalid number: ${e}`);return n}),boolean:i=>a("boolean",i,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:(i,e)=>a("enum",e,n=>{if(!i.includes(n))throw new Error(`Value "${n}" is not one of: ${i.join(", ")}`);return n},i),array:(i,e=",")=>a("array",i,n=>Array.isArray(n)?n:typeof n!="string"?[]:n.split(e).map(s=>s.trim()).filter(Boolean))};export{m as BUILD,l as DEV,f as SERVE,h as VITE_DEV_FLAG,y as VITE_PREFIX,g as formatErrorReport,u as parseDotEnv,D as reportErrors,p as s,T as safeEnv};
|
|
@@ -1,20 +1,15 @@
|
|
|
1
|
+
declare const DEV = "development";
|
|
2
|
+
declare const SERVE = "serve";
|
|
3
|
+
declare const BUILD = "build";
|
|
4
|
+
declare const VITE_DEV_FLAG = "VITE_DEV_SERVER";
|
|
5
|
+
declare const VITE_PREFIX = "VITE_";
|
|
1
6
|
type BaseType = "string" | "number" | "boolean" | "enum" | "array";
|
|
2
7
|
interface FieldDefinition<T = any, D extends string = string> {
|
|
3
8
|
type: BaseType;
|
|
4
9
|
default?: T;
|
|
5
10
|
required: boolean;
|
|
6
11
|
sourceKey?: string;
|
|
7
|
-
metadata?:
|
|
8
|
-
min?: number;
|
|
9
|
-
max?: number;
|
|
10
|
-
options?: T[];
|
|
11
|
-
description?: string;
|
|
12
|
-
isSecret?: boolean;
|
|
13
|
-
validate?: {
|
|
14
|
-
fn: (val: T) => boolean;
|
|
15
|
-
message: string;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
12
|
+
metadata?: any;
|
|
18
13
|
parse: (val: any) => T;
|
|
19
14
|
from: (key: string) => FieldDefinition<T, D>;
|
|
20
15
|
validate: (fn: (val: T) => boolean, message?: string) => FieldDefinition<T, D>;
|
|
@@ -35,9 +30,16 @@ interface EnvError {
|
|
|
35
30
|
isSecret?: boolean;
|
|
36
31
|
}
|
|
37
32
|
type InferSchema<T> = {
|
|
38
|
-
[K in keyof T]: T[K] extends FieldDefinition<infer U,
|
|
39
|
-
readonly __description?: D;
|
|
40
|
-
} : never;
|
|
33
|
+
[K in keyof T]: T[K] extends FieldDefinition<infer U, any> ? U : never;
|
|
41
34
|
};
|
|
35
|
+
interface SafeEnvOptions {
|
|
36
|
+
mode?: string;
|
|
37
|
+
loadProcessEnv?: boolean;
|
|
38
|
+
source?: Record<string, any>;
|
|
39
|
+
prefix?: string;
|
|
40
|
+
cwd?: string;
|
|
41
|
+
/** @internal */ manualSource?: boolean;
|
|
42
|
+
/** @internal */ devMode?: boolean;
|
|
43
|
+
}
|
|
42
44
|
|
|
43
|
-
export
|
|
45
|
+
export { BUILD as B, DEV as D, type EnvError as E, type FieldDefinition as F, type InferSchema as I, type Schema as S, VITE_DEV_FLAG as V, type SafeEnvOptions as a, type BaseType as b, SERVE as c, VITE_PREFIX as d };
|
|
@@ -1,20 +1,15 @@
|
|
|
1
|
+
declare const DEV = "development";
|
|
2
|
+
declare const SERVE = "serve";
|
|
3
|
+
declare const BUILD = "build";
|
|
4
|
+
declare const VITE_DEV_FLAG = "VITE_DEV_SERVER";
|
|
5
|
+
declare const VITE_PREFIX = "VITE_";
|
|
1
6
|
type BaseType = "string" | "number" | "boolean" | "enum" | "array";
|
|
2
7
|
interface FieldDefinition<T = any, D extends string = string> {
|
|
3
8
|
type: BaseType;
|
|
4
9
|
default?: T;
|
|
5
10
|
required: boolean;
|
|
6
11
|
sourceKey?: string;
|
|
7
|
-
metadata?:
|
|
8
|
-
min?: number;
|
|
9
|
-
max?: number;
|
|
10
|
-
options?: T[];
|
|
11
|
-
description?: string;
|
|
12
|
-
isSecret?: boolean;
|
|
13
|
-
validate?: {
|
|
14
|
-
fn: (val: T) => boolean;
|
|
15
|
-
message: string;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
12
|
+
metadata?: any;
|
|
18
13
|
parse: (val: any) => T;
|
|
19
14
|
from: (key: string) => FieldDefinition<T, D>;
|
|
20
15
|
validate: (fn: (val: T) => boolean, message?: string) => FieldDefinition<T, D>;
|
|
@@ -35,9 +30,16 @@ interface EnvError {
|
|
|
35
30
|
isSecret?: boolean;
|
|
36
31
|
}
|
|
37
32
|
type InferSchema<T> = {
|
|
38
|
-
[K in keyof T]: T[K] extends FieldDefinition<infer U,
|
|
39
|
-
readonly __description?: D;
|
|
40
|
-
} : never;
|
|
33
|
+
[K in keyof T]: T[K] extends FieldDefinition<infer U, any> ? U : never;
|
|
41
34
|
};
|
|
35
|
+
interface SafeEnvOptions {
|
|
36
|
+
mode?: string;
|
|
37
|
+
loadProcessEnv?: boolean;
|
|
38
|
+
source?: Record<string, any>;
|
|
39
|
+
prefix?: string;
|
|
40
|
+
cwd?: string;
|
|
41
|
+
/** @internal */ manualSource?: boolean;
|
|
42
|
+
/** @internal */ devMode?: boolean;
|
|
43
|
+
}
|
|
42
44
|
|
|
43
|
-
export
|
|
45
|
+
export { BUILD as B, DEV as D, type EnvError as E, type FieldDefinition as F, type InferSchema as I, type Schema as S, VITE_DEV_FLAG as V, type SafeEnvOptions as a, type BaseType as b, SERVE as c, VITE_PREFIX as d };
|
package/dist/vite.cjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkSHSPQLLUcjs = require('./chunk-SHSPQLLU.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===_chunkSHSPQLLUcjs.b,process.env[_chunkSHSPQLLUcjs.d]=o?"true":"";let{envDir:t=e.root,prefix:r=e.envPrefix||_chunkSHSPQLLUcjs.e}=f,p=_vite.loadEnv.call(void 0, e.mode,t,r);try{_chunkSHSPQLLUcjs.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
|
+
`),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.d.cts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
|
-
import { S as Schema } from './types-
|
|
2
|
+
import { S as Schema } from './types-C7kDNgjd.cjs';
|
|
3
3
|
|
|
4
|
-
interface ViteSafeEnvOptions {
|
|
5
|
-
/**
|
|
6
|
-
* 环境变量目录,默认为项目根目录
|
|
7
|
-
*/
|
|
8
|
-
envDir?: string;
|
|
9
|
-
/**
|
|
10
|
-
* 环境变量前缀,默认是 VITE_
|
|
11
|
-
*/
|
|
12
|
-
prefix?: string | string[];
|
|
13
|
-
}
|
|
14
4
|
/**
|
|
15
5
|
* Vite 插件:在构建或开发启动时校验环境变量
|
|
16
6
|
*/
|
|
17
|
-
declare function viteSafeEnv(schema: Schema, options?:
|
|
7
|
+
declare function viteSafeEnv(schema: Schema, options?: any): Plugin;
|
|
18
8
|
|
|
19
9
|
export { viteSafeEnv };
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
|
-
import { S as Schema } from './types-
|
|
2
|
+
import { S as Schema } from './types-C7kDNgjd.js';
|
|
3
3
|
|
|
4
|
-
interface ViteSafeEnvOptions {
|
|
5
|
-
/**
|
|
6
|
-
* 环境变量目录,默认为项目根目录
|
|
7
|
-
*/
|
|
8
|
-
envDir?: string;
|
|
9
|
-
/**
|
|
10
|
-
* 环境变量前缀,默认是 VITE_
|
|
11
|
-
*/
|
|
12
|
-
prefix?: string | string[];
|
|
13
|
-
}
|
|
14
4
|
/**
|
|
15
5
|
* Vite 插件:在构建或开发启动时校验环境变量
|
|
16
6
|
*/
|
|
17
|
-
declare function viteSafeEnv(schema: Schema, options?:
|
|
7
|
+
declare function viteSafeEnv(schema: Schema, options?: any): Plugin;
|
|
18
8
|
|
|
19
9
|
export { viteSafeEnv };
|
package/dist/vite.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{b as
|
|
1
|
+
import{b as a,d as i,e as l,h as m}from"./chunk-E625KLX5.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
|
|
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
package/dist/chunk-MODJPD2X.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
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 o(s){let i={},r=s.split(/\r?\n/);for(let f of r){let n=f.trim();if(!n||n.startsWith("#"))continue;let e=n.indexOf("=");if(e==-1)continue;let l=n.slice(0,e).trim(),t=n.slice(e+1).trim();(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))&&(t=t.slice(1,-1)),i[l]=t}return i}function g(s=".env",i){try{let r=_path2.default.resolve(i||process.cwd(),s);if(_fs2.default.existsSync(r))return o(_fs2.default.readFileSync(r,"utf-8"))}catch (e2){}return{}}exports.a = o; exports.b = g;
|
package/dist/chunk-UONNQTFU.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{b as y}from"./chunk-WZTPUQ3S.js";function $(m){let e={r:"\x1B[31m",g:"\x1B[32m",y:"\x1B[33m",b:"\x1B[1m",res:"\x1B[0m",d:"\x1B[2m",cy:"\x1B[36m"},d=Math.max(80,process.stdout.columns||80)-10,f=Math.floor(d*.3),u=Math.floor(d*.5),l=(r,a)=>{let t=String(r),o=()=>t.length+(t.match(/[^\x00-\xff]/g)||[]).length;for(;o()>a;)t=t.slice(0,-1);return t+" ".repeat(a-o())};console.error(`
|
|
2
|
-
${e.r}${e.b}\u274C SafeEnv Validation Failed${e.res}`),console.error(` ${e.b}${l("Key",f)} \u2502 ${l("Error",u)} \u2502 Value${e.res}`),console.error(e.d+"\u2500".repeat(d+5)+e.res),m.forEach(r=>{let a=r.isSecret?"********":r.value===void 0?"undefined":`"${r.value}"`,t=r.isSecret?e.y:r.value===void 0?e.d:e.cy;console.error(` ${e.y}${l(r.key,f)}${e.res} \u2502 ${e.r}${l(r.error,u)}${e.res} \u2502 ${t}${a}${e.res}`)}),console.error(e.d+"\u2500".repeat(d+5)+e.res),console.error(` ${e.g}\u{1F4A1} Tip: Check your .env files or schema definitions.${e.res}
|
|
3
|
-
`)}function b(m,e={}){let{loadProcessEnv:d=!0,source:f,prefix:u="",cwd:l}=e,r;if(f!==void 0)r=f||{};else{let o=e.mode||(typeof process<"u"?process.env.NODE_ENV:"development"),s=[".env",`.env.${o}`,".env.local",`.env.${o}.local`],i={};for(let c of s)i={...i,...y(c,l)};r={...i,...d&&typeof process<"u"?process.env:{}}}let a={},t=[];for(let o in m){let s=m[o],i=s.sourceKey;if(!i){let n=u+o;r[n]!==void 0?i=n:r[o]!==void 0?i=o:i=u?n:o}let c=r[i];try{let n;if(c===void 0||c===""&&s.default!==void 0){if(s.required&&c===void 0)throw new Error("Required field missing");n=s.default}else n=s.parse(c);if(n!==void 0&&s.metadata){let{min:p,max:v,validate:E}=s.metadata;if(typeof n=="number"){if(p!==void 0&&n<p)throw new Error(`Below min ${p}`);if(v!==void 0&&n>v)throw new Error(`Above max ${v}`)}if(E&&!E.fn(n))throw new Error(E.message)}a[o]=n}catch(n){t.push({key:i,error:n.message,value:c,isSecret:s.metadata?.isSecret})}}if(t.length>0){$(t);let o=typeof process<"u"&&!!process.exit,s=typeof process<"u"&&process.env.NODE_ENV==="test";if(o&&!f&&!s)process.exit(1);else throw new Error("SafeEnv: Configuration validation failed.")}return Object.freeze(a)}export{$ as a,b};
|
package/dist/chunk-WXZ32K3G.cjs
DELETED
|
@@ -1,3 +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 _chunkMODJPD2Xcjs = require('./chunk-MODJPD2X.cjs');function $(m){let e={r:"\x1B[31m",g:"\x1B[32m",y:"\x1B[33m",b:"\x1B[1m",res:"\x1B[0m",d:"\x1B[2m",cy:"\x1B[36m"},d=Math.max(80,process.stdout.columns||80)-10,f=Math.floor(d*.3),u=Math.floor(d*.5),l=(r,a)=>{let t=String(r),o=()=>t.length+(t.match(/[^\x00-\xff]/g)||[]).length;for(;o()>a;)t=t.slice(0,-1);return t+" ".repeat(a-o())};console.error(`
|
|
2
|
-
${e.r}${e.b}\u274C SafeEnv Validation Failed${e.res}`),console.error(` ${e.b}${l("Key",f)} \u2502 ${l("Error",u)} \u2502 Value${e.res}`),console.error(e.d+"\u2500".repeat(d+5)+e.res),m.forEach(r=>{let a=r.isSecret?"********":r.value===void 0?"undefined":`"${r.value}"`,t=r.isSecret?e.y:r.value===void 0?e.d:e.cy;console.error(` ${e.y}${l(r.key,f)}${e.res} \u2502 ${e.r}${l(r.error,u)}${e.res} \u2502 ${t}${a}${e.res}`)}),console.error(e.d+"\u2500".repeat(d+5)+e.res),console.error(` ${e.g}\u{1F4A1} Tip: Check your .env files or schema definitions.${e.res}
|
|
3
|
-
`)}function b(m,e={}){let{loadProcessEnv:d=!0,source:f,prefix:u="",cwd:l}=e,r;if(f!==void 0)r=f||{};else{let o=e.mode||(typeof process<"u"?process.env.NODE_ENV:"development"),s=[".env",`.env.${o}`,".env.local",`.env.${o}.local`],i={};for(let c of s)i={...i,..._chunkMODJPD2Xcjs.b.call(void 0, c,l)};r={...i,...d&&typeof process<"u"?process.env:{}}}let a={},t=[];for(let o in m){let s=m[o],i=s.sourceKey;if(!i){let n=u+o;r[n]!==void 0?i=n:r[o]!==void 0?i=o:i=u?n:o}let c=r[i];try{let n;if(c===void 0||c===""&&s.default!==void 0){if(s.required&&c===void 0)throw new Error("Required field missing");n=s.default}else n=s.parse(c);if(n!==void 0&&s.metadata){let{min:p,max:v,validate:E}=s.metadata;if(typeof n=="number"){if(p!==void 0&&n<p)throw new Error(`Below min ${p}`);if(v!==void 0&&n>v)throw new Error(`Above max ${v}`)}if(E&&!E.fn(n))throw new Error(E.message)}a[o]=n}catch(n){t.push({key:i,error:n.message,value:c,isSecret:_optionalChain([s, 'access', _ => _.metadata, 'optionalAccess', _2 => _2.isSecret])})}}if(t.length>0){$(t);let o=typeof process<"u"&&!!process.exit,s=typeof process<"u"&&process.env.NODE_ENV==="test";if(o&&!f&&!s)process.exit(1);else throw new Error("SafeEnv: Configuration validation failed.")}return Object.freeze(a)}exports.a = $; exports.b = b;
|
package/dist/chunk-WZTPUQ3S.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import c from"fs";import a from"path";function o(s){let i={},r=s.split(/\r?\n/);for(let f of r){let n=f.trim();if(!n||n.startsWith("#"))continue;let e=n.indexOf("=");if(e==-1)continue;let l=n.slice(0,e).trim(),t=n.slice(e+1).trim();(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))&&(t=t.slice(1,-1)),i[l]=t}return i}function g(s=".env",i){try{let r=a.resolve(i||process.cwd(),s);if(c.existsSync(r))return o(c.readFileSync(r,"utf-8"))}catch{}return{}}export{o as a,g as b};
|