import { Ok, Error, toList, Empty as $Empty, prepend as listPrepend, CustomType as $CustomType, isEqual, } from "../gleam.mjs"; import * as $int from "../gleam/int.mjs"; import * as $list from "../gleam/list.mjs"; import * as $option from "../gleam/option.mjs"; import { None, Some } from "../gleam/option.mjs"; import * as $string from "../gleam/string.mjs"; import * as $string_tree from "../gleam/string_tree.mjs"; import { pop_codeunit, string_codeunit_slice as codeunit_slice, parse_query, percent_encode, percent_decode, } from "../gleam_stdlib.mjs"; export { parse_query, percent_decode, percent_encode }; export class Uri extends $CustomType { constructor(scheme, userinfo, host, port, path, query, fragment) { super(); this.scheme = scheme; this.userinfo = userinfo; this.host = host; this.port = port; this.path = path; this.query = query; this.fragment = fragment; } } export const Uri$Uri = (scheme, userinfo, host, port, path, query, fragment) => new Uri(scheme, userinfo, host, port, path, query, fragment); export const Uri$isUri = (value) => value instanceof Uri; export const Uri$Uri$scheme = (value) => value.scheme; export const Uri$Uri$0 = (value) => value.scheme; export const Uri$Uri$userinfo = (value) => value.userinfo; export const Uri$Uri$1 = (value) => value.userinfo; export const Uri$Uri$host = (value) => value.host; export const Uri$Uri$2 = (value) => value.host; export const Uri$Uri$port = (value) => value.port; export const Uri$Uri$3 = (value) => value.port; export const Uri$Uri$path = (value) => value.path; export const Uri$Uri$4 = (value) => value.path; export const Uri$Uri$query = (value) => value.query; export const Uri$Uri$5 = (value) => value.query; export const Uri$Uri$fragment = (value) => value.fragment; export const Uri$Uri$6 = (value) => value.fragment; function is_valid_host_within_brackets_char(char) { return (((((48 >= char) && (char <= 57)) || ((65 >= char) && (char <= 90))) || ((97 >= char) && (char <= 122))) || (char === 58)) || (char === 46); } function parse_fragment(rest, pieces) { return new Ok( new Uri( pieces.scheme, pieces.userinfo, pieces.host, pieces.port, pieces.path, pieces.query, new Some(rest), ), ); } function parse_query_with_question_mark_loop( loop$original, loop$uri_string, loop$pieces, loop$size ) { while (true) { let original = loop$original; let uri_string = loop$uri_string; let pieces = loop$pieces; let size = loop$size; if (uri_string.startsWith("#")) { if (size === 0) { let rest = uri_string.slice(1); return parse_fragment(rest, pieces); } else { let rest = uri_string.slice(1); let query = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, pieces.host, pieces.port, pieces.path, new Some(query), pieces.fragment, ); return parse_fragment(rest, pieces$1); } } else if (uri_string === "") { return new Ok( new Uri( pieces.scheme, pieces.userinfo, pieces.host, pieces.port, pieces.path, new Some(original), pieces.fragment, ), ); } else { let $ = pop_codeunit(uri_string); let rest; rest = $[1]; loop$original = original; loop$uri_string = rest; loop$pieces = pieces; loop$size = size + 1; } } } function parse_query_with_question_mark(uri_string, pieces) { return parse_query_with_question_mark_loop(uri_string, uri_string, pieces, 0); } function parse_path_loop(loop$original, loop$uri_string, loop$pieces, loop$size) { while (true) { let original = loop$original; let uri_string = loop$uri_string; let pieces = loop$pieces; let size = loop$size; if (uri_string.startsWith("?")) { let rest = uri_string.slice(1); let path = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, pieces.host, pieces.port, path, pieces.query, pieces.fragment, ); return parse_query_with_question_mark(rest, pieces$1); } else if (uri_string.startsWith("#")) { let rest = uri_string.slice(1); let path = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, pieces.host, pieces.port, path, pieces.query, pieces.fragment, ); return parse_fragment(rest, pieces$1); } else if (uri_string === "") { return new Ok( new Uri( pieces.scheme, pieces.userinfo, pieces.host, pieces.port, original, pieces.query, pieces.fragment, ), ); } else { let $ = pop_codeunit(uri_string); let rest; rest = $[1]; loop$original = original; loop$uri_string = rest; loop$pieces = pieces; loop$size = size + 1; } } } function parse_path(uri_string, pieces) { return parse_path_loop(uri_string, uri_string, pieces, 0); } function parse_port_loop(loop$uri_string, loop$pieces, loop$port) { while (true) { let uri_string = loop$uri_string; let pieces = loop$pieces; let port = loop$port; if (uri_string.startsWith("0")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10; } else if (uri_string.startsWith("1")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10 + 1; } else if (uri_string.startsWith("2")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10 + 2; } else if (uri_string.startsWith("3")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10 + 3; } else if (uri_string.startsWith("4")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10 + 4; } else if (uri_string.startsWith("5")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10 + 5; } else if (uri_string.startsWith("6")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10 + 6; } else if (uri_string.startsWith("7")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10 + 7; } else if (uri_string.startsWith("8")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10 + 8; } else if (uri_string.startsWith("9")) { let rest = uri_string.slice(1); loop$uri_string = rest; loop$pieces = pieces; loop$port = port * 10 + 9; } else if (uri_string.startsWith("?")) { let rest = uri_string.slice(1); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, pieces.host, new Some(port), pieces.path, pieces.query, pieces.fragment, ); return parse_query_with_question_mark(rest, pieces$1); } else if (uri_string.startsWith("#")) { let rest = uri_string.slice(1); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, pieces.host, new Some(port), pieces.path, pieces.query, pieces.fragment, ); return parse_fragment(rest, pieces$1); } else if (uri_string.startsWith("/")) { let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, pieces.host, new Some(port), pieces.path, pieces.query, pieces.fragment, ); return parse_path(uri_string, pieces$1); } else if (uri_string === "") { return new Ok( new Uri( pieces.scheme, pieces.userinfo, pieces.host, new Some(port), pieces.path, pieces.query, pieces.fragment, ), ); } else { return new Error(undefined); } } } function parse_port(uri_string, pieces) { if (uri_string.startsWith(":0")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 0); } else if (uri_string.startsWith(":1")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 1); } else if (uri_string.startsWith(":2")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 2); } else if (uri_string.startsWith(":3")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 3); } else if (uri_string.startsWith(":4")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 4); } else if (uri_string.startsWith(":5")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 5); } else if (uri_string.startsWith(":6")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 6); } else if (uri_string.startsWith(":7")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 7); } else if (uri_string.startsWith(":8")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 8); } else if (uri_string.startsWith(":9")) { let rest = uri_string.slice(2); return parse_port_loop(rest, pieces, 9); } else if (uri_string === ":") { return new Ok(pieces); } else if (uri_string === "") { return new Ok(pieces); } else if (uri_string.startsWith("?")) { let rest = uri_string.slice(1); return parse_query_with_question_mark(rest, pieces); } else if (uri_string.startsWith(":?")) { let rest = uri_string.slice(2); return parse_query_with_question_mark(rest, pieces); } else if (uri_string.startsWith("#")) { let rest = uri_string.slice(1); return parse_fragment(rest, pieces); } else if (uri_string.startsWith(":#")) { let rest = uri_string.slice(2); return parse_fragment(rest, pieces); } else if (uri_string.startsWith("/")) { return parse_path(uri_string, pieces); } else if (uri_string.startsWith(":")) { let rest = uri_string.slice(1); if (rest.startsWith("/")) { return parse_path(rest, pieces); } else { return new Error(undefined); } } else { return new Error(undefined); } } function parse_host_outside_of_brackets_loop( loop$original, loop$uri_string, loop$pieces, loop$size ) { while (true) { let original = loop$original; let uri_string = loop$uri_string; let pieces = loop$pieces; let size = loop$size; if (uri_string === "") { return new Ok( new Uri( pieces.scheme, pieces.userinfo, new Some(original), pieces.port, pieces.path, pieces.query, pieces.fragment, ), ); } else if (uri_string.startsWith(":")) { let host = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, new Some(host), pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_port(uri_string, pieces$1); } else if (uri_string.startsWith("/")) { let host = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, new Some(host), pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_path(uri_string, pieces$1); } else if (uri_string.startsWith("?")) { let rest = uri_string.slice(1); let host = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, new Some(host), pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_query_with_question_mark(rest, pieces$1); } else if (uri_string.startsWith("#")) { let rest = uri_string.slice(1); let host = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, new Some(host), pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_fragment(rest, pieces$1); } else { let $ = pop_codeunit(uri_string); let rest; rest = $[1]; loop$original = original; loop$uri_string = rest; loop$pieces = pieces; loop$size = size + 1; } } } function parse_host_within_brackets_loop( loop$original, loop$uri_string, loop$pieces, loop$size ) { while (true) { let original = loop$original; let uri_string = loop$uri_string; let pieces = loop$pieces; let size = loop$size; if (uri_string === "") { return new Ok( new Uri( pieces.scheme, pieces.userinfo, new Some(uri_string), pieces.port, pieces.path, pieces.query, pieces.fragment, ), ); } else if (uri_string.startsWith("]")) { if (size === 0) { let rest = uri_string.slice(1); return parse_port(rest, pieces); } else { let rest = uri_string.slice(1); let host = codeunit_slice(original, 0, size + 1); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, new Some(host), pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_port(rest, pieces$1); } } else if (uri_string.startsWith("/")) { if (size === 0) { return parse_path(uri_string, pieces); } else { let host = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, new Some(host), pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_path(uri_string, pieces$1); } } else if (uri_string.startsWith("?")) { if (size === 0) { let rest = uri_string.slice(1); return parse_query_with_question_mark(rest, pieces); } else { let rest = uri_string.slice(1); let host = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, new Some(host), pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_query_with_question_mark(rest, pieces$1); } } else if (uri_string.startsWith("#")) { if (size === 0) { let rest = uri_string.slice(1); return parse_fragment(rest, pieces); } else { let rest = uri_string.slice(1); let host = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, new Some(host), pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_fragment(rest, pieces$1); } } else { let $ = pop_codeunit(uri_string); let char; let rest; char = $[0]; rest = $[1]; let $1 = is_valid_host_within_brackets_char(char); if ($1) { loop$original = original; loop$uri_string = rest; loop$pieces = pieces; loop$size = size + 1; } else { return parse_host_outside_of_brackets_loop( original, original, pieces, 0, ); } } } } function parse_host_within_brackets(uri_string, pieces) { return parse_host_within_brackets_loop(uri_string, uri_string, pieces, 0); } function parse_host_outside_of_brackets(uri_string, pieces) { return parse_host_outside_of_brackets_loop(uri_string, uri_string, pieces, 0); } function parse_host(uri_string, pieces) { if (uri_string.startsWith("[")) { return parse_host_within_brackets(uri_string, pieces); } else if (uri_string.startsWith(":")) { let pieces$1 = new Uri( pieces.scheme, pieces.userinfo, new Some(""), pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_port(uri_string, pieces$1); } else if (uri_string === "") { return new Ok( new Uri( pieces.scheme, pieces.userinfo, new Some(""), pieces.port, pieces.path, pieces.query, pieces.fragment, ), ); } else { return parse_host_outside_of_brackets(uri_string, pieces); } } function parse_userinfo_loop( loop$original, loop$uri_string, loop$pieces, loop$size ) { while (true) { let original = loop$original; let uri_string = loop$uri_string; let pieces = loop$pieces; let size = loop$size; if (uri_string.startsWith("@")) { if (size === 0) { let rest = uri_string.slice(1); return parse_host(rest, pieces); } else { let rest = uri_string.slice(1); let userinfo = codeunit_slice(original, 0, size); let pieces$1 = new Uri( pieces.scheme, new Some(userinfo), pieces.host, pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_host(rest, pieces$1); } } else if (uri_string === "") { return parse_host(original, pieces); } else if (uri_string.startsWith("/")) { return parse_host(original, pieces); } else if (uri_string.startsWith("?")) { return parse_host(original, pieces); } else if (uri_string.startsWith("#")) { return parse_host(original, pieces); } else { let $ = pop_codeunit(uri_string); let rest; rest = $[1]; loop$original = original; loop$uri_string = rest; loop$pieces = pieces; loop$size = size + 1; } } } function parse_authority_pieces(string, pieces) { return parse_userinfo_loop(string, string, pieces, 0); } function parse_authority_with_slashes(uri_string, pieces) { if (uri_string === "//") { return new Ok( new Uri( pieces.scheme, pieces.userinfo, new Some(""), pieces.port, pieces.path, pieces.query, pieces.fragment, ), ); } else if (uri_string.startsWith("//")) { let rest = uri_string.slice(2); return parse_authority_pieces(rest, pieces); } else { return parse_path(uri_string, pieces); } } function parse_scheme_loop( loop$original, loop$uri_string, loop$pieces, loop$size ) { while (true) { let original = loop$original; let uri_string = loop$uri_string; let pieces = loop$pieces; let size = loop$size; if (uri_string.startsWith("/")) { if (size === 0) { return parse_authority_with_slashes(uri_string, pieces); } else { let scheme = codeunit_slice(original, 0, size); let pieces$1 = new Uri( new Some($string.lowercase(scheme)), pieces.userinfo, pieces.host, pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_authority_with_slashes(uri_string, pieces$1); } } else if (uri_string.startsWith("?")) { if (size === 0) { let rest = uri_string.slice(1); return parse_query_with_question_mark(rest, pieces); } else { let rest = uri_string.slice(1); let scheme = codeunit_slice(original, 0, size); let pieces$1 = new Uri( new Some($string.lowercase(scheme)), pieces.userinfo, pieces.host, pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_query_with_question_mark(rest, pieces$1); } } else if (uri_string.startsWith("#")) { if (size === 0) { let rest = uri_string.slice(1); return parse_fragment(rest, pieces); } else { let rest = uri_string.slice(1); let scheme = codeunit_slice(original, 0, size); let pieces$1 = new Uri( new Some($string.lowercase(scheme)), pieces.userinfo, pieces.host, pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_fragment(rest, pieces$1); } } else if (uri_string.startsWith(":")) { if (size === 0) { return new Error(undefined); } else { let rest = uri_string.slice(1); let scheme = codeunit_slice(original, 0, size); let pieces$1 = new Uri( new Some($string.lowercase(scheme)), pieces.userinfo, pieces.host, pieces.port, pieces.path, pieces.query, pieces.fragment, ); return parse_authority_with_slashes(rest, pieces$1); } } else if (uri_string === "") { return new Ok( new Uri( pieces.scheme, pieces.userinfo, pieces.host, pieces.port, original, pieces.query, pieces.fragment, ), ); } else { let $ = pop_codeunit(uri_string); let rest; rest = $[1]; loop$original = original; loop$uri_string = rest; loop$pieces = pieces; loop$size = size + 1; } } } function query_pair(pair) { return $string_tree.from_strings( toList([percent_encode(pair[0]), "=", percent_encode(pair[1])]), ); } /** * Encodes a list of key value pairs as a URI query string. * * The opposite operation is `uri.parse_query`. * * ## Examples * * ```gleam * query_to_string([#("a", "1"), #("b", "2")]) * // -> "a=1&b=2" * ``` */ export function query_to_string(query) { let _pipe = query; let _pipe$1 = $list.map(_pipe, query_pair); let _pipe$2 = $list.intersperse(_pipe$1, $string_tree.from_string("&")); let _pipe$3 = $string_tree.concat(_pipe$2); return $string_tree.to_string(_pipe$3); } function remove_dot_segments_loop(loop$input, loop$accumulator) { while (true) { let input = loop$input; let accumulator = loop$accumulator; if (input instanceof $Empty) { return $list.reverse(accumulator); } else { let segment = input.head; let rest = input.tail; let _block; if (segment === "") { _block = accumulator; } else if (segment === ".") { _block = accumulator; } else if (segment === "..") { if (accumulator instanceof $Empty) { _block = accumulator; } else { let accumulator$1 = accumulator.tail; _block = accumulator$1; } } else { let segment$1 = segment; let accumulator$1 = accumulator; _block = listPrepend(segment$1, accumulator$1); } let accumulator$1 = _block; loop$input = rest; loop$accumulator = accumulator$1; } } } function remove_dot_segments(input) { return remove_dot_segments_loop(input, toList([])); } /** * Splits the path section of a URI into it's constituent segments. * * Removes empty segments and resolves dot-segments as specified in * [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. * * ## Examples * * ```gleam * path_segments("/users/1") * // -> ["users" ,"1"] * ``` */ export function path_segments(path) { return remove_dot_segments($string.split(path, "/")); } /** * Encodes a `Uri` value as a URI string. * * The opposite operation is `uri.parse`. * * ## Examples * * ```gleam * let uri = Uri(..empty, scheme: Some("https"), host: Some("example.com")) * to_string(uri) * // -> "https://example.com" * ``` */ export function to_string(uri) { let _block; let $ = uri.fragment; if ($ instanceof Some) { let fragment = $[0]; _block = toList(["#", fragment]); } else { _block = toList([]); } let parts = _block; let _block$1; let $1 = uri.query; if ($1 instanceof Some) { let query = $1[0]; _block$1 = listPrepend("?", listPrepend(query, parts)); } else { _block$1 = parts; } let parts$1 = _block$1; let parts$2 = listPrepend(uri.path, parts$1); let _block$2; let $2 = uri.host; let $3 = $string.starts_with(uri.path, "/"); if ($2 instanceof Some && !$3) { let host = $2[0]; if (host !== "") { _block$2 = listPrepend("/", parts$2); } else { _block$2 = parts$2; } } else { _block$2 = parts$2; } let parts$3 = _block$2; let _block$3; let $4 = uri.host; let $5 = uri.port; if ($4 instanceof Some && $5 instanceof Some) { let port = $5[0]; _block$3 = listPrepend(":", listPrepend($int.to_string(port), parts$3)); } else { _block$3 = parts$3; } let parts$4 = _block$3; let _block$4; let $6 = uri.scheme; let $7 = uri.userinfo; let $8 = uri.host; if ($6 instanceof Some) { if ($7 instanceof Some) { if ($8 instanceof Some) { let s = $6[0]; let u = $7[0]; let h = $8[0]; _block$4 = listPrepend( s, listPrepend( "://", listPrepend(u, listPrepend("@", listPrepend(h, parts$4))), ), ); } else { let s = $6[0]; _block$4 = listPrepend(s, listPrepend(":", parts$4)); } } else if ($8 instanceof Some) { let s = $6[0]; let h = $8[0]; _block$4 = listPrepend(s, listPrepend("://", listPrepend(h, parts$4))); } else { let s = $6[0]; _block$4 = listPrepend(s, listPrepend(":", parts$4)); } } else if ($7 instanceof None && $8 instanceof Some) { let h = $8[0]; _block$4 = listPrepend("//", listPrepend(h, parts$4)); } else { _block$4 = parts$4; } let parts$5 = _block$4; return $string.concat(parts$5); } /** * Fetches the origin of a URI. * * Returns the origin of a uri as defined in * [RFC 6454](https://tools.ietf.org/html/rfc6454) * * The supported URI schemes are `http` and `https`. * URLs without a scheme will return `Error`. * * ## Examples * * ```gleam * let assert Ok(uri) = parse("https://example.com/path?foo#bar") * origin(uri) * // -> Ok("https://example.com") * ``` */ export function origin(uri) { let scheme; let host; let port; scheme = uri.scheme; host = uri.host; port = uri.port; if (host instanceof Some && scheme instanceof Some) { let $ = scheme[0]; if ($ === "https" && isEqual(port, new Some(443))) { let h = host[0]; return new Ok($string.concat(toList(["https://", h]))); } else if ($ === "http" && isEqual(port, new Some(80))) { let h = host[0]; return new Ok($string.concat(toList(["http://", h]))); } else { let s = $; if ((s === "http") || (s === "https")) { let h = host[0]; if (port instanceof Some) { let p = port[0]; return new Ok( $string.concat(toList([s, "://", h, ":", $int.to_string(p)])), ); } else { return new Ok($string.concat(toList([s, "://", h]))); } } else { return new Error(undefined); } } } else { return new Error(undefined); } } function drop_last(elements) { return $list.take(elements, $list.length(elements) - 1); } function join_segments(segments) { return $string.join(listPrepend("", segments), "/"); } /** * Resolves a URI with respect to the given base URI. * * The base URI must be an absolute URI or this function will return an error. * The algorithm for merging uris is described in * [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). */ export function merge(base, relative) { let $ = base.scheme; if ($ instanceof Some) { let $1 = base.host; if ($1 instanceof Some) { let $2 = relative.host; if ($2 instanceof Some) { let _block; let _pipe = relative.path; let _pipe$1 = $string.split(_pipe, "/"); let _pipe$2 = remove_dot_segments(_pipe$1); _block = join_segments(_pipe$2); let path = _block; let resolved = new Uri( $option.or(relative.scheme, base.scheme), new None(), relative.host, $option.or(relative.port, base.port), path, relative.query, relative.fragment, ); return new Ok(resolved); } else { let _block; let $4 = relative.path; if ($4 === "") { _block = [base.path, $option.or(relative.query, base.query)]; } else { let _block$1; let $5 = $string.starts_with(relative.path, "/"); if ($5) { _block$1 = $string.split(relative.path, "/"); } else { let _pipe = base.path; let _pipe$1 = $string.split(_pipe, "/"); let _pipe$2 = drop_last(_pipe$1); _block$1 = $list.append(_pipe$2, $string.split(relative.path, "/")); } let path_segments$1 = _block$1; let _block$2; let _pipe = path_segments$1; let _pipe$1 = remove_dot_segments(_pipe); _block$2 = join_segments(_pipe$1); let path = _block$2; _block = [path, relative.query]; } let $3 = _block; let new_path; let new_query; new_path = $3[0]; new_query = $3[1]; let resolved = new Uri( base.scheme, new None(), base.host, base.port, new_path, new_query, relative.fragment, ); return new Ok(resolved); } } else { return new Error(undefined); } } else { return new Error(undefined); } } /** * Constant representing an empty URI, equivalent to "". * * ## Examples * * ```gleam * let uri = Uri(..empty, scheme: Some("https"), host: Some("example.com")) * // -> Uri( * // scheme: Some("https"), * // userinfo: None, * // host: Some("example.com"), * // port: None, * // path: "", * // query: None, * // fragment: None, * // ) * ``` */ export const empty = /* @__PURE__ */ new Uri( /* @__PURE__ */ new None(), /* @__PURE__ */ new None(), /* @__PURE__ */ new None(), /* @__PURE__ */ new None(), "", /* @__PURE__ */ new None(), /* @__PURE__ */ new None(), ); /** * Parses a compliant URI string into the `Uri` Type. * If the string is not a valid URI string then an error is returned. * * The opposite operation is `uri.to_string`. * * ## Examples * * ```gleam * parse("https://example.com:1234/a/b?query=true#fragment") * // -> Ok( * // Uri( * // scheme: Some("https"), * // userinfo: None, * // host: Some("example.com"), * // port: Some(1234), * // path: "/a/b", * // query: Some("query=true"), * // fragment: Some("fragment") * // ) * // ) * ``` */ export function parse(uri_string) { return parse_scheme_loop(uri_string, uri_string, empty, 0); }