@danielszlaski/envguard 0.1.2 → 0.1.4
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/.envguardrc.example.json +1 -0
- package/.envguardrc.json +16 -0
- package/.github/FUNDING.yml +15 -0
- package/LICENSE +1 -1
- package/README.md +246 -11
- package/dist/analyzer/envAnalyzer.d.ts +8 -2
- package/dist/analyzer/envAnalyzer.d.ts.map +1 -1
- package/dist/analyzer/envAnalyzer.js +22 -8
- package/dist/analyzer/envAnalyzer.js.map +1 -1
- package/dist/cli.js +25 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +32 -7
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/scan.d.ts +1 -0
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +150 -41
- package/dist/commands/scan.js.map +1 -1
- package/dist/config/configLoader.d.ts +6 -0
- package/dist/config/configLoader.d.ts.map +1 -1
- package/dist/config/configLoader.js +1 -0
- package/dist/config/configLoader.js.map +1 -1
- package/dist/scanner/codeScanner.d.ts +5 -2
- package/dist/scanner/codeScanner.d.ts.map +1 -1
- package/dist/scanner/codeScanner.js +72 -25
- package/dist/scanner/codeScanner.js.map +1 -1
- package/dist/types.d.ts +6 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/analyzer/envAnalyzer.ts +27 -10
- package/src/cli.ts +29 -3
- package/src/commands/fix.ts +40 -9
- package/src/commands/scan.ts +168 -47
- package/src/config/configLoader.ts +8 -0
- package/src/scanner/codeScanner.ts +97 -28
- package/src/types.ts +3 -1
- package/test-project/src/lambda2/handler2.js +1 -1
- package/test-project/.envguardrc.json +0 -7
package/.envguardrc.example.json
CHANGED
package/.envguardrc.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft-07/schema",
|
|
3
|
+
"title": "EnvGuard Configuration",
|
|
4
|
+
"description": "Configuration file for EnvGuard - keep your environment variables in sync",
|
|
5
|
+
"ignoreVars": [
|
|
6
|
+
"VAR_NAME"
|
|
7
|
+
],
|
|
8
|
+
"strict": false,
|
|
9
|
+
"detectFallbacks": true,
|
|
10
|
+
"exclude": [
|
|
11
|
+
"**/tmp/**",
|
|
12
|
+
"**/cache/**",
|
|
13
|
+
"**/node_modules/**",
|
|
14
|
+
"**/dist/**"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# These are supported funding model platforms
|
|
2
|
+
|
|
3
|
+
github: szlaskidaniel # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
|
4
|
+
# patreon: # Replace with a single Patreon username
|
|
5
|
+
# open_collective: # Replace with a single Open Collective username
|
|
6
|
+
# ko_fi: # Replace with a single Ko-fi username
|
|
7
|
+
# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
8
|
+
# community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
9
|
+
# liberapay: # Replace with a single Liberapay username
|
|
10
|
+
# issuehunt: # Replace with a single IssueHunt username
|
|
11
|
+
# lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
|
12
|
+
# polar: # Replace with a single Polar username
|
|
13
|
+
# buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
|
|
14
|
+
# thanks_dev: # Replace with a single thanks.dev username
|
|
15
|
+
# custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
# EnvGuard
|
|
1
|
+
# EnvGuard CLI
|
|
2
|
+
**Static Analysis for Environment Variables**
|
|
2
3
|
|
|
3
4
|
Keep your environment variables in sync with your codebase.
|
|
4
5
|
|
|
6
|
+
|
|
5
7
|
## The Problem
|
|
6
8
|
|
|
7
9
|
- `.env.example` is always out of sync with actual `.env`
|
|
@@ -21,18 +23,27 @@ EnvGuard automatically:
|
|
|
21
23
|
|
|
22
24
|
## Installation
|
|
23
25
|
|
|
26
|
+
**Option 1: Install globally**
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -g @danielszlaski/envguard
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
After installation, use the short command:
|
|
24
33
|
```bash
|
|
25
|
-
|
|
34
|
+
envguard scan
|
|
26
35
|
```
|
|
27
36
|
|
|
28
|
-
|
|
37
|
+
**Option 2: Use with npx (no installation needed)**
|
|
29
38
|
|
|
30
39
|
```bash
|
|
31
|
-
npx envguard scan
|
|
40
|
+
npx @danielszlaski/envguard scan
|
|
32
41
|
```
|
|
33
42
|
|
|
34
43
|
## Usage
|
|
35
44
|
|
|
45
|
+
> **Note:** The examples below use `envguard` (short form), which works after installation. If using npx without installation, use `npx @danielszlaski/envguard` instead.
|
|
46
|
+
|
|
36
47
|
### Scan for issues
|
|
37
48
|
|
|
38
49
|
```bash
|
|
@@ -111,19 +122,183 @@ envguard check
|
|
|
111
122
|
|
|
112
123
|
This is equivalent to `envguard scan --ci` and will exit with code 1 if issues are found.
|
|
113
124
|
|
|
114
|
-
|
|
125
|
+
## GitHub Actions Setup
|
|
126
|
+
|
|
127
|
+
EnvGuard integrates seamlessly with GitHub Actions to validate your environment variables on every pull request or push.
|
|
128
|
+
|
|
129
|
+
### Quick Setup (Recommended)
|
|
130
|
+
|
|
131
|
+
Create `.github/workflows/envguard.yml` in your repository:
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
name: Environment Variables Check
|
|
135
|
+
|
|
136
|
+
on:
|
|
137
|
+
pull_request:
|
|
138
|
+
branches: [main]
|
|
139
|
+
push:
|
|
140
|
+
branches: [main, develop]
|
|
141
|
+
|
|
142
|
+
jobs:
|
|
143
|
+
envguard:
|
|
144
|
+
runs-on: ubuntu-latest
|
|
145
|
+
|
|
146
|
+
steps:
|
|
147
|
+
- name: Checkout code
|
|
148
|
+
uses: actions/checkout@v4
|
|
149
|
+
|
|
150
|
+
- name: Setup Node.js
|
|
151
|
+
uses: actions/setup-node@v4
|
|
152
|
+
with:
|
|
153
|
+
node-version: '20.x'
|
|
154
|
+
|
|
155
|
+
- name: Run EnvGuard check
|
|
156
|
+
run: npx @danielszlaski/envguard scan --ci
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**That's it!** No installation needed - `npx` downloads EnvGuard on demand.
|
|
160
|
+
|
|
161
|
+
### Advanced Setup - With PR Comments
|
|
162
|
+
|
|
163
|
+
Get automatic comments on pull requests when issues are found:
|
|
115
164
|
|
|
116
165
|
```yaml
|
|
117
|
-
name:
|
|
118
|
-
|
|
166
|
+
name: Environment Variables Check
|
|
167
|
+
|
|
168
|
+
on:
|
|
169
|
+
pull_request:
|
|
170
|
+
branches: [main]
|
|
119
171
|
|
|
120
172
|
jobs:
|
|
121
173
|
envguard:
|
|
122
174
|
runs-on: ubuntu-latest
|
|
175
|
+
permissions:
|
|
176
|
+
pull-requests: write
|
|
177
|
+
|
|
178
|
+
steps:
|
|
179
|
+
- name: Checkout code
|
|
180
|
+
uses: actions/checkout@v4
|
|
181
|
+
|
|
182
|
+
- name: Setup Node.js
|
|
183
|
+
uses: actions/setup-node@v4
|
|
184
|
+
with:
|
|
185
|
+
node-version: '20.x'
|
|
186
|
+
|
|
187
|
+
- name: Run EnvGuard scan
|
|
188
|
+
id: envguard
|
|
189
|
+
continue-on-error: true
|
|
190
|
+
run: |
|
|
191
|
+
OUTPUT=$(npx @danielszlaski/envguard scan 2>&1)
|
|
192
|
+
echo "$OUTPUT"
|
|
193
|
+
echo "output<<EOF" >> $GITHUB_OUTPUT
|
|
194
|
+
echo "$OUTPUT" >> $GITHUB_OUTPUT
|
|
195
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
196
|
+
npx @danielszlaski/envguard scan --ci
|
|
197
|
+
|
|
198
|
+
- name: Comment on PR if failed
|
|
199
|
+
if: failure()
|
|
200
|
+
uses: actions/github-script@v7
|
|
201
|
+
with:
|
|
202
|
+
script: |
|
|
203
|
+
github.rest.issues.createComment({
|
|
204
|
+
issue_number: context.issue.number,
|
|
205
|
+
owner: context.repo.owner,
|
|
206
|
+
repo: context.repo.repo,
|
|
207
|
+
body: '## ⚠️ EnvGuard Check Failed\n\n```\n${{ steps.envguard.outputs.output }}\n```\n\nPlease run `npx @danielszlaski/envguard fix` locally to generate `.env.example` files, then commit the changes.'
|
|
208
|
+
})
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Strict Mode in CI
|
|
212
|
+
|
|
213
|
+
Enable strict mode to catch all variables including runtime-provided ones:
|
|
214
|
+
|
|
215
|
+
```yaml
|
|
216
|
+
- name: Run EnvGuard check (strict)
|
|
217
|
+
run: npx @danielszlaski/envguard scan --ci --strict
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Weekly Audit
|
|
221
|
+
|
|
222
|
+
Schedule weekly checks to catch configuration drift:
|
|
223
|
+
|
|
224
|
+
```yaml
|
|
225
|
+
name: Weekly Environment Audit
|
|
226
|
+
|
|
227
|
+
on:
|
|
228
|
+
schedule:
|
|
229
|
+
- cron: '0 9 * * MON' # Every Monday at 9am UTC
|
|
230
|
+
|
|
231
|
+
jobs:
|
|
232
|
+
audit:
|
|
233
|
+
runs-on: ubuntu-latest
|
|
234
|
+
|
|
235
|
+
steps:
|
|
236
|
+
- uses: actions/checkout@v4
|
|
237
|
+
- uses: actions/setup-node@v4
|
|
238
|
+
with:
|
|
239
|
+
node-version: '20.x'
|
|
240
|
+
- run: npx @danielszlaski/envguard scan --ci --strict
|
|
241
|
+
|
|
242
|
+
- name: Create issue if problems found
|
|
243
|
+
if: failure()
|
|
244
|
+
uses: actions/github-script@v7
|
|
245
|
+
with:
|
|
246
|
+
script: |
|
|
247
|
+
github.rest.issues.create({
|
|
248
|
+
owner: context.repo.owner,
|
|
249
|
+
repo: context.repo.repo,
|
|
250
|
+
title: '⚠️ Environment Variables Out of Sync',
|
|
251
|
+
body: 'Weekly EnvGuard audit found issues. Run `npx @danielszlaski/envguard scan` locally for details.',
|
|
252
|
+
labels: ['env-config', 'maintenance']
|
|
253
|
+
})
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Caching for Faster Runs
|
|
257
|
+
|
|
258
|
+
Speed up CI runs by caching npx downloads:
|
|
259
|
+
|
|
260
|
+
```yaml
|
|
261
|
+
- name: Setup Node.js
|
|
262
|
+
uses: actions/setup-node@v4
|
|
263
|
+
with:
|
|
264
|
+
node-version: '20.x'
|
|
265
|
+
cache: 'npm' # Caches npx downloads
|
|
266
|
+
|
|
267
|
+
- name: Run EnvGuard
|
|
268
|
+
run: npx @danielszlaski/envguard scan --ci
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Other CI Platforms
|
|
272
|
+
|
|
273
|
+
**GitLab CI** (`.gitlab-ci.yml`):
|
|
274
|
+
```yaml
|
|
275
|
+
envguard:
|
|
276
|
+
image: node:20
|
|
277
|
+
script:
|
|
278
|
+
- npx @danielszlaski/envguard scan --ci
|
|
279
|
+
only:
|
|
280
|
+
- merge_requests
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**CircleCI** (`.circleci/config.yml`):
|
|
284
|
+
```yaml
|
|
285
|
+
version: 2.1
|
|
286
|
+
jobs:
|
|
287
|
+
envguard:
|
|
288
|
+
docker:
|
|
289
|
+
- image: cimg/node:20.0
|
|
123
290
|
steps:
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
|
|
291
|
+
- checkout
|
|
292
|
+
- run: npx @danielszlaski/envguard scan --ci
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Travis CI** (`.travis.yml`):
|
|
296
|
+
```yaml
|
|
297
|
+
language: node_js
|
|
298
|
+
node_js:
|
|
299
|
+
- '20'
|
|
300
|
+
script:
|
|
301
|
+
- npx @danielszlaski/envguard scan --ci
|
|
127
302
|
```
|
|
128
303
|
|
|
129
304
|
## Supported Languages & Frameworks
|
|
@@ -166,6 +341,7 @@ Create a `.envguardrc.json` file in your project root to customize behavior:
|
|
|
166
341
|
"COMPANY_INTERNAL_VAR"
|
|
167
342
|
],
|
|
168
343
|
"strict": false,
|
|
344
|
+
"detectFallbacks": true,
|
|
169
345
|
"exclude": [
|
|
170
346
|
"**/build/**",
|
|
171
347
|
"**/tmp/**"
|
|
@@ -177,6 +353,7 @@ Create a `.envguardrc.json` file in your project root to customize behavior:
|
|
|
177
353
|
|
|
178
354
|
- `ignoreVars` (string[]): Custom environment variables to ignore in non-strict mode. These will be treated like AWS_REGION and won't trigger warnings.
|
|
179
355
|
- `strict` (boolean): Enable strict mode by default (can be overridden with CLI flag)
|
|
356
|
+
- `detectFallbacks` (boolean): Detect fallback patterns in code and treat them as warnings instead of errors (default: `true`)
|
|
180
357
|
- `exclude` (string[]): Additional file patterns to exclude from scanning
|
|
181
358
|
|
|
182
359
|
**Alternative: package.json**
|
|
@@ -203,6 +380,62 @@ You can also add configuration to your `package.json`:
|
|
|
203
380
|
**GitHub Apps & CI/CD:**
|
|
204
381
|
When using EnvGuard as a GitHub App or in CI/CD pipelines, commit your `.envguardrc.json` to the repository. This ensures consistent behavior across all environments and team members.
|
|
205
382
|
|
|
383
|
+
### Fallback Detection (Smart Severity)
|
|
384
|
+
|
|
385
|
+
EnvGuard automatically detects common defensive patterns in your code and adjusts issue severity accordingly. When a variable is used with a fallback or default value, it's treated as a **WARNING** instead of an **ERROR**.
|
|
386
|
+
|
|
387
|
+
**Detected patterns:**
|
|
388
|
+
|
|
389
|
+
```javascript
|
|
390
|
+
// Default values with || or ??
|
|
391
|
+
const port = process.env.PORT || 3000; // WARNING
|
|
392
|
+
const url = process.env.API_URL ?? 'localhost'; // WARNING
|
|
393
|
+
|
|
394
|
+
// Ternary operators
|
|
395
|
+
const env = process.env.NODE_ENV ? 'set' : 'dev'; // WARNING
|
|
396
|
+
|
|
397
|
+
// Conditional checks
|
|
398
|
+
if (process.env.FEATURE_FLAG) { } // WARNING
|
|
399
|
+
if (!process.env.DEBUG) { } // WARNING
|
|
400
|
+
|
|
401
|
+
// Destructuring with defaults
|
|
402
|
+
const { LOG_LEVEL = 'info' } = process.env; // WARNING
|
|
403
|
+
|
|
404
|
+
// Optional chaining
|
|
405
|
+
const value = process.env?.OPTIONAL_VAR; // WARNING
|
|
406
|
+
|
|
407
|
+
// No fallback - strict requirement
|
|
408
|
+
const apiKey = process.env.API_KEY; // ERROR
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**Severity levels:**
|
|
412
|
+
|
|
413
|
+
- **ERROR** (✖): Variable used without any safety mechanism - likely to cause runtime errors
|
|
414
|
+
- **WARNING** (⚠): Variable used with fallback/default - code handles missing values
|
|
415
|
+
- **INFO** (ℹ): Unused variables or optional documentation issues
|
|
416
|
+
|
|
417
|
+
**Disable fallback detection:**
|
|
418
|
+
|
|
419
|
+
If you prefer all missing variables to be treated as errors regardless of fallbacks:
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
# CLI flag
|
|
423
|
+
envguard scan --no-detect-fallbacks
|
|
424
|
+
|
|
425
|
+
# Config file
|
|
426
|
+
{
|
|
427
|
+
"detectFallbacks": false
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Why this feature exists:**
|
|
432
|
+
|
|
433
|
+
Not all missing environment variables are equal. Variables with defensive fallbacks are less critical than those that will cause `undefined` errors. This feature helps you prioritize what to fix first while still being aware of all env var usage.
|
|
434
|
+
|
|
435
|
+
**Limitations:**
|
|
436
|
+
|
|
437
|
+
Fallback detection uses regex patterns and catches common cases (~80% of real-world usage). Complex patterns like function calls with fallbacks or deeply nested conditionals may not be detected. For strict validation, use `--no-detect-fallbacks` or set `detectFallbacks: false` in your config.
|
|
438
|
+
|
|
206
439
|
### Monorepo Support
|
|
207
440
|
|
|
208
441
|
EnvGuard automatically detects all `.env` files in your project, including subdirectories. When you run `envguard fix`, it creates a `.env.example` file next to each `.env` file it finds.
|
|
@@ -276,9 +509,11 @@ Checking src/lambda/serverless.yml
|
|
|
276
509
|
- `envguard scan` - Scan for issues and display report
|
|
277
510
|
- `envguard scan --ci` - Scan and exit with error code if issues found
|
|
278
511
|
- `envguard scan --strict` - Report all variables including known runtime variables
|
|
512
|
+
- `envguard scan --no-detect-fallbacks` - Treat all missing variables as errors (ignore fallback detection)
|
|
279
513
|
- `envguard fix` - Auto-generate `.env.example`
|
|
280
514
|
- `envguard check` - Alias for `scan --ci`
|
|
281
515
|
- `envguard check --strict` - Check with strict mode enabled
|
|
516
|
+
- `envguard check --no-detect-fallbacks` - Check without fallback detection
|
|
282
517
|
|
|
283
518
|
### Strict Mode
|
|
284
519
|
|
|
@@ -318,4 +553,4 @@ npm start scan
|
|
|
318
553
|
|
|
319
554
|
## License
|
|
320
555
|
|
|
321
|
-
MIT
|
|
556
|
+
MIT 2026 Daniel Szlaski
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { ScanResult } from '../types';
|
|
2
2
|
import { EnvEntry } from '../parser/envParser';
|
|
3
3
|
export declare class EnvAnalyzer {
|
|
4
|
-
analyze(usedVars: Map<string,
|
|
5
|
-
|
|
4
|
+
analyze(usedVars: Map<string, {
|
|
5
|
+
locations: string[];
|
|
6
|
+
hasFallback: boolean;
|
|
7
|
+
}>, definedVars: Map<string, EnvEntry>, exampleVars: Set<string>, detectFallbacks?: boolean): ScanResult;
|
|
8
|
+
generateExampleContent(usedVars: Map<string, {
|
|
9
|
+
locations: string[];
|
|
10
|
+
hasFallback: boolean;
|
|
11
|
+
}>, existingEntries: Map<string, EnvEntry>): string;
|
|
6
12
|
private getFormatHint;
|
|
7
13
|
}
|
|
8
14
|
//# sourceMappingURL=envAnalyzer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/envAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,qBAAa,WAAW;IACtB,OAAO,CACL,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"envAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/envAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,qBAAa,WAAW;IACtB,OAAO,CACL,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC,EACpE,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAClC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,eAAe,GAAE,OAAc,GAC9B,UAAU;IA6Db,sBAAsB,CACpB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC,EACpE,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GACrC,MAAM;IA0CT,OAAO,CAAC,aAAa;CAkCtB"}
|
|
@@ -2,16 +2,22 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EnvAnalyzer = void 0;
|
|
4
4
|
class EnvAnalyzer {
|
|
5
|
-
analyze(usedVars, definedVars, exampleVars) {
|
|
5
|
+
analyze(usedVars, definedVars, exampleVars, detectFallbacks = true) {
|
|
6
6
|
const issues = [];
|
|
7
7
|
// Issue 1: Variables used in code but missing from .env
|
|
8
|
-
for (const [varName,
|
|
8
|
+
for (const [varName, usage] of usedVars.entries()) {
|
|
9
9
|
if (!definedVars.has(varName)) {
|
|
10
|
+
// If detectFallbacks is enabled and variable has a fallback, it's a WARNING, otherwise ERROR
|
|
11
|
+
const severity = (detectFallbacks && usage.hasFallback) ? 'warning' : 'error';
|
|
12
|
+
const details = (detectFallbacks && usage.hasFallback)
|
|
13
|
+
? `Used in code with fallback/default but not defined in .env`
|
|
14
|
+
: `Used in code but not defined in .env`;
|
|
10
15
|
issues.push({
|
|
11
16
|
type: 'missing',
|
|
17
|
+
severity,
|
|
12
18
|
varName,
|
|
13
|
-
details
|
|
14
|
-
locations,
|
|
19
|
+
details,
|
|
20
|
+
locations: usage.locations,
|
|
15
21
|
});
|
|
16
22
|
}
|
|
17
23
|
}
|
|
@@ -20,19 +26,26 @@ class EnvAnalyzer {
|
|
|
20
26
|
if (!usedVars.has(varName)) {
|
|
21
27
|
issues.push({
|
|
22
28
|
type: 'unused',
|
|
29
|
+
severity: 'info',
|
|
23
30
|
varName,
|
|
24
31
|
details: `Defined in .env but never used in code`,
|
|
25
32
|
});
|
|
26
33
|
}
|
|
27
34
|
}
|
|
28
35
|
// Issue 3: Variables used in code but not in .env.example
|
|
29
|
-
for (const [varName,
|
|
36
|
+
for (const [varName, usage] of usedVars.entries()) {
|
|
30
37
|
if (!exampleVars.has(varName)) {
|
|
38
|
+
// If detectFallbacks is enabled and variable has a fallback, it's less critical for documentation
|
|
39
|
+
const severity = (detectFallbacks && usage.hasFallback) ? 'info' : 'warning';
|
|
40
|
+
const details = (detectFallbacks && usage.hasFallback)
|
|
41
|
+
? `Used in code with fallback but missing from .env.example`
|
|
42
|
+
: `Used in code but missing from .env.example`;
|
|
31
43
|
issues.push({
|
|
32
44
|
type: 'undocumented',
|
|
45
|
+
severity,
|
|
33
46
|
varName,
|
|
34
|
-
details
|
|
35
|
-
locations,
|
|
47
|
+
details,
|
|
48
|
+
locations: usage.locations,
|
|
36
49
|
});
|
|
37
50
|
}
|
|
38
51
|
}
|
|
@@ -48,7 +61,8 @@ class EnvAnalyzer {
|
|
|
48
61
|
content += '# Do not put actual secrets in this file - use .env instead\n\n';
|
|
49
62
|
const sortedVars = Array.from(usedVars.keys()).sort();
|
|
50
63
|
for (const varName of sortedVars) {
|
|
51
|
-
const
|
|
64
|
+
const usage = usedVars.get(varName);
|
|
65
|
+
const locations = usage.locations;
|
|
52
66
|
const existingEntry = existingEntries.get(varName);
|
|
53
67
|
// Add location comments
|
|
54
68
|
content += `# Used in: ${locations.slice(0, 3).join(', ')}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/envAnalyzer.ts"],"names":[],"mappings":";;;AAGA,MAAa,WAAW;IACtB,OAAO,CACL,
|
|
1
|
+
{"version":3,"file":"envAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/envAnalyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -15,8 +15,20 @@ program
|
|
|
15
15
|
.description('Scan codebase and compare with .env files')
|
|
16
16
|
.option('--ci', 'Exit with error code if issues found (for CI/CD)')
|
|
17
17
|
.option('--strict', 'Report all variables including known runtime variables (AWS_REGION, NODE_ENV, etc.)')
|
|
18
|
-
.
|
|
18
|
+
.option('--no-detect-fallbacks', 'Treat all missing variables as errors, ignoring fallback detection')
|
|
19
|
+
.action(async (cmd, command) => {
|
|
19
20
|
try {
|
|
21
|
+
// Build options object, only including detectFallbacks if the flag was used
|
|
22
|
+
const options = {
|
|
23
|
+
ci: cmd.ci,
|
|
24
|
+
strict: cmd.strict
|
|
25
|
+
};
|
|
26
|
+
// Check if the --no-detect-fallbacks flag was explicitly provided
|
|
27
|
+
// Commander adds it to the command's options when the flag is used
|
|
28
|
+
const flagProvided = command.parent?.rawArgs.some((arg) => arg.includes('detect-fallback'));
|
|
29
|
+
if (flagProvided) {
|
|
30
|
+
options.detectFallbacks = cmd.detectFallbacks;
|
|
31
|
+
}
|
|
20
32
|
await (0, scan_1.scanCommand)(options);
|
|
21
33
|
}
|
|
22
34
|
catch (error) {
|
|
@@ -40,9 +52,19 @@ program
|
|
|
40
52
|
.command('check')
|
|
41
53
|
.description('Check for issues (alias for scan --ci)')
|
|
42
54
|
.option('--strict', 'Report all variables including known runtime variables (AWS_REGION, NODE_ENV, etc.)')
|
|
43
|
-
.
|
|
55
|
+
.option('--no-detect-fallbacks', 'Treat all missing variables as errors, ignoring fallback detection')
|
|
56
|
+
.action(async (cmd, command) => {
|
|
44
57
|
try {
|
|
45
|
-
|
|
58
|
+
const options = {
|
|
59
|
+
ci: true,
|
|
60
|
+
strict: cmd.strict
|
|
61
|
+
};
|
|
62
|
+
// Check if the --no-detect-fallbacks flag was explicitly provided
|
|
63
|
+
const flagProvided = command.parent?.rawArgs.some((arg) => arg.includes('detect-fallback'));
|
|
64
|
+
if (flagProvided) {
|
|
65
|
+
options.detectFallbacks = cmd.detectFallbacks;
|
|
66
|
+
}
|
|
67
|
+
await (0, scan_1.scanCommand)(options);
|
|
46
68
|
}
|
|
47
69
|
catch (error) {
|
|
48
70
|
logger_1.Logger.error(`${error}`);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,0CAA8C;AAC9C,wCAA4C;AAE5C,2CAAwC;AAExC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CAAC,MAAM,EAAE,kDAAkD,CAAC;KAClE,MAAM,CAAC,UAAU,EAAE,qFAAqF,CAAC;KACzG,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,0CAA8C;AAC9C,wCAA4C;AAE5C,2CAAwC;AAExC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CAAC,MAAM,EAAE,kDAAkD,CAAC;KAClE,MAAM,CAAC,UAAU,EAAE,qFAAqF,CAAC;KACzG,MAAM,CAAC,uBAAuB,EAAE,oEAAoE,CAAC;KACrG,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAC7B,IAAI,CAAC;QACH,4EAA4E;QAC5E,MAAM,OAAO,GAAQ;YACnB,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB,CAAC;QAEF,kEAAkE;QAClE,mEAAmE;QACnE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACpG,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;QAChD,CAAC;QAED,MAAM,IAAA,kBAAW,EAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,IAAA,gBAAU,GAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,UAAU,EAAE,qFAAqF,CAAC;KACzG,MAAM,CAAC,uBAAuB,EAAE,oEAAoE,CAAC;KACrG,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAC7B,IAAI,CAAC;QACH,MAAM,OAAO,GAAQ;YACnB,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB,CAAC;QAEF,kEAAkE;QAClE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACpG,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;QAChD,CAAC;QAED,MAAM,IAAA,kBAAW,EAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"AAOA,wBAAsB,UAAU;;
|
|
1
|
+
{"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"AAOA,wBAAsB,UAAU;;GAiG/B"}
|
package/dist/commands/fix.js
CHANGED
|
@@ -43,8 +43,18 @@ const logger_1 = require("../utils/logger");
|
|
|
43
43
|
async function fixCommand() {
|
|
44
44
|
const rootDir = process.cwd();
|
|
45
45
|
logger_1.Logger.startSpinner('Generating .env.example files...');
|
|
46
|
+
// Load configuration
|
|
47
|
+
const { ConfigLoader } = require('../config/configLoader');
|
|
48
|
+
const config = ConfigLoader.loadConfig(rootDir);
|
|
46
49
|
// Step 1: Find all .env files
|
|
47
|
-
const
|
|
50
|
+
const excludePatterns = [
|
|
51
|
+
'node_modules',
|
|
52
|
+
'dist',
|
|
53
|
+
'build',
|
|
54
|
+
'.git',
|
|
55
|
+
...(config.exclude || []),
|
|
56
|
+
];
|
|
57
|
+
const scanner = new codeScanner_1.CodeScanner(rootDir, excludePatterns);
|
|
48
58
|
const envFiles = await scanner.findEnvFiles();
|
|
49
59
|
logger_1.Logger.stopSpinner();
|
|
50
60
|
if (envFiles.length === 0) {
|
|
@@ -64,7 +74,18 @@ async function fixCommand() {
|
|
|
64
74
|
const displayPath = relativePath || '.';
|
|
65
75
|
logger_1.Logger.path(`Processing ${displayPath}/`);
|
|
66
76
|
// Step 3: Scan code files in this directory and subdirectories
|
|
67
|
-
const
|
|
77
|
+
const allUsedVars = await scanDirectoryForVars(rootDir, envDir, scanner, config.exclude);
|
|
78
|
+
// Filter out ignored variables based on config (they shouldn't be in .env.example)
|
|
79
|
+
const { isKnownRuntimeVar } = require('../constants/knownEnvVars');
|
|
80
|
+
const usedVars = new Map();
|
|
81
|
+
for (const [varName, usage] of allUsedVars.entries()) {
|
|
82
|
+
const isCustomIgnored = ConfigLoader.shouldIgnoreVar(varName, config);
|
|
83
|
+
const isRuntimeVar = isKnownRuntimeVar(varName);
|
|
84
|
+
// Skip known runtime variables and custom ignore vars
|
|
85
|
+
if (!isRuntimeVar && !isCustomIgnored) {
|
|
86
|
+
usedVars.set(varName, usage);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
68
89
|
if (usedVars.size === 0) {
|
|
69
90
|
logger_1.Logger.info('No environment variables found in code', true);
|
|
70
91
|
logger_1.Logger.blank();
|
|
@@ -93,25 +114,29 @@ async function fixCommand() {
|
|
|
93
114
|
logger_1.Logger.summary(`Generated ${envFiles.length} .env.example file(s) with ${totalVars} total variables`);
|
|
94
115
|
return { success: true };
|
|
95
116
|
}
|
|
96
|
-
async function scanDirectoryForVars(rootDir, targetDir, scanner) {
|
|
117
|
+
async function scanDirectoryForVars(rootDir, targetDir, scanner, excludePatterns = []) {
|
|
97
118
|
const envVars = new Map();
|
|
98
119
|
const { glob } = require('glob');
|
|
99
120
|
// Find all code files in this directory and subdirectories
|
|
100
121
|
const relativeDir = path.relative(rootDir, targetDir);
|
|
101
122
|
const pattern = relativeDir ? `${relativeDir}/**/*.{js,ts,jsx,tsx,mjs,cjs}` : '**/*.{js,ts,jsx,tsx,mjs,cjs}';
|
|
123
|
+
const defaultIgnore = ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**'];
|
|
124
|
+
const customIgnore = excludePatterns.map(p => p.includes('*') ? p : `**/${p}/**`);
|
|
102
125
|
const files = await glob(pattern, {
|
|
103
126
|
cwd: rootDir,
|
|
104
|
-
ignore: [
|
|
127
|
+
ignore: [...defaultIgnore, ...customIgnore],
|
|
105
128
|
absolute: true,
|
|
106
129
|
});
|
|
107
130
|
for (const file of files) {
|
|
108
131
|
const vars = await scanner.scanFile(file);
|
|
109
|
-
for (const varName of vars) {
|
|
132
|
+
for (const [varName, hasFallback] of vars.entries()) {
|
|
110
133
|
const relativePath = path.relative(rootDir, file);
|
|
111
134
|
if (!envVars.has(varName)) {
|
|
112
|
-
envVars.set(varName, []);
|
|
135
|
+
envVars.set(varName, { locations: [], hasFallback: false });
|
|
113
136
|
}
|
|
114
|
-
envVars.get(varName)
|
|
137
|
+
const entry = envVars.get(varName);
|
|
138
|
+
entry.locations.push(relativePath);
|
|
139
|
+
entry.hasFallback = entry.hasFallback || hasFallback;
|
|
115
140
|
}
|
|
116
141
|
}
|
|
117
142
|
return envVars;
|
package/dist/commands/fix.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,
|
|
1
|
+
{"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,gCAiGC;AAxGD,2CAA6B;AAC7B,uCAAyB;AACzB,wDAAqD;AACrD,mDAAgD;AAChD,yDAAsD;AACtD,4CAAyC;AAElC,KAAK,UAAU,UAAU;IAC9B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE9B,eAAM,CAAC,YAAY,CAAC,kCAAkC,CAAC,CAAC;IAExD,qBAAqB;IACrB,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAEhD,8BAA8B;IAC9B,MAAM,eAAe,GAAG;QACtB,cAAc;QACd,MAAM;QACN,OAAO;QACP,MAAM;QACN,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;KAC1B,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,yBAAW,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;IAE9C,eAAM,CAAC,WAAW,EAAE,CAAC;IAErB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,eAAM,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;QACrD,eAAM,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,eAAM,CAAC,OAAO,CAAC,SAAS,QAAQ,CAAC,MAAM,eAAe,CAAC,CAAC;IACxD,eAAM,CAAC,KAAK,EAAE,CAAC;IAEf,MAAM,MAAM,GAAG,IAAI,qBAAS,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,IAAI,yBAAW,EAAE,CAAC;IACnC,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,iCAAiC;IACjC,KAAK,MAAM,WAAW,IAAI,QAAQ,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,YAAY,IAAI,GAAG,CAAC;QAExC,eAAM,CAAC,IAAI,CAAC,cAAc,WAAW,GAAG,CAAC,CAAC;QAE1C,+DAA+D;QAC/D,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAEzF,mFAAmF;QACnF,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyD,CAAC;QAElF,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YACrD,MAAM,eAAe,GAAG,YAAY,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACtE,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAEhD,sDAAsD;YACtD,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,EAAE,CAAC;gBACtC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACxB,eAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE,IAAI,CAAC,CAAC;YAC5D,eAAM,CAAC,KAAK,EAAE,CAAC;YACf,SAAS;QACX,CAAC;QAED,eAAM,CAAC,OAAO,CAAC,SAAS,QAAQ,CAAC,IAAI,qCAAqC,EAAE,IAAI,CAAC,CAAC;QAClF,eAAM,CAAC,KAAK,EAAE,CAAC;QAEf,2DAA2D;QAC3D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QACtD,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAElD,4CAA4C;QAC5C,MAAM,UAAU,GAAG,QAAQ,CAAC,sBAAsB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QAE9E,gCAAgC;QAChC,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAEnD,eAAM,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACzE,eAAM,CAAC,KAAK,EAAE,CAAC;QAEf,SAAS,IAAI,QAAQ,CAAC,IAAI,CAAC;QAE3B,0CAA0C;QAC1C,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,eAAM,CAAC,OAAO,CAAC,sBAAsB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACxE,eAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,eAAM,CAAC,OAAO,CAAC,aAAa,QAAQ,CAAC,MAAM,8BAA8B,SAAS,kBAAkB,CAAC,CAAC;IAEtG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,OAAe,EACf,SAAiB,EACjB,OAAoB,EACpB,kBAA4B,EAAE;IAE9B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyD,CAAC;IACjF,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEjC,2DAA2D;IAC3D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,+BAA+B,CAAC,CAAC,CAAC,8BAA8B,CAAC;IAE7G,MAAM,aAAa,GAAG,CAAC,oBAAoB,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;IACxF,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAElF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;QAChC,GAAG,EAAE,OAAO;QACZ,MAAM,EAAE,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC;QAC3C,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,MAAO,OAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAClD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC;YACpC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,WAAW,CAAC;QACvD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/commands/scan.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAKjC,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,EAAE,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE;;;
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAKjC,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,EAAE,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE;;;GAgVvG"}
|