54 lines
2.3 KiB
Plaintext
54 lines
2.3 KiB
Plaintext
|
# Extract the named capturing groups of a regular expression into a
|
||
|
# {name: matched text} mapping.
|
||
|
def regex_capture(regex):
|
||
|
match(regex).captures
|
||
|
| [
|
||
|
.[]
|
||
|
| select(.name)
|
||
|
| { key: .name, value: .string }
|
||
|
] | from_entries;
|
||
|
|
||
|
# Parse URLs into an object with {scheme, netloc, path, params, query, fragment}.
|
||
|
# Similar to Python's urllib.parse.urlparse.
|
||
|
def urlparse: regex_capture("^(?:(?<scheme>[^:/?#]+):)?(?://(?<netloc>[^/?#]*))?(?:(?<path>(?:[^?#]+/)?[^?#;]*)(?:;(?<params>[^?#/]*))?)?(?:\\?(?<query>[^#]*))?(?:#(?<fragment>.*))?$");
|
||
|
|
||
|
# Parse URLs into an object with {scheme, netloc, path, query, fragment}. Path parameters are not parsed.
|
||
|
# Similar to Python's urllib.parse.urlsplit.
|
||
|
def urlsplit: regex_capture("^(?:(?<scheme>[^:/?#]+):)?(?://(?<netloc>[^/?#]*))?(?<path>(?:[^?#]+/)?[^?#]*)?(?:\\?(?<query>[^#]*))?(?:#(?<fragment>.*))?$");
|
||
|
|
||
|
# Reverse operation of either urlparse or urlsplit.
|
||
|
def urlunparse:
|
||
|
(if .scheme then .scheme + "://" else "" end)
|
||
|
+ (.netloc // "")
|
||
|
+ (.path // "")
|
||
|
+ (if .params then ";" + .params else "" end)
|
||
|
+ (if .query then "?" + .query else "" end)
|
||
|
+ (if .fragment then "#" + .fragment else "" end);
|
||
|
|
||
|
# Resolve a possibly relative URI into an absolute URI.
|
||
|
def urlresolve(base):
|
||
|
(if type == "string" then urlsplit else . end) as $parsed
|
||
|
# There is a scheme: this is an absolute URL
|
||
|
| if $parsed.scheme then . else (
|
||
|
base|(if type == "string" then urlsplit else . end) as $parsedbase
|
||
|
# No scheme but a domain: use the base's scheme
|
||
|
| $parsed
|
||
|
| if .netloc then (
|
||
|
.scheme = $parsedbase.scheme
|
||
|
# No scheme and no domain: resolve the relative URI
|
||
|
) elif .path then (
|
||
|
.scheme = $parsedbase.scheme
|
||
|
| .netloc = $parsedbase.netloc
|
||
|
# When the path does not start with a slash, make it relative to the base's path
|
||
|
# Note that this assumes the base URL always points to a folder, even if it does not end with a /
|
||
|
| if .path|startswith("/")|not then (
|
||
|
.path = (($parsedbase.path|rtrimstr("/")) + "/" + ($parsed.path|ltrimstr("/")))
|
||
|
) else . end
|
||
|
) elif (.query // .fragment) then (
|
||
|
.scheme = $parsedbase.scheme
|
||
|
| .netloc = $parsedbase.netloc
|
||
|
| .path = $parsedbase.path
|
||
|
) else . end
|
||
|
| urlunparse
|
||
|
) end;
|