Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 325753b

Browse files
committed
refactor(linter): remove usage of url crate
1 parent 580e5e6 commit 325753b

File tree

9 files changed

+71
-29
lines changed

9 files changed

+71
-29
lines changed

Cargo.lock

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ tower-lsp = "0.20.0"
198198
tracing-subscriber = "0.3.19"
199199
tsify = "0.4.5"
200200
ureq = { version = "3.0.0", default-features = false }
201-
url = "2.5.4"
202201
walkdir = "2.5.0"
203202
wasm-bindgen = "0.2.99"
204203

crates/oxc_linter/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ schemars = { workspace = true, features = ["indexmap2"] }
5858
serde = { workspace = true, features = ["derive"] }
5959
serde_json = { workspace = true }
6060
simdutf8 = { workspace = true }
61-
url = { workspace = true }
6261

6362
[dev-dependencies]
6463
insta = { workspace = true }

crates/oxc_linter/src/rules/nextjs/google_font_display.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use oxc_span::{GetSpan, Span};
66
use crate::{
77
context::LintContext,
88
rule::Rule,
9-
utils::{get_string_literal_prop_value, has_jsx_prop_ignore_case},
9+
utils::{find_url_query_value, get_string_literal_prop_value, has_jsx_prop_ignore_case},
1010
AstNode,
1111
};
1212

@@ -102,21 +102,13 @@ impl Rule for GoogleFontDisplay {
102102
};
103103

104104
if href_prop_value.starts_with("https://fonts.googleapis.com/css") {
105-
let Ok(url) = url::Url::parse(href_prop_value) else {
106-
return;
107-
};
108-
109-
let Some((_, display_value)) = url.query_pairs().find(|(key, _)| key == "display")
110-
else {
105+
let Some(display_value) = find_url_query_value(href_prop_value, "display") else {
111106
ctx.diagnostic(font_display_parameter_missing(jsx_opening_element_name.span));
112107
return;
113108
};
114109

115-
if matches!(&*display_value, "auto" | "block" | "fallback") {
116-
ctx.diagnostic(not_recommended_font_display_value(
117-
href_prop.span(),
118-
&display_value,
119-
));
110+
if matches!(display_value, "auto" | "block" | "fallback") {
111+
ctx.diagnostic(not_recommended_font_display_value(href_prop.span(), display_value));
120112
}
121113
}
122114
}

crates/oxc_linter/src/rules/nextjs/no_unwanted_polyfillio.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use cow_utils::CowUtils;
12
use oxc_ast::{
23
ast::{JSXAttributeItem, JSXAttributeName, JSXAttributeValue},
34
AstKind,
@@ -8,7 +9,11 @@ use oxc_semantic::AstNode;
89
use oxc_span::Span;
910
use phf::{phf_set, Set};
1011

11-
use crate::{context::LintContext, rule::Rule, utils::get_next_script_import_local_name};
12+
use crate::{
13+
context::LintContext,
14+
rule::Rule,
15+
utils::{find_url_query_value, get_next_script_import_local_name},
16+
};
1217

1318
fn no_unwanted_polyfillio_diagnostic(polyfill_name: &str, span: Span) -> OxcDiagnostic {
1419
OxcDiagnostic::warn(format!(
@@ -147,14 +152,14 @@ impl Rule for NoUnwantedPolyfillio {
147152
if src_value.value.as_str().starts_with("https://cdn.polyfill.io/v2/")
148153
|| src_value.value.as_str().starts_with("https://polyfill.io/v3/")
149154
{
150-
let Ok(url) = url::Url::parse(src_value.value.as_str()) else {
151-
return;
152-
};
153-
let Some((_, features_value)) = url.query_pairs().find(|(key, _)| key == "features")
155+
let Some(features_value) = find_url_query_value(src_value.value.as_str(), "features")
154156
else {
155157
return;
156158
};
157159

160+
// Replace URL encoded values
161+
let features_value = features_value.cow_replace("%2C", ",");
162+
158163
let unwanted_features: Vec<&str> = features_value
159164
.split(',')
160165
.filter(|feature| NEXT_POLYFILLED_FEATURES.contains(feature))

crates/oxc_linter/src/utils/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ mod promise;
77
mod react;
88
mod react_perf;
99
mod unicorn;
10+
mod url;
1011
mod vitest;
1112

1213
use std::{io, path::Path};
1314

1415
pub use self::{
1516
config::*, express::*, jest::*, jsdoc::*, nextjs::*, promise::*, react::*, react_perf::*,
16-
unicorn::*, vitest::*,
17+
unicorn::*, url::*, vitest::*,
1718
};
1819

1920
/// List of Jest rules that have Vitest equivalents.

crates/oxc_linter/src/utils/url.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/// Finds the first value of a query parameter in a URL. Is not guaranteed to be accurate
2+
/// with the URL standard and is just meant to be a simple helper that doesn't require
3+
/// fully parsing the URL.
4+
///
5+
/// # Example
6+
///
7+
/// ```rust
8+
/// find_url_query_value("https://example.com/?foo=bar&baz=qux", "baz") // => Some("qux")
9+
/// ```
10+
pub fn find_url_query_value<'url>(url: &'url str, key: &str) -> Option<&'url str> {
11+
// Return None right away if this doesn't look like a URL at all.
12+
if !url.starts_with("http://") && !url.starts_with("https://") {
13+
return None;
14+
}
15+
// Skip everything up to the first `?` as we're not parsing the host/path/etc.
16+
let url = url.split('?').nth(1)?;
17+
// Now parse the query string in pairs of `key=value`, we don't need
18+
// to be too strict about this as we're not trying to be spec-compliant.
19+
for pair in url.split('&') {
20+
if let Some((k, v)) = pair.split_once('=') {
21+
if k == key {
22+
return Some(v);
23+
}
24+
}
25+
}
26+
None
27+
}
28+
29+
mod test {
30+
#[test]
31+
fn test_find_url_query_value() {
32+
use super::find_url_query_value;
33+
assert_eq!(find_url_query_value("something", "q"), None);
34+
assert_eq!(find_url_query_value("https://example.com/?foo=bar", "foo"), Some("bar"));
35+
assert_eq!(find_url_query_value("https://example.com/?foo=bar", "baz"), None);
36+
assert_eq!(
37+
find_url_query_value("https://example.com/?foo=bar&baz=qux", "baz"),
38+
Some("qux")
39+
);
40+
assert_eq!(
41+
find_url_query_value("https://example.com/?foo=bar&foo=qux", "foo"),
42+
Some("bar")
43+
);
44+
assert_eq!(
45+
find_url_query_value("https://polyfill.io/v3/polyfill.min.js?features=WeakSet%2CPromise%2CPromise.prototype.finally%2Ces2015%2Ces5%2Ces6", "features"),
46+
Some("WeakSet%2CPromise%2CPromise.prototype.finally%2Ces2015%2Ces5%2Ces6")
47+
);
48+
}
49+
}

tasks/common/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,3 @@ project-root = { workspace = true }
1919
similar = { workspace = true }
2020

2121
ureq = { workspace = true, features = ["json", "rustls"] }
22-
url = { workspace = true }

tasks/common/src/test_file.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{fmt, str::FromStr};
1+
use std::fmt;
22

33
use crate::{project_root, request::agent};
44

@@ -94,11 +94,11 @@ impl TestFile {
9494
/// # Errors
9595
/// # Panics
9696
pub fn get_source_text(lib: &str) -> Result<(String, String), String> {
97-
let url = url::Url::from_str(lib).map_err(err_to_string)?;
98-
99-
let segments = url.path_segments().ok_or_else(|| "lib url has no segments".to_string())?;
100-
101-
let filename = segments.last().ok_or_else(|| "lib url has no segments".to_string())?;
97+
if !lib.starts_with("https://") {
98+
return Err(format!("Not an https url: {lib:?}"));
99+
}
100+
let filename =
101+
lib.split('/').last().ok_or_else(|| "lib url has no segments".to_string())?;
102102

103103
let file = project_root().join("target").join(filename);
104104

0 commit comments

Comments
 (0)