thrivekit 2.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/.claude/commands/explain.md +114 -0
- package/.claude/commands/idea.md +370 -0
- package/.claude/commands/my-dna.md +122 -0
- package/.claude/commands/prd.md +286 -0
- package/.claude/commands/review.md +167 -0
- package/.claude/commands/sign.md +32 -0
- package/.claude/commands/styleguide.md +450 -0
- package/.claude/commands/tour.md +301 -0
- package/.claude/commands/vibe-check.md +116 -0
- package/.claude/commands/vibe-help.md +47 -0
- package/.claude/commands/vibe-list.md +203 -0
- package/.claude/settings.json +75 -0
- package/.claude/settings.local.json +12 -0
- package/.pre-commit-hooks.yaml +102 -0
- package/LICENSE +21 -0
- package/README.md +214 -0
- package/bin/postinstall.sh +29 -0
- package/bin/ralph.sh +171 -0
- package/bin/thrivekit.sh +24 -0
- package/bin/vibe-check.js +19 -0
- package/dist/checks/check-any-types.d.ts +6 -0
- package/dist/checks/check-any-types.d.ts.map +1 -0
- package/dist/checks/check-any-types.js +73 -0
- package/dist/checks/check-any-types.js.map +1 -0
- package/dist/checks/check-commented-code.d.ts +6 -0
- package/dist/checks/check-commented-code.d.ts.map +1 -0
- package/dist/checks/check-commented-code.js +81 -0
- package/dist/checks/check-commented-code.js.map +1 -0
- package/dist/checks/check-console-error.d.ts +6 -0
- package/dist/checks/check-console-error.d.ts.map +1 -0
- package/dist/checks/check-console-error.js +41 -0
- package/dist/checks/check-console-error.js.map +1 -0
- package/dist/checks/check-debug-statements.d.ts +6 -0
- package/dist/checks/check-debug-statements.d.ts.map +1 -0
- package/dist/checks/check-debug-statements.js +120 -0
- package/dist/checks/check-debug-statements.js.map +1 -0
- package/dist/checks/check-deep-nesting.d.ts +6 -0
- package/dist/checks/check-deep-nesting.d.ts.map +1 -0
- package/dist/checks/check-deep-nesting.js +116 -0
- package/dist/checks/check-deep-nesting.js.map +1 -0
- package/dist/checks/check-docker-platform.d.ts +6 -0
- package/dist/checks/check-docker-platform.d.ts.map +1 -0
- package/dist/checks/check-docker-platform.js +42 -0
- package/dist/checks/check-docker-platform.js.map +1 -0
- package/dist/checks/check-dry-violations.d.ts +6 -0
- package/dist/checks/check-dry-violations.d.ts.map +1 -0
- package/dist/checks/check-dry-violations.js +124 -0
- package/dist/checks/check-dry-violations.js.map +1 -0
- package/dist/checks/check-empty-catch.d.ts +6 -0
- package/dist/checks/check-empty-catch.d.ts.map +1 -0
- package/dist/checks/check-empty-catch.js +111 -0
- package/dist/checks/check-empty-catch.js.map +1 -0
- package/dist/checks/check-function-length.d.ts +6 -0
- package/dist/checks/check-function-length.d.ts.map +1 -0
- package/dist/checks/check-function-length.js +152 -0
- package/dist/checks/check-function-length.js.map +1 -0
- package/dist/checks/check-hardcoded-ai-models.d.ts +10 -0
- package/dist/checks/check-hardcoded-ai-models.d.ts.map +1 -0
- package/dist/checks/check-hardcoded-ai-models.js +102 -0
- package/dist/checks/check-hardcoded-ai-models.js.map +1 -0
- package/dist/checks/check-hardcoded-urls.d.ts +6 -0
- package/dist/checks/check-hardcoded-urls.d.ts.map +1 -0
- package/dist/checks/check-hardcoded-urls.js +124 -0
- package/dist/checks/check-hardcoded-urls.js.map +1 -0
- package/dist/checks/check-magic-numbers.d.ts +6 -0
- package/dist/checks/check-magic-numbers.d.ts.map +1 -0
- package/dist/checks/check-magic-numbers.js +116 -0
- package/dist/checks/check-magic-numbers.js.map +1 -0
- package/dist/checks/check-secrets.d.ts +6 -0
- package/dist/checks/check-secrets.d.ts.map +1 -0
- package/dist/checks/check-secrets.js +138 -0
- package/dist/checks/check-secrets.js.map +1 -0
- package/dist/checks/check-snake-case-ts.d.ts +6 -0
- package/dist/checks/check-snake-case-ts.d.ts.map +1 -0
- package/dist/checks/check-snake-case-ts.js +78 -0
- package/dist/checks/check-snake-case-ts.js.map +1 -0
- package/dist/checks/check-todo-fixme.d.ts +6 -0
- package/dist/checks/check-todo-fixme.d.ts.map +1 -0
- package/dist/checks/check-todo-fixme.js +41 -0
- package/dist/checks/check-todo-fixme.js.map +1 -0
- package/dist/checks/check-unsafe-html.d.ts +6 -0
- package/dist/checks/check-unsafe-html.d.ts.map +1 -0
- package/dist/checks/check-unsafe-html.js +101 -0
- package/dist/checks/check-unsafe-html.js.map +1 -0
- package/dist/checks/index.d.ts +30 -0
- package/dist/checks/index.d.ts.map +1 -0
- package/dist/checks/index.js +57 -0
- package/dist/checks/index.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +206 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/file-reader.d.ts +24 -0
- package/dist/utils/file-reader.d.ts.map +1 -0
- package/dist/utils/file-reader.js +140 -0
- package/dist/utils/file-reader.js.map +1 -0
- package/dist/utils/patterns.d.ts +27 -0
- package/dist/utils/patterns.d.ts.map +1 -0
- package/dist/utils/patterns.js +84 -0
- package/dist/utils/patterns.js.map +1 -0
- package/dist/utils/reporters.d.ts +21 -0
- package/dist/utils/reporters.d.ts.map +1 -0
- package/dist/utils/reporters.js +115 -0
- package/dist/utils/reporters.js.map +1 -0
- package/dist/utils/types.d.ts +71 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +5 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +82 -0
- package/ralph/api.sh +210 -0
- package/ralph/backup.sh +838 -0
- package/ralph/browser-verify/README.md +135 -0
- package/ralph/browser-verify/verify.ts +450 -0
- package/ralph/checks/check-fastapi-responses.py +155 -0
- package/ralph/hooks/hooks-config.json +72 -0
- package/ralph/hooks/inject-context.sh +44 -0
- package/ralph/hooks/install.sh +207 -0
- package/ralph/hooks/log-tools.sh +45 -0
- package/ralph/hooks/protect-prd.sh +27 -0
- package/ralph/hooks/save-learnings.sh +36 -0
- package/ralph/hooks/warn-debug.sh +54 -0
- package/ralph/hooks/warn-empty-catch.sh +63 -0
- package/ralph/hooks/warn-secrets.sh +89 -0
- package/ralph/hooks/warn-urls.sh +77 -0
- package/ralph/init.sh +388 -0
- package/ralph/loop.sh +570 -0
- package/ralph/playwright.sh +238 -0
- package/ralph/prd.sh +295 -0
- package/ralph/setup/feature-tour.sh +155 -0
- package/ralph/setup/quick-setup.sh +239 -0
- package/ralph/setup/tutorial.sh +159 -0
- package/ralph/setup/ui.sh +136 -0
- package/ralph/setup.sh +353 -0
- package/ralph/signs.sh +150 -0
- package/ralph/utils.sh +682 -0
- package/ralph/verify/browser.sh +324 -0
- package/ralph/verify/lint.sh +363 -0
- package/ralph/verify/review.sh +164 -0
- package/ralph/verify/tests.sh +81 -0
- package/ralph/verify.sh +224 -0
- package/templates/PROMPT.md +235 -0
- package/templates/config/fullstack.json +86 -0
- package/templates/config/go.json +81 -0
- package/templates/config/minimal.json +76 -0
- package/templates/config/node.json +81 -0
- package/templates/config/python.json +81 -0
- package/templates/config/rust.json +81 -0
- package/templates/examples/CLAUDE-django.md +174 -0
- package/templates/examples/CLAUDE-fastapi.md +270 -0
- package/templates/examples/CLAUDE-fastmcp.md +352 -0
- package/templates/examples/CLAUDE-fullstack.md +256 -0
- package/templates/examples/CLAUDE-node.md +246 -0
- package/templates/examples/CLAUDE-react.md +138 -0
- package/templates/optional/cursorrules.template +147 -0
- package/templates/optional/eslint.config.js +34 -0
- package/templates/optional/lint-staged.config.js +34 -0
- package/templates/optional/ruff.toml +125 -0
- package/templates/optional/vibe-check.yml +116 -0
- package/templates/optional/vscode-settings.json +127 -0
- package/templates/signs.json +46 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for 'any' type usage in TypeScript
|
|
3
|
+
*/
|
|
4
|
+
export const checkAnyTypes = {
|
|
5
|
+
id: 'any-types',
|
|
6
|
+
name: 'Check Any Types',
|
|
7
|
+
description: 'Detect usage of "any" type in TypeScript',
|
|
8
|
+
severity: 'warning',
|
|
9
|
+
fileTypes: ['ts', 'tsx', 'mts', 'cts'],
|
|
10
|
+
check(context) {
|
|
11
|
+
const results = [];
|
|
12
|
+
const lines = context.content.split('\n');
|
|
13
|
+
// Track if we're in a block comment
|
|
14
|
+
let inBlockComment = false;
|
|
15
|
+
for (let i = 0; i < lines.length; i++) {
|
|
16
|
+
const line = lines[i];
|
|
17
|
+
const lineNum = i + 1;
|
|
18
|
+
// Handle block comments
|
|
19
|
+
if (line.includes('/*')) {
|
|
20
|
+
inBlockComment = true;
|
|
21
|
+
}
|
|
22
|
+
if (line.includes('*/')) {
|
|
23
|
+
inBlockComment = false;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (inBlockComment) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// Skip single-line comments
|
|
30
|
+
if (line.trim().startsWith('//')) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
// Remove string literals to avoid false positives
|
|
34
|
+
const lineWithoutStrings = line
|
|
35
|
+
.replace(/"[^"]*"/g, '""')
|
|
36
|
+
.replace(/'[^']*'/g, "''")
|
|
37
|
+
.replace(/`[^`]*`/g, '``');
|
|
38
|
+
// Look for 'any' type annotations
|
|
39
|
+
// Matches: : any, : any[], <any>, as any, etc.
|
|
40
|
+
const anyPatterns = [
|
|
41
|
+
/:\s*any\b/, // : any
|
|
42
|
+
/:\s*any\s*\[/, // : any[]
|
|
43
|
+
/:\s*any\s*\|/, // : any |
|
|
44
|
+
/\|\s*any\b/, // | any
|
|
45
|
+
/<\s*any\s*>/, // <any>
|
|
46
|
+
/<\s*any\s*,/, // <any,
|
|
47
|
+
/,\s*any\s*>/, // , any>
|
|
48
|
+
/as\s+any\b/, // as any
|
|
49
|
+
/:\s*Array\s*<\s*any\s*>/, // : Array<any>
|
|
50
|
+
/:\s*Record\s*<\s*[^,]+,\s*any\s*>/, // : Record<..., any>
|
|
51
|
+
];
|
|
52
|
+
for (const pattern of anyPatterns) {
|
|
53
|
+
const match = lineWithoutStrings.match(pattern);
|
|
54
|
+
if (match) {
|
|
55
|
+
// Check if it's disabled via eslint comment
|
|
56
|
+
if (line.includes('eslint-disable') || line.includes('@ts-ignore')) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
results.push({
|
|
60
|
+
line: lineNum,
|
|
61
|
+
column: match.index || 0,
|
|
62
|
+
message: 'Avoid using "any" type - use "unknown" or a specific type instead',
|
|
63
|
+
severity: 'warning',
|
|
64
|
+
ruleId: 'any-types/no-any',
|
|
65
|
+
});
|
|
66
|
+
break; // Only report once per line
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return results;
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=check-any-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-any-types.js","sourceRoot":"","sources":["../../src/checks/check-any-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,aAAa,GAAS;IACjC,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,0CAA0C;IACvD,QAAQ,EAAE,SAAS;IACnB,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAEtC,KAAK,CAAC,OAAoB;QACxB,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE1C,oCAAoC;QACpC,IAAI,cAAc,GAAG,KAAK,CAAC;QAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YAEtB,wBAAwB;YACxB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,cAAc,GAAG,IAAI,CAAC;YACxB,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,cAAc,GAAG,KAAK,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,IAAI,cAAc,EAAE,CAAC;gBACnB,SAAS;YACX,CAAC;YAED,4BAA4B;YAC5B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjC,SAAS;YACX,CAAC;YAED,kDAAkD;YAClD,MAAM,kBAAkB,GAAG,IAAI;iBAC5B,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC;iBACzB,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC;iBACzB,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAE7B,kCAAkC;YAClC,+CAA+C;YAC/C,MAAM,WAAW,GAAG;gBAClB,WAAW,EAAqB,QAAQ;gBACxC,cAAc,EAAkB,UAAU;gBAC1C,cAAc,EAAkB,UAAU;gBAC1C,YAAY,EAAoB,QAAQ;gBACxC,aAAa,EAAmB,QAAQ;gBACxC,aAAa,EAAmB,QAAQ;gBACxC,aAAa,EAAmB,SAAS;gBACzC,YAAY,EAAoB,SAAS;gBACzC,yBAAyB,EAAO,eAAe;gBAC/C,mCAAmC,EAAE,qBAAqB;aAC3D,CAAC;YAEF,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;gBAClC,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAChD,IAAI,KAAK,EAAE,CAAC;oBACV,4CAA4C;oBAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;wBACnE,SAAS;oBACX,CAAC;oBAED,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO;wBACb,MAAM,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;wBACxB,OAAO,EAAE,mEAAmE;wBAC5E,QAAQ,EAAE,SAAS;wBACnB,MAAM,EAAE,kBAAkB;qBAC3B,CAAC,CAAC;oBACH,MAAM,CAAC,4BAA4B;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-commented-code.d.ts","sourceRoot":"","sources":["../../src/checks/check-commented-code.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAsBvE,eAAO,MAAM,kBAAkB,EAAE,IAwDhC,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for commented-out code blocks
|
|
3
|
+
*/
|
|
4
|
+
// Patterns that indicate commented-out code vs regular comments
|
|
5
|
+
const JS_CODE_PATTERNS = [
|
|
6
|
+
/^\s*\/\/\s*(?:const|let|var|function|class|import|export|return|if|else|for|while|try|catch|switch)\b/,
|
|
7
|
+
/^\s*\/\/\s*\w+\s*\([^)]*\)\s*[;{]?\s*$/, // function calls
|
|
8
|
+
/^\s*\/\/\s*\w+\s*=\s*.+[;,]?\s*$/, // assignments
|
|
9
|
+
/^\s*\/\/\s*}\s*(?:else|catch|finally)?\s*{?\s*$/, // closing braces
|
|
10
|
+
/^\s*\/\/\s*\w+\.\w+\s*\(/, // method calls
|
|
11
|
+
/^\s*\/\*\s*(?:const|let|var|function|class|import|export)\b/,
|
|
12
|
+
];
|
|
13
|
+
const PY_CODE_PATTERNS = [
|
|
14
|
+
/^\s*#\s*(?:def|class|import|from|return|if|elif|else|for|while|try|except|with|async)\b/,
|
|
15
|
+
/^\s*#\s*\w+\s*=\s*.+$/, // assignments
|
|
16
|
+
/^\s*#\s*\w+\s*\([^)]*\)\s*$/, // function calls
|
|
17
|
+
/^\s*#\s*\w+\.\w+\s*\(/, // method calls
|
|
18
|
+
];
|
|
19
|
+
// Minimum consecutive commented lines to report
|
|
20
|
+
const MIN_CONSECUTIVE_LINES = 3;
|
|
21
|
+
export const checkCommentedCode = {
|
|
22
|
+
id: 'commented-code',
|
|
23
|
+
name: 'Check Commented Code',
|
|
24
|
+
description: 'Detect commented-out code blocks that should be removed',
|
|
25
|
+
severity: 'info',
|
|
26
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py'],
|
|
27
|
+
check(context) {
|
|
28
|
+
const results = [];
|
|
29
|
+
const lines = context.content.split('\n');
|
|
30
|
+
const language = getLanguage(context.extension);
|
|
31
|
+
const patterns = language === 'python' ? PY_CODE_PATTERNS : JS_CODE_PATTERNS;
|
|
32
|
+
let consecutiveCodeComments = 0;
|
|
33
|
+
let blockStartLine = 0;
|
|
34
|
+
for (let i = 0; i < lines.length; i++) {
|
|
35
|
+
const line = lines[i];
|
|
36
|
+
const lineNum = i + 1;
|
|
37
|
+
// Check if this line looks like commented-out code
|
|
38
|
+
const looksLikeCode = patterns.some((pattern) => pattern.test(line));
|
|
39
|
+
if (looksLikeCode) {
|
|
40
|
+
if (consecutiveCodeComments === 0) {
|
|
41
|
+
blockStartLine = lineNum;
|
|
42
|
+
}
|
|
43
|
+
consecutiveCodeComments++;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// End of potential block
|
|
47
|
+
if (consecutiveCodeComments >= MIN_CONSECUTIVE_LINES) {
|
|
48
|
+
results.push({
|
|
49
|
+
line: blockStartLine,
|
|
50
|
+
column: 0,
|
|
51
|
+
message: `${consecutiveCodeComments} lines of commented-out code - consider removing`,
|
|
52
|
+
severity: 'info',
|
|
53
|
+
ruleId: 'commented-code/block',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
consecutiveCodeComments = 0;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Check for block at end of file
|
|
60
|
+
if (consecutiveCodeComments >= MIN_CONSECUTIVE_LINES) {
|
|
61
|
+
results.push({
|
|
62
|
+
line: blockStartLine,
|
|
63
|
+
column: 0,
|
|
64
|
+
message: `${consecutiveCodeComments} lines of commented-out code - consider removing`,
|
|
65
|
+
severity: 'info',
|
|
66
|
+
ruleId: 'commented-code/block',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return results;
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
function getLanguage(ext) {
|
|
73
|
+
if (['js', 'jsx', 'mjs', 'cjs'].includes(ext))
|
|
74
|
+
return 'javascript';
|
|
75
|
+
if (['ts', 'tsx', 'mts', 'cts'].includes(ext))
|
|
76
|
+
return 'typescript';
|
|
77
|
+
if (['py', 'pyw'].includes(ext))
|
|
78
|
+
return 'python';
|
|
79
|
+
return 'unknown';
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=check-commented-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-commented-code.js","sourceRoot":"","sources":["../../src/checks/check-commented-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-console-error.d.ts","sourceRoot":"","sources":["../../src/checks/check-console-error.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,iBAAiB,EAAE,IA0C/B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for console.error usage that might need proper error handling
|
|
3
|
+
*/
|
|
4
|
+
export const checkConsoleError = {
|
|
5
|
+
id: 'console-error',
|
|
6
|
+
name: 'Check Console Error',
|
|
7
|
+
description: 'Detect console.error that might need proper error handling',
|
|
8
|
+
severity: 'info',
|
|
9
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'],
|
|
10
|
+
check(context) {
|
|
11
|
+
const results = [];
|
|
12
|
+
const lines = context.content.split('\n');
|
|
13
|
+
for (let i = 0; i < lines.length; i++) {
|
|
14
|
+
const line = lines[i];
|
|
15
|
+
const lineNum = i + 1;
|
|
16
|
+
// Skip comment lines
|
|
17
|
+
if (line.trim().startsWith('//') || line.trim().startsWith('*')) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
// Look for console.error
|
|
21
|
+
const match = line.match(/console\.error\s*\(/);
|
|
22
|
+
if (match) {
|
|
23
|
+
// Check if it's in a catch block (look at nearby lines)
|
|
24
|
+
const nearbyLines = lines.slice(Math.max(0, i - 5), i + 1).join('\n');
|
|
25
|
+
const inCatchBlock = /catch\s*\([^)]*\)\s*\{/.test(nearbyLines);
|
|
26
|
+
if (inCatchBlock) {
|
|
27
|
+
// In a catch block - suggest proper error handling
|
|
28
|
+
results.push({
|
|
29
|
+
line: lineNum,
|
|
30
|
+
column: match.index || 0,
|
|
31
|
+
message: 'console.error in catch block - consider using a logging service or rethrowing',
|
|
32
|
+
severity: 'info',
|
|
33
|
+
ruleId: 'console-error/in-catch',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return results;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=check-console-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-console-error.js","sourceRoot":"","sources":["../../src/checks/check-console-error.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAAS;IACrC,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,4DAA4D;IACzE,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAEnD,KAAK,CAAC,OAAoB;QACxB,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YAEtB,qBAAqB;YACrB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChE,SAAS;YACX,CAAC;YAED,yBAAyB;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YAChD,IAAI,KAAK,EAAE,CAAC;gBACV,wDAAwD;gBACxD,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,MAAM,YAAY,GAAG,wBAAwB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAEhE,IAAI,YAAY,EAAE,CAAC;oBACjB,mDAAmD;oBACnD,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO;wBACb,MAAM,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;wBACxB,OAAO,EAAE,+EAA+E;wBACxF,QAAQ,EAAE,MAAM;wBAChB,MAAM,EAAE,wBAAwB;qBACjC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-debug-statements.d.ts","sourceRoot":"","sources":["../../src/checks/check-debug-statements.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAGvE,eAAO,MAAM,oBAAoB,EAAE,IA0ElC,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for debug statements that should be removed before commit
|
|
3
|
+
*/
|
|
4
|
+
import { DEBUG_PATTERNS } from '../utils/patterns.js';
|
|
5
|
+
export const checkDebugStatements = {
|
|
6
|
+
id: 'debug',
|
|
7
|
+
name: 'Check Debug Statements',
|
|
8
|
+
description: 'Detect console.log, print(), debugger, and other debug statements',
|
|
9
|
+
severity: 'warning',
|
|
10
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py'],
|
|
11
|
+
check(context) {
|
|
12
|
+
const results = [];
|
|
13
|
+
const lines = context.content.split('\n');
|
|
14
|
+
// Get patterns for this language
|
|
15
|
+
const language = getLanguageFromExtension(context.extension);
|
|
16
|
+
const patterns = DEBUG_PATTERNS[language] || [];
|
|
17
|
+
if (patterns.length === 0) {
|
|
18
|
+
return results;
|
|
19
|
+
}
|
|
20
|
+
// Track if we're inside a multi-line comment
|
|
21
|
+
let inBlockComment = false;
|
|
22
|
+
for (let i = 0; i < lines.length; i++) {
|
|
23
|
+
const line = lines[i];
|
|
24
|
+
const lineNum = i + 1;
|
|
25
|
+
// Handle block comments for JS/TS
|
|
26
|
+
if (['javascript', 'typescript'].includes(language)) {
|
|
27
|
+
if (line.includes('/*') && !line.includes('*/')) {
|
|
28
|
+
inBlockComment = true;
|
|
29
|
+
}
|
|
30
|
+
if (line.includes('*/')) {
|
|
31
|
+
inBlockComment = false;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (inBlockComment) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Skip single-line comments
|
|
39
|
+
if (isCommentLine(line, language)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
// Check each pattern
|
|
43
|
+
for (const pattern of patterns) {
|
|
44
|
+
const match = line.match(pattern);
|
|
45
|
+
if (match) {
|
|
46
|
+
const patternType = getPatternType(pattern.source, language);
|
|
47
|
+
// Skip console.error and console.warn - these are often intentional
|
|
48
|
+
if (patternType === 'console' && /console\.(error|warn)\s*\(/.test(line)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
// Skip if explicitly marked to keep
|
|
52
|
+
if (line.includes('// eslint-disable') || line.includes('# noqa')) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
results.push({
|
|
56
|
+
line: lineNum,
|
|
57
|
+
column: match.index || 0,
|
|
58
|
+
message: getDebugMessage(patternType, language),
|
|
59
|
+
severity: 'warning',
|
|
60
|
+
ruleId: `debug/${patternType}`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return results;
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
function getLanguageFromExtension(ext) {
|
|
69
|
+
if (['js', 'jsx', 'mjs', 'cjs'].includes(ext))
|
|
70
|
+
return 'javascript';
|
|
71
|
+
if (['ts', 'tsx', 'mts', 'cts'].includes(ext))
|
|
72
|
+
return 'typescript';
|
|
73
|
+
if (['py', 'pyw'].includes(ext))
|
|
74
|
+
return 'python';
|
|
75
|
+
return 'unknown';
|
|
76
|
+
}
|
|
77
|
+
function isCommentLine(line, language) {
|
|
78
|
+
const trimmed = line.trim();
|
|
79
|
+
if (['javascript', 'typescript'].includes(language)) {
|
|
80
|
+
return trimmed.startsWith('//') || trimmed.startsWith('*');
|
|
81
|
+
}
|
|
82
|
+
if (language === 'python') {
|
|
83
|
+
return trimmed.startsWith('#');
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
function getPatternType(patternSource, _language) {
|
|
88
|
+
if (patternSource.includes('console'))
|
|
89
|
+
return 'console';
|
|
90
|
+
if (patternSource.includes('debugger'))
|
|
91
|
+
return 'debugger';
|
|
92
|
+
if (patternSource.includes('alert'))
|
|
93
|
+
return 'alert';
|
|
94
|
+
if (patternSource.includes('print'))
|
|
95
|
+
return 'print';
|
|
96
|
+
if (patternSource.includes('breakpoint'))
|
|
97
|
+
return 'breakpoint';
|
|
98
|
+
if (patternSource.includes('pdb') || patternSource.includes('ipdb'))
|
|
99
|
+
return 'pdb';
|
|
100
|
+
return 'debug';
|
|
101
|
+
}
|
|
102
|
+
function getDebugMessage(patternType, _language) {
|
|
103
|
+
switch (patternType) {
|
|
104
|
+
case 'console':
|
|
105
|
+
return 'console.log() statement - remove before commit';
|
|
106
|
+
case 'debugger':
|
|
107
|
+
return 'debugger statement - remove before commit';
|
|
108
|
+
case 'alert':
|
|
109
|
+
return 'alert() statement - remove before commit';
|
|
110
|
+
case 'print':
|
|
111
|
+
return 'print() statement - use proper logging instead';
|
|
112
|
+
case 'breakpoint':
|
|
113
|
+
return 'breakpoint() - remove before commit';
|
|
114
|
+
case 'pdb':
|
|
115
|
+
return 'pdb debugger - remove before commit';
|
|
116
|
+
default:
|
|
117
|
+
return 'Debug statement - remove before commit';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=check-debug-statements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-debug-statements.js","sourceRoot":"","sources":["../../src/checks/check-debug-statements.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-deep-nesting.d.ts","sourceRoot":"","sources":["../../src/checks/check-deep-nesting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAIvE,eAAO,MAAM,gBAAgB,EAAE,IAmB9B,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for deeply nested code blocks
|
|
3
|
+
*/
|
|
4
|
+
const MAX_NESTING_DEPTH = 4;
|
|
5
|
+
export const checkDeepNesting = {
|
|
6
|
+
id: 'deep-nesting',
|
|
7
|
+
name: 'Check Deep Nesting',
|
|
8
|
+
description: 'Detect deeply nested code blocks that should be refactored',
|
|
9
|
+
severity: 'warning',
|
|
10
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py'],
|
|
11
|
+
check(context) {
|
|
12
|
+
const results = [];
|
|
13
|
+
const language = getLanguage(context.extension);
|
|
14
|
+
if (language === 'javascript' || language === 'typescript') {
|
|
15
|
+
results.push(...checkJavaScriptNesting(context.content));
|
|
16
|
+
}
|
|
17
|
+
else if (language === 'python') {
|
|
18
|
+
results.push(...checkPythonNesting(context.content));
|
|
19
|
+
}
|
|
20
|
+
return results;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
function getLanguage(ext) {
|
|
24
|
+
if (['js', 'jsx', 'mjs', 'cjs'].includes(ext))
|
|
25
|
+
return 'javascript';
|
|
26
|
+
if (['ts', 'tsx', 'mts', 'cts'].includes(ext))
|
|
27
|
+
return 'typescript';
|
|
28
|
+
if (['py', 'pyw'].includes(ext))
|
|
29
|
+
return 'python';
|
|
30
|
+
return 'unknown';
|
|
31
|
+
}
|
|
32
|
+
function checkJavaScriptNesting(content) {
|
|
33
|
+
const results = [];
|
|
34
|
+
const lines = content.split('\n');
|
|
35
|
+
const reportedLines = new Set();
|
|
36
|
+
let nestingDepth = 0;
|
|
37
|
+
let inString = false;
|
|
38
|
+
let stringChar = '';
|
|
39
|
+
for (let i = 0; i < lines.length; i++) {
|
|
40
|
+
const line = lines[i];
|
|
41
|
+
const lineNum = i + 1;
|
|
42
|
+
// Skip comment-only lines
|
|
43
|
+
if (line.trim().startsWith('//') || line.trim().startsWith('*')) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
// Track nesting by counting braces (simplified - doesn't handle all edge cases)
|
|
47
|
+
for (let j = 0; j < line.length; j++) {
|
|
48
|
+
const char = line[j];
|
|
49
|
+
const prevChar = j > 0 ? line[j - 1] : '';
|
|
50
|
+
// Handle strings
|
|
51
|
+
if ((char === '"' || char === "'" || char === '`') && prevChar !== '\\') {
|
|
52
|
+
if (!inString) {
|
|
53
|
+
inString = true;
|
|
54
|
+
stringChar = char;
|
|
55
|
+
}
|
|
56
|
+
else if (char === stringChar) {
|
|
57
|
+
inString = false;
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (inString)
|
|
62
|
+
continue;
|
|
63
|
+
// Track braces
|
|
64
|
+
if (char === '{') {
|
|
65
|
+
nestingDepth++;
|
|
66
|
+
if (nestingDepth > MAX_NESTING_DEPTH && !reportedLines.has(lineNum)) {
|
|
67
|
+
reportedLines.add(lineNum);
|
|
68
|
+
results.push({
|
|
69
|
+
line: lineNum,
|
|
70
|
+
column: j,
|
|
71
|
+
message: `Nesting depth ${nestingDepth} exceeds maximum of ${MAX_NESTING_DEPTH} - consider refactoring`,
|
|
72
|
+
severity: 'warning',
|
|
73
|
+
ruleId: 'deep-nesting/too-deep',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else if (char === '}') {
|
|
78
|
+
nestingDepth = Math.max(0, nestingDepth - 1);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return results;
|
|
83
|
+
}
|
|
84
|
+
function checkPythonNesting(content) {
|
|
85
|
+
const results = [];
|
|
86
|
+
const lines = content.split('\n');
|
|
87
|
+
const reportedLines = new Set();
|
|
88
|
+
// In Python, we track indentation-based nesting
|
|
89
|
+
// Each 4 spaces or 1 tab = 1 level of nesting (approximately)
|
|
90
|
+
const INDENT_SIZE = 4;
|
|
91
|
+
for (let i = 0; i < lines.length; i++) {
|
|
92
|
+
const line = lines[i];
|
|
93
|
+
const lineNum = i + 1;
|
|
94
|
+
// Skip empty lines and comments
|
|
95
|
+
if (!line.trim() || line.trim().startsWith('#')) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// Count leading whitespace
|
|
99
|
+
const leadingSpaces = line.match(/^(\s*)/)?.[1] || '';
|
|
100
|
+
// Convert tabs to spaces for consistent counting
|
|
101
|
+
const normalizedSpaces = leadingSpaces.replace(/\t/g, ' ');
|
|
102
|
+
const indentLevel = Math.floor(normalizedSpaces.length / INDENT_SIZE);
|
|
103
|
+
if (indentLevel > MAX_NESTING_DEPTH && !reportedLines.has(lineNum)) {
|
|
104
|
+
reportedLines.add(lineNum);
|
|
105
|
+
results.push({
|
|
106
|
+
line: lineNum,
|
|
107
|
+
column: 0,
|
|
108
|
+
message: `Indentation level ${indentLevel} exceeds maximum of ${MAX_NESTING_DEPTH} - consider refactoring`,
|
|
109
|
+
severity: 'warning',
|
|
110
|
+
ruleId: 'deep-nesting/too-deep',
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return results;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=check-deep-nesting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-deep-nesting.js","sourceRoot":"","sources":["../../src/checks/check-deep-nesting.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-docker-platform.d.ts","sourceRoot":"","sources":["../../src/checks/check-docker-platform.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,mBAAmB,EAAE,IA2CjC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for missing platform specification in Dockerfiles
|
|
3
|
+
*/
|
|
4
|
+
export const checkDockerPlatform = {
|
|
5
|
+
id: 'docker-platform',
|
|
6
|
+
name: 'Check Docker Platform',
|
|
7
|
+
description: 'Detect missing --platform flag in Dockerfile FROM instructions',
|
|
8
|
+
severity: 'info',
|
|
9
|
+
fileTypes: ['dockerfile'],
|
|
10
|
+
check(context) {
|
|
11
|
+
const results = [];
|
|
12
|
+
const lines = context.content.split('\n');
|
|
13
|
+
for (let i = 0; i < lines.length; i++) {
|
|
14
|
+
const line = lines[i];
|
|
15
|
+
const lineNum = i + 1;
|
|
16
|
+
// Skip comments
|
|
17
|
+
if (line.trim().startsWith('#')) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
// Check for FROM instruction
|
|
21
|
+
if (/^\s*FROM\s+/i.test(line)) {
|
|
22
|
+
// Check if --platform is specified
|
|
23
|
+
if (!line.includes('--platform')) {
|
|
24
|
+
// Skip if using ARG for platform (dynamic platform)
|
|
25
|
+
if (/\$\{?TARGETPLATFORM\}?|\$\{?BUILDPLATFORM\}?/i.test(line)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
results.push({
|
|
29
|
+
line: lineNum,
|
|
30
|
+
column: 0,
|
|
31
|
+
message: 'Consider adding --platform flag for reproducible builds (e.g., --platform=linux/amd64)',
|
|
32
|
+
severity: 'info',
|
|
33
|
+
ruleId: 'docker-platform/missing',
|
|
34
|
+
fix: 'Add --platform=linux/amd64 or --platform=$TARGETPLATFORM',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return results;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=check-docker-platform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-docker-platform.js","sourceRoot":"","sources":["../../src/checks/check-docker-platform.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,mBAAmB,GAAS;IACvC,EAAE,EAAE,iBAAiB;IACrB,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EAAE,gEAAgE;IAC7E,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,YAAY,CAAC;IAEzB,KAAK,CAAC,OAAoB;QACxB,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YAEtB,gBAAgB;YAChB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChC,SAAS;YACX,CAAC;YAED,6BAA6B;YAC7B,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,mCAAmC;gBACnC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;oBACjC,oDAAoD;oBACpD,IAAI,+CAA+C,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC/D,SAAS;oBACX,CAAC;oBAED,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO;wBACb,MAAM,EAAE,CAAC;wBACT,OAAO,EAAE,wFAAwF;wBACjG,QAAQ,EAAE,MAAM;wBAChB,MAAM,EAAE,yBAAyB;wBACjC,GAAG,EAAE,0DAA0D;qBAChE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-dry-violations.d.ts","sourceRoot":"","sources":["../../src/checks/check-dry-violations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAoBvE,eAAO,MAAM,kBAAkB,EAAE,IAmEhC,CAAC"}
|