fix(ci): fix rust/frontend/security job failures and expand local checks

This commit is contained in:
2026-01-30 21:22:01 -06:00
parent 3494341e3f
commit dd148e08a0
39 changed files with 331 additions and 481 deletions
+11
View File
@@ -0,0 +1,11 @@
# cargo-audit configuration
# https://github.com/rustsec/rustsec/tree/main/cargo-audit
[advisories]
# Transitive dependencies we can't control
ignore = [
# rsa: Marvin Attack timing sidechannel (via sqlx-mysql, no fix available)
"RUSTSEC-2023-0071",
# derivative: unmaintained (via poise)
"RUSTSEC-2024-0388",
]
+3 -3
View File
@@ -36,7 +36,7 @@ jobs:
fi fi
- name: Clippy - name: Clippy
run: cargo clippy --all-features -- -D warnings run: cargo clippy --no-default-features -- -D warnings
frontend-quality: frontend-quality:
name: Frontend Quality name: Frontend Quality
@@ -85,7 +85,7 @@ jobs:
cache-on-failure: true cache-on-failure: true
- name: Run tests - name: Run tests
run: cargo test --all-features run: cargo test --no-default-features
frontend-tests: frontend-tests:
name: Frontend Tests name: Frontend Tests
@@ -164,6 +164,6 @@ jobs:
- name: Upload Trivy results - name: Upload Trivy results
uses: github/codeql-action/upload-sarif@v3 uses: github/codeql-action/upload-sarif@v3
if: always() if: always() && hashFiles('trivy-results.sarif') != ''
with: with:
sarif_file: trivy-results.sarif sarif_file: trivy-results.sarif
Generated
+153 -316
View File
@@ -182,14 +182,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
dependencies = [ dependencies = [
"axum-core", "axum-core",
"base64 0.22.1", "base64",
"bytes", "bytes",
"form_urlencoded", "form_urlencoded",
"futures-util", "futures-util",
"http 1.3.1", "http",
"http-body 1.0.1", "http-body",
"http-body-util", "http-body-util",
"hyper 1.7.0", "hyper",
"hyper-util", "hyper-util",
"itoa", "itoa",
"matchit", "matchit",
@@ -202,7 +202,7 @@ dependencies = [
"serde_path_to_error", "serde_path_to_error",
"serde_urlencoded", "serde_urlencoded",
"sha1", "sha1",
"sync_wrapper 1.0.2", "sync_wrapper",
"tokio", "tokio",
"tokio-tungstenite 0.28.0", "tokio-tungstenite 0.28.0",
"tower", "tower",
@@ -219,12 +219,12 @@ checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
"http 1.3.1", "http",
"http-body 1.0.1", "http-body",
"http-body-util", "http-body-util",
"mime", "mime",
"pin-project-lite", "pin-project-lite",
"sync_wrapper 1.0.2", "sync_wrapper",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
"tracing", "tracing",
@@ -242,8 +242,8 @@ dependencies = [
"form_urlencoded", "form_urlencoded",
"futures-core", "futures-core",
"futures-util", "futures-util",
"http 1.3.1", "http",
"http-body 1.0.1", "http-body",
"http-body-util", "http-body-util",
"mime", "mime",
"pin-project-lite", "pin-project-lite",
@@ -278,7 +278,7 @@ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
"axum-extra", "axum-extra",
"bitflags 2.9.4", "bitflags",
"chrono", "chrono",
"chrono-tz", "chrono-tz",
"clap", "clap",
@@ -293,14 +293,14 @@ dependencies = [
"governor", "governor",
"html-escape", "html-escape",
"htmlize", "htmlize",
"http 1.3.1", "http",
"mime_guess", "mime_guess",
"num-format", "num-format",
"poise", "poise",
"rand 0.9.2", "rand 0.9.2",
"rapidhash", "rapidhash",
"regex", "regex",
"reqwest 0.12.23", "reqwest",
"reqwest-middleware", "reqwest-middleware",
"rust-embed", "rust-embed",
"serde", "serde",
@@ -322,12 +322,6 @@ dependencies = [
"yansi", "yansi",
] ]
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.22.1" version = "0.22.1"
@@ -340,12 +334,6 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.9.4" version = "2.9.4"
@@ -473,6 +461,12 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]] [[package]]
name = "chrono" name = "chrono"
version = "0.4.42" version = "0.4.42"
@@ -545,9 +539,9 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]] [[package]]
name = "command_attr" name = "command_attr"
version = "0.5.3" version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fcc89439e1bb4e19050a9586a767781a3060000d2f3296fd2a40597ad9421c5" checksum = "8208103c5e25a091226dfa8d61d08d0561cc14f31b25691811ba37d4ec9b157b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1146,15 +1140,6 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.7" version = "0.14.7"
@@ -1172,8 +1157,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"js-sys",
"libc", "libc",
"wasi 0.11.1+wasi-snapshot-preview1", "wasi 0.11.1+wasi-snapshot-preview1",
"wasm-bindgen",
] ]
[[package]] [[package]]
@@ -1238,25 +1225,6 @@ dependencies = [
"web-time", "web-time",
] ]
[[package]]
name = "h2"
version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 0.2.12",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.4.12" version = "0.4.12"
@@ -1268,7 +1236,7 @@ dependencies = [
"fnv", "fnv",
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"http 1.3.1", "http",
"indexmap", "indexmap",
"slab", "slab",
"tokio", "tokio",
@@ -1363,17 +1331,6 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "http"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]] [[package]]
name = "http" name = "http"
version = "1.3.1" version = "1.3.1"
@@ -1385,17 +1342,6 @@ dependencies = [
"itoa", "itoa",
] ]
[[package]]
name = "http-body"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http 0.2.12",
"pin-project-lite",
]
[[package]] [[package]]
name = "http-body" name = "http-body"
version = "1.0.1" version = "1.0.1"
@@ -1403,7 +1349,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [ dependencies = [
"bytes", "bytes",
"http 1.3.1", "http",
] ]
[[package]] [[package]]
@@ -1414,8 +1360,8 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
"http 1.3.1", "http",
"http-body 1.0.1", "http-body",
"pin-project-lite", "pin-project-lite",
] ]
@@ -1431,30 +1377,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "0.14.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2 0.3.27",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2 0.5.10",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "1.7.0" version = "1.7.0"
@@ -1465,9 +1387,9 @@ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"h2 0.4.12", "h2",
"http 1.3.1", "http",
"http-body 1.0.1", "http-body",
"httparse", "httparse",
"httpdate", "httpdate",
"itoa", "itoa",
@@ -1478,34 +1400,21 @@ dependencies = [
"want", "want",
] ]
[[package]]
name = "hyper-rustls"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [
"futures-util",
"http 0.2.12",
"hyper 0.14.32",
"rustls 0.21.12",
"tokio",
"tokio-rustls 0.24.1",
]
[[package]] [[package]]
name = "hyper-rustls" name = "hyper-rustls"
version = "0.27.7" version = "0.27.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
dependencies = [ dependencies = [
"http 1.3.1", "http",
"hyper 1.7.0", "hyper",
"hyper-util", "hyper-util",
"rustls 0.23.31", "rustls 0.23.31",
"rustls-pki-types", "rustls-pki-types",
"tokio", "tokio",
"tokio-rustls 0.26.2", "tokio-rustls 0.26.2",
"tower-service", "tower-service",
"webpki-roots 1.0.2",
] ]
[[package]] [[package]]
@@ -1516,7 +1425,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [ dependencies = [
"bytes", "bytes",
"http-body-util", "http-body-util",
"hyper 1.7.0", "hyper",
"hyper-util", "hyper-util",
"native-tls", "native-tls",
"tokio", "tokio",
@@ -1530,20 +1439,20 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"bytes", "bytes",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-util", "futures-util",
"http 1.3.1", "http",
"http-body 1.0.1", "http-body",
"hyper 1.7.0", "hyper",
"ipnet", "ipnet",
"libc", "libc",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"socket2 0.6.0", "socket2",
"system-configuration 0.6.1", "system-configuration",
"tokio", "tokio",
"tower-service", "tower-service",
"tracing", "tracing",
@@ -1709,7 +1618,7 @@ version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags",
"cfg-if", "cfg-if",
"libc", "libc",
] ]
@@ -1795,7 +1704,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags",
"libc", "libc",
"redox_syscall", "redox_syscall",
] ]
@@ -1844,6 +1753,12 @@ version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "lru-slab"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]] [[package]]
name = "matchers" name = "matchers"
version = "0.2.0" version = "0.2.0"
@@ -2048,7 +1963,7 @@ version = "0.10.73"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags",
"cfg-if", "cfg-if",
"foreign-types", "foreign-types",
"libc", "libc",
@@ -2357,7 +2272,7 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags",
"memchr", "memchr",
"unicase", "unicase",
] ]
@@ -2377,6 +2292,61 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "quinn"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
dependencies = [
"bytes",
"cfg_aliases",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustls 0.23.31",
"socket2",
"thiserror 2.0.16",
"tokio",
"tracing",
"web-time",
]
[[package]]
name = "quinn-proto"
version = "0.11.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
dependencies = [
"bytes",
"getrandom 0.3.3",
"lru-slab",
"rand 0.9.2",
"ring",
"rustc-hash",
"rustls 0.23.31",
"rustls-pki-types",
"slab",
"thiserror 2.0.16",
"tinyvec",
"tracing",
"web-time",
]
[[package]]
name = "quinn-udp"
version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2",
"tracing",
"windows-sys 0.60.2",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.40" version = "1.0.40"
@@ -2466,7 +2436,7 @@ version = "11.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags",
] ]
[[package]] [[package]]
@@ -2475,7 +2445,7 @@ version = "0.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags",
] ]
[[package]] [[package]]
@@ -2507,90 +2477,54 @@ version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
[[package]]
name = "reqwest"
version = "0.11.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
dependencies = [
"base64 0.21.7",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2 0.3.27",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.32",
"hyper-rustls 0.24.2",
"ipnet",
"js-sys",
"log",
"mime",
"mime_guess",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls 0.21.12",
"rustls-pemfile",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 0.1.2",
"system-configuration 0.5.1",
"tokio",
"tokio-rustls 0.24.1",
"tokio-util",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"webpki-roots 0.25.4",
"winreg",
]
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.12.23" version = "0.12.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"bytes", "bytes",
"cookie", "cookie",
"cookie_store", "cookie_store",
"encoding_rs", "encoding_rs",
"futures-core", "futures-core",
"h2 0.4.12", "futures-util",
"http 1.3.1", "h2",
"http-body 1.0.1", "http",
"http-body",
"http-body-util", "http-body-util",
"hyper 1.7.0", "hyper",
"hyper-rustls 0.27.7", "hyper-rustls",
"hyper-tls", "hyper-tls",
"hyper-util", "hyper-util",
"js-sys", "js-sys",
"log", "log",
"mime", "mime",
"mime_guess",
"native-tls", "native-tls",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"quinn",
"rustls 0.23.31",
"rustls-pki-types", "rustls-pki-types",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"sync_wrapper 1.0.2", "sync_wrapper",
"tokio", "tokio",
"tokio-native-tls", "tokio-native-tls",
"tokio-rustls 0.26.2",
"tokio-util",
"tower", "tower",
"tower-http", "tower-http",
"tower-service", "tower-service",
"url", "url",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasm-streams",
"web-sys", "web-sys",
"webpki-roots 1.0.2",
] ]
[[package]] [[package]]
@@ -2601,8 +2535,8 @@ checksum = "57f17d28a6e6acfe1733fe24bcd30774d13bffa4b8a22535b4c8c98423088d4e"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
"http 1.3.1", "http",
"reqwest 0.12.23", "reqwest",
"serde", "serde",
"thiserror 1.0.69", "thiserror 1.0.69",
"tower-service", "tower-service",
@@ -2683,6 +2617,12 @@ version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
[[package]]
name = "rustc-hash"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.4.1" version = "0.4.1"
@@ -2698,25 +2638,13 @@ version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags",
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
"windows-sys 0.60.2", "windows-sys 0.60.2",
] ]
[[package]]
name = "rustls"
version = "0.21.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
dependencies = [
"log",
"ring",
"rustls-webpki 0.101.7",
"sct",
]
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.22.4" version = "0.22.4"
@@ -2745,34 +2673,16 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64 0.21.7",
]
[[package]] [[package]]
name = "rustls-pki-types" name = "rustls-pki-types"
version = "1.12.0" version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
dependencies = [ dependencies = [
"web-time",
"zeroize", "zeroize",
] ]
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring",
"untrusted",
]
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
version = "0.102.8" version = "0.102.8"
@@ -2831,16 +2741,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted",
]
[[package]] [[package]]
name = "secrecy" name = "secrecy"
version = "0.8.0" version = "0.8.0"
@@ -2857,7 +2757,7 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags",
"core-foundation", "core-foundation",
"core-foundation-sys", "core-foundation-sys",
"libc", "libc",
@@ -2980,26 +2880,26 @@ dependencies = [
[[package]] [[package]]
name = "serenity" name = "serenity"
version = "0.12.4" version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d72ec4323681bf9a3cabe40fd080abc2435859b502a1b5aa9bf693f125bfa76" checksum = "9bde37f42765dfdc34e2a039e0c84afbf79a3101c1941763b0beb816c2f17541"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"async-trait", "async-trait",
"base64 0.22.1", "base64",
"bitflags 2.9.4", "bitflags",
"bytes", "bytes",
"chrono", "chrono",
"command_attr", "command_attr",
"dashmap 5.5.3", "dashmap 5.5.3",
"flate2", "flate2",
"futures", "futures",
"fxhash",
"levenshtein", "levenshtein",
"mime_guess", "mime_guess",
"parking_lot", "parking_lot",
"percent-encoding", "percent-encoding",
"reqwest 0.11.27", "reqwest",
"rustc-hash",
"secrecy", "secrecy",
"serde", "serde",
"serde_cow", "serde_cow",
@@ -3107,16 +3007,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "socket2"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.6.0" version = "0.6.0"
@@ -3174,7 +3064,7 @@ version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"bytes", "bytes",
"chrono", "chrono",
"crc", "crc",
@@ -3250,8 +3140,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526"
dependencies = [ dependencies = [
"atoi", "atoi",
"base64 0.22.1", "base64",
"bitflags 2.9.4", "bitflags",
"byteorder", "byteorder",
"bytes", "bytes",
"chrono", "chrono",
@@ -3293,8 +3183,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46"
dependencies = [ dependencies = [
"atoi", "atoi",
"base64 0.22.1", "base64",
"bitflags 2.9.4", "bitflags",
"byteorder", "byteorder",
"chrono", "chrono",
"crc", "crc",
@@ -3406,12 +3296,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]] [[package]]
name = "sync_wrapper" name = "sync_wrapper"
version = "1.0.2" version = "1.0.2"
@@ -3432,36 +3316,15 @@ dependencies = [
"syn 2.0.106", "syn 2.0.106",
] ]
[[package]]
name = "system-configuration"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"system-configuration-sys 0.5.0",
]
[[package]] [[package]]
name = "system-configuration" name = "system-configuration"
version = "0.6.1" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags",
"core-foundation", "core-foundation",
"system-configuration-sys 0.6.0", "system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
dependencies = [
"core-foundation-sys",
"libc",
] ]
[[package]] [[package]]
@@ -3621,7 +3484,7 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
"slab", "slab",
"socket2 0.6.0", "socket2",
"tokio-macros", "tokio-macros",
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
@@ -3647,16 +3510,6 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tokio-rustls"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
"rustls 0.21.12",
"tokio",
]
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.25.0" version = "0.25.0"
@@ -3780,7 +3633,7 @@ dependencies = [
"futures-core", "futures-core",
"futures-util", "futures-util",
"pin-project-lite", "pin-project-lite",
"sync_wrapper 1.0.2", "sync_wrapper",
"tokio", "tokio",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
@@ -3794,12 +3647,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
dependencies = [ dependencies = [
"async-compression", "async-compression",
"bitflags 2.9.4", "bitflags",
"bytes", "bytes",
"futures-core", "futures-core",
"futures-util", "futures-util",
"http 1.3.1", "http",
"http-body 1.0.1", "http-body",
"iri-string", "iri-string",
"pin-project-lite", "pin-project-lite",
"tokio", "tokio",
@@ -3942,7 +3795,7 @@ dependencies = [
"byteorder", "byteorder",
"bytes", "bytes",
"data-encoding", "data-encoding",
"http 1.3.1", "http",
"httparse", "httparse",
"log", "log",
"rand 0.8.5", "rand 0.8.5",
@@ -3962,7 +3815,7 @@ checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442"
dependencies = [ dependencies = [
"bytes", "bytes",
"data-encoding", "data-encoding",
"http 1.3.1", "http",
"httparse", "httparse",
"log", "log",
"rand 0.9.2", "rand 0.9.2",
@@ -4270,12 +4123,6 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "webpki-roots"
version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]] [[package]]
name = "webpki-roots" name = "webpki-roots"
version = "0.26.11" version = "0.26.11"
@@ -4642,16 +4489,6 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "winreg"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.45.0" version = "0.45.0"
+3 -1
View File
@@ -38,7 +38,7 @@ check *flags:
], ],
}, },
biome: { biome: {
peers: ["svelte-check", "web-test"], peers: ["svelte-check", "biome-lint", "web-test"],
format: () => run(["bun", "run", "--cwd", "web", "format"]), format: () => run(["bun", "run", "--cwd", "web", "format"]),
recheck: [ recheck: [
{ name: "biome", cmd: ["bun", "run", "--cwd", "web", "format:check"] }, { name: "biome", cmd: ["bun", "run", "--cwd", "web", "format:check"] },
@@ -53,7 +53,9 @@ check *flags:
{ name: "rust-test", cmd: ["cargo", "nextest", "run", "-E", "not test(export_bindings)"] }, { name: "rust-test", cmd: ["cargo", "nextest", "run", "-E", "not test(export_bindings)"] },
{ name: "svelte-check", cmd: ["bun", "run", "--cwd", "web", "check"] }, { name: "svelte-check", cmd: ["bun", "run", "--cwd", "web", "check"] },
{ name: "biome", cmd: ["bun", "run", "--cwd", "web", "format:check"] }, { name: "biome", cmd: ["bun", "run", "--cwd", "web", "format:check"] },
{ name: "biome-lint", cmd: ["bun", "run", "--cwd", "web", "lint"] },
{ name: "web-test", cmd: ["bun", "run", "--cwd", "web", "test"] }, { name: "web-test", cmd: ["bun", "run", "--cwd", "web", "test"] },
{ name: "actionlint", cmd: ["actionlint"] },
// { name: "sqlx-prepare", cmd: ["cargo", "sqlx", "prepare", "--check"] }, // { name: "sqlx-prepare", cmd: ["cargo", "sqlx", "prepare", "--check"] },
]; ];
+4 -4
View File
@@ -1,4 +1,7 @@
#!/usr/bin/env bun #!/usr/bin/env bun
import { extname, join } from "path";
import { constants, brotliCompressSync, gzipSync } from "zlib";
import { $ } from "bun";
/** /**
* Pre-compress static assets with maximum compression levels. * Pre-compress static assets with maximum compression levels.
* Run after `bun run build`. * Run after `bun run build`.
@@ -7,10 +10,7 @@
* These are embedded alongside originals by rust-embed and served via * These are embedded alongside originals by rust-embed and served via
* content negotiation in src/web/assets.rs. * content negotiation in src/web/assets.rs.
*/ */
import { readdir, stat, readFile, writeFile } from "fs/promises"; import { readFile, readdir, stat, writeFile } from "fs/promises";
import { join, extname } from "path";
import { gzipSync, brotliCompressSync, constants } from "zlib";
import { $ } from "bun";
// Must match COMPRESSION_MIN_SIZE in src/web/encoding.rs // Must match COMPRESSION_MIN_SIZE in src/web/encoding.rs
const MIN_SIZE = 512; const MIN_SIZE = 512;
+11 -11
View File
@@ -1,31 +1,31 @@
<script lang="ts"> <script lang="ts">
import type { CourseResponse } from "$lib/api"; import type { CourseResponse } from "$lib/api";
import { useClipboard } from "$lib/composables/useClipboard.svelte";
import { import {
formatTime, RMP_CONFIDENCE_THRESHOLD,
formatCreditHours, formatCreditHours,
formatDate, formatDate,
formatMeetingDaysLong, formatMeetingDaysLong,
formatTime,
isMeetingTimeTBA, isMeetingTimeTBA,
isTimeTBA, isTimeTBA,
ratingStyle, ratingStyle,
rmpUrl, rmpUrl,
RMP_CONFIDENCE_THRESHOLD,
} from "$lib/course"; } from "$lib/course";
import { themeStore } from "$lib/stores/theme.svelte"; import { themeStore } from "$lib/stores/theme.svelte";
import { useClipboard } from "$lib/composables/useClipboard.svelte"; import { cn, formatNumber, tooltipContentClass } from "$lib/utils";
import { cn, tooltipContentClass, formatNumber } from "$lib/utils";
import { Tooltip } from "bits-ui";
import SimpleTooltip from "./SimpleTooltip.svelte";
import { import {
Info, Calendar,
Copy,
Check, Check,
Copy,
Download,
ExternalLink,
Info,
Star, Star,
Triangle, Triangle,
ExternalLink,
Calendar,
Download,
} from "@lucide/svelte"; } from "@lucide/svelte";
import { Tooltip } from "bits-ui";
import SimpleTooltip from "./SimpleTooltip.svelte";
let { course }: { course: CourseResponse } = $props(); let { course }: { course: CourseResponse } = $props();
+22 -22
View File
@@ -1,6 +1,10 @@
<script lang="ts"> <script lang="ts">
import type { CourseResponse } from "$lib/api"; import type { CourseResponse } from "$lib/api";
import { FlexRender, createSvelteTable } from "$lib/components/ui/data-table/index.js";
import { useClipboard } from "$lib/composables/useClipboard.svelte";
import { useOverlayScrollbars } from "$lib/composables/useOverlayScrollbars.svelte";
import { import {
RMP_CONFIDENCE_THRESHOLD,
abbreviateInstructor, abbreviateInstructor,
concernAccentColor, concernAccentColor,
formatLocationDisplay, formatLocationDisplay,
@@ -13,40 +17,36 @@ import {
isMeetingTimeTBA, isMeetingTimeTBA,
isTimeTBA, isTimeTBA,
openSeats, openSeats,
seatsColor,
seatsDotColor,
ratingStyle, ratingStyle,
rmpUrl, rmpUrl,
RMP_CONFIDENCE_THRESHOLD, seatsColor,
seatsDotColor,
} from "$lib/course"; } from "$lib/course";
import { themeStore } from "$lib/stores/theme.svelte"; import { themeStore } from "$lib/stores/theme.svelte";
import { useClipboard } from "$lib/composables/useClipboard.svelte"; import { cn, formatNumber, tooltipContentClass } from "$lib/utils";
import { useOverlayScrollbars } from "$lib/composables/useOverlayScrollbars.svelte";
import CourseDetail from "./CourseDetail.svelte";
import { fade, fly, slide } from "svelte/transition";
import { flip } from "svelte/animate";
import { createSvelteTable, FlexRender } from "$lib/components/ui/data-table/index.js";
import { import {
getCoreRowModel,
getSortedRowModel,
type ColumnDef,
type SortingState,
type VisibilityState,
type Updater,
} from "@tanstack/table-core";
import {
ArrowUp,
ArrowDown, ArrowDown,
ArrowUp,
ArrowUpDown, ArrowUpDown,
Columns3,
Check, Check,
Columns3,
ExternalLink,
RotateCcw, RotateCcw,
Star, Star,
Triangle, Triangle,
ExternalLink,
} from "@lucide/svelte"; } from "@lucide/svelte";
import { DropdownMenu, ContextMenu, Tooltip } from "bits-ui"; import {
import { cn, tooltipContentClass, formatNumber } from "$lib/utils"; type ColumnDef,
type SortingState,
type Updater,
type VisibilityState,
getCoreRowModel,
getSortedRowModel,
} from "@tanstack/table-core";
import { ContextMenu, DropdownMenu, Tooltip } from "bits-ui";
import { flip } from "svelte/animate";
import { fade, fly, slide } from "svelte/transition";
import CourseDetail from "./CourseDetail.svelte";
import SimpleTooltip from "./SimpleTooltip.svelte"; import SimpleTooltip from "./SimpleTooltip.svelte";
let { let {
@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { page } from "$app/state"; import { page } from "$app/state";
import { TriangleAlert, RotateCcw } from "@lucide/svelte"; import { RotateCcw, TriangleAlert } from "@lucide/svelte";
interface Props { interface Props {
/** Heading shown in the error card */ /** Heading shown in the error card */
+1 -1
View File
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { page } from "$app/state"; import { page } from "$app/state";
import { Search, User, Clock } from "@lucide/svelte";
import { authStore } from "$lib/auth.svelte"; import { authStore } from "$lib/auth.svelte";
import { Clock, Search, User } from "@lucide/svelte";
import ThemeToggle from "./ThemeToggle.svelte"; import ThemeToggle from "./ThemeToggle.svelte";
const staticTabs = [ const staticTabs = [
+3 -3
View File
@@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import { Select } from "bits-ui";
import { ChevronUp, ChevronDown } from "@lucide/svelte";
import type { Action } from "svelte/action";
import { formatNumber } from "$lib/utils"; import { formatNumber } from "$lib/utils";
import { ChevronDown, ChevronUp } from "@lucide/svelte";
import { Select } from "bits-ui";
import type { Action } from "svelte/action";
const slideIn: Action<HTMLElement, number> = (node, direction) => { const slideIn: Action<HTMLElement, number> = (node, direction) => {
if (direction !== 0) { if (direction !== 0) {
+2 -2
View File
@@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { Term, Subject } from "$lib/api"; import type { Subject, Term } from "$lib/api";
import SimpleTooltip from "./SimpleTooltip.svelte"; import SimpleTooltip from "./SimpleTooltip.svelte";
import TermCombobox from "./TermCombobox.svelte";
import SubjectCombobox from "./SubjectCombobox.svelte"; import SubjectCombobox from "./SubjectCombobox.svelte";
import TermCombobox from "./TermCombobox.svelte";
let { let {
terms, terms,
+1 -1
View File
@@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte";
import SimpleTooltip from "$lib/components/SimpleTooltip.svelte"; import SimpleTooltip from "$lib/components/SimpleTooltip.svelte";
import { relativeTime } from "$lib/time"; import { relativeTime } from "$lib/time";
import { formatNumber } from "$lib/utils"; import { formatNumber } from "$lib/utils";
import { onMount } from "svelte";
export interface SearchMeta { export interface SearchMeta {
totalCount: number; totalCount: number;
+1 -1
View File
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { cn } from "$lib/utils";
import { Tooltip } from "bits-ui"; import { Tooltip } from "bits-ui";
import type { Snippet } from "svelte"; import type { Snippet } from "svelte";
import { cn } from "$lib/utils";
let { let {
text, text,
@@ -1,9 +1,9 @@
<script lang="ts"> <script lang="ts">
import { Combobox } from "bits-ui";
import { Check, ChevronsUpDown } from "@lucide/svelte";
import { fly } from "svelte/transition";
import type { Subject } from "$lib/api"; import type { Subject } from "$lib/api";
import { formatNumber } from "$lib/utils"; import { formatNumber } from "$lib/utils";
import { Check, ChevronsUpDown } from "@lucide/svelte";
import { Combobox } from "bits-ui";
import { fly } from "svelte/transition";
let { let {
subjects, subjects,
+3 -3
View File
@@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import { Combobox } from "bits-ui";
import { Check, ChevronsUpDown } from "@lucide/svelte";
import { fly } from "svelte/transition";
import type { Term } from "$lib/api"; import type { Term } from "$lib/api";
import { Check, ChevronsUpDown } from "@lucide/svelte";
import { Combobox } from "bits-ui";
import { fly } from "svelte/transition";
let { let {
terms, terms,
+2 -2
View File
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { tick } from "svelte";
import { Moon, Sun } from "@lucide/svelte";
import { themeStore } from "$lib/stores/theme.svelte"; import { themeStore } from "$lib/stores/theme.svelte";
import { Moon, Sun } from "@lucide/svelte";
import { tick } from "svelte";
import SimpleTooltip from "./SimpleTooltip.svelte"; import SimpleTooltip from "./SimpleTooltip.svelte";
/** /**
+42 -42
View File
@@ -1,60 +1,60 @@
<script lang="ts"> <script lang="ts">
import { scaleLinear, scaleTime } from "d3-scale";
import { onMount } from "svelte"; import { onMount } from "svelte";
import { scaleTime, scaleLinear } from "d3-scale";
import type { TimeSlot, ChartContext } from "$lib/timeline/types";
import {
PADDING,
DEFAULT_AXIS_RATIO,
CHART_HEIGHT_RATIO,
MIN_SPAN_MS,
MAX_SPAN_MS,
DEFAULT_SPAN_MS,
ZOOM_FACTOR,
ZOOM_KEY_FACTOR,
ZOOM_EASE,
ZOOM_SETTLE_THRESHOLD,
PAN_FRICTION,
PAN_STOP_THRESHOLD,
PAN_STOP_THRESHOLD_Y,
VELOCITY_SAMPLE_WINDOW,
VELOCITY_MIN_DT,
PAN_STEP_RATIO,
PAN_STEP_CTRL_RATIO,
PAN_EASE,
PAN_SETTLE_THRESHOLD_PX,
YRATIO_STEP,
YRATIO_MIN,
YRATIO_MAX,
YRATIO_SETTLE_THRESHOLD,
FOLLOW_EASE,
MIN_MAXY,
MAX_DT,
DEFAULT_DT,
TAP_MAX_DURATION_MS,
TAP_MAX_DISTANCE_PX,
} from "$lib/timeline/constants";
import { createTimelineStore } from "$lib/timeline/store.svelte";
import { import {
createAnimMap, createAnimMap,
syncAnimTargets,
stepAnimations,
pruneAnimMap, pruneAnimMap,
stepAnimations,
syncAnimTargets,
} from "$lib/timeline/animation"; } from "$lib/timeline/animation";
import { import {
getVisibleSlots, CHART_HEIGHT_RATIO,
findSlotByTime, DEFAULT_AXIS_RATIO,
snapToSlot, DEFAULT_DT,
enabledTotalClasses, DEFAULT_SPAN_MS,
} from "$lib/timeline/viewport"; FOLLOW_EASE,
MAX_DT,
MAX_SPAN_MS,
MIN_MAXY,
MIN_SPAN_MS,
PADDING,
PAN_EASE,
PAN_FRICTION,
PAN_SETTLE_THRESHOLD_PX,
PAN_STEP_CTRL_RATIO,
PAN_STEP_RATIO,
PAN_STOP_THRESHOLD,
PAN_STOP_THRESHOLD_Y,
TAP_MAX_DISTANCE_PX,
TAP_MAX_DURATION_MS,
VELOCITY_MIN_DT,
VELOCITY_SAMPLE_WINDOW,
YRATIO_MAX,
YRATIO_MIN,
YRATIO_SETTLE_THRESHOLD,
YRATIO_STEP,
ZOOM_EASE,
ZOOM_FACTOR,
ZOOM_KEY_FACTOR,
ZOOM_SETTLE_THRESHOLD,
} from "$lib/timeline/constants";
import { import {
drawGrid, drawGrid,
drawHoverColumn, drawHoverColumn,
drawStackedArea,
drawNowLine, drawNowLine,
drawStackedArea,
drawTimeAxis, drawTimeAxis,
stackVisibleSlots, stackVisibleSlots,
} from "$lib/timeline/renderer"; } from "$lib/timeline/renderer";
import { createTimelineStore } from "$lib/timeline/store.svelte";
import type { ChartContext, TimeSlot } from "$lib/timeline/types";
import {
enabledTotalClasses,
findSlotByTime,
getVisibleSlots,
snapToSlot,
} from "$lib/timeline/viewport";
import TimelineDrawer from "./TimelineDrawer.svelte"; import TimelineDrawer from "./TimelineDrawer.svelte";
import TimelineTooltip from "./TimelineTooltip.svelte"; import TimelineTooltip from "./TimelineTooltip.svelte";
+2 -2
View File
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { Filter, X } from "@lucide/svelte";
import { getSubjectColor } from "$lib/timeline/data";
import { DRAWER_WIDTH } from "$lib/timeline/constants"; import { DRAWER_WIDTH } from "$lib/timeline/constants";
import { getSubjectColor } from "$lib/timeline/data";
import { Filter, X } from "@lucide/svelte";
interface Props { interface Props {
open: boolean; open: boolean;
@@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import { timeFormat } from "d3-time-format";
import { getSubjectColor } from "$lib/timeline/data"; import { getSubjectColor } from "$lib/timeline/data";
import type { TimeSlot } from "$lib/timeline/types"; import type { TimeSlot } from "$lib/timeline/types";
import { enabledTotalClasses } from "$lib/timeline/viewport"; import { enabledTotalClasses } from "$lib/timeline/viewport";
import { timeFormat } from "d3-time-format";
interface Props { interface Props {
visible: boolean; visible: boolean;
@@ -1,6 +1,6 @@
import { onMount } from "svelte";
import { OverlayScrollbars, type PartialOptions } from "overlayscrollbars";
import { themeStore } from "$lib/stores/theme.svelte"; import { themeStore } from "$lib/stores/theme.svelte";
import { OverlayScrollbars, type PartialOptions } from "overlayscrollbars";
import { onMount } from "svelte";
/** /**
* Set up OverlayScrollbars on an element with automatic theme reactivity. * Set up OverlayScrollbars on an element with automatic theme reactivity.
+9 -9
View File
@@ -1,22 +1,22 @@
import { describe, it, expect } from "vitest"; import type { CourseResponse, DbMeetingTime, InstructorResponse } from "$lib/api";
import { import {
formatTime, abbreviateInstructor,
formatTimeRange, formatCreditHours,
formatDate,
formatDateShort,
formatMeetingDays, formatMeetingDays,
formatMeetingDaysLong,
formatMeetingDaysVerbose, formatMeetingDaysVerbose,
formatMeetingTime, formatMeetingTime,
formatMeetingTimeTooltip, formatMeetingTimeTooltip,
formatMeetingTimesTooltip, formatMeetingTimesTooltip,
abbreviateInstructor, formatTime,
formatCreditHours, formatTimeRange,
getPrimaryInstructor, getPrimaryInstructor,
isMeetingTimeTBA, isMeetingTimeTBA,
isTimeTBA, isTimeTBA,
formatDate,
formatDateShort,
formatMeetingDaysLong,
} from "$lib/course"; } from "$lib/course";
import type { DbMeetingTime, CourseResponse, InstructorResponse } from "$lib/api"; import { describe, expect, it } from "vitest";
function makeMeetingTime(overrides: Partial<DbMeetingTime> = {}): DbMeetingTime { function makeMeetingTime(overrides: Partial<DbMeetingTime> = {}): DbMeetingTime {
return { return {
+1 -1
View File
@@ -1,4 +1,4 @@
import type { DbMeetingTime, CourseResponse, InstructorResponse } from "$lib/api"; import type { CourseResponse, DbMeetingTime, InstructorResponse } from "$lib/api";
/** Convert "0900" to "9:00 AM" */ /** Convert "0900" to "9:00 AM" */
export function formatTime(time: string | null): string { export function formatTime(time: string | null): string {
+2 -2
View File
@@ -1,5 +1,5 @@
import { describe, it, expect } from "vitest"; import { describe, expect, it } from "vitest";
import { termToFriendly, termToBanner } from "./term-format"; import { termToBanner, termToFriendly } from "./term-format";
describe("termToFriendly", () => { describe("termToFriendly", () => {
it("converts spring term correctly", () => { it("converts spring term correctly", () => {
+1 -1
View File
@@ -5,7 +5,7 @@
* targets. This module owns the AnimMap lifecycle: syncing targets, * targets. This module owns the AnimMap lifecycle: syncing targets,
* stepping current values, and pruning offscreen entries. * stepping current values, and pruning offscreen entries.
*/ */
import { VALUE_EASE, MAXY_EASE, SETTLE_THRESHOLD, MIN_MAXY } from "./constants"; import { MAXY_EASE, MIN_MAXY, SETTLE_THRESHOLD, VALUE_EASE } from "./constants";
import type { AnimEntry, TimeSlot } from "./types"; import type { AnimEntry, TimeSlot } from "./types";
export type AnimMap = Map<number, Map<string, AnimEntry>>; export type AnimMap = Map<number, Map<string, AnimEntry>>;
+14 -14
View File
@@ -4,28 +4,28 @@
* Every function takes a {@link ChartContext} plus any data it needs. * Every function takes a {@link ChartContext} plus any data it needs.
* No Svelte reactivity, no side-effects beyond drawing on the context. * No Svelte reactivity, no side-effects beyond drawing on the context.
*/ */
import { stack, area, curveMonotoneX, type Series } from "d3-shape"; import { type Series, area, curveMonotoneX, stack } from "d3-shape";
import { timeFormat } from "d3-time-format"; import { timeFormat } from "d3-time-format";
import { getSubjectColor } from "./data";
import type { AnimMap } from "./animation"; import type { AnimMap } from "./animation";
import { getStackSubjects } from "./viewport";
import type { ChartContext, TimeSlot } from "./types";
import { import {
GRID_ALPHA,
HOUR_GRID_ALPHA,
NOW_LINE_WIDTH,
NOW_LINE_COLOR,
NOW_TRIANGLE_HEIGHT,
NOW_TRIANGLE_HALF_WIDTH,
NOW_LABEL_FONT,
HOVER_HIGHLIGHT_ALPHA,
AREA_FILL_ALPHA, AREA_FILL_ALPHA,
AREA_STROKE_ALPHA, AREA_STROKE_ALPHA,
SLOT_INTERVAL_MS,
SETTLE_THRESHOLD,
AXIS_FONT, AXIS_FONT,
GRID_ALPHA,
HOUR_GRID_ALPHA,
HOVER_HIGHLIGHT_ALPHA,
NOW_LABEL_FONT,
NOW_LINE_COLOR,
NOW_LINE_WIDTH,
NOW_TRIANGLE_HALF_WIDTH,
NOW_TRIANGLE_HEIGHT,
SETTLE_THRESHOLD,
SLOT_INTERVAL_MS,
} from "./constants"; } from "./constants";
import { getSubjectColor } from "./data";
import type { ChartContext, TimeSlot } from "./types";
import { getStackSubjects } from "./viewport";
// ── Formatters (allocated once) ───────────────────────────────────── // ── Formatters (allocated once) ─────────────────────────────────────
const fmtHour = timeFormat("%-I %p"); const fmtHour = timeFormat("%-I %p");
+1 -1
View File
@@ -5,7 +5,7 @@
* the missing segments when the view expands into unloaded territory. * the missing segments when the view expands into unloaded territory.
* Fetches are throttled so rapid panning/zooming doesn't flood the API. * Fetches are throttled so rapid panning/zooming doesn't flood the API.
*/ */
import { client, type TimelineRange } from "$lib/api"; import { type TimelineRange, client } from "$lib/api";
import { SLOT_INTERVAL_MS } from "./constants"; import { SLOT_INTERVAL_MS } from "./constants";
import type { TimeSlot } from "./types"; import type { TimeSlot } from "./types";
+1 -1
View File
@@ -2,7 +2,7 @@
* Pure viewport utility functions: binary search, visible-slot slicing, * Pure viewport utility functions: binary search, visible-slot slicing,
* hit-testing, and snapping for the timeline canvas. * hit-testing, and snapping for the timeline canvas.
*/ */
import { SLOT_INTERVAL_MS, RENDER_MARGIN_SLOTS } from "./constants"; import { RENDER_MARGIN_SLOTS, SLOT_INTERVAL_MS } from "./constants";
import type { TimeSlot } from "./types"; import type { TimeSlot } from "./types";
/** /**
+1 -1
View File
@@ -1,4 +1,4 @@
import { clsx, type ClassValue } from "clsx"; import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
+1 -1
View File
@@ -2,8 +2,8 @@
import { goto } from "$app/navigation"; import { goto } from "$app/navigation";
import { page } from "$app/state"; import { page } from "$app/state";
import { authStore } from "$lib/auth.svelte"; import { authStore } from "$lib/auth.svelte";
import PageTransition from "$lib/components/PageTransition.svelte";
import ErrorBoundaryFallback from "$lib/components/ErrorBoundaryFallback.svelte"; import ErrorBoundaryFallback from "$lib/components/ErrorBoundaryFallback.svelte";
import PageTransition from "$lib/components/PageTransition.svelte";
import { import {
Activity, Activity,
ClipboardList, ClipboardList,
+2 -2
View File
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { type AdminStatus, client } from "$lib/api";
import { client, type AdminStatus } from "$lib/api";
import { formatNumber } from "$lib/utils"; import { formatNumber } from "$lib/utils";
import { onMount } from "svelte";
let status = $state<AdminStatus | null>(null); let status = $state<AdminStatus | null>(null);
let error = $state<string | null>(null); let error = $state<string | null>(null);
@@ -1,13 +1,12 @@
<script lang="ts"> <script lang="ts">
import { onMount, onDestroy } from "svelte";
import { slide, fade } from "svelte/transition";
import { import {
client, type CandidateResponse,
type InstructorDetailResponse,
type InstructorListItem, type InstructorListItem,
type InstructorStats, type InstructorStats,
type InstructorDetailResponse, client,
type CandidateResponse,
} from "$lib/api"; } from "$lib/api";
import SimpleTooltip from "$lib/components/SimpleTooltip.svelte";
import { formatInstructorName, isRatingValid, ratingStyle } from "$lib/course"; import { formatInstructorName, isRatingValid, ratingStyle } from "$lib/course";
import { themeStore } from "$lib/stores/theme.svelte"; import { themeStore } from "$lib/stores/theme.svelte";
import { import {
@@ -19,7 +18,8 @@ import {
Search, Search,
X, X,
} from "@lucide/svelte"; } from "@lucide/svelte";
import SimpleTooltip from "$lib/components/SimpleTooltip.svelte"; import { onDestroy, onMount } from "svelte";
import { fade, slide } from "svelte/transition";
import CandidateCard from "./CandidateCard.svelte"; import CandidateCard from "./CandidateCard.svelte";
// --- State --- // --- State ---
+1 -1
View File
@@ -3,6 +3,7 @@ import { type ScrapeJob, client } from "$lib/api";
import { FlexRender, createSvelteTable } from "$lib/components/ui/data-table/index.js"; import { FlexRender, createSvelteTable } from "$lib/components/ui/data-table/index.js";
import { formatAbsoluteDate } from "$lib/date"; import { formatAbsoluteDate } from "$lib/date";
import { formatDuration } from "$lib/time"; import { formatDuration } from "$lib/time";
import { type ConnectionState, ScrapeJobsStore } from "$lib/ws";
import { ArrowDown, ArrowUp, ArrowUpDown, TriangleAlert } from "@lucide/svelte"; import { ArrowDown, ArrowUp, ArrowUpDown, TriangleAlert } from "@lucide/svelte";
import { import {
type ColumnDef, type ColumnDef,
@@ -12,7 +13,6 @@ import {
getSortedRowModel, getSortedRowModel,
} from "@tanstack/table-core"; } from "@tanstack/table-core";
import { onMount } from "svelte"; import { onMount } from "svelte";
import { type ConnectionState, ScrapeJobsStore } from "$lib/ws";
let jobs = $state<ScrapeJob[]>([]); let jobs = $state<ScrapeJob[]>([]);
let connectionState = $state<ConnectionState>("disconnected"); let connectionState = $state<ConnectionState>("disconnected");
@@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte";
import { client } from "$lib/api"; import { client } from "$lib/api";
import type { User } from "$lib/bindings"; import type { User } from "$lib/bindings";
import { Shield, ShieldOff } from "@lucide/svelte"; import { Shield, ShieldOff } from "@lucide/svelte";
import { onMount } from "svelte";
let users = $state<User[]>([]); let users = $state<User[]>([]);
let error = $state<string | null>(null); let error = $state<string | null>(null);
+3 -3
View File
@@ -2,14 +2,14 @@
import "overlayscrollbars/overlayscrollbars.css"; import "overlayscrollbars/overlayscrollbars.css";
import "./layout.css"; import "./layout.css";
import { page } from "$app/state"; import { page } from "$app/state";
import PageTransition from "$lib/components/PageTransition.svelte"; import { authStore } from "$lib/auth.svelte";
import ErrorBoundaryFallback from "$lib/components/ErrorBoundaryFallback.svelte";
import NavBar from "$lib/components/NavBar.svelte"; import NavBar from "$lib/components/NavBar.svelte";
import PageTransition from "$lib/components/PageTransition.svelte";
import { useOverlayScrollbars } from "$lib/composables/useOverlayScrollbars.svelte"; import { useOverlayScrollbars } from "$lib/composables/useOverlayScrollbars.svelte";
import { initNavigation } from "$lib/stores/navigation.svelte"; import { initNavigation } from "$lib/stores/navigation.svelte";
import { themeStore } from "$lib/stores/theme.svelte"; import { themeStore } from "$lib/stores/theme.svelte";
import { authStore } from "$lib/auth.svelte";
import { Tooltip } from "bits-ui"; import { Tooltip } from "bits-ui";
import ErrorBoundaryFallback from "$lib/components/ErrorBoundaryFallback.svelte";
import { onMount } from "svelte"; import { onMount } from "svelte";
let { children } = $props(); let { children } = $props();
+6 -6
View File
@@ -1,20 +1,20 @@
<script lang="ts"> <script lang="ts">
import { untrack } from "svelte";
import { goto } from "$app/navigation"; import { goto } from "$app/navigation";
import { import {
type Subject,
type SearchResponse, type SearchResponse,
type SortColumn, type SortColumn,
type SortDirection, type SortDirection,
type Subject,
client, client,
} from "$lib/api"; } from "$lib/api";
import type { SortingState } from "@tanstack/table-core"; import CourseTable from "$lib/components/CourseTable.svelte";
import Footer from "$lib/components/Footer.svelte";
import Pagination from "$lib/components/Pagination.svelte";
import SearchFilters from "$lib/components/SearchFilters.svelte"; import SearchFilters from "$lib/components/SearchFilters.svelte";
import SearchStatus, { type SearchMeta } from "$lib/components/SearchStatus.svelte"; import SearchStatus, { type SearchMeta } from "$lib/components/SearchStatus.svelte";
import CourseTable from "$lib/components/CourseTable.svelte";
import Pagination from "$lib/components/Pagination.svelte";
import Footer from "$lib/components/Footer.svelte";
import { termToBanner, termToFriendly } from "$lib/term-format"; import { termToBanner, termToFriendly } from "$lib/term-format";
import type { SortingState } from "@tanstack/table-core";
import { untrack } from "svelte";
let { data } = $props(); let { data } = $props();
+1 -1
View File
@@ -1,5 +1,5 @@
import type { PageLoad } from "./$types";
import { BannerApiClient } from "$lib/api"; import { BannerApiClient } from "$lib/api";
import type { PageLoad } from "./$types";
export const load: PageLoad = async ({ url, fetch }) => { export const load: PageLoad = async ({ url, fetch }) => {
const client = new BannerApiClient(undefined, fetch); const client = new BannerApiClient(undefined, fetch);
+6 -6
View File
@@ -1,5 +1,9 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { type ServiceInfo, type ServiceStatus, type StatusResponse, client } from "$lib/api";
import Footer from "$lib/components/Footer.svelte";
import SimpleTooltip from "$lib/components/SimpleTooltip.svelte";
import { relativeTime } from "$lib/time";
import { formatNumber } from "$lib/utils";
import { import {
Activity, Activity,
Bot, Bot,
@@ -12,11 +16,7 @@ import {
WifiOff, WifiOff,
XCircle, XCircle,
} from "@lucide/svelte"; } from "@lucide/svelte";
import SimpleTooltip from "$lib/components/SimpleTooltip.svelte"; import { onMount } from "svelte";
import Footer from "$lib/components/Footer.svelte";
import { type ServiceStatus, type ServiceInfo, type StatusResponse, client } from "$lib/api";
import { relativeTime } from "$lib/time";
import { formatNumber } from "$lib/utils";
const REFRESH_INTERVAL = import.meta.env.DEV ? 3000 : 30000; const REFRESH_INTERVAL = import.meta.env.DEV ? 3000 : 30000;
const REQUEST_TIMEOUT = 10000; const REQUEST_TIMEOUT = 10000;
+1 -1
View File
@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte";
import TimelineCanvas from "$lib/components/TimelineCanvas.svelte"; import TimelineCanvas from "$lib/components/TimelineCanvas.svelte";
import { onMount } from "svelte";
// Prevent body scroll while this page is mounted via a CSS class // Prevent body scroll while this page is mounted via a CSS class
// (avoids conflicting with other components that may manage overflow). // (avoids conflicting with other components that may manage overflow).
+2 -2
View File
@@ -1,8 +1,8 @@
import { existsSync, readFileSync } from "node:fs";
import { resolve } from "node:path";
import { sveltekit } from "@sveltejs/kit/vite"; import { sveltekit } from "@sveltejs/kit/vite";
import tailwindcss from "@tailwindcss/vite"; import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import { resolve } from "node:path";
import { readFileSync, existsSync } from "node:fs";
function getVersion() { function getVersion() {
const filename = "Cargo.toml"; const filename = "Cargo.toml";