@mmnto/totem 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler-schema.d.ts +201 -0
- package/dist/compiler-schema.d.ts.map +1 -0
- package/dist/compiler-schema.js +46 -0
- package/dist/compiler-schema.js.map +1 -0
- package/dist/compiler.d.ts +14 -230
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +17 -380
- package/dist/compiler.js.map +1 -1
- package/dist/diff-parser.d.ts +8 -0
- package/dist/diff-parser.d.ts.map +1 -0
- package/dist/diff-parser.js +70 -0
- package/dist/diff-parser.js.map +1 -0
- package/dist/embedders/embedder.d.ts.map +1 -1
- package/dist/embedders/embedder.js +3 -7
- package/dist/embedders/embedder.js.map +1 -1
- package/dist/embedders/gemini-embedder.d.ts.map +1 -1
- package/dist/embedders/gemini-embedder.js +7 -9
- package/dist/embedders/gemini-embedder.js.map +1 -1
- package/dist/embedders/openai-embedder.d.ts.map +1 -1
- package/dist/embedders/openai-embedder.js +4 -4
- package/dist/embedders/openai-embedder.js.map +1 -1
- package/dist/exporter.d.ts.map +1 -1
- package/dist/exporter.js +3 -2
- package/dist/exporter.js.map +1 -1
- package/dist/lesson-io.d.ts.map +1 -1
- package/dist/lesson-io.js +19 -4
- package/dist/lesson-io.js.map +1 -1
- package/dist/lesson-io.test.js +18 -0
- package/dist/lesson-io.test.js.map +1 -1
- package/dist/lock.d.ts.map +1 -1
- package/dist/lock.js +2 -2
- package/dist/lock.js.map +1 -1
- package/dist/rule-engine.d.ts +31 -0
- package/dist/rule-engine.d.ts.map +1 -0
- package/dist/rule-engine.js +278 -0
- package/dist/rule-engine.js.map +1 -0
- package/dist/sarif.d.ts.map +1 -1
- package/dist/sarif.js +2 -1
- package/dist/sarif.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { extensionToLanguage } from './ast-classifier.js';
|
|
4
|
+
import { matchAstGrepPatternsBatch } from './ast-grep-query.js';
|
|
5
|
+
import { matchAstQueriesBatch } from './ast-query.js';
|
|
6
|
+
import { extractAddedLines } from './diff-parser.js';
|
|
7
|
+
// ─── File glob matching ─────────────────────────────
|
|
8
|
+
/**
|
|
9
|
+
* Check if a file path matches a single glob pattern.
|
|
10
|
+
* Supports: `*.ext`, `**\/*.ext`, `dir/**\/*.ext`, `dir/**`, literal filenames.
|
|
11
|
+
*/
|
|
12
|
+
export function matchesGlob(filePath, glob) {
|
|
13
|
+
// Normalize separators
|
|
14
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
15
|
+
// *.ext — match file extension anywhere
|
|
16
|
+
if (glob.startsWith('*.')) {
|
|
17
|
+
return normalized.endsWith(glob.slice(1));
|
|
18
|
+
}
|
|
19
|
+
// **/*.ext — same as *.ext (match extension anywhere in path)
|
|
20
|
+
if (glob.startsWith('**/')) {
|
|
21
|
+
return matchesGlob(normalized, glob.slice(3));
|
|
22
|
+
}
|
|
23
|
+
// dir/**/*.ext or dir/** — directory-prefixed recursive glob
|
|
24
|
+
const dstarIdx = glob.indexOf('/**/');
|
|
25
|
+
if (dstarIdx > 0) {
|
|
26
|
+
const prefix = glob.slice(0, dstarIdx);
|
|
27
|
+
const suffix = glob.slice(dstarIdx + 4); // after "/**/"
|
|
28
|
+
if (!normalized.startsWith(prefix + '/'))
|
|
29
|
+
return false;
|
|
30
|
+
const rest = normalized.slice(prefix.length + 1);
|
|
31
|
+
return suffix === '' || matchesGlob(rest, suffix);
|
|
32
|
+
}
|
|
33
|
+
// dir/** — match anything under directory (no trailing pattern)
|
|
34
|
+
if (glob.endsWith('/**')) {
|
|
35
|
+
const prefix = glob.slice(0, -3);
|
|
36
|
+
return normalized.startsWith(prefix + '/');
|
|
37
|
+
}
|
|
38
|
+
// dir/*.ext — single-star, non-recursive (matches files in exact directory)
|
|
39
|
+
const singleStarIdx = glob.indexOf('/*.');
|
|
40
|
+
// totem-ignore-next-line — this IS the glob matcher
|
|
41
|
+
if (singleStarIdx > 0 && !glob.includes('**')) {
|
|
42
|
+
const prefix = glob.slice(0, singleStarIdx);
|
|
43
|
+
const ext = glob.slice(singleStarIdx + 2); // "*.ext" portion
|
|
44
|
+
if (!normalized.startsWith(prefix + '/'))
|
|
45
|
+
return false;
|
|
46
|
+
const rest = normalized.slice(prefix.length + 1);
|
|
47
|
+
// Must be a direct child (no further slashes) and match the extension
|
|
48
|
+
return !rest.includes('/') && rest.endsWith(ext); // totem-ignore — this IS the glob matcher
|
|
49
|
+
}
|
|
50
|
+
// Literal filename match (e.g., "Dockerfile")
|
|
51
|
+
return normalized === glob || normalized.endsWith('/' + glob);
|
|
52
|
+
}
|
|
53
|
+
function fileMatchesGlobs(filePath, globs) {
|
|
54
|
+
const positive = globs.filter((g) => !g.startsWith('!'));
|
|
55
|
+
const negative = globs.filter((g) => g.startsWith('!')).map((g) => g.slice(1));
|
|
56
|
+
const positiveMatch = positive.length === 0 || positive.some((g) => matchesGlob(filePath, g));
|
|
57
|
+
const negativeMatch = negative.some((g) => matchesGlob(filePath, g));
|
|
58
|
+
return positiveMatch && !negativeMatch;
|
|
59
|
+
}
|
|
60
|
+
// ─── Inline suppression ─────────────────────────────
|
|
61
|
+
const SUPPRESS_MARKER = 'totem-ignore';
|
|
62
|
+
const SUPPRESS_NEXT_LINE_MARKER = 'totem-ignore-next-line';
|
|
63
|
+
/**
|
|
64
|
+
* Check if a line should be suppressed via inline directives.
|
|
65
|
+
* Supports two forms:
|
|
66
|
+
* - Same-line: code(); // totem-ignore (suppresses all rules on this line)
|
|
67
|
+
* - Next-line: // totem-ignore-next-line on the preceding line (suppresses all rules on this line)
|
|
68
|
+
*
|
|
69
|
+
* Syntax-agnostic: works with any comment style (//, #, HTML comments, block comments).
|
|
70
|
+
*/
|
|
71
|
+
function isSuppressed(line, precedingLine) {
|
|
72
|
+
// Same-line: 'totem-ignore' substring also matches 'totem-ignore-next-line',
|
|
73
|
+
// so directive lines themselves are inherently suppressed.
|
|
74
|
+
if (line.includes(SUPPRESS_MARKER))
|
|
75
|
+
return true;
|
|
76
|
+
// Next-line: preceding line (context or added) contains the next-line directive
|
|
77
|
+
if (precedingLine != null && precedingLine.includes(SUPPRESS_NEXT_LINE_MARKER))
|
|
78
|
+
return true;
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
// ─── Regex rule execution ───────────────────────────
|
|
82
|
+
/**
|
|
83
|
+
* Apply compiled rules against pre-extracted diff additions.
|
|
84
|
+
* Skips additions with non-code AST context (strings, comments, regex).
|
|
85
|
+
* Optional `onRuleEvent` callback enables observability metrics collection.
|
|
86
|
+
*/
|
|
87
|
+
export function applyRulesToAdditions(rules, additions, onRuleEvent) {
|
|
88
|
+
if (additions.length === 0 || rules.length === 0)
|
|
89
|
+
return [];
|
|
90
|
+
const violations = [];
|
|
91
|
+
// Only process regex-engine rules — AST rules have pattern: '' which would match everything
|
|
92
|
+
const regexRules = rules.filter((r) => r.engine === 'regex' || !r.engine);
|
|
93
|
+
for (const rule of regexRules) {
|
|
94
|
+
let re;
|
|
95
|
+
try {
|
|
96
|
+
re = new RegExp(rule.pattern);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Skip invalid patterns (shouldn't happen if validation gate works)
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
for (const addition of additions) {
|
|
103
|
+
// Skip non-code lines when AST context is available
|
|
104
|
+
if (addition.astContext && addition.astContext !== 'code')
|
|
105
|
+
continue;
|
|
106
|
+
// Skip if rule has fileGlobs and this file doesn't match
|
|
107
|
+
if (rule.fileGlobs && rule.fileGlobs.length > 0) {
|
|
108
|
+
if (!fileMatchesGlobs(addition.file, rule.fileGlobs))
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
// Skip if suppressed via inline directive
|
|
112
|
+
if (isSuppressed(addition.line, addition.precedingLine)) {
|
|
113
|
+
if (re.test(addition.line)) {
|
|
114
|
+
onRuleEvent?.('suppress', rule.lessonHash);
|
|
115
|
+
}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (re.test(addition.line)) {
|
|
119
|
+
onRuleEvent?.('trigger', rule.lessonHash);
|
|
120
|
+
violations.push({
|
|
121
|
+
rule,
|
|
122
|
+
file: addition.file,
|
|
123
|
+
line: addition.line,
|
|
124
|
+
lineNumber: addition.lineNumber,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return violations;
|
|
130
|
+
}
|
|
131
|
+
// ─── AST rule execution ─────────────────────────────
|
|
132
|
+
/**
|
|
133
|
+
* Apply AST-engine compiled rules against pre-extracted diff additions.
|
|
134
|
+
* Handles both Tree-sitter S-expression ('ast') and ast-grep ('ast-grep') engines.
|
|
135
|
+
* Async because it reads files and runs Tree-sitter queries.
|
|
136
|
+
* Handles fileGlobs filtering and suppression same as regex rules.
|
|
137
|
+
*/
|
|
138
|
+
export async function applyAstRulesToAdditions(rules, additions, cwd, onRuleEvent) {
|
|
139
|
+
const treeSitterRules = rules.filter((r) => r.engine === 'ast' && r.astQuery);
|
|
140
|
+
const astGrepRules = rules.filter((r) => r.engine === 'ast-grep' && r.astGrepPattern);
|
|
141
|
+
if ((treeSitterRules.length === 0 && astGrepRules.length === 0) || additions.length === 0) {
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
// Group additions by file
|
|
145
|
+
const byFile = new Map();
|
|
146
|
+
for (const a of additions) {
|
|
147
|
+
const existing = byFile.get(a.file);
|
|
148
|
+
if (existing) {
|
|
149
|
+
existing.push(a);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
byFile.set(a.file, [a]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const violations = [];
|
|
156
|
+
// Process each file once — batch all applicable queries per file
|
|
157
|
+
for (const [file, fileAdditions] of byFile) {
|
|
158
|
+
// Check language support
|
|
159
|
+
const ext = path.extname(file);
|
|
160
|
+
if (!extensionToLanguage(ext))
|
|
161
|
+
continue;
|
|
162
|
+
// Collect added line numbers, filtering suppressed lines
|
|
163
|
+
const addedLineNumbers = [];
|
|
164
|
+
for (const addition of fileAdditions) {
|
|
165
|
+
if (addition.astContext && addition.astContext !== 'code')
|
|
166
|
+
continue;
|
|
167
|
+
if (isSuppressed(addition.line, addition.precedingLine))
|
|
168
|
+
continue;
|
|
169
|
+
addedLineNumbers.push(addition.lineNumber);
|
|
170
|
+
}
|
|
171
|
+
if (addedLineNumbers.length === 0)
|
|
172
|
+
continue;
|
|
173
|
+
// ── Tree-sitter S-expression rules ────────────────
|
|
174
|
+
if (treeSitterRules.length > 0) {
|
|
175
|
+
const applicableTreeSitter = treeSitterRules.filter((rule) => {
|
|
176
|
+
if (rule.fileGlobs && rule.fileGlobs.length > 0) {
|
|
177
|
+
return fileMatchesGlobs(file, rule.fileGlobs);
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
});
|
|
181
|
+
if (applicableTreeSitter.length > 0) {
|
|
182
|
+
// Batch: parse file once, run all queries against the cached tree
|
|
183
|
+
const queries = applicableTreeSitter.map((rule) => ({
|
|
184
|
+
astQuery: rule.astQuery,
|
|
185
|
+
addedLineNumbers,
|
|
186
|
+
}));
|
|
187
|
+
const batchResults = await matchAstQueriesBatch(file, queries, cwd);
|
|
188
|
+
// Map results back to violations
|
|
189
|
+
for (const rule of applicableTreeSitter) {
|
|
190
|
+
const matches = batchResults.get(rule.astQuery) ?? [];
|
|
191
|
+
for (const match of matches) {
|
|
192
|
+
const addition = fileAdditions.find((a) => a.lineNumber === match.lineNumber);
|
|
193
|
+
if (addition && isSuppressed(addition.line, addition.precedingLine)) {
|
|
194
|
+
onRuleEvent?.('suppress', rule.lessonHash);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
onRuleEvent?.('trigger', rule.lessonHash);
|
|
198
|
+
violations.push({
|
|
199
|
+
rule,
|
|
200
|
+
file,
|
|
201
|
+
line: match.lineText,
|
|
202
|
+
lineNumber: match.lineNumber,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// ── ast-grep structural pattern rules ─────────────
|
|
209
|
+
if (astGrepRules.length > 0) {
|
|
210
|
+
const applicableAstGrep = astGrepRules.filter((rule) => {
|
|
211
|
+
if (rule.fileGlobs && rule.fileGlobs.length > 0) {
|
|
212
|
+
return fileMatchesGlobs(file, rule.fileGlobs);
|
|
213
|
+
}
|
|
214
|
+
return true;
|
|
215
|
+
});
|
|
216
|
+
if (applicableAstGrep.length > 0) {
|
|
217
|
+
// Read file content once for all ast-grep rules on this file
|
|
218
|
+
let content = null;
|
|
219
|
+
try {
|
|
220
|
+
const fullPath = path.resolve(cwd, file);
|
|
221
|
+
content = await fs.promises.readFile(fullPath, 'utf-8');
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// Fall through — content stays null
|
|
225
|
+
}
|
|
226
|
+
if (content) {
|
|
227
|
+
// Batch: parse file once, run all patterns
|
|
228
|
+
const queries = applicableAstGrep.map((rule) => ({
|
|
229
|
+
rule: rule.astGrepPattern,
|
|
230
|
+
addedLineNumbers,
|
|
231
|
+
}));
|
|
232
|
+
const batchResults = matchAstGrepPatternsBatch(content, ext, queries);
|
|
233
|
+
for (let i = 0; i < applicableAstGrep.length; i++) {
|
|
234
|
+
const rule = applicableAstGrep[i];
|
|
235
|
+
const matches = batchResults[i] ?? [];
|
|
236
|
+
for (const match of matches) {
|
|
237
|
+
const addition = fileAdditions.find((a) => a.lineNumber === match.lineNumber);
|
|
238
|
+
if (addition && isSuppressed(addition.line, addition.precedingLine)) {
|
|
239
|
+
onRuleEvent?.('suppress', rule.lessonHash);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
onRuleEvent?.('trigger', rule.lessonHash);
|
|
243
|
+
violations.push({
|
|
244
|
+
rule,
|
|
245
|
+
file,
|
|
246
|
+
line: match.lineText,
|
|
247
|
+
lineNumber: match.lineNumber,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return violations;
|
|
256
|
+
}
|
|
257
|
+
// ─── Convenience wrapper ────────────────────────────
|
|
258
|
+
/**
|
|
259
|
+
* Apply **regex-engine** compiled rules against added lines from a diff.
|
|
260
|
+
* This is a convenience wrapper that only handles 'regex' engine rules.
|
|
261
|
+
* For 'ast' and 'ast-grep' rules, call `applyAstRulesToAdditions` separately.
|
|
262
|
+
*
|
|
263
|
+
* @param rules — The full list of compiled rules. This function filters to regex rules.
|
|
264
|
+
* @param diff — The unified diff string.
|
|
265
|
+
* @param excludeFiles — File paths to skip (e.g., compiled-rules.json to avoid self-matches).
|
|
266
|
+
* @returns All regex-based violations found.
|
|
267
|
+
*/
|
|
268
|
+
export function applyRules(rules, diff, excludeFiles) {
|
|
269
|
+
let additions = extractAddedLines(diff);
|
|
270
|
+
if (additions.length === 0 || rules.length === 0)
|
|
271
|
+
return [];
|
|
272
|
+
if (excludeFiles && excludeFiles.length > 0) {
|
|
273
|
+
const excluded = new Set(excludeFiles);
|
|
274
|
+
additions = additions.filter((a) => !excluded.has(a.file));
|
|
275
|
+
}
|
|
276
|
+
return applyRulesToAdditions(rules, additions);
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=rule-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-engine.js","sourceRoot":"","sources":["../src/rule-engine.ts"],"names":[],"mappings":"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"}
|
package/dist/sarif.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../src/sarif.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../src/sarif.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG7D,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAIpD,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,QAAQ,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE;QACJ,MAAM,EAAE;YACN,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;YAChB,cAAc,EAAE,MAAM,CAAC;YACvB,KAAK,EAAE,wBAAwB,EAAE,CAAC;YAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACrC,CAAC;KACH,CAAC;IACF,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,eAAe,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE;QAChB,gBAAgB,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;QAClC,MAAM,EAAE;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAID,MAAM,WAAW,YAAY;IAC3B,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID;;;GAGG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEjD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,SAAS,EAAE,EACvB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,EAAE,YAAY,GACpB,QAAQ,CAqFV"}
|
package/dist/sarif.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { TotemCompileError } from './errors.js';
|
|
2
3
|
/** Default rule category when none is specified on the compiled rule. */
|
|
3
4
|
export const DEFAULT_RULE_CATEGORY = 'architecture';
|
|
4
5
|
// ─── Builder ─────────────────────────────────────────
|
|
@@ -38,7 +39,7 @@ export function buildSarifLog(violations, rules, options) {
|
|
|
38
39
|
const results = violations.map((v) => {
|
|
39
40
|
const idx = ruleIndexMap.get(v.rule.lessonHash);
|
|
40
41
|
if (idx === undefined) {
|
|
41
|
-
throw new
|
|
42
|
+
throw new TotemCompileError(`SARIF builder: no rule index for lessonHash ${v.rule.lessonHash}`, 'This is an internal error — the compiled rules may be corrupted. Run `totem compile --force`.');
|
|
42
43
|
}
|
|
43
44
|
return {
|
|
44
45
|
ruleId: ruleId(v.rule),
|
package/dist/sarif.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sarif.js","sourceRoot":"","sources":["../src/sarif.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sarif.js","sourceRoot":"","sources":["../src/sarif.ts"],"names":[],"mappings":"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"}
|