@rhost/testkit 0.1.1 → 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.
Files changed (110) hide show
  1. package/README.md +393 -5
  2. package/ROADMAP.md +241 -0
  3. package/dist/benchmark.d.ts +44 -0
  4. package/dist/benchmark.d.ts.map +1 -0
  5. package/dist/benchmark.js +118 -0
  6. package/dist/benchmark.js.map +1 -0
  7. package/dist/cli/deploy.d.ts +2 -0
  8. package/dist/cli/deploy.d.ts.map +1 -0
  9. package/dist/cli/deploy.js +120 -0
  10. package/dist/cli/deploy.js.map +1 -0
  11. package/dist/cli/fmt.d.ts +2 -0
  12. package/dist/cli/fmt.d.ts.map +1 -0
  13. package/dist/cli/fmt.js +119 -0
  14. package/dist/cli/fmt.js.map +1 -0
  15. package/dist/cli/index.d.ts +3 -0
  16. package/dist/cli/index.d.ts.map +1 -0
  17. package/dist/cli/index.js +81 -0
  18. package/dist/cli/index.js.map +1 -0
  19. package/dist/cli/init.d.ts +2 -0
  20. package/dist/cli/init.d.ts.map +1 -0
  21. package/dist/cli/init.js +210 -0
  22. package/dist/cli/init.js.map +1 -0
  23. package/dist/cli/validate.d.ts +2 -0
  24. package/dist/cli/validate.d.ts.map +1 -0
  25. package/dist/cli/validate.js +126 -0
  26. package/dist/cli/validate.js.map +1 -0
  27. package/dist/cli/watch.d.ts +2 -0
  28. package/dist/cli/watch.d.ts.map +1 -0
  29. package/dist/cli/watch.js +136 -0
  30. package/dist/cli/watch.js.map +1 -0
  31. package/dist/client.d.ts +56 -0
  32. package/dist/client.d.ts.map +1 -1
  33. package/dist/client.js +117 -30
  34. package/dist/client.js.map +1 -1
  35. package/dist/container.d.ts.map +1 -1
  36. package/dist/container.js +1 -1
  37. package/dist/container.js.map +1 -1
  38. package/dist/deployer.d.ts +86 -0
  39. package/dist/deployer.d.ts.map +1 -0
  40. package/dist/deployer.js +154 -0
  41. package/dist/deployer.js.map +1 -0
  42. package/dist/expect.d.ts +27 -1
  43. package/dist/expect.d.ts.map +1 -1
  44. package/dist/expect.js +47 -2
  45. package/dist/expect.js.map +1 -1
  46. package/dist/index.d.ts +10 -3
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +39 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/preflight.d.ts +70 -0
  51. package/dist/preflight.d.ts.map +1 -0
  52. package/dist/preflight.js +121 -0
  53. package/dist/preflight.js.map +1 -0
  54. package/dist/reporter.d.ts +2 -0
  55. package/dist/reporter.d.ts.map +1 -1
  56. package/dist/reporter.js +24 -1
  57. package/dist/reporter.js.map +1 -1
  58. package/dist/runner.d.ts +83 -2
  59. package/dist/runner.d.ts.map +1 -1
  60. package/dist/runner.js +137 -8
  61. package/dist/runner.js.map +1 -1
  62. package/dist/snapshots.d.ts +84 -0
  63. package/dist/snapshots.d.ts.map +1 -0
  64. package/dist/snapshots.js +230 -0
  65. package/dist/snapshots.js.map +1 -0
  66. package/dist/validator/builtins.d.ts +18 -0
  67. package/dist/validator/builtins.d.ts.map +1 -0
  68. package/dist/validator/builtins.js +265 -0
  69. package/dist/validator/builtins.js.map +1 -0
  70. package/dist/validator/checker.d.ts +13 -0
  71. package/dist/validator/checker.d.ts.map +1 -0
  72. package/dist/validator/checker.js +111 -0
  73. package/dist/validator/checker.js.map +1 -0
  74. package/dist/validator/clobber.d.ts +7 -0
  75. package/dist/validator/clobber.d.ts.map +1 -0
  76. package/dist/validator/clobber.js +102 -0
  77. package/dist/validator/clobber.js.map +1 -0
  78. package/dist/validator/compat.d.ts +19 -0
  79. package/dist/validator/compat.d.ts.map +1 -0
  80. package/dist/validator/compat.js +58 -0
  81. package/dist/validator/compat.js.map +1 -0
  82. package/dist/validator/formatter.d.ts +21 -0
  83. package/dist/validator/formatter.d.ts.map +1 -0
  84. package/dist/validator/formatter.js +120 -0
  85. package/dist/validator/formatter.js.map +1 -0
  86. package/dist/validator/index.d.ts +57 -0
  87. package/dist/validator/index.d.ts.map +1 -0
  88. package/dist/validator/index.js +133 -0
  89. package/dist/validator/index.js.map +1 -0
  90. package/dist/validator/parser.d.ts +16 -0
  91. package/dist/validator/parser.d.ts.map +1 -0
  92. package/dist/validator/parser.js +260 -0
  93. package/dist/validator/parser.js.map +1 -0
  94. package/dist/validator/tokenizer.d.ts +28 -0
  95. package/dist/validator/tokenizer.d.ts.map +1 -0
  96. package/dist/validator/tokenizer.js +174 -0
  97. package/dist/validator/tokenizer.js.map +1 -0
  98. package/dist/validator/types.d.ts +55 -0
  99. package/dist/validator/types.d.ts.map +1 -0
  100. package/dist/validator/types.js +6 -0
  101. package/dist/validator/types.js.map +1 -0
  102. package/dist/watcher.d.ts +44 -0
  103. package/dist/watcher.d.ts.map +1 -0
  104. package/dist/watcher.js +297 -0
  105. package/dist/watcher.js.map +1 -0
  106. package/dist/world.d.ts +79 -0
  107. package/dist/world.d.ts.map +1 -1
  108. package/dist/world.js +167 -1
  109. package/dist/world.js.map +1 -1
  110. package/package.json +19 -3
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // SnapshotManager — persistent snapshot storage for toMatchSnapshot()
4
+ // ---------------------------------------------------------------------------
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.SnapshotManager = void 0;
40
+ exports.formatSnapshotDiff = formatSnapshotDiff;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ // ---------------------------------------------------------------------------
44
+ // SnapshotManager
45
+ // ---------------------------------------------------------------------------
46
+ /**
47
+ * Manages a single `.snap` JSON file on disk.
48
+ *
49
+ * Lifecycle per test run:
50
+ * 1. `new SnapshotManager(filePath, updateMode)` — loads existing snapshots
51
+ * 2. For each test: `resetCounter(testName)` at test start
52
+ * 3. For each assertion: `check(nextKey(testName), actual)` inside `toMatchSnapshot()`
53
+ * 4. `save()` after all tests complete — writes new/updated snapshots to disk
54
+ * 5. `stats()` — retrieve final counts for the run summary
55
+ *
56
+ * Snapshot file format:
57
+ * A sorted JSON object mapping string keys → string values, e.g.:
58
+ * {
59
+ * "Math > add returns sum: 1": "5",
60
+ * "Math > iter lnum(1,10): 1": "1 2 3 4 5 6 7 8 9 10"
61
+ * }
62
+ *
63
+ * Key format: `"Suite > Sub > Test Name: N"` where N resets to 1 per test.
64
+ */
65
+ class SnapshotManager {
66
+ constructor(filePath, updateMode) {
67
+ this.filePath = filePath;
68
+ this.updateMode = updateMode;
69
+ /** All key→actual values evaluated in this run */
70
+ this.touched = new Map();
71
+ /** Per-test snapshot call counter */
72
+ this.counters = new Map();
73
+ this._matched = 0;
74
+ this._written = 0;
75
+ this._updated = 0;
76
+ this.stored = this.load();
77
+ }
78
+ // -------------------------------------------------------------------------
79
+ // Key management
80
+ // -------------------------------------------------------------------------
81
+ /**
82
+ * Advance and return the next snapshot key for `testName`.
83
+ * Call `resetCounter(testName)` at the start of each test.
84
+ */
85
+ nextKey(testName) {
86
+ const n = (this.counters.get(testName) ?? 0) + 1;
87
+ this.counters.set(testName, n);
88
+ return `${testName}: ${n}`;
89
+ }
90
+ /** Reset the per-test counter. Call this at the start of every test. */
91
+ resetCounter(testName) {
92
+ this.counters.delete(testName);
93
+ }
94
+ // -------------------------------------------------------------------------
95
+ // Core assertion logic
96
+ // -------------------------------------------------------------------------
97
+ /**
98
+ * Check `actual` against the stored snapshot for `key`.
99
+ *
100
+ * - **No prior value**: write it (returns `'written'`, always passes)
101
+ * - **Update mode**: overwrite with `actual` (returns `'updated'` if changed, `'matched'` if same)
102
+ * - **Normal mode**: compare; returns `'matched'` or `'mismatch'`
103
+ */
104
+ check(key, actual) {
105
+ this.touched.set(key, actual);
106
+ const hasStored = Object.prototype.hasOwnProperty.call(this.stored, key);
107
+ if (!hasStored) {
108
+ this._written++;
109
+ return { status: 'written', expected: undefined };
110
+ }
111
+ const expected = this.stored[key];
112
+ if (this.updateMode) {
113
+ if (expected !== actual) {
114
+ this._updated++;
115
+ return { status: 'updated', expected };
116
+ }
117
+ this._matched++;
118
+ return { status: 'matched', expected };
119
+ }
120
+ if (expected === actual) {
121
+ this._matched++;
122
+ return { status: 'matched', expected };
123
+ }
124
+ return { status: 'mismatch', expected };
125
+ }
126
+ // -------------------------------------------------------------------------
127
+ // Persistence
128
+ // -------------------------------------------------------------------------
129
+ /**
130
+ * Flush snapshot state to disk.
131
+ *
132
+ * **Normal mode**: merges new snapshots into the existing file.
133
+ * Existing values are never overwritten — failed snapshots retain
134
+ * their previous (correct) value until the user runs `--updateSnapshot`.
135
+ *
136
+ * **Update mode**: writes only the snapshots evaluated in this run,
137
+ * discarding any obsolete entries that were not touched.
138
+ */
139
+ save() {
140
+ let toWrite;
141
+ if (this.updateMode) {
142
+ // Write only what was evaluated — trims obsolete entries automatically
143
+ toWrite = Object.fromEntries(this.touched);
144
+ }
145
+ else {
146
+ // Start from existing, add only NEW keys (never overwrite)
147
+ toWrite = { ...this.stored };
148
+ for (const [key, value] of this.touched) {
149
+ if (!Object.prototype.hasOwnProperty.call(toWrite, key)) {
150
+ toWrite[key] = value;
151
+ }
152
+ }
153
+ }
154
+ // Sort keys for stable diffs
155
+ const sorted = {};
156
+ for (const key of Object.keys(toWrite).sort()) {
157
+ sorted[key] = toWrite[key];
158
+ }
159
+ // If there's nothing to write, don't create (or leave) an empty snapshot file.
160
+ // An empty {} file would be flagged as obsolete by Jest and cause exit code 1.
161
+ if (Object.keys(sorted).length === 0) {
162
+ if (fs.existsSync(this.filePath)) {
163
+ fs.unlinkSync(this.filePath);
164
+ }
165
+ return;
166
+ }
167
+ const dir = path.dirname(this.filePath);
168
+ fs.mkdirSync(dir, { recursive: true });
169
+ fs.writeFileSync(this.filePath, JSON.stringify(sorted, null, 2) + '\n', 'utf-8');
170
+ }
171
+ // -------------------------------------------------------------------------
172
+ // Stats
173
+ // -------------------------------------------------------------------------
174
+ stats() {
175
+ const touchedKeys = new Set(this.touched.keys());
176
+ const obsolete = Object.keys(this.stored).filter((k) => !touchedKeys.has(k)).length;
177
+ return {
178
+ matched: this._matched,
179
+ written: this._written,
180
+ updated: this._updated,
181
+ obsolete,
182
+ };
183
+ }
184
+ // -------------------------------------------------------------------------
185
+ // Internals
186
+ // -------------------------------------------------------------------------
187
+ load() {
188
+ try {
189
+ const raw = fs.readFileSync(this.filePath, 'utf-8');
190
+ const parsed = JSON.parse(raw);
191
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
192
+ return parsed;
193
+ }
194
+ }
195
+ catch {
196
+ // File doesn't exist or is malformed — start fresh
197
+ }
198
+ return {};
199
+ }
200
+ }
201
+ exports.SnapshotManager = SnapshotManager;
202
+ // ---------------------------------------------------------------------------
203
+ // Snapshot diff formatter (used in error messages)
204
+ // ---------------------------------------------------------------------------
205
+ /**
206
+ * Format a human-readable diff between expected and actual snapshot values.
207
+ * Uses a simple line-by-line format (not a full diff algorithm — values are
208
+ * single-line MUSH results in most cases).
209
+ */
210
+ function formatSnapshotDiff(expected, actual) {
211
+ const expLines = expected.split('\n');
212
+ const actLines = actual.split('\n');
213
+ const maxLines = Math.max(expLines.length, actLines.length);
214
+ const lines = [];
215
+ for (let i = 0; i < maxLines; i++) {
216
+ const e = expLines[i];
217
+ const a = actLines[i];
218
+ if (e !== undefined && a !== undefined && e === a) {
219
+ lines.push(` ${e}`);
220
+ }
221
+ else {
222
+ if (e !== undefined)
223
+ lines.push(` - ${e}`);
224
+ if (a !== undefined)
225
+ lines.push(` + ${a}`);
226
+ }
227
+ }
228
+ return lines.join('\n');
229
+ }
230
+ //# sourceMappingURL=snapshots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshots.js","sourceRoot":"","sources":["../src/snapshots.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,sEAAsE;AACtE,8EAA8E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6N9E,gDAkBC;AA7OD,uCAAyB;AACzB,2CAA6B;AAyB7B,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAa,eAAe;IAY1B,YACmB,QAAgB,EAChB,UAAmB;QADnB,aAAQ,GAAR,QAAQ,CAAQ;QAChB,eAAU,GAAV,UAAU,CAAS;QAXtC,kDAAkD;QACjC,YAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QACrD,qCAAqC;QACpB,aAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE9C,aAAQ,GAAG,CAAC,CAAC;QACb,aAAQ,GAAG,CAAC,CAAC;QACb,aAAQ,GAAG,CAAC,CAAC;QAMnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,4EAA4E;IAC5E,iBAAiB;IACjB,4EAA4E;IAE5E;;;OAGG;IACH,OAAO,CAAC,QAAgB;QACtB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC/B,OAAO,GAAG,QAAQ,KAAK,CAAC,EAAE,CAAC;IAC7B,CAAC;IAED,wEAAwE;IACxE,YAAY,CAAC,QAAgB;QAC3B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,4EAA4E;IAC5E,uBAAuB;IACvB,4EAA4E;IAE5E;;;;;;OAMG;IACH,KAAK,CAAC,GAAW,EAAE,MAAc;QAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAE9B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAEzE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACpD,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;YACzC,CAAC;YACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;QACzC,CAAC;QAED,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;QACzC,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;IAC1C,CAAC;IAED,4EAA4E;IAC5E,cAAc;IACd,4EAA4E;IAE5E;;;;;;;;;OASG;IACH,IAAI;QACF,IAAI,OAA+B,CAAC;QAEpC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,uEAAuE;YACvE,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,2DAA2D;YAC3D,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC7B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;oBACxD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACvB,CAAC;YACH,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAED,+EAA+E;QAC/E,+EAA+E;QAC/E,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACnF,CAAC;IAED,4EAA4E;IAC5E,QAAQ;IACR,4EAA4E;IAE5E,KAAK;QACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACpF,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,YAAY;IACZ,4EAA4E;IAEpE,IAAI;QACV,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5E,OAAO,MAAgC,CAAC;YAC1C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;QACrD,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AA/JD,0CA+JC;AAED,8EAA8E;AAC9E,mDAAmD;AACnD,8EAA8E;AAE9E;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,QAAgB,EAAE,MAAc;IACjE,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,KAAK,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,18 @@
1
+ export type Platform = 'rhost' | 'penn' | 'mux';
2
+ export interface FunctionSignature {
3
+ name: string;
4
+ minArgs: number;
5
+ /** Use Infinity for variadic functions with no upper bound */
6
+ maxArgs: number;
7
+ deprecated?: boolean;
8
+ /** True for functions specific to RhostMUSH (not standard PennMUSH/TinyMUX) */
9
+ rhostOnly?: boolean;
10
+ /**
11
+ * If set, the function is only available on these platforms.
12
+ * Omit for functions that are universally available.
13
+ */
14
+ platforms?: Platform[];
15
+ }
16
+ /** Pre-built map of lowercase function name → signature for O(1) lookup */
17
+ export declare const BUILTIN_FUNCTIONS: ReadonlyMap<string, FunctionSignature>;
18
+ //# sourceMappingURL=builtins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../../src/validator/builtins.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB;AAwQD,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAKpE,CAAC"}
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // RhostMUSH built-in function signature database
4
+ // ---------------------------------------------------------------------------
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BUILTIN_FUNCTIONS = void 0;
7
+ // minArgs, maxArgs shorthand builder
8
+ function sig(minArgs, maxArgs, opts = {}) {
9
+ return { name: '', minArgs, maxArgs, ...opts };
10
+ }
11
+ const INF = Infinity;
12
+ const DEFINITIONS = [
13
+ // -------------------------------------------------------------------------
14
+ // Math
15
+ // -------------------------------------------------------------------------
16
+ ['abs', 1, 1],
17
+ ['add', 2, INF],
18
+ ['sub', 2, 2],
19
+ ['mul', 2, INF],
20
+ ['div', 2, 2],
21
+ ['fdiv', 2, 2],
22
+ ['mod', 2, 2],
23
+ ['modulo', 2, 2],
24
+ ['remainder', 2, 2],
25
+ ['power', 2, 2],
26
+ ['sqrt', 1, 1],
27
+ ['ceil', 1, 1],
28
+ ['floor', 1, 1],
29
+ ['round', 1, 2],
30
+ ['trunc', 1, 1],
31
+ ['max', 1, INF],
32
+ ['min', 1, INF],
33
+ ['sign', 1, 1],
34
+ ['gt', 2, 2],
35
+ ['gte', 2, 2],
36
+ ['lt', 2, 2],
37
+ ['lte', 2, 2],
38
+ ['eq', 2, 2],
39
+ ['neq', 2, 2],
40
+ ['and', 2, INF],
41
+ ['or', 2, INF],
42
+ ['not', 1, 1],
43
+ ['xor', 2, 2],
44
+ ['nand', 2, INF],
45
+ ['nor', 2, INF],
46
+ ['band', 2, 2],
47
+ ['bor', 2, 2],
48
+ ['bxor', 2, 2],
49
+ ['bnot', 1, 1],
50
+ ['bshl', 2, 2],
51
+ ['bshr', 2, 2],
52
+ ['pi', 0, 0],
53
+ ['e', 0, 0],
54
+ ['sin', 1, 2],
55
+ ['cos', 1, 2],
56
+ ['tan', 1, 2],
57
+ ['asin', 1, 2],
58
+ ['acos', 1, 2],
59
+ ['atan', 1, 3],
60
+ ['exp', 1, 1],
61
+ ['ln', 1, 1],
62
+ ['log', 1, 2],
63
+ ['dist2d', 4, 4],
64
+ ['dist3d', 6, 6],
65
+ ['isnum', 1, 1],
66
+ ['isint', 1, 1],
67
+ // -------------------------------------------------------------------------
68
+ // String
69
+ // -------------------------------------------------------------------------
70
+ ['strlen', 1, 1],
71
+ ['len', 1, 1],
72
+ ['lcstr', 1, 1],
73
+ ['ucstr', 1, 1],
74
+ ['capstr', 1, 1],
75
+ ['left', 2, 2],
76
+ ['right', 2, 2],
77
+ ['mid', 3, 3],
78
+ ['first', 1, 2],
79
+ ['last', 1, 2],
80
+ ['rest', 1, 2],
81
+ ['before', 2, 2],
82
+ ['after', 2, 2],
83
+ ['cat', 1, INF],
84
+ ['strcat', 1, INF],
85
+ ['trim', 1, 3],
86
+ ['ltrim', 1, 2],
87
+ ['rtrim', 1, 2],
88
+ ['space', 1, 1],
89
+ ['ljust', 2, 3],
90
+ ['rjust', 2, 3],
91
+ ['center', 2, 3],
92
+ ['repeat', 2, 2],
93
+ ['edit', 3, INF],
94
+ ['replace', 3, 4],
95
+ ['revwords', 1, 2],
96
+ ['words', 1, 2],
97
+ ['word', 2, 3],
98
+ ['wordpos', 2, 3],
99
+ ['numwords', 1, 2],
100
+ ['index', 3, 4],
101
+ ['rindex', 3, 3],
102
+ ['pos', 2, 2],
103
+ ['lpos', 2, 3],
104
+ ['comp', 2, 2],
105
+ ['strcmp', 2, 2],
106
+ ['strmatch', 2, 3],
107
+ ['wildmatch', 2, 3],
108
+ ['pmatch', 1, INF],
109
+ ['escape', 1, 1],
110
+ ['decompose', 1, 1],
111
+ ['secure', 1, 1],
112
+ ['stripansi', 1, 1],
113
+ ['ansi', 2, 2],
114
+ ['soundex', 1, 1, { platforms: ['rhost', 'penn'] }],
115
+ ['soundslike', 2, 2],
116
+ ['strdistance', 2, 2, { rhostOnly: true, platforms: ['rhost'] }],
117
+ ['checkstr', 1, 1],
118
+ ['strinsert', 3, 3],
119
+ ['encrypt', 2, 2],
120
+ ['decrypt', 2, 2],
121
+ ['encode64', 1, 1, { rhostOnly: true, platforms: ['rhost'] }],
122
+ ['decode64', 1, 1, { rhostOnly: true, platforms: ['rhost'] }],
123
+ ['digest', 2, 2, { rhostOnly: true, platforms: ['rhost'] }],
124
+ ['crypt', 2, 2],
125
+ ['tr', 3, 3],
126
+ ['flip', 0, 1],
127
+ ['lit', 1, 1],
128
+ ['readable', 1, 1],
129
+ ['visible', 2, 2],
130
+ ['valid', 2, 2],
131
+ ['hastype', 2, 2],
132
+ // -------------------------------------------------------------------------
133
+ // List
134
+ // -------------------------------------------------------------------------
135
+ ['member', 2, 3],
136
+ ['elements', 2, 3],
137
+ ['insert', 3, 4],
138
+ ['remove', 2, 3],
139
+ ['sort', 1, 4],
140
+ ['lsort', 1, 4],
141
+ ['sortby', 2, 4],
142
+ ['shuffle', 1, 3],
143
+ ['setunion', 2, 4],
144
+ ['setinter', 2, 4],
145
+ ['setdiff', 2, 4],
146
+ ['setq', 2, INF],
147
+ ['getq', 1, 1],
148
+ ['r', 1, 1],
149
+ ['filter', 2, 4],
150
+ ['filterfun', 2, INF],
151
+ ['map', 2, 5],
152
+ ['fold', 2, 4],
153
+ ['iter', 2, 4],
154
+ ['parse', 2, 4],
155
+ ['itext', 1, 1],
156
+ ['inum', 1, 1],
157
+ ['lnum', 1, 4],
158
+ ['list', 2, INF],
159
+ ['grab', 2, 3],
160
+ ['graball', 2, 4],
161
+ ['match', 2, 3],
162
+ ['matchall', 2, 4],
163
+ ['splice', 2, 3],
164
+ ['unique', 1, 3],
165
+ ['munge', 3, 5],
166
+ ['step', 3, 5],
167
+ ['table', 1, 6],
168
+ // -------------------------------------------------------------------------
169
+ // Object / database
170
+ // -------------------------------------------------------------------------
171
+ ['name', 1, 1],
172
+ ['fullname', 1, 1],
173
+ ['alias', 1, 1],
174
+ ['owner', 1, 1],
175
+ ['loc', 1, 1],
176
+ ['rloc', 2, 2],
177
+ ['con', 1, 1],
178
+ ['next', 1, 1],
179
+ ['num', 1, 1],
180
+ ['dbref', 1, 1],
181
+ ['locate', 3, 3],
182
+ ['nearby', 2, 2],
183
+ ['flags', 1, 2],
184
+ ['hasflag', 2, 2],
185
+ ['haspower', 2, 2],
186
+ ['powers', 1, 1],
187
+ ['type', 1, 1],
188
+ ['istype', 2, 2],
189
+ ['isobject', 1, 1],
190
+ ['isroom', 1, 1],
191
+ ['isplayer', 1, 1],
192
+ ['isthing', 1, 1],
193
+ ['isexit', 1, 1],
194
+ ['isdbref', 1, 1],
195
+ ['get', 1, 1],
196
+ ['xget', 2, 2],
197
+ ['get_eval', 1, 1],
198
+ ['v', 1, 1],
199
+ ['attr', 2, 2],
200
+ ['lattr', 1, 2],
201
+ ['lattrp', 1, 2],
202
+ ['lcon', 1, 2],
203
+ ['lexits', 1, 1],
204
+ ['create', 1, 2],
205
+ ['open', 1, 2],
206
+ ['link', 2, 2],
207
+ ['zone', 1, 1],
208
+ ['parent', 1, 1],
209
+ ['children', 1, 1],
210
+ ['lparent', 1, 2],
211
+ // -------------------------------------------------------------------------
212
+ // Control / evaluation
213
+ // -------------------------------------------------------------------------
214
+ ['u', 1, INF],
215
+ ['ulocal', 1, INF],
216
+ ['ufun', 2, INF],
217
+ ['udefault', 2, INF],
218
+ ['ulambda', 2, INF],
219
+ ['default', 2, 2],
220
+ ['edefault', 2, 2],
221
+ ['switch', 3, INF],
222
+ ['switchall', 3, INF],
223
+ ['cond', 2, INF],
224
+ ['condall', 2, INF],
225
+ ['if', 2, 3],
226
+ ['ifelse', 3, 3],
227
+ ['when', 2, 2],
228
+ ['null', 0, INF],
229
+ ['nop', 0, INF],
230
+ ['localize', 1, 1, { platforms: ['rhost', 'penn'] }],
231
+ ['objeval', 2, 2],
232
+ ['eval', 2, 2],
233
+ ['apply', 2, 3],
234
+ ['zfun', 1, INF],
235
+ // -------------------------------------------------------------------------
236
+ // Time / random
237
+ // -------------------------------------------------------------------------
238
+ ['time', 0, 1],
239
+ ['secs', 0, 1],
240
+ ['convsecs', 1, 1],
241
+ ['convtime', 1, 1],
242
+ ['timestring', 1, 2],
243
+ ['rand', 1, 2],
244
+ ['die', 2, 2],
245
+ // -------------------------------------------------------------------------
246
+ // Registers / misc
247
+ // -------------------------------------------------------------------------
248
+ ['setvars', 2, 2],
249
+ ['xvars', 2, 2],
250
+ ['lvars', 0, 1],
251
+ ['execscript', 1, INF, { rhostOnly: true, platforms: ['rhost'] }],
252
+ ['pemit', 2, 2],
253
+ ['emit', 1, 1],
254
+ ['remit', 2, 2],
255
+ ['lemit', 1, 1],
256
+ ['zemit', 2, 2],
257
+ ['think', 1, 1],
258
+ ['select', 3, INF],
259
+ ];
260
+ /** Pre-built map of lowercase function name → signature for O(1) lookup */
261
+ exports.BUILTIN_FUNCTIONS = new Map(DEFINITIONS.map(([name, min, max, opts]) => [
262
+ name,
263
+ { name: name, minArgs: min, maxArgs: max, ...(opts ?? {}) },
264
+ ]));
265
+ //# sourceMappingURL=builtins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtins.js","sourceRoot":"","sources":["../../src/validator/builtins.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { ASTNode, Diagnostic } from './types';
2
+ /**
3
+ * Walk the AST and emit semantic diagnostics.
4
+ *
5
+ * Checks performed per `FunctionCallNode`:
6
+ * E005 — Unknown function (warning, not error — may be a UDF)
7
+ * E006 — Too few arguments
8
+ * E007 — Too many arguments
9
+ * W002 — Empty argument
10
+ * W003 — Deprecated function
11
+ */
12
+ export declare function semanticCheck(nodes: ASTNode[]): Diagnostic[];
13
+ //# sourceMappingURL=checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../../src/validator/checker.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAoB,MAAM,SAAS,CAAC;AAOhE;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,CAI5D"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // Semantic checker: validates the AST against the built-in function database
4
+ // ---------------------------------------------------------------------------
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.semanticCheck = semanticCheck;
7
+ const builtins_1 = require("./builtins");
8
+ // ---------------------------------------------------------------------------
9
+ // Public entry point
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * Walk the AST and emit semantic diagnostics.
13
+ *
14
+ * Checks performed per `FunctionCallNode`:
15
+ * E005 — Unknown function (warning, not error — may be a UDF)
16
+ * E006 — Too few arguments
17
+ * E007 — Too many arguments
18
+ * W002 — Empty argument
19
+ * W003 — Deprecated function
20
+ */
21
+ function semanticCheck(nodes) {
22
+ const diagnostics = [];
23
+ walkNodes(nodes, diagnostics);
24
+ return diagnostics;
25
+ }
26
+ // ---------------------------------------------------------------------------
27
+ // AST walkers
28
+ // ---------------------------------------------------------------------------
29
+ function walkNodes(nodes, diagnostics) {
30
+ for (const node of nodes) {
31
+ walkNode(node, diagnostics);
32
+ }
33
+ }
34
+ function walkNode(node, diagnostics) {
35
+ switch (node.type) {
36
+ case 'FunctionCall':
37
+ checkFunctionCall(node, diagnostics);
38
+ break;
39
+ case 'BracketEval':
40
+ walkNodes(node.nodes, diagnostics);
41
+ break;
42
+ case 'RawText':
43
+ case 'Substitution':
44
+ // Nothing to validate at the leaf level
45
+ break;
46
+ }
47
+ }
48
+ function checkFunctionCall(node, diagnostics) {
49
+ const key = node.name.toLowerCase();
50
+ const sig = builtins_1.BUILTIN_FUNCTIONS.get(key);
51
+ if (!sig) {
52
+ // Unknown function — warn rather than error because MUSHcoders heavily
53
+ // use user-defined @functions and inline u() attribute patterns.
54
+ diagnostics.push({
55
+ severity: 'warning',
56
+ code: 'W005',
57
+ message: `Unknown function '${node.name}' — not in built-in database (may be a UDF or @function)`,
58
+ offset: node.nameOffset,
59
+ length: node.name.length,
60
+ });
61
+ }
62
+ else {
63
+ const argCount = node.args.length;
64
+ if (argCount < sig.minArgs) {
65
+ diagnostics.push({
66
+ severity: 'error',
67
+ code: 'E006',
68
+ message: argCount === 0
69
+ ? `'${node.name}' requires at least ${sig.minArgs} argument${sig.minArgs !== 1 ? 's' : ''}, but got none`
70
+ : `'${node.name}' requires at least ${sig.minArgs} argument${sig.minArgs !== 1 ? 's' : ''}, but got ${argCount}`,
71
+ offset: node.nameOffset,
72
+ length: node.name.length,
73
+ });
74
+ }
75
+ else if (isFinite(sig.maxArgs) && argCount > sig.maxArgs) {
76
+ diagnostics.push({
77
+ severity: 'error',
78
+ code: 'E007',
79
+ message: `'${node.name}' accepts at most ${sig.maxArgs} argument${sig.maxArgs !== 1 ? 's' : ''}, but got ${argCount}`,
80
+ offset: node.nameOffset,
81
+ length: node.name.length,
82
+ });
83
+ }
84
+ if (sig.deprecated) {
85
+ diagnostics.push({
86
+ severity: 'warning',
87
+ code: 'W003',
88
+ message: `'${node.name}' is deprecated`,
89
+ offset: node.nameOffset,
90
+ length: node.name.length,
91
+ });
92
+ }
93
+ }
94
+ // Check for empty arguments (potential typos like `add(,3)`)
95
+ for (let i = 0; i < node.args.length; i++) {
96
+ if (node.args[i].length === 0) {
97
+ diagnostics.push({
98
+ severity: 'warning',
99
+ code: 'W002',
100
+ message: `Argument ${i + 1} of '${node.name}' is empty`,
101
+ offset: node.offset,
102
+ length: 1,
103
+ });
104
+ }
105
+ }
106
+ // Recurse into each argument's nodes
107
+ for (const arg of node.args) {
108
+ walkNodes(arg, diagnostics);
109
+ }
110
+ }
111
+ //# sourceMappingURL=checker.js.map