@mmnto/totem 0.17.0 → 0.19.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/dist/compiler.d.ts +158 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +213 -0
- package/dist/compiler.js.map +1 -0
- package/dist/compiler.test.d.ts +2 -0
- package/dist/compiler.test.d.ts.map +1 -0
- package/dist/compiler.test.js +350 -0
- package/dist/compiler.test.js.map +1 -0
- package/dist/config-schema.d.ts +194 -36
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config-schema.js +41 -10
- package/dist/config-schema.js.map +1 -1
- package/dist/config-schema.test.js +131 -1
- package/dist/config-schema.test.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { applyRules, extractAddedLines, hashLesson, loadCompiledRules, parseCompilerResponse, saveCompiledRules, validateRegex, } from './compiler.js';
|
|
6
|
+
// ─── hashLesson ──────────────────────────────────────
|
|
7
|
+
describe('hashLesson', () => {
|
|
8
|
+
it('returns a 16-char hex string', () => {
|
|
9
|
+
const hash = hashLesson('heading', 'body');
|
|
10
|
+
expect(hash).toMatch(/^[0-9a-f]{16}$/);
|
|
11
|
+
});
|
|
12
|
+
it('returns different hashes for different inputs', () => {
|
|
13
|
+
const h1 = hashLesson('heading1', 'body');
|
|
14
|
+
const h2 = hashLesson('heading2', 'body');
|
|
15
|
+
expect(h1).not.toBe(h2);
|
|
16
|
+
});
|
|
17
|
+
it('returns stable hashes for the same input', () => {
|
|
18
|
+
const h1 = hashLesson('heading', 'body');
|
|
19
|
+
const h2 = hashLesson('heading', 'body');
|
|
20
|
+
expect(h1).toBe(h2);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
// ─── validateRegex ───────────────────────────────────
|
|
24
|
+
describe('validateRegex', () => {
|
|
25
|
+
it('accepts a valid regex', () => {
|
|
26
|
+
expect(validateRegex('\\bfoo\\b')).toEqual({ valid: true });
|
|
27
|
+
});
|
|
28
|
+
it('accepts a simple string pattern', () => {
|
|
29
|
+
expect(validateRegex('console.log')).toEqual({ valid: true });
|
|
30
|
+
});
|
|
31
|
+
it('accepts a complex but safe pattern', () => {
|
|
32
|
+
// Anchored API key format — complex but not vulnerable
|
|
33
|
+
expect(validateRegex('^[A-Za-z0-9]{32,}$')).toEqual({ valid: true });
|
|
34
|
+
});
|
|
35
|
+
it('rejects an invalid regex', () => {
|
|
36
|
+
const result = validateRegex('[invalid');
|
|
37
|
+
expect(result.valid).toBe(false);
|
|
38
|
+
expect(result.reason).toBe('invalid syntax');
|
|
39
|
+
});
|
|
40
|
+
it('rejects unbalanced parentheses', () => {
|
|
41
|
+
const result = validateRegex('(unclosed');
|
|
42
|
+
expect(result.valid).toBe(false);
|
|
43
|
+
expect(result.reason).toBe('invalid syntax');
|
|
44
|
+
});
|
|
45
|
+
it('rejects ReDoS pattern: nested quantifiers (a+)+', () => {
|
|
46
|
+
const result = validateRegex('(a+)+$');
|
|
47
|
+
expect(result.valid).toBe(false);
|
|
48
|
+
expect(result.reason).toBe('ReDoS vulnerability detected');
|
|
49
|
+
});
|
|
50
|
+
it('rejects ReDoS pattern: nested character class quantifiers ([a-zA-Z]+)*', () => {
|
|
51
|
+
const result = validateRegex('([a-zA-Z]+)*');
|
|
52
|
+
expect(result.valid).toBe(false);
|
|
53
|
+
expect(result.reason).toBe('ReDoS vulnerability detected');
|
|
54
|
+
});
|
|
55
|
+
it('rejects ReDoS pattern: nested repetition (.*a){10}', () => {
|
|
56
|
+
const result = validateRegex('(.*a){10}');
|
|
57
|
+
expect(result.valid).toBe(false);
|
|
58
|
+
expect(result.reason).toBe('ReDoS vulnerability detected');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
// ─── extractAddedLines ──────────────────────────────
|
|
62
|
+
describe('extractAddedLines', () => {
|
|
63
|
+
it('extracts added lines from a unified diff', () => {
|
|
64
|
+
const diff = `diff --git a/src/foo.ts b/src/foo.ts
|
|
65
|
+
index abc1234..def5678 100644
|
|
66
|
+
--- a/src/foo.ts
|
|
67
|
+
+++ b/src/foo.ts
|
|
68
|
+
@@ -1,3 +1,4 @@
|
|
69
|
+
const a = 1;
|
|
70
|
+
-const b = 2;
|
|
71
|
+
+const b = 3;
|
|
72
|
+
+const c = 4;
|
|
73
|
+
const d = 5;
|
|
74
|
+
`;
|
|
75
|
+
const additions = extractAddedLines(diff);
|
|
76
|
+
expect(additions).toHaveLength(2);
|
|
77
|
+
expect(additions[0]).toEqual({ file: 'src/foo.ts', line: 'const b = 3;', lineNumber: 2 });
|
|
78
|
+
expect(additions[1]).toEqual({ file: 'src/foo.ts', line: 'const c = 4;', lineNumber: 3 });
|
|
79
|
+
});
|
|
80
|
+
it('handles multiple files', () => {
|
|
81
|
+
const diff = `diff --git a/a.ts b/a.ts
|
|
82
|
+
--- a/a.ts
|
|
83
|
+
+++ b/a.ts
|
|
84
|
+
@@ -1,2 +1,3 @@
|
|
85
|
+
line1
|
|
86
|
+
+added in a
|
|
87
|
+
line2
|
|
88
|
+
diff --git a/b.ts b/b.ts
|
|
89
|
+
--- a/b.ts
|
|
90
|
+
+++ b/b.ts
|
|
91
|
+
@@ -1,2 +1,3 @@
|
|
92
|
+
line1
|
|
93
|
+
+added in b
|
|
94
|
+
line2
|
|
95
|
+
`;
|
|
96
|
+
const additions = extractAddedLines(diff);
|
|
97
|
+
expect(additions).toHaveLength(2);
|
|
98
|
+
expect(additions[0].file).toBe('a.ts');
|
|
99
|
+
expect(additions[1].file).toBe('b.ts');
|
|
100
|
+
});
|
|
101
|
+
it('returns empty array for empty diff', () => {
|
|
102
|
+
expect(extractAddedLines('')).toEqual([]);
|
|
103
|
+
});
|
|
104
|
+
it('handles quoted filenames with spaces', () => {
|
|
105
|
+
const diff = `diff --git "a/path with spaces/file.ts" "b/path with spaces/file.ts"
|
|
106
|
+
--- "a/path with spaces/file.ts"
|
|
107
|
+
+++ "b/path with spaces/file.ts"
|
|
108
|
+
@@ -1,2 +1,3 @@
|
|
109
|
+
line1
|
|
110
|
+
+added line
|
|
111
|
+
line2
|
|
112
|
+
`;
|
|
113
|
+
const additions = extractAddedLines(diff);
|
|
114
|
+
expect(additions).toHaveLength(1);
|
|
115
|
+
expect(additions[0].file).toBe('path with spaces/file.ts');
|
|
116
|
+
});
|
|
117
|
+
it('returns empty array for deletion-only diff', () => {
|
|
118
|
+
const diff = `diff --git a/foo.ts b/foo.ts
|
|
119
|
+
--- a/foo.ts
|
|
120
|
+
+++ b/foo.ts
|
|
121
|
+
@@ -1,3 +1,2 @@
|
|
122
|
+
line1
|
|
123
|
+
-removed
|
|
124
|
+
line2
|
|
125
|
+
`;
|
|
126
|
+
expect(extractAddedLines(diff)).toEqual([]);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
// ─── applyRules ──────────────────────────────────────
|
|
130
|
+
describe('applyRules', () => {
|
|
131
|
+
const makeRule = (pattern, message) => ({
|
|
132
|
+
lessonHash: 'abc123',
|
|
133
|
+
lessonHeading: 'Test rule',
|
|
134
|
+
pattern,
|
|
135
|
+
message,
|
|
136
|
+
engine: 'regex',
|
|
137
|
+
compiledAt: new Date().toISOString(),
|
|
138
|
+
});
|
|
139
|
+
const diff = `diff --git a/src/app.ts b/src/app.ts
|
|
140
|
+
--- a/src/app.ts
|
|
141
|
+
+++ b/src/app.ts
|
|
142
|
+
@@ -1,3 +1,5 @@
|
|
143
|
+
import { foo } from './foo';
|
|
144
|
+
+import { error } from './errors';
|
|
145
|
+
+const result = npm.install('package');
|
|
146
|
+
export default foo;
|
|
147
|
+
`;
|
|
148
|
+
it('detects a simple pattern violation', () => {
|
|
149
|
+
const rules = [makeRule('\\bnpm\\.install\\b', 'Do not call npm.install directly')];
|
|
150
|
+
const violations = applyRules(rules, diff);
|
|
151
|
+
expect(violations).toHaveLength(1);
|
|
152
|
+
expect(violations[0].rule.message).toBe('Do not call npm.install directly');
|
|
153
|
+
expect(violations[0].file).toBe('src/app.ts');
|
|
154
|
+
});
|
|
155
|
+
it('returns no violations when patterns do not match', () => {
|
|
156
|
+
const rules = [makeRule('\\byarn\\b', 'Do not use yarn')];
|
|
157
|
+
const violations = applyRules(rules, diff);
|
|
158
|
+
expect(violations).toHaveLength(0);
|
|
159
|
+
});
|
|
160
|
+
it('applies multiple rules', () => {
|
|
161
|
+
const rules = [
|
|
162
|
+
makeRule('\\bnpm\\b', 'Do not use npm'),
|
|
163
|
+
makeRule('\\berror\\b', 'Use err, not error'),
|
|
164
|
+
];
|
|
165
|
+
const violations = applyRules(rules, diff);
|
|
166
|
+
expect(violations).toHaveLength(2);
|
|
167
|
+
});
|
|
168
|
+
it('skips rules with invalid patterns', () => {
|
|
169
|
+
const rules = [makeRule('[invalid', 'Bad pattern')];
|
|
170
|
+
const violations = applyRules(rules, diff);
|
|
171
|
+
expect(violations).toHaveLength(0);
|
|
172
|
+
});
|
|
173
|
+
it('returns empty for empty diff', () => {
|
|
174
|
+
const rules = [makeRule('anything', 'test')];
|
|
175
|
+
expect(applyRules(rules, '')).toEqual([]);
|
|
176
|
+
});
|
|
177
|
+
it('returns empty for empty rules', () => {
|
|
178
|
+
expect(applyRules([], diff)).toEqual([]);
|
|
179
|
+
});
|
|
180
|
+
it('excludes files listed in excludeFiles', () => {
|
|
181
|
+
const rules = [makeRule('\\bnpm\\.install\\b', 'Do not call npm.install directly')];
|
|
182
|
+
const violations = applyRules(rules, diff, ['src/app.ts']);
|
|
183
|
+
expect(violations).toHaveLength(0);
|
|
184
|
+
});
|
|
185
|
+
it('still detects violations in non-excluded files', () => {
|
|
186
|
+
const rules = [makeRule('\\bnpm\\.install\\b', 'Do not call npm.install directly')];
|
|
187
|
+
const violations = applyRules(rules, diff, ['other-file.ts']);
|
|
188
|
+
expect(violations).toHaveLength(1);
|
|
189
|
+
});
|
|
190
|
+
// ─── fileGlobs scoping ─────────────────────────────
|
|
191
|
+
// Build test data from array join to avoid embedded diff headers
|
|
192
|
+
// (+++, ---) being parsed as real file boundaries by the shield.
|
|
193
|
+
const multiFileDiff = [
|
|
194
|
+
'diff --git a/deploy.sh b/deploy.sh',
|
|
195
|
+
'--- a/deploy.sh',
|
|
196
|
+
'+++ b/deploy.sh',
|
|
197
|
+
'@@ -1,2 +1,3 @@',
|
|
198
|
+
' #!/bin/bash',
|
|
199
|
+
'+echo $UNQUOTED_VAR',
|
|
200
|
+
' exit 0',
|
|
201
|
+
'diff --git a/src/utils.ts b/src/utils.ts',
|
|
202
|
+
'--- a/src/utils.ts',
|
|
203
|
+
'+++ b/src/utils.ts',
|
|
204
|
+
'@@ -1,2 +1,3 @@',
|
|
205
|
+
' const x = 1;',
|
|
206
|
+
"+const msg = $name + ' hello';",
|
|
207
|
+
' export default x;',
|
|
208
|
+
].join('\n');
|
|
209
|
+
it('applies rule to all files when fileGlobs is absent', () => {
|
|
210
|
+
const rules = [makeRule('\\$\\w+', 'Found a dollar-sign variable')];
|
|
211
|
+
const violations = applyRules(rules, multiFileDiff);
|
|
212
|
+
expect(violations).toHaveLength(2); // matches in both .sh and .ts
|
|
213
|
+
});
|
|
214
|
+
it('restricts rule to matching file types via fileGlobs', () => {
|
|
215
|
+
const rules = [
|
|
216
|
+
{
|
|
217
|
+
...makeRule('\\$\\w+', 'Quote shell variables'),
|
|
218
|
+
fileGlobs: ['*.sh', '*.bash'],
|
|
219
|
+
},
|
|
220
|
+
];
|
|
221
|
+
const violations = applyRules(rules, multiFileDiff);
|
|
222
|
+
expect(violations).toHaveLength(1);
|
|
223
|
+
expect(violations[0].file).toBe('deploy.sh');
|
|
224
|
+
});
|
|
225
|
+
it('skips rule entirely when no files match fileGlobs', () => {
|
|
226
|
+
const rules = [
|
|
227
|
+
{
|
|
228
|
+
...makeRule('\\$\\w+', 'Quote shell variables'),
|
|
229
|
+
fileGlobs: ['*.py'],
|
|
230
|
+
},
|
|
231
|
+
];
|
|
232
|
+
const violations = applyRules(rules, multiFileDiff);
|
|
233
|
+
expect(violations).toHaveLength(0);
|
|
234
|
+
});
|
|
235
|
+
it('handles **/*.ext glob pattern', () => {
|
|
236
|
+
const rules = [
|
|
237
|
+
{
|
|
238
|
+
...makeRule('\\$\\w+', 'Found dollar variable'),
|
|
239
|
+
fileGlobs: ['**/*.ts'],
|
|
240
|
+
},
|
|
241
|
+
];
|
|
242
|
+
const violations = applyRules(rules, multiFileDiff);
|
|
243
|
+
expect(violations).toHaveLength(1);
|
|
244
|
+
expect(violations[0].file).toBe('src/utils.ts');
|
|
245
|
+
});
|
|
246
|
+
it('applies rule when fileGlobs is empty array (treated as no restriction)', () => {
|
|
247
|
+
const rules = [
|
|
248
|
+
{
|
|
249
|
+
...makeRule('\\$\\w+', 'Found dollar variable'),
|
|
250
|
+
fileGlobs: [],
|
|
251
|
+
},
|
|
252
|
+
];
|
|
253
|
+
const violations = applyRules(rules, multiFileDiff);
|
|
254
|
+
expect(violations).toHaveLength(2);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
// ─── loadCompiledRules / saveCompiledRules ───────────
|
|
258
|
+
describe('compiled rules file I/O', () => {
|
|
259
|
+
let tmpDir;
|
|
260
|
+
beforeEach(() => {
|
|
261
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-compiler-'));
|
|
262
|
+
});
|
|
263
|
+
afterEach(() => {
|
|
264
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
265
|
+
});
|
|
266
|
+
it('round-trips rules through save and load', () => {
|
|
267
|
+
const rulesPath = path.join(tmpDir, 'compiled-rules.json');
|
|
268
|
+
const rules = [
|
|
269
|
+
{
|
|
270
|
+
lessonHash: 'abc123def456',
|
|
271
|
+
lessonHeading: 'Use err not error',
|
|
272
|
+
pattern: '\\berror\\b',
|
|
273
|
+
message: 'Use err instead of error in catch blocks',
|
|
274
|
+
engine: 'regex',
|
|
275
|
+
compiledAt: '2026-03-08T12:00:00Z',
|
|
276
|
+
},
|
|
277
|
+
];
|
|
278
|
+
saveCompiledRules(rulesPath, rules);
|
|
279
|
+
const loaded = loadCompiledRules(rulesPath);
|
|
280
|
+
expect(loaded).toEqual(rules);
|
|
281
|
+
});
|
|
282
|
+
it('returns empty array for missing file', () => {
|
|
283
|
+
const loaded = loadCompiledRules(path.join(tmpDir, 'nonexistent.json'));
|
|
284
|
+
expect(loaded).toEqual([]);
|
|
285
|
+
});
|
|
286
|
+
it('returns empty array for invalid JSON', () => {
|
|
287
|
+
const rulesPath = path.join(tmpDir, 'bad.json');
|
|
288
|
+
fs.writeFileSync(rulesPath, 'not valid json');
|
|
289
|
+
expect(loadCompiledRules(rulesPath)).toEqual([]);
|
|
290
|
+
});
|
|
291
|
+
it('returns empty array for wrong schema', () => {
|
|
292
|
+
const rulesPath = path.join(tmpDir, 'wrong.json');
|
|
293
|
+
fs.writeFileSync(rulesPath, JSON.stringify({ version: 99, rules: [] }));
|
|
294
|
+
expect(loadCompiledRules(rulesPath)).toEqual([]);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
// ─── parseCompilerResponse ──────────────────────────
|
|
298
|
+
describe('parseCompilerResponse', () => {
|
|
299
|
+
it('parses a valid compilable response', () => {
|
|
300
|
+
const response = JSON.stringify({
|
|
301
|
+
compilable: true,
|
|
302
|
+
pattern: '\\bnpm\\b',
|
|
303
|
+
message: 'Use pnpm instead of npm',
|
|
304
|
+
});
|
|
305
|
+
const result = parseCompilerResponse(response);
|
|
306
|
+
expect(result).toEqual({
|
|
307
|
+
compilable: true,
|
|
308
|
+
pattern: '\\bnpm\\b',
|
|
309
|
+
message: 'Use pnpm instead of npm',
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
it('parses a non-compilable response', () => {
|
|
313
|
+
const response = JSON.stringify({ compilable: false });
|
|
314
|
+
const result = parseCompilerResponse(response);
|
|
315
|
+
expect(result).toEqual({ compilable: false });
|
|
316
|
+
});
|
|
317
|
+
it('extracts JSON from a code fence', () => {
|
|
318
|
+
const response = `Here is the compiled rule:
|
|
319
|
+
\`\`\`json
|
|
320
|
+
{"compilable": true, "pattern": "console\\\\.log", "message": "Remove debug logging"}
|
|
321
|
+
\`\`\``;
|
|
322
|
+
const result = parseCompilerResponse(response);
|
|
323
|
+
expect(result).not.toBeNull();
|
|
324
|
+
expect(result.compilable).toBe(true);
|
|
325
|
+
expect(result.pattern).toBe('console\\.log');
|
|
326
|
+
});
|
|
327
|
+
it('returns null for completely invalid output', () => {
|
|
328
|
+
expect(parseCompilerResponse('I cannot compile this lesson.')).toBeNull();
|
|
329
|
+
});
|
|
330
|
+
it('returns null for JSON with wrong schema', () => {
|
|
331
|
+
const response = JSON.stringify({ foo: 'bar' });
|
|
332
|
+
expect(parseCompilerResponse(response)).toBeNull();
|
|
333
|
+
});
|
|
334
|
+
it('parses a response with fileGlobs', () => {
|
|
335
|
+
const response = JSON.stringify({
|
|
336
|
+
compilable: true,
|
|
337
|
+
pattern: '\\$[a-zA-Z_]+',
|
|
338
|
+
message: 'Quote shell variables',
|
|
339
|
+
fileGlobs: ['*.sh', '*.bash', '*.yml'],
|
|
340
|
+
});
|
|
341
|
+
const result = parseCompilerResponse(response);
|
|
342
|
+
expect(result).toEqual({
|
|
343
|
+
compilable: true,
|
|
344
|
+
pattern: '\\$[a-zA-Z_]+',
|
|
345
|
+
message: 'Quote shell variables',
|
|
346
|
+
fileGlobs: ['*.sh', '*.bash', '*.yml'],
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
//# sourceMappingURL=compiler.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.test.js","sourceRoot":"","sources":["../src/compiler.test.ts"],"names":[],"mappings":"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"}
|