guardian-framework 0.1.99 → 0.1.100
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/dist/cli.js +1 -1
- package/dist/exports.js +1 -1
- package/package.json +1 -1
- package/templates/pi/preflight_report.json +1 -1
- package/templates/pi/scripts/languages/go/validate-architecture.sh +5 -5
- package/templates/pi/scripts/languages/go/validate-canonical.sh +3 -3
- package/templates/pi/scripts/languages/go/validate-integration.sh +1 -1
- package/templates/pi/scripts/languages/go/validate-operations.sh +2 -2
- package/templates/pi/scripts/languages/go/validate-security.sh +1 -1
- package/templates/pi/scripts/languages/java/validate-integration.sh +10 -10
- package/templates/pi/scripts/languages/java/validate-operations.sh +4 -4
- package/templates/pi/scripts/languages/python/validate-architecture.sh +3 -3
- package/templates/pi/scripts/languages/python/validate-canonical.sh +2 -2
- package/templates/pi/scripts/languages/python/validate-integration.sh +1 -1
- package/templates/pi/scripts/languages/python/validate-security.sh +1 -1
- package/templates/pi/scripts/languages/rust/validate-architecture.sh +5 -5
- package/templates/pi/scripts/languages/rust/validate-canonical.sh +3 -3
- package/templates/pi/scripts/languages/rust/validate-security.sh +2 -2
- package/templates/pi/scripts/languages/rust/validate-tests.sh +1 -1
- package/templates/pi/scripts/languages/typescript/validate-architecture.sh +3 -3
- package/templates/pi/scripts/languages/typescript/validate-canonical.sh +3 -3
- package/templates/pi/scripts/languages/typescript/validate-integration.sh +2 -2
- package/templates/pi/scripts/languages/typescript/validate-operations.sh +7 -7
- package/templates/pi/scripts/languages/typescript/validate-security.sh +4 -4
package/dist/cli.js
CHANGED
|
@@ -3197,7 +3197,7 @@ __export(exports_package, {
|
|
|
3197
3197
|
bin: () => bin,
|
|
3198
3198
|
author: () => author
|
|
3199
3199
|
});
|
|
3200
|
-
var name = "guardian-framework", version = "0.1.
|
|
3200
|
+
var name = "guardian-framework", version = "0.1.100", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
|
|
3201
3201
|
var init_package = __esm(() => {
|
|
3202
3202
|
exports = {
|
|
3203
3203
|
".": {
|
package/dist/exports.js
CHANGED
|
@@ -1982,7 +1982,7 @@ __export(exports_package, {
|
|
|
1982
1982
|
bin: () => bin,
|
|
1983
1983
|
author: () => author
|
|
1984
1984
|
});
|
|
1985
|
-
var name = "guardian-framework", version = "0.1.
|
|
1985
|
+
var name = "guardian-framework", version = "0.1.100", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
|
|
1986
1986
|
var init_package = __esm(() => {
|
|
1987
1987
|
exports = {
|
|
1988
1988
|
".": {
|
package/package.json
CHANGED
|
@@ -54,7 +54,7 @@ echo "--- Domain Models ---"
|
|
|
54
54
|
DOMAIN_FILES=0
|
|
55
55
|
for dir in "internal/domain" "pkg/domain"; do
|
|
56
56
|
if [ -d "$dir" ]; then
|
|
57
|
-
COUNT=$(grep -rlE 'type\s+\w+\s+struct' "$dir" --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
57
|
+
COUNT=$(grep -rlE 'type\s+\w+\s+struct' "$dir" --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
58
58
|
DOMAIN_FILES=$((DOMAIN_FILES + COUNT))
|
|
59
59
|
fi
|
|
60
60
|
done
|
|
@@ -73,7 +73,7 @@ VIOLATIONS=0
|
|
|
73
73
|
for dir in "internal/domain" "pkg/domain"; do
|
|
74
74
|
if [ -d "$dir" ]; then
|
|
75
75
|
# Domain should not import from infrastructure or cmd
|
|
76
|
-
VIOLATIONS=$((VIOLATIONS + $(grep -rlE 'import.*"(.*/infrastructure|/cmd)"' "$dir" --include="*.go" 2>/dev/null | wc -l | tr -d ' ')))
|
|
76
|
+
VIOLATIONS=$((VIOLATIONS + $(grep -rlE 'import.*"(.*/infrastructure|/cmd)"' "$dir" --include="*.go" 2>/dev/null | wc -l | tr -d ' '))) || true
|
|
77
77
|
fi
|
|
78
78
|
done
|
|
79
79
|
if [ "$VIOLATIONS" -eq 0 ]; then
|
|
@@ -88,8 +88,8 @@ fi
|
|
|
88
88
|
echo ""
|
|
89
89
|
echo "--- Error Handling ---"
|
|
90
90
|
if [ -f "go.mod" ]; then
|
|
91
|
-
ERROR_VARIABS=$(grep -rE 'var\s+Err\w+\s*=\s*(errors\.New|fmt\.Errorf)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
92
|
-
ERROR_STRUCTS=$(grep -rE 'type\s+\w*Error\w*\s+struct' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
91
|
+
ERROR_VARIABS=$(grep -rE 'var\s+Err\w+\s*=\s*(errors\.New|fmt\.Errorf)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
92
|
+
ERROR_STRUCTS=$(grep -rE 'type\s+\w*Error\w*\s+struct' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
93
93
|
TOTAL=$((ERROR_VARIABS + ERROR_STRUCTS))
|
|
94
94
|
if [ "$TOTAL" -gt 0 ]; then
|
|
95
95
|
pass "Custom error types defined ($TOTAL definitions)"
|
|
@@ -106,7 +106,7 @@ fi
|
|
|
106
106
|
echo ""
|
|
107
107
|
echo "--- Interfaces ---"
|
|
108
108
|
if [ -f "go.mod" ]; then
|
|
109
|
-
INTERFACE_COUNT=$(grep -rE 'type\s+\w+\s+interface' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
109
|
+
INTERFACE_COUNT=$(grep -rE 'type\s+\w+\s+interface' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
110
110
|
if [ "$INTERFACE_COUNT" -gt 0 ]; then
|
|
111
111
|
pass "Interface definitions found ($INTERFACE_COUNT interfaces)"
|
|
112
112
|
else
|
|
@@ -22,7 +22,7 @@ echo "--- Architecture Reference Tracing ---"
|
|
|
22
22
|
if [ -f "go.mod" ]; then
|
|
23
23
|
GO_FILES=$(find . -name "*.go" -not -path "./vendor/*" 2>/dev/null | wc -l | tr -d ' ')
|
|
24
24
|
if [ "$GO_FILES" -gt 0 ]; then
|
|
25
|
-
CANONICAL_REFS=$(grep -rlE '//\s*(Canonical:|@canonical|Reference:|Canonical\s+ref)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
25
|
+
CANONICAL_REFS=$(grep -rlE '//\s*(Canonical:|@canonical|Reference:|Canonical\s+ref)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
26
26
|
if [ "$CANONICAL_REFS" -gt 0 ]; then
|
|
27
27
|
PCT=$((CANONICAL_REFS * 100 / GO_FILES))
|
|
28
28
|
pass "Canonical references found in ${CANONICAL_REFS}/${GO_FILES} Go files (${PCT}%)"
|
|
@@ -74,7 +74,7 @@ fi
|
|
|
74
74
|
echo ""
|
|
75
75
|
echo "--- Package Documentation ---"
|
|
76
76
|
if [ -f "go.mod" ]; then
|
|
77
|
-
PKG_FILES_WITH_DOC=$(grep -rlE '//\s*Package\s+\w+\s+(implements|provides|defines|is|contains)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
77
|
+
PKG_FILES_WITH_DOC=$(grep -rlE '//\s*Package\s+\w+\s+(implements|provides|defines|is|contains)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
78
78
|
GO_PACKAGES=$(go list ./... 2>/dev/null | wc -l | tr -d ' ')
|
|
79
79
|
if [ "$GO_PACKAGES" -gt 0 ] && [ "$PKG_FILES_WITH_DOC" -gt 0 ]; then
|
|
80
80
|
pass "Package documentation found in $PKG_FILES_WITH_DOC files"
|
|
@@ -93,7 +93,7 @@ echo "--- ADR Linkage ---"
|
|
|
93
93
|
if [ -d ".pi/architecture/decisions" ]; then
|
|
94
94
|
ADR_COUNT=$(find .pi/architecture/decisions -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
95
95
|
if [ "$ADR_COUNT" -gt 0 ]; then
|
|
96
|
-
ADR_REFS=$(grep -rlE '//\s*ADR[-_]?\d+' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
96
|
+
ADR_REFS=$(grep -rlE '//\s*ADR[-_]?\d+' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
97
97
|
if [ "$ADR_REFS" -gt 0 ]; then
|
|
98
98
|
pass "ADR references found in $ADR_REFS Go files"
|
|
99
99
|
else
|
|
@@ -123,7 +123,7 @@ fi
|
|
|
123
123
|
echo ""
|
|
124
124
|
echo "--- HTTP Integration ---"
|
|
125
125
|
if [ -f "go.mod" ]; then
|
|
126
|
-
HTTPTEST_COUNT=$(grep -rl '"net/http/httptest"' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
126
|
+
HTTPTEST_COUNT=$(grep -rl '"net/http/httptest"' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
127
127
|
if [ "$HTTPTEST_COUNT" -gt 0 ]; then
|
|
128
128
|
pass "HTTP integration tests found (httptest in $HTTPTEST_COUNT files)"
|
|
129
129
|
else
|
|
@@ -40,7 +40,7 @@ fi
|
|
|
40
40
|
echo ""
|
|
41
41
|
echo "--- Health Checks ---"
|
|
42
42
|
if [ -f "go.mod" ]; then
|
|
43
|
-
HEALTH_ENDPOINTS=$(grep -rE '("/health|/healthz|/ready|/readiness)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
43
|
+
HEALTH_ENDPOINTS=$(grep -rE '("/health|/healthz|/ready|/readiness)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
44
44
|
if [ "$HEALTH_ENDPOINTS" -gt 0 ]; then
|
|
45
45
|
pass "Health/readiness endpoint handlers found ($HEALTH_ENDPOINTS references)"
|
|
46
46
|
else
|
|
@@ -94,7 +94,7 @@ fi
|
|
|
94
94
|
echo ""
|
|
95
95
|
echo "--- Error Wrapping ---"
|
|
96
96
|
if [ -f "go.mod" ]; then
|
|
97
|
-
WRAP_COUNT=$(grep -rE 'fmt\.Errorf\(.*%w' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
97
|
+
WRAP_COUNT=$(grep -rE 'fmt\.Errorf\(.*%w' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
98
98
|
if [ "$WRAP_COUNT" -gt 0 ]; then
|
|
99
99
|
pass "Error wrapping with %w found ($WRAP_COUNT usages)"
|
|
100
100
|
else
|
|
@@ -100,7 +100,7 @@ echo ""
|
|
|
100
100
|
echo "--- Input Validation ---"
|
|
101
101
|
if [ -f "go.mod" ]; then
|
|
102
102
|
TEXT_TEMPLATE=$(grep -rl '"text/template"' . --include="*.go" 2>/dev/null | grep -v "_test.go" | wc -l | tr -d ' ')
|
|
103
|
-
HTML_TEMPLATE=$(grep -rl '"html/template"' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ')
|
|
103
|
+
HTML_TEMPLATE=$(grep -rl '"html/template"' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
104
104
|
if [ "$TEXT_TEMPLATE" -eq 0 ]; then
|
|
105
105
|
pass "No text/template usage in production code (html/template auto-escapes)"
|
|
106
106
|
elif [ "$HTML_TEMPLATE" -gt 0 ]; then
|
|
@@ -24,12 +24,12 @@ TEST_DIR="${2:-src/test/java}"
|
|
|
24
24
|
echo "--- Test Slice Correctness ---"
|
|
25
25
|
if [ -d "$TEST_DIR" ]; then
|
|
26
26
|
# Check for @SpringBootTest usage (no slice annotations)
|
|
27
|
-
FULL_CONTEXT_TESTS=$(grep -r "@SpringBootTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
27
|
+
FULL_CONTEXT_TESTS=$(grep -r "@SpringBootTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
28
28
|
# Check for slice test annotations
|
|
29
|
-
WEB_MVC_TESTS=$(grep -r "@WebMvcTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
30
|
-
DATA_JPA_TESTS=$(grep -r "@DataJpaTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
31
|
-
JSON_TESTS=$(grep -r "@JsonTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
32
|
-
REST_CLIENT_TESTS=$(grep -r "@RestClientTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
29
|
+
WEB_MVC_TESTS=$(grep -r "@WebMvcTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
30
|
+
DATA_JPA_TESTS=$(grep -r "@DataJpaTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
31
|
+
JSON_TESTS=$(grep -r "@JsonTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
32
|
+
REST_CLIENT_TESTS=$(grep -r "@RestClientTest" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
33
33
|
|
|
34
34
|
TOTAL_SLICE_TESTS=$((WEB_MVC_TESTS + DATA_JPA_TESTS + JSON_TESTS + REST_CLIENT_TESTS))
|
|
35
35
|
|
|
@@ -52,7 +52,7 @@ fi
|
|
|
52
52
|
echo ""
|
|
53
53
|
echo "--- Context Caching ---"
|
|
54
54
|
if [ -d "$TEST_DIR" ]; then
|
|
55
|
-
DIRTY_CONTEXT=$(grep -r "@DirtiesContext" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
55
|
+
DIRTY_CONTEXT=$(grep -r "@DirtiesContext" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
56
56
|
if [ "$DIRTY_CONTEXT" -gt 0 ]; then
|
|
57
57
|
warn "$DIRTY_CONTEXT @DirtiesContext annotations found — these disable context caching and slow tests"
|
|
58
58
|
else
|
|
@@ -74,7 +74,7 @@ if [ -d "$TEST_DIR" ]; then
|
|
|
74
74
|
TRANSACTIONAL_TESTS=$(echo "$DATA_JPA_CLASSES" | wc -l | tr -d ' ')
|
|
75
75
|
fi
|
|
76
76
|
|
|
77
|
-
ROLLBACK_COUNT=$(grep -r "@Rollback" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
77
|
+
ROLLBACK_COUNT=$(grep -r "@Rollback" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
78
78
|
|
|
79
79
|
if [ "$TRANSACTIONAL_TESTS" -gt 0 ] || [ "$ROLLBACK_COUNT" -gt 0 ]; then
|
|
80
80
|
pass "Database state management found (@DataJpaTest: $TRANSACTIONAL_TESTS, @Rollback: $ROLLBACK_COUNT)"
|
|
@@ -103,7 +103,7 @@ fi
|
|
|
103
103
|
echo ""
|
|
104
104
|
echo "--- Mockito Usage ---"
|
|
105
105
|
if [ -d "$TEST_DIR" ]; then
|
|
106
|
-
MOCKITO_ANNOTATIONS=$(grep -r "@Mock\|@InjectMocks\|@MockBean\|@SpyBean" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
106
|
+
MOCKITO_ANNOTATIONS=$(grep -r "@Mock\|@InjectMocks\|@MockBean\|@SpyBean" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
107
107
|
if [ "$MOCKITO_ANNOTATIONS" -gt 0 ]; then
|
|
108
108
|
pass "Mockito usage detected ($MOCKITO_ANNOTATIONS annotations)"
|
|
109
109
|
else
|
|
@@ -117,8 +117,8 @@ fi
|
|
|
117
117
|
echo ""
|
|
118
118
|
echo "--- Assertions ---"
|
|
119
119
|
if [ -d "$TEST_DIR" ]; then
|
|
120
|
-
ASSERTJ=$(grep -r "assertThat\|Assertions.assertThat" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
121
|
-
JUNIT_ASSERT=$(grep -r "assertEquals\|assertTrue\|assertNotNull\|assertThrows" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
120
|
+
ASSERTJ=$(grep -r "assertThat\|Assertions.assertThat" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
121
|
+
JUNIT_ASSERT=$(grep -r "assertEquals\|assertTrue\|assertNotNull\|assertThrows" "$TEST_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
122
122
|
if [ "$ASSERTJ" -gt 0 ] || [ "$JUNIT_ASSERT" -gt 0 ]; then
|
|
123
123
|
pass "Assertions found (AssertJ: $ASSERTJ, JUnit: $JUNIT_ASSERT)"
|
|
124
124
|
else
|
|
@@ -44,10 +44,10 @@ fi
|
|
|
44
44
|
echo ""
|
|
45
45
|
echo "--- @Scheduled Tasks ---"
|
|
46
46
|
if [ -d "$SRC_DIR" ]; then
|
|
47
|
-
SCHEDULED_COUNT=$(grep -r "@Scheduled" "$SRC_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
47
|
+
SCHEDULED_COUNT=$(grep -r "@Scheduled" "$SRC_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
48
48
|
if [ "$SCHEDULED_COUNT" -gt 0 ]; then
|
|
49
49
|
# Check if @EnableScheduling is present
|
|
50
|
-
ENABLED_SCHEDULING=$(grep -r "@EnableScheduling" "$SRC_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
50
|
+
ENABLED_SCHEDULING=$(grep -r "@EnableScheduling" "$SRC_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
51
51
|
if [ "$ENABLED_SCHEDULING" -gt 0 ]; then
|
|
52
52
|
pass "$SCHEDULED_COUNT @Scheduled tasks found with @EnableScheduling"
|
|
53
53
|
else
|
|
@@ -64,9 +64,9 @@ fi
|
|
|
64
64
|
echo ""
|
|
65
65
|
echo "--- @Async Tasks ---"
|
|
66
66
|
if [ -d "$SRC_DIR" ]; then
|
|
67
|
-
ASYNC_COUNT=$(grep -r "@Async" "$SRC_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
67
|
+
ASYNC_COUNT=$(grep -r "@Async" "$SRC_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
68
68
|
if [ "$ASYNC_COUNT" -gt 0 ]; then
|
|
69
|
-
ENABLED_ASYNC=$(grep -r "@EnableAsync" "$SRC_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ')
|
|
69
|
+
ENABLED_ASYNC=$(grep -r "@EnableAsync" "$SRC_DIR" --include="*.java" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
70
70
|
if [ "$ENABLED_ASYNC" -gt 0 ]; then
|
|
71
71
|
pass "$ASYNC_COUNT @Async methods found with @EnableAsync"
|
|
72
72
|
else
|
|
@@ -60,7 +60,7 @@ fi
|
|
|
60
60
|
# Dependency direction
|
|
61
61
|
echo ""
|
|
62
62
|
echo "--- Dependency Direction ---"
|
|
63
|
-
DOMAIN_INFRA_IMPORTS=$(find "$SRC_DIR" -path "*/domain/*.py" -exec grep -l "from.*infrastructure" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
63
|
+
DOMAIN_INFRA_IMPORTS=$(find "$SRC_DIR" -path "*/domain/*.py" -exec grep -l "from.*infrastructure" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
64
64
|
if [ "$DOMAIN_INFRA_IMPORTS" -eq 0 ]; then
|
|
65
65
|
pass "Domain layer has no infrastructure dependencies (clean architecture)"
|
|
66
66
|
else
|
|
@@ -70,7 +70,7 @@ fi
|
|
|
70
70
|
# Error handling
|
|
71
71
|
echo ""
|
|
72
72
|
echo "--- Error Handling ---"
|
|
73
|
-
ERROR_COUNT=$(grep -r "class.*Error" "$SRC_DIR" 2>/dev/null | wc -l | tr -d ' ')
|
|
73
|
+
ERROR_COUNT=$(grep -r "class.*Error" "$SRC_DIR" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
74
74
|
if [ "$ERROR_COUNT" -gt 0 ]; then
|
|
75
75
|
pass "Custom exception classes defined ($ERROR_COUNT found)"
|
|
76
76
|
else
|
|
@@ -80,7 +80,7 @@ fi
|
|
|
80
80
|
# Typed models
|
|
81
81
|
echo ""
|
|
82
82
|
echo "--- Typed Models ---"
|
|
83
|
-
MODEL_COUNT=$(grep -r "@dataclass" "$SRC_DIR" 2>/dev/null | wc -l | tr -d ' ')
|
|
83
|
+
MODEL_COUNT=$(grep -r "@dataclass" "$SRC_DIR" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
84
84
|
if [ "$MODEL_COUNT" -gt 0 ]; then
|
|
85
85
|
pass "Typed dataclass models found ($MODEL_COUNT definitions)"
|
|
86
86
|
else
|
|
@@ -28,7 +28,7 @@ SRC_DIR="${1:-src}"
|
|
|
28
28
|
echo "--- Architecture Reference Tracing ---"
|
|
29
29
|
TOTAL_PY_FILES=$(find "$SRC_DIR" -name "*.py" 2>/dev/null | wc -l | tr -d ' ')
|
|
30
30
|
if [ "$TOTAL_PY_FILES" -gt 0 ]; then
|
|
31
|
-
FILES_WITH_REFS=$(grep -rlE "(Canonical:|@canonical|Reference:.*\.pi/architecture)" "$SRC_DIR" --include="*.py" 2>/dev/null | wc -l | tr -d ' ')
|
|
31
|
+
FILES_WITH_REFS=$(grep -rlE "(Canonical:|@canonical|Reference:.*\.pi/architecture)" "$SRC_DIR" --include="*.py" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
32
32
|
PCT=$((FILES_WITH_REFS * 100 / TOTAL_PY_FILES))
|
|
33
33
|
if [ "$FILES_WITH_REFS" -gt 0 ]; then
|
|
34
34
|
pass "Canonical references detected in $FILES_WITH_REFS/$TOTAL_PY_FILES files (${PCT}%)"
|
|
@@ -93,7 +93,7 @@ echo ""
|
|
|
93
93
|
echo "--- ADR Linkage ---"
|
|
94
94
|
if [ -d ".pi/architecture/decisions" ]; then
|
|
95
95
|
ADR_COUNT=$(find .pi/architecture/decisions -name "ADR-*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
96
|
-
ADR_REFS=$(grep -rlE "ADR-[0-9]+" "$SRC_DIR" --include="*.py" 2>/dev/null | wc -l | tr -d ' ')
|
|
96
|
+
ADR_REFS=$(grep -rlE "ADR-[0-9]+" "$SRC_DIR" --include="*.py" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
97
97
|
if [ "$ADR_REFS" -gt 0 ]; then
|
|
98
98
|
pass "ADR references found in $ADR_REFS source files ($ADR_COUNT ADRs exist)"
|
|
99
99
|
else
|
|
@@ -75,7 +75,7 @@ fi
|
|
|
75
75
|
# ── Database Integration Tests ──
|
|
76
76
|
echo ""
|
|
77
77
|
echo "--- Database Integration Tests ---"
|
|
78
|
-
DB_TEST_COUNT=$(grep -rlE "(pytest.*db|session_scope|test_db|database_url|SQLALCHEMY)" tests/ --include="*.py" 2>/dev/null | wc -l | tr -d ' ')
|
|
78
|
+
DB_TEST_COUNT=$(grep -rlE "(pytest.*db|session_scope|test_db|database_url|SQLALCHEMY)" tests/ --include="*.py" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
79
79
|
if [ "$DB_TEST_COUNT" -gt 0 ]; then
|
|
80
80
|
pass "Database integration tests found ($DB_TEST_COUNT files)"
|
|
81
81
|
else
|
|
@@ -33,7 +33,7 @@ fi
|
|
|
33
33
|
# SQL injection
|
|
34
34
|
echo ""
|
|
35
35
|
echo "--- Injection Patterns ---"
|
|
36
|
-
INJECT_COUNT=$(grep -rE "(execute|cursor\.execute)\s*\(\s*['\"]" "$SRC_DIR" --include="*.py" 2>/dev/null | wc -l | tr -d ' ')
|
|
36
|
+
INJECT_COUNT=$(grep -rE "(execute|cursor\.execute)\s*\(\s*['\"]" "$SRC_DIR" --include="*.py" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
37
37
|
if [ "$INJECT_COUNT" -eq 0 ]; then
|
|
38
38
|
pass "No obvious injection patterns"
|
|
39
39
|
else
|
|
@@ -82,7 +82,7 @@ echo "--- Domain Models ---"
|
|
|
82
82
|
DOMAIN_MODELS=0
|
|
83
83
|
for dir in src/domain src/models; do
|
|
84
84
|
if [ -d "$dir" ]; then
|
|
85
|
-
MODELS=$(grep -rlE '^\s*(pub\s+)?struct\s' "$dir" 2>/dev/null | wc -l | tr -d ' ')
|
|
85
|
+
MODELS=$(grep -rlE '^\s*(pub\s+)?struct\s' "$dir" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
86
86
|
DOMAIN_MODELS=$((DOMAIN_MODELS + MODELS))
|
|
87
87
|
fi
|
|
88
88
|
done
|
|
@@ -90,7 +90,7 @@ if [ "$DOMAIN_MODELS" -gt 0 ]; then
|
|
|
90
90
|
pass "Domain models found ($DOMAIN_MODELS files with struct definitions)"
|
|
91
91
|
else
|
|
92
92
|
# Check all of src as fallback
|
|
93
|
-
ALL_MODELS=$(grep -rlE '^\s*(pub\s+)?struct\s' src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
93
|
+
ALL_MODELS=$(grep -rlE '^\s*(pub\s+)?struct\s' src/ 2>/dev/null | wc -l | tr -d ' ') || true
|
|
94
94
|
if [ "$ALL_MODELS" -gt 0 ]; then
|
|
95
95
|
pass "Struct definitions found in src/ ($ALL_MODELS files)"
|
|
96
96
|
else
|
|
@@ -104,7 +104,7 @@ fi
|
|
|
104
104
|
echo ""
|
|
105
105
|
echo "--- Dependency Direction ---"
|
|
106
106
|
if [ -d "src/domain" ]; then
|
|
107
|
-
DOMAIN_DEPS=$(grep -rE 'use\s+crate::infrastructure' src/domain/ 2>/dev/null | wc -l | tr -d ' ')
|
|
107
|
+
DOMAIN_DEPS=$(grep -rE 'use\s+crate::infrastructure' src/domain/ 2>/dev/null | wc -l | tr -d ' ') || true
|
|
108
108
|
if [ "$DOMAIN_DEPS" -eq 0 ]; then
|
|
109
109
|
pass "Domain layer does not depend on infrastructure"
|
|
110
110
|
else
|
|
@@ -127,7 +127,7 @@ if command -v cargo &>/dev/null; then
|
|
|
127
127
|
fi
|
|
128
128
|
fi
|
|
129
129
|
# Also check for custom error enum definitions
|
|
130
|
-
CUSTOM_ERRORS=$(grep -rE 'enum\s+\w*Error' src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
130
|
+
CUSTOM_ERRORS=$(grep -rE 'enum\s+\w*Error' src/ 2>/dev/null | wc -l | tr -d ' ') || true
|
|
131
131
|
if [ "$HAS_ERROR_TYPES" -eq 1 ] || [ "$CUSTOM_ERRORS" -gt 0 ]; then
|
|
132
132
|
pass "Custom error handling detected"
|
|
133
133
|
else
|
|
@@ -139,7 +139,7 @@ fi
|
|
|
139
139
|
# ---------------------------------------------------------------------------
|
|
140
140
|
echo ""
|
|
141
141
|
echo "--- Trait Definitions ---"
|
|
142
|
-
TRAITS=$(grep -rE '^\s*(pub\s+)?trait\s+' src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
142
|
+
TRAITS=$(grep -rE '^\s*(pub\s+)?trait\s+' src/ 2>/dev/null | wc -l | tr -d ' ') || true
|
|
143
143
|
if [ "$TRAITS" -gt 0 ]; then
|
|
144
144
|
pass "Trait definitions found ($TRAITS interfaces)"
|
|
145
145
|
else
|
|
@@ -46,7 +46,7 @@ TOTAL_RS=0
|
|
|
46
46
|
TOTAL_RS=$(find src -name "*.rs" 2>/dev/null | wc -l | tr -d ' ')
|
|
47
47
|
if [ "$TOTAL_RS" -gt 0 ]; then
|
|
48
48
|
# Look for canonical reference patterns in doc comments
|
|
49
|
-
CANONICAL_REFS=$(grep -rE '(///\s*Canonical:|//!\s*@canonical|///\s*Reference:)' src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
49
|
+
CANONICAL_REFS=$(grep -rE '(///\s*Canonical:|//!\s*@canonical|///\s*Reference:)' src/ 2>/dev/null | wc -l | tr -d ' ') || true
|
|
50
50
|
if [ "$CANONICAL_REFS" -gt 0 ]; then
|
|
51
51
|
PCT=$((CANONICAL_REFS * 100 / TOTAL_RS))
|
|
52
52
|
pass "Canonical references found: ${CANONICAL_REFS} files (${PCT}% of ${TOTAL_RS} Rust files)"
|
|
@@ -91,7 +91,7 @@ fi
|
|
|
91
91
|
echo ""
|
|
92
92
|
echo "--- Module Documentation ---"
|
|
93
93
|
if [ "$TOTAL_RS" -gt 0 ]; then
|
|
94
|
-
MOD_DOCS=$(grep -rlE '^//!\s' src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
94
|
+
MOD_DOCS=$(grep -rlE '^//!\s' src/ 2>/dev/null | wc -l | tr -d ' ') || true
|
|
95
95
|
if [ "$MOD_DOCS" -gt 0 ]; then
|
|
96
96
|
PCT=$((MOD_DOCS * 100 / TOTAL_RS))
|
|
97
97
|
pass "Module documentation found in ${MOD_DOCS}/${TOTAL_RS} files (${PCT}%)"
|
|
@@ -110,7 +110,7 @@ echo "--- ADR Linkage ---"
|
|
|
110
110
|
if [ -d ".pi/architecture/decisions" ]; then
|
|
111
111
|
ADR_FILES=$(find .pi/architecture/decisions -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
112
112
|
if [ "$ADR_FILES" -gt 0 ]; then
|
|
113
|
-
ADR_REFS=$(grep -rE '///\s*ADR-' src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
113
|
+
ADR_REFS=$(grep -rE '///\s*ADR-' src/ 2>/dev/null | wc -l | tr -d ' ') || true
|
|
114
114
|
if [ "$ADR_REFS" -gt 0 ]; then
|
|
115
115
|
pass "ADR references found in code ($ADR_REFS references)"
|
|
116
116
|
else
|
|
@@ -59,7 +59,7 @@ echo "--- SQL Injection ---"
|
|
|
59
59
|
SQL_INJECT=0
|
|
60
60
|
if grep -qE 'sqlx' Cargo.toml 2>/dev/null; then
|
|
61
61
|
# Check for unsafe query patterns: format! inside query! or query()
|
|
62
|
-
SQL_INJECT=$(grep -rE 'query\s*\(\s*(format!|format_args!)' src/ --include="*.rs" 2>/dev/null | wc -l | tr -d ' ')
|
|
62
|
+
SQL_INJECT=$(grep -rE 'query\s*\(\s*(format!|format_args!)' src/ --include="*.rs" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
63
63
|
fi
|
|
64
64
|
if [ "$SQL_INJECT" -gt 0 ]; then
|
|
65
65
|
fail "Potential SQL injection patterns found ($SQL_INJECT occurrences — avoid format! inside query)"
|
|
@@ -94,7 +94,7 @@ fi
|
|
|
94
94
|
# ---------------------------------------------------------------------------
|
|
95
95
|
echo ""
|
|
96
96
|
echo "--- Unsafe Code ---"
|
|
97
|
-
UNSAFE_BLOCKS=$(grep -rE 'unsafe\s*\{' --include="*.rs" src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
97
|
+
UNSAFE_BLOCKS=$(grep -rE 'unsafe\s*\{' --include="*.rs" src/ 2>/dev/null | wc -l | tr -d ' ') || true
|
|
98
98
|
if [ "$UNSAFE_BLOCKS" -gt 0 ]; then
|
|
99
99
|
warn "Unsafe code blocks found ($UNSAFE_BLOCKS occurrences — recommend manual audit)"
|
|
100
100
|
else
|
|
@@ -88,7 +88,7 @@ echo "--- Doctests ---"
|
|
|
88
88
|
if cargo test --doc --quiet 2>/dev/null; then
|
|
89
89
|
pass "Doctests passed"
|
|
90
90
|
else
|
|
91
|
-
DOCS=$(grep -rl '//!\|///' src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
91
|
+
DOCS=$(grep -rl '//!\|///' src/ 2>/dev/null | wc -l | tr -d ' ') || true
|
|
92
92
|
if [ "$DOCS" -eq 0 ]; then
|
|
93
93
|
pass "No doc comments found (no doctests to run)"
|
|
94
94
|
else
|
|
@@ -56,7 +56,7 @@ fi
|
|
|
56
56
|
echo ""
|
|
57
57
|
echo "--- Domain Models ---"
|
|
58
58
|
if [ -d "$SRC_DIR/domain" ]; then
|
|
59
|
-
DOMAIN_MODELS=$(find "$SRC_DIR/domain" -name "*.ts" -o -name "*.tsx" 2>/dev/null | xargs grep -lE '\b(interface|type|class)\b' 2>/dev/null | wc -l | tr -d ' ')
|
|
59
|
+
DOMAIN_MODELS=$(find "$SRC_DIR/domain" -name "*.ts" -o -name "*.tsx" 2>/dev/null | xargs grep -lE '\b(interface|type|class)\b' 2>/dev/null | wc -l | tr -d ' ') || true
|
|
60
60
|
if [ "$DOMAIN_MODELS" -gt 0 ]; then
|
|
61
61
|
pass "Domain model definitions found ($DOMAIN_MODELS files with interface/type/class)"
|
|
62
62
|
else
|
|
@@ -93,7 +93,7 @@ fi
|
|
|
93
93
|
echo ""
|
|
94
94
|
echo "--- Error Handling ---"
|
|
95
95
|
if [ -d "$SRC_DIR" ]; then
|
|
96
|
-
ERROR_CLASSES=$(grep -rE "class\s+\w+Error.*extends\s+(Error|AppError)" "$SRC_DIR" 2>/dev/null | wc -l | tr -d ' ')
|
|
96
|
+
ERROR_CLASSES=$(grep -rE "class\s+\w+Error.*extends\s+(Error|AppError)" "$SRC_DIR" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
97
97
|
if [ "$ERROR_CLASSES" -gt 0 ]; then
|
|
98
98
|
pass "Custom error classes defined ($ERROR_CLASSES found)"
|
|
99
99
|
else
|
|
@@ -109,7 +109,7 @@ fi
|
|
|
109
109
|
echo ""
|
|
110
110
|
echo "--- Interfaces / Contracts ---"
|
|
111
111
|
if [ -d "$SRC_DIR" ]; then
|
|
112
|
-
INTERFACE_COUNT=$(grep -rE "^\s*(export\s+)?interface\s+" "$SRC_DIR" --include="*.ts" --include="*.tsx" 2>/dev/null | wc -l | tr -d ' ')
|
|
112
|
+
INTERFACE_COUNT=$(grep -rE "^\s*(export\s+)?interface\s+" "$SRC_DIR" --include="*.ts" --include="*.tsx" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
113
113
|
if [ "$INTERFACE_COUNT" -gt 0 ]; then
|
|
114
114
|
pass "Interface contracts defined ($INTERFACE_COUNT found)"
|
|
115
115
|
else
|
|
@@ -25,7 +25,7 @@ CANONICAL_REFS=0
|
|
|
25
25
|
TOTAL_TS_FILES=0
|
|
26
26
|
if [ -d "$SRC_DIR" ]; then
|
|
27
27
|
TOTAL_TS_FILES=$(find "$SRC_DIR" -name "*.ts" -o -name "*.tsx" 2>/dev/null | wc -l | tr -d ' ')
|
|
28
|
-
CANONICAL_REFS=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -exec grep -lE '(// Canonical:|@canonical).*\.pi/architecture/' {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
28
|
+
CANONICAL_REFS=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -exec grep -lE '(// Canonical:|@canonical).*\.pi/architecture/' {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
29
29
|
if [ "$TOTAL_TS_FILES" -gt 0 ] && [ "$CANONICAL_REFS" -gt 0 ]; then
|
|
30
30
|
PCT=$((CANONICAL_REFS * 100 / TOTAL_TS_FILES))
|
|
31
31
|
pass "Canonical references found: $CANONICAL_REFS / $TOTAL_TS_FILES files ($PCT%)"
|
|
@@ -77,7 +77,7 @@ if [ -d "$SRC_DIR" ]; then
|
|
|
77
77
|
EXPORT_WITH_DOCS=0
|
|
78
78
|
EXPORTS_TOTAL=0
|
|
79
79
|
# Check for documented exports: JSDoc comment (/** ... */) immediately before export
|
|
80
|
-
EXPORTS_TOTAL=$(grep -rE "^\s*(export\s+(const|function|class|interface|type|default))" "$SRC_DIR" --include="*.ts" --include="*.tsx" 2>/dev/null | wc -l | tr -d ' ')
|
|
80
|
+
EXPORTS_TOTAL=$(grep -rE "^\s*(export\s+(const|function|class|interface|type|default))" "$SRC_DIR" --include="*.ts" --include="*.tsx" 2>/dev/null | wc -l | tr -d ' ') || true
|
|
81
81
|
EXPORT_WITH_DOCS=$(grep -B1 -rE "^\s*(export\s+(const|function|class|interface|type|default))" "$SRC_DIR" --include="*.ts" --include="*.tsx" 2>/dev/null | grep -c '\*/' 2>/dev/null || echo "0")
|
|
82
82
|
if [ "$EXPORTS_TOTAL" -gt 0 ]; then
|
|
83
83
|
if [ "$EXPORT_WITH_DOCS" -gt 0 ]; then
|
|
@@ -100,7 +100,7 @@ echo ""
|
|
|
100
100
|
echo "--- ADR Linkage ---"
|
|
101
101
|
if [ -d ".pi/architecture/decisions" ]; then
|
|
102
102
|
ADR_FILES=$(find .pi/architecture/decisions -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
103
|
-
ADR_REFS=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -exec grep -rlE '(@adr|ADR-)' {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
103
|
+
ADR_REFS=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -exec grep -rlE '(@adr|ADR-)' {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
104
104
|
if [ "$ADR_FILES" -gt 0 ] && [ "$ADR_REFS" -gt 0 ]; then
|
|
105
105
|
pass "ADR references found: $ADR_REFS files link to $ADR_FILES decisions"
|
|
106
106
|
elif [ "$ADR_FILES" -gt 0 ]; then
|
|
@@ -99,7 +99,7 @@ echo "--- Mock/Stub Detection ---"
|
|
|
99
99
|
MOCK_USAGE=0
|
|
100
100
|
for ext in ts tsx; do
|
|
101
101
|
COUNT=$(find . -name "*.$ext" -not -path "./node_modules/*" -not -path "./dist/*" \
|
|
102
|
-
-exec grep -lE "(vitest\.mock|jest\.mock|from\s+['\"]msw['\"]|from\s+['\"]@testing-library)" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
102
|
+
-exec grep -lE "(vitest\.mock|jest\.mock|from\s+['\"]msw['\"]|from\s+['\"]@testing-library)" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
103
103
|
MOCK_USAGE=$((MOCK_USAGE + COUNT))
|
|
104
104
|
done
|
|
105
105
|
if [ "$MOCK_USAGE" -gt 0 ]; then
|
|
@@ -134,7 +134,7 @@ echo "--- HTTP Integration ---"
|
|
|
134
134
|
HTTP_LIBS=0
|
|
135
135
|
for ext in ts tsx; do
|
|
136
136
|
COUNT=$(find . -name "*.$ext" -not -path "./node_modules/*" -not -path "./dist/*" \
|
|
137
|
-
-exec grep -lE "(supertest|msw|@testing-library)" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
137
|
+
-exec grep -lE "(supertest|msw|@testing-library)" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
138
138
|
HTTP_LIBS=$((HTTP_LIBS + COUNT))
|
|
139
139
|
done
|
|
140
140
|
if [ "$HTTP_LIBS" -gt 0 ]; then
|
|
@@ -32,7 +32,7 @@ if [ -d "$SRC_DIR" ] || [ -d "." ]; then
|
|
|
32
32
|
for dir in $SEARCH_DIRS; do
|
|
33
33
|
[ -d "$dir" ] || continue
|
|
34
34
|
FOUND=$(find "$dir" -type f \( -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*" \
|
|
35
|
-
-exec grep -lE "(winston|pino|bunyan|console\.(log|info|warn|error))" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
35
|
+
-exec grep -lE "(winston|pino|bunyan|console\.(log|info|warn|error))" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
36
36
|
LOGGING_LIBS=$((LOGGING_LIBS + FOUND))
|
|
37
37
|
done
|
|
38
38
|
if [ "$LOGGING_LIBS" -gt 0 ]; then
|
|
@@ -52,7 +52,7 @@ echo "--- Health Checks ---"
|
|
|
52
52
|
HEALTH_ROUTES=0
|
|
53
53
|
if [ -d "$SRC_DIR" ]; then
|
|
54
54
|
HEALTH_ROUTES=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*" \
|
|
55
|
-
-exec grep -lE "(/health[^/]?|/healthz|/ready|/readiness)" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
55
|
+
-exec grep -lE "(/health[^/]?|/healthz|/ready|/readiness)" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
56
56
|
if [ "$HEALTH_ROUTES" -gt 0 ]; then
|
|
57
57
|
pass "Health check endpoints found ($HEALTH_ROUTES files)"
|
|
58
58
|
else
|
|
@@ -70,7 +70,7 @@ echo "--- Graceful Shutdown ---"
|
|
|
70
70
|
SHUTDOWN_HANDLERS=0
|
|
71
71
|
if [ -d "$SRC_DIR" ]; then
|
|
72
72
|
SHUTDOWN_HANDLERS=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*" \
|
|
73
|
-
-exec grep -lE "process\.on\(['\"]SIG(TERM|INT)['\"]" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
73
|
+
-exec grep -lE "process\.on\(['\"]SIG(TERM|INT)['\"]" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
74
74
|
if [ "$SHUTDOWN_HANDLERS" -gt 0 ]; then
|
|
75
75
|
pass "Graceful shutdown handlers found ($SHUTDOWN_HANDLERS files)"
|
|
76
76
|
else
|
|
@@ -88,7 +88,7 @@ echo "--- Metrics ---"
|
|
|
88
88
|
METRICS_LIBS=0
|
|
89
89
|
if [ -d "$SRC_DIR" ]; then
|
|
90
90
|
METRICS_LIBS=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*" \
|
|
91
|
-
-exec grep -lE "(prom-client|@opentelemetry|statsd|hot-shots|dd-trace)" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
91
|
+
-exec grep -lE "(prom-client|@opentelemetry|statsd|hot-shots|dd-trace)" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
92
92
|
if [ "$METRICS_LIBS" -gt 0 ]; then
|
|
93
93
|
pass "Metrics/observability libraries detected ($METRICS_LIBS files)"
|
|
94
94
|
else
|
|
@@ -107,10 +107,10 @@ ERROR_PATTERNS=0
|
|
|
107
107
|
if [ -d "$SRC_DIR" ]; then
|
|
108
108
|
# Check for try/catch blocks
|
|
109
109
|
TRY_CATCH=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*" \
|
|
110
|
-
-exec grep -lE "try\s*\{" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
110
|
+
-exec grep -lE "try\s*\{" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
111
111
|
# Check for error middleware (Express-style)
|
|
112
112
|
ERROR_MIDDLEWARE=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*" \
|
|
113
|
-
-exec grep -lE "error.*:.*Error.*req.*res" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
113
|
+
-exec grep -lE "error.*:.*Error.*req.*res" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
114
114
|
ERROR_PATTERNS=$((TRY_CATCH + ERROR_MIDDLEWARE))
|
|
115
115
|
if [ "$ERROR_PATTERNS" -gt 0 ]; then
|
|
116
116
|
pass "Error handling patterns found ($ERROR_PATTERNS files with try/catch or error middleware)"
|
|
@@ -129,7 +129,7 @@ echo "--- Configuration ---"
|
|
|
129
129
|
CONFIG_FOUND=0
|
|
130
130
|
if [ -d "$SRC_DIR" ]; then
|
|
131
131
|
CONFIG_FOUND=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*" \
|
|
132
|
-
-exec grep -lE "(dotenv|require\(['\"]config['\"]\)|process\.env)" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
132
|
+
-exec grep -lE "(dotenv|require\(['\"]config['\"]\)|process\.env)" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
133
133
|
if [ "$CONFIG_FOUND" -gt 0 ]; then
|
|
134
134
|
pass "Configuration management detected ($CONFIG_FOUND files with dotenv/config/process.env)"
|
|
135
135
|
else
|
|
@@ -32,7 +32,7 @@ echo "--- Hardcoded Secrets ---"
|
|
|
32
32
|
SECRET_COUNT=0
|
|
33
33
|
for ext in ts tsx; do
|
|
34
34
|
COUNT=$(find . -name "*.$ext" -not -path "./node_modules/*" -not -path "./.next/*" -not -path "./dist/*" \
|
|
35
|
-
-exec grep -E "(apiKey|api_key|apiKey|secret|password|token|privateKey)\s*[:=]\s*['\"][^'\"]{8,}['\"]" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
35
|
+
-exec grep -E "(apiKey|api_key|apiKey|secret|password|token|privateKey)\s*[:=]\s*['\"][^'\"]{8,}['\"]" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
36
36
|
SECRET_COUNT=$((SECRET_COUNT + COUNT))
|
|
37
37
|
done
|
|
38
38
|
if [ "$SECRET_COUNT" -eq 0 ]; then
|
|
@@ -50,7 +50,7 @@ INJECTION_PATTERNS=0
|
|
|
50
50
|
for ext in ts tsx; do
|
|
51
51
|
# Template literals used with query/exec calls
|
|
52
52
|
COUNT=$(find . -name "*.$ext" -not -path "./node_modules/*" -not -path "./.next/*" -not -path "./dist/*" \
|
|
53
|
-
-exec grep -E "\.(query|exec)\(\s*\`" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
53
|
+
-exec grep -E "\.(query|exec)\(\s*\`" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
54
54
|
INJECTION_PATTERNS=$((INJECTION_PATTERNS + COUNT))
|
|
55
55
|
done
|
|
56
56
|
if [ "$INJECTION_PATTERNS" -eq 0 ]; then
|
|
@@ -97,7 +97,7 @@ echo "--- eval / Dangerous Patterns ---"
|
|
|
97
97
|
DANGEROUS_COUNT=0
|
|
98
98
|
for ext in ts tsx; do
|
|
99
99
|
COUNT=$(find . -name "*.$ext" -not -path "./node_modules/*" -not -path "./.next/*" -not -path "./dist/*" \
|
|
100
|
-
-exec grep -E "(eval\(|innerHTML\s*=|dangerouslySetInnerHTML)" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
100
|
+
-exec grep -E "(eval\(|innerHTML\s*=|dangerouslySetInnerHTML)" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
101
101
|
DANGEROUS_COUNT=$((DANGEROUS_COUNT + COUNT))
|
|
102
102
|
done
|
|
103
103
|
if [ "$DANGEROUS_COUNT" -eq 0 ]; then
|
|
@@ -114,7 +114,7 @@ echo "--- XSS Prevention ---"
|
|
|
114
114
|
SANITIZE_LIBS=0
|
|
115
115
|
for ext in ts tsx; do
|
|
116
116
|
COUNT=$(find . -name "*.$ext" -not -path "./node_modules/*" -not -path "./.next/*" -not -path "./dist/*" \
|
|
117
|
-
-exec grep -lE "(DOMPurify|sanitize-html|xss|sanitize)" {} + 2>/dev/null | wc -l | tr -d ' ')
|
|
117
|
+
-exec grep -lE "(DOMPurify|sanitize-html|xss|sanitize)" {} + 2>/dev/null | wc -l | tr -d ' ') || true
|
|
118
118
|
SANITIZE_LIBS=$((SANITIZE_LIBS + COUNT))
|
|
119
119
|
done
|
|
120
120
|
if [ "$SANITIZE_LIBS" -gt 0 ]; then
|