pi-lens 2.2.9 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +198 -0
- package/README.md +709 -519
- package/clients/__tests__/file-time.test.js +216 -0
- package/clients/__tests__/file-time.test.ts +276 -0
- package/clients/__tests__/format-service.test.js +245 -0
- package/clients/__tests__/format-service.test.ts +339 -0
- package/clients/__tests__/formatters.test.js +271 -0
- package/clients/__tests__/formatters.test.ts +401 -0
- package/clients/amain-types.js +164 -0
- package/clients/amain-types.ts +165 -0
- package/clients/architect-client.js +56 -12
- package/clients/architect-client.ts +81 -16
- package/clients/ast-grep-client.js +2 -2
- package/clients/ast-grep-client.ts +14 -39
- package/clients/ast-grep-parser.ts +1 -1
- package/clients/ast-grep-rule-manager.js +8 -0
- package/clients/ast-grep-rule-manager.ts +10 -1
- package/clients/ast-grep-types.js +9 -0
- package/clients/ast-grep-types.ts +106 -0
- package/clients/auto-loop.js +10 -0
- package/clients/auto-loop.ts +14 -1
- package/clients/biome-client.js +81 -19
- package/clients/biome-client.ts +103 -22
- package/clients/bus/bus.js +191 -0
- package/clients/bus/bus.ts +251 -0
- package/clients/bus/events.js +214 -0
- package/clients/bus/events.ts +279 -0
- package/clients/bus/index.js +8 -0
- package/clients/bus/index.ts +9 -0
- package/clients/bus/integration.js +158 -0
- package/clients/bus/integration.ts +214 -0
- package/clients/complexity-client.js +13 -7
- package/clients/complexity-client.ts +13 -7
- package/clients/config-validator.js +465 -0
- package/clients/config-validator.ts +558 -0
- package/clients/dependency-checker.js +4 -10
- package/clients/dependency-checker.ts +4 -10
- package/clients/dispatch/__tests__/autofix-integration.test.js +245 -0
- package/clients/dispatch/__tests__/autofix-integration.test.ts +300 -0
- package/clients/dispatch/__tests__/runner-registration.test.js +236 -0
- package/clients/dispatch/__tests__/runner-registration.test.ts +282 -0
- package/clients/dispatch/bus-dispatcher.js +177 -0
- package/clients/dispatch/bus-dispatcher.ts +251 -0
- package/clients/dispatch/dispatcher.edge.test.js +82 -0
- package/clients/dispatch/dispatcher.edge.test.ts +100 -0
- package/clients/dispatch/dispatcher.format.test.js +46 -0
- package/clients/dispatch/dispatcher.format.test.ts +58 -0
- package/clients/dispatch/dispatcher.inline.test.js +74 -0
- package/clients/dispatch/dispatcher.inline.test.ts +93 -0
- package/clients/dispatch/dispatcher.js +19 -53
- package/clients/dispatch/dispatcher.ts +20 -67
- package/clients/dispatch/plan.js +9 -4
- package/clients/dispatch/plan.ts +9 -4
- package/clients/dispatch/runners/architect.js +21 -7
- package/clients/dispatch/runners/architect.test.js +138 -0
- package/clients/dispatch/runners/architect.test.ts +162 -0
- package/clients/dispatch/runners/architect.ts +22 -7
- package/clients/dispatch/runners/ast-grep-napi.js +462 -0
- package/clients/dispatch/runners/ast-grep-napi.test.js +111 -0
- package/clients/dispatch/runners/ast-grep-napi.test.ts +133 -0
- package/clients/dispatch/runners/ast-grep-napi.ts +506 -0
- package/clients/dispatch/runners/ast-grep.js +62 -19
- package/clients/dispatch/runners/ast-grep.ts +70 -18
- package/clients/dispatch/runners/biome.js +29 -53
- package/clients/dispatch/runners/biome.ts +29 -63
- package/clients/dispatch/runners/config-validation.js +67 -0
- package/clients/dispatch/runners/config-validation.ts +82 -0
- package/clients/dispatch/runners/go-vet.js +4 -28
- package/clients/dispatch/runners/go-vet.ts +4 -32
- package/clients/dispatch/runners/index.js +30 -10
- package/clients/dispatch/runners/index.ts +30 -10
- package/clients/dispatch/runners/oxlint.js +141 -0
- package/clients/dispatch/runners/oxlint.test.js +230 -0
- package/clients/dispatch/runners/oxlint.test.ts +303 -0
- package/clients/dispatch/runners/oxlint.ts +175 -0
- package/clients/dispatch/runners/pyright.js +40 -70
- package/clients/dispatch/runners/pyright.test.js +16 -2
- package/clients/dispatch/runners/pyright.test.ts +14 -2
- package/clients/dispatch/runners/pyright.ts +48 -91
- package/clients/dispatch/runners/python-slop.js +97 -0
- package/clients/dispatch/runners/python-slop.test.js +203 -0
- package/clients/dispatch/runners/python-slop.test.ts +298 -0
- package/clients/dispatch/runners/python-slop.ts +124 -0
- package/clients/dispatch/runners/ruff.js +18 -71
- package/clients/dispatch/runners/ruff.ts +19 -79
- package/clients/dispatch/runners/rust-clippy.js +28 -32
- package/clients/dispatch/runners/rust-clippy.ts +29 -31
- package/clients/dispatch/runners/scan_codebase.test.js +89 -0
- package/clients/dispatch/runners/scan_codebase.test.ts +105 -0
- package/clients/dispatch/runners/shellcheck.js +147 -0
- package/clients/dispatch/runners/shellcheck.test.js +98 -0
- package/clients/dispatch/runners/shellcheck.test.ts +129 -0
- package/clients/dispatch/runners/shellcheck.ts +188 -0
- package/clients/dispatch/runners/similarity.js +230 -0
- package/clients/dispatch/runners/similarity.ts +339 -0
- package/clients/dispatch/runners/spellcheck.js +106 -0
- package/clients/dispatch/runners/spellcheck.test.js +158 -0
- package/clients/dispatch/runners/spellcheck.test.ts +214 -0
- package/clients/dispatch/runners/spellcheck.ts +136 -0
- package/clients/dispatch/runners/tree-sitter.js +107 -0
- package/clients/dispatch/runners/tree-sitter.ts +135 -0
- package/clients/dispatch/runners/ts-lsp.js +104 -33
- package/clients/dispatch/runners/ts-lsp.ts +120 -38
- package/clients/dispatch/runners/ts-slop.js +113 -0
- package/clients/dispatch/runners/ts-slop.test.js +180 -0
- package/clients/dispatch/runners/ts-slop.test.ts +230 -0
- package/clients/dispatch/runners/ts-slop.ts +142 -0
- package/clients/dispatch/runners/utils/diagnostic-parsers.js +134 -0
- package/clients/dispatch/runners/utils/diagnostic-parsers.ts +186 -0
- package/clients/dispatch/runners/utils/runner-helpers.js +115 -0
- package/clients/dispatch/runners/utils/runner-helpers.ts +167 -0
- package/clients/dispatch/runners/utils.js +2 -4
- package/clients/dispatch/runners/utils.ts +2 -4
- package/clients/dispatch/types.ts +1 -1
- package/clients/dispatch/utils/format-utils.js +49 -0
- package/clients/dispatch/utils/format-utils.ts +60 -0
- package/clients/dogfood.test.js +201 -0
- package/clients/dogfood.test.ts +269 -0
- package/clients/file-time.js +152 -0
- package/clients/file-time.ts +208 -0
- package/clients/file-utils.js +40 -0
- package/clients/file-utils.ts +44 -0
- package/clients/fix-scanners.js +10 -20
- package/clients/fix-scanners.ts +10 -22
- package/clients/format-service.js +172 -0
- package/clients/format-service.ts +254 -0
- package/clients/formatters.js +435 -0
- package/clients/formatters.ts +508 -0
- package/clients/go-client.js +5 -14
- package/clients/go-client.ts +5 -13
- package/clients/installer/index.js +356 -0
- package/clients/installer/index.ts +426 -0
- package/clients/jscpd-client.js +11 -9
- package/clients/jscpd-client.ts +12 -8
- package/clients/knip-client.js +3 -7
- package/clients/knip-client.ts +3 -6
- package/clients/lsp/__tests__/client.test.js +325 -0
- package/clients/lsp/__tests__/client.test.ts +434 -0
- package/clients/lsp/__tests__/config.test.js +166 -0
- package/clients/lsp/__tests__/config.test.ts +209 -0
- package/clients/lsp/__tests__/error-recovery.test.js +213 -0
- package/clients/lsp/__tests__/error-recovery.test.ts +279 -0
- package/clients/lsp/__tests__/integration.test.js +127 -0
- package/clients/lsp/__tests__/integration.test.ts +160 -0
- package/clients/lsp/__tests__/launch.test.js +260 -0
- package/clients/lsp/__tests__/launch.test.ts +329 -0
- package/clients/lsp/__tests__/server.test.js +259 -0
- package/clients/lsp/__tests__/server.test.ts +332 -0
- package/clients/lsp/__tests__/service.test.js +417 -0
- package/clients/lsp/__tests__/service.test.ts +499 -0
- package/clients/lsp/client.js +235 -0
- package/clients/lsp/client.ts +328 -0
- package/clients/lsp/config.js +115 -0
- package/clients/lsp/config.ts +149 -0
- package/clients/lsp/index.js +222 -0
- package/clients/lsp/index.ts +280 -0
- package/clients/lsp/installer/index.js +391 -0
- package/clients/lsp/interactive-install.js +210 -0
- package/clients/lsp/interactive-install.ts +251 -0
- package/clients/lsp/language.js +170 -0
- package/clients/lsp/language.ts +216 -0
- package/clients/lsp/launch.js +174 -0
- package/clients/lsp/launch.ts +240 -0
- package/clients/lsp/lsp/launch.js +116 -0
- package/clients/lsp/lsp/server.js +532 -0
- package/clients/lsp/lsp-index.js +10 -0
- package/clients/lsp/lsp-index.ts +11 -0
- package/clients/lsp/path-utils.js +48 -0
- package/clients/lsp/path-utils.ts +52 -0
- package/clients/lsp/server.js +615 -0
- package/clients/lsp/server.ts +800 -0
- package/clients/lsp/test-py-spawn/requirements.txt +1 -0
- package/clients/lsp/test-py-spawn/test.py +3 -0
- package/clients/lsp/test-py-svc/requirements.txt +1 -0
- package/clients/lsp/test-py-svc/test.py +3 -0
- package/clients/lsp/test-python-project/requirements.txt +1 -0
- package/clients/lsp/test-python-project/test.py +5 -0
- package/clients/metrics-history.js +2 -2
- package/clients/metrics-history.ts +2 -2
- package/clients/production-readiness.js +522 -0
- package/clients/production-readiness.ts +556 -0
- package/clients/project-index.js +255 -0
- package/clients/project-index.ts +383 -0
- package/clients/project-metadata.js +531 -0
- package/clients/project-metadata.ts +624 -0
- package/clients/ruff-client.js +56 -16
- package/clients/ruff-client.ts +72 -15
- package/clients/runner-tracker.js +152 -0
- package/clients/runner-tracker.ts +213 -0
- package/clients/rust-client.js +4 -11
- package/clients/rust-client.ts +5 -11
- package/clients/safe-spawn.js +96 -0
- package/clients/safe-spawn.ts +128 -0
- package/clients/scan-architectural-debt.js +3 -6
- package/clients/scan-architectural-debt.ts +3 -6
- package/clients/scan-utils.js +5 -20
- package/clients/scan-utils.ts +5 -29
- package/clients/secrets-scanner.js +3 -17
- package/clients/secrets-scanner.ts +4 -20
- package/clients/services/__tests__/effect-integration.test.js +86 -0
- package/clients/services/__tests__/effect-integration.test.ts +111 -0
- package/clients/services/effect-integration.js +194 -0
- package/clients/services/effect-integration.ts +268 -0
- package/clients/services/index.js +7 -0
- package/clients/services/index.ts +8 -0
- package/clients/services/runner-service.js +105 -0
- package/clients/services/runner-service.ts +179 -0
- package/clients/sg-runner.js +87 -13
- package/clients/sg-runner.ts +97 -13
- package/clients/state-matrix.js +160 -0
- package/clients/state-matrix.ts +202 -0
- package/clients/subprocess-client.js +10 -9
- package/clients/subprocess-client.ts +10 -8
- package/clients/test-runner-client.js +3 -7
- package/clients/test-runner-client.ts +3 -6
- package/clients/tool-availability.js +4 -10
- package/clients/tool-availability.ts +4 -9
- package/clients/tree-sitter-client.js +564 -0
- package/clients/tree-sitter-client.ts +797 -0
- package/clients/tree-sitter-query-loader.js +355 -0
- package/clients/tree-sitter-query-loader.ts +425 -0
- package/clients/type-coverage-client.js +3 -7
- package/clients/type-coverage-client.ts +3 -6
- package/clients/typescript-client.codefix.test.js +157 -0
- package/clients/typescript-client.codefix.test.ts +186 -0
- package/clients/typescript-client.js +43 -0
- package/clients/typescript-client.ts +98 -0
- package/commands/booboo.js +799 -219
- package/commands/booboo.ts +1004 -225
- package/commands/clients/ast-grep-client.js +250 -0
- package/commands/clients/ast-grep-parser.js +86 -0
- package/commands/clients/ast-grep-rule-manager.js +91 -0
- package/commands/clients/ast-grep-types.js +9 -0
- package/commands/clients/biome-client.js +380 -0
- package/commands/clients/complexity-client.js +667 -0
- package/commands/clients/file-kinds.js +177 -0
- package/commands/clients/file-utils.js +40 -0
- package/commands/clients/jscpd-client.js +169 -0
- package/commands/clients/knip-client.js +211 -0
- package/commands/clients/ruff-client.js +297 -0
- package/commands/clients/safe-spawn.js +88 -0
- package/commands/clients/scan-utils.js +83 -0
- package/commands/clients/sg-runner.js +190 -0
- package/commands/clients/types.js +11 -0
- package/commands/clients/typescript-client.js +505 -0
- package/commands/fix-from-booboo.js +398 -0
- package/commands/fix-from-booboo.ts +485 -0
- package/commands/fix-simplified.js +618 -0
- package/commands/fix-simplified.ts +768 -0
- package/commands/rate.js +10 -14
- package/commands/rate.ts +9 -16
- package/default-architect.yaml +59 -15
- package/index.ts +342 -429
- package/package.json +16 -3
- package/rules/ast-grep-rules/rules/empty-catch.yml +38 -13
- package/rules/ast-grep-rules/rules/no-array-constructor.yml +1 -0
- package/rules/ast-grep-rules/rules/no-debugger.yml +2 -0
- package/rules/python-slop-rules/.sgconfig.yml +4 -0
- package/rules/python-slop-rules/rules/slop-rules.yml +647 -0
- package/rules/tree-sitter-queries/python/bare-except.yml +54 -0
- package/rules/tree-sitter-queries/python/eval-exec.yml +50 -0
- package/rules/tree-sitter-queries/python/is-vs-equals.yml +60 -0
- package/rules/tree-sitter-queries/python/mutable-default-arg.yml +57 -0
- package/rules/tree-sitter-queries/python/unreachable-except.yml +60 -0
- package/rules/tree-sitter-queries/python/wildcard-import.yml +46 -0
- package/rules/tree-sitter-queries/tsx/dangerously-set-inner-html.yml +63 -0
- package/rules/tree-sitter-queries/typescript/await-in-loop.yml +56 -0
- package/rules/tree-sitter-queries/typescript/console-statement.yml +47 -0
- package/rules/tree-sitter-queries/typescript/debugger.yml +47 -0
- package/rules/tree-sitter-queries/typescript/deep-nesting.yml +117 -0
- package/rules/tree-sitter-queries/typescript/deep-promise-chain.yml +73 -0
- package/rules/tree-sitter-queries/typescript/empty-catch.yml +64 -0
- package/rules/tree-sitter-queries/typescript/eval.yml +48 -0
- package/rules/tree-sitter-queries/typescript/hardcoded-secrets.yml +78 -0
- package/rules/tree-sitter-queries/typescript/long-parameter-list.yml +62 -0
- package/rules/tree-sitter-queries/typescript/mixed-async-styles.yml +49 -0
- package/rules/tree-sitter-queries/typescript/nested-ternary.yml +45 -0
- package/rules/ts-slop-rules/.sgconfig.yml +4 -0
- package/rules/ts-slop-rules/rules/in-correct-optional-input-type.yml +10 -0
- package/rules/ts-slop-rules/rules/jwt-no-verify.yml +13 -0
- package/rules/ts-slop-rules/rules/no-architecture-violation.yml +10 -0
- package/rules/ts-slop-rules/rules/no-case-declarations.yml +10 -0
- package/rules/ts-slop-rules/rules/no-dangerously-set-inner-html.yml +10 -0
- package/rules/ts-slop-rules/rules/no-debugger.yml +10 -0
- package/rules/ts-slop-rules/rules/no-dupe-args.yml +10 -0
- package/rules/ts-slop-rules/rules/no-dupe-class-members.yml +10 -0
- package/rules/ts-slop-rules/rules/no-dupe-keys.yml +10 -0
- package/rules/ts-slop-rules/rules/no-eval.yml +13 -0
- package/rules/ts-slop-rules/rules/no-hardcoded-secrets.yml +12 -0
- package/rules/ts-slop-rules/rules/no-implied-eval.yml +12 -0
- package/rules/ts-slop-rules/rules/no-inner-html.yml +13 -0
- package/rules/ts-slop-rules/rules/no-javascript-url.yml +10 -0
- package/rules/ts-slop-rules/rules/no-mutable-default.yml +10 -0
- package/rules/ts-slop-rules/rules/no-nested-links.yml +12 -0
- package/rules/ts-slop-rules/rules/no-new-symbol.yml +10 -0
- package/rules/ts-slop-rules/rules/no-new-wrappers.yml +13 -0
- package/rules/ts-slop-rules/rules/no-open-redirect.yml +16 -0
- package/rules/ts-slop-rules/rules/slop-rules.yml +455 -0
- package/rules/ts-slop-rules/rules/weak-rsa-key.yml +12 -0
- package/skills/ast-grep/SKILL.md +182 -0
- package/clients/dispatch/runners/secrets.js +0 -109
- package/commands/fix.js +0 -244
- package/commands/fix.ts +0 -373
- package/rules/ast-grep-rules/rules/no-lonely-if.yml +0 -13
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Empty Catch Block
|
|
2
|
+
# Detects catch blocks that silently swallow errors
|
|
3
|
+
id: empty-catch
|
|
4
|
+
name: Empty Catch Block
|
|
5
|
+
severity: error
|
|
6
|
+
category: reliability
|
|
7
|
+
language: typescript
|
|
8
|
+
|
|
9
|
+
message: "Empty catch block — properly handle or log the error"
|
|
10
|
+
|
|
11
|
+
description: |
|
|
12
|
+
Silently swallowing errors makes debugging impossible.
|
|
13
|
+
|
|
14
|
+
✅ PROPER FIXES (choose one):
|
|
15
|
+
1. Log the error: console.error(`[context] Failed to X:`, err)
|
|
16
|
+
2. Rethrow if can't handle: throw err
|
|
17
|
+
3. Return a safe default: return null / return [] / return defaultValue
|
|
18
|
+
4. Handle specific errors: if (err.code === 'ENOENT') { ... }
|
|
19
|
+
5. Propagate to caller: callback(err) / reject(err)
|
|
20
|
+
|
|
21
|
+
❌ NOT ACCEPTABLE:
|
|
22
|
+
- void err; (just references variable, does nothing)
|
|
23
|
+
- /* ignored */ comments without action
|
|
24
|
+
- console.log without the error object
|
|
25
|
+
|
|
26
|
+
query: |
|
|
27
|
+
(catch_clause
|
|
28
|
+
(identifier) @ERR
|
|
29
|
+
(statement_block) @BODY)
|
|
30
|
+
|
|
31
|
+
# Post-filter: Check if body is effectively empty (ignoring comments)
|
|
32
|
+
post_filter: empty_body
|
|
33
|
+
|
|
34
|
+
# Capture metavariables
|
|
35
|
+
metavars:
|
|
36
|
+
- ERR # The error parameter name
|
|
37
|
+
- BODY # The catch block body
|
|
38
|
+
|
|
39
|
+
# Additional metadata
|
|
40
|
+
tags:
|
|
41
|
+
- security
|
|
42
|
+
- debugging
|
|
43
|
+
- reliability
|
|
44
|
+
- best-practice
|
|
45
|
+
|
|
46
|
+
# Examples for documentation
|
|
47
|
+
examples:
|
|
48
|
+
bad: |
|
|
49
|
+
try {
|
|
50
|
+
await fetch('/api');
|
|
51
|
+
} catch (err) {
|
|
52
|
+
// Empty - BAD!
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
good: |
|
|
56
|
+
try {
|
|
57
|
+
await fetch('/api');
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.error('[API] Fetch failed:', err);
|
|
60
|
+
throw err; // or return safe default
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Auto-fix available
|
|
64
|
+
has_fix: false
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Eval Usage
|
|
2
|
+
# Detects eval() calls (security risk)
|
|
3
|
+
id: no-eval
|
|
4
|
+
name: Eval Usage
|
|
5
|
+
severity: error
|
|
6
|
+
category: security
|
|
7
|
+
language: typescript
|
|
8
|
+
|
|
9
|
+
message: "eval() detected — security risk, never use eval"
|
|
10
|
+
|
|
11
|
+
description: |
|
|
12
|
+
eval() executes arbitrary code and is a major security vulnerability.
|
|
13
|
+
It allows code injection attacks.
|
|
14
|
+
|
|
15
|
+
✅ ALTERNATIVES:
|
|
16
|
+
- JSON.parse() for parsing JSON
|
|
17
|
+
- Function constructor for dynamic functions (still risky)
|
|
18
|
+
- Template literals for string interpolation
|
|
19
|
+
- Proper parsing libraries for complex needs
|
|
20
|
+
|
|
21
|
+
query: |
|
|
22
|
+
(call_expression
|
|
23
|
+
function: (identifier) @FUNC
|
|
24
|
+
(#eq? @FUNC "eval")
|
|
25
|
+
arguments: (arguments) @ARGS)
|
|
26
|
+
|
|
27
|
+
metavars:
|
|
28
|
+
- FUNC
|
|
29
|
+
- ARGS
|
|
30
|
+
|
|
31
|
+
tags:
|
|
32
|
+
- security
|
|
33
|
+
- xss
|
|
34
|
+
- owasp
|
|
35
|
+
|
|
36
|
+
examples:
|
|
37
|
+
bad: |
|
|
38
|
+
const userCode = "alert('hacked')";
|
|
39
|
+
eval(userCode); // DON'T DO THIS
|
|
40
|
+
|
|
41
|
+
good: |
|
|
42
|
+
// Use JSON.parse for JSON
|
|
43
|
+
const data = JSON.parse(jsonString);
|
|
44
|
+
|
|
45
|
+
// Use template literals
|
|
46
|
+
const message = `Hello, ${name}`;
|
|
47
|
+
|
|
48
|
+
has_fix: false
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Hardcoded Secrets
|
|
2
|
+
# Detects hardcoded API keys, passwords, tokens in code
|
|
3
|
+
id: hardcoded-secrets
|
|
4
|
+
name: Hardcoded Secret
|
|
5
|
+
severity: error
|
|
6
|
+
category: security
|
|
7
|
+
language: typescript
|
|
8
|
+
|
|
9
|
+
message: "Hardcoded {{VARNAME}} — use environment variables"
|
|
10
|
+
|
|
11
|
+
description: |
|
|
12
|
+
Hardcoded secrets in source code are a serious security risk.
|
|
13
|
+
They can be exposed through:
|
|
14
|
+
- Git history (even if deleted)
|
|
15
|
+
- Decompiled code
|
|
16
|
+
- Public repositories
|
|
17
|
+
|
|
18
|
+
✅ FIX: Use environment variables
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
const apiKey = process.env.API_KEY;
|
|
22
|
+
if (!apiKey) throw new Error('API_KEY not set');
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Then add to .env file (which should be in .gitignore):
|
|
26
|
+
```
|
|
27
|
+
API_KEY=your_secret_here
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
query: |
|
|
31
|
+
(lexical_declaration
|
|
32
|
+
(variable_declarator
|
|
33
|
+
name: (identifier) @VARNAME
|
|
34
|
+
value: (string) @SECRET))
|
|
35
|
+
(#match? @VARNAME "^(api_key|apikey|password|secret|token|auth|private_key|access_token)$")
|
|
36
|
+
(assignment_expression
|
|
37
|
+
left: (identifier) @VARNAME
|
|
38
|
+
right: (string) @SECRET)
|
|
39
|
+
(#match? @VARNAME "^(api_key|apikey|password|secret|token|auth|private_key|access_token)$")
|
|
40
|
+
|
|
41
|
+
metavars:
|
|
42
|
+
- VARNAME
|
|
43
|
+
- SECRET
|
|
44
|
+
|
|
45
|
+
tags:
|
|
46
|
+
- security
|
|
47
|
+
- secrets
|
|
48
|
+
- best-practice
|
|
49
|
+
- owasp
|
|
50
|
+
|
|
51
|
+
examples:
|
|
52
|
+
bad: |
|
|
53
|
+
const api_key = "sk-live-abc123xyz789";
|
|
54
|
+
const password = "hunter2";
|
|
55
|
+
const SECRET = "my-secret-value";
|
|
56
|
+
|
|
57
|
+
good: |
|
|
58
|
+
const api_key = process.env.API_KEY;
|
|
59
|
+
const password = process.env.DATABASE_PASSWORD;
|
|
60
|
+
const secret = process.env.SECRET_KEY;
|
|
61
|
+
|
|
62
|
+
has_fix: false
|
|
63
|
+
|
|
64
|
+
# Additional patterns to match
|
|
65
|
+
patterns:
|
|
66
|
+
variable_names:
|
|
67
|
+
- api_key
|
|
68
|
+
- apikey
|
|
69
|
+
- apiKey
|
|
70
|
+
- API_KEY
|
|
71
|
+
- password
|
|
72
|
+
- secret
|
|
73
|
+
- token
|
|
74
|
+
- auth
|
|
75
|
+
- private_key
|
|
76
|
+
- access_token
|
|
77
|
+
- aws_secret
|
|
78
|
+
- github_token
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Long Parameter List
|
|
2
|
+
# Detects functions with 6+ parameters
|
|
3
|
+
id: long-parameter-list
|
|
4
|
+
name: Long Parameter List
|
|
5
|
+
severity: warning
|
|
6
|
+
category: complexity
|
|
7
|
+
language: typescript
|
|
8
|
+
|
|
9
|
+
message: "Function has {{PARAM_COUNT}} parameters — use object pattern"
|
|
10
|
+
|
|
11
|
+
description: |
|
|
12
|
+
Functions with many parameters are hard to use and maintain.
|
|
13
|
+
Use an options object instead.
|
|
14
|
+
|
|
15
|
+
✅ FIX: Convert to options object pattern
|
|
16
|
+
|
|
17
|
+
query: |
|
|
18
|
+
(function_declaration
|
|
19
|
+
name: (identifier) @NAME
|
|
20
|
+
parameters: (formal_parameters) @PARAMS
|
|
21
|
+
body: (statement_block) @BODY)
|
|
22
|
+
|
|
23
|
+
metavars:
|
|
24
|
+
- NAME
|
|
25
|
+
- PARAMS
|
|
26
|
+
- BODY
|
|
27
|
+
|
|
28
|
+
# Post-filter: count parameters
|
|
29
|
+
post_filter: count_params
|
|
30
|
+
post_filter_params:
|
|
31
|
+
min_params: 6
|
|
32
|
+
|
|
33
|
+
tags:
|
|
34
|
+
- complexity
|
|
35
|
+
- refactoring
|
|
36
|
+
- maintainability
|
|
37
|
+
|
|
38
|
+
examples:
|
|
39
|
+
bad: |
|
|
40
|
+
function createUser(
|
|
41
|
+
firstName, lastName, email,
|
|
42
|
+
password, age, role, status
|
|
43
|
+
) {
|
|
44
|
+
// ...
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
good: |
|
|
48
|
+
interface CreateUserOptions {
|
|
49
|
+
firstName: string;
|
|
50
|
+
lastName: string;
|
|
51
|
+
email: string;
|
|
52
|
+
password: string;
|
|
53
|
+
age: number;
|
|
54
|
+
role: string;
|
|
55
|
+
status: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function createUser(options: CreateUserOptions) {
|
|
59
|
+
// ...
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
has_fix: false
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Mixed Async Styles
|
|
2
|
+
# Detects mixing async/await with promise chains in the same function
|
|
3
|
+
id: mixed-async-styles
|
|
4
|
+
name: Mixed Async/Await and Promise Chains
|
|
5
|
+
severity: warning
|
|
6
|
+
category: style
|
|
7
|
+
language: typescript
|
|
8
|
+
|
|
9
|
+
message: "Mixed async/await + promise chains — use consistent async style"
|
|
10
|
+
|
|
11
|
+
description: |
|
|
12
|
+
Mixing async/await with .then()/.catch() chains in the same function
|
|
13
|
+
is confusing and inconsistent. Choose one style per function.
|
|
14
|
+
|
|
15
|
+
✅ FIXES:
|
|
16
|
+
1. Convert all to async/await (preferred)
|
|
17
|
+
2. Convert all to promise chains (if needed for specific control flow)
|
|
18
|
+
|
|
19
|
+
query: |
|
|
20
|
+
(function_declaration
|
|
21
|
+
(async_modifier)
|
|
22
|
+
body: (statement_block) @BODY)
|
|
23
|
+
|
|
24
|
+
# Post-filter: Check if body contains both await and .then()
|
|
25
|
+
post_filter: has_mixed_async
|
|
26
|
+
|
|
27
|
+
metavars:
|
|
28
|
+
- BODY
|
|
29
|
+
|
|
30
|
+
tags:
|
|
31
|
+
- style
|
|
32
|
+
- async
|
|
33
|
+
- consistency
|
|
34
|
+
|
|
35
|
+
examples:
|
|
36
|
+
bad: |
|
|
37
|
+
async function getUser() {
|
|
38
|
+
const response = await fetch('/api/user');
|
|
39
|
+
return response.json().then(data => data.name); // Mixed!
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
good: |
|
|
43
|
+
async function getUser() {
|
|
44
|
+
const response = await fetch('/api/user');
|
|
45
|
+
const data = await response.json(); // Consistent async/await
|
|
46
|
+
return data.name;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
has_fix: false
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Nested Ternary
|
|
2
|
+
# Detects deeply nested ternary operators (readability issue)
|
|
3
|
+
id: nested-ternary
|
|
4
|
+
name: Nested Ternary
|
|
5
|
+
severity: warning
|
|
6
|
+
category: readability
|
|
7
|
+
language: typescript
|
|
8
|
+
|
|
9
|
+
message: "Nested ternary — use if/else or early returns for clarity"
|
|
10
|
+
|
|
11
|
+
description: |
|
|
12
|
+
Nested ternary operators are hard to read and understand.
|
|
13
|
+
Prefer if/else statements or early returns.
|
|
14
|
+
|
|
15
|
+
✅ FIX: Use if/else or switch statement
|
|
16
|
+
|
|
17
|
+
query: |
|
|
18
|
+
(ternary_expression
|
|
19
|
+
consequence: (ternary_expression) @NESTED)
|
|
20
|
+
(ternary_expression
|
|
21
|
+
alternative: (ternary_expression) @NESTED)
|
|
22
|
+
|
|
23
|
+
metavars:
|
|
24
|
+
- NESTED
|
|
25
|
+
|
|
26
|
+
tags:
|
|
27
|
+
- readability
|
|
28
|
+
- code-quality
|
|
29
|
+
|
|
30
|
+
examples:
|
|
31
|
+
bad: |
|
|
32
|
+
const value = condition1
|
|
33
|
+
? condition2
|
|
34
|
+
? condition3 ? "a" : "b"
|
|
35
|
+
: "c"
|
|
36
|
+
: "d";
|
|
37
|
+
|
|
38
|
+
good: |
|
|
39
|
+
function getValue(c1, c2, c3) {
|
|
40
|
+
if (!c1) return "d";
|
|
41
|
+
if (!c2) return "c";
|
|
42
|
+
return c3 ? "a" : "b";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
has_fix: false
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ts-jwt-no-verify
|
|
3
|
+
language: TypeScript
|
|
4
|
+
severity: warning
|
|
5
|
+
message: "Unsafe JWT operation — verification is bypassed"
|
|
6
|
+
metadata:
|
|
7
|
+
weight: 4
|
|
8
|
+
category: security
|
|
9
|
+
rule:
|
|
10
|
+
any:
|
|
11
|
+
- pattern: "jwt.decode($$$, { noVerify: true })"
|
|
12
|
+
- pattern: "jwt.verify($$$, { ignoreExpiration: true, $$$ })"
|
|
13
|
+
- pattern: "jwt.verify($$$, { ignoreNotBefore: true, $$$ })"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ts-no-architecture-violation
|
|
3
|
+
language: TypeScript
|
|
4
|
+
severity: warning
|
|
5
|
+
message: "Forbidden import — layer boundary violation: importing from database/model layer"
|
|
6
|
+
metadata:
|
|
7
|
+
weight: 4
|
|
8
|
+
category: security
|
|
9
|
+
rule:
|
|
10
|
+
pattern: "import { $$$ } from \"$PATH\""
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ts-no-eval
|
|
3
|
+
language: typescript
|
|
4
|
+
severity: warning
|
|
5
|
+
message: Avoid eval() — it can execute arbitrary code and is a security risk
|
|
6
|
+
metadata:
|
|
7
|
+
weight: 4
|
|
8
|
+
category: security
|
|
9
|
+
rule:
|
|
10
|
+
any:
|
|
11
|
+
- pattern: "eval($$$ARGS)"
|
|
12
|
+
- pattern: "window.eval($$$ARGS)"
|
|
13
|
+
- pattern: "global.eval($$$ARGS)"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ts-no-hardcoded-secrets
|
|
3
|
+
language: TypeScript
|
|
4
|
+
severity: warning
|
|
5
|
+
message: "Hardcoded secret detected — use process.env instead"
|
|
6
|
+
metadata:
|
|
7
|
+
weight: 4
|
|
8
|
+
category: security
|
|
9
|
+
rule:
|
|
10
|
+
any:
|
|
11
|
+
- pattern: "const $VAR = \"$_\""
|
|
12
|
+
- pattern: "const $VAR = '$_'"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ts-no-implied-eval
|
|
3
|
+
language: TypeScript
|
|
4
|
+
severity: warning
|
|
5
|
+
message: "Avoid implied eval via setTimeout/setInterval with string arguments"
|
|
6
|
+
metadata:
|
|
7
|
+
weight: 4
|
|
8
|
+
category: security
|
|
9
|
+
rule:
|
|
10
|
+
any:
|
|
11
|
+
- pattern: "setTimeout($$$ARGS)"
|
|
12
|
+
- pattern: "setInterval($$$ARGS)"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ts-no-inner-html
|
|
3
|
+
language: TypeScript
|
|
4
|
+
severity: warning
|
|
5
|
+
message: "Avoid innerHTML/outerHTML — use textContent or a sanitizer to prevent XSS"
|
|
6
|
+
metadata:
|
|
7
|
+
weight: 4
|
|
8
|
+
category: security
|
|
9
|
+
rule:
|
|
10
|
+
any:
|
|
11
|
+
- pattern: "$EL.innerHTML = $$$"
|
|
12
|
+
- pattern: "$EL.outerHTML = $$$"
|
|
13
|
+
- pattern: "$EL.insertAdjacentHTML($$$)"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ts-no-new-wrappers
|
|
3
|
+
language: TypeScript
|
|
4
|
+
severity: warning
|
|
5
|
+
message: "Do not use 'new' with wrapper objects — use literal primitives instead"
|
|
6
|
+
metadata:
|
|
7
|
+
weight: 4
|
|
8
|
+
category: security
|
|
9
|
+
rule:
|
|
10
|
+
any:
|
|
11
|
+
- pattern: "new Boolean($$$ARGS)"
|
|
12
|
+
- pattern: "new Number($$$ARGS)"
|
|
13
|
+
- pattern: "new String($$$ARGS)"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ts-no-open-redirect
|
|
3
|
+
language: TypeScript
|
|
4
|
+
severity: warning
|
|
5
|
+
message: "Potential open redirect vulnerability — validate redirect URLs"
|
|
6
|
+
metadata:
|
|
7
|
+
weight: 4
|
|
8
|
+
category: security
|
|
9
|
+
rule:
|
|
10
|
+
any:
|
|
11
|
+
- pattern: "window.location = $URL"
|
|
12
|
+
- pattern: "window.location.href = $URL"
|
|
13
|
+
- pattern: "window.open($URL, $$$)"
|
|
14
|
+
- pattern: "location.href = $URL"
|
|
15
|
+
- pattern: "res.redirect($URL)"
|
|
16
|
+
- pattern: "response.redirect($URL)"
|