@rhost/testkit 1.5.3 → 1.6.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.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Pueblo markup → semantic HTML converter
3
+ *
4
+ * Converts the mixed stream that RhostMUSH emits after a PUEBLOCLIENT
5
+ * handshake (raw HTML tags + plain text + ANSI) into clean, safe,
6
+ * semantic HTML. Pure TypeScript — no DOMParser, works in Node.js.
7
+ *
8
+ * Reference: http://www.legacymud.com/pueblo/pueblo_ext.html
9
+ */
10
+ /** Options for `convertPueblo` (reserved for future extension). */
11
+ export interface PuebloConvertOptions {
12
+ [key: string]: unknown;
13
+ }
14
+ /**
15
+ * Parsed representation of a Pueblo client handshake.
16
+ * @deprecated parsePuebloHandshake now returns boolean — kept for compat.
17
+ */
18
+ export interface PuebloHandshake {
19
+ version: string;
20
+ supportsXchCmd: boolean;
21
+ extra: Record<string, string>;
22
+ }
23
+ /**
24
+ * Convert a Pueblo-enhanced mixed stream into clean, safe semantic HTML.
25
+ *
26
+ * @param input Raw string received from a Pueblo-enabled RhostMUSH server.
27
+ * @returns Sanitized HTML string.
28
+ */
29
+ export declare function convertPueblo(input: string): string;
30
+ /**
31
+ * Returns true when the input line begins with the PUEBLOCLIENT keyword,
32
+ * indicating this is a Pueblo client handshake.
33
+ */
34
+ export declare function parsePuebloHandshake(input: string): boolean;
35
+ /**
36
+ * Returns the canonical Pueblo client handshake string that should be sent
37
+ * to a Pueblo-enabled RhostMUSH server immediately after connecting.
38
+ */
39
+ export declare function generatePuebloHandshake(): string;
40
+ //# sourceMappingURL=pueblo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pueblo.d.ts","sourceRoot":"","sources":["../src/pueblo.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,mEAAmE;AACnE,MAAM,WAAW,oBAAoB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AA2LD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA4EnD;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD"}
package/dist/pueblo.js ADDED
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ /**
3
+ * Pueblo markup → semantic HTML converter
4
+ *
5
+ * Converts the mixed stream that RhostMUSH emits after a PUEBLOCLIENT
6
+ * handshake (raw HTML tags + plain text + ANSI) into clean, safe,
7
+ * semantic HTML. Pure TypeScript — no DOMParser, works in Node.js.
8
+ *
9
+ * Reference: http://www.legacymud.com/pueblo/pueblo_ext.html
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.convertPueblo = convertPueblo;
13
+ exports.parsePuebloHandshake = parsePuebloHandshake;
14
+ exports.generatePuebloHandshake = generatePuebloHandshake;
15
+ // ---------------------------------------------------------------------------
16
+ // Constants
17
+ // ---------------------------------------------------------------------------
18
+ const PUEBLOCLIENT_HANDSHAKE = 'PUEBLOCLIENT 1.0.1\r\n';
19
+ /** Tags whose entire subtree (open + content + close) must be stripped. */
20
+ const BLOCKED_TAGS = new Set([
21
+ 'script', 'style', 'iframe', 'object', 'embed', 'form',
22
+ 'input', 'button', 'textarea', 'select', 'meta', 'link',
23
+ 'base', 'noscript', 'template', 'slot', 'applet',
24
+ ]);
25
+ /** Tags that are allowed through (after attribute sanitization). */
26
+ const ALLOWED_TAGS = new Set([
27
+ 'a', 'b', 'i', 'u', 's', 'strong', 'em', 'small', 'big',
28
+ 'font', 'span', 'div', 'p', 'br', 'hr', 'pre', 'code', 'tt',
29
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
30
+ 'ul', 'ol', 'li', 'dl', 'dt', 'dd',
31
+ 'table', 'tr', 'td', 'th', 'thead', 'tbody', 'tfoot',
32
+ 'img', 'audio', 'video', 'source',
33
+ // Pueblo-specific / legacy
34
+ 'center', 'bgsound',
35
+ ]);
36
+ /** Per-tag attribute allowlist (tag → set of allowed attribute names). */
37
+ const TAG_ATTRS = {
38
+ a: new Set(['href', 'name', 'target', 'title', 'data-xch-cmd']),
39
+ img: new Set(['src', 'alt', 'width', 'height', 'title']),
40
+ audio: new Set(['src', 'controls', 'loop', 'autoplay', 'preload']),
41
+ video: new Set(['src', 'controls', 'loop', 'width', 'height', 'poster']),
42
+ source: new Set(['src', 'type']),
43
+ font: new Set(['color', 'size', 'face']),
44
+ table: new Set(['border', 'cellpadding', 'cellspacing', 'width']),
45
+ td: new Set(['colspan', 'rowspan', 'align', 'valign', 'width']),
46
+ th: new Set(['colspan', 'rowspan', 'align', 'valign', 'width']),
47
+ div: new Set(['style', 'class', 'id']),
48
+ span: new Set(['style', 'class', 'id']),
49
+ p: new Set(['align']),
50
+ hr: new Set(['width', 'size', 'noshade']),
51
+ b: new Set(), i: new Set(), u: new Set(), s: new Set(),
52
+ strong: new Set(), em: new Set(), small: new Set(), big: new Set(),
53
+ pre: new Set(), code: new Set(), tt: new Set(),
54
+ br: new Set(),
55
+ ul: new Set(), ol: new Set(), li: new Set(),
56
+ h1: new Set(), h2: new Set(), h3: new Set(),
57
+ h4: new Set(), h5: new Set(), h6: new Set(),
58
+ };
59
+ // ---------------------------------------------------------------------------
60
+ // Helpers
61
+ // ---------------------------------------------------------------------------
62
+ function escapeHtml(text) {
63
+ return text
64
+ .replace(/&/g, '&amp;')
65
+ .replace(/</g, '&lt;')
66
+ .replace(/>/g, '&gt;')
67
+ .replace(/"/g, '&quot;');
68
+ }
69
+ function escapeAttrValue(value) {
70
+ return value
71
+ .replace(/&/g, '&amp;')
72
+ .replace(/"/g, '&quot;')
73
+ .replace(/</g, '&lt;')
74
+ .replace(/>/g, '&gt;');
75
+ }
76
+ function isDangerousHref(value) {
77
+ const v = value.trim().toLowerCase().replace(/[\t\n\r ]/g, '');
78
+ return v.startsWith('javascript:') || v.startsWith('vbscript:') || v.startsWith('data:');
79
+ }
80
+ function parseAttrs(raw) {
81
+ const map = new Map();
82
+ const re = /([a-zA-Z_:][a-zA-Z0-9_:.-]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]*)))?/g;
83
+ let m;
84
+ while ((m = re.exec(raw)) !== null) {
85
+ const name = m[1].toLowerCase();
86
+ const value = m[2] ?? m[3] ?? m[4] ?? '';
87
+ map.set(name, value);
88
+ }
89
+ return map;
90
+ }
91
+ function tokenize(input) {
92
+ const tokens = [];
93
+ let i = 0;
94
+ while (i < input.length) {
95
+ if (input[i] !== '<') {
96
+ const end = input.indexOf('<', i);
97
+ const text = end === -1 ? input.slice(i) : input.slice(i, end);
98
+ tokens.push({ type: 'text', value: text });
99
+ i = end === -1 ? input.length : end;
100
+ continue;
101
+ }
102
+ const closeAngle = input.indexOf('>', i);
103
+ if (closeAngle === -1) {
104
+ tokens.push({ type: 'text', value: input.slice(i) });
105
+ break;
106
+ }
107
+ const tagContent = input.slice(i + 1, closeAngle);
108
+ if (tagContent.startsWith('/')) {
109
+ const tagName = tagContent.slice(1).trim().toLowerCase().split(/[\s/]/)[0];
110
+ // Only treat as close tag if it looks like a real tag name
111
+ if (/^[a-z][a-z0-9]*$/.test(tagName)) {
112
+ tokens.push({ type: 'close', tag: tagName });
113
+ i = closeAngle + 1;
114
+ continue;
115
+ }
116
+ // Not a real close tag — emit as text
117
+ tokens.push({ type: 'text', value: input.slice(i, closeAngle + 1) });
118
+ i = closeAngle + 1;
119
+ continue;
120
+ }
121
+ if (tagContent.startsWith('!') || tagContent.startsWith('?')) {
122
+ i = closeAngle + 1;
123
+ continue;
124
+ }
125
+ const selfClose = tagContent.endsWith('/');
126
+ const inner = selfClose ? tagContent.slice(0, -1) : tagContent;
127
+ const spaceIdx = inner.search(/\s/);
128
+ const tag = (spaceIdx === -1 ? inner : inner.slice(0, spaceIdx)).toLowerCase();
129
+ // Not a valid tag name — emit entire bracket-to-bracket span as text
130
+ if (!/^[a-z][a-z0-9]*$/.test(tag)) {
131
+ tokens.push({ type: 'text', value: input.slice(i, closeAngle + 1) });
132
+ i = closeAngle + 1;
133
+ continue;
134
+ }
135
+ const attrRaw = spaceIdx === -1 ? '' : inner.slice(spaceIdx + 1);
136
+ const attrs = parseAttrs(attrRaw);
137
+ tokens.push({ type: 'open', tag, attrs, selfClose });
138
+ i = closeAngle + 1;
139
+ }
140
+ return tokens;
141
+ }
142
+ // ---------------------------------------------------------------------------
143
+ // Sanitizer helpers
144
+ // ---------------------------------------------------------------------------
145
+ function sanitizeOpenTag(tag, attrs, selfClose) {
146
+ const allowedAttrs = TAG_ATTRS[tag] ?? new Set();
147
+ const parts = [tag];
148
+ for (const [name, value] of attrs) {
149
+ if (/^on/i.test(name))
150
+ continue;
151
+ if (!allowedAttrs.has(name))
152
+ continue;
153
+ if (name === 'href' && isDangerousHref(value))
154
+ continue;
155
+ // Boolean attributes (controls, loop, etc.)
156
+ if (value === '') {
157
+ parts.push(name);
158
+ }
159
+ else {
160
+ parts.push(`${name}="${escapeAttrValue(value)}"`);
161
+ }
162
+ }
163
+ const close = selfClose ? ' />' : '>';
164
+ return '<' + parts.join(' ') + close;
165
+ }
166
+ // ---------------------------------------------------------------------------
167
+ // Main converter
168
+ // ---------------------------------------------------------------------------
169
+ /**
170
+ * Convert a Pueblo-enhanced mixed stream into clean, safe semantic HTML.
171
+ *
172
+ * @param input Raw string received from a Pueblo-enabled RhostMUSH server.
173
+ * @returns Sanitized HTML string.
174
+ */
175
+ function convertPueblo(input) {
176
+ const tokens = tokenize(input);
177
+ const out = [];
178
+ // Track depth inside blocked subtrees (e.g. <script>...</script>)
179
+ const blockedStack = [];
180
+ for (const token of tokens) {
181
+ if (token.type === 'text') {
182
+ if (blockedStack.length > 0)
183
+ continue;
184
+ out.push(escapeHtml(token.value));
185
+ continue;
186
+ }
187
+ if (token.type === 'close') {
188
+ const { tag } = token;
189
+ if (blockedStack.length > 0) {
190
+ if (blockedStack[blockedStack.length - 1] === tag)
191
+ blockedStack.pop();
192
+ continue;
193
+ }
194
+ if (tag === 'center') {
195
+ out.push('</div>');
196
+ continue;
197
+ }
198
+ if (tag === 'bgsound')
199
+ continue;
200
+ if (ALLOWED_TAGS.has(tag))
201
+ out.push(`</${tag}>`);
202
+ continue;
203
+ }
204
+ // token.type === 'open'
205
+ const { tag, attrs, selfClose } = token;
206
+ if (BLOCKED_TAGS.has(tag)) {
207
+ if (!selfClose)
208
+ blockedStack.push(tag);
209
+ continue;
210
+ }
211
+ if (!ALLOWED_TAGS.has(tag))
212
+ continue;
213
+ // ---- Special transformations ----
214
+ // <center> → <div style="text-align:center">
215
+ if (tag === 'center') {
216
+ out.push('<div style="text-align:center">');
217
+ continue;
218
+ }
219
+ // <bgsound src="..."> → <audio src="..." controls loop>
220
+ if (tag === 'bgsound') {
221
+ const src = attrs.get('src') ?? '';
222
+ out.push(`<audio src="${escapeAttrValue(src)}" controls loop>`);
223
+ continue;
224
+ }
225
+ // <audio ...> — ensure controls is present
226
+ if (tag === 'audio') {
227
+ if (!attrs.has('controls'))
228
+ attrs.set('controls', '');
229
+ out.push(sanitizeOpenTag(tag, attrs, selfClose));
230
+ continue;
231
+ }
232
+ // <a xch_cmd="..."> — move xch_cmd to data-xch-cmd; set href="#" if none
233
+ if (tag === 'a') {
234
+ const xchCmd = attrs.get('xch_cmd');
235
+ if (xchCmd !== undefined) {
236
+ attrs.delete('xch_cmd');
237
+ attrs.set('data-xch-cmd', xchCmd);
238
+ if (!attrs.has('href'))
239
+ attrs.set('href', '#');
240
+ }
241
+ out.push(sanitizeOpenTag(tag, attrs, selfClose));
242
+ continue;
243
+ }
244
+ out.push(sanitizeOpenTag(tag, attrs, selfClose));
245
+ }
246
+ return out.join('');
247
+ }
248
+ // ---------------------------------------------------------------------------
249
+ // Handshake helpers
250
+ // ---------------------------------------------------------------------------
251
+ /**
252
+ * Returns true when the input line begins with the PUEBLOCLIENT keyword,
253
+ * indicating this is a Pueblo client handshake.
254
+ */
255
+ function parsePuebloHandshake(input) {
256
+ return input.trimStart().toUpperCase().startsWith('PUEBLOCLIENT');
257
+ }
258
+ /**
259
+ * Returns the canonical Pueblo client handshake string that should be sent
260
+ * to a Pueblo-enabled RhostMUSH server immediately after connecting.
261
+ */
262
+ function generatePuebloHandshake() {
263
+ return PUEBLOCLIENT_HANDSHAKE;
264
+ }
265
+ //# sourceMappingURL=pueblo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pueblo.js","sourceRoot":"","sources":["../src/pueblo.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAoNH,sCA4EC;AAUD,oDAEC;AAMD,0DAEC;AA/RD,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAExD,2EAA2E;AAC3E,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IACzB,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IACtD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM;IACvD,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ;CACnD,CAAC,CAAC;AAEH,oEAAoE;AACpE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IACzB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK;IACvD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI;IAC3D,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;IACpD,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ;IACjC,2BAA2B;IAC3B,QAAQ,EAAE,SAAS;CACtB,CAAC,CAAC;AAEH,0EAA0E;AAC1E,MAAM,SAAS,GAAgC;IAC3C,CAAC,EAAO,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;IACpE,GAAG,EAAK,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3D,KAAK,EAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACnE,KAAK,EAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAI,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,KAAK,EAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAClE,EAAE,EAAM,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnE,EAAE,EAAM,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnE,GAAG,EAAK,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACzC,IAAI,EAAI,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC,EAAO,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAC1B,EAAE,EAAM,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAC7C,CAAC,EAAO,IAAI,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,GAAG,EAAE;IAC3D,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,GAAG,EAAE;IAClE,GAAG,EAAK,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE;IACjD,EAAE,EAAM,IAAI,GAAG,EAAE;IACjB,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE;IAC3C,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE;IAC3C,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE;CAC9C,CAAC;AAEF,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,UAAU,CAAC,IAAY;IAC5B,OAAO,IAAI;SACN,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IAClC,OAAO,KAAK;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IAClC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC/D,OAAO,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAC7F,CAAC;AAWD,SAAS,UAAU,CAAC,GAAW;IAC3B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,MAAM,EAAE,GAAG,4EAA4E,CAAC;IACxF,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa;IAC3B,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC/D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3C,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;YACpC,SAAS;QACb,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACzC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrD,MAAM;QACV,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;QAElD,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3E,2DAA2D;YAC3D,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC7C,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;gBACnB,SAAS;YACb,CAAC;YACD,sCAAsC;YACtC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;YACrE,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;YACnB,SAAS;QACb,CAAC;QAED,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3D,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;YACnB,SAAS;QACb,CAAC;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAE/E,qEAAqE;QACrE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;YACrE,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;YACnB,SAAS;QACb,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAElC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACrD,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,SAAS,eAAe,CAAC,GAAW,EAAE,KAA0B,EAAE,SAAkB;IAChF,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;IACzD,MAAM,KAAK,GAAa,CAAC,GAAG,CAAC,CAAC;IAE9B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;QAChC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAChC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QACtC,IAAI,IAAI,KAAK,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC;YAAE,SAAS;QAExD,4CAA4C;QAC5C,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtD,CAAC;IACL,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;IACtC,OAAO,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACzC,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,KAAa;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAa,EAAE,CAAC;IAEzB,kEAAkE;IAClE,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxB,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YACtC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YAClC,SAAS;QACb,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;YAEtB,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,IAAI,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG;oBAAE,YAAY,CAAC,GAAG,EAAE,CAAC;gBACtE,SAAS;YACb,CAAC;YAED,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAAC,SAAS;YAAC,CAAC;YACvD,IAAI,GAAG,KAAK,SAAS;gBAAE,SAAS;YAChC,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;YACjD,SAAS;QACb,CAAC;QAED,wBAAwB;QACxB,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;QAExC,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,SAAS;gBAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvC,SAAS;QACb,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAErC,oCAAoC;QAEpC,6CAA6C;QAC7C,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;YAC5C,SAAS;QACb,CAAC;QAED,wDAAwD;QACxD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACnC,GAAG,CAAC,IAAI,CAAC,eAAe,eAAe,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAChE,SAAS;QACb,CAAC;QAED,2CAA2C;QAC3C,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YACtD,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;YACjD,SAAS;QACb,CAAC;QAED,yEAAyE;QACzE,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;YACd,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACvB,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBACxB,KAAK,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;gBAClC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;oBAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACnD,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;YACjD,SAAS;QACb,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,KAAa;IAC9C,OAAO,KAAK,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB;IACnC,OAAO,sBAAsB,CAAC;AAClC,CAAC"}
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@rhost/testkit",
3
- "version": "1.5.3",
3
+ "version": "1.6.0",
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",
7
7
  "bin": {
8
- "rhost-testkit": "./dist/cli/index.js"
8
+ "rhost-testkit": "./dist/cli/index.js",
9
+ "rhost-server": "./dist/cli/server-bin.js"
9
10
  },
10
11
  "exports": {
11
12
  ".": {
@@ -78,11 +79,13 @@
78
79
  "license": "MIT",
79
80
  "dependencies": {
80
81
  "@ursamu/mushcode": "npm:@jsr/ursamu__mushcode@^0.3.4",
81
- "testcontainers": "^11.13.0"
82
+ "testcontainers": "^11.13.0",
83
+ "ws": "^8.20.0"
82
84
  },
83
85
  "devDependencies": {
84
86
  "@types/jest": "^29.5.0",
85
87
  "@types/node": "^20.0.0",
88
+ "@types/ws": "^8.18.1",
86
89
  "jest": "^29.5.0",
87
90
  "ts-jest": "^29.1.0",
88
91
  "ts-node": "^10.9.0",
@@ -105,5 +108,8 @@
105
108
  "statements": 80
106
109
  }
107
110
  }
108
- }
111
+ },
112
+ "bundleDependencies": [
113
+ "@ursamu/mushcode"
114
+ ]
109
115
  }