Rust library to generate static websites
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: create a proper setup for JavaScript code in the repo

+228 -606
+2
.cargo/config.toml
··· 1 + [alias] 2 + xtask = "run --package xtask --"
+8 -1
Cargo.lock
··· 2590 2590 version = "0.6.2" 2591 2591 dependencies = [ 2592 2592 "axum", 2593 - "brk_rolldown", 2594 2593 "cargo_metadata", 2595 2594 "chrono", 2596 2595 "clap", ··· 5869 5868 dependencies = [ 5870 5869 "libc", 5871 5870 "rustix", 5871 + ] 5872 + 5873 + [[package]] 5874 + name = "xtask" 5875 + version = "0.1.0" 5876 + dependencies = [ 5877 + "brk_rolldown", 5878 + "tokio", 5872 5879 ] 5873 5880 5874 5881 [[package]]
+1 -1
Cargo.toml
··· 1 1 [workspace] 2 - members = ["crates/*", "benchmarks/*", "examples/*", "website"] 2 + members = ["crates/*", "benchmarks/*", "examples/*", "website", "xtask"] 3 3 resolver = "3" 4 4 5 5 [workspace.dependencies]
-4
crates/maudit-cli/Cargo.toml
··· 41 41 serde_json = "1.0" 42 42 tokio-util = "0.7" 43 43 cargo_metadata = "0.23.0" 44 - 45 - [build-dependencies] 46 - rolldown = { package = "brk_rolldown", version = "0.2.3" } 47 - tokio = { version = "1", features = ["rt"] }
-44
crates/maudit-cli/build.rs
··· 1 - use rolldown::{Bundler, BundlerOptions, InputItem}; 2 - use std::path::PathBuf; 3 - 4 - fn main() { 5 - // Tell Cargo to rerun if any of our JS/TS files change 6 - println!("cargo:rerun-if-changed=src/dev/js"); 7 - println!("cargo:rerun-if-changed=tsconfig.json"); 8 - 9 - // Only bundle during regular builds, not during cargo check or similar 10 - if std::env::var("CARGO_CFG_TARGET_ARCH").is_err() { 11 - return; 12 - } 13 - 14 - let js_src_dir = PathBuf::from("src/dev/js"); 15 - let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR environment variable not set"); 16 - let js_dist_dir = PathBuf::from(out_dir).join("js"); 17 - 18 - // Ensure the dist directory exists 19 - std::fs::create_dir_all(&js_dist_dir).expect("Failed to create dist directory"); 20 - 21 - // Configure Rolldown bundler input 22 - let input_items = vec![InputItem { 23 - name: Some("client".to_string()), 24 - import: js_src_dir.join("client.ts").to_string_lossy().to_string(), 25 - }]; 26 - 27 - let bundler_options = BundlerOptions { 28 - input: Some(input_items), 29 - dir: Some(js_dist_dir.to_string_lossy().to_string()), 30 - format: Some(rolldown::OutputFormat::Esm), 31 - ..Default::default() 32 - }; 33 - 34 - // Create and run the bundler 35 - let runtime = tokio::runtime::Runtime::new().expect("Failed to create tokio runtime"); 36 - 37 - runtime.block_on(async { 38 - let mut bundler = Bundler::new(bundler_options).unwrap(); 39 - if let Err(e) = bundler.write().await { 40 - panic!("Failed to bundle JavaScript: {:?}", e); 41 - } 42 - println!("Successfully bundled JavaScript files"); 43 - }); 44 - }
+7
crates/maudit-cli/package.json
··· 1 + { 2 + "name": "maudit-cli-packages", 3 + "private": true, 4 + "dependencies": { 5 + "ansi_up": "^6.0.6" 6 + } 7 + }
+22
crates/maudit-cli/pnpm-lock.yaml
··· 1 + lockfileVersion: '9.0' 2 + 3 + settings: 4 + autoInstallPeers: true 5 + excludeLinksFromLockfile: false 6 + 7 + importers: 8 + 9 + .: 10 + dependencies: 11 + ansi_up: 12 + specifier: ^6.0.6 13 + version: 6.0.6 14 + 15 + packages: 16 + 17 + ansi_up@6.0.6: 18 + resolution: {integrity: sha512-yIa1x3Ecf8jWP4UWEunNjqNX6gzE4vg2gGz+xqRGY+TBSucnYp6RRdPV4brmtg6bQ1ljD48mZ5iGSEj7QEpRKA==} 19 + 20 + snapshots: 21 + 22 + ansi_up@6.0.6: {}
+2 -2
crates/maudit-cli/src/dev/js/client.ts crates/maudit-cli/js/client.ts
··· 3 3 * It might be better to use a more sophisticated approach, using some sort of diffing, handling reconnecting, etc. 4 4 */ 5 5 6 - import { AnsiUp } from "./vendor/ansi_up"; 6 + import { AnsiUp } from "ansi_up"; 7 7 import { createErrorOverlay } from "./overlay"; 8 8 import { error, log } from "./utils"; 9 9 ··· 32 32 33 33 const socket = new WebSocket(`ws://${WS_SERVER_ADDRESS}/ws`); 34 34 35 - socket.addEventListener("open", (event) => { 35 + socket.addEventListener("open", () => { 36 36 console.log("Connected to server"); 37 37 socket.send("Hello Server!"); 38 38 });
crates/maudit-cli/src/dev/js/overlay.ts crates/maudit-cli/js/overlay.ts
+3 -3
crates/maudit-cli/src/dev/js/utils.ts crates/maudit-cli/js/utils.ts
··· 1 1 const ansiPattern = new RegExp( 2 2 "(?:\\u001B\\][\\s\\S]*?(?:\\u0007|\\u001B\\u005C|\\u009C))|[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]", 3 - "g" 3 + "g", 4 4 ); 5 5 6 6 export function stripAnsi(str: string): string { ··· 24 24 "%cMaudit", 25 25 "background: #ba1f33; color: white; padding-inline: 4px; border-radius: 2px; font-family: serif;", 26 26 ...message.map((m) => 27 - typeof m === "string" ? stripAnsi(m) : JSON.stringify(m, null, 2) 28 - ) 27 + typeof m === "string" ? stripAnsi(m) : JSON.stringify(m, null, 2), 28 + ), 29 29 ); 30 30 }
-7
crates/maudit-cli/src/dev/js/vendor/README.md
··· 1 - # Vendored libraries for the Maudit CLI dev server. 2 - 3 - Since the JS part of the Maudit CLI is built at build time through a Rust build script, we cannot rely on a package manager to fetch dependencies, as people downloading the Maudit CLI from crates.io won't have access to npm, pnpm, yarn, etc. 4 - 5 - As such, we vendor the dependencies we need here. They are copied as-is from their respective repositories and include their license information at the top of the file. 6 - 7 - An alternative to this approach would be to pre-bundle the JS code and ship the bundled version with the crate, but it's a lot more cumbersome in development so while things are still evolving, we prefer this approach.
-46
crates/maudit-cli/src/dev/js/vendor/ansi_up.d.ts
··· 1 - export declare class AnsiUp { 2 - VERSION: string; 3 - private ansi_colors; 4 - private palette_256; 5 - private fg; 6 - private bg; 7 - private bold; 8 - private faint; 9 - private italic; 10 - private underline; 11 - private _use_classes; 12 - private _csi_regex; 13 - private _osc_st; 14 - private _osc_regex; 15 - private _url_allowlist; 16 - private _escape_html; 17 - private _buffer; 18 - private _boldStyle; 19 - private _faintStyle; 20 - private _italicStyle; 21 - private _underlineStyle; 22 - constructor(); 23 - set use_classes(arg: boolean); 24 - get use_classes(): boolean; 25 - set url_allowlist(arg: {}); 26 - get url_allowlist(): {}; 27 - set escape_html(arg: boolean); 28 - get escape_html(): boolean; 29 - set boldStyle(arg: string); 30 - get boldStyle(): string; 31 - set faintStyle(arg: string); 32 - get faintStyle(): string; 33 - set italicStyle(arg: string); 34 - get italicStyle(): string; 35 - set underlineStyle(arg: string); 36 - get underlineStyle(): string; 37 - private setup_palettes; 38 - private escape_txt_for_html; 39 - private append_buffer; 40 - private get_next_packet; 41 - ansi_to_html(txt: string): string; 42 - private with_state; 43 - private process_ansi; 44 - private transform_to_html; 45 - private process_hyperlink; 46 - }
-469
crates/maudit-cli/src/dev/js/vendor/ansi_up.js
··· 1 - /* ansi_up.js 2 - * author : http://github.com/drudru/ 3 - * license : MIT 4 - * http://github.com/drudru/ansi_up 5 - */ 6 - 7 - "use strict"; 8 - var __makeTemplateObject = 9 - (this && this.__makeTemplateObject) || 10 - function (cooked, raw) { 11 - if (Object.defineProperty) { 12 - Object.defineProperty(cooked, "raw", { value: raw }); 13 - } else { 14 - cooked.raw = raw; 15 - } 16 - return cooked; 17 - }; 18 - var PacketKind; 19 - (function (PacketKind) { 20 - PacketKind[(PacketKind["EOS"] = 0)] = "EOS"; 21 - PacketKind[(PacketKind["Text"] = 1)] = "Text"; 22 - PacketKind[(PacketKind["Incomplete"] = 2)] = "Incomplete"; 23 - PacketKind[(PacketKind["ESC"] = 3)] = "ESC"; 24 - PacketKind[(PacketKind["Unknown"] = 4)] = "Unknown"; 25 - PacketKind[(PacketKind["SGR"] = 5)] = "SGR"; 26 - PacketKind[(PacketKind["OSCURL"] = 6)] = "OSCURL"; 27 - })(PacketKind || (PacketKind = {})); 28 - export class AnsiUp { 29 - constructor() { 30 - this.VERSION = "6.0.6"; 31 - this.setup_palettes(); 32 - this._use_classes = false; 33 - this.bold = false; 34 - this.faint = false; 35 - this.italic = false; 36 - this.underline = false; 37 - this.fg = this.bg = null; 38 - this._buffer = ""; 39 - this._url_allowlist = { http: 1, https: 1 }; 40 - this._escape_html = true; 41 - this.boldStyle = "font-weight:bold"; 42 - this.faintStyle = "opacity:0.7"; 43 - this.italicStyle = "font-style:italic"; 44 - this.underlineStyle = "text-decoration:underline"; 45 - } 46 - set use_classes(arg) { 47 - this._use_classes = arg; 48 - } 49 - get use_classes() { 50 - return this._use_classes; 51 - } 52 - set url_allowlist(arg) { 53 - this._url_allowlist = arg; 54 - } 55 - get url_allowlist() { 56 - return this._url_allowlist; 57 - } 58 - set escape_html(arg) { 59 - this._escape_html = arg; 60 - } 61 - get escape_html() { 62 - return this._escape_html; 63 - } 64 - set boldStyle(arg) { 65 - this._boldStyle = arg; 66 - } 67 - get boldStyle() { 68 - return this._boldStyle; 69 - } 70 - set faintStyle(arg) { 71 - this._faintStyle = arg; 72 - } 73 - get faintStyle() { 74 - return this._faintStyle; 75 - } 76 - set italicStyle(arg) { 77 - this._italicStyle = arg; 78 - } 79 - get italicStyle() { 80 - return this._italicStyle; 81 - } 82 - set underlineStyle(arg) { 83 - this._underlineStyle = arg; 84 - } 85 - get underlineStyle() { 86 - return this._underlineStyle; 87 - } 88 - setup_palettes() { 89 - this.ansi_colors = [ 90 - [ 91 - { rgb: [0, 0, 0], class_name: "ansi-black" }, 92 - { rgb: [187, 0, 0], class_name: "ansi-red" }, 93 - { rgb: [0, 187, 0], class_name: "ansi-green" }, 94 - { rgb: [187, 187, 0], class_name: "ansi-yellow" }, 95 - { rgb: [0, 0, 187], class_name: "ansi-blue" }, 96 - { rgb: [187, 0, 187], class_name: "ansi-magenta" }, 97 - { rgb: [0, 187, 187], class_name: "ansi-cyan" }, 98 - { rgb: [255, 255, 255], class_name: "ansi-white" }, 99 - ], 100 - [ 101 - { rgb: [85, 85, 85], class_name: "ansi-bright-black" }, 102 - { rgb: [255, 85, 85], class_name: "ansi-bright-red" }, 103 - { rgb: [0, 255, 0], class_name: "ansi-bright-green" }, 104 - { rgb: [255, 255, 85], class_name: "ansi-bright-yellow" }, 105 - { rgb: [85, 85, 255], class_name: "ansi-bright-blue" }, 106 - { rgb: [255, 85, 255], class_name: "ansi-bright-magenta" }, 107 - { rgb: [85, 255, 255], class_name: "ansi-bright-cyan" }, 108 - { rgb: [255, 255, 255], class_name: "ansi-bright-white" }, 109 - ], 110 - ]; 111 - this.palette_256 = []; 112 - this.ansi_colors.forEach((palette) => { 113 - palette.forEach((rec) => { 114 - this.palette_256.push(rec); 115 - }); 116 - }); 117 - let levels = [0, 95, 135, 175, 215, 255]; 118 - for (let r = 0; r < 6; ++r) { 119 - for (let g = 0; g < 6; ++g) { 120 - for (let b = 0; b < 6; ++b) { 121 - let col = { 122 - rgb: [levels[r], levels[g], levels[b]], 123 - class_name: "truecolor", 124 - }; 125 - this.palette_256.push(col); 126 - } 127 - } 128 - } 129 - let grey_level = 8; 130 - for (let i = 0; i < 24; ++i, grey_level += 10) { 131 - let gry = { 132 - rgb: [grey_level, grey_level, grey_level], 133 - class_name: "truecolor", 134 - }; 135 - this.palette_256.push(gry); 136 - } 137 - } 138 - escape_txt_for_html(txt) { 139 - if (!this._escape_html) return txt; 140 - return txt.replace(/[&<>"']/gm, (str) => { 141 - if (str === "&") return "&amp;"; 142 - if (str === "<") return "&lt;"; 143 - if (str === ">") return "&gt;"; 144 - if (str === '"') return "&quot;"; 145 - if (str === "'") return "&#x27;"; 146 - }); 147 - } 148 - append_buffer(txt) { 149 - var str = this._buffer + txt; 150 - this._buffer = str; 151 - } 152 - get_next_packet() { 153 - var pkt = { 154 - kind: PacketKind.EOS, 155 - text: "", 156 - url: "", 157 - }; 158 - var len = this._buffer.length; 159 - if (len == 0) return pkt; 160 - var pos = this._buffer.indexOf("\x1B"); 161 - if (pos == -1) { 162 - pkt.kind = PacketKind.Text; 163 - pkt.text = this._buffer; 164 - this._buffer = ""; 165 - return pkt; 166 - } 167 - if (pos > 0) { 168 - pkt.kind = PacketKind.Text; 169 - pkt.text = this._buffer.slice(0, pos); 170 - this._buffer = this._buffer.slice(pos); 171 - return pkt; 172 - } 173 - if (pos == 0) { 174 - if (len < 3) { 175 - pkt.kind = PacketKind.Incomplete; 176 - return pkt; 177 - } 178 - var next_char = this._buffer.charAt(1); 179 - if (next_char != "[" && next_char != "]" && next_char != "(") { 180 - pkt.kind = PacketKind.ESC; 181 - pkt.text = this._buffer.slice(0, 1); 182 - this._buffer = this._buffer.slice(1); 183 - return pkt; 184 - } 185 - if (next_char == "[") { 186 - if (!this._csi_regex) { 187 - this._csi_regex = rgx( 188 - templateObject_1 || 189 - (templateObject_1 = __makeTemplateObject( 190 - [ 191 - "\n ^ # beginning of line\n #\n # First attempt\n (?: # legal sequence\n \u001B[ # CSI\n ([<-?]?) # private-mode char\n ([d;]*) # any digits or semicolons\n ([ -/]? # an intermediate modifier\n [@-~]) # the command\n )\n | # alternate (second attempt)\n (?: # illegal sequence\n \u001B[ # CSI\n [ -~]* # anything legal\n ([\0-\u001F:]) # anything illegal\n )\n ", 192 - ], 193 - [ 194 - "\n ^ # beginning of line\n #\n # First attempt\n (?: # legal sequence\n \\x1b\\[ # CSI\n ([\\x3c-\\x3f]?) # private-mode char\n ([\\d;]*) # any digits or semicolons\n ([\\x20-\\x2f]? # an intermediate modifier\n [\\x40-\\x7e]) # the command\n )\n | # alternate (second attempt)\n (?: # illegal sequence\n \\x1b\\[ # CSI\n [\\x20-\\x7e]* # anything legal\n ([\\x00-\\x1f:]) # anything illegal\n )\n ", 195 - ] 196 - )) 197 - ); 198 - } 199 - let match = this._buffer.match(this._csi_regex); 200 - if (match === null) { 201 - pkt.kind = PacketKind.Incomplete; 202 - return pkt; 203 - } 204 - if (match[4]) { 205 - pkt.kind = PacketKind.ESC; 206 - pkt.text = this._buffer.slice(0, 1); 207 - this._buffer = this._buffer.slice(1); 208 - return pkt; 209 - } 210 - if (match[1] != "" || match[3] != "m") pkt.kind = PacketKind.Unknown; 211 - else pkt.kind = PacketKind.SGR; 212 - pkt.text = match[2]; 213 - var rpos = match[0].length; 214 - this._buffer = this._buffer.slice(rpos); 215 - return pkt; 216 - } else if (next_char == "]") { 217 - if (len < 4) { 218 - pkt.kind = PacketKind.Incomplete; 219 - return pkt; 220 - } 221 - if (this._buffer.charAt(2) != "8" || this._buffer.charAt(3) != ";") { 222 - pkt.kind = PacketKind.ESC; 223 - pkt.text = this._buffer.slice(0, 1); 224 - this._buffer = this._buffer.slice(1); 225 - return pkt; 226 - } 227 - if (!this._osc_st) { 228 - this._osc_st = rgxG( 229 - templateObject_2 || 230 - (templateObject_2 = __makeTemplateObject( 231 - [ 232 - "\n (?: # legal sequence\n (\u001B\\) # ESC | # alternate\n (\u0007) # BEL (what xterm did)\n )\n | # alternate (second attempt)\n ( # illegal sequence\n [\0-\u0006] # anything illegal\n | # alternate\n [\b-\u001A] # anything illegal\n | # alternate\n [\u001C-\u001F] # anything illegal\n )\n ", 233 - ], 234 - [ 235 - "\n (?: # legal sequence\n (\\x1b\\\\) # ESC \\\n | # alternate\n (\\x07) # BEL (what xterm did)\n )\n | # alternate (second attempt)\n ( # illegal sequence\n [\\x00-\\x06] # anything illegal\n | # alternate\n [\\x08-\\x1a] # anything illegal\n | # alternate\n [\\x1c-\\x1f] # anything illegal\n )\n ", 236 - ] 237 - )) 238 - ); 239 - } 240 - this._osc_st.lastIndex = 0; 241 - { 242 - let match = this._osc_st.exec(this._buffer); 243 - if (match === null) { 244 - pkt.kind = PacketKind.Incomplete; 245 - return pkt; 246 - } 247 - if (match[3]) { 248 - pkt.kind = PacketKind.ESC; 249 - pkt.text = this._buffer.slice(0, 1); 250 - this._buffer = this._buffer.slice(1); 251 - return pkt; 252 - } 253 - } 254 - { 255 - let match = this._osc_st.exec(this._buffer); 256 - if (match === null) { 257 - pkt.kind = PacketKind.Incomplete; 258 - return pkt; 259 - } 260 - if (match[3]) { 261 - pkt.kind = PacketKind.ESC; 262 - pkt.text = this._buffer.slice(0, 1); 263 - this._buffer = this._buffer.slice(1); 264 - return pkt; 265 - } 266 - } 267 - if (!this._osc_regex) { 268 - this._osc_regex = rgx( 269 - templateObject_3 || 270 - (templateObject_3 = __makeTemplateObject( 271 - [ 272 - "\n ^ # beginning of line\n #\n \u001B]8; # OSC Hyperlink\n [ -:<-~]* # params (excluding ;)\n ; # end of params\n ([!-~]{0,512}) # URL capture\n (?: # ST\n (?:\u001B\\) # ESC | # alternate\n (?:\u0007) # BEL (what xterm did)\n )\n ([ -~]+) # TEXT capture\n \u001B]8;; # OSC Hyperlink End\n (?: # ST\n (?:\u001B\\) # ESC | # alternate\n (?:\u0007) # BEL (what xterm did)\n )\n ", 273 - ], 274 - [ 275 - "\n ^ # beginning of line\n #\n \\x1b\\]8; # OSC Hyperlink\n [\\x20-\\x3a\\x3c-\\x7e]* # params (excluding ;)\n ; # end of params\n ([\\x21-\\x7e]{0,512}) # URL capture\n (?: # ST\n (?:\\x1b\\\\) # ESC \\\n | # alternate\n (?:\\x07) # BEL (what xterm did)\n )\n ([\\x20-\\x7e]+) # TEXT capture\n \\x1b\\]8;; # OSC Hyperlink End\n (?: # ST\n (?:\\x1b\\\\) # ESC \\\n | # alternate\n (?:\\x07) # BEL (what xterm did)\n )\n ", 276 - ] 277 - )) 278 - ); 279 - } 280 - let match = this._buffer.match(this._osc_regex); 281 - if (match === null) { 282 - pkt.kind = PacketKind.ESC; 283 - pkt.text = this._buffer.slice(0, 1); 284 - this._buffer = this._buffer.slice(1); 285 - return pkt; 286 - } 287 - pkt.kind = PacketKind.OSCURL; 288 - pkt.url = match[1]; 289 - pkt.text = match[2]; 290 - var rpos = match[0].length; 291 - this._buffer = this._buffer.slice(rpos); 292 - return pkt; 293 - } else if (next_char == "(") { 294 - pkt.kind = PacketKind.Unknown; 295 - this._buffer = this._buffer.slice(3); 296 - return pkt; 297 - } 298 - } 299 - } 300 - ansi_to_html(txt) { 301 - this.append_buffer(txt); 302 - var blocks = []; 303 - while (true) { 304 - var packet = this.get_next_packet(); 305 - if (packet.kind == PacketKind.EOS || packet.kind == PacketKind.Incomplete) 306 - break; 307 - if (packet.kind == PacketKind.ESC || packet.kind == PacketKind.Unknown) 308 - continue; 309 - if (packet.kind == PacketKind.Text) 310 - blocks.push(this.transform_to_html(this.with_state(packet))); 311 - else if (packet.kind == PacketKind.SGR) this.process_ansi(packet); 312 - else if (packet.kind == PacketKind.OSCURL) 313 - blocks.push(this.process_hyperlink(packet)); 314 - } 315 - return blocks.join(""); 316 - } 317 - with_state(pkt) { 318 - return { 319 - bold: this.bold, 320 - faint: this.faint, 321 - italic: this.italic, 322 - underline: this.underline, 323 - fg: this.fg, 324 - bg: this.bg, 325 - text: pkt.text, 326 - }; 327 - } 328 - process_ansi(pkt) { 329 - let sgr_cmds = pkt.text.split(";"); 330 - while (sgr_cmds.length > 0) { 331 - let sgr_cmd_str = sgr_cmds.shift(); 332 - let num = parseInt(sgr_cmd_str, 10); 333 - if (isNaN(num) || num === 0) { 334 - this.fg = null; 335 - this.bg = null; 336 - this.bold = false; 337 - this.faint = false; 338 - this.italic = false; 339 - this.underline = false; 340 - } else if (num === 1) { 341 - this.bold = true; 342 - } else if (num === 2) { 343 - this.faint = true; 344 - } else if (num === 3) { 345 - this.italic = true; 346 - } else if (num === 4) { 347 - this.underline = true; 348 - } else if (num === 21) { 349 - this.bold = false; 350 - } else if (num === 22) { 351 - this.faint = false; 352 - this.bold = false; 353 - } else if (num === 23) { 354 - this.italic = false; 355 - } else if (num === 24) { 356 - this.underline = false; 357 - } else if (num === 39) { 358 - this.fg = null; 359 - } else if (num === 49) { 360 - this.bg = null; 361 - } else if (num >= 30 && num < 38) { 362 - this.fg = this.ansi_colors[0][num - 30]; 363 - } else if (num >= 40 && num < 48) { 364 - this.bg = this.ansi_colors[0][num - 40]; 365 - } else if (num >= 90 && num < 98) { 366 - this.fg = this.ansi_colors[1][num - 90]; 367 - } else if (num >= 100 && num < 108) { 368 - this.bg = this.ansi_colors[1][num - 100]; 369 - } else if (num === 38 || num === 48) { 370 - if (sgr_cmds.length > 0) { 371 - let is_foreground = num === 38; 372 - let mode_cmd = sgr_cmds.shift(); 373 - if (mode_cmd === "5" && sgr_cmds.length > 0) { 374 - let palette_index = parseInt(sgr_cmds.shift(), 10); 375 - if (palette_index >= 0 && palette_index <= 255) { 376 - if (is_foreground) this.fg = this.palette_256[palette_index]; 377 - else this.bg = this.palette_256[palette_index]; 378 - } 379 - } 380 - if (mode_cmd === "2" && sgr_cmds.length > 2) { 381 - let r = parseInt(sgr_cmds.shift(), 10); 382 - let g = parseInt(sgr_cmds.shift(), 10); 383 - let b = parseInt(sgr_cmds.shift(), 10); 384 - if ( 385 - r >= 0 && 386 - r <= 255 && 387 - g >= 0 && 388 - g <= 255 && 389 - b >= 0 && 390 - b <= 255 391 - ) { 392 - let c = { rgb: [r, g, b], class_name: "truecolor" }; 393 - if (is_foreground) this.fg = c; 394 - else this.bg = c; 395 - } 396 - } 397 - } 398 - } 399 - } 400 - } 401 - transform_to_html(fragment) { 402 - let txt = fragment.text; 403 - if (txt.length === 0) return txt; 404 - txt = this.escape_txt_for_html(txt); 405 - if ( 406 - !fragment.bold && 407 - !fragment.italic && 408 - !fragment.faint && 409 - !fragment.underline && 410 - fragment.fg === null && 411 - fragment.bg === null 412 - ) 413 - return txt; 414 - let styles = []; 415 - let classes = []; 416 - let fg = fragment.fg; 417 - let bg = fragment.bg; 418 - if (fragment.bold) styles.push(this._boldStyle); 419 - if (fragment.faint) styles.push(this._faintStyle); 420 - if (fragment.italic) styles.push(this._italicStyle); 421 - if (fragment.underline) styles.push(this._underlineStyle); 422 - if (!this._use_classes) { 423 - if (fg) styles.push(`color:rgb(${fg.rgb.join(",")})`); 424 - if (bg) styles.push(`background-color:rgb(${bg.rgb})`); 425 - } else { 426 - if (fg) { 427 - if (fg.class_name !== "truecolor") { 428 - classes.push(`${fg.class_name}-fg`); 429 - } else { 430 - styles.push(`color:rgb(${fg.rgb.join(",")})`); 431 - } 432 - } 433 - if (bg) { 434 - if (bg.class_name !== "truecolor") { 435 - classes.push(`${bg.class_name}-bg`); 436 - } else { 437 - styles.push(`background-color:rgb(${bg.rgb.join(",")})`); 438 - } 439 - } 440 - } 441 - let class_string = ""; 442 - let style_string = ""; 443 - if (classes.length) class_string = ` class="${classes.join(" ")}"`; 444 - if (styles.length) style_string = ` style="${styles.join(";")}"`; 445 - return `<span${style_string}${class_string}>${txt}</span>`; 446 - } 447 - process_hyperlink(pkt) { 448 - let parts = pkt.url.split(":"); 449 - if (parts.length < 1) return ""; 450 - if (!this._url_allowlist[parts[0]]) return ""; 451 - let result = `<a href="${this.escape_txt_for_html( 452 - pkt.url 453 - )}">${this.escape_txt_for_html(pkt.text)}</a>`; 454 - return result; 455 - } 456 - } 457 - function rgx(tmplObj, ...subst) { 458 - let regexText = tmplObj.raw[0]; 459 - let wsrgx = /^\s+|\s+\n|\s*#[\s\S]*?\n|\n/gm; 460 - let txt2 = regexText.replace(wsrgx, ""); 461 - return new RegExp(txt2); 462 - } 463 - function rgxG(tmplObj, ...subst) { 464 - let regexText = tmplObj.raw[0]; 465 - let wsrgx = /^\s+|\s+\n|\s*#[\s\S]*?\n|\n/gm; 466 - let txt2 = regexText.replace(wsrgx, ""); 467 - return new RegExp(txt2, "g"); 468 - } 469 - var templateObject_1, templateObject_2, templateObject_3;
+2 -1
crates/maudit-cli/src/dev/server.rs
··· 72 72 fn inject_live_reload_script(html_content: &str, socket_addr: SocketAddr, host: bool) -> String { 73 73 let mut content = html_content.to_string(); 74 74 75 - let script_content = include_str!(concat!(env!("OUT_DIR"), "/js/client.js")).replace( 75 + // Run cargo xtask build-cli-js to build the client.js file if missing 76 + let script_content = include_str!("../../js/dist/client.js").replace( 76 77 "{SERVER_ADDRESS}", 77 78 &format!( 78 79 "{}:{}",
-26
crates/maudit-cli/tsconfig.json
··· 1 - { 2 - "compilerOptions": { 3 - "rootDir": "./src/dev/js", 4 - "noEmit": true, 5 - 6 - "module": "esnext", 7 - "target": "es2020", 8 - "lib": ["dom", "dom.iterable", "es2020"], 9 - "moduleResolution": "bundler", 10 - 11 - // Other Outputs 12 - "sourceMap": true, 13 - 14 - // Stricter Typechecking Options 15 - "noUncheckedIndexedAccess": true, 16 - "exactOptionalPropertyTypes": true, 17 - 18 - // Recommended Options 19 - "strict": true, 20 - "verbatimModuleSyntax": true, 21 - "isolatedModules": true, 22 - "noUncheckedSideEffectImports": true, 23 - "moduleDetection": "force", 24 - "skipLibCheck": true, 25 - } 26 - }
crates/maudit/js/preload.ts

This is a binary file and will not be displayed.

+1 -2
package.json
··· 5 5 "packageManager": "pnpm@9.15.0+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c", 6 6 "dependencies": { 7 7 "@tailwindcss/cli": "^4.0.0", 8 - "tailwindcss": "^4.0.0", 9 - "thumbhash": "^0.1.1" 8 + "tailwindcss": "^4.0.0" 10 9 }, 11 10 "devDependencies": { 12 11 "netlify-plugin-debug-cache": "^1.0.4",
+27
tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + "noEmit": true, 4 + 5 + "module": "esnext", 6 + "target": "es2020", 7 + "lib": ["dom", "dom.iterable", "es2020"], 8 + "moduleResolution": "bundler", 9 + 10 + // Other Outputs 11 + "sourceMap": true, 12 + 13 + // Stricter Typechecking Options 14 + "noUncheckedIndexedAccess": true, 15 + "exactOptionalPropertyTypes": true, 16 + 17 + // Recommended Options 18 + "strict": true, 19 + "verbatimModuleSyntax": true, 20 + "isolatedModules": true, 21 + "noUncheckedSideEffectImports": true, 22 + "moduleDetection": "force", 23 + "skipLibCheck": true, 24 + }, 25 + "include": ["crates/**/js", "website/assets"], 26 + "exclude": ["node_modules", "dist", "vendor"], 27 + }
+8
xtask/Cargo.toml
··· 1 + [package] 2 + name = "xtask" 3 + version = "0.1.0" 4 + edition = "2024" 5 + 6 + [dependencies] 7 + rolldown = { package = "brk_rolldown", version = "0.2.3" } 8 + tokio = { version = "1", features = ["rt"] }
+145
xtask/src/main.rs
··· 1 + use rolldown::{Bundler, BundlerOptions, InputItem, RawMinifyOptions}; 2 + use std::{ 3 + env, fs, 4 + path::{Path, PathBuf}, 5 + }; 6 + 7 + type DynError = Box<dyn std::error::Error>; 8 + 9 + fn main() { 10 + if let Err(e) = try_main() { 11 + eprintln!("{}", e); 12 + std::process::exit(-1); 13 + } 14 + } 15 + 16 + fn try_main() -> Result<(), DynError> { 17 + let task = env::args().nth(1); 18 + match task.as_deref() { 19 + Some("build-js") => build_js()?, 20 + Some("build-cli-js") => build_cli_js()?, 21 + Some("build-maudit-js") => build_maudit_js()?, 22 + _ => print_help(), 23 + } 24 + Ok(()) 25 + } 26 + 27 + fn print_help() { 28 + println!("Usage: cargo xtask <task>"); 29 + println!(); 30 + println!("Available tasks:"); 31 + println!(" build-js Bundle JavaScript/TypeScript assets for all crates"); 32 + println!(" build-cli-js Bundle JavaScript/TypeScript assets for the CLI crate"); 33 + println!(" build-maudit-js Bundle JavaScript/TypeScript assets for the maudit crate"); 34 + } 35 + 36 + fn build_js() -> Result<(), DynError> { 37 + println!("Building JavaScript for all crates..."); 38 + build_cli_js()?; 39 + build_maudit_js()?; 40 + println!("All JavaScript builds completed successfully!"); 41 + Ok(()) 42 + } 43 + 44 + fn build_cli_js() -> Result<(), DynError> { 45 + let workspace_root = project_root(); 46 + let cli_crate = workspace_root.join("crates/maudit-cli"); 47 + let js_src_dir = cli_crate.join("js"); 48 + let js_dist_dir = js_src_dir.join("dist"); 49 + 50 + println!("Building JavaScript for maudit-cli..."); 51 + 52 + // Ensure the dist directory exists 53 + fs::create_dir_all(&js_dist_dir)?; 54 + 55 + // Configure Rolldown bundler input 56 + let input_items = vec![InputItem { 57 + name: Some("client".to_string()), 58 + import: js_src_dir.join("client.ts").to_string_lossy().to_string(), 59 + }]; 60 + 61 + let bundler_options = BundlerOptions { 62 + input: Some(input_items), 63 + dir: Some(js_dist_dir.to_string_lossy().to_string()), 64 + format: Some(rolldown::OutputFormat::Esm), 65 + minify: Some(RawMinifyOptions::Bool(true)), 66 + ..Default::default() 67 + }; 68 + 69 + // Create and run the bundler 70 + let runtime = tokio::runtime::Runtime::new()?; 71 + 72 + runtime.block_on(async { 73 + let mut bundler = Bundler::new(bundler_options) 74 + .map_err(|e| format!("Failed to create bundler: {:?}", e))?; 75 + 76 + bundler 77 + .write() 78 + .await 79 + .map_err(|e| format!("Failed to bundle JavaScript: {:?}", e))?; 80 + 81 + println!( 82 + "Successfully bundled JavaScript files to {}", 83 + js_dist_dir.display() 84 + ); 85 + 86 + Ok::<(), DynError>(()) 87 + })?; 88 + 89 + Ok(()) 90 + } 91 + 92 + fn build_maudit_js() -> Result<(), DynError> { 93 + let workspace_root = project_root(); 94 + let maudit_crate = workspace_root.join("crates/maudit"); 95 + let js_src_dir = maudit_crate.join("js"); 96 + let js_dist_dir = js_src_dir.join("dist"); 97 + 98 + println!("Building JavaScript for maudit..."); 99 + 100 + // Ensure the dist directory exists 101 + fs::create_dir_all(&js_dist_dir)?; 102 + 103 + // Configure Rolldown bundler input 104 + let input_items = vec![InputItem { 105 + name: Some("preload".to_string()), 106 + import: js_src_dir.join("preload.ts").to_string_lossy().to_string(), 107 + }]; 108 + 109 + let bundler_options = BundlerOptions { 110 + input: Some(input_items), 111 + dir: Some(js_dist_dir.to_string_lossy().to_string()), 112 + format: Some(rolldown::OutputFormat::Esm), 113 + ..Default::default() 114 + }; 115 + 116 + // Create and run the bundler 117 + let runtime = tokio::runtime::Runtime::new()?; 118 + 119 + runtime.block_on(async { 120 + let mut bundler = Bundler::new(bundler_options) 121 + .map_err(|e| format!("Failed to create bundler: {:?}", e))?; 122 + 123 + bundler 124 + .write() 125 + .await 126 + .map_err(|e| format!("Failed to bundle JavaScript: {:?}", e))?; 127 + 128 + println!( 129 + "Successfully bundled JavaScript files to {}", 130 + js_dist_dir.display() 131 + ); 132 + 133 + Ok::<(), DynError>(()) 134 + })?; 135 + 136 + Ok(()) 137 + } 138 + 139 + fn project_root() -> PathBuf { 140 + Path::new(&env!("CARGO_MANIFEST_DIR")) 141 + .ancestors() 142 + .nth(1) 143 + .unwrap() 144 + .to_path_buf() 145 + }