Skip to content

Commit

Permalink
feat: Improved compliance of URL object (#409)
Browse files Browse the repository at this point in the history
* feat: Improved compliance of url object

Signed-off-by: WATANABE Shinya <[email protected]>

* Fix API.md

* Refactoring

---------

Signed-off-by: WATANABE Shinya <[email protected]>
  • Loading branch information
nabetti1720 authored Jun 7, 2024
1 parent e67efd7 commit b1ca602
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 15 deletions.
1 change: 1 addition & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ export class URL {
searchParams: URLSearchParams;
username: string;

parse(input: string, base?: string): URL | null;
canParse(input: string, base?: string): boolean;
toJSON(): string;
toString(): string;
Expand Down
35 changes: 22 additions & 13 deletions llrt_core/src/modules/http/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rquickjs::{
class::{Trace, Tracer},
function::Opt,
prelude::This,
Class, Coerced, Ctx, Exception, FromJs, Function, Object, Result, Value,
Class, Coerced, Ctx, Exception, FromJs, Function, IntoJs, Null, Object, Result, Value,
};
use url::Url;

Expand Down Expand Up @@ -64,31 +64,40 @@ impl<'js> URL<'js> {

#[qjs(static)]
pub fn can_parse(ctx: Ctx<'js>, input: Value<'js>, base: Opt<Value<'js>>) -> bool {
match Self::parse(ctx.clone(), input.clone(), Opt(base.clone())) {
Ok(val) => !val.is_null(),
Err(_) => false,
}
}

#[qjs(static)]
pub fn parse(ctx: Ctx<'js>, input: Value<'js>, base: Opt<Value<'js>>) -> Result<Value<'js>> {
if let Some(base) = base.0 {
let base_string = match get_string(&ctx, base) {
Ok(s) => s,
Err(_) => return false,
Err(_) => return Null.into_js(&ctx),
};
let path_string = match get_string(&ctx, input) {
Ok(s) => s,
Err(_) => return false,
Err(_) => return Null.into_js(&ctx),
};

match base_string.parse::<Url>() {
Ok(base_url) => base_url.join(&path_string).is_ok(),
Err(_) => false, // Base URL parsing failed
Ok(base_url) => {
if let Ok(parsed_url) = base_url.join(&path_string) {
return URL::create(ctx.clone(), parsed_url).unwrap().into_js(&ctx);
}
},
Err(_) => return Null.into_js(&ctx),
}
} else {
// Handle the case where base is not provided
if input.is_string() {
match input.get::<String>() {
Ok(string_val) => Url::parse(&string_val).is_ok(),
Err(_) => false,
} else if input.is_string() {
if let Ok(string_val) = input.get::<String>() {
if let Ok(parsed_url) = Url::parse(&string_val) {
return URL::create(ctx.clone(), parsed_url).unwrap().into_js(&ctx);
}
} else {
false
}
}
Null.into_js(&ctx)
}

pub fn to_string(&self) -> String {
Expand Down
9 changes: 7 additions & 2 deletions tests/unit/http.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,13 +492,18 @@ describe("URL class", () => {
expect(url.username).toEqual("anonymous");
expect(url.password).toEqual("flabada");
});
it("should provide canParse util", () => {
it("should provide parse/canParse util", () => {
const validUrl = "https://www.example.com/";
const invalidUrl = "not_a_valid_url";
expect(URL.parse(validUrl).href).toEqual(validUrl);
expect(URL.canParse(validUrl)).toEqual(true);
expect(URL.parse(invalidUrl)).toBeNull();
expect(URL.canParse(invalidUrl)).toEqual(false);
});
it("canParse works for relative urls", () => {
it("parse/canParse works for relative urls", () => {
expect(URL.parse("/foo", "https://example.org/").href).toEqual(
"https://example.org/foo"
);
expect(URL.canParse("/foo", "https://example.org/")).toEqual(true);
});
});
Expand Down

0 comments on commit b1ca602

Please sign in to comment.