@rhost/testkit 1.4.1 → 1.5.1
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/cli/index.js +15 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +107 -19
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/lint.d.ts +2 -0
- package/dist/cli/lint.d.ts.map +1 -0
- package/dist/cli/lint.js +163 -0
- package/dist/cli/lint.js.map +1 -0
- package/dist/cli/mush-format.d.ts +2 -0
- package/dist/cli/mush-format.d.ts.map +1 -0
- package/dist/cli/mush-format.js +232 -0
- package/dist/cli/mush-format.js.map +1 -0
- package/dist/client.d.ts +43 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +78 -5
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/offline/document.d.ts +8 -0
- package/dist/offline/document.d.ts.map +1 -0
- package/dist/offline/document.js +124 -0
- package/dist/offline/document.js.map +1 -0
- package/dist/offline/expect.d.ts +27 -0
- package/dist/offline/expect.d.ts.map +1 -0
- package/dist/offline/expect.js +90 -0
- package/dist/offline/expect.js.map +1 -0
- package/dist/offline/index.d.ts +5 -0
- package/dist/offline/index.d.ts.map +1 -0
- package/dist/offline/index.js +14 -0
- package/dist/offline/index.js.map +1 -0
- package/dist/offline/mock-client.d.ts +19 -0
- package/dist/offline/mock-client.d.ts.map +1 -0
- package/dist/offline/mock-client.js +36 -0
- package/dist/offline/mock-client.js.map +1 -0
- package/dist/offline/mock-world.d.ts +30 -0
- package/dist/offline/mock-world.d.ts.map +1 -0
- package/dist/offline/mock-world.js +64 -0
- package/dist/offline/mock-world.js.map +1 -0
- package/dist/offline/reduced-expect.d.ts +38 -0
- package/dist/offline/reduced-expect.d.ts.map +1 -0
- package/dist/offline/reduced-expect.js +61 -0
- package/dist/offline/reduced-expect.js.map +1 -0
- package/dist/offline/runner.d.ts +13 -0
- package/dist/offline/runner.d.ts.map +1 -0
- package/dist/offline/runner.js +174 -0
- package/dist/offline/runner.js.map +1 -0
- package/dist/offline/types.d.ts +78 -0
- package/dist/offline/types.d.ts.map +1 -0
- package/dist/offline/types.js +3 -0
- package/dist/offline/types.js.map +1 -0
- package/dist/reporter.d.ts +3 -1
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +20 -0
- package/dist/reporter.js.map +1 -1
- package/dist/runner.d.ts +39 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +82 -15
- package/dist/runner.js.map +1 -1
- package/dist/validator/mush-format.d.ts +43 -0
- package/dist/validator/mush-format.d.ts.map +1 -0
- package/dist/validator/mush-format.js +484 -0
- package/dist/validator/mush-format.js.map +1 -0
- package/dist/validator/mush-lint.d.ts +22 -0
- package/dist/validator/mush-lint.d.ts.map +1 -0
- package/dist/validator/mush-lint.js +590 -0
- package/dist/validator/mush-lint.js.map +1 -0
- package/package.json +10 -2
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// mush-lint — static analysis for RhostMUSH softcode files
|
|
4
|
+
//
|
|
5
|
+
// Checks implemented:
|
|
6
|
+
// Safety S1 Bare user input in @pemit/@emit/think
|
|
7
|
+
// S2 @create without @lock
|
|
8
|
+
// S3 execscript() with user input
|
|
9
|
+
// S4 User input in @switch case label
|
|
10
|
+
// S5 Hardcoded dbref in HELP* attrs
|
|
11
|
+
// Complete C1 FN_* accepts %0 without input guard
|
|
12
|
+
// C2 CMD_* with no HELP* entry
|
|
13
|
+
// C3 Installer missing header/footer markers
|
|
14
|
+
// C4 Installer missing UNINSTALL section
|
|
15
|
+
// Format F1 Line > 78 chars in help.txt or @@ comments
|
|
16
|
+
// F2 Separator line not 78 chars
|
|
17
|
+
// F3 Wrong attribute order (Config→UDFs→Commands→Help)
|
|
18
|
+
// F4 Comment style mismatch (// or ## instead of @@)
|
|
19
|
+
// Length L1 Attribute body > 7500 chars
|
|
20
|
+
// Style I1 Attribute name not uppercase
|
|
21
|
+
// I2 No Version field in installer header
|
|
22
|
+
// I3 No Requires field in installer header
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.lintContent = lintContent;
|
|
26
|
+
const mushcode_1 = require("@ursamu/mushcode");
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Entry point
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
/**
|
|
31
|
+
* Lint a softcode file (.mush or .installer.txt).
|
|
32
|
+
* Returns all diagnostics sorted by line number.
|
|
33
|
+
*/
|
|
34
|
+
function lintContent(content, filename = '<input>') {
|
|
35
|
+
const lines = content.split('\n');
|
|
36
|
+
const attrs = parseAttrs(lines);
|
|
37
|
+
const diags = [];
|
|
38
|
+
// File-level checks
|
|
39
|
+
checkInstallerStructure(lines, diags); // C3, C4, I2, I3
|
|
40
|
+
checkCommentStyle(lines, attrs, diags); // F4
|
|
41
|
+
checkLineLengths(lines, diags); // F1, F2
|
|
42
|
+
// Attribute-level checks
|
|
43
|
+
checkAttrOrder(attrs, diags); // F3
|
|
44
|
+
checkAttrNames(attrs, diags); // I1
|
|
45
|
+
for (const attr of attrs) {
|
|
46
|
+
checkAttrLength(attr, diags); // L1
|
|
47
|
+
if (!attr.ast)
|
|
48
|
+
continue;
|
|
49
|
+
checkBareUserInput(attr, diags); // S1
|
|
50
|
+
checkSwitchCaseLabel(attr, diags); // S4
|
|
51
|
+
checkExecscript(attr, diags); // S3
|
|
52
|
+
checkHelpDbref(attr, diags); // S5
|
|
53
|
+
checkFnGuard(attr, diags); // C1
|
|
54
|
+
}
|
|
55
|
+
checkUncreatedObjects(lines, diags); // S2
|
|
56
|
+
checkCmdHelpPairs(attrs, diags); // C2
|
|
57
|
+
diags.sort((a, b) => a.line - b.line);
|
|
58
|
+
return {
|
|
59
|
+
diagnostics: diags,
|
|
60
|
+
errors: diags.filter(d => d.severity === 'ERROR').length,
|
|
61
|
+
warnings: diags.filter(d => d.severity === 'WARN').length,
|
|
62
|
+
infos: diags.filter(d => d.severity === 'INFO').length,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// File parser — extract AttrRecords from lines
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
function parseAttrs(lines) {
|
|
69
|
+
const records = [];
|
|
70
|
+
// Collect multi-line logical attributes (indented continuation lines)
|
|
71
|
+
let current = null;
|
|
72
|
+
for (let i = 0; i < lines.length; i++) {
|
|
73
|
+
const raw = lines[i];
|
|
74
|
+
const trimmed = raw.trim();
|
|
75
|
+
// New attribute line
|
|
76
|
+
const m = trimmed.match(/^&([A-Za-z_][A-Za-z0-9_.:@-]*)\s+([^=\s][^=]*)=(.*)$/);
|
|
77
|
+
if (m) {
|
|
78
|
+
if (current)
|
|
79
|
+
records.push(finishAttr(current));
|
|
80
|
+
current = { name: m[1].toUpperCase(), rawName: m[1], object: m[2].trim(), value: m[3], line: i + 1 };
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
// Continuation: indented line after an attribute
|
|
84
|
+
if (current && raw.match(/^\s+\S/) && !trimmed.startsWith('&') && !trimmed.startsWith('@') && !trimmed.startsWith('//')) {
|
|
85
|
+
current.value += ' ' + trimmed;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
// Any other command resets continuation
|
|
89
|
+
if (current) {
|
|
90
|
+
records.push(finishAttr(current));
|
|
91
|
+
current = null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (current)
|
|
95
|
+
records.push(finishAttr(current));
|
|
96
|
+
return records;
|
|
97
|
+
}
|
|
98
|
+
function finishAttr(r) {
|
|
99
|
+
const value = r.value.trim();
|
|
100
|
+
let ast = null;
|
|
101
|
+
if (value) {
|
|
102
|
+
try {
|
|
103
|
+
ast = (0, mushcode_1.parse)(value);
|
|
104
|
+
}
|
|
105
|
+
catch { /* unparseable */ }
|
|
106
|
+
}
|
|
107
|
+
return { ...r, value, ast };
|
|
108
|
+
}
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// S1 — Bare user input in @pemit / @emit / @remit / @oemit / think
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
const OUTPUT_CMDS = new Set(['pemit', 'emit', 'remit', 'oemit', 'zemit', 'wall', 'notify']);
|
|
113
|
+
// Any function call is treated as "handling" its arguments for S1 purposes.
|
|
114
|
+
// Only flag substitutions in the raw text flow (not inside any function call).
|
|
115
|
+
// Substitution codes that represent user input
|
|
116
|
+
const USER_INPUT_RE = /^[0-9]$|^v[a-z]$/;
|
|
117
|
+
function checkBareUserInput(attr, diags) {
|
|
118
|
+
if (!attr.ast)
|
|
119
|
+
return;
|
|
120
|
+
walkAtCmd(attr.ast, (cmd) => {
|
|
121
|
+
if (!OUTPUT_CMDS.has(cmd.name.toLowerCase()))
|
|
122
|
+
return;
|
|
123
|
+
const bare = findBareUserSubs(cmd.value);
|
|
124
|
+
for (const sub of bare) {
|
|
125
|
+
diags.push({
|
|
126
|
+
code: 'S1',
|
|
127
|
+
severity: 'ERROR',
|
|
128
|
+
line: attr.line,
|
|
129
|
+
attr: attr.name,
|
|
130
|
+
message: `Bare %${sub.code} in @${cmd.name} — wrap with secure(%${sub.code}) or stripchars(...)`,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/** Walk AST and call cb for every AtCommand node (including those inside DollarPattern/BracedString) */
|
|
136
|
+
function walkAtCmd(node, cb) {
|
|
137
|
+
if (!node || typeof node !== 'object')
|
|
138
|
+
return;
|
|
139
|
+
switch (node.type) {
|
|
140
|
+
case 'AtCommand':
|
|
141
|
+
cb(node);
|
|
142
|
+
walkAtCmd(node.value, cb);
|
|
143
|
+
break;
|
|
144
|
+
case 'DollarPattern':
|
|
145
|
+
walkAtCmd(node.action, cb);
|
|
146
|
+
break;
|
|
147
|
+
case 'CommandList':
|
|
148
|
+
for (const c of node.commands)
|
|
149
|
+
walkAtCmd(c, cb);
|
|
150
|
+
break;
|
|
151
|
+
case 'UserCommand':
|
|
152
|
+
for (const p of node.parts)
|
|
153
|
+
walkAtCmd(p, cb);
|
|
154
|
+
break;
|
|
155
|
+
case 'BracedString':
|
|
156
|
+
// Re-parse braced content to catch nested @pemit in action bodies
|
|
157
|
+
for (const p of node.parts)
|
|
158
|
+
walkAtCmd(p, cb);
|
|
159
|
+
break;
|
|
160
|
+
case 'EvalBlock':
|
|
161
|
+
for (const p of node.parts)
|
|
162
|
+
walkAtCmd(p, cb);
|
|
163
|
+
break;
|
|
164
|
+
case 'FunctionCall':
|
|
165
|
+
for (const arg of node.args)
|
|
166
|
+
walkAtCmd(arg, cb);
|
|
167
|
+
break;
|
|
168
|
+
case 'Arg':
|
|
169
|
+
for (const p of node.parts)
|
|
170
|
+
walkAtCmd(p, cb);
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Find user-input substitutions (%0-9, %va-vz) that appear in the "text flow"
|
|
176
|
+
* of a node — i.e. NOT inside any protective function call.
|
|
177
|
+
* We stop recursing into FunctionCall nodes whose name is in SAFE_FUNS;
|
|
178
|
+
* other function calls are treated as pass-through.
|
|
179
|
+
*/
|
|
180
|
+
function findBareUserSubs(node) {
|
|
181
|
+
const found = [];
|
|
182
|
+
collectBareUserSubs(node, false /* insideFn */, found);
|
|
183
|
+
return found;
|
|
184
|
+
}
|
|
185
|
+
function collectBareUserSubs(node, insideFn, out) {
|
|
186
|
+
if (!node || typeof node !== 'object')
|
|
187
|
+
return;
|
|
188
|
+
switch (node.type) {
|
|
189
|
+
case 'Substitution':
|
|
190
|
+
// Only flag if NOT inside any function call at any depth
|
|
191
|
+
if (!insideFn && USER_INPUT_RE.test(node.code))
|
|
192
|
+
out.push(node);
|
|
193
|
+
break;
|
|
194
|
+
case 'FunctionCall':
|
|
195
|
+
// All function calls protect their arguments — don't flag inside them
|
|
196
|
+
return;
|
|
197
|
+
case 'Arg':
|
|
198
|
+
for (const p of node.parts)
|
|
199
|
+
collectBareUserSubs(p, insideFn, out);
|
|
200
|
+
break;
|
|
201
|
+
case 'EvalBlock':
|
|
202
|
+
case 'UserCommand':
|
|
203
|
+
case 'BracedString':
|
|
204
|
+
case 'Text': {
|
|
205
|
+
const parts = node.parts;
|
|
206
|
+
for (const p of parts)
|
|
207
|
+
collectBareUserSubs(p, insideFn, out);
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
case 'CommandList':
|
|
211
|
+
for (const c of node.commands)
|
|
212
|
+
collectBareUserSubs(c, insideFn, out);
|
|
213
|
+
break;
|
|
214
|
+
case 'AtCommand':
|
|
215
|
+
// Only check the value, not object (which is typically %#)
|
|
216
|
+
collectBareUserSubs(node.value, insideFn, out);
|
|
217
|
+
break;
|
|
218
|
+
case 'DollarPattern':
|
|
219
|
+
collectBareUserSubs(node.action, insideFn, out);
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
// S2 — @create without @lock
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
function checkUncreatedObjects(lines, diags) {
|
|
227
|
+
// Track @create <name> and watch for @lock <name>=
|
|
228
|
+
const created = new Map(); // name → line
|
|
229
|
+
const locked = new Set();
|
|
230
|
+
for (let i = 0; i < lines.length; i++) {
|
|
231
|
+
const line = lines[i].trim();
|
|
232
|
+
const createM = line.match(/^@create\s+(.+?)(\s*=.*)?$/i);
|
|
233
|
+
if (createM) {
|
|
234
|
+
const name = createM[1].trim().replace(/\s+<[^>]+>$/, ''); // strip <tag>
|
|
235
|
+
created.set(name.toLowerCase(), i + 1);
|
|
236
|
+
}
|
|
237
|
+
const lockM = line.match(/^@lock\s+(.+?)=/i);
|
|
238
|
+
if (lockM) {
|
|
239
|
+
locked.add(lockM[1].trim().toLowerCase());
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
for (const [name, lineNo] of created) {
|
|
243
|
+
if (!locked.has(name)) {
|
|
244
|
+
diags.push({
|
|
245
|
+
code: 'S2',
|
|
246
|
+
severity: 'ERROR',
|
|
247
|
+
line: lineNo,
|
|
248
|
+
message: `@create "${name}" has no @lock — all system objects must be locked`,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
// S3 — execscript() with user input
|
|
255
|
+
// ---------------------------------------------------------------------------
|
|
256
|
+
function checkExecscript(attr, diags) {
|
|
257
|
+
// Walk AST for FunctionCall named execscript and check args 0 and 1
|
|
258
|
+
walkFunctionCalls(attr.ast, 'execscript', (node) => {
|
|
259
|
+
const args = node.args;
|
|
260
|
+
// Check first two args for user substitutions
|
|
261
|
+
for (let i = 0; i < Math.min(args.length, 2); i++) {
|
|
262
|
+
const subs = findAllUserSubs(args[i]);
|
|
263
|
+
if (subs.length > 0) {
|
|
264
|
+
diags.push({
|
|
265
|
+
code: 'S3',
|
|
266
|
+
severity: 'ERROR',
|
|
267
|
+
line: attr.line,
|
|
268
|
+
attr: attr.name,
|
|
269
|
+
message: `execscript() arg ${i + 1} contains %${subs[0].code} — never pass user input to execscript`,
|
|
270
|
+
});
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
function walkFunctionCalls(node, name, cb) {
|
|
277
|
+
if (!node || typeof node !== 'object')
|
|
278
|
+
return;
|
|
279
|
+
if (node.type === 'FunctionCall' && node.name.toLowerCase() === name.toLowerCase()) {
|
|
280
|
+
cb(node);
|
|
281
|
+
}
|
|
282
|
+
const children = getChildren(node);
|
|
283
|
+
for (const c of children)
|
|
284
|
+
walkFunctionCalls(c, name, cb);
|
|
285
|
+
}
|
|
286
|
+
function getChildren(node) {
|
|
287
|
+
switch (node.type) {
|
|
288
|
+
case 'UserCommand': return node.parts;
|
|
289
|
+
case 'CommandList': return node.commands;
|
|
290
|
+
case 'AtCommand': return [node.object, node.value];
|
|
291
|
+
case 'DollarPattern': return [node.action];
|
|
292
|
+
case 'FunctionCall': return node.args;
|
|
293
|
+
case 'Arg': return node.parts;
|
|
294
|
+
case 'EvalBlock': return node.parts;
|
|
295
|
+
case 'BracedString': return node.parts;
|
|
296
|
+
case 'Text': return node.parts;
|
|
297
|
+
default: return [];
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/** Find ALL user substitution nodes (including those inside function calls) */
|
|
301
|
+
function findAllUserSubs(node) {
|
|
302
|
+
const found = [];
|
|
303
|
+
collectAllUserSubs(node, found);
|
|
304
|
+
return found;
|
|
305
|
+
}
|
|
306
|
+
function collectAllUserSubs(node, out) {
|
|
307
|
+
if (!node || typeof node !== 'object')
|
|
308
|
+
return;
|
|
309
|
+
if (node.type === 'Substitution' && USER_INPUT_RE.test(node.code)) {
|
|
310
|
+
out.push(node);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
for (const c of getChildren(node))
|
|
314
|
+
collectAllUserSubs(c, out);
|
|
315
|
+
}
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
// S4 — User input in @switch case label
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
const SWITCH_CMDS = new Set(['switch', 'switchall']);
|
|
320
|
+
function checkSwitchCaseLabel(attr, diags) {
|
|
321
|
+
if (!attr.ast)
|
|
322
|
+
return;
|
|
323
|
+
walkAtCmd(attr.ast, (cmd) => {
|
|
324
|
+
if (!SWITCH_CMDS.has(cmd.name.toLowerCase()))
|
|
325
|
+
return;
|
|
326
|
+
// The case list is in cmd.value (a UserCommand or CommandList)
|
|
327
|
+
// Split into label and body segments: bodies are BracedStrings
|
|
328
|
+
const valueParts = flatParts(cmd.value);
|
|
329
|
+
let inLabel = true;
|
|
330
|
+
for (const part of valueParts) {
|
|
331
|
+
if (part.type === 'BracedString') {
|
|
332
|
+
inLabel = false;
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
if (part.type === 'Literal' && part.value === ',') {
|
|
336
|
+
inLabel = true;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if (inLabel) {
|
|
340
|
+
const subs = findAllUserSubs(part);
|
|
341
|
+
if (subs.length > 0) {
|
|
342
|
+
diags.push({
|
|
343
|
+
code: 'S4',
|
|
344
|
+
severity: 'ERROR',
|
|
345
|
+
line: attr.line,
|
|
346
|
+
attr: attr.name,
|
|
347
|
+
message: `User input (%${subs[0].code}) in @switch case label — case labels are evaluated, this is injectable`,
|
|
348
|
+
});
|
|
349
|
+
return; // one diag per @switch is enough
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
function flatParts(node) {
|
|
356
|
+
if (node.type === 'UserCommand')
|
|
357
|
+
return node.parts;
|
|
358
|
+
if (node.type === 'CommandList')
|
|
359
|
+
return node.commands;
|
|
360
|
+
return [node];
|
|
361
|
+
}
|
|
362
|
+
// ---------------------------------------------------------------------------
|
|
363
|
+
// S5 — Hardcoded dbref in HELP* attributes
|
|
364
|
+
// ---------------------------------------------------------------------------
|
|
365
|
+
function checkHelpDbref(attr, diags) {
|
|
366
|
+
if (!attr.name.startsWith('HELP'))
|
|
367
|
+
return;
|
|
368
|
+
if (/#\d+/.test(attr.value)) {
|
|
369
|
+
diags.push({
|
|
370
|
+
code: 'S5',
|
|
371
|
+
severity: 'ERROR',
|
|
372
|
+
line: attr.line,
|
|
373
|
+
attr: attr.name,
|
|
374
|
+
message: `Hardcoded dbref in ${attr.name} — help text must use names only`,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
// ---------------------------------------------------------------------------
|
|
379
|
+
// C1 — FN_* accepts %0 without input guard
|
|
380
|
+
// ---------------------------------------------------------------------------
|
|
381
|
+
function checkFnGuard(attr, diags) {
|
|
382
|
+
if (!attr.name.startsWith('FN_'))
|
|
383
|
+
return;
|
|
384
|
+
// Does this function use %0-%9 at all?
|
|
385
|
+
const subs = findAllUserSubs(attr.ast);
|
|
386
|
+
if (subs.length === 0)
|
|
387
|
+
return;
|
|
388
|
+
// Check for a guard: value should start with [if(not(%0,...) or [if(eq(%0,...)]
|
|
389
|
+
// In the AST, the top-level node should be a UserCommand whose first non-whitespace
|
|
390
|
+
// part is an EvalBlock containing an 'if' or 'switch' FunctionCall.
|
|
391
|
+
if (hasInputGuard(attr.ast))
|
|
392
|
+
return;
|
|
393
|
+
diags.push({
|
|
394
|
+
code: 'C1',
|
|
395
|
+
severity: 'ERROR',
|
|
396
|
+
line: attr.line,
|
|
397
|
+
attr: attr.name,
|
|
398
|
+
message: `${attr.name} accepts %0 but has no input guard — add [if(not(%0),#-1 MISSING ARG,...)]`,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
function hasInputGuard(node) {
|
|
402
|
+
if (node.type !== 'UserCommand')
|
|
403
|
+
return false;
|
|
404
|
+
// First significant part must be an EvalBlock
|
|
405
|
+
const firstSig = node.parts.find(p => p.type !== 'Literal' || p.value.trim() !== '');
|
|
406
|
+
if (!firstSig || firstSig.type !== 'EvalBlock')
|
|
407
|
+
return false;
|
|
408
|
+
// The EvalBlock should contain a guard function call as its only (or first) element
|
|
409
|
+
const inner = firstSig.parts[0];
|
|
410
|
+
if (!inner || inner.type !== 'FunctionCall')
|
|
411
|
+
return false;
|
|
412
|
+
const name = inner.name.toLowerCase();
|
|
413
|
+
return name === 'if' || name === 'ifelse' || name === 'switch' || name === 'when';
|
|
414
|
+
}
|
|
415
|
+
// ---------------------------------------------------------------------------
|
|
416
|
+
// C2 — CMD_* with no HELP* entry
|
|
417
|
+
// ---------------------------------------------------------------------------
|
|
418
|
+
function checkCmdHelpPairs(attrs, diags) {
|
|
419
|
+
const cmds = attrs.filter(a => a.name.startsWith('CMD_'));
|
|
420
|
+
const helps = new Set(attrs.filter(a => a.name.startsWith('HELP')).map(a => a.name));
|
|
421
|
+
for (const cmd of cmds) {
|
|
422
|
+
// Strip CMD_ prefix, look for HELP_<suffix> or HELP<suffix>
|
|
423
|
+
const suffix = cmd.name.slice(4); // e.g. FINGER from CMD_FINGER
|
|
424
|
+
const hasHelp = helps.has(`HELP_${suffix}`) || helps.has(`HELP${suffix}`);
|
|
425
|
+
if (!hasHelp) {
|
|
426
|
+
diags.push({
|
|
427
|
+
code: 'C2',
|
|
428
|
+
severity: 'ERROR',
|
|
429
|
+
line: cmd.line,
|
|
430
|
+
attr: cmd.name,
|
|
431
|
+
message: `${cmd.name} has no HELP entry — every command needs help text`,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
// ---------------------------------------------------------------------------
|
|
437
|
+
// C3 — Installer missing header/footer markers
|
|
438
|
+
// C4 — Installer missing UNINSTALL section
|
|
439
|
+
// ---------------------------------------------------------------------------
|
|
440
|
+
function checkInstallerStructure(lines, diags) {
|
|
441
|
+
const text = lines.join('\n');
|
|
442
|
+
// Only run structural checks on installer files (look for @@ markers)
|
|
443
|
+
const isInstaller = lines.some(l => l.startsWith('@@'));
|
|
444
|
+
if (!isInstaller)
|
|
445
|
+
return;
|
|
446
|
+
if (!/@@ Mushcode Installer for:/i.test(text)) {
|
|
447
|
+
diags.push({ code: 'C3', severity: 'ERROR', line: 1, message: 'Missing "@@ Mushcode Installer for:" header line' });
|
|
448
|
+
}
|
|
449
|
+
if (!/@@ \[END OF FILE\]/i.test(text)) {
|
|
450
|
+
diags.push({ code: 'C3', severity: 'ERROR', line: lines.length, message: 'Missing "@@ [END OF FILE]" terminal marker' });
|
|
451
|
+
}
|
|
452
|
+
if (!/@@ ---\[ UNINSTALL \]---/i.test(text)) {
|
|
453
|
+
diags.push({ code: 'C4', severity: 'ERROR', line: lines.length, message: 'No UNINSTALL section — add @@ ---[ UNINSTALL ]--- block' });
|
|
454
|
+
}
|
|
455
|
+
// I2, I3 — header field presence
|
|
456
|
+
if (!/@@ Version:/i.test(text)) {
|
|
457
|
+
diags.push({ code: 'I2', severity: 'INFO', line: 1, message: 'Version field missing from installer header' });
|
|
458
|
+
}
|
|
459
|
+
if (!/@@ Requires:/i.test(text)) {
|
|
460
|
+
diags.push({ code: 'I3', severity: 'INFO', line: 1, message: 'Requires field missing from installer header — add "None" if no prerequisites' });
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
// ---------------------------------------------------------------------------
|
|
464
|
+
// F1 — Line > 78 chars (help and @@ comment lines only)
|
|
465
|
+
// F2 — Separator line not exactly 78 chars
|
|
466
|
+
// ---------------------------------------------------------------------------
|
|
467
|
+
function checkLineLengths(lines, diags) {
|
|
468
|
+
for (let i = 0; i < lines.length; i++) {
|
|
469
|
+
const line = lines[i];
|
|
470
|
+
const lineNo = i + 1;
|
|
471
|
+
// F2 — separator lines must be exactly 78 chars
|
|
472
|
+
if (/^@@ ={3,}/.test(line) || /^@@ ---\[/.test(line)) {
|
|
473
|
+
if (line.length !== 78) {
|
|
474
|
+
diags.push({
|
|
475
|
+
code: 'F2',
|
|
476
|
+
severity: 'WARN',
|
|
477
|
+
line: lineNo,
|
|
478
|
+
message: `Separator line is ${line.length} chars — must be exactly 78`,
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
// F1 — @@ comment lines
|
|
484
|
+
if (line.startsWith('@@') && line.length > 78) {
|
|
485
|
+
diags.push({
|
|
486
|
+
code: 'F1',
|
|
487
|
+
severity: 'WARN',
|
|
488
|
+
line: lineNo,
|
|
489
|
+
message: `@@ comment line is ${line.length} chars — max is 78`,
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
// ---------------------------------------------------------------------------
|
|
495
|
+
// F3 — Wrong attribute order (Config → UDFs → Commands → Help)
|
|
496
|
+
// ---------------------------------------------------------------------------
|
|
497
|
+
const ATTR_ORDER_RANK = {
|
|
498
|
+
D_: 0, CONF_: 0, CONFIG_: 0, // config/data
|
|
499
|
+
FN_: 1, // UDFs
|
|
500
|
+
CMD_: 2, // commands
|
|
501
|
+
HELP: 3, // help (prefix match)
|
|
502
|
+
};
|
|
503
|
+
function attrRank(name) {
|
|
504
|
+
for (const [prefix, rank] of Object.entries(ATTR_ORDER_RANK)) {
|
|
505
|
+
if (name.startsWith(prefix))
|
|
506
|
+
return rank;
|
|
507
|
+
}
|
|
508
|
+
return 1; // default: treat as UDF-level
|
|
509
|
+
}
|
|
510
|
+
function checkAttrOrder(attrs, diags) {
|
|
511
|
+
// Group by object, then check order within each object
|
|
512
|
+
const byObj = new Map();
|
|
513
|
+
for (const attr of attrs) {
|
|
514
|
+
const key = attr.object.toLowerCase();
|
|
515
|
+
if (!byObj.has(key))
|
|
516
|
+
byObj.set(key, []);
|
|
517
|
+
byObj.get(key).push(attr);
|
|
518
|
+
}
|
|
519
|
+
for (const [, objAttrs] of byObj) {
|
|
520
|
+
let maxRank = -1;
|
|
521
|
+
for (const attr of objAttrs) {
|
|
522
|
+
const rank = attrRank(attr.name);
|
|
523
|
+
if (rank < maxRank) {
|
|
524
|
+
diags.push({
|
|
525
|
+
code: 'F3',
|
|
526
|
+
severity: 'WARN',
|
|
527
|
+
line: attr.line,
|
|
528
|
+
attr: attr.name,
|
|
529
|
+
message: `${attr.name} appears after a higher-priority attribute — order must be: Config, UDFs, Commands, Help`,
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
maxRank = Math.max(maxRank, rank);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
// ---------------------------------------------------------------------------
|
|
539
|
+
// F4 — Comment style: // or ## used instead of @@
|
|
540
|
+
// ---------------------------------------------------------------------------
|
|
541
|
+
function checkCommentStyle(lines, attrs, diags) {
|
|
542
|
+
// Build set of attribute line numbers so we don't flag inline comments in attr values
|
|
543
|
+
const attrLines = new Set(attrs.map(a => a.line));
|
|
544
|
+
for (let i = 0; i < lines.length; i++) {
|
|
545
|
+
const lineNo = i + 1;
|
|
546
|
+
if (attrLines.has(lineNo))
|
|
547
|
+
continue;
|
|
548
|
+
const trimmed = lines[i].trim();
|
|
549
|
+
// Standalone // comment line at the top level of an installer file
|
|
550
|
+
if (/^\/\//.test(trimmed) || /^##\s/.test(trimmed)) {
|
|
551
|
+
diags.push({
|
|
552
|
+
code: 'F4',
|
|
553
|
+
severity: 'WARN',
|
|
554
|
+
line: lineNo,
|
|
555
|
+
message: `Line ${lineNo} uses "${trimmed.slice(0, 2)}" comment style — convert to @@ in installer files`,
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
// ---------------------------------------------------------------------------
|
|
561
|
+
// L1 — Attribute body > 7500 chars
|
|
562
|
+
// ---------------------------------------------------------------------------
|
|
563
|
+
function checkAttrLength(attr, diags) {
|
|
564
|
+
if (attr.value.length > 7500) {
|
|
565
|
+
diags.push({
|
|
566
|
+
code: 'L1',
|
|
567
|
+
severity: 'WARN',
|
|
568
|
+
line: attr.line,
|
|
569
|
+
attr: attr.name,
|
|
570
|
+
message: `${attr.name} is ${attr.value.length} chars — approaching 8000-char Rhost limit, consider chunking into ${attr.name}.0, ${attr.name}.1, ...`,
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
// ---------------------------------------------------------------------------
|
|
575
|
+
// I1 — Attribute name not uppercase
|
|
576
|
+
// ---------------------------------------------------------------------------
|
|
577
|
+
function checkAttrNames(attrs, diags) {
|
|
578
|
+
for (const attr of attrs) {
|
|
579
|
+
if (attr.rawName !== attr.name) {
|
|
580
|
+
diags.push({
|
|
581
|
+
code: 'I1',
|
|
582
|
+
severity: 'INFO',
|
|
583
|
+
line: attr.line,
|
|
584
|
+
attr: attr.name,
|
|
585
|
+
message: `Attribute ${attr.rawName} should be ${attr.name} — use uppercase for all attribute names`,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
//# sourceMappingURL=mush-lint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mush-lint.js","sourceRoot":"","sources":["../../src/validator/mush-lint.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rhost/testkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "SDK for programmatically testing MUSHcode against a RhostMUSH server",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
"./validator": {
|
|
16
16
|
"require": "./dist/validator/index.js",
|
|
17
17
|
"types": "./dist/validator/index.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"./offline": {
|
|
20
|
+
"require": "./dist/offline/index.js",
|
|
21
|
+
"types": "./dist/offline/index.d.ts"
|
|
18
22
|
}
|
|
19
23
|
},
|
|
20
24
|
"files": [
|
|
@@ -70,6 +74,7 @@
|
|
|
70
74
|
],
|
|
71
75
|
"license": "MIT",
|
|
72
76
|
"dependencies": {
|
|
77
|
+
"@ursamu/mushcode": "npm:@jsr/ursamu__mushcode@^0.3.4",
|
|
73
78
|
"testcontainers": "^11.13.0"
|
|
74
79
|
},
|
|
75
80
|
"devDependencies": {
|
|
@@ -87,6 +92,9 @@
|
|
|
87
92
|
"<rootDir>/src/__tests__/**/*.test.ts"
|
|
88
93
|
],
|
|
89
94
|
"testTimeout": 15000,
|
|
90
|
-
"testPathIgnorePatterns": []
|
|
95
|
+
"testPathIgnorePatterns": [],
|
|
96
|
+
"moduleNameMapper": {
|
|
97
|
+
"^@ursamu/mushcode$": "<rootDir>/scripts/mushcode-compat.js"
|
|
98
|
+
}
|
|
91
99
|
}
|
|
92
100
|
}
|