@sfirew/minecraft-motd-parser 1.1.5 → 1.1.9-dev.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/CHANGELOG.md CHANGED
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
 
9
9
 
10
+ ## [1.1.9-dev.001] - 2026-06-04
11
+
12
+ ### Fixed
13
+ - `textToHTML`: repeated formatting codes (e.g. `§l§l`) no longer produce duplicate CSS properties such as `font-weight: bold;font-weight: bold;`
14
+ - `textToJSON`: multiple simultaneous formatting codes (e.g. `§l§o`) now correctly produce all corresponding properties (`bold: true, italic: true`) instead of only the last one
15
+
16
+ ### Changed
17
+ - `textToHTML`: replaced string concatenation with a `Set`-based approach (`fontStyleSet`) to track active font styles, ensuring each CSS rule appears at most once per span
18
+ - `textToJSON`: replaced single-style overwrite logic with `fontStyleSet` accumulation; each text segment is now assigned all currently active styles directly
19
+ - `textToJSON`: removed the post-processing merge block; empty-text segments from adjacent style/color codes are now handled by a simple filter, simplifying the parser logic
20
+
21
+ ### Documentation
22
+ - README: added Quick Decision Table and restructured API Reference into Use Cases for easier navigation
23
+
24
+ ### Tests
25
+ - Added `textToHTML` tests: duplicate style prevention, multiple simultaneous styles, `§r` full reset, `§f` + style ordering
26
+ - Added `textToJSON` tests: multiple simultaneous styles (`§l§o`, `§l§m`), correct bold + strikethrough coexistence
27
+ - Updated `autoToHTML` snapshot to reflect deduplicated style output
28
+
29
+
30
+
10
31
  ## [1.1.5] - 2025-05-31
11
32
 
12
33
  ### Added
package/README.md CHANGED
@@ -7,20 +7,30 @@
7
7
 
8
8
  A powerful and lightweight library to parse Minecraft server MOTD (Message of the Day) data into various formats.
9
9
 
10
+ ## Quick Decision Table
10
11
 
12
+ Not sure which function to use? Find your use case below:
13
+
14
+ | What you want | Function | When to use |
15
+ |---------------|----------|------------|
16
+ | 🎯 **Convert to HTML** (any format) | `autoToHTML` | You don't know if input is text or JSON |
17
+ | 🎯 **Extract plain text** (any format) | `autoCleanToText` | You need clean text, format unknown |
18
+ | Format HTML from `§` text | `textToHTML` | Input is definitely `§` formatted text |
19
+ | Format HTML from JSON | `JSONToHTML` | Input is definitely a JSON object |
20
+ | Extract text from `§` text | `cleanCodes` | Remove § codes from text string |
21
+ | Extract text from JSON | `JSONToCleanedText` | Extract plain text from JSON object |
22
+ | Parse `§` text to JSON | `textToJSON` | Convert text format to JSON structure |
23
+
24
+ **Tip:** Start with the 🎯 marked functions if unsure. They auto-detect input format.
11
25
 
12
26
  ## Table of Contents
13
27
 
14
28
  - [Features](#features)
15
29
  - [Installation](#installation)
16
30
  - [Quick Start](#quick-start)
17
- - [API Reference](#api-reference)
18
- - [Auto Detection](#auto-detection)
19
- - [Text Parsing](#text-parsing)
20
- - [JSON Parsing](#json-parsing)
21
- - [Clean Text](#clean-text)
22
- - [Examples](#examples)
31
+ - [Use Cases](#use-cases)
23
32
  - [Visual Examples](#visual-examples)
33
+ - [Advanced API Reference](#advanced-api-reference)
24
34
  - [Contributing](#contributing)
25
35
 
26
36
 
@@ -55,117 +65,275 @@ pnpm add @sfirew/minecraft-motd-parser
55
65
 
56
66
  ## Quick Start
57
67
 
58
- ### ES6 Modules
68
+ Choose your import style:
69
+
70
+ **ES6 Modules**
59
71
  ```typescript
60
72
  import { autoToHTML } from '@sfirew/minecraft-motd-parser'
61
-
62
- const motd = "§aHypixel Network §7§c1.8/1.9/1.10/1.11/1.12 §e§lNEW PTL GAME:§b§l THE BRIDGE";
63
- const html = autoToHTML(motd);
64
- console.log(html);
65
73
  ```
66
74
 
67
- ### CommonJS
68
- ```typescript
69
- const { autoToHTML } = require('@sfirew/minecraft-motd-parser');
75
+ **CommonJS**
76
+ ```javascript
77
+ const { autoToHTML } = require('@sfirew/minecraft-motd-parser')
70
78
  ```
71
79
 
72
- ### Default Import
80
+ Then use it the same way:
81
+
73
82
  ```typescript
74
- import motdParser from '@sfirew/minecraft-motd-parser'
75
- motdParser.autoToHTML('motdString...');
83
+ const motd = "§aHypixel §7Network §c1.8-1.19";
84
+ const html = autoToHTML(motd);
85
+ // → <span style="color:#55FF55;">Hypixel </span><span style="color:#AAAAAA;">Network </span><span style="color:#FF5555;">1.8-1.19</span>
86
+
87
+ // Works with JSON too
88
+ const json = { text: "", extra: [{ color: "green", text: "Hello" }] };
89
+ console.log(autoToHTML(json)); // Detects format automatically
76
90
  ```
77
91
 
78
92
 
79
93
 
80
- ## API Reference
94
+ ## Use Cases
81
95
 
82
- ### Auto Detection
96
+ ### Converting to HTML
83
97
 
84
- #### `autoToHTML(data: string | object): string`
85
- Automatically detects the MOTD data type and converts it to HTML.
98
+ #### Automatic format detection (recommended for most cases)
86
99
 
87
100
  ```typescript
88
101
  import { autoToHTML } from '@sfirew/minecraft-motd-parser'
89
102
 
90
- // Works with both text and JSON formats
91
- const textMOTD = "§aHypixel Network §c1.8-1.19";
92
- const jsonMOTD = { text: "", extra: [{ color: "green", text: "Hello World" }] };
103
+ // Works with both text and JSON formats - detects automatically
104
+ const textMOTD = "§aHypixel §cNetwork";
105
+ const jsonMOTD = { text: "", extra: [{ color: "green", text: "Hello" }] };
93
106
 
94
- console.log(autoToHTML(textMOTD));
95
- console.log(autoToHTML(jsonMOTD));
107
+ console.log(autoToHTML(textMOTD)); // <span style="color:#55FF55;">Hypixel </span><span style="color:#FF5555;">Network</span>
108
+ console.log(autoToHTML(jsonMOTD)); // <span style="color:#55FF55;">Hello</span>
96
109
  ```
97
110
 
98
- #### `autoCleanToText(data: string | object): string`
99
- Automatically detects the MOTD data type and returns clean text without formatting codes.
111
+ #### From `§` formatted text
112
+
113
+ ```typescript
114
+ import { textToHTML } from '@sfirew/minecraft-motd-parser'
115
+
116
+ const motd = "§aGreen §lBold §rReset §cRed";
117
+ const html = textToHTML(motd);
118
+ ```
119
+
120
+ #### From JSON object
121
+
122
+ ```typescript
123
+ import { JSONToHTML, JSONRender } from '@sfirew/minecraft-motd-parser'
124
+
125
+ const motdJson = {
126
+ text: "",
127
+ extra: [
128
+ { color: "green", text: "Hello " },
129
+ { color: "blue", text: "World", bold: true }
130
+ ]
131
+ };
132
+
133
+ // JSONToHTML: strict type checking
134
+ const html1 = JSONToHTML(motdJson);
135
+
136
+ // JSONRender: works with any object (useful when parsing JSON from servers)
137
+ const serverResponse = JSON.parse(apiResponse);
138
+ const html2 = JSONRender(serverResponse);
139
+ ```
140
+
141
+ ### Extracting Plain Text
142
+
143
+ #### Automatic format detection
100
144
 
101
145
  ```typescript
102
146
  import { autoCleanToText } from '@sfirew/minecraft-motd-parser'
103
147
 
104
- const motd = "§aHypixel Network §c1.8-1.19";
105
- console.log(autoCleanToText(motd)); // "Hypixel Network 1.8-1.19"
148
+ const motd = "§aHypixel §c1.8-1.19";
149
+ console.log(autoCleanToText(motd)); // "Hypixel 1.8-1.19"
150
+
151
+ // Also works with JSON
152
+ const json = { text: "Welcome", extra: [{ text: " to Hypixel" }] };
153
+ console.log(autoCleanToText(json)); // "Welcome to Hypixel"
106
154
  ```
107
155
 
108
- ### Text Parsing
156
+ #### From `§` formatted text
109
157
 
110
- #### `textToHTML(text: string): string`
111
- Converts MOTD text format to HTML.
158
+ ```typescript
159
+ import { cleanCodes } from '@sfirew/minecraft-motd-parser'
160
+
161
+ const motd = "§aServer §bStatus";
162
+ const clean = cleanCodes(motd); // "Server Status"
163
+ ```
164
+
165
+ #### From JSON object
112
166
 
113
167
  ```typescript
114
- import { textToHTML } from '@sfirew/minecraft-motd-parser'
168
+ import { JSONToCleanedText } from '@sfirew/minecraft-motd-parser'
115
169
 
116
- const motd = "§aGreen §lBold §rReset §cRed";
117
- const html = textToHTML(motd);
118
- // Output: <span style="color:#55FF55;">Green <span style="font-weight:bold;">Bold </span></span><span style="color:#FF5555;">Red</span>
170
+ const motdJson = {
171
+ text: "Welcome",
172
+ extra: [{ color: "green", text: " to", bold: true }, { text: " Hypixel" }]
173
+ };
174
+ const text = JSONToCleanedText(motdJson); // "Welcome to Hypixel"
119
175
  ```
120
176
 
121
- #### `textToJSON(text: string): object`
122
- Converts MOTD text format to JSON structure.
177
+ ### Converting Format
178
+
179
+ #### Parse `§` text to JSON structure
123
180
 
124
181
  ```typescript
125
182
  import { textToJSON } from '@sfirew/minecraft-motd-parser'
126
183
 
127
184
  const motd = "§aHello §bWorld";
128
185
  const json = textToJSON(motd);
129
- console.log(json);
186
+ // → { text: "", extra: [{ color: "#55FF55", text: "Hello " }, { color: "#5555FF", text: "World" }] }
130
187
  ```
131
188
 
132
- ### JSON Parsing
189
+ ### Advanced: Data Sanitization
133
190
 
134
- #### `JSONToHTML(json: object): string`
135
- Converts MOTD JSON format to HTML.
191
+ #### Remove HTML tags safely (XSS prevention)
136
192
 
137
193
  ```typescript
138
- import { JSONToHTML } from '@sfirew/minecraft-motd-parser'
194
+ import { cleanHtmlTags } from '@sfirew/minecraft-motd-parser'
139
195
 
140
- const motdJson = {
196
+ const untrusted = '<span>Hello</span><script>alert("xss")</script> World';
197
+ const safe = cleanHtmlTags(untrusted); // "Hello World"
198
+ ```
199
+
200
+ #### Escape HTML special characters
201
+
202
+ ```typescript
203
+ import { htmlStringFormatting } from '@sfirew/minecraft-motd-parser'
204
+
205
+ const userInput = '<script>alert("xss")</script>';
206
+ const safe = htmlStringFormatting(userInput);
207
+ // → "&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;"
208
+ ```
209
+
210
+ #### Validate MOTD JSON format (TypeScript)
211
+
212
+ ```typescript
213
+ import { isMotdJSONType, JSONToHTML } from '@sfirew/minecraft-motd-parser'
214
+
215
+ const data: unknown = JSON.parse(response);
216
+ if (isMotdJSONType(data)) {
217
+ const html = JSONToHTML(data);
218
+ } else {
219
+ console.error('Invalid MOTD JSON format');
220
+ }
221
+ ```
222
+
223
+
224
+
225
+ ## Visual Examples
226
+
227
+ The parser supports rich formatting including colors, bold, italic, underline, and strikethrough text.
228
+
229
+ ### With Minecraft Font
230
+ ![Minecraft Font Example](https://user-images.githubusercontent.com/14024836/149810729-71909ca5-5705-43cf-ab3c-bdd66db00b78.png)
231
+
232
+ ### Standard Font
233
+ ![Standard Font Example](https://user-images.githubusercontent.com/14024836/149811501-d1376d90-d9ad-4092-912a-de1f78fa42eb.png)
234
+
235
+ > **Try it live**: Check out the [Minecraft Server Status Viewer](https://mcsv.top/server/mc.hypixel.net) to see the parser in action.
236
+
237
+ ## Advanced API Reference
238
+
239
+ Complete API documentation for all functions. Most users can stick with the [Use Cases](#use-cases) section above.
240
+
241
+ ### Core Functions
242
+
243
+ #### `autoToHTML(data: string | object): string`
244
+ Automatically detects MOTD data type (text or JSON) and converts to HTML.
245
+
246
+ ```typescript
247
+ const textResult = autoToHTML("§aGreen §lBold");
248
+ const jsonResult = autoToHTML({ color: "green", text: "Hello", bold: true });
249
+ ```
250
+
251
+ #### `autoCleanToText(data: string | object): string`
252
+ Automatically detects MOTD data type and returns plain text.
253
+
254
+ ```typescript
255
+ const text = autoCleanToText("§aServer §cStatus");
256
+ ```
257
+
258
+ #### `textToHTML(text: string): string`
259
+ Converts `§` formatted text to HTML.
260
+
261
+ ```typescript
262
+ const html = textToHTML("§aGreen §lBold §rReset §cRed");
263
+ ```
264
+
265
+ #### `textToJSON(text: string): object`
266
+ Parses `§` formatted text into JSON structure.
267
+
268
+ ```typescript
269
+ const json = textToJSON("§aHello §bWorld");
270
+ // → { text: "", extra: [{ color: "#55FF55", text: "Hello " }, ...] }
271
+ ```
272
+
273
+ #### `JSONToHTML(json: object): string`
274
+ Converts MOTD JSON object to HTML.
275
+
276
+ ```typescript
277
+ const html = JSONToHTML({
141
278
  text: "",
142
- extra: [
143
- { color: "green", text: "Hello " },
144
- { color: "blue", text: "World", bold: true }
145
- ]
146
- };
279
+ extra: [{ color: "green", text: "Hello", bold: true }]
280
+ });
281
+ ```
282
+
283
+ #### `JSONRender(json: object): string`
284
+ Type-loose wrapper around `JSONToHTML`. Accepts any object without strict type checking.
147
285
 
148
- const html = JSONToHTML(motdJson);
286
+ ```typescript
287
+ const serverData = JSON.parse(apiResponse);
288
+ const html = JSONRender(serverData);
149
289
  ```
150
290
 
151
- ### Clean Text
291
+ #### `JSONToCleanedText(json: object): string`
292
+ Extracts plain text from MOTD JSON object.
293
+
294
+ ```typescript
295
+ const text = JSONToCleanedText({
296
+ text: "Welcome",
297
+ extra: [{ text: " to Hypixel", color: "green" }]
298
+ });
299
+ // → "Welcome to Hypixel"
300
+ ```
301
+
302
+ ### Utility Functions
152
303
 
153
304
  #### `cleanCodes(text: string): string`
154
- Removes all formatting codes from MOTD text.
305
+ Removes all `§` formatting codes from text.
155
306
 
156
307
  ```typescript
157
- import { cleanCodes } from '@sfirew/minecraft-motd-parser'
308
+ const clean = cleanCodes("§aServer §bStatus"); // "Server Status"
309
+ ```
310
+
311
+ #### `cleanHtmlTags(text: string): string`
312
+ Safely removes HTML tags using FSM-based parsing. Dangerous tags (script, iframe, etc.) are removed along with their contents for XSS prevention.
158
313
 
159
- const motd = "§aHypixel Network §c1.8-1.19";
160
- const clean = cleanCodes(motd);
161
- console.log(clean); // "Hypixel Network 1.8-1.19"
314
+ ```typescript
315
+ const safe = cleanHtmlTags('<span>Hello</span><script>bad()</script>');
316
+ // "Hello"
162
317
  ```
163
318
 
319
+ #### `htmlStringFormatting(text: string): string`
320
+ Escapes HTML special characters to entities. Prevents double-encoding of existing entities.
164
321
 
322
+ ```typescript
323
+ const safe = htmlStringFormatting('<script>alert("xss")</script>');
324
+ // → "&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;"
325
+ ```
326
+
327
+ #### `isMotdJSONType(object: unknown): object is motdJsonType`
328
+ TypeScript type guard to validate MOTD JSON format.
165
329
 
166
- ## Examples
330
+ ```typescript
331
+ if (isMotdJSONType(data)) {
332
+ const html = JSONToHTML(data);
333
+ }
334
+ ```
167
335
 
168
- ### Complex MOTD with Multiple Formats
336
+ ### Complex Examples
169
337
 
170
338
  ```typescript
171
339
  import motdParser from '@sfirew/minecraft-motd-parser'
@@ -188,18 +356,6 @@ const jsonExample = {
188
356
  console.log(motdParser.autoToHTML(jsonExample));
189
357
  ```
190
358
 
191
- ## Visual Examples
192
-
193
- The parser supports rich formatting including colors, bold, italic, underline, and strikethrough text.
194
-
195
- ### With Minecraft Font
196
- ![Minecraft Font Example](https://user-images.githubusercontent.com/14024836/149810729-71909ca5-5705-43cf-ab3c-bdd66db00b78.png)
197
-
198
- ### Standard Font
199
- ![Standard Font Example](https://user-images.githubusercontent.com/14024836/149811501-d1376d90-d9ad-4092-912a-de1f78fa42eb.png)
200
-
201
- > **Try it live**: Check out the [Minecraft Server Status Viewer](https://mcsv.top/server/mc.hypixel.net) to see the parser in action.
202
-
203
359
  ## Contributing
204
360
 
205
361
  Contributions are welcome! Please feel free to submit a Pull Request.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var S=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames,k=Object.getOwnPropertySymbols;var R=Object.prototype.hasOwnProperty,X=Object.prototype.propertyIsEnumerable;var j=(t,e,o)=>e in t?S(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o,L=(t,e)=>{for(var o in e||(e={}))R.call(e,o)&&j(t,o,e[o]);if(k)for(var o of k(e))X.call(e,o)&&j(t,o,e[o]);return t};var K=(t,e)=>{for(var o in e)S(t,o,{get:e[o],enumerable:!0})},$=(t,e,o,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of _(e))!R.call(t,n)&&n!==o&&S(t,n,{get:()=>e[n],enumerable:!(s=J(e,n))||s.enumerable});return t};var G=t=>$(S({},"__esModule",{value:!0}),t);var I={};K(I,{JSONRender:()=>b,JSONToCleanedText:()=>y,JSONToHTML:()=>g,autoCleanToText:()=>C,autoToHTML:()=>O,baseColorCodeRegex:()=>u,cleanCodes:()=>m,cleanHtmlTags:()=>w,default:()=>B,htmlStringFormatting:()=>A,isMotdJSONType:()=>F,textToHTML:()=>x,textToJSON:()=>h});module.exports=G(I);var u=/([§][0-9a-fA-FklmnorKLMNOR])/g;function F(t){if(!t||typeof t!="object"||Array.isArray(t))return!1;let e="text"in t,o="translate"in t,s="extra"in t&&Array.isArray(t.extra);return e||o||s}function A(t){return!t||typeof t!="string"?"":t.replace(/&(?!(?:amp|lt|gt|quot|#39|#x[0-9A-Fa-f]+|#[0-9]+);)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/\n/g,"<br/>")}function w(t){if(!t||typeof t!="string")return"";let e="",o=new Set(["script","style","noscript","iframe","object","embed","applet","svg","math","foreignobject"]),s;(T=>(T[T.TEXT=0]="TEXT",T[T.TAG=1]="TAG",T[T.SKIP_BLOCK=2]="SKIP_BLOCK",T[T.COMMENT=3]="COMMENT"))(s||(s={}));let n=0,l="",f="",a=t.length;for(let r=0;r<a;r++){let p=t[r];if(n===0&&p==="<"){if(t.slice(r,r+4)==="<!--"){n=3;continue}let i=r+1,c=!1;for(i<a&&t[i]==="/"&&(c=!0,i++);i<a&&/\s/.test(t[i]);)i++;let T=i;for(;i<a&&/[A-Za-z0-9-]/.test(t[i]);)i++;l=t.slice(T,i).toLowerCase(),!c&&o.has(l)?(n=2,f=`</${l}>`):n=1;continue}if(n===1){p===">"&&(n=0);continue}if(n===3){t.slice(r,r+3)==="-->"&&(r+=2,n=0);continue}if(n===2){p==="<"&&t.slice(r,r+f.length).toLowerCase()===f&&(r+=f.length-1,n=0);continue}n===0&&(e+=p)}return e.trim()}function m(t){let e=/(?:§)([0-9a-fA-FklmnorFKLMNOR])/g,o="";return o=t.replace(e,""),o}var E={"\xA7k":"obfuscated;","\xA7l":"font-weight: bold;","\xA7m":"text-decoration: line-through;","\xA7n":"text-decoration: underline;","\xA7o":"font-style: italic;","\xA7r":"color: inherit;text-decoration: none !important;font-weight:normal!important;font-style: normal!important;"},H={bold:"font-weight: bold;",italic:"font-style: italic;",underlined:"text-decoration:underline;",strikethrough:"text-decoration: line-through;",obfuscated:"mc_obfuscated;",reset:"color: inherit;text-decoration: none !important;font-weight:normal!important;font-style: normal!important;"},M={"\xA7k":"obfuscated","\xA7l":"bold","\xA7m":"strikethrough","\xA7n":"underlined","\xA7o":"italic","\xA7r":"reset"},d={"\xA70":"#000000","\xA71":"#0000AA","\xA72":"#00AA00","\xA73":"#00AAAA","\xA74":"#AA0000","\xA75":"#AA00AA","\xA76":"#FFAA00","\xA77":"#AAAAAA","\xA78":"#555555","\xA79":"#5555FF","\xA7a":"#55FF55","\xA7b":"#55FFFF","\xA7c":"#FF5555","\xA7d":"#FF55FF","\xA7e":"#FFFF55","\xA7f":"#FFFFFF"},N={black:"#000000",dark_blue:"#0000AA",dark_green:"#00AA00",dark_aqua:"#00AAAA",dark_red:"#AA0000",dark_purple:"#AA00AA",gold:"#FFAA00",gray:"#AAAAAA",dark_gray:"#555555",blue:"#5555FF",green:"#55FF55",aqua:"#55FFFF",red:"#FF5555",light_purple:"#FF55FF",yellow:"#FFFF55",white:"#FFFFFF"};function x(t){let e=u,o=new RegExp(e.source),s=t.split(o).filter(a=>a!==""),n="",l="",f="";return s.forEach(a=>{let r=a.toLowerCase();if(Object.hasOwn(d,r))l=d[r],r==="\xA7f"&&(n="");else if(Object.hasOwn(E,r))r==="\xA7r"?(l="",n=""):n+=E[r];else{let p="",i=a;l!==""&&(p=`color:${l};`),i!==""&&(i=A(i),p.length!==0||n.length!==0?f+=`<span style="${p}${n}">${i}</span>`:f+=i)}}),f}function g(t){let e="",o="",s="";for(let l of Object.keys(t)){if(l=l.toLowerCase(),Object.hasOwn(H,l)&&t[l]&&(s+=String(H[l])),l==="color"){let f=t[l],a="";if(typeof f=="string")if(Object.hasOwn(N,f))a=N[f];else if(Object.hasOwn(d,f))a=d[f];else{let r=f.match(/^#([-+]?0+|\+?0*[1-9A-Fa-f][0-9A-Fa-f]{0,5})$/);r!==null&&(a="#"+r[1].replace(/^[-+]?0*/,"").padStart(6,"0"))}a!==""&&(o=`color:${a};`)}if(l==="extra"&&typeof t.extra=="object"){(typeof t.text=="string"||typeof t.text=="number")&&(e+=x(String(t.text)));for(let f of t.extra)typeof f=="string"?e+=x(f):F(f)&&(e+=g(f))}}if(t.extra===void 0&&t.text!==void 0){let l=t.text;(typeof t.text=="string"||typeof t.text=="number")&&(e+=x(String(l)))}let n="";return s.length!==0||o.length!==0?n=`<span style="${o+s}">${e}</span>`:n=e,n}function y(t){let e="";for(let o of Object.keys(t))if(o=o.toLowerCase(),o==="extra"&&typeof t.extra=="object"){(typeof t.text=="string"||typeof t.text=="number")&&(e+=m(String(t.text)));for(let s of t.extra)typeof s=="string"?e+=m(s):F(s)&&(e+=y(s))}if(t.extra===void 0&&t.text!==void 0){let o=t.text;(typeof t.text=="string"||typeof t.text=="number")&&(e+=m(String(o)))}return e}function h(t){let e=t,o=u,s=new RegExp(o.source),n=e.split(s),l="",f="",a={text:"",extra:[]};n.forEach(p=>{let i=p.toLowerCase();if(Object.hasOwn(d,i))f=d[i],i==="\xA7f"&&(l="");else if(Object.hasOwn(M,i))i==="\xA7r"?(l="",f=""):l=M[i];else{let c={text:"",extra:[]};l!==""&&(c[l]=!0),c.text=p,f!==""&&(c.color=f),typeof a.extra=="object"&&a.extra.push(c)}});let r=[];return a.extra&&(a.extra.length>1?a.extra.forEach((p,i)=>{var c;p.text===""?a.extra&&typeof a.extra[i+1]=="object"&&r.push(L(L({},p),a.extra[i+1])):p.text!==((c=r[r.length-1])==null?void 0:c.text)&&r.push(p)}):r.push(a.extra[0])),r=r.filter(p=>p.text!==""),{text:a.text,extra:r}}function b(t){return g(t)}function O(t){return typeof t=="object"?b(t):typeof t=="string"?x(t):"unknown motd data type"}function q(t){return typeof t=="object"?y(t):typeof t=="string"?m(t):"unknown motd data type"}var C=q;var P={textToHTML:x,textToJSON:h,JSONToHTML:g,JSONRender:b,autoToHTML:O,htmlStringFormatting:A,cleanCodes:m,cleanHtmlTags:w,JSONToCleanedText:y,autoCleanToText:C},B=P;0&&(module.exports={JSONRender,JSONToCleanedText,JSONToHTML,autoCleanToText,autoToHTML,baseColorCodeRegex,cleanCodes,cleanHtmlTags,htmlStringFormatting,isMotdJSONType,textToHTML,textToJSON});
1
+ var b=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames,k=Object.getOwnPropertySymbols;var R=Object.prototype.hasOwnProperty,X=Object.prototype.propertyIsEnumerable;var j=(t,e,o)=>e in t?b(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o,L=(t,e)=>{for(var o in e||(e={}))R.call(e,o)&&j(t,o,e[o]);if(k)for(var o of k(e))X.call(e,o)&&j(t,o,e[o]);return t};var K=(t,e)=>{for(var o in e)b(t,o,{get:e[o],enumerable:!0})},$=(t,e,o,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of _(e))!R.call(t,n)&&n!==o&&b(t,n,{get:()=>e[n],enumerable:!(s=J(e,n))||s.enumerable});return t};var G=t=>$(b({},"__esModule",{value:!0}),t);var I={};K(I,{JSONRender:()=>S,JSONToCleanedText:()=>y,JSONToHTML:()=>g,autoCleanToText:()=>C,autoToHTML:()=>O,baseColorCodeRegex:()=>u,cleanCodes:()=>m,cleanHtmlTags:()=>w,default:()=>B,htmlStringFormatting:()=>A,isMotdJSONType:()=>F,textToHTML:()=>c,textToJSON:()=>h});module.exports=G(I);var u=/([§][0-9a-fA-FklmnorKLMNOR])/g;function F(t){if(!t||typeof t!="object"||Array.isArray(t))return!1;let e="text"in t,o="translate"in t,s="extra"in t&&Array.isArray(t.extra);return e||o||s}function A(t){return!t||typeof t!="string"?"":t.replace(/&(?!(?:amp|lt|gt|quot|#39|#x[0-9A-Fa-f]+|#[0-9]+);)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/\n/g,"<br/>")}function w(t){if(!t||typeof t!="string")return"";let e="",o=new Set(["script","style","noscript","iframe","object","embed","applet","svg","math","foreignobject"]),s;(T=>(T[T.TEXT=0]="TEXT",T[T.TAG=1]="TAG",T[T.SKIP_BLOCK=2]="SKIP_BLOCK",T[T.COMMENT=3]="COMMENT"))(s||(s={}));let n=0,l="",i="",f=t.length;for(let r=0;r<f;r++){let p=t[r];if(n===0&&p==="<"){if(t.slice(r,r+4)==="<!--"){n=3;continue}let a=r+1,x=!1;for(a<f&&t[a]==="/"&&(x=!0,a++);a<f&&/\s/.test(t[a]);)a++;let T=a;for(;a<f&&/[A-Za-z0-9-]/.test(t[a]);)a++;l=t.slice(T,a).toLowerCase(),!x&&o.has(l)?(n=2,i=`</${l}>`):n=1;continue}if(n===1){p===">"&&(n=0);continue}if(n===3){t.slice(r,r+3)==="-->"&&(r+=2,n=0);continue}if(n===2){p==="<"&&t.slice(r,r+i.length).toLowerCase()===i&&(r+=i.length-1,n=0);continue}n===0&&(e+=p)}return e.trim()}function m(t){let e=/(?:§)([0-9a-fA-FklmnorFKLMNOR])/g,o="";return o=t.replace(e,""),o}var E={"\xA7k":"obfuscated;","\xA7l":"font-weight: bold;","\xA7m":"text-decoration: line-through;","\xA7n":"text-decoration: underline;","\xA7o":"font-style: italic;","\xA7r":"color: inherit;text-decoration: none !important;font-weight:normal!important;font-style: normal!important;"},H={bold:"font-weight: bold;",italic:"font-style: italic;",underlined:"text-decoration:underline;",strikethrough:"text-decoration: line-through;",obfuscated:"mc_obfuscated;",reset:"color: inherit;text-decoration: none !important;font-weight:normal!important;font-style: normal!important;"},M={"\xA7k":"obfuscated","\xA7l":"bold","\xA7m":"strikethrough","\xA7n":"underlined","\xA7o":"italic","\xA7r":"reset"},d={"\xA70":"#000000","\xA71":"#0000AA","\xA72":"#00AA00","\xA73":"#00AAAA","\xA74":"#AA0000","\xA75":"#AA00AA","\xA76":"#FFAA00","\xA77":"#AAAAAA","\xA78":"#555555","\xA79":"#5555FF","\xA7a":"#55FF55","\xA7b":"#55FFFF","\xA7c":"#FF5555","\xA7d":"#FF55FF","\xA7e":"#FFFF55","\xA7f":"#FFFFFF"},N={black:"#000000",dark_blue:"#0000AA",dark_green:"#00AA00",dark_aqua:"#00AAAA",dark_red:"#AA0000",dark_purple:"#AA00AA",gold:"#FFAA00",gray:"#AAAAAA",dark_gray:"#555555",blue:"#5555FF",green:"#55FF55",aqua:"#55FFFF",red:"#FF5555",light_purple:"#FF55FF",yellow:"#FFFF55",white:"#FFFFFF"};function c(t){let e=u,o=new RegExp(e.source),s=t.split(o).filter(f=>f!==""),n=new Set,l="",i="";return s.forEach(f=>{let r=f.toLowerCase();if(Object.hasOwn(d,r))l=d[r];else if(Object.hasOwn(E,r))r==="\xA7r"?(l="",n.clear()):n.add(E[r]);else{let p="",a=f;if(l!==""&&(p=`color:${l};`),a!==""){a=A(a);let x=Array.from(n).join("");p.length!==0||x.length!==0?i+=`<span style="${p}${x}">${a}</span>`:i+=a}}}),i}function g(t){let e="",o="",s="";for(let l of Object.keys(t)){if(l=l.toLowerCase(),Object.hasOwn(H,l)&&t[l]&&(s+=H[l]),l==="color"){let i=t[l],f="";if(typeof i=="string")if(Object.hasOwn(N,i))f=N[i];else if(Object.hasOwn(d,i))f=d[i];else{let r=i.match(/^#([-+]?0+|\+?0*[1-9A-Fa-f][0-9A-Fa-f]{0,5})$/);r!==null&&(f="#"+r[1].replace(/^[-+]?0*/,"").padStart(6,"0"))}f!==""&&(o=`color:${f};`)}if(l==="extra"&&typeof t.extra=="object"){(typeof t.text=="string"||typeof t.text=="number")&&(e+=c(String(t.text)));for(let i of t.extra)typeof i=="string"?e+=c(i):F(i)&&(e+=g(i))}}if(t.extra===void 0&&t.text!==void 0){let l=t.text;(typeof t.text=="string"||typeof t.text=="number")&&(e+=c(String(l)))}let n="";return s.length!==0||o.length!==0?n=`<span style="${o+s}">${e}</span>`:n=e,n}function y(t){let e="";for(let o of Object.keys(t))if(o=o.toLowerCase(),o==="extra"&&typeof t.extra=="object"){(typeof t.text=="string"||typeof t.text=="number")&&(e+=m(String(t.text)));for(let s of t.extra)typeof s=="string"?e+=m(s):F(s)&&(e+=y(s))}if(t.extra===void 0&&t.text!==void 0){let o=t.text;(typeof t.text=="string"||typeof t.text=="number")&&(e+=m(String(o)))}return e}function h(t){let e=u,o=new RegExp(e.source),s=t.split(o),n=new Set,l="",i={text:"",extra:[]};s.forEach(r=>{let p=r.toLowerCase();if(Object.hasOwn(d,p))l=d[p];else if(Object.hasOwn(M,p))p==="\xA7r"?(n.clear(),l=""):n.add(M[p]);else{let a={text:"",extra:[]};for(let x of n)a[x]=!0;a.text=r,l!==""&&(a.color=l),typeof i.extra=="object"&&i.extra.push(a)}});let f=[];if(i.extra&&i.extra.length>0){let r=i.extra;r.length>1?r.forEach((p,a)=>{var x;p.text===""?r&&typeof r[a+1]=="object"&&f.push(L(L({},p),r[a+1])):p.text!==((x=f[f.length-1])==null?void 0:x.text)&&f.push(p)}):f.push(r[0])}return f=f.filter(r=>r.text!==""),{text:i.text,extra:f}}function S(t){return g(t)}function O(t){return typeof t=="object"?S(t):typeof t=="string"?c(t):"unknown motd data type"}function q(t){return typeof t=="object"?y(t):typeof t=="string"?m(t):"unknown motd data type"}var C=q;var P={textToHTML:c,textToJSON:h,JSONToHTML:g,JSONRender:S,autoToHTML:O,htmlStringFormatting:A,cleanCodes:m,cleanHtmlTags:w,JSONToCleanedText:y,autoCleanToText:C},B=P;0&&(module.exports={JSONRender,JSONToCleanedText,JSONToHTML,autoCleanToText,autoToHTML,baseColorCodeRegex,cleanCodes,cleanHtmlTags,htmlStringFormatting,isMotdJSONType,textToHTML,textToJSON});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/styleLibrary.ts","../src/parser/textToHTML.ts","../src/parser/JSONToHTML.ts","../src/parser/JSONToCleanedText.ts","../src/parser/textToJSON.ts","../src/parser/autoToHTML.ts","../src/parser/autoCleanToText.ts"],"sourcesContent":["/*\n * minecraft motd parser\n * (c) 2021 Kevin Zheng\n * Released under the MIT license\n */\nimport {\n htmlStringFormatting,\n cleanCodes,\n cleanHtmlTags,\n} from \"./utils\";\nimport {\n JSONToHTML,\n JSONToCleanedText,\n\n textToHTML,\n textToJSON,\n\n JSONRender,\n autoToHTML,\n autoCleanToText,\n} from \"./parser\";\n\n\n\n\n\n\nexport * from \"./utils\";\nexport * from \"./parser\";\n\n\n\n/*\n * #### minecraft motd parser\n * * [github](https://github.com/SnowFireWolf/minecraft-motd-parser/tree/main#minecraft-server-motd-parser)\n * * [npm](https://www.npmjs.com/package/@sfirew/minecraft-motd-parser)\n *\n * (c) 2021 Kevin Zheng\n *\n * Released under the MIT license\n */\nconst motdParser = {\n // --- normal format ---\n // text convert to HTML\n textToHTML,\n // text convert to JSON\n textToJSON,\n // JSON convert to HTML\n JSONToHTML,\n // JSON string to JSON object and convert to HTML\n JSONRender,\n // auto check type to convert\n autoToHTML,\n\n // --- utils ---\n // html string formatter\n htmlStringFormatting,\n // clean all motd codes\n cleanCodes,\n // clean all html tags\n cleanHtmlTags,\n // json to not html text\n JSONToCleanedText,\n // auto check type and convert to cleaned text\n autoCleanToText,\n};\n\nexport default motdParser;\n","/*\n * minecraft motd parser\n * (c) 2023 Kevin Zheng\n * Released under the MIT license\n */\n\nimport { motdJsonType } from \"./types\";\n\n\n\n\n/**\n * Base color code regex\n */\nexport const baseColorCodeRegex = /([§][0-9a-fA-FklmnorKLMNOR])/g;\n\n\n\n// Type checking function\nexport function isMotdJSONType(object: unknown): object is motdJsonType {\n // basic type check\n if (!object || typeof object !== \"object\" || Array.isArray(object)) {\n return false;\n }\n\n // check if has necessary property\n const hasText = \"text\" in object;\n const hasTranslate = \"translate\" in object;\n const hasExtra = \"extra\" in object && Array.isArray(object.extra);\n\n // MOTD JSON at least need one of text, translate or extra\n return hasText || hasTranslate || hasExtra;\n}\n\n\n\n/**\n * Replace all HTML special characters with HTML entities\n * Prevents HTML injection by safely encoding special characters\n */\nexport function htmlStringFormatting(text: string): string {\n if (!text || typeof text !== \"string\") {\n return \"\";\n }\n\n return (\n text\n // First handle & character, but avoid breaking existing HTML entities\n // Use negative lookahead to prevent double-encoding existing HTML entities\n .replace(/&(?!(?:amp|lt|gt|quot|#39|#x[0-9A-Fa-f]+|#[0-9]+);)/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\")\n // Convert newlines to HTML line breaks\n .replace(/\\n/g, \"<br/>\")\n );\n};\n\n\n\n/**\n * Clean HTML tags safely\n * \n * Safely removes HTML tags and prevents HTML injection vulnerabilities.\n * \n * @param text - Input text that may contain HTML tags\n * @example `<span>hello world</span>` → `hello world`\n * \n * @returns Clean text without HTML tags\n */\nexport function cleanHtmlTags(text: string): string {\n if (!text || typeof text !== \"string\") {\n return \"\";\n }\n\n let cleanedText = \"\";\n\n // === Config ===\n const DANGEROUS_TAGS = new Set([\n \"script\", \"style\", \"noscript\",\n \"iframe\", \"object\", \"embed\", \"applet\",\n \"svg\", \"math\", \"foreignobject\",\n ]);\n\n // === FSM States ===\n enum State {\n TEXT, // Normal text\n TAG, // Currently consuming a normal tag until >\n SKIP_BLOCK, // Currently skipping dangerous block until </tag>\n COMMENT // HTML comment <!-- ... -->\n }\n\n let state = State.TEXT;\n let tagName = \"\"; // Temporary storage for encountered tag name\n let skipUntil = \"\"; // Corresponding \"</tag>\" for dangerous block\n const len = text.length;\n\n for (let i = 0; i < len; i++) {\n const ch = text[i];\n\n /* --------------- TEXT -> TAG/COMMENT --------------- */\n if (state === State.TEXT && ch === \"<\") {\n // Check if it's an HTML comment\n if (text.slice(i, i + 4) === \"<!--\") {\n state = State.COMMENT;\n continue;\n }\n\n // Try to extract tag name\n let j = i + 1;\n let isClosing = false;\n\n // Skip '/'\n if (j < len && text[j] === \"/\") {\n isClosing = true;\n j++;\n }\n // Skip whitespace\n while (j < len && /\\s/.test(text[j])) j++;\n\n // Extract tagName (a~z or A~Z or 0-9 or -)\n const start = j;\n while (j < len && /[A-Za-z0-9-]/.test(text[j])) j++;\n\n tagName = text.slice(start, j).toLowerCase();\n\n /* Dangerous block ── only \"opening tag\" starts skip */\n if (!isClosing && DANGEROUS_TAGS.has(tagName)) {\n state = State.SKIP_BLOCK;\n skipUntil = `</${tagName}>`;\n } else {\n state = State.TAG;\n }\n continue;\n }\n\n /* --------------- TAG -> TEXT --------------- */\n if (state === State.TAG) {\n if (ch === \">\") state = State.TEXT;\n // Don't write to output\n continue;\n }\n\n /* --------------- COMMENT -> TEXT --------------- */\n if (state === State.COMMENT) {\n // Check for comment end -->\n if (text.slice(i, i + 3) === \"-->\") {\n i += 2; // Skip '-->'\n state = State.TEXT;\n }\n continue;\n }\n\n /* --------------- SKIP_BLOCK Logic --------------- */\n if (state === State.SKIP_BLOCK) {\n // Transition: SKIP_BLOCK -> TEXT\n // Check if the current segment matches the end tag (e.g., </script>)\n if (\n ch === \"<\" &&\n text.slice(i, i + skipUntil.length).toLowerCase() === skipUntil\n ) {\n // Skip the entire end tag (case-insensitive match)\n i += skipUntil.length - 1;\n state = State.TEXT; // Return to TEXT state\n }\n continue; // Consume all content until the end tag is found\n }\n\n /* --------------- TEXT State: Normal output --------------- */\n if (state === State.TEXT) {\n cleanedText += ch;\n }\n }\n\n return cleanedText.trim();\n}\n\n\n\n/**\n * Clean MOTD color codes\n * \n * Clean all formatting codes from MOTD source string.\n * \n * @param {string} text - MOTD string with § formatting codes to be removed\n * @returns {string} Text without MOTD formatting codes\n */\nexport function cleanCodes(text: string): string {\n const REGEX = /(?:§)([0-9a-fA-FklmnorFKLMNOR])/g;\n let textResult = \"\";\n\n textResult = text.replace(REGEX, \"\");\n\n return textResult;\n};\n","import { extraLibraryType } from \"./types\";\n\n\n\n// color code to font styles\nconst extras: extraLibraryType = {\n \"§k\": \"obfuscated;\",\n \"§l\": \"font-weight: bold;\",\n \"§m\": \"text-decoration: line-through;\",\n \"§n\": \"text-decoration: underline;\",\n \"§o\": \"font-style: italic;\",\n \"§r\": \"color: inherit;text-decoration: none !important;font-weight:normal!important;font-style: normal!important;\",\n};\n\n// json extra font styles\nconst extraFontStyles: extraLibraryType = {\n bold: \"font-weight: bold;\",\n italic: \"font-style: italic;\",\n underlined: \"text-decoration:underline;\",\n strikethrough: \"text-decoration: line-through;\",\n obfuscated: \"mc_obfuscated;\",\n reset: \"color: inherit;text-decoration: none !important;font-weight:normal!important;font-style: normal!important;\",\n};\n\n// text to json extra name\nconst textToJsonExtras: extraLibraryType = {\n \"§k\": \"obfuscated\",\n \"§l\": \"bold\",\n \"§m\": \"strikethrough\",\n \"§n\": \"underlined\",\n \"§o\": \"italic\",\n \"§r\": \"reset\",\n};\n\n// base color hex\nconst colorCodeToHex: extraLibraryType = {\n \"§0\": \"#000000\",\n \"§1\": \"#0000AA\",\n \"§2\": \"#00AA00\",\n \"§3\": \"#00AAAA\",\n \"§4\": \"#AA0000\",\n \"§5\": \"#AA00AA\",\n \"§6\": \"#FFAA00\",\n \"§7\": \"#AAAAAA\",\n \"§8\": \"#555555\",\n \"§9\": \"#5555FF\",\n \"§a\": \"#55FF55\",\n \"§b\": \"#55FFFF\",\n \"§c\": \"#FF5555\",\n \"§d\": \"#FF55FF\",\n \"§e\": \"#FFFF55\",\n \"§f\": \"#FFFFFF\",\n};\n\n// json extra to hex color\nconst extraColorsToHex: extraLibraryType = {\n black: \"#000000\",\n dark_blue: \"#0000AA\",\n dark_green: \"#00AA00\",\n dark_aqua: \"#00AAAA\",\n dark_red: \"#AA0000\",\n dark_purple: \"#AA00AA\",\n gold: \"#FFAA00\",\n gray: \"#AAAAAA\",\n dark_gray: \"#555555\",\n blue: \"#5555FF\",\n green: \"#55FF55\",\n aqua: \"#55FFFF\",\n red: \"#FF5555\",\n light_purple: \"#FF55FF\",\n yellow: \"#FFFF55\",\n white: \"#FFFFFF\",\n};\n\n\n\nexport {\n extras,\n extraFontStyles,\n textToJsonExtras,\n colorCodeToHex,\n extraColorsToHex,\n};\n","import {\n extras,\n colorCodeToHex,\n} from \"../styleLibrary\";\nimport {\n htmlStringFormatting,\n baseColorCodeRegex,\n} from \"../utils\";\n\n\n\n/**\n * Convert motd text to html.\n * @param motdString\n */\nexport default function textToHTML(motdString: string) {\n const colorCodeReg = baseColorCodeRegex;\n const codeREGEX = new RegExp(colorCodeReg.source);\n const codeSplit = motdString.split(codeREGEX).filter(item => item !== \"\");\n\n let fontStyle = \"\";\n let colorHex = \"\";\n let resultHTML = \"\";\n\n codeSplit.forEach((item) => {\n const motdStringToLowerCase = item.toLowerCase();\n // console.log('motdStringToLowerCase', motdStringToLowerCase);\n\n // 過濾 hex\n if (Object.hasOwn(colorCodeToHex, motdStringToLowerCase)) {\n //console.log(`偵測出 ${ colorCodeToHex[item] }`)\n colorHex = colorCodeToHex[motdStringToLowerCase];\n\n // §f reset\n if(motdStringToLowerCase === \"§f\") {\n fontStyle = \"\";\n }\n // 過濾文字 style\n } else if (Object.hasOwn(extras, motdStringToLowerCase)) {\n if(motdStringToLowerCase === \"§r\") {\n colorHex = \"\";\n fontStyle = \"\";\n } else {\n // font style code 轉換\n // console.log(`偵測出 style ${ extras[motdStringToLowerCase] }`);\n fontStyle += extras[motdStringToLowerCase];\n }\n // console.log('motdStringToLowerCase', motdStringToLowerCase);\n // console.log('textFont: ' + fontStyle);\n // 正常文字\n } else {\n let resultColor = \"\";\n let textContent = item;\n //console.log(fontStyle)\n\n // 檢查 Hex color\n if (colorHex !== \"\") {\n resultColor = `color:${colorHex};`;\n }\n\n if (textContent !== \"\") {\n //console.log('font: ' + fontStyle)\n //console.log('color: ' + colorHex)\n //console.log('text: ' + item)\n //console.log('---------------------------------')\n // replace html tags\n textContent = htmlStringFormatting(textContent);\n\n if (resultColor.length !== 0 || fontStyle.length !== 0) {\n resultHTML += `<span style=\"${resultColor}${fontStyle}\">${textContent}</span>`;\n } else {\n resultHTML += textContent;\n }\n }\n }\n });\n\n return resultHTML;\n}\n","import { motdJsonType } from \"../types\";\nimport {\n extraFontStyles,\n colorCodeToHex,\n extraColorsToHex,\n} from \"../styleLibrary\";\nimport {\n isMotdJSONType,\n} from \"../utils\";\nimport textToHTML from \"./textToHTML\";\n\n\n\n/**\n * Convert JSON to HTML.\n * \n * @param sourceJson\n */\nexport default function parseJSONToHTML(\n sourceJson: motdJsonType,\n) {\n let htmlElement = \"\";\n let colorStyle = \"\";\n let fontStyle = \"\";\n\n // console.log('sourceJson', sourceJson);\n // console.log('---------');\n\n for (let key of Object.keys(sourceJson)) {\n // console.log('sourceJson key', key);\n key = key.toLowerCase();\n\n // text styles\n if (Object.hasOwn(extraFontStyles, key)) {\n if (sourceJson[key]) {\n fontStyle += String(extraFontStyles[key]);\n }\n }\n\n // ---------- old text process ----------\n // if (key === \"text\") {\n // if (\n // typeof sourceJson.text === \"string\" ||\n // typeof sourceJson.text === \"number\"\n // ) {\n // // convert all type to string\n // htmlElement += textToHTML(String(sourceJson.text));\n // }\n // }\n\n // color\n if (key === \"color\") {\n const colorKey = sourceJson[key];\n let colorHex = \"\";\n\n if (typeof colorKey === \"string\") {\n // Hex color\n if (Object.hasOwn(extraColorsToHex, colorKey)) {\n colorHex = extraColorsToHex[colorKey];\n // color code\n } else if (Object.hasOwn(colorCodeToHex, colorKey)) {\n colorHex = colorCodeToHex[colorKey];\n // custom color\n } else {\n const customHexColorMatches = colorKey.match(\n /^#([-+]?0+|\\+?0*[1-9A-Fa-f][0-9A-Fa-f]{0,5})$/,\n );\n\n if (customHexColorMatches !== null) {\n // custom hex color code mode\n colorHex =\n \"#\" +\n customHexColorMatches[1].replace(/^[-+]?0*/, \"\").padStart(6, \"0\");\n }\n }\n }\n\n if(colorHex !== \"\") {\n colorStyle = `color:${colorHex};`;\n }\n }\n\n // extra\n if (key === \"extra\" && typeof sourceJson.extra === \"object\") {\n // ---------- with extra text ----------\n if (typeof sourceJson.text === \"string\" || typeof sourceJson.text === \"number\") {\n // content to html\n htmlElement += textToHTML(String(sourceJson.text));\n }\n\n // ---------- foreach extra data and parse ----------\n for (const sourceJsonExtra of sourceJson.extra) {\n // console.log('sourceJsonExtra', sourceJsonExtra);\n if (typeof sourceJsonExtra === \"string\") {\n // Process string elements directly with textToHTML\n htmlElement += textToHTML(sourceJsonExtra);\n } else if (isMotdJSONType(sourceJsonExtra)) {\n htmlElement += parseJSONToHTML(sourceJsonExtra);\n }\n }\n }\n }\n\n // ---------- without extra text content ----------\n if (sourceJson.extra === undefined && sourceJson.text !== undefined) {\n const currentText = sourceJson.text;\n if (\n typeof sourceJson.text === \"string\" ||\n typeof sourceJson.text === \"number\"\n ) {\n // convert all type to string\n htmlElement += textToHTML(String(currentText));\n }\n }\n\n\n\n let returnHTML = \"\";\n if (fontStyle.length !== 0 || colorStyle.length !== 0) {\n returnHTML = `<span style=\"${colorStyle + fontStyle}\">${htmlElement}</span>`;\n } else {\n returnHTML = htmlElement;\n }\n\n return returnHTML;\n}\n","import { motdJsonType } from \"../types\";\nimport {\n isMotdJSONType,\n cleanCodes\n} from \"../utils\";\n\n\n\n/**\n * Convert JSON to Cleaned Text.\n * \n * @param sourceJson\n */\nexport default function JSONToCleanedText(\n sourceJson: motdJsonType,\n) {\n let textString = \"\";\n\n for (let key of Object.keys(sourceJson)) {\n key = key.toLowerCase();\n\n // extra\n if (key === \"extra\" && typeof sourceJson.extra === \"object\") {\n // ---------- with extra text ----------\n if (typeof sourceJson.text === \"string\" || typeof sourceJson.text === \"number\") {\n // content to html\n textString += cleanCodes(String(sourceJson.text));\n }\n\n // ---------- foreach extra data and parse ----------\n for (const sourceJsonExtra of sourceJson.extra) {\n // console.log('sourceJsonExtra', sourceJsonExtra);\n if (typeof sourceJsonExtra === \"string\") {\n // Add string elements directly to the output\n textString += cleanCodes(sourceJsonExtra);\n } else if (isMotdJSONType(sourceJsonExtra)) {\n textString += JSONToCleanedText(sourceJsonExtra);\n }\n }\n }\n }\n\n // ---------- without extra text content ----------\n if (sourceJson.extra === undefined && sourceJson.text !== undefined) {\n const currentText = sourceJson.text;\n if (\n typeof sourceJson.text === \"string\" ||\n typeof sourceJson.text === \"number\"\n ) {\n // convert all type to string\n textString += cleanCodes(String(currentText));\n }\n }\n\n return textString;\n}\n","import { motdJsonType } from \"../types\";\nimport {\n textToJsonExtras,\n colorCodeToHex,\n} from \"../styleLibrary\";\nimport { baseColorCodeRegex } from \"../utils\";\n\n\n\n/**\n * Convert motd text to JSON.\n * \n * @param text\n */\nexport default function parseTextToJSON(text: string) {\n const motdText = text;\n\n const colorCodeReg = baseColorCodeRegex;\n const codeREGEX = new RegExp(colorCodeReg.source);\n const textSplit = motdText.split(codeREGEX);\n let fontStyle = \"\";\n let colorHex = \"\";\n\n const resultObject: motdJsonType = {\n text: \"\",\n extra: [],\n };\n\n // console.log('textSplit', textSplit);\n textSplit.forEach((item) => {\n const stringToLowerCase = item.toLowerCase();\n\n // color code 轉換成 hex\n if (Object.hasOwn(colorCodeToHex, stringToLowerCase)) {\n //console.log(`偵測出 ${ colorCodeToHex[item] }`)\n colorHex = colorCodeToHex[stringToLowerCase];\n // §f reset\n if(stringToLowerCase === \"§f\") {\n fontStyle = \"\";\n }\n } else if (Object.hasOwn(textToJsonExtras, stringToLowerCase)) {\n if(stringToLowerCase === \"§r\") {\n fontStyle = \"\";\n colorHex = \"\";\n } else {\n // font style code 轉換\n //console.log(`偵測出 style ${ textToJsonExtras[item] }`)\n fontStyle = textToJsonExtras[stringToLowerCase];\n }\n } else {\n const innerObject: motdJsonType = {\n text: \"\",\n extra: [],\n };\n\n // 其餘字串\n if (fontStyle !== \"\") {\n innerObject[fontStyle] = true;\n }\n\n innerObject.text = item;\n\n if (colorHex !== \"\") {\n innerObject.color = colorHex;\n }\n\n if (typeof resultObject.extra === \"object\") {\n resultObject.extra.push(innerObject);\n }\n }\n });\n\n // code styles merge\n let newExtra: motdJsonType[] = [];\n // console.log('resultObject', resultObject);\n if (resultObject.extra) {\n if (resultObject.extra.length > 1) {\n // if text is '', remove it and merge to next array\n resultObject.extra.forEach((item, index) => {\n // console.log('item', item);\n if (item.text === \"\") {\n if (\n resultObject.extra\n && typeof resultObject.extra[index + 1] === \"object\"\n ) {\n newExtra.push({\n ...(item as motdJsonType),\n ...resultObject.extra[index + 1],\n });\n }\n } else {\n if (\n item.text !== newExtra[newExtra.length - 1]?.text\n ) {\n newExtra.push(item as motdJsonType);\n }\n }\n });\n } else {\n newExtra.push(resultObject.extra[0] as motdJsonType);\n }\n }\n\n // console.log('newExtra', newExtra);\n // remove blank content\n newExtra = newExtra.filter((item) => item.text !== \"\");\n // console.log('newExtra', newExtra);\n\n return {\n text: resultObject.text,\n extra: newExtra,\n };\n}\n","import { motdJsonType } from \"../types\";\nimport {\n JSONToHTML,\n textToHTML,\n} from \"./\";\n\n\n\n// make sure JSON data is JSON object and then convert.\nexport function JSONRender(json: object) {\n return JSONToHTML(json as motdJsonType);\n}\n\n/**\n * auto check data type then convert to html.\n */\nexport function autoToHTML(motd: string | object): string {\n // type check\n if (typeof motd === \"object\") {\n // console.log('process mode: Object mode');\n return JSONRender(motd);\n } else if (typeof motd === \"string\") {\n // console.log('process mode: String mode');\n // console.log('textToJSON(motd)', textToJSON(motd));\n return textToHTML(motd);\n // return jsonRender(textToJSON(motd));\n } else {\n return \"unknown motd data type\";\n }\n}\n\n\n\nexport default autoToHTML;\n","import { motdJsonType } from \"../types\";\nimport {\n JSONToCleanedText,\n} from \".\";\nimport { cleanCodes } from \"../utils\";\n\n\n\n/**\n * auto check data type then convert to html.\n */\nexport function autoCleanToText(motd: string | object): string {\n // type check\n if (typeof motd === \"object\") {\n // console.log('process mode: Object mode');\n return JSONToCleanedText(motd as motdJsonType);\n } else if (typeof motd === \"string\") {\n // console.log('process mode: String mode');\n return cleanCodes(motd);\n } else {\n return \"unknown motd data type\";\n }\n}\n\n\n\nexport default autoCleanToText;\n"],"mappings":"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","names":["index_exports","__export","JSONRender","JSONToCleanedText","parseJSONToHTML","autoCleanToText_default","autoToHTML","baseColorCodeRegex","cleanCodes","cleanHtmlTags","index_default","htmlStringFormatting","isMotdJSONType","textToHTML","parseTextToJSON","__toCommonJS","baseColorCodeRegex","isMotdJSONType","object","hasText","hasTranslate","hasExtra","htmlStringFormatting","text","cleanHtmlTags","cleanedText","DANGEROUS_TAGS","State","state","tagName","skipUntil","len","i","ch","j","isClosing","start","cleanCodes","REGEX","textResult","extras","extraFontStyles","textToJsonExtras","colorCodeToHex","extraColorsToHex","textToHTML","motdString","colorCodeReg","baseColorCodeRegex","codeREGEX","codeSplit","item","fontStyle","colorHex","resultHTML","motdStringToLowerCase","colorCodeToHex","extras","resultColor","textContent","htmlStringFormatting","parseJSONToHTML","sourceJson","htmlElement","colorStyle","fontStyle","key","extraFontStyles","colorKey","colorHex","extraColorsToHex","colorCodeToHex","customHexColorMatches","textToHTML","sourceJsonExtra","isMotdJSONType","currentText","returnHTML","JSONToCleanedText","sourceJson","textString","key","cleanCodes","sourceJsonExtra","isMotdJSONType","currentText","parseTextToJSON","text","motdText","colorCodeReg","baseColorCodeRegex","codeREGEX","textSplit","fontStyle","colorHex","resultObject","item","stringToLowerCase","colorCodeToHex","textToJsonExtras","innerObject","newExtra","index","_a","__spreadValues","JSONRender","json","parseJSONToHTML","autoToHTML","motd","textToHTML","autoCleanToText","motd","JSONToCleanedText","cleanCodes","autoCleanToText_default","motdParser","textToHTML","parseTextToJSON","parseJSONToHTML","JSONRender","autoToHTML","htmlStringFormatting","cleanCodes","cleanHtmlTags","JSONToCleanedText","autoCleanToText_default","index_default"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/styleLibrary.ts","../src/parser/textToHTML.ts","../src/parser/JSONToHTML.ts","../src/parser/JSONToCleanedText.ts","../src/parser/textToJSON.ts","../src/parser/autoToHTML.ts","../src/parser/autoCleanToText.ts"],"sourcesContent":["/*\n * minecraft motd parser\n * (c) 2021 Kevin Zheng\n * Released under the MIT license\n */\nimport {\n htmlStringFormatting,\n cleanCodes,\n cleanHtmlTags,\n} from \"./utils\";\nimport {\n JSONToHTML,\n JSONToCleanedText,\n\n textToHTML,\n textToJSON,\n\n JSONRender,\n autoToHTML,\n autoCleanToText,\n} from \"./parser\";\n\n\n\n\n\n\nexport * from \"./utils\";\nexport * from \"./parser\";\n\n\n\nconst motdParser = {\n textToHTML,\n textToJSON,\n JSONToHTML,\n JSONRender,\n autoToHTML,\n htmlStringFormatting,\n cleanCodes,\n cleanHtmlTags,\n JSONToCleanedText,\n autoCleanToText,\n};\n\nexport default motdParser;\n","/*\n * minecraft motd parser\n * (c) 2023 Kevin Zheng\n * Released under the MIT license\n */\n\nimport { motdJsonType } from \"./types\";\n\n\n\n\n/**\n * Base color code regex\n */\nexport const baseColorCodeRegex = /([§][0-9a-fA-FklmnorKLMNOR])/g;\n\n\n\n// Type checking function\nexport function isMotdJSONType(object: unknown): object is motdJsonType {\n // basic type check\n if (!object || typeof object !== \"object\" || Array.isArray(object)) {\n return false;\n }\n\n // check if has necessary property\n const hasText = \"text\" in object;\n const hasTranslate = \"translate\" in object;\n const hasExtra = \"extra\" in object && Array.isArray(object.extra);\n\n // MOTD JSON at least need one of text, translate or extra\n return hasText || hasTranslate || hasExtra;\n}\n\n\n\n/**\n * Replace all HTML special characters with HTML entities\n * Prevents HTML injection by safely encoding special characters\n */\nexport function htmlStringFormatting(text: string): string {\n if (!text || typeof text !== \"string\") {\n return \"\";\n }\n\n return (\n text\n // First handle & character, but avoid breaking existing HTML entities\n // Use negative lookahead to prevent double-encoding existing HTML entities\n .replace(/&(?!(?:amp|lt|gt|quot|#39|#x[0-9A-Fa-f]+|#[0-9]+);)/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\")\n // Convert newlines to HTML line breaks\n .replace(/\\n/g, \"<br/>\")\n );\n};\n\n\n\n/**\n * Clean HTML tags safely\n * \n * Safely removes HTML tags and prevents HTML injection vulnerabilities.\n * \n * @param text - Input text that may contain HTML tags\n * @example `<span>hello world</span>` → `hello world`\n * \n * @returns Clean text without HTML tags\n */\nexport function cleanHtmlTags(text: string): string {\n if (!text || typeof text !== \"string\") {\n return \"\";\n }\n\n let cleanedText = \"\";\n\n // === Config ===\n const DANGEROUS_TAGS = new Set([\n \"script\", \"style\", \"noscript\",\n \"iframe\", \"object\", \"embed\", \"applet\",\n \"svg\", \"math\", \"foreignobject\",\n ]);\n\n // === FSM States ===\n enum State {\n TEXT, // Normal text\n TAG, // Currently consuming a normal tag until >\n SKIP_BLOCK, // Currently skipping dangerous block until </tag>\n COMMENT // HTML comment <!-- ... -->\n }\n\n let state = State.TEXT;\n let tagName = \"\"; // Temporary storage for encountered tag name\n let skipUntil = \"\"; // Corresponding \"</tag>\" for dangerous block\n const len = text.length;\n\n for (let i = 0; i < len; i++) {\n const ch = text[i];\n\n /* --------------- TEXT -> TAG/COMMENT --------------- */\n if (state === State.TEXT && ch === \"<\") {\n // Check if it's an HTML comment\n if (text.slice(i, i + 4) === \"<!--\") {\n state = State.COMMENT;\n continue;\n }\n\n // Try to extract tag name\n let j = i + 1;\n let isClosing = false;\n\n // Skip '/'\n if (j < len && text[j] === \"/\") {\n isClosing = true;\n j++;\n }\n // Skip whitespace\n while (j < len && /\\s/.test(text[j])) j++;\n\n // Extract tagName (a~z or A~Z or 0-9 or -)\n const start = j;\n while (j < len && /[A-Za-z0-9-]/.test(text[j])) j++;\n\n tagName = text.slice(start, j).toLowerCase();\n\n /* Dangerous block ── only \"opening tag\" starts skip */\n if (!isClosing && DANGEROUS_TAGS.has(tagName)) {\n state = State.SKIP_BLOCK;\n skipUntil = `</${tagName}>`;\n } else {\n state = State.TAG;\n }\n continue;\n }\n\n /* --------------- TAG -> TEXT --------------- */\n if (state === State.TAG) {\n if (ch === \">\") state = State.TEXT;\n // Don't write to output\n continue;\n }\n\n /* --------------- COMMENT -> TEXT --------------- */\n if (state === State.COMMENT) {\n // Check for comment end -->\n if (text.slice(i, i + 3) === \"-->\") {\n i += 2; // Skip '-->'\n state = State.TEXT;\n }\n continue;\n }\n\n /* --------------- SKIP_BLOCK Logic --------------- */\n if (state === State.SKIP_BLOCK) {\n // Transition: SKIP_BLOCK -> TEXT\n // Check if the current segment matches the end tag (e.g., </script>)\n if (\n ch === \"<\" &&\n text.slice(i, i + skipUntil.length).toLowerCase() === skipUntil\n ) {\n // Skip the entire end tag (case-insensitive match)\n i += skipUntil.length - 1;\n state = State.TEXT; // Return to TEXT state\n }\n continue; // Consume all content until the end tag is found\n }\n\n /* --------------- TEXT State: Normal output --------------- */\n if (state === State.TEXT) {\n cleanedText += ch;\n }\n }\n\n return cleanedText.trim();\n}\n\n\n\n/**\n * Clean MOTD color codes\n * \n * Clean all formatting codes from MOTD source string.\n * \n * @param {string} text - MOTD string with § formatting codes to be removed\n * @returns {string} Text without MOTD formatting codes\n */\nexport function cleanCodes(text: string): string {\n const REGEX = /(?:§)([0-9a-fA-FklmnorFKLMNOR])/g;\n let textResult = \"\";\n\n textResult = text.replace(REGEX, \"\");\n\n return textResult;\n};\n","import { extraLibraryType } from \"./types\";\n\n\n\n// color code to font styles\nconst extras: extraLibraryType = {\n \"§k\": \"obfuscated;\",\n \"§l\": \"font-weight: bold;\",\n \"§m\": \"text-decoration: line-through;\",\n \"§n\": \"text-decoration: underline;\",\n \"§o\": \"font-style: italic;\",\n \"§r\": \"color: inherit;text-decoration: none !important;font-weight:normal!important;font-style: normal!important;\",\n};\n\n// json extra font styles\nconst extraFontStyles: extraLibraryType = {\n bold: \"font-weight: bold;\",\n italic: \"font-style: italic;\",\n underlined: \"text-decoration:underline;\",\n strikethrough: \"text-decoration: line-through;\",\n obfuscated: \"mc_obfuscated;\",\n reset: \"color: inherit;text-decoration: none !important;font-weight:normal!important;font-style: normal!important;\",\n};\n\n// text to json extra name\nconst textToJsonExtras: extraLibraryType = {\n \"§k\": \"obfuscated\",\n \"§l\": \"bold\",\n \"§m\": \"strikethrough\",\n \"§n\": \"underlined\",\n \"§o\": \"italic\",\n \"§r\": \"reset\",\n};\n\n// base color hex\nconst colorCodeToHex: extraLibraryType = {\n \"§0\": \"#000000\",\n \"§1\": \"#0000AA\",\n \"§2\": \"#00AA00\",\n \"§3\": \"#00AAAA\",\n \"§4\": \"#AA0000\",\n \"§5\": \"#AA00AA\",\n \"§6\": \"#FFAA00\",\n \"§7\": \"#AAAAAA\",\n \"§8\": \"#555555\",\n \"§9\": \"#5555FF\",\n \"§a\": \"#55FF55\",\n \"§b\": \"#55FFFF\",\n \"§c\": \"#FF5555\",\n \"§d\": \"#FF55FF\",\n \"§e\": \"#FFFF55\",\n \"§f\": \"#FFFFFF\",\n};\n\n// json extra to hex color\nconst extraColorsToHex: extraLibraryType = {\n black: \"#000000\",\n dark_blue: \"#0000AA\",\n dark_green: \"#00AA00\",\n dark_aqua: \"#00AAAA\",\n dark_red: \"#AA0000\",\n dark_purple: \"#AA00AA\",\n gold: \"#FFAA00\",\n gray: \"#AAAAAA\",\n dark_gray: \"#555555\",\n blue: \"#5555FF\",\n green: \"#55FF55\",\n aqua: \"#55FFFF\",\n red: \"#FF5555\",\n light_purple: \"#FF55FF\",\n yellow: \"#FFFF55\",\n white: \"#FFFFFF\",\n};\n\n\n\nexport {\n extras,\n extraFontStyles,\n textToJsonExtras,\n colorCodeToHex,\n extraColorsToHex,\n};\n","import {\n extras,\n colorCodeToHex,\n} from \"../styleLibrary\";\nimport {\n htmlStringFormatting,\n baseColorCodeRegex,\n} from \"../utils\";\n\n\n\nexport default function textToHTML(motdString: string) {\n const colorCodeReg = baseColorCodeRegex;\n const codeREGEX = new RegExp(colorCodeReg.source);\n const codeSplit = motdString.split(codeREGEX).filter(item => item !== \"\");\n\n const fontStyleSet = new Set<string>();\n let colorHex = \"\";\n let resultHTML = \"\";\n\n codeSplit.forEach((item) => {\n const motdStringToLowerCase = item.toLowerCase();\n\n // detect hex\n if (Object.hasOwn(colorCodeToHex, motdStringToLowerCase)) {\n colorHex = colorCodeToHex[motdStringToLowerCase];\n\n // §f reset - only reset color, not font styles\n if(motdStringToLowerCase === \"§f\") {\n // §f does not reset font styles, only color\n }\n\n // detect style\n } else if (Object.hasOwn(extras, motdStringToLowerCase)) {\n if(motdStringToLowerCase === \"§r\") {\n colorHex = \"\";\n fontStyleSet.clear();\n } else {\n fontStyleSet.add(extras[motdStringToLowerCase]);\n }\n\n // detect normal text\n } else {\n let resultColor = \"\";\n let textContent = item;\n\n if (colorHex !== \"\") {\n resultColor = `color:${colorHex};`;\n }\n\n if (textContent !== \"\") {\n textContent = htmlStringFormatting(textContent);\n\n const fontStyle = Array.from(fontStyleSet).join(\"\");\n if (resultColor.length !== 0 || fontStyle.length !== 0) {\n resultHTML += `<span style=\"${resultColor}${fontStyle}\">${textContent}</span>`;\n } else {\n resultHTML += textContent;\n }\n }\n }\n });\n\n return resultHTML;\n}\n","import { motdJsonType } from \"../types\";\nimport {\n extraFontStyles,\n colorCodeToHex,\n extraColorsToHex,\n} from \"../styleLibrary\";\nimport {\n isMotdJSONType,\n} from \"../utils\";\nimport textToHTML from \"./textToHTML\";\n\n\n\nexport default function parseJSONToHTML(\n sourceJson: motdJsonType,\n) {\n let htmlElement = \"\";\n let colorStyle = \"\";\n let fontStyle = \"\";\n\n for (let key of Object.keys(sourceJson)) {\n key = key.toLowerCase();\n\n if (Object.hasOwn(extraFontStyles, key)) {\n if (sourceJson[key]) {\n fontStyle += extraFontStyles[key];\n }\n }\n\n if (key === \"color\") {\n const colorKey = sourceJson[key];\n let colorHex = \"\";\n\n if (typeof colorKey === \"string\") {\n if (Object.hasOwn(extraColorsToHex, colorKey)) {\n colorHex = extraColorsToHex[colorKey];\n } else if (Object.hasOwn(colorCodeToHex, colorKey)) {\n colorHex = colorCodeToHex[colorKey];\n } else {\n const customHexColorMatches = colorKey.match(\n /^#([-+]?0+|\\+?0*[1-9A-Fa-f][0-9A-Fa-f]{0,5})$/,\n );\n\n if (customHexColorMatches !== null) {\n colorHex =\n \"#\" +\n customHexColorMatches[1].replace(/^[-+]?0*/, \"\").padStart(6, \"0\");\n }\n }\n }\n\n if(colorHex !== \"\") {\n colorStyle = `color:${colorHex};`;\n }\n }\n\n if (key === \"extra\" && typeof sourceJson.extra === \"object\") {\n if (\n typeof sourceJson.text === \"string\" ||\n typeof sourceJson.text === \"number\"\n ) {\n htmlElement += textToHTML(String(sourceJson.text));\n }\n\n for (const sourceJsonExtra of sourceJson.extra) {\n if (typeof sourceJsonExtra === \"string\") {\n htmlElement += textToHTML(sourceJsonExtra);\n } else if (isMotdJSONType(sourceJsonExtra)) {\n htmlElement += parseJSONToHTML(sourceJsonExtra);\n }\n }\n }\n }\n\n if (sourceJson.extra === undefined && sourceJson.text !== undefined) {\n const currentText = sourceJson.text;\n if (\n typeof sourceJson.text === \"string\" ||\n typeof sourceJson.text === \"number\"\n ) {\n htmlElement += textToHTML(String(currentText));\n }\n }\n\n\n\n let returnHTML = \"\";\n if (fontStyle.length !== 0 || colorStyle.length !== 0) {\n returnHTML = `<span style=\"${colorStyle + fontStyle}\">${htmlElement}</span>`;\n } else {\n returnHTML = htmlElement;\n }\n\n return returnHTML;\n}\n","import { motdJsonType } from \"../types\";\nimport {\n isMotdJSONType,\n cleanCodes\n} from \"../utils\";\n\n\n\n/**\n * Convert JSON to Cleaned Text.\n * \n * @param sourceJson\n * @returns\n */\nexport default function JSONToCleanedText(\n sourceJson: motdJsonType,\n) {\n let textString = \"\";\n\n for (let key of Object.keys(sourceJson)) {\n key = key.toLowerCase();\n\n // extra\n if (key === \"extra\" && typeof sourceJson.extra === \"object\") {\n // ---------- with extra text ----------\n if (\n typeof sourceJson.text === \"string\" ||\n typeof sourceJson.text === \"number\"\n ) {\n // content to html\n textString += cleanCodes(String(sourceJson.text));\n }\n\n // ---------- foreach extra data and parse ----------\n for (const sourceJsonExtra of sourceJson.extra) {\n // console.log('sourceJsonExtra', sourceJsonExtra);\n if (typeof sourceJsonExtra === \"string\") {\n // Add string elements directly to the output\n textString += cleanCodes(sourceJsonExtra);\n } else if (isMotdJSONType(sourceJsonExtra)) {\n textString += JSONToCleanedText(sourceJsonExtra);\n }\n }\n }\n }\n\n // ---------- without extra text content ----------\n if (sourceJson.extra === undefined && sourceJson.text !== undefined) {\n const currentText = sourceJson.text;\n if (\n typeof sourceJson.text === \"string\" ||\n typeof sourceJson.text === \"number\"\n ) {\n // convert all type to string\n textString += cleanCodes(String(currentText));\n }\n }\n\n return textString;\n}\n","import { motdJsonType } from \"../types\";\nimport {\n textToJsonExtras,\n colorCodeToHex,\n} from \"../styleLibrary\";\nimport { baseColorCodeRegex } from \"../utils\";\n\n\n\nexport default function parseTextToJSON(text: string) {\n const colorCodeReg = baseColorCodeRegex;\n const codeREGEX = new RegExp(colorCodeReg.source);\n const textSplit = text.split(codeREGEX);\n const fontStyleSet = new Set<string>();\n let colorHex = \"\";\n\n const resultObject: motdJsonType = {\n text: \"\",\n extra: [],\n };\n\n textSplit.forEach((item) => {\n const stringToLowerCase = item.toLowerCase();\n\n if (Object.hasOwn(colorCodeToHex, stringToLowerCase)) {\n colorHex = colorCodeToHex[stringToLowerCase];\n if(stringToLowerCase === \"§f\") {\n // §f does not reset font styles, only color\n }\n } else if (Object.hasOwn(textToJsonExtras, stringToLowerCase)) {\n if(stringToLowerCase === \"§r\") {\n fontStyleSet.clear();\n colorHex = \"\";\n } else {\n fontStyleSet.add(textToJsonExtras[stringToLowerCase]);\n }\n } else {\n const innerObject: motdJsonType = {\n text: \"\",\n extra: [],\n };\n\n for (const styleName of fontStyleSet) {\n innerObject[styleName] = true;\n }\n\n innerObject.text = item;\n\n if (colorHex !== \"\") {\n innerObject.color = colorHex;\n }\n\n if (typeof resultObject.extra === \"object\") {\n resultObject.extra.push(innerObject);\n }\n }\n });\n\n // code styles merge\n let newExtra: motdJsonType[] = [];\n if (resultObject.extra && resultObject.extra.length > 0) {\n const extraArray = resultObject.extra as motdJsonType[];\n if (extraArray.length > 1) {\n // if text is '', remove it and merge to next array\n extraArray.forEach((item, index) => {\n if (item.text === \"\") {\n if (extraArray && typeof extraArray[index + 1] === \"object\") {\n newExtra.push({\n ...item,\n ...(extraArray[index + 1] as motdJsonType),\n });\n }\n } else {\n if (item.text !== newExtra[newExtra.length - 1]?.text) {\n newExtra.push(item);\n }\n }\n });\n } else {\n newExtra.push(extraArray[0]);\n }\n }\n\n // remove blank content\n newExtra = newExtra.filter((item) => item.text !== \"\");\n\n return {\n text: resultObject.text,\n extra: newExtra,\n };\n}\n","import { motdJsonType } from \"../types\";\nimport {\n JSONToHTML,\n textToHTML,\n} from \"./\";\n\nexport function JSONRender(json: object) {\n return JSONToHTML(json as motdJsonType);\n}\n\nexport function autoToHTML(motd: string | object): string {\n if (typeof motd === \"object\") {\n return JSONRender(motd);\n } else if (typeof motd === \"string\") {\n return textToHTML(motd);\n } else {\n return \"unknown motd data type\";\n }\n}\n\nexport default autoToHTML;\n","import { motdJsonType } from \"../types\";\nimport {\n JSONToCleanedText,\n} from \".\";\nimport { cleanCodes } from \"../utils\";\n\nexport function autoCleanToText(motd: string | object): string {\n if (typeof motd === \"object\") {\n return JSONToCleanedText(motd as motdJsonType);\n } else if (typeof motd === \"string\") {\n return cleanCodes(motd);\n } else {\n return \"unknown motd data type\";\n }\n}\n\nexport default autoCleanToText;\n"],"mappings":"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","names":["index_exports","__export","JSONRender","JSONToCleanedText","parseJSONToHTML","autoCleanToText_default","autoToHTML","baseColorCodeRegex","cleanCodes","cleanHtmlTags","index_default","htmlStringFormatting","isMotdJSONType","textToHTML","parseTextToJSON","__toCommonJS","baseColorCodeRegex","isMotdJSONType","object","hasText","hasTranslate","hasExtra","htmlStringFormatting","text","cleanHtmlTags","cleanedText","DANGEROUS_TAGS","State","state","tagName","skipUntil","len","i","ch","j","isClosing","start","cleanCodes","REGEX","textResult","extras","extraFontStyles","textToJsonExtras","colorCodeToHex","extraColorsToHex","textToHTML","motdString","colorCodeReg","baseColorCodeRegex","codeREGEX","codeSplit","item","fontStyleSet","colorHex","resultHTML","motdStringToLowerCase","colorCodeToHex","extras","resultColor","textContent","htmlStringFormatting","fontStyle","parseJSONToHTML","sourceJson","htmlElement","colorStyle","fontStyle","key","extraFontStyles","colorKey","colorHex","extraColorsToHex","colorCodeToHex","customHexColorMatches","textToHTML","sourceJsonExtra","isMotdJSONType","currentText","returnHTML","JSONToCleanedText","sourceJson","textString","key","cleanCodes","sourceJsonExtra","isMotdJSONType","currentText","parseTextToJSON","text","colorCodeReg","baseColorCodeRegex","codeREGEX","textSplit","fontStyleSet","colorHex","resultObject","item","stringToLowerCase","colorCodeToHex","textToJsonExtras","innerObject","styleName","newExtra","extraArray","index","_a","__spreadValues","JSONRender","json","parseJSONToHTML","autoToHTML","motd","textToHTML","autoCleanToText","motd","JSONToCleanedText","cleanCodes","autoCleanToText_default","motdParser","textToHTML","parseTextToJSON","parseJSONToHTML","JSONRender","autoToHTML","htmlStringFormatting","cleanCodes","cleanHtmlTags","JSONToCleanedText","autoCleanToText_default","index_default"]}