guardrail-cli 1.0.6 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +483 -10
- package/dist/commands/baseline.d.ts +7 -0
- package/dist/commands/baseline.d.ts.map +1 -0
- package/dist/commands/baseline.js +79 -0
- package/dist/commands/baseline.js.map +1 -0
- package/dist/commands/cache.d.ts +13 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +165 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/evidence.d.ts +45 -0
- package/dist/commands/evidence.d.ts.map +1 -0
- package/dist/commands/evidence.js +197 -0
- package/dist/commands/evidence.js.map +1 -0
- package/dist/commands/index.d.ts +8 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +15 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/scan-secrets.d.ts +47 -0
- package/dist/commands/scan-secrets.d.ts.map +1 -0
- package/dist/commands/scan-secrets.js +225 -0
- package/dist/commands/scan-secrets.js.map +1 -0
- package/dist/commands/scan-vulnerabilities-enhanced.d.ts +41 -0
- package/dist/commands/scan-vulnerabilities-enhanced.d.ts.map +1 -0
- package/dist/commands/scan-vulnerabilities-enhanced.js +368 -0
- package/dist/commands/scan-vulnerabilities-enhanced.js.map +1 -0
- package/dist/commands/scan-vulnerabilities-osv.d.ts +58 -0
- package/dist/commands/scan-vulnerabilities-osv.d.ts.map +1 -0
- package/dist/commands/scan-vulnerabilities-osv.js +716 -0
- package/dist/commands/scan-vulnerabilities-osv.js.map +1 -0
- package/dist/commands/scan-vulnerabilities.d.ts +32 -0
- package/dist/commands/scan-vulnerabilities.d.ts.map +1 -0
- package/dist/commands/scan-vulnerabilities.js +283 -0
- package/dist/commands/scan-vulnerabilities.js.map +1 -0
- package/dist/commands/secrets-allowlist.d.ts +7 -0
- package/dist/commands/secrets-allowlist.d.ts.map +1 -0
- package/dist/commands/secrets-allowlist.js +85 -0
- package/dist/commands/secrets-allowlist.js.map +1 -0
- package/dist/fix/applicator.d.ts +44 -0
- package/dist/fix/applicator.d.ts.map +1 -0
- package/dist/fix/applicator.js +144 -0
- package/dist/fix/applicator.js.map +1 -0
- package/dist/fix/backup.d.ts +38 -0
- package/dist/fix/backup.d.ts.map +1 -0
- package/dist/fix/backup.js +154 -0
- package/dist/fix/backup.js.map +1 -0
- package/dist/fix/engine.d.ts +55 -0
- package/dist/fix/engine.d.ts.map +1 -0
- package/dist/fix/engine.js +285 -0
- package/dist/fix/engine.js.map +1 -0
- package/dist/fix/index.d.ts +5 -0
- package/dist/fix/index.d.ts.map +1 -0
- package/dist/fix/index.js +12 -0
- package/dist/fix/index.js.map +1 -0
- package/dist/fix/interactive.d.ts +22 -0
- package/dist/fix/interactive.d.ts.map +1 -0
- package/dist/fix/interactive.js +172 -0
- package/dist/fix/interactive.js.map +1 -0
- package/dist/formatters/index.d.ts +6 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +11 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/sarif-enhanced.d.ts +78 -0
- package/dist/formatters/sarif-enhanced.d.ts.map +1 -0
- package/dist/formatters/sarif-enhanced.js +144 -0
- package/dist/formatters/sarif-enhanced.js.map +1 -0
- package/dist/formatters/sarif-v2.d.ts +121 -0
- package/dist/formatters/sarif-v2.d.ts.map +1 -0
- package/dist/formatters/sarif-v2.js +356 -0
- package/dist/formatters/sarif-v2.js.map +1 -0
- package/dist/formatters/sarif.d.ts +72 -0
- package/dist/formatters/sarif.d.ts.map +1 -0
- package/dist/formatters/sarif.js +146 -0
- package/dist/formatters/sarif.js.map +1 -0
- package/dist/index.js +3362 -1397
- package/dist/index.js.map +1 -1
- package/dist/init/ci-generator.d.ts +18 -0
- package/dist/init/ci-generator.d.ts.map +1 -0
- package/dist/init/ci-generator.js +251 -0
- package/dist/init/ci-generator.js.map +1 -0
- package/dist/init/detect-framework.d.ts +15 -0
- package/dist/init/detect-framework.d.ts.map +1 -0
- package/dist/init/detect-framework.js +299 -0
- package/dist/init/detect-framework.js.map +1 -0
- package/dist/init/hooks-installer.d.ts +22 -0
- package/dist/init/hooks-installer.d.ts.map +1 -0
- package/dist/init/hooks-installer.js +302 -0
- package/dist/init/hooks-installer.js.map +1 -0
- package/dist/init/index.d.ts +8 -0
- package/dist/init/index.d.ts.map +1 -0
- package/dist/init/index.js +22 -0
- package/dist/init/index.js.map +1 -0
- package/dist/init/templates.d.ts +401 -0
- package/dist/init/templates.d.ts.map +1 -0
- package/dist/init/templates.js +240 -0
- package/dist/init/templates.js.map +1 -0
- package/dist/reality/reality-runner.d.ts +76 -0
- package/dist/reality/reality-runner.d.ts.map +1 -0
- package/dist/reality/reality-runner.js +454 -0
- package/dist/reality/reality-runner.js.map +1 -0
- package/dist/runtime/auth-utils.d.ts +43 -0
- package/dist/runtime/auth-utils.d.ts.map +1 -0
- package/dist/runtime/auth-utils.js +126 -0
- package/dist/runtime/auth-utils.js.map +1 -0
- package/dist/runtime/client.d.ts +74 -0
- package/dist/runtime/client.d.ts.map +1 -0
- package/dist/runtime/client.js +222 -0
- package/dist/runtime/client.js.map +1 -0
- package/dist/runtime/creds.d.ts +48 -0
- package/dist/runtime/creds.d.ts.map +1 -0
- package/dist/runtime/creds.js +245 -0
- package/dist/runtime/creds.js.map +1 -0
- package/dist/runtime/exit-codes.d.ts +47 -0
- package/dist/runtime/exit-codes.d.ts.map +1 -0
- package/dist/runtime/exit-codes.js +91 -0
- package/dist/runtime/exit-codes.js.map +1 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +25 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/semver.d.ts +37 -0
- package/dist/runtime/semver.d.ts.map +1 -0
- package/dist/runtime/semver.js +110 -0
- package/dist/runtime/semver.js.map +1 -0
- package/dist/scanner/baseline.d.ts +52 -0
- package/dist/scanner/baseline.d.ts.map +1 -0
- package/dist/scanner/baseline.js +85 -0
- package/dist/scanner/baseline.js.map +1 -0
- package/dist/scanner/incremental.d.ts +30 -0
- package/dist/scanner/incremental.d.ts.map +1 -0
- package/dist/scanner/incremental.js +82 -0
- package/dist/scanner/incremental.js.map +1 -0
- package/dist/scanner/parallel.d.ts +43 -0
- package/dist/scanner/parallel.d.ts.map +1 -0
- package/dist/scanner/parallel.js +99 -0
- package/dist/scanner/parallel.js.map +1 -0
- package/dist/ui/frame.d.ts +68 -0
- package/dist/ui/frame.d.ts.map +1 -0
- package/dist/ui/frame.js +165 -0
- package/dist/ui/frame.js.map +1 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +16 -0
- package/dist/ui/index.js.map +1 -0
- package/package.json +42 -9
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CI Workflow Generator
|
|
4
|
+
* Generates working GitHub Actions workflows with SARIF upload support
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.generateCIWorkflow = generateCIWorkflow;
|
|
8
|
+
exports.getCIProviderFromProject = getCIProviderFromProject;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
function generateGitHubActionsWorkflow(config) {
|
|
12
|
+
const useSarif = config.output.format === 'sarif' || config.output.sarifUpload;
|
|
13
|
+
const runCompliance = config.scans.compliance.enabled;
|
|
14
|
+
const runSbom = config.scans.sbom?.enabled;
|
|
15
|
+
const workflow = `name: Guardrail Security Scan
|
|
16
|
+
|
|
17
|
+
on:
|
|
18
|
+
push:
|
|
19
|
+
branches: [main, master, develop]
|
|
20
|
+
pull_request:
|
|
21
|
+
branches: [main, master, develop]
|
|
22
|
+
workflow_dispatch:
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
security-events: write
|
|
27
|
+
actions: read
|
|
28
|
+
|
|
29
|
+
jobs:
|
|
30
|
+
guardrail-scan:
|
|
31
|
+
name: Security Scan
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
steps:
|
|
34
|
+
- name: Checkout code
|
|
35
|
+
uses: actions/checkout@v4
|
|
36
|
+
with:
|
|
37
|
+
fetch-depth: 0
|
|
38
|
+
|
|
39
|
+
- name: Setup Node.js
|
|
40
|
+
uses: actions/setup-node@v4
|
|
41
|
+
with:
|
|
42
|
+
node-version: '20'
|
|
43
|
+
cache: 'npm'
|
|
44
|
+
|
|
45
|
+
- name: Install dependencies
|
|
46
|
+
run: npm ci --ignore-scripts
|
|
47
|
+
|
|
48
|
+
- name: Install Guardrail CLI
|
|
49
|
+
run: npm install -g guardrail-cli
|
|
50
|
+
|
|
51
|
+
- name: Run Secrets Scan
|
|
52
|
+
id: secrets
|
|
53
|
+
run: |
|
|
54
|
+
guardrail scan:secrets \\
|
|
55
|
+
--path . \\
|
|
56
|
+
--format ${useSarif ? 'sarif' : 'json'} \\
|
|
57
|
+
${useSarif ? '--output secrets-results.sarif' : '--output secrets-results.json'} \\
|
|
58
|
+
--exit-code
|
|
59
|
+
env:
|
|
60
|
+
GUARDRAIL_API_KEY: \${{ secrets.GUARDRAIL_API_KEY }}
|
|
61
|
+
continue-on-error: true
|
|
62
|
+
|
|
63
|
+
- name: Run Vulnerability Scan
|
|
64
|
+
id: vulns
|
|
65
|
+
run: |
|
|
66
|
+
guardrail scan:vulnerabilities \\
|
|
67
|
+
--path . \\
|
|
68
|
+
--format ${useSarif ? 'sarif' : 'json'} \\
|
|
69
|
+
${useSarif ? '--output vuln-results.sarif' : '--output vuln-results.json'} \\
|
|
70
|
+
--exit-code
|
|
71
|
+
env:
|
|
72
|
+
GUARDRAIL_API_KEY: \${{ secrets.GUARDRAIL_API_KEY }}
|
|
73
|
+
continue-on-error: true
|
|
74
|
+
${runCompliance ? `
|
|
75
|
+
- name: Run Compliance Scan
|
|
76
|
+
id: compliance
|
|
77
|
+
run: |
|
|
78
|
+
guardrail scan:compliance \\
|
|
79
|
+
--path . \\
|
|
80
|
+
--framework ${config.scans.compliance.frameworks?.[0] || 'soc2'} \\
|
|
81
|
+
--format json \\
|
|
82
|
+
--output compliance-results.json \\
|
|
83
|
+
--exit-code
|
|
84
|
+
env:
|
|
85
|
+
GUARDRAIL_API_KEY: \${{ secrets.GUARDRAIL_API_KEY }}
|
|
86
|
+
continue-on-error: true
|
|
87
|
+
` : ''}${runSbom ? `
|
|
88
|
+
- name: Generate SBOM
|
|
89
|
+
id: sbom
|
|
90
|
+
run: |
|
|
91
|
+
guardrail sbom:generate \\
|
|
92
|
+
--path . \\
|
|
93
|
+
--format cyclonedx \\
|
|
94
|
+
--output sbom.json
|
|
95
|
+
env:
|
|
96
|
+
GUARDRAIL_API_KEY: \${{ secrets.GUARDRAIL_API_KEY }}
|
|
97
|
+
continue-on-error: true
|
|
98
|
+
` : ''}
|
|
99
|
+
- name: Run Ship Check
|
|
100
|
+
id: ship
|
|
101
|
+
run: |
|
|
102
|
+
guardrail ship \\
|
|
103
|
+
--path . \\
|
|
104
|
+
--format json \\
|
|
105
|
+
--output ship-results.json
|
|
106
|
+
env:
|
|
107
|
+
GUARDRAIL_API_KEY: \${{ secrets.GUARDRAIL_API_KEY }}
|
|
108
|
+
continue-on-error: true
|
|
109
|
+
${useSarif ? `
|
|
110
|
+
- name: Upload Secrets SARIF to GitHub Security
|
|
111
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
112
|
+
if: always() && hashFiles('secrets-results.sarif') != ''
|
|
113
|
+
with:
|
|
114
|
+
sarif_file: secrets-results.sarif
|
|
115
|
+
category: guardrail-secrets
|
|
116
|
+
|
|
117
|
+
- name: Upload Vulnerability SARIF to GitHub Security
|
|
118
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
119
|
+
if: always() && hashFiles('vuln-results.sarif') != ''
|
|
120
|
+
with:
|
|
121
|
+
sarif_file: vuln-results.sarif
|
|
122
|
+
category: guardrail-vulnerabilities
|
|
123
|
+
` : ''}
|
|
124
|
+
- name: Upload Scan Artifacts
|
|
125
|
+
uses: actions/upload-artifact@v4
|
|
126
|
+
if: always()
|
|
127
|
+
with:
|
|
128
|
+
name: guardrail-results
|
|
129
|
+
path: |
|
|
130
|
+
*-results.json
|
|
131
|
+
*-results.sarif
|
|
132
|
+
sbom.json
|
|
133
|
+
retention-days: 30
|
|
134
|
+
|
|
135
|
+
- name: Check Scan Results
|
|
136
|
+
run: |
|
|
137
|
+
echo "=== Guardrail Security Scan Summary ==="
|
|
138
|
+
|
|
139
|
+
if [ -f ship-results.json ]; then
|
|
140
|
+
VERDICT=$(cat ship-results.json | jq -r '.verdict // "unknown"')
|
|
141
|
+
SCORE=$(cat ship-results.json | jq -r '.score // "N/A"')
|
|
142
|
+
echo "Ship Status: $VERDICT (Score: $SCORE)"
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# Fail the workflow if critical issues were found
|
|
146
|
+
FAILED=false
|
|
147
|
+
|
|
148
|
+
if [ "\${{ steps.secrets.outcome }}" == "failure" ]; then
|
|
149
|
+
echo "❌ Secrets scan found issues"
|
|
150
|
+
FAILED=true
|
|
151
|
+
else
|
|
152
|
+
echo "✅ Secrets scan passed"
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
if [ "\${{ steps.vulns.outcome }}" == "failure" ]; then
|
|
156
|
+
echo "❌ Vulnerability scan found issues"
|
|
157
|
+
FAILED=true
|
|
158
|
+
else
|
|
159
|
+
echo "✅ Vulnerability scan passed"
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
if [ "$FAILED" == "true" ]; then
|
|
163
|
+
echo ""
|
|
164
|
+
echo "Security issues detected. Please review the scan results."
|
|
165
|
+
exit 1
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
echo ""
|
|
169
|
+
echo "All security checks passed! ✅"
|
|
170
|
+
`;
|
|
171
|
+
return workflow;
|
|
172
|
+
}
|
|
173
|
+
function generateGitLabCI(config) {
|
|
174
|
+
const runCompliance = config.scans.compliance.enabled;
|
|
175
|
+
return `stages:
|
|
176
|
+
- security
|
|
177
|
+
|
|
178
|
+
guardrail-scan:
|
|
179
|
+
stage: security
|
|
180
|
+
image: node:20-alpine
|
|
181
|
+
before_script:
|
|
182
|
+
- npm ci --ignore-scripts
|
|
183
|
+
- npm install -g guardrail-cli
|
|
184
|
+
script:
|
|
185
|
+
- guardrail scan:secrets --path . --format json --output secrets-results.json --exit-code || true
|
|
186
|
+
- guardrail scan:vulnerabilities --path . --format json --output vuln-results.json --exit-code || true
|
|
187
|
+
${runCompliance ? ` - guardrail scan:compliance --path . --framework ${config.scans.compliance.frameworks?.[0] || 'soc2'} --format json --output compliance-results.json || true` : ''}
|
|
188
|
+
- guardrail ship --path . --format json --output ship-results.json
|
|
189
|
+
artifacts:
|
|
190
|
+
paths:
|
|
191
|
+
- "*-results.json"
|
|
192
|
+
reports:
|
|
193
|
+
sast: secrets-results.json
|
|
194
|
+
expire_in: 30 days
|
|
195
|
+
variables:
|
|
196
|
+
GUARDRAIL_API_KEY: $GUARDRAIL_API_KEY
|
|
197
|
+
rules:
|
|
198
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
199
|
+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
|
200
|
+
`;
|
|
201
|
+
}
|
|
202
|
+
function generateCIWorkflow(options) {
|
|
203
|
+
const { projectPath, config, provider = 'github' } = options;
|
|
204
|
+
let workflowContent;
|
|
205
|
+
let workflowPath;
|
|
206
|
+
switch (provider) {
|
|
207
|
+
case 'github': {
|
|
208
|
+
workflowContent = generateGitHubActionsWorkflow(config);
|
|
209
|
+
const workflowDir = (0, path_1.join)(projectPath, '.github', 'workflows');
|
|
210
|
+
if (!(0, fs_1.existsSync)(workflowDir)) {
|
|
211
|
+
(0, fs_1.mkdirSync)(workflowDir, { recursive: true });
|
|
212
|
+
}
|
|
213
|
+
workflowPath = (0, path_1.join)(workflowDir, 'guardrail.yml');
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
case 'gitlab': {
|
|
217
|
+
workflowContent = generateGitLabCI(config);
|
|
218
|
+
workflowPath = (0, path_1.join)(projectPath, '.gitlab-ci.yml');
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
default:
|
|
222
|
+
workflowContent = generateGitHubActionsWorkflow(config);
|
|
223
|
+
const defaultDir = (0, path_1.join)(projectPath, '.github', 'workflows');
|
|
224
|
+
if (!(0, fs_1.existsSync)(defaultDir)) {
|
|
225
|
+
(0, fs_1.mkdirSync)(defaultDir, { recursive: true });
|
|
226
|
+
}
|
|
227
|
+
workflowPath = (0, path_1.join)(defaultDir, 'guardrail.yml');
|
|
228
|
+
}
|
|
229
|
+
(0, fs_1.writeFileSync)(workflowPath, workflowContent, 'utf-8');
|
|
230
|
+
return {
|
|
231
|
+
success: true,
|
|
232
|
+
workflowPath,
|
|
233
|
+
provider,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function getCIProviderFromProject(projectPath) {
|
|
237
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, '.github'))) {
|
|
238
|
+
return 'github';
|
|
239
|
+
}
|
|
240
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, '.gitlab-ci.yml'))) {
|
|
241
|
+
return 'gitlab';
|
|
242
|
+
}
|
|
243
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, 'azure-pipelines.yml'))) {
|
|
244
|
+
return 'azure';
|
|
245
|
+
}
|
|
246
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, 'bitbucket-pipelines.yml'))) {
|
|
247
|
+
return 'bitbucket';
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=ci-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-generator.js","sourceRoot":"","sources":["../../src/init/ci-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework Detection Module
|
|
3
|
+
* Detects project type by inspecting package.json and file structure
|
|
4
|
+
*/
|
|
5
|
+
export type DetectedFramework = 'nextjs' | 'express' | 'nestjs' | 'fastify' | 'remix' | 'vite-react' | 'unknown';
|
|
6
|
+
export interface FrameworkDetectionResult {
|
|
7
|
+
framework: DetectedFramework;
|
|
8
|
+
confidence: 'high' | 'medium' | 'low';
|
|
9
|
+
signals: string[];
|
|
10
|
+
recommendedScans: string[];
|
|
11
|
+
scanDescription: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function detectFramework(projectPath: string): FrameworkDetectionResult;
|
|
14
|
+
export declare function formatFrameworkName(framework: DetectedFramework): string;
|
|
15
|
+
//# sourceMappingURL=detect-framework.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-framework.d.ts","sourceRoot":"","sources":["../../src/init/detect-framework.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,SAAS,GACT,OAAO,GACP,YAAY,GACZ,SAAS,CAAC;AAEd,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AA+QD,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,wBAAwB,CAsC7E;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAWxE"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Framework Detection Module
|
|
4
|
+
* Detects project type by inspecting package.json and file structure
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.detectFramework = detectFramework;
|
|
8
|
+
exports.formatFrameworkName = formatFrameworkName;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
function loadPackageJson(projectPath) {
|
|
12
|
+
const packageJsonPath = (0, path_1.join)(projectPath, 'package.json');
|
|
13
|
+
if (!(0, fs_1.existsSync)(packageJsonPath)) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse((0, fs_1.readFileSync)(packageJsonPath, 'utf-8'));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function hasDependency(pkg, depName) {
|
|
24
|
+
if (!pkg)
|
|
25
|
+
return false;
|
|
26
|
+
return Boolean(pkg.dependencies?.[depName] || pkg.devDependencies?.[depName]);
|
|
27
|
+
}
|
|
28
|
+
function hasFile(projectPath, ...patterns) {
|
|
29
|
+
for (const pattern of patterns) {
|
|
30
|
+
if (pattern.includes('*')) {
|
|
31
|
+
const dir = (0, path_1.join)(projectPath, pattern.split('/')[0] || '.');
|
|
32
|
+
const filePattern = pattern.split('/').pop()?.replace('*', '') || '';
|
|
33
|
+
try {
|
|
34
|
+
const files = (0, fs_1.readdirSync)(dir);
|
|
35
|
+
if (files.some(f => f.includes(filePattern.replace('*', '')))) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, pattern))) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
function hasDirectory(projectPath, dirName) {
|
|
52
|
+
const dirPath = (0, path_1.join)(projectPath, dirName);
|
|
53
|
+
try {
|
|
54
|
+
return (0, fs_1.existsSync)(dirPath) && (0, fs_1.statSync)(dirPath).isDirectory();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function hasFilePattern(projectPath, dir, pattern) {
|
|
61
|
+
const dirPath = (0, path_1.join)(projectPath, dir);
|
|
62
|
+
if (!(0, fs_1.existsSync)(dirPath))
|
|
63
|
+
return false;
|
|
64
|
+
try {
|
|
65
|
+
const files = (0, fs_1.readdirSync)(dirPath);
|
|
66
|
+
return files.some(f => pattern.test(f));
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function detectNextJS(projectPath, pkg) {
|
|
73
|
+
const signals = [];
|
|
74
|
+
let confidence = 'low';
|
|
75
|
+
if (hasDependency(pkg, 'next')) {
|
|
76
|
+
signals.push('next dependency found in package.json');
|
|
77
|
+
confidence = 'high';
|
|
78
|
+
}
|
|
79
|
+
if (hasFile(projectPath, 'next.config.js', 'next.config.mjs', 'next.config.ts')) {
|
|
80
|
+
signals.push('next.config.* file found');
|
|
81
|
+
confidence = 'high';
|
|
82
|
+
}
|
|
83
|
+
if (hasDirectory(projectPath, 'app') && hasFile(projectPath, 'app/layout.tsx', 'app/layout.js', 'app/page.tsx', 'app/page.js')) {
|
|
84
|
+
signals.push('Next.js app directory structure detected');
|
|
85
|
+
if (confidence !== 'high')
|
|
86
|
+
confidence = 'medium';
|
|
87
|
+
}
|
|
88
|
+
if (hasDirectory(projectPath, 'pages')) {
|
|
89
|
+
const pagesPath = (0, path_1.join)(projectPath, 'pages');
|
|
90
|
+
try {
|
|
91
|
+
const files = (0, fs_1.readdirSync)(pagesPath);
|
|
92
|
+
if (files.some(f => f.endsWith('.tsx') || f.endsWith('.jsx') || f === '_app.js' || f === '_app.tsx')) {
|
|
93
|
+
signals.push('Next.js pages directory structure detected');
|
|
94
|
+
if (confidence !== 'high')
|
|
95
|
+
confidence = 'medium';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch { }
|
|
99
|
+
}
|
|
100
|
+
if (signals.length === 0)
|
|
101
|
+
return null;
|
|
102
|
+
return {
|
|
103
|
+
framework: 'nextjs',
|
|
104
|
+
confidence,
|
|
105
|
+
signals,
|
|
106
|
+
recommendedScans: ['secrets', 'vuln', 'ship', 'reality'],
|
|
107
|
+
scanDescription: 'Full-stack scanning: secrets detection, dependency vulnerabilities, ship readiness, and reality mode for auth/dashboard flows',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function detectExpress(projectPath, pkg) {
|
|
111
|
+
const signals = [];
|
|
112
|
+
let confidence = 'low';
|
|
113
|
+
if (hasDependency(pkg, 'express')) {
|
|
114
|
+
signals.push('express dependency found in package.json');
|
|
115
|
+
confidence = 'high';
|
|
116
|
+
}
|
|
117
|
+
if (hasFilePattern(projectPath, 'src', /^(server|app|index)\.(ts|js)$/)) {
|
|
118
|
+
signals.push('src/server.* or src/app.* pattern detected');
|
|
119
|
+
if (confidence !== 'high')
|
|
120
|
+
confidence = 'medium';
|
|
121
|
+
}
|
|
122
|
+
if (hasFilePattern(projectPath, '.', /^(server|app)\.(ts|js)$/)) {
|
|
123
|
+
signals.push('Root server.* or app.* file detected');
|
|
124
|
+
if (confidence !== 'high')
|
|
125
|
+
confidence = 'medium';
|
|
126
|
+
}
|
|
127
|
+
if (hasDirectory(projectPath, 'routes') || hasDirectory(projectPath, 'src/routes')) {
|
|
128
|
+
signals.push('routes directory detected');
|
|
129
|
+
if (confidence !== 'high')
|
|
130
|
+
confidence = 'low';
|
|
131
|
+
}
|
|
132
|
+
if (signals.length === 0)
|
|
133
|
+
return null;
|
|
134
|
+
return {
|
|
135
|
+
framework: 'express',
|
|
136
|
+
confidence,
|
|
137
|
+
signals,
|
|
138
|
+
recommendedScans: ['secrets', 'vuln', 'ship', 'compliance'],
|
|
139
|
+
scanDescription: 'API-focused scanning: secrets detection, dependency vulnerabilities, ship readiness, and compliance checks for logging/rate limits',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function detectNestJS(projectPath, pkg) {
|
|
143
|
+
const signals = [];
|
|
144
|
+
let confidence = 'low';
|
|
145
|
+
if (hasDependency(pkg, '@nestjs/core')) {
|
|
146
|
+
signals.push('@nestjs/core dependency found');
|
|
147
|
+
confidence = 'high';
|
|
148
|
+
}
|
|
149
|
+
if (hasDependency(pkg, '@nestjs/common')) {
|
|
150
|
+
signals.push('@nestjs/common dependency found');
|
|
151
|
+
if (confidence !== 'high')
|
|
152
|
+
confidence = 'medium';
|
|
153
|
+
}
|
|
154
|
+
if (hasFile(projectPath, 'nest-cli.json')) {
|
|
155
|
+
signals.push('nest-cli.json configuration found');
|
|
156
|
+
confidence = 'high';
|
|
157
|
+
}
|
|
158
|
+
if (hasFilePattern(projectPath, 'src', /\.module\.ts$/)) {
|
|
159
|
+
signals.push('NestJS module files detected');
|
|
160
|
+
if (confidence !== 'high')
|
|
161
|
+
confidence = 'medium';
|
|
162
|
+
}
|
|
163
|
+
if (signals.length === 0)
|
|
164
|
+
return null;
|
|
165
|
+
return {
|
|
166
|
+
framework: 'nestjs',
|
|
167
|
+
confidence,
|
|
168
|
+
signals,
|
|
169
|
+
recommendedScans: ['secrets', 'vuln', 'ship', 'compliance'],
|
|
170
|
+
scanDescription: 'Enterprise API scanning: secrets detection, dependency vulnerabilities, ship readiness, and compliance checks for decorators/guards',
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function detectFastify(projectPath, pkg) {
|
|
174
|
+
const signals = [];
|
|
175
|
+
let confidence = 'low';
|
|
176
|
+
if (hasDependency(pkg, 'fastify')) {
|
|
177
|
+
signals.push('fastify dependency found in package.json');
|
|
178
|
+
confidence = 'high';
|
|
179
|
+
}
|
|
180
|
+
if (hasDependency(pkg, '@fastify/autoload') || hasDependency(pkg, 'fastify-plugin')) {
|
|
181
|
+
signals.push('Fastify ecosystem packages detected');
|
|
182
|
+
if (confidence !== 'high')
|
|
183
|
+
confidence = 'medium';
|
|
184
|
+
}
|
|
185
|
+
if (signals.length === 0)
|
|
186
|
+
return null;
|
|
187
|
+
return {
|
|
188
|
+
framework: 'fastify',
|
|
189
|
+
confidence,
|
|
190
|
+
signals,
|
|
191
|
+
recommendedScans: ['secrets', 'vuln', 'ship', 'compliance'],
|
|
192
|
+
scanDescription: 'High-performance API scanning: secrets detection, dependency vulnerabilities, ship readiness, and compliance checks',
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function detectRemix(projectPath, pkg) {
|
|
196
|
+
const signals = [];
|
|
197
|
+
let confidence = 'low';
|
|
198
|
+
if (hasDependency(pkg, '@remix-run/node') || hasDependency(pkg, '@remix-run/react')) {
|
|
199
|
+
signals.push('@remix-run packages found in package.json');
|
|
200
|
+
confidence = 'high';
|
|
201
|
+
}
|
|
202
|
+
if (hasFile(projectPath, 'remix.config.js', 'remix.config.ts')) {
|
|
203
|
+
signals.push('remix.config.* file found');
|
|
204
|
+
confidence = 'high';
|
|
205
|
+
}
|
|
206
|
+
if (hasDirectory(projectPath, 'app/routes')) {
|
|
207
|
+
signals.push('Remix app/routes directory structure detected');
|
|
208
|
+
if (confidence !== 'high')
|
|
209
|
+
confidence = 'medium';
|
|
210
|
+
}
|
|
211
|
+
if (signals.length === 0)
|
|
212
|
+
return null;
|
|
213
|
+
return {
|
|
214
|
+
framework: 'remix',
|
|
215
|
+
confidence,
|
|
216
|
+
signals,
|
|
217
|
+
recommendedScans: ['secrets', 'vuln', 'ship', 'reality'],
|
|
218
|
+
scanDescription: 'Full-stack scanning: secrets detection, dependency vulnerabilities, ship readiness, and reality mode for form/loader flows',
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function detectViteReact(projectPath, pkg) {
|
|
222
|
+
const signals = [];
|
|
223
|
+
let confidence = 'low';
|
|
224
|
+
const hasVite = hasDependency(pkg, 'vite');
|
|
225
|
+
const hasReact = hasDependency(pkg, 'react') || hasDependency(pkg, 'react-dom');
|
|
226
|
+
if (hasVite && hasReact) {
|
|
227
|
+
signals.push('vite + react dependencies found');
|
|
228
|
+
confidence = 'high';
|
|
229
|
+
}
|
|
230
|
+
if (hasFile(projectPath, 'vite.config.ts', 'vite.config.js', 'vite.config.mjs')) {
|
|
231
|
+
signals.push('vite.config.* file found');
|
|
232
|
+
if (hasReact) {
|
|
233
|
+
confidence = 'high';
|
|
234
|
+
}
|
|
235
|
+
else if (confidence !== 'high') {
|
|
236
|
+
confidence = 'medium';
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (hasDependency(pkg, '@vitejs/plugin-react') || hasDependency(pkg, '@vitejs/plugin-react-swc')) {
|
|
240
|
+
signals.push('Vite React plugin detected');
|
|
241
|
+
confidence = 'high';
|
|
242
|
+
}
|
|
243
|
+
if (signals.length === 0)
|
|
244
|
+
return null;
|
|
245
|
+
return {
|
|
246
|
+
framework: 'vite-react',
|
|
247
|
+
confidence,
|
|
248
|
+
signals,
|
|
249
|
+
recommendedScans: ['secrets', 'vuln', 'ship'],
|
|
250
|
+
scanDescription: 'Frontend scanning: secrets detection in client code, dependency vulnerabilities, and ship readiness checks',
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function detectFramework(projectPath) {
|
|
254
|
+
const pkg = loadPackageJson(projectPath);
|
|
255
|
+
const detectors = [
|
|
256
|
+
detectNextJS,
|
|
257
|
+
detectNestJS,
|
|
258
|
+
detectRemix,
|
|
259
|
+
detectFastify,
|
|
260
|
+
detectExpress,
|
|
261
|
+
detectViteReact,
|
|
262
|
+
];
|
|
263
|
+
let bestMatch = null;
|
|
264
|
+
const confidenceOrder = { high: 3, medium: 2, low: 1 };
|
|
265
|
+
for (const detector of detectors) {
|
|
266
|
+
const result = detector(projectPath, pkg);
|
|
267
|
+
if (result) {
|
|
268
|
+
if (!bestMatch || confidenceOrder[result.confidence] > confidenceOrder[bestMatch.confidence]) {
|
|
269
|
+
bestMatch = result;
|
|
270
|
+
}
|
|
271
|
+
if (result.confidence === 'high') {
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (bestMatch) {
|
|
277
|
+
return bestMatch;
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
framework: 'unknown',
|
|
281
|
+
confidence: 'low',
|
|
282
|
+
signals: ['No specific framework detected'],
|
|
283
|
+
recommendedScans: ['secrets', 'vuln'],
|
|
284
|
+
scanDescription: 'Basic scanning: secrets detection and dependency vulnerability checks',
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function formatFrameworkName(framework) {
|
|
288
|
+
const names = {
|
|
289
|
+
nextjs: 'Next.js',
|
|
290
|
+
express: 'Express.js',
|
|
291
|
+
nestjs: 'NestJS',
|
|
292
|
+
fastify: 'Fastify',
|
|
293
|
+
remix: 'Remix',
|
|
294
|
+
'vite-react': 'Vite + React',
|
|
295
|
+
unknown: 'Unknown',
|
|
296
|
+
};
|
|
297
|
+
return names[framework];
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=detect-framework.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-framework.js","sourceRoot":"","sources":["../../src/init/detect-framework.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Hooks Installer
|
|
3
|
+
* Installs and configures husky or lefthook for pre-commit/pre-push hooks
|
|
4
|
+
*/
|
|
5
|
+
import type { GuardrailConfig } from './templates';
|
|
6
|
+
export type HookRunner = 'husky' | 'lefthook';
|
|
7
|
+
export interface HooksInstallerOptions {
|
|
8
|
+
projectPath: string;
|
|
9
|
+
config: GuardrailConfig;
|
|
10
|
+
runner?: HookRunner;
|
|
11
|
+
preCommit?: boolean;
|
|
12
|
+
prePush?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface HooksInstallerResult {
|
|
15
|
+
success: boolean;
|
|
16
|
+
runner: HookRunner;
|
|
17
|
+
installedHooks: string[];
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function installHooks(options: HooksInstallerOptions): HooksInstallerResult;
|
|
21
|
+
export declare function getRecommendedRunner(projectPath: string): HookRunner;
|
|
22
|
+
//# sourceMappingURL=hooks-installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks-installer.d.ts","sourceRoot":"","sources":["../../src/init/hooks-installer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgMD,wBAAgB,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,oBAAoB,CAqHjF;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAkBpE"}
|