@iris-code/core 0.1.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/README.md +38 -0
- package/dist/config.d.ts +147 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +550 -0
- package/dist/config.js.map +1 -0
- package/dist/csharp/analyser.d.ts +14 -0
- package/dist/csharp/analyser.d.ts.map +1 -0
- package/dist/csharp/analyser.js +436 -0
- package/dist/csharp/analyser.js.map +1 -0
- package/dist/csharp/lexer.d.ts +29 -0
- package/dist/csharp/lexer.d.ts.map +1 -0
- package/dist/csharp/lexer.js +182 -0
- package/dist/csharp/lexer.js.map +1 -0
- package/dist/duplicates.d.ts +53 -0
- package/dist/duplicates.d.ts.map +1 -0
- package/dist/duplicates.js +491 -0
- package/dist/duplicates.js.map +1 -0
- package/dist/fileAnalyser.d.ts +4 -0
- package/dist/fileAnalyser.d.ts.map +1 -0
- package/dist/fileAnalyser.js +8 -0
- package/dist/fileAnalyser.js.map +1 -0
- package/dist/fileNaming.d.ts +68 -0
- package/dist/fileNaming.d.ts.map +1 -0
- package/dist/fileNaming.js +343 -0
- package/dist/fileNaming.js.map +1 -0
- package/dist/gate.d.ts +49 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +242 -0
- package/dist/gate.js.map +1 -0
- package/dist/go/analyser.d.ts +5 -0
- package/dist/go/analyser.d.ts.map +1 -0
- package/dist/go/analyser.js +576 -0
- package/dist/go/analyser.js.map +1 -0
- package/dist/guards.d.ts +16 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +355 -0
- package/dist/guards.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/languages.d.ts +46 -0
- package/dist/languages.d.ts.map +1 -0
- package/dist/languages.js +155 -0
- package/dist/languages.js.map +1 -0
- package/dist/lines.d.ts +9 -0
- package/dist/lines.d.ts.map +1 -0
- package/dist/lines.js +58 -0
- package/dist/lines.js.map +1 -0
- package/dist/python/analyser.d.ts +5 -0
- package/dist/python/analyser.d.ts.map +1 -0
- package/dist/python/analyser.js +630 -0
- package/dist/python/analyser.js.map +1 -0
- package/dist/qualitySignals.d.ts +30 -0
- package/dist/qualitySignals.d.ts.map +1 -0
- package/dist/qualitySignals.js +101 -0
- package/dist/qualitySignals.js.map +1 -0
- package/dist/ruby/analyser.d.ts +5 -0
- package/dist/ruby/analyser.d.ts.map +1 -0
- package/dist/ruby/analyser.js +450 -0
- package/dist/ruby/analyser.js.map +1 -0
- package/dist/scoring.d.ts +4 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +37 -0
- package/dist/scoring.js.map +1 -0
- package/dist/secrets.d.ts +5 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +245 -0
- package/dist/secrets.js.map +1 -0
- package/dist/securityContext.d.ts +2 -0
- package/dist/securityContext.d.ts.map +1 -0
- package/dist/securityContext.js +16 -0
- package/dist/securityContext.js.map +1 -0
- package/dist/sfc.d.ts +32 -0
- package/dist/sfc.d.ts.map +1 -0
- package/dist/sfc.js +228 -0
- package/dist/sfc.js.map +1 -0
- package/dist/slop.d.ts +37 -0
- package/dist/slop.d.ts.map +1 -0
- package/dist/slop.js +81 -0
- package/dist/slop.js.map +1 -0
- package/dist/suppressions.d.ts +19 -0
- package/dist/suppressions.d.ts.map +1 -0
- package/dist/suppressions.js +152 -0
- package/dist/suppressions.js.map +1 -0
- package/dist/ts/analyser.d.ts +4 -0
- package/dist/ts/analyser.d.ts.map +1 -0
- package/dist/ts/analyser.js +769 -0
- package/dist/ts/analyser.js.map +1 -0
- package/dist/types.d.ts +139 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +46 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
package/dist/secrets.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasSuspectKeyword = hasSuspectKeyword;
|
|
4
|
+
exports.detectHardcodedSecrets = detectHardcodedSecrets;
|
|
5
|
+
const guards_1 = require("./guards");
|
|
6
|
+
const SUSPECT_KEYWORDS = new Set(['key', 'token', 'secret', 'password', 'passwd', 'pwd', 'auth', 'credential', 'private', 'api', 'apikey']);
|
|
7
|
+
function hasSuspectKeyword(varName) {
|
|
8
|
+
const normalized = varName
|
|
9
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
10
|
+
.replace(/[^A-Za-z0-9]+/g, ' ')
|
|
11
|
+
.toLowerCase();
|
|
12
|
+
const segments = normalized.split(/\s+/).filter(Boolean);
|
|
13
|
+
return segments.some(seg => SUSPECT_KEYWORDS.has(seg));
|
|
14
|
+
}
|
|
15
|
+
// Values that are obviously placeholders, not real credentials
|
|
16
|
+
const PLACEHOLDER_RE = /your.*here|changeme|placeholder|^x{3,}$|^<[^>]+>$|^your_|^my_secret|^example|^sample|^test_|^dummy|^fake/i;
|
|
17
|
+
function maskSecret(value) {
|
|
18
|
+
return `${value.slice(0, 4)}****`;
|
|
19
|
+
}
|
|
20
|
+
function lineOf(source, index) {
|
|
21
|
+
let count = 0;
|
|
22
|
+
for (let i = 0; i < index; i++) {
|
|
23
|
+
if (source[i] === '\n')
|
|
24
|
+
count++;
|
|
25
|
+
}
|
|
26
|
+
return count + 1;
|
|
27
|
+
}
|
|
28
|
+
function isPlaceholder(value, varName) {
|
|
29
|
+
if (!value || !value.trim())
|
|
30
|
+
return true;
|
|
31
|
+
const v = value.trim();
|
|
32
|
+
if (PLACEHOLDER_RE.test(v))
|
|
33
|
+
return true;
|
|
34
|
+
// Value is ALL_CAPS (e.g. YOUR_TOKEN, REPLACE_ME)
|
|
35
|
+
if (/^[A-Z][A-Z0-9_]{2,}$/.test(v))
|
|
36
|
+
return true;
|
|
37
|
+
// Value equals the variable name (e.g. password = "password")
|
|
38
|
+
if (v.toLowerCase() === varName.toLowerCase())
|
|
39
|
+
return true;
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
// Layer 1: JS/TS — const/let/var name[: type] = "value" or 'value'
|
|
43
|
+
function detectLayer1Ts(source) {
|
|
44
|
+
const results = [];
|
|
45
|
+
const re = /(?:const|let|var)\s+(\w+)(?:\s*:\s*\S+)?\s*=\s*(['"])([^'"]{4,500})\2/g;
|
|
46
|
+
let m;
|
|
47
|
+
while ((m = re.exec(source)) !== null) {
|
|
48
|
+
const varName = m[1];
|
|
49
|
+
const value = m[3];
|
|
50
|
+
if (value.length < 8)
|
|
51
|
+
continue;
|
|
52
|
+
if (!hasSuspectKeyword(varName))
|
|
53
|
+
continue;
|
|
54
|
+
if (isPlaceholder(value, varName))
|
|
55
|
+
continue;
|
|
56
|
+
results.push({
|
|
57
|
+
line: lineOf(source, m.index),
|
|
58
|
+
variable: varName,
|
|
59
|
+
pattern: 'suspicious-name',
|
|
60
|
+
message: `Possible hardcoded secret: ${varName} assigned directly to a string literal`,
|
|
61
|
+
value,
|
|
62
|
+
maskedValue: maskSecret(value),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return results;
|
|
66
|
+
}
|
|
67
|
+
// Layer 1: Go — name := "value" or var/const name [type] = "value"
|
|
68
|
+
function detectLayer1Go(source) {
|
|
69
|
+
const results = [];
|
|
70
|
+
let m;
|
|
71
|
+
// Short var decl
|
|
72
|
+
const shortRe = /(\w+)\s*:=\s*"([^"\n]{4,500})"/g;
|
|
73
|
+
while ((m = shortRe.exec(source)) !== null) {
|
|
74
|
+
const varName = m[1];
|
|
75
|
+
const value = m[2];
|
|
76
|
+
if (value.length < 8)
|
|
77
|
+
continue;
|
|
78
|
+
if (!hasSuspectKeyword(varName))
|
|
79
|
+
continue;
|
|
80
|
+
if (isPlaceholder(value, varName))
|
|
81
|
+
continue;
|
|
82
|
+
results.push({
|
|
83
|
+
line: lineOf(source, m.index),
|
|
84
|
+
variable: varName,
|
|
85
|
+
pattern: 'suspicious-name',
|
|
86
|
+
message: `Possible hardcoded secret: ${varName} assigned directly to a string literal`,
|
|
87
|
+
value,
|
|
88
|
+
maskedValue: maskSecret(value),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Explicit var/const decl
|
|
92
|
+
const varRe = /(?:var|const)\s+(\w+)(?:\s+\w+)?\s*=\s*"([^"\n]{4,500})"/g;
|
|
93
|
+
while ((m = varRe.exec(source)) !== null) {
|
|
94
|
+
const varName = m[1];
|
|
95
|
+
const value = m[2];
|
|
96
|
+
if (value.length < 8)
|
|
97
|
+
continue;
|
|
98
|
+
if (!hasSuspectKeyword(varName))
|
|
99
|
+
continue;
|
|
100
|
+
if (isPlaceholder(value, varName))
|
|
101
|
+
continue;
|
|
102
|
+
results.push({
|
|
103
|
+
line: lineOf(source, m.index),
|
|
104
|
+
variable: varName,
|
|
105
|
+
pattern: 'suspicious-name',
|
|
106
|
+
message: `Possible hardcoded secret: ${varName} assigned directly to a string literal`,
|
|
107
|
+
value,
|
|
108
|
+
maskedValue: maskSecret(value),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return results;
|
|
112
|
+
}
|
|
113
|
+
// Layer 1: Python — name = "value" or name = 'value'
|
|
114
|
+
function detectLayer1Py(source) {
|
|
115
|
+
const results = [];
|
|
116
|
+
const re = /^[ \t]*(\w+)\s*=\s*(?:"([^"\n]{4,500})"|'([^'\n]{4,500})')/gm;
|
|
117
|
+
let m;
|
|
118
|
+
while ((m = re.exec(source)) !== null) {
|
|
119
|
+
const varName = m[1];
|
|
120
|
+
const value = m[2] ?? m[3];
|
|
121
|
+
if (value.length < 8)
|
|
122
|
+
continue;
|
|
123
|
+
if (!hasSuspectKeyword(varName))
|
|
124
|
+
continue;
|
|
125
|
+
if (isPlaceholder(value, varName))
|
|
126
|
+
continue;
|
|
127
|
+
results.push({
|
|
128
|
+
line: lineOf(source, m.index),
|
|
129
|
+
variable: varName,
|
|
130
|
+
pattern: 'suspicious-name',
|
|
131
|
+
message: `Possible hardcoded secret: ${varName} assigned directly to a string literal`,
|
|
132
|
+
value,
|
|
133
|
+
maskedValue: maskSecret(value),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return results;
|
|
137
|
+
}
|
|
138
|
+
// Layer 1: Ruby constants, locals, instance/class variables and hash-style config.
|
|
139
|
+
function detectLayer1Ruby(source) {
|
|
140
|
+
const results = [];
|
|
141
|
+
const re = /^[ \t]*(?:(?:self\.)?([A-Za-z_]\w*[!?]?)|(@@?[A-Za-z_]\w*)|:([A-Za-z_]\w*))\s*(?:=>|:)??\s*=\s*(?:"([^"\n]{4,500})"|'([^'\n]{4,500})')/gm;
|
|
142
|
+
let m;
|
|
143
|
+
while ((m = re.exec(source)) !== null) {
|
|
144
|
+
const varName = m[1] ?? m[2] ?? m[3];
|
|
145
|
+
const value = m[4] ?? m[5];
|
|
146
|
+
if (!varName || !value || value.length < 8 || !hasSuspectKeyword(varName) || isPlaceholder(value, varName))
|
|
147
|
+
continue;
|
|
148
|
+
results.push({ line: lineOf(source, m.index), variable: varName, pattern: 'suspicious-name', message: `Possible hardcoded secret: ${varName} assigned directly to a string literal`, value, maskedValue: maskSecret(value) });
|
|
149
|
+
}
|
|
150
|
+
return results;
|
|
151
|
+
}
|
|
152
|
+
// MSBuild properties whose NAME contains a suspect keyword but whose value is
|
|
153
|
+
// never a credential. UserSecretsId is the important one: it is the id of the
|
|
154
|
+
// out-of-tree secrets file, so flagging it would punish the very feature that
|
|
155
|
+
// keeps secrets out of the repo.
|
|
156
|
+
const CSHARP_XML_EXEMPT_PROPERTIES = new Set([
|
|
157
|
+
'usersecretsid', 'assemblyoriginatorkeyfile', 'keyoriginatorfile', 'publicsign',
|
|
158
|
+
'signassembly', 'delaysign', 'packagelicensefile', 'privateassets',
|
|
159
|
+
]);
|
|
160
|
+
// Layer 1: C# fields, properties, locals, and XML project properties.
|
|
161
|
+
// `var` is included on purpose - `var apiKey = "..."` is at least as common in
|
|
162
|
+
// C# as an explicitly typed field, and typing it `string` is optional.
|
|
163
|
+
function detectLayer1CSharp(source) {
|
|
164
|
+
const results = [];
|
|
165
|
+
const assignRe = /(?:(?:const|readonly|static|private|protected|internal|public|required|volatile)\s+)*\b(?:string|var)\s+([A-Za-z_]\w*)\s*(?:\{[^}]*\}\s*)?=\s*(?:@?"([^"\n]{4,500})"|"""([^"\n]{4,500})""")/g;
|
|
166
|
+
let m;
|
|
167
|
+
while ((m = assignRe.exec(source)) !== null) {
|
|
168
|
+
const varName = m[1];
|
|
169
|
+
const value = m[2] ?? m[3];
|
|
170
|
+
if (!varName || !value || value.length < 8 || !hasSuspectKeyword(varName) || isPlaceholder(value, varName))
|
|
171
|
+
continue;
|
|
172
|
+
results.push({ line: lineOf(source, m.index), variable: varName, pattern: 'suspicious-name', message: `Possible hardcoded secret: ${varName} assigned directly to a string literal`, value, maskedValue: maskSecret(value) });
|
|
173
|
+
}
|
|
174
|
+
const xmlRe = /<([A-Za-z_][\w.-]*(?:Key|Token|Secret|Password|Credential|Private|Pwd)[\w.-]*)>([^<]{8,500})<\/\1>/gi;
|
|
175
|
+
while ((m = xmlRe.exec(source)) !== null) {
|
|
176
|
+
const varName = m[1];
|
|
177
|
+
const value = m[2].trim();
|
|
178
|
+
if (!value || CSHARP_XML_EXEMPT_PROPERTIES.has(varName.toLowerCase()) || isPlaceholder(value, varName))
|
|
179
|
+
continue;
|
|
180
|
+
// A value made only of MSBuild property/item references - $(ApiToken),
|
|
181
|
+
// @(Items), %(Meta) - is injected at build time from CI or a secret store.
|
|
182
|
+
// That is the FIX for this rule, so flagging it would punish it.
|
|
183
|
+
if (/^(?:[$@%]\([^)]+\)|\s)+$/.test(value))
|
|
184
|
+
continue;
|
|
185
|
+
results.push({ line: lineOf(source, m.index), variable: varName, pattern: 'suspicious-name', message: `Possible hardcoded secret: ${varName} assigned directly in project XML`, value, maskedValue: maskSecret(value) });
|
|
186
|
+
}
|
|
187
|
+
return results;
|
|
188
|
+
}
|
|
189
|
+
// Layer 2: Known secret format patterns — language-agnostic, scan full source
|
|
190
|
+
const KNOWN_PATTERNS = [
|
|
191
|
+
{ re: /sk-[a-zA-Z0-9]{10,}/g, name: 'OpenAI/Stripe secret key (sk-)' },
|
|
192
|
+
// Stripe live/restricted keys use underscores, so the sk- pattern above
|
|
193
|
+
// never matched them - gap found in the 2026-07-19 security pass.
|
|
194
|
+
{ re: /[sr]k_live_[a-zA-Z0-9]{16,}/g, name: 'Stripe live key (sk_live_/rk_live_)' },
|
|
195
|
+
{ re: /ghp_[a-zA-Z0-9]{36,}/g, name: 'GitHub PAT (ghp_)' },
|
|
196
|
+
{ re: /ghs_[a-zA-Z0-9]{36,}/g, name: 'GitHub token (ghs_)' },
|
|
197
|
+
{ re: /github_pat_[a-zA-Z0-9_]{36,}/g, name: 'GitHub fine-grained PAT (github_pat_)' },
|
|
198
|
+
{ re: /glpat-[a-zA-Z0-9_-]{20,}/g, name: 'GitLab PAT (glpat-)' },
|
|
199
|
+
{ re: /npm_[a-zA-Z0-9]{36,}/g, name: 'npm access token (npm_)' },
|
|
200
|
+
{ re: /SG\.[a-zA-Z0-9_-]{16,}\.[a-zA-Z0-9_-]{16,}/g, name: 'SendGrid API key (SG.)' },
|
|
201
|
+
{ re: /xoxb-[a-zA-Z0-9-]{10,}/g, name: 'Slack bot token (xoxb-)' },
|
|
202
|
+
{ re: /xoxp-[a-zA-Z0-9-]{10,}/g, name: 'Slack user token (xoxp-)' },
|
|
203
|
+
{ re: /AIza[a-zA-Z0-9_-]{35}/g, name: 'Google API key (AIza)' },
|
|
204
|
+
{ re: /AKIA[A-Z0-9]{16}/g, name: 'AWS access key (AKIA)' },
|
|
205
|
+
{ re: /Bearer\s+[a-zA-Z0-9_\-.=+/]{20,}/g, name: 'Inline Bearer token' },
|
|
206
|
+
{ re: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g, name: 'Private key material (PEM header)' },
|
|
207
|
+
];
|
|
208
|
+
function detectLayer2(source) {
|
|
209
|
+
const results = [];
|
|
210
|
+
for (const { re, name } of KNOWN_PATTERNS) {
|
|
211
|
+
re.lastIndex = 0;
|
|
212
|
+
let m;
|
|
213
|
+
while ((m = re.exec(source)) !== null) {
|
|
214
|
+
results.push({
|
|
215
|
+
line: lineOf(source, m.index),
|
|
216
|
+
pattern: name,
|
|
217
|
+
message: `Possible hardcoded secret: ${name} detected`,
|
|
218
|
+
value: m[0],
|
|
219
|
+
maskedValue: maskSecret(m[0]),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return results;
|
|
224
|
+
}
|
|
225
|
+
function detectHardcodedSecrets(source, config, language, filePath = '') {
|
|
226
|
+
if (!config.enableSecretsDetection)
|
|
227
|
+
return [];
|
|
228
|
+
// In test files, fixture credentials (e.g. password="secret123") are expected
|
|
229
|
+
// and not real. Skip the suspicious-name heuristic (Layer 1) there, but keep
|
|
230
|
+
// Layer 2 so a genuinely leaked provider token (AWS/Stripe/GitHub/...) is still
|
|
231
|
+
// flagged even when it appears in a test.
|
|
232
|
+
const layer1 = (0, guards_1.isTestFile)(filePath)
|
|
233
|
+
? []
|
|
234
|
+
: language === 'go' ? detectLayer1Go(source) :
|
|
235
|
+
language === 'python' ? detectLayer1Py(source) :
|
|
236
|
+
language === 'ruby' ? detectLayer1Ruby(source) :
|
|
237
|
+
language === 'csharp' ? detectLayer1CSharp(source) :
|
|
238
|
+
detectLayer1Ts(source);
|
|
239
|
+
const layer2 = detectLayer2(source);
|
|
240
|
+
// Suppress Layer 2 hits on lines already flagged by Layer 1 (avoid duplicate Problems entries)
|
|
241
|
+
const layer1Lines = new Set(layer1.map(s => s.line));
|
|
242
|
+
const uniqueLayer2 = layer2.filter(s => !layer1Lines.has(s.line));
|
|
243
|
+
return [...layer1, ...uniqueLayer2];
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"securityContext.d.ts","sourceRoot":"","sources":["../src/securityContext.ts"],"names":[],"mappings":"AASA,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAIvE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasSecurityContext = hasSecurityContext;
|
|
4
|
+
const secrets_1 = require("./secrets");
|
|
5
|
+
// Math.random()/rand.Intn()/random.random() are only a security smell when
|
|
6
|
+
// the value feeds something security-sensitive (a token, key, password, ...).
|
|
7
|
+
// Most calls are UI jitter, sampling, or test data, so a nearby suspect
|
|
8
|
+
// keyword is required before flagging - otherwise every RNG call would fire.
|
|
9
|
+
const CONTEXT_CHARS_BEFORE = 200;
|
|
10
|
+
const CONTEXT_CHARS_AFTER = 60;
|
|
11
|
+
function hasSecurityContext(text, index) {
|
|
12
|
+
const start = Math.max(0, index - CONTEXT_CHARS_BEFORE);
|
|
13
|
+
const end = Math.min(text.length, index + CONTEXT_CHARS_AFTER);
|
|
14
|
+
return (0, secrets_1.hasSuspectKeyword)(text.slice(start, end));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=securityContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"securityContext.js","sourceRoot":"","sources":["../src/securityContext.ts"],"names":[],"mappings":";;AASA,gDAIC;AAbD,uCAA6C;AAE7C,2EAA2E;AAC3E,8EAA8E;AAC9E,wEAAwE;AACxE,6EAA6E;AAC7E,MAAM,oBAAoB,GAAG,GAAG,CAAA;AAChC,MAAM,mBAAmB,GAAG,EAAE,CAAA;AAE9B,SAAgB,kBAAkB,CAAC,IAAY,EAAE,KAAa;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,oBAAoB,CAAC,CAAA;IACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,mBAAmB,CAAC,CAAA;IAC9D,OAAO,IAAA,2BAAiB,EAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;AAClD,CAAC"}
|
package/dist/sfc.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Language } from './types';
|
|
2
|
+
export type SingleFileComponentKind = 'vue' | 'svelte';
|
|
3
|
+
export interface SfcScriptBlock {
|
|
4
|
+
/** Zero-based source offsets. The content excludes the opening/closing tags. */
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
startLine: number;
|
|
8
|
+
endLine: number;
|
|
9
|
+
language: 'javascript' | 'typescript';
|
|
10
|
+
attributes: string;
|
|
11
|
+
}
|
|
12
|
+
export interface PreparedSource {
|
|
13
|
+
source: string;
|
|
14
|
+
language: Language;
|
|
15
|
+
kind: 'source' | SingleFileComponentKind | 'erb';
|
|
16
|
+
scriptBlocks: readonly SfcScriptBlock[];
|
|
17
|
+
}
|
|
18
|
+
export declare function singleFileComponentKind(filePath: string): SingleFileComponentKind | null;
|
|
19
|
+
export declare function isSingleFileComponent(filePath: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Extract every executable script region from a Vue or Svelte component.
|
|
22
|
+
*
|
|
23
|
+
* Non-script characters become spaces while CR/LF characters are retained.
|
|
24
|
+
* The result therefore has the same length and line layout as the component,
|
|
25
|
+
* allowing every existing analyser and suppression/duplicate finding to report
|
|
26
|
+
* native SFC line numbers without a host-specific remapping layer.
|
|
27
|
+
*/
|
|
28
|
+
export declare function extractSfcScripts(source: string, filePath: string): PreparedSource;
|
|
29
|
+
export declare function prepareSourceForAnalysis(source: string, filePath: string): PreparedSource;
|
|
30
|
+
/** Extract executable ERB tags while retaining byte offsets and native lines. */
|
|
31
|
+
export declare function extractErbRuby(source: string): PreparedSource;
|
|
32
|
+
//# sourceMappingURL=sfc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfc.d.ts","sourceRoot":"","sources":["../src/sfc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGvC,MAAM,MAAM,uBAAuB,GAAG,KAAK,GAAG,QAAQ,CAAA;AAEtD,MAAM,WAAW,cAAc;IAC7B,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,YAAY,GAAG,YAAY,CAAA;IACrC,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,QAAQ,CAAA;IAClB,IAAI,EAAE,QAAQ,GAAG,uBAAuB,GAAG,KAAK,CAAA;IAChD,YAAY,EAAE,SAAS,cAAc,EAAE,CAAA;CACxC;AAMD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI,CAGxF;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE/D;AAgFD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAmElF;AAcD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAGzF;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CA2B7D"}
|
package/dist/sfc.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.singleFileComponentKind = singleFileComponentKind;
|
|
4
|
+
exports.isSingleFileComponent = isSingleFileComponent;
|
|
5
|
+
exports.extractSfcScripts = extractSfcScripts;
|
|
6
|
+
exports.prepareSourceForAnalysis = prepareSourceForAnalysis;
|
|
7
|
+
exports.extractErbRuby = extractErbRuby;
|
|
8
|
+
const lines_1 = require("./lines");
|
|
9
|
+
const SFC_EXTENSION_RE = /\.(vue|svelte)$/i;
|
|
10
|
+
const LANG_ATTRIBUTE_RE = /(?:^|\s)lang\s*=\s*(?:["']([^"']+)["']|([^\s]+))/i;
|
|
11
|
+
const VOID_ELEMENTS = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
|
|
12
|
+
function singleFileComponentKind(filePath) {
|
|
13
|
+
const match = SFC_EXTENSION_RE.exec(filePath);
|
|
14
|
+
return match ? match[1].toLowerCase() : null;
|
|
15
|
+
}
|
|
16
|
+
function isSingleFileComponent(filePath) {
|
|
17
|
+
return singleFileComponentKind(filePath) !== null;
|
|
18
|
+
}
|
|
19
|
+
function scriptLanguage(attributes) {
|
|
20
|
+
const match = LANG_ATTRIBUTE_RE.exec(attributes);
|
|
21
|
+
if (!match)
|
|
22
|
+
return 'javascript';
|
|
23
|
+
const value = (match[1] ?? match[2] ?? '').toLowerCase();
|
|
24
|
+
if (value === 'ts' || value === 'typescript' || value === 'tsx')
|
|
25
|
+
return 'typescript';
|
|
26
|
+
if (value === 'js' || value === 'javascript' || value === 'jsx')
|
|
27
|
+
return 'javascript';
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
function tagEndAt(source, start) {
|
|
31
|
+
let quote = null;
|
|
32
|
+
for (let index = start; index < source.length; index++) {
|
|
33
|
+
const character = source[index];
|
|
34
|
+
if (quote) {
|
|
35
|
+
if (character === quote)
|
|
36
|
+
quote = null;
|
|
37
|
+
}
|
|
38
|
+
else if (character === '"' || character === "'") {
|
|
39
|
+
quote = character;
|
|
40
|
+
}
|
|
41
|
+
else if (character === '>') {
|
|
42
|
+
return index;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return -1;
|
|
46
|
+
}
|
|
47
|
+
/** True only when a script tag is at component root, not rendered markup. */
|
|
48
|
+
function isTopLevelScript(structure, offset) {
|
|
49
|
+
const stack = [];
|
|
50
|
+
let svelteBlockDepth = 0;
|
|
51
|
+
let index = 0;
|
|
52
|
+
while (index < offset) {
|
|
53
|
+
if (structure[index] === '{' && structure[index + 1] === '#') {
|
|
54
|
+
svelteBlockDepth++;
|
|
55
|
+
index += 2;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (structure[index] === '{' && structure[index + 1] === '/') {
|
|
59
|
+
svelteBlockDepth = Math.max(0, svelteBlockDepth - 1);
|
|
60
|
+
index += 2;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (structure[index] !== '<') {
|
|
64
|
+
index++;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (structure.slice(index, index + 4).join('') === '<!--') {
|
|
68
|
+
const end = structure.slice(index + 4).join('').indexOf('-->');
|
|
69
|
+
index = end === -1 ? offset : index + 4 + end + 3;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const closing = structure[index + 1] === '/';
|
|
73
|
+
let nameStart = index + (closing ? 2 : 1);
|
|
74
|
+
if (!/[A-Za-z]/.test(structure[nameStart] ?? '')) {
|
|
75
|
+
index++;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
let nameEnd = nameStart + 1;
|
|
79
|
+
while (/[\w:.-]/.test(structure[nameEnd] ?? ''))
|
|
80
|
+
nameEnd++;
|
|
81
|
+
const name = structure.slice(nameStart, nameEnd).join('').toLowerCase();
|
|
82
|
+
const tagEnd = tagEndAt(structure, nameEnd);
|
|
83
|
+
if (tagEnd === -1 || tagEnd >= offset)
|
|
84
|
+
break;
|
|
85
|
+
if (closing) {
|
|
86
|
+
const matching = stack.lastIndexOf(name);
|
|
87
|
+
if (matching !== -1)
|
|
88
|
+
stack.splice(matching);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
let slash = tagEnd - 1;
|
|
92
|
+
while (slash > nameEnd && /\s/.test(structure[slash]))
|
|
93
|
+
slash--;
|
|
94
|
+
if (structure[slash] !== '/' && !VOID_ELEMENTS.has(name))
|
|
95
|
+
stack.push(name);
|
|
96
|
+
}
|
|
97
|
+
index = tagEnd + 1;
|
|
98
|
+
}
|
|
99
|
+
return stack.length === 0 && svelteBlockDepth === 0;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Extract every executable script region from a Vue or Svelte component.
|
|
103
|
+
*
|
|
104
|
+
* Non-script characters become spaces while CR/LF characters are retained.
|
|
105
|
+
* The result therefore has the same length and line layout as the component,
|
|
106
|
+
* allowing every existing analyser and suppression/duplicate finding to report
|
|
107
|
+
* native SFC line numbers without a host-specific remapping layer.
|
|
108
|
+
*/
|
|
109
|
+
function extractSfcScripts(source, filePath) {
|
|
110
|
+
const kind = singleFileComponentKind(filePath);
|
|
111
|
+
if (!kind) {
|
|
112
|
+
return {
|
|
113
|
+
source,
|
|
114
|
+
language: languageForRegularFile(filePath),
|
|
115
|
+
kind: 'source',
|
|
116
|
+
scriptBlocks: [],
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const output = Array.from(source, character => character === '\n' || character === '\r' ? character : ' ');
|
|
120
|
+
const structure = Array.from(source);
|
|
121
|
+
const blocks = [];
|
|
122
|
+
const openTag = /<script(?=\s|>)/gi;
|
|
123
|
+
let match;
|
|
124
|
+
while ((match = openTag.exec(source)) !== null) {
|
|
125
|
+
const topLevel = isTopLevelScript(structure, match.index);
|
|
126
|
+
// Vue's `generic` attribute may itself contain `>` characters. Find the
|
|
127
|
+
// real tag end instead of relying on `[^>]*`, respecting quoted values.
|
|
128
|
+
const tagEnd = tagEndAt(source, openTag.lastIndex);
|
|
129
|
+
if (tagEnd === -1)
|
|
130
|
+
break;
|
|
131
|
+
const attributes = source.slice(openTag.lastIndex, tagEnd);
|
|
132
|
+
openTag.lastIndex = tagEnd + 1;
|
|
133
|
+
if (/\/\s*$/.test(attributes))
|
|
134
|
+
continue;
|
|
135
|
+
const contentStart = tagEnd + 1;
|
|
136
|
+
const closeTag = /<\/script\s*>/gi;
|
|
137
|
+
closeTag.lastIndex = contentStart;
|
|
138
|
+
const close = closeTag.exec(source);
|
|
139
|
+
const contentEnd = close?.index ?? source.length;
|
|
140
|
+
const language = scriptLanguage(attributes);
|
|
141
|
+
for (let index = contentStart; index < contentEnd; index++) {
|
|
142
|
+
if (structure[index] !== '\n' && structure[index] !== '\r')
|
|
143
|
+
structure[index] = ' ';
|
|
144
|
+
}
|
|
145
|
+
if (!topLevel || !language) {
|
|
146
|
+
if (!close)
|
|
147
|
+
break;
|
|
148
|
+
openTag.lastIndex = close.index + close[0].length;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
for (let index = contentStart; index < contentEnd; index++) {
|
|
152
|
+
output[index] = source[index];
|
|
153
|
+
}
|
|
154
|
+
blocks.push({
|
|
155
|
+
start: contentStart,
|
|
156
|
+
end: contentEnd,
|
|
157
|
+
startLine: (0, lines_1.lineOf)(source, contentStart),
|
|
158
|
+
endLine: (0, lines_1.lineOf)(source, contentEnd),
|
|
159
|
+
language,
|
|
160
|
+
attributes,
|
|
161
|
+
});
|
|
162
|
+
if (!close)
|
|
163
|
+
break;
|
|
164
|
+
openTag.lastIndex = close.index + close[0].length;
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
source: output.join(''),
|
|
168
|
+
// A component containing any TypeScript block must be analysed with the TS
|
|
169
|
+
// metrics enabled. Plain/missing script tags use JavaScript semantics.
|
|
170
|
+
language: blocks.some(block => block.language === 'typescript') ? 'typescript' : 'javascript',
|
|
171
|
+
kind,
|
|
172
|
+
scriptBlocks: blocks,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function languageForRegularFile(filePath) {
|
|
176
|
+
const lower = filePath.toLowerCase();
|
|
177
|
+
if (lower.endsWith('.go'))
|
|
178
|
+
return 'go';
|
|
179
|
+
if (lower.endsWith('.py') || lower.endsWith('.pyw'))
|
|
180
|
+
return 'python';
|
|
181
|
+
if (/\.(?:rb|rbw|rake|gemspec|ru|thor|builder|jbuilder|rabl|arb|podspec|erb|rhtml)$/.test(lower))
|
|
182
|
+
return 'ruby';
|
|
183
|
+
if (/\.(?:cs|csproj)$/.test(lower))
|
|
184
|
+
return 'csharp';
|
|
185
|
+
const base = lower.replace(/\\/g, '/').split('/').pop() ?? lower;
|
|
186
|
+
if (new Set(['appfile', 'berksfile', 'brewfile', 'capfile', 'dangerfile', 'deliverfile', 'fastfile', 'gemfile', 'guardfile', 'gymfile', 'matchfile', 'podfile', 'pluginfile', 'puppetfile', 'rakefile', 'scanfile', 'snapfile', 'thorfile', 'vagrantfile', '.irbrc', '.pryrc']).has(base))
|
|
187
|
+
return 'ruby';
|
|
188
|
+
if (/\.(js|jsx|mjs|cjs)$/.test(lower))
|
|
189
|
+
return 'javascript';
|
|
190
|
+
return 'typescript';
|
|
191
|
+
}
|
|
192
|
+
function prepareSourceForAnalysis(source, filePath) {
|
|
193
|
+
if (/\.(?:erb|rhtml)$/i.test(filePath))
|
|
194
|
+
return extractErbRuby(source);
|
|
195
|
+
return extractSfcScripts(source, filePath);
|
|
196
|
+
}
|
|
197
|
+
/** Extract executable ERB tags while retaining byte offsets and native lines. */
|
|
198
|
+
function extractErbRuby(source) {
|
|
199
|
+
const output = Array.from(source, character => character === '\n' || character === '\r' ? character : ' ');
|
|
200
|
+
const blocks = [];
|
|
201
|
+
const open = /<%(?!%)([-=#]?)/g;
|
|
202
|
+
let match;
|
|
203
|
+
while ((match = open.exec(source)) !== null) {
|
|
204
|
+
const marker = match[1];
|
|
205
|
+
const contentStart = open.lastIndex;
|
|
206
|
+
const close = /-?%>/g;
|
|
207
|
+
close.lastIndex = contentStart;
|
|
208
|
+
const endMatch = close.exec(source);
|
|
209
|
+
const contentEnd = endMatch?.index ?? source.length;
|
|
210
|
+
if (marker !== '#') {
|
|
211
|
+
for (let index = contentStart; index < contentEnd; index++)
|
|
212
|
+
output[index] = source[index];
|
|
213
|
+
blocks.push({
|
|
214
|
+
start: contentStart,
|
|
215
|
+
end: contentEnd,
|
|
216
|
+
startLine: (0, lines_1.lineOf)(source, contentStart),
|
|
217
|
+
endLine: (0, lines_1.lineOf)(source, contentEnd),
|
|
218
|
+
language: 'javascript',
|
|
219
|
+
attributes: marker,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (!endMatch)
|
|
223
|
+
break;
|
|
224
|
+
open.lastIndex = endMatch.index + endMatch[0].length;
|
|
225
|
+
}
|
|
226
|
+
return { source: output.join(''), language: 'ruby', kind: 'erb', scriptBlocks: blocks };
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=sfc.js.map
|
package/dist/sfc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfc.js","sourceRoot":"","sources":["../src/sfc.ts"],"names":[],"mappings":"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"}
|
package/dist/slop.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type SlopBand = 'clean' | 'drifting' | 'slop';
|
|
2
|
+
export type SlopContributorKey = 'duplication' | 'security' | 'suppressions' | 'type-debt' | 'debug-prints' | 'complexity' | 'todos' | 'file-naming';
|
|
3
|
+
export interface SlopScoreInput {
|
|
4
|
+
totalCodeLines: number;
|
|
5
|
+
fileCount: number;
|
|
6
|
+
typeScriptFileCount: number;
|
|
7
|
+
duplicationPercent: number;
|
|
8
|
+
duplicateBlockCount: number;
|
|
9
|
+
bareSuppressionCount: number;
|
|
10
|
+
suppressedCount: number;
|
|
11
|
+
securitySmellCount: number;
|
|
12
|
+
anyUsageCount: number;
|
|
13
|
+
missingReturnTypeCount: number;
|
|
14
|
+
debugPrintCount: number;
|
|
15
|
+
todoCount: number;
|
|
16
|
+
highComplexityFileCount: number;
|
|
17
|
+
namingViolationCount: number;
|
|
18
|
+
}
|
|
19
|
+
export interface SlopContributor {
|
|
20
|
+
key: SlopContributorKey;
|
|
21
|
+
label: string;
|
|
22
|
+
rawValue: number;
|
|
23
|
+
points: number;
|
|
24
|
+
}
|
|
25
|
+
export interface SlopScoreResult {
|
|
26
|
+
score: number;
|
|
27
|
+
band: SlopBand;
|
|
28
|
+
contributors: SlopContributor[];
|
|
29
|
+
}
|
|
30
|
+
export declare const SLOP_WEIGHTS: Readonly<Record<SlopContributorKey, number>>;
|
|
31
|
+
export declare const SLOP_SATURATION: Readonly<Record<SlopContributorKey, number>>;
|
|
32
|
+
export declare const SLOP_BANDS: {
|
|
33
|
+
readonly cleanMax: 24;
|
|
34
|
+
readonly driftingMax: 54;
|
|
35
|
+
};
|
|
36
|
+
export declare function computeSlopScore(input: SlopScoreInput): SlopScoreResult;
|
|
37
|
+
//# sourceMappingURL=slop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slop.d.ts","sourceRoot":"","sources":["../src/slop.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAA;AAEpD,MAAM,MAAM,kBAAkB,GAC1B,aAAa,GACb,UAAU,GACV,cAAc,GACd,WAAW,GACX,cAAc,GACd,YAAY,GACZ,OAAO,GACP,aAAa,CAAA;AAEjB,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,oBAAoB,EAAE,MAAM,CAAA;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,uBAAuB,EAAE,MAAM,CAAA;IAC/B,oBAAoB,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,kBAAkB,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,QAAQ,CAAA;IACd,YAAY,EAAE,eAAe,EAAE,CAAA;CAChC;AAED,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CASrE,CAAA;AAID,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CASxE,CAAA;AAED,eAAO,MAAM,UAAU;;;CAGb,CAAA;AAYV,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CA2CvE"}
|