@anhuijie/envguard 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -12
- package/package.json +1 -1
- package/src/commands/init.js +17 -0
- package/src/core/schema.js +1 -1
- package/src/core/validator.js +68 -0
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
**Environment Variable Validation, Security Scanning & Documentation Generator**
|
|
6
6
|
|
|
7
7
|
[](https://github.com/AnhuiJie/envguard/actions/workflows/ci.yml)
|
|
8
|
+
[](https://www.npmjs.com/package/@anhuijie/envguard)
|
|
8
9
|
[](https://opensource.org/licenses/MIT)
|
|
9
10
|
[](https://nodejs.org/)
|
|
10
11
|
|
|
@@ -36,7 +37,7 @@ Misconfigured environment variables are a leading cause of production incidents.
|
|
|
36
37
|
|
|
37
38
|
```bash
|
|
38
39
|
# Install
|
|
39
|
-
npm install -g envguard
|
|
40
|
+
npm install -g @anhuijie/envguard
|
|
40
41
|
|
|
41
42
|
# Create config
|
|
42
43
|
envguard init
|
|
@@ -103,6 +104,9 @@ module.exports = {
|
|
|
103
104
|
| `port` | Valid port number (0-65535) | `3000` |
|
|
104
105
|
| `json` | Valid JSON string | `'{"key":"value"}'` |
|
|
105
106
|
| `regex` | Valid regex pattern | `^\\d+$` |
|
|
107
|
+
| `date` | ISO 8601 date string | `2024-01-15` |
|
|
108
|
+
| `semver` | Semantic version | `1.2.3` |
|
|
109
|
+
| `color` | CSS color (hex, rgb, named) | `#ff6600` |
|
|
106
110
|
|
|
107
111
|
### Rule Options
|
|
108
112
|
|
|
@@ -137,10 +141,10 @@ EnvGuard detects these secret types:
|
|
|
137
141
|
|
|
138
142
|
```yaml
|
|
139
143
|
- name: Validate env config
|
|
140
|
-
run: npx envguard validate
|
|
144
|
+
run: npx @anhuijie/envguard validate
|
|
141
145
|
|
|
142
146
|
- name: Security check
|
|
143
|
-
run: npx envguard check
|
|
147
|
+
run: npx @anhuijie/envguard check
|
|
144
148
|
```
|
|
145
149
|
|
|
146
150
|
The command exits with code `1` on validation errors or critical security findings, failing the build.
|
|
@@ -148,7 +152,7 @@ The command exits with code `1` on validation errors or critical security findin
|
|
|
148
152
|
### Programmatic API
|
|
149
153
|
|
|
150
154
|
```js
|
|
151
|
-
const { validateEnv, scanForSecrets, generateEnvExample } = require('envguard');
|
|
155
|
+
const { validateEnv, scanForSecrets, generateEnvExample } = require('@anhuijie/envguard');
|
|
152
156
|
|
|
153
157
|
const schema = { PORT: { required: true, type: 'port' } };
|
|
154
158
|
const result = validateEnv(process.env, schema);
|
|
@@ -189,7 +193,7 @@ const example = generateEnvExample(schema);
|
|
|
189
193
|
|
|
190
194
|
```bash
|
|
191
195
|
# 安装
|
|
192
|
-
npm install -g envguard
|
|
196
|
+
npm install -g @anhuijie/envguard
|
|
193
197
|
|
|
194
198
|
# 创建配置
|
|
195
199
|
envguard init
|
|
@@ -256,6 +260,9 @@ module.exports = {
|
|
|
256
260
|
| `port` | 合法端口号 (0-65535) | `3000` |
|
|
257
261
|
| `json` | 合法 JSON 字符串 | `'{"key":"value"}'` |
|
|
258
262
|
| `regex` | 合法正则表达式 | `^\\d+$` |
|
|
263
|
+
| `date` | ISO 8601 日期字符串 | `2024-01-15` |
|
|
264
|
+
| `semver` | 语义化版本号 | `1.2.3` |
|
|
265
|
+
| `color` | CSS 颜色(hex、rgb、命名色) | `#ff6600` |
|
|
259
266
|
|
|
260
267
|
### 安全扫描
|
|
261
268
|
|
|
@@ -276,10 +283,10 @@ EnvGuard 可检测以下密钥类型:
|
|
|
276
283
|
|
|
277
284
|
```yaml
|
|
278
285
|
- name: 验证环境配置
|
|
279
|
-
run: npx envguard validate
|
|
286
|
+
run: npx @anhuijie/envguard validate
|
|
280
287
|
|
|
281
288
|
- name: 安全检查
|
|
282
|
-
run: npx envguard check
|
|
289
|
+
run: npx @anhuijie/envguard check
|
|
283
290
|
```
|
|
284
291
|
|
|
285
292
|
验证失败或发现严重安全问题时,命令以退出码 `1` 退出,使构建失败。
|
|
@@ -287,7 +294,7 @@ EnvGuard 可检测以下密钥类型:
|
|
|
287
294
|
### 编程式 API
|
|
288
295
|
|
|
289
296
|
```js
|
|
290
|
-
const { validateEnv, scanForSecrets, generateEnvExample } = require('envguard');
|
|
297
|
+
const { validateEnv, scanForSecrets, generateEnvExample } = require('@anhuijie/envguard');
|
|
291
298
|
|
|
292
299
|
const schema = { PORT: { required: true, type: 'port' } };
|
|
293
300
|
const result = validateEnv(process.env, schema);
|
|
@@ -328,7 +335,7 @@ const example = generateEnvExample(schema);
|
|
|
328
335
|
|
|
329
336
|
```bash
|
|
330
337
|
# インストール
|
|
331
|
-
npm install -g envguard
|
|
338
|
+
npm install -g @anhuijie/envguard
|
|
332
339
|
|
|
333
340
|
# 設定ファイルの作成
|
|
334
341
|
envguard init
|
|
@@ -395,6 +402,9 @@ module.exports = {
|
|
|
395
402
|
| `port` | 有効なポート番号 (0-65535) | `3000` |
|
|
396
403
|
| `json` | 有効な JSON 文字列 | `'{"key":"value"}'` |
|
|
397
404
|
| `regex` | 有効な正規表現パターン | `^\\d+$` |
|
|
405
|
+
| `date` | ISO 8601 日付文字列 | `2024-01-15` |
|
|
406
|
+
| `semver` | セマンティックバージョン | `1.2.3` |
|
|
407
|
+
| `color` | CSS カラー(hex、rgb、名前付き) | `#ff6600` |
|
|
398
408
|
|
|
399
409
|
### セキュリティスキャン
|
|
400
410
|
|
|
@@ -415,10 +425,10 @@ EnvGuard は以下のシークレットタイプを検出します:
|
|
|
415
425
|
|
|
416
426
|
```yaml
|
|
417
427
|
- name: 環境設定の検証
|
|
418
|
-
run: npx envguard validate
|
|
428
|
+
run: npx @anhuijie/envguard validate
|
|
419
429
|
|
|
420
430
|
- name: セキュリティチェック
|
|
421
|
-
run: npx envguard check
|
|
431
|
+
run: npx @anhuijie/envguard check
|
|
422
432
|
```
|
|
423
433
|
|
|
424
434
|
検証エラーや重大なセキュリティ問題が見つかった場合、コマンドは終了コード `1` で終了し、ビルドを失敗させます。
|
|
@@ -426,7 +436,7 @@ EnvGuard は以下のシークレットタイプを検出します:
|
|
|
426
436
|
### プログラマティック API
|
|
427
437
|
|
|
428
438
|
```js
|
|
429
|
-
const { validateEnv, scanForSecrets, generateEnvExample } = require('envguard');
|
|
439
|
+
const { validateEnv, scanForSecrets, generateEnvExample } = require('@anhuijie/envguard');
|
|
430
440
|
|
|
431
441
|
const schema = { PORT: { required: true, type: 'port' } };
|
|
432
442
|
const result = validateEnv(process.env, schema);
|
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -48,6 +48,23 @@ module.exports = {
|
|
|
48
48
|
// type: 'string',
|
|
49
49
|
// description: 'External API key',
|
|
50
50
|
// },
|
|
51
|
+
|
|
52
|
+
// ── Additional Types ─────────────────
|
|
53
|
+
// APP_VERSION: {
|
|
54
|
+
// required: false,
|
|
55
|
+
// type: 'semver',
|
|
56
|
+
// description: 'Application version (e.g. 1.2.3)',
|
|
57
|
+
// },
|
|
58
|
+
// RELEASE_DATE: {
|
|
59
|
+
// required: false,
|
|
60
|
+
// type: 'date',
|
|
61
|
+
// description: 'Release date (ISO 8601, e.g. 2024-01-15)',
|
|
62
|
+
// },
|
|
63
|
+
// BRAND_COLOR: {
|
|
64
|
+
// required: false,
|
|
65
|
+
// type: 'color',
|
|
66
|
+
// description: 'Primary brand color (hex, rgb, or named CSS color)',
|
|
67
|
+
// },
|
|
51
68
|
},
|
|
52
69
|
|
|
53
70
|
// Security scanning options
|
package/src/core/schema.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Schema definition and parsing for envguard.config.js
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
const SUPPORTED_TYPES = ['string', 'number', 'boolean', 'url', 'email', 'json', 'regex', 'port'];
|
|
5
|
+
const SUPPORTED_TYPES = ['string', 'number', 'boolean', 'url', 'email', 'json', 'regex', 'port', 'date', 'semver', 'color'];
|
|
6
6
|
|
|
7
7
|
function validateSchema(schema) {
|
|
8
8
|
if (!schema || typeof schema !== 'object') {
|
package/src/core/validator.js
CHANGED
|
@@ -66,6 +66,74 @@ const validators = {
|
|
|
66
66
|
}
|
|
67
67
|
return { valid: true };
|
|
68
68
|
},
|
|
69
|
+
|
|
70
|
+
// Date type: validates ISO 8601 date strings (YYYY-MM-DD or full ISO format)
|
|
71
|
+
date: (value) => {
|
|
72
|
+
const dateRegex = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:?\d{2})?)?$/;
|
|
73
|
+
if (!dateRegex.test(value)) {
|
|
74
|
+
return { valid: false, error: `"${value}" is not a valid date (expected ISO 8601 format, e.g. 2024-01-15)` };
|
|
75
|
+
}
|
|
76
|
+
const parsed = new Date(value);
|
|
77
|
+
if (isNaN(parsed.getTime())) {
|
|
78
|
+
return { valid: false, error: `"${value}" is not a valid date` };
|
|
79
|
+
}
|
|
80
|
+
return { valid: true };
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
// Semver type: validates semantic version strings (e.g. 1.2.3, 1.0.0-beta.1)
|
|
84
|
+
semver: (value) => {
|
|
85
|
+
const semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*)?(\+[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*)?$/;
|
|
86
|
+
return semverRegex.test(value)
|
|
87
|
+
? { valid: true }
|
|
88
|
+
: { valid: false, error: `"${value}" is not a valid semver (expected format: X.Y.Z, e.g. 1.2.3)` };
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Color type: validates CSS color values (hex, rgb, rgba, hsl, named colors)
|
|
92
|
+
color: (value) => {
|
|
93
|
+
const str = String(value).trim();
|
|
94
|
+
// Hex: #RGB, #RRGGBB, #RRGGBBAA
|
|
95
|
+
if (/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(str)) {
|
|
96
|
+
return { valid: true };
|
|
97
|
+
}
|
|
98
|
+
// rgb/rgba
|
|
99
|
+
if (/^rgba?\(\s*\d+(\.\d+)?%?\s*(,\s*\d+(\.\d+)?%?\s*){2,3}\)$/.test(str)) {
|
|
100
|
+
return { valid: true };
|
|
101
|
+
}
|
|
102
|
+
// hsl/hsla
|
|
103
|
+
if (/^hsla?\(\s*\d+(\.\d+)?(deg)?\s*(,\s*\d+(\.\d+)?%?\s*){2,3}\)$/.test(str)) {
|
|
104
|
+
return { valid: true };
|
|
105
|
+
}
|
|
106
|
+
// Named CSS colors
|
|
107
|
+
const namedColors = [
|
|
108
|
+
'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black',
|
|
109
|
+
'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse',
|
|
110
|
+
'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue',
|
|
111
|
+
'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki',
|
|
112
|
+
'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon',
|
|
113
|
+
'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise',
|
|
114
|
+
'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick',
|
|
115
|
+
'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod',
|
|
116
|
+
'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo',
|
|
117
|
+
'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue',
|
|
118
|
+
'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey',
|
|
119
|
+
'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray',
|
|
120
|
+
'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta',
|
|
121
|
+
'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple',
|
|
122
|
+
'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise',
|
|
123
|
+
'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite',
|
|
124
|
+
'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod',
|
|
125
|
+
'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink',
|
|
126
|
+
'plum', 'powderblue', 'purple', 'rebeccapurple', 'red', 'rosybrown', 'royalblue',
|
|
127
|
+
'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver',
|
|
128
|
+
'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue',
|
|
129
|
+
'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke',
|
|
130
|
+
'yellow', 'yellowgreen',
|
|
131
|
+
];
|
|
132
|
+
if (namedColors.includes(str.toLowerCase())) {
|
|
133
|
+
return { valid: true };
|
|
134
|
+
}
|
|
135
|
+
return { valid: false, error: `"${value}" is not a valid color (expected hex, rgb, hsl, or named CSS color)` };
|
|
136
|
+
},
|
|
69
137
|
};
|
|
70
138
|
|
|
71
139
|
function validateValue(value, rule) {
|