stellar_prune/build/dev/javascript/gleam_stdlib/gleam/uri.mjs
2025-11-30 15:44:22 +01:00

1147 lines
31 KiB
JavaScript

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);
}