full site update

This commit is contained in:
2025-07-24 18:46:24 +02:00
parent bfe2b90d8d
commit 37a6e0ab31
6912 changed files with 540482 additions and 361712 deletions

21
node_modules/ufo/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Pooya Parsa <pooya@pi0.io>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

466
node_modules/ufo/README.md generated vendored Normal file
View File

@@ -0,0 +1,466 @@
# ufo
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![bundle][bundle-src]][bundle-href]
[![Codecov][codecov-src]][codecov-href]
URL utils for humans.
## Install
Install using npm or your favourite package manager:
Install package:
```sh
# npm
npm install ufo
# yarn
yarn add ufo
# pnpm
pnpm install ufo
# bun
bun install ufo
```
Import utils:
```js
// ESM
import { normalizeURL, joinURL } from "ufo";
// CommonJS
const { normalizeURL, joinURL } = require("ufo");
// Deno
import { parseURL } from "https://unpkg.com/ufo/dist/index.mjs";
```
<!-- automd:jsdocs src=./src defaultGroup=utils -->
## Encoding Utils
### `decode(text)`
Decodes text using `decodeURIComponent`. Returns the original text if it fails.
### `decodePath(text)`
Decodes path section of URL (consistent with encodePath for slash encoding).
### `decodeQueryKey(text)`
Decodes query key (consistent with `encodeQueryKey` for plus encoding).
### `decodeQueryValue(text)`
Decodes query value (consistent with `encodeQueryValue` for plus encoding).
### `encode(text)`
Encodes characters that need to be encoded in the path, search and hash sections of the URL.
### `encodeHash(text)`
Encodes characters that need to be encoded in the hash section of the URL.
### `encodeHost(name)`
Encodes hostname with punycode encoding.
### `encodeParam(text)`
Encodes characters that need to be encoded in the path section of the URL as a param. This function encodes everything `encodePath` does plus the slash (`/`) character.
### `encodePath(text)`
Encodes characters that need to be encoded in the path section of the URL.
### `encodeQueryKey(text)`
Encodes characters that need to be encoded for query values in the query section of the URL and also encodes the `=` character.
### `encodeQueryValue(input)`
Encodes characters that need to be encoded for query values in the query section of the URL.
## Parsing Utils
### `parseAuth(input)`
Takes a string of the form `username:password` and returns an object with the username and password decoded.
### `parseFilename(input, opts?: { strict? })`
Parses a URL and returns last segment in path as filename.
If `{ strict: true }` is passed as the second argument, it will only return the last segment only if ending with an extension.
**Example:**
```js
// Result: filename.ext
parseFilename("http://example.com/path/to/filename.ext");
// Result: undefined
parseFilename("/path/to/.hidden-file", { strict: true });
```
### `parseHost(input)`
Takes a string, and returns an object with two properties: `hostname` and `port`.
### `parsePath(input)`
Splits the input string into three parts, and returns an object with those three parts.
### `parseURL(input, defaultProto?)`
Takes a URL string and returns an object with the URL's `protocol`, `auth`, `host`, `pathname`, `search`, and `hash`.
**Example:**
```js
parseURL("http://foo.com/foo?test=123#token");
// { protocol: 'http:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
parseURL("foo.com/foo?test=123#token");
// { pathname: 'foo.com/foo', search: '?test=123', hash: '#token' }
parseURL("foo.com/foo?test=123#token", "https://");
// { protocol: 'https:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
```
### `stringifyParsedURL(parsed)`
Takes a `ParsedURL` object and returns the stringified URL.
**Example:**
```js
const obj = parseURL("http://foo.com/foo?test=123#token");
obj.host = "bar.com";
stringifyParsedURL(obj); // "http://bar.com/foo?test=123#token"
```
## Query Utils
### `encodeQueryItem(key, value)`
Encodes a pair of key and value into a url query string value.
If the value is an array, it will be encoded as multiple key-value pairs with the same key.
### `parseQuery(parametersString)`
Parses and decodes a query string into an object.
The input can be a query string with or without the leading `?`.
### `stringifyQuery(query)`
Stringfies and encodes a query object into a query string.
## Utils
### `$URL()`
### `cleanDoubleSlashes(input)`
Removes double slashes from the URL.
**Example:**
```js
cleanDoubleSlashes("//foo//bar//"); // "/foo/bar/"
cleanDoubleSlashes("http://example.com/analyze//http://localhost:3000//");
// Returns "http://example.com/analyze/http://localhost:3000/"
```
### `filterQuery(input, predicate)`
Removes the query section of the URL.
**Example:**
```js
filterQuery("/foo?bar=1&baz=2", (key) => key !== "bar"); // "/foo?baz=2"
```
### `getQuery(input)`
Parses and decodes the query object of an input URL into an object.
**Example:**
```js
getQuery("http://foo.com/foo?test=123&unicode=%E5%A5%BD");
// { test: "123", unicode: "好" }
```
### `hasLeadingSlash(input)`
Checks if the input has a leading slash (e.g. `/foo`).
### `hasProtocol(inputString, opts)`
### `hasTrailingSlash(input, respectQueryAndFragment?)`
Checks if the input has a trailing slash.
### `isEmptyURL(url)`
Checks if the input URL is empty or `/`.
### `isEqual(a, b, options)`
Checks if two paths are equal regardless of encoding, trailing slash, and leading slash differences.
You can make slash check strict by setting `{ trailingSlash: true, leadingSlash: true }` as options.
You can make encoding check strict by setting `{ encoding: true }` as options.
**Example:**
```js
isEqual("/foo", "foo"); // true
isEqual("foo/", "foo"); // true
isEqual("/foo bar", "/foo%20bar"); // true
// Strict compare
isEqual("/foo", "foo", { leadingSlash: true }); // false
isEqual("foo/", "foo", { trailingSlash: true }); // false
isEqual("/foo bar", "/foo%20bar", { encoding: true }); // false
```
### `isNonEmptyURL(url)`
Checks if the input URL is neither empty nor `/`.
### `isRelative(inputString)`
Check if a path starts with `./` or `../`.
**Example:**
```js
isRelative("./foo"); // true
```
### `isSamePath(p1, p2)`
Check if two paths are equal or not. Trailing slash and encoding are normalized before comparison.
**Example:**
```js
isSamePath("/foo", "/foo/"); // true
```
### `isScriptProtocol(protocol?)`
Checks if the input protocol is any of the dangerous `blob:`, `data:`, `javascript`: or `vbscript:` protocols.
### `joinRelativeURL()`
Joins multiple URL segments into a single URL and also handles relative paths with `./` and `../`.
**Example:**
```js
joinRelativeURL("/a", "../b", "./c"); // "/b/c"
```
### `joinURL(base)`
Joins multiple URL segments into a single URL.
**Example:**
```js
joinURL("a", "/b", "/c"); // "a/b/c"
```
### `normalizeURL(input)`
Normalizes the input URL:
- Ensures the URL is properly encoded - Ensures pathname starts with a slash - Preserves protocol/host if provided
**Example:**
```js
normalizeURL("test?query=123 123#hash, test");
// Returns "test?query=123%20123#hash,%20test"
normalizeURL("http://localhost:3000");
// Returns "http://localhost:3000"
```
### `resolveURL(base)`
Resolves multiple URL segments into a single URL.
**Example:**
```js
resolveURL("http://foo.com/foo?test=123#token", "bar", "baz");
// Returns "http://foo.com/foo/bar/baz?test=123#token"
```
### `withBase(input, base)`
Ensures the URL or pathname starts with base.
If input already starts with base, it will not be added again.
### `withFragment(input, hash)`
Adds or replaces the fragment section of the URL.
**Example:**
```js
withFragment("/foo", "bar"); // "/foo#bar"
withFragment("/foo#bar", "baz"); // "/foo#baz"
withFragment("/foo#bar", ""); // "/foo"
```
### `withHttp(input)`
Adds or replaces the URL protocol to `http://`.
**Example:**
```js
withHttp("https://example.com"); // http://example.com
```
### `withHttps(input)`
Adds or replaces the URL protocol to `https://`.
**Example:**
```js
withHttps("http://example.com"); // https://example.com
```
### `withLeadingSlash(input)`
Ensures the URL or pathname has a leading slash.
### `withoutBase(input, base)`
Removes the base from the URL or pathname.
If input does not start with base, it will not be removed.
### `withoutFragment(input)`
Removes the fragment section from the URL.
**Example:**
```js
withoutFragment("http://example.com/foo?q=123#bar")
// Returns "http://example.com/foo?q=123"
```
### `withoutHost(input)`
Removes the host from the URL while preserving everything else.
**Example:**
```js
withoutHost("http://example.com/foo?q=123#bar")
// Returns "/foo?q=123#bar"
```
### `withoutLeadingSlash(input)`
Removes leading slash from the URL or pathname.
### `withoutProtocol(input)`
Removes the protocol from the input.
**Example:**
```js
withoutProtocol("http://example.com"); // "example.com"
```
### `withoutTrailingSlash(input, respectQueryAndFragment?)`
Removes the trailing slash from the URL or pathname.
If second argument is `true`, it will only remove the trailing slash if it's not part of the query or fragment with cost of more expensive operations.
**Example:**
```js
withoutTrailingSlash("/foo/"); // "/foo"
withoutTrailingSlash("/path/?query=true", true); // "/path?query=true"
```
### `withProtocol(input, protocol)`
Adds or replaces protocol of the input URL.
**Example:**
```js
withProtocol("http://example.com", "ftp://"); // "ftp://example.com"
```
### `withQuery(input, query)`
Add/Replace the query section of the URL.
**Example:**
```js
withQuery("/foo?page=a", { token: "secret" }); // "/foo?page=a&token=secret"
```
### `withTrailingSlash(input, respectQueryAndFragment?)`
Ensures the URL ends with a trailing slash.
If second argument is `true`, it will only add the trailing slash if it's not part of the query or fragment with cost of more expensive operation.
**Example:**
```js
withTrailingSlash("/foo"); // "/foo/"
withTrailingSlash("/path?query=true", true); // "/path/?query=true"
```
<!-- /automd -->
## License
[MIT](./LICENSE)
Special thanks to Eduardo San Martin Morote ([posva](https://github.com/posva)) for [encoding utilities](https://github.com/vuejs/vue-router-next/blob/v4.0.1/src/encoding.ts)
<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/ufo?style=flat&colorA=18181B&colorB=F0DB4F
[npm-version-href]: https://npmjs.com/package/ufo
[npm-downloads-src]: https://img.shields.io/npm/dm/ufo?style=flat&colorA=18181B&colorB=F0DB4F
[npm-downloads-href]: https://npmjs.com/package/ufo
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/ufo/main?style=flat&colorA=18181B&colorB=F0DB4F
[codecov-href]: https://codecov.io/gh/unjs/ufo
[bundle-src]: https://img.shields.io/bundlephobia/minzip/ufo?style=flat&colorA=18181B&colorB=F0DB4F
[bundle-href]: https://bundlephobia.com/result?p=ufo

691
node_modules/ufo/dist/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,691 @@
'use strict';
const n = /[^\0-\x7E]/;
const t = /[\x2E\u3002\uFF0E\uFF61]/g;
const o = {
overflow: "Overflow Error",
"not-basic": "Illegal Input",
"invalid-input": "Invalid Input"
};
const e = Math.floor;
const r = String.fromCharCode;
function s(n2) {
throw new RangeError(o[n2]);
}
const c = function(n2, t2) {
return n2 + 22 + 75 * (n2 < 26) - ((t2 != 0) << 5);
};
const u = function(n2, t2, o2) {
let r2 = 0;
for (n2 = o2 ? e(n2 / 700) : n2 >> 1, n2 += e(n2 / t2); n2 > 455; r2 += 36) {
n2 = e(n2 / 35);
}
return e(r2 + 36 * n2 / (n2 + 38));
};
function toASCII(o2) {
return function(n2, o3) {
const e2 = n2.split("@");
let r2 = "";
e2.length > 1 && (r2 = e2[0] + "@", n2 = e2[1]);
const s2 = function(n3, t2) {
const o4 = [];
let e3 = n3.length;
for (; e3--; ) {
o4[e3] = t2(n3[e3]);
}
return o4;
}((n2 = n2.replace(t, ".")).split("."), o3).join(".");
return r2 + s2;
}(o2, function(t2) {
return n.test(t2) ? "xn--" + function(n2) {
const t3 = [];
const o3 = (n2 = function(n3) {
const t4 = [];
let o4 = 0;
const e2 = n3.length;
for (; o4 < e2; ) {
const r2 = n3.charCodeAt(o4++);
if (r2 >= 55296 && r2 <= 56319 && o4 < e2) {
const e3 = n3.charCodeAt(o4++);
(64512 & e3) == 56320 ? t4.push(((1023 & r2) << 10) + (1023 & e3) + 65536) : (t4.push(r2), o4--);
} else {
t4.push(r2);
}
}
return t4;
}(n2)).length;
let f = 128;
let i = 0;
let l = 72;
for (const o4 of n2) {
o4 < 128 && t3.push(r(o4));
}
const h = t3.length;
let p = h;
for (h && t3.push("-"); p < o3; ) {
let o4 = 2147483647;
for (const t4 of n2) {
t4 >= f && t4 < o4 && (o4 = t4);
}
const a = p + 1;
o4 - f > e((2147483647 - i) / a) && s("overflow"), i += (o4 - f) * a, f = o4;
for (const o5 of n2) {
if (o5 < f && ++i > 2147483647 && s("overflow"), o5 == f) {
let n3 = i;
for (let o6 = 36; ; o6 += 36) {
const s2 = o6 <= l ? 1 : o6 >= l + 26 ? 26 : o6 - l;
if (n3 < s2) {
break;
}
const u2 = n3 - s2;
const f2 = 36 - s2;
t3.push(r(c(s2 + u2 % f2, 0))), n3 = e(u2 / f2);
}
t3.push(r(c(n3, 0))), l = u(i, a, p == h), i = 0, ++p;
}
}
++i, ++f;
}
return t3.join("");
}(t2) : t2;
});
}
const HASH_RE = /#/g;
const AMPERSAND_RE = /&/g;
const SLASH_RE = /\//g;
const EQUAL_RE = /=/g;
const IM_RE = /\?/g;
const PLUS_RE = /\+/g;
const ENC_CARET_RE = /%5e/gi;
const ENC_BACKTICK_RE = /%60/gi;
const ENC_CURLY_OPEN_RE = /%7b/gi;
const ENC_PIPE_RE = /%7c/gi;
const ENC_CURLY_CLOSE_RE = /%7d/gi;
const ENC_SPACE_RE = /%20/gi;
const ENC_SLASH_RE = /%2f/gi;
const ENC_ENC_SLASH_RE = /%252f/gi;
function encode(text) {
return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
}
function encodeHash(text) {
return encode(text).replace(ENC_CURLY_OPEN_RE, "{").replace(ENC_CURLY_CLOSE_RE, "}").replace(ENC_CARET_RE, "^");
}
function encodeQueryValue(input) {
return encode(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
}
function encodeQueryKey(text) {
return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
}
function encodePath(text) {
return encode(text).replace(HASH_RE, "%23").replace(IM_RE, "%3F").replace(ENC_ENC_SLASH_RE, "%2F").replace(AMPERSAND_RE, "%26").replace(PLUS_RE, "%2B");
}
function encodeParam(text) {
return encodePath(text).replace(SLASH_RE, "%2F");
}
function decode(text = "") {
try {
return decodeURIComponent("" + text);
} catch {
return "" + text;
}
}
function decodePath(text) {
return decode(text.replace(ENC_SLASH_RE, "%252F"));
}
function decodeQueryKey(text) {
return decode(text.replace(PLUS_RE, " "));
}
function decodeQueryValue(text) {
return decode(text.replace(PLUS_RE, " "));
}
function encodeHost(name = "") {
return toASCII(name);
}
function parseQuery(parametersString = "") {
const object = /* @__PURE__ */ Object.create(null);
if (parametersString[0] === "?") {
parametersString = parametersString.slice(1);
}
for (const parameter of parametersString.split("&")) {
const s = parameter.match(/([^=]+)=?(.*)/) || [];
if (s.length < 2) {
continue;
}
const key = decodeQueryKey(s[1]);
if (key === "__proto__" || key === "constructor") {
continue;
}
const value = decodeQueryValue(s[2] || "");
if (object[key] === void 0) {
object[key] = value;
} else if (Array.isArray(object[key])) {
object[key].push(value);
} else {
object[key] = [object[key], value];
}
}
return object;
}
function encodeQueryItem(key, value) {
if (typeof value === "number" || typeof value === "boolean") {
value = String(value);
}
if (!value) {
return encodeQueryKey(key);
}
if (Array.isArray(value)) {
return value.map(
(_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`
).join("&");
}
return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
}
function stringifyQuery(query) {
return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join("&");
}
const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/;
const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/;
const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
const PROTOCOL_SCRIPT_RE = /^[\s\0]*(blob|data|javascript|vbscript):$/i;
const TRAILING_SLASH_RE = /\/$|\/\?|\/#/;
const JOIN_LEADING_SLASH_RE = /^\.?\//;
function isRelative(inputString) {
return ["./", "../"].some((string_) => inputString.startsWith(string_));
}
function hasProtocol(inputString, opts = {}) {
if (typeof opts === "boolean") {
opts = { acceptRelative: opts };
}
if (opts.strict) {
return PROTOCOL_STRICT_REGEX.test(inputString);
}
return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
}
function isScriptProtocol(protocol) {
return !!protocol && PROTOCOL_SCRIPT_RE.test(protocol);
}
function hasTrailingSlash(input = "", respectQueryAndFragment) {
if (!respectQueryAndFragment) {
return input.endsWith("/");
}
return TRAILING_SLASH_RE.test(input);
}
function withoutTrailingSlash(input = "", respectQueryAndFragment) {
if (!respectQueryAndFragment) {
return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
}
if (!hasTrailingSlash(input, true)) {
return input || "/";
}
let path = input;
let fragment = "";
const fragmentIndex = input.indexOf("#");
if (fragmentIndex !== -1) {
path = input.slice(0, fragmentIndex);
fragment = input.slice(fragmentIndex);
}
const [s0, ...s] = path.split("?");
const cleanPath = s0.endsWith("/") ? s0.slice(0, -1) : s0;
return (cleanPath || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
}
function withTrailingSlash(input = "", respectQueryAndFragment) {
if (!respectQueryAndFragment) {
return input.endsWith("/") ? input : input + "/";
}
if (hasTrailingSlash(input, true)) {
return input || "/";
}
let path = input;
let fragment = "";
const fragmentIndex = input.indexOf("#");
if (fragmentIndex !== -1) {
path = input.slice(0, fragmentIndex);
fragment = input.slice(fragmentIndex);
if (!path) {
return fragment;
}
}
const [s0, ...s] = path.split("?");
return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
}
function hasLeadingSlash(input = "") {
return input.startsWith("/");
}
function withoutLeadingSlash(input = "") {
return (hasLeadingSlash(input) ? input.slice(1) : input) || "/";
}
function withLeadingSlash(input = "") {
return hasLeadingSlash(input) ? input : "/" + input;
}
function cleanDoubleSlashes(input = "") {
return input.split("://").map((string_) => string_.replace(/\/{2,}/g, "/")).join("://");
}
function withBase(input, base) {
if (isEmptyURL(base) || hasProtocol(input)) {
return input;
}
const _base = withoutTrailingSlash(base);
if (input.startsWith(_base)) {
return input;
}
return joinURL(_base, input);
}
function withoutBase(input, base) {
if (isEmptyURL(base)) {
return input;
}
const _base = withoutTrailingSlash(base);
if (!input.startsWith(_base)) {
return input;
}
const trimmed = input.slice(_base.length);
return trimmed[0] === "/" ? trimmed : "/" + trimmed;
}
function withQuery(input, query) {
const parsed = parseURL(input);
const mergedQuery = { ...parseQuery(parsed.search), ...query };
parsed.search = stringifyQuery(mergedQuery);
return stringifyParsedURL(parsed);
}
function filterQuery(input, predicate) {
if (!input.includes("?")) {
return input;
}
const parsed = parseURL(input);
const query = parseQuery(parsed.search);
const filteredQuery = Object.fromEntries(
Object.entries(query).filter(([key, value]) => predicate(key, value))
);
parsed.search = stringifyQuery(filteredQuery);
return stringifyParsedURL(parsed);
}
function getQuery(input) {
return parseQuery(parseURL(input).search);
}
function isEmptyURL(url) {
return !url || url === "/";
}
function isNonEmptyURL(url) {
return url && url !== "/";
}
function joinURL(base, ...input) {
let url = base || "";
for (const segment of input.filter((url2) => isNonEmptyURL(url2))) {
if (url) {
const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
url = withTrailingSlash(url) + _segment;
} else {
url = segment;
}
}
return url;
}
function joinRelativeURL(..._input) {
const JOIN_SEGMENT_SPLIT_RE = /\/(?!\/)/;
const input = _input.filter(Boolean);
const segments = [];
let segmentsDepth = 0;
for (const i of input) {
if (!i || i === "/") {
continue;
}
for (const [sindex, s] of i.split(JOIN_SEGMENT_SPLIT_RE).entries()) {
if (!s || s === ".") {
continue;
}
if (s === "..") {
if (segments.length === 1 && hasProtocol(segments[0])) {
continue;
}
segments.pop();
segmentsDepth--;
continue;
}
if (sindex === 1 && segments[segments.length - 1]?.endsWith(":/")) {
segments[segments.length - 1] += "/" + s;
continue;
}
segments.push(s);
segmentsDepth++;
}
}
let url = segments.join("/");
if (segmentsDepth >= 0) {
if (input[0]?.startsWith("/") && !url.startsWith("/")) {
url = "/" + url;
} else if (input[0]?.startsWith("./") && !url.startsWith("./")) {
url = "./" + url;
}
} else {
url = "../".repeat(-1 * segmentsDepth) + url;
}
if (input[input.length - 1]?.endsWith("/") && !url.endsWith("/")) {
url += "/";
}
return url;
}
function withHttp(input) {
return withProtocol(input, "http://");
}
function withHttps(input) {
return withProtocol(input, "https://");
}
function withoutProtocol(input) {
return withProtocol(input, "");
}
function withProtocol(input, protocol) {
let match = input.match(PROTOCOL_REGEX);
if (!match) {
match = input.match(/^\/{2,}/);
}
if (!match) {
return protocol + input;
}
return protocol + input.slice(match[0].length);
}
function normalizeURL(input) {
const parsed = parseURL(input);
parsed.pathname = encodePath(decodePath(parsed.pathname));
parsed.hash = encodeHash(decode(parsed.hash));
parsed.host = encodeHost(decode(parsed.host));
parsed.search = stringifyQuery(parseQuery(parsed.search));
return stringifyParsedURL(parsed);
}
function resolveURL(base = "", ...inputs) {
if (typeof base !== "string") {
throw new TypeError(
`URL input should be string received ${typeof base} (${base})`
);
}
const filteredInputs = inputs.filter((input) => isNonEmptyURL(input));
if (filteredInputs.length === 0) {
return base;
}
const url = parseURL(base);
for (const inputSegment of filteredInputs) {
const urlSegment = parseURL(inputSegment);
if (urlSegment.pathname) {
url.pathname = withTrailingSlash(url.pathname) + withoutLeadingSlash(urlSegment.pathname);
}
if (urlSegment.hash && urlSegment.hash !== "#") {
url.hash = urlSegment.hash;
}
if (urlSegment.search && urlSegment.search !== "?") {
if (url.search && url.search !== "?") {
const queryString = stringifyQuery({
...parseQuery(url.search),
...parseQuery(urlSegment.search)
});
url.search = queryString.length > 0 ? "?" + queryString : "";
} else {
url.search = urlSegment.search;
}
}
}
return stringifyParsedURL(url);
}
function isSamePath(p1, p2) {
return decode(withoutTrailingSlash(p1)) === decode(withoutTrailingSlash(p2));
}
function isEqual(a, b, options = {}) {
if (!options.trailingSlash) {
a = withTrailingSlash(a);
b = withTrailingSlash(b);
}
if (!options.leadingSlash) {
a = withLeadingSlash(a);
b = withLeadingSlash(b);
}
if (!options.encoding) {
a = decode(a);
b = decode(b);
}
return a === b;
}
function withFragment(input, hash) {
if (!hash || hash === "#") {
return input;
}
const parsed = parseURL(input);
parsed.hash = hash === "" ? "" : "#" + encodeHash(hash);
return stringifyParsedURL(parsed);
}
function withoutFragment(input) {
return stringifyParsedURL({ ...parseURL(input), hash: "" });
}
function withoutHost(input) {
const parsed = parseURL(input);
return (parsed.pathname || "/") + parsed.search + parsed.hash;
}
const protocolRelative = Symbol.for("ufo:protocolRelative");
function parseURL(input = "", defaultProto) {
const _specialProtoMatch = input.match(
/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i
);
if (_specialProtoMatch) {
const [, _proto, _pathname = ""] = _specialProtoMatch;
return {
protocol: _proto.toLowerCase(),
pathname: _pathname,
href: _proto + _pathname,
auth: "",
host: "",
search: "",
hash: ""
};
}
if (!hasProtocol(input, { acceptRelative: true })) {
return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
}
const [, protocol = "", auth, hostAndPath = ""] = input.replace(/\\/g, "/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/) || [];
let [, host = "", path = ""] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];
if (protocol === "file:") {
path = path.replace(/\/(?=[A-Za-z]:)/, "");
}
const { pathname, search, hash } = parsePath(path);
return {
protocol: protocol.toLowerCase(),
auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
host,
pathname,
search,
hash,
[protocolRelative]: !protocol
};
}
function parsePath(input = "") {
const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
return {
pathname,
search,
hash
};
}
function parseAuth(input = "") {
const [username, password] = input.split(":");
return {
username: decode(username),
password: decode(password)
};
}
function parseHost(input = "") {
const [hostname, port] = (input.match(/([^/:]*):?(\d+)?/) || []).splice(1);
return {
hostname: decode(hostname),
port
};
}
function stringifyParsedURL(parsed) {
const pathname = parsed.pathname || "";
const search = parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "";
const hash = parsed.hash || "";
const auth = parsed.auth ? parsed.auth + "@" : "";
const host = parsed.host || "";
const proto = parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "";
return proto + auth + host + pathname + search + hash;
}
const FILENAME_STRICT_REGEX = /\/([^/]+\.[^/]+)$/;
const FILENAME_REGEX = /\/([^/]+)$/;
function parseFilename(input = "", opts) {
const { pathname } = parseURL(input);
const matches = opts?.strict ? pathname.match(FILENAME_STRICT_REGEX) : pathname.match(FILENAME_REGEX);
return matches ? matches[1] : void 0;
}
class $URL {
protocol;
host;
auth;
pathname;
query = {};
hash;
constructor(input = "") {
if (typeof input !== "string") {
throw new TypeError(
`URL input should be string received ${typeof input} (${input})`
);
}
const parsed = parseURL(input);
this.protocol = decode(parsed.protocol);
this.host = decode(parsed.host);
this.auth = decode(parsed.auth);
this.pathname = decodePath(parsed.pathname);
this.query = parseQuery(parsed.search);
this.hash = decode(parsed.hash);
}
get hostname() {
return parseHost(this.host).hostname;
}
get port() {
return parseHost(this.host).port || "";
}
get username() {
return parseAuth(this.auth).username;
}
get password() {
return parseAuth(this.auth).password || "";
}
get hasProtocol() {
return this.protocol.length;
}
get isAbsolute() {
return this.hasProtocol || this.pathname[0] === "/";
}
get search() {
const q = stringifyQuery(this.query);
return q.length > 0 ? "?" + q : "";
}
get searchParams() {
const p = new URLSearchParams();
for (const name in this.query) {
const value = this.query[name];
if (Array.isArray(value)) {
for (const v of value) {
p.append(name, v);
}
} else {
p.append(
name,
typeof value === "string" ? value : JSON.stringify(value)
);
}
}
return p;
}
get origin() {
return (this.protocol ? this.protocol + "//" : "") + encodeHost(this.host);
}
get fullpath() {
return encodePath(this.pathname) + this.search + encodeHash(this.hash);
}
get encodedAuth() {
if (!this.auth) {
return "";
}
const { username, password } = parseAuth(this.auth);
return encodeURIComponent(username) + (password ? ":" + encodeURIComponent(password) : "");
}
get href() {
const auth = this.encodedAuth;
const originWithAuth = (this.protocol ? this.protocol + "//" : "") + (auth ? auth + "@" : "") + encodeHost(this.host);
return this.hasProtocol && this.isAbsolute ? originWithAuth + this.fullpath : this.fullpath;
}
append(url) {
if (url.hasProtocol) {
throw new Error("Cannot append a URL with protocol");
}
Object.assign(this.query, url.query);
if (url.pathname) {
this.pathname = withTrailingSlash(this.pathname) + withoutLeadingSlash(url.pathname);
}
if (url.hash) {
this.hash = url.hash;
}
}
toJSON() {
return this.href;
}
toString() {
return this.href;
}
}
function createURL(input) {
return new $URL(input);
}
exports.$URL = $URL;
exports.cleanDoubleSlashes = cleanDoubleSlashes;
exports.createURL = createURL;
exports.decode = decode;
exports.decodePath = decodePath;
exports.decodeQueryKey = decodeQueryKey;
exports.decodeQueryValue = decodeQueryValue;
exports.encode = encode;
exports.encodeHash = encodeHash;
exports.encodeHost = encodeHost;
exports.encodeParam = encodeParam;
exports.encodePath = encodePath;
exports.encodeQueryItem = encodeQueryItem;
exports.encodeQueryKey = encodeQueryKey;
exports.encodeQueryValue = encodeQueryValue;
exports.filterQuery = filterQuery;
exports.getQuery = getQuery;
exports.hasLeadingSlash = hasLeadingSlash;
exports.hasProtocol = hasProtocol;
exports.hasTrailingSlash = hasTrailingSlash;
exports.isEmptyURL = isEmptyURL;
exports.isEqual = isEqual;
exports.isNonEmptyURL = isNonEmptyURL;
exports.isRelative = isRelative;
exports.isSamePath = isSamePath;
exports.isScriptProtocol = isScriptProtocol;
exports.joinRelativeURL = joinRelativeURL;
exports.joinURL = joinURL;
exports.normalizeURL = normalizeURL;
exports.parseAuth = parseAuth;
exports.parseFilename = parseFilename;
exports.parseHost = parseHost;
exports.parsePath = parsePath;
exports.parseQuery = parseQuery;
exports.parseURL = parseURL;
exports.resolveURL = resolveURL;
exports.stringifyParsedURL = stringifyParsedURL;
exports.stringifyQuery = stringifyQuery;
exports.withBase = withBase;
exports.withFragment = withFragment;
exports.withHttp = withHttp;
exports.withHttps = withHttps;
exports.withLeadingSlash = withLeadingSlash;
exports.withProtocol = withProtocol;
exports.withQuery = withQuery;
exports.withTrailingSlash = withTrailingSlash;
exports.withoutBase = withoutBase;
exports.withoutFragment = withoutFragment;
exports.withoutHost = withoutHost;
exports.withoutLeadingSlash = withoutLeadingSlash;
exports.withoutProtocol = withoutProtocol;
exports.withoutTrailingSlash = withoutTrailingSlash;

624
node_modules/ufo/dist/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1,624 @@
type QueryValue = string | number | undefined | null | boolean | Array<QueryValue> | Record<string, any>;
type QueryObject = Record<string, QueryValue | QueryValue[]>;
type ParsedQuery = Record<string, string | string[]>;
/**
* Parses and decodes a query string into an object.
*
* The input can be a query string with or without the leading `?`.
*
* @note
* The `__proto__` and `constructor` keys are ignored to prevent prototype pollution.
*
* @group Query_utils
*/
declare function parseQuery<T extends ParsedQuery = ParsedQuery>(parametersString?: string): T;
/**
* Encodes a pair of key and value into a url query string value.
*
* If the value is an array, it will be encoded as multiple key-value pairs with the same key.
*
* @group Query_utils
*/
declare function encodeQueryItem(key: string, value: QueryValue | QueryValue[]): string;
/**
* Stringfies and encodes a query object into a query string.
*
* @group Query_utils
*/
declare function stringifyQuery(query: QueryObject): string;
/**
* Encodes characters that need to be encoded in the path, search and hash
* sections of the URL.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encode(text: string | number): string;
/**
* Encodes characters that need to be encoded in the hash section of the URL.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encodeHash(text: string): string;
/**
* Encodes characters that need to be encoded for query values in the query
* section of the URL.
*
* @group encoding_utils
*
* @param input - string to encode
* @returns encoded string
*/
declare function encodeQueryValue(input: QueryValue): string;
/**
* Encodes characters that need to be encoded for query values in the query
* section of the URL and also encodes the `=` character.
*
* @group encoding_utils
*
* @param text - string to encode
*/
declare function encodeQueryKey(text: string | number): string;
/**
* Encodes characters that need to be encoded in the path section of the URL.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encodePath(text: string | number): string;
/**
* Encodes characters that need to be encoded in the path section of the URL as a
* param. This function encodes everything `encodePath` does plus the
* slash (`/`) character.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encodeParam(text: string | number): string;
/**
* Decodes text using `decodeURIComponent`. Returns the original text if it
* fails.
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decode(text?: string | number): string;
/**
* Decodes path section of URL (consistent with encodePath for slash encoding).
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decodePath(text: string): string;
/**
* Decodes query key (consistent with `encodeQueryKey` for plus encoding).
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decodeQueryKey(text: string): string;
/**
* Decodes query value (consistent with `encodeQueryValue` for plus encoding).
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decodeQueryValue(text: string): string;
/**
* Encodes hostname with punycode encoding.
*
* @group encoding_utils
*/
declare function encodeHost(name?: string): string;
declare const protocolRelative: unique symbol;
interface ParsedURL {
protocol?: string;
host?: string;
auth?: string;
href?: string;
pathname: string;
hash: string;
search: string;
[protocolRelative]?: boolean;
}
interface ParsedAuth {
username: string;
password: string;
}
interface ParsedHost {
hostname: string;
port: string;
}
/**
* Takes a URL string and returns an object with the URL's `protocol`, `auth`, `host`, `pathname`, `search`, and `hash`.
*
* @example
*
* ```js
* parseURL("http://foo.com/foo?test=123#token");
* // { protocol: 'http:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
*
* parseURL("foo.com/foo?test=123#token");
* // { pathname: 'foo.com/foo', search: '?test=123', hash: '#token' }
*
* parseURL("foo.com/foo?test=123#token", "https://");
* // { protocol: 'https:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
* ```
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @param [defaultProto] - The default protocol to use if the input doesn't have one.
* @returns A parsed URL object.
*/
declare function parseURL(input?: string, defaultProto?: string): ParsedURL;
/**
* Splits the input string into three parts, and returns an object with those three parts.
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @returns An object with three properties: `pathname`, `search`, and `hash`.
*/
declare function parsePath(input?: string): ParsedURL;
/**
* Takes a string of the form `username:password` and returns an object with the username and
* password decoded.
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @returns An object with two properties: username and password.
*/
declare function parseAuth(input?: string): ParsedAuth;
/**
* Takes a string, and returns an object with two properties: `hostname` and `port`.
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @returns A function that takes a string and returns an object with two properties: `hostname` and
* `port`.
*/
declare function parseHost(input?: string): ParsedHost;
/**
* Takes a `ParsedURL` object and returns the stringified URL.
*
* @group parsing_utils
*
* @example
*
* ```js
* const obj = parseURL("http://foo.com/foo?test=123#token");
* obj.host = "bar.com";
*
* stringifyParsedURL(obj); // "http://bar.com/foo?test=123#token"
* ```
*
* @param [parsed] - The parsed URL
* @returns A stringified URL.
*/
declare function stringifyParsedURL(parsed: Partial<ParsedURL>): string;
/**
* Parses a URL and returns last segment in path as filename.
*
* If `{ strict: true }` is passed as the second argument, it will only return the last segment only if ending with an extension.
*
* @group parsing_utils
*
* @example
*
* ```js
* // Result: filename.ext
* parseFilename("http://example.com/path/to/filename.ext");
*
* // Result: undefined
* parseFilename("/path/to/.hidden-file", { strict: true });
* ```
*
* @param [input] - The URL to parse.
* @param [opts] - Options to use while parsing
*/
declare function parseFilename(input?: string, opts?: {
strict?: boolean;
}): string | undefined;
/**
* @deprecated use native URL with `new URL(input)` or `ufo.parseURL(input)`
*/
declare class $URL implements URL {
protocol: string;
host: string;
auth: string;
pathname: string;
query: QueryObject;
hash: string;
constructor(input?: string);
get hostname(): string;
get port(): string;
get username(): string;
get password(): string;
get hasProtocol(): number;
get isAbsolute(): number | boolean;
get search(): string;
get searchParams(): URLSearchParams;
get origin(): string;
get fullpath(): string;
get encodedAuth(): string;
get href(): string;
append(url: $URL): void;
toJSON(): string;
toString(): string;
}
/**
* @deprecated use native URL with `new URL(input)` or `ufo.parseURL(input)`
*/
declare function createURL(input: string): $URL;
/**
* Check if a path starts with `./` or `../`.
*
* @example
* ```js
* isRelative("./foo"); // true
* ```
*
* @group utils
*/
declare function isRelative(inputString: string): boolean;
interface HasProtocolOptions {
acceptRelative?: boolean;
strict?: boolean;
}
/**
* Checks if the input has a protocol.
*
* You can use `{ acceptRelative: true }` to accept relative URLs as valid protocol.
*
* @group utils
*/
declare function hasProtocol(inputString: string, opts?: HasProtocolOptions): boolean;
/** @deprecated Same as { hasProtocol(inputString, { acceptRelative: true }) */
declare function hasProtocol(inputString: string, acceptRelative: boolean): boolean;
/**
* Checks if the input protocol is any of the dangerous `blob:`, `data:`, `javascript`: or `vbscript:` protocols.
*
* @group utils
*/
declare function isScriptProtocol(protocol?: string): boolean;
/**
* Checks if the input has a trailing slash.
*
* @group utils
*/
declare function hasTrailingSlash(input?: string, respectQueryAndFragment?: boolean): boolean;
/**
* Removes the trailing slash from the URL or pathname.
*
* If second argument is `true`, it will only remove the trailing slash if it's not part of the query or fragment with cost of more expensive operations.
*
* @example
*
* ```js
* withoutTrailingSlash("/foo/"); // "/foo"
*
* withoutTrailingSlash("/path/?query=true", true); // "/path?query=true"
* ```
*
* @group utils
*/
declare function withoutTrailingSlash(input?: string, respectQueryAndFragment?: boolean): string;
/**
* Ensures the URL ends with a trailing slash.
*
* If second argument is `true`, it will only add the trailing slash if it's not part of the query or fragment with cost of more expensive operation.
*
* @example
*
* ```js
* withTrailingSlash("/foo"); // "/foo/"
*
* withTrailingSlash("/path?query=true", true); // "/path/?query=true"
* ```
*
* @group utils
*/
declare function withTrailingSlash(input?: string, respectQueryAndFragment?: boolean): string;
/**
* Checks if the input has a leading slash (e.g. `/foo`).
*
* @group utils
*/
declare function hasLeadingSlash(input?: string): boolean;
/**
* Removes leading slash from the URL or pathname.
*
* @group utils
*/
declare function withoutLeadingSlash(input?: string): string;
/**
* Ensures the URL or pathname has a leading slash.
*
* @group utils
*/
declare function withLeadingSlash(input?: string): string;
/**
* Removes double slashes from the URL.
*
* @example
*
* ```js
* cleanDoubleSlashes("//foo//bar//"); // "/foo/bar/"
*
* cleanDoubleSlashes("http://example.com/analyze//http://localhost:3000//");
* // Returns "http://example.com/analyze/http://localhost:3000/"
* ```
*
* @group utils
*/
declare function cleanDoubleSlashes(input?: string): string;
/**
* Ensures the URL or pathname starts with base.
*
* If input already starts with base, it will not be added again.
*
* @group utils
*/
declare function withBase(input: string, base: string): string;
/**
* Removes the base from the URL or pathname.
*
* If input does not start with base, it will not be removed.
*
* @group utils
*/
declare function withoutBase(input: string, base: string): string;
/**
* Add/Replace the query section of the URL.
*
* @example
*
* ```js
* withQuery("/foo?page=a", { token: "secret" }); // "/foo?page=a&token=secret"
* ```
*
* @group utils
*/
declare function withQuery(input: string, query: QueryObject): string;
/**
* Removes the query section of the URL.
*
* @example
*
* ```js
* filterQuery("/foo?bar=1&baz=2", (key) => key !== "bar"); // "/foo?baz=2"
* ```
*
* @group utils
*/
declare function filterQuery(input: string, predicate: (key: string, value: string | string[]) => boolean): string;
/**
* Parses and decodes the query object of an input URL into an object.
*
* @example
*
* ```js
* getQuery("http://foo.com/foo?test=123&unicode=%E5%A5%BD");
* // { test: "123", unicode: "好" }
* ```
* @group utils
*/
declare function getQuery<T extends ParsedQuery = ParsedQuery>(input: string): T;
/**
* Checks if the input URL is empty or `/`.
*
* @group utils
*/
declare function isEmptyURL(url: string): boolean;
/**
* Checks if the input URL is neither empty nor `/`.
*
* @group utils
*/
declare function isNonEmptyURL(url: string): boolean;
/**
* Joins multiple URL segments into a single URL.
*
* @example
*
* ```js
* joinURL("a", "/b", "/c"); // "a/b/c"
* ```
*
* @group utils
*/
declare function joinURL(base: string, ...input: string[]): string;
/**
* Joins multiple URL segments into a single URL and also handles relative paths with `./` and `../`.
*
* @example
*
* ```js
* joinRelativeURL("/a", "../b", "./c"); // "/b/c"
* ```
*
* @group utils
*/
declare function joinRelativeURL(..._input: string[]): string;
/**
* Adds or replaces the URL protocol to `http://`.
*
* @example
*
* ```js
* withHttp("https://example.com"); // http://example.com
* ```
*
* @group utils
*/
declare function withHttp(input: string): string;
/**
* Adds or replaces the URL protocol to `https://`.
*
* @example
*
* ```js
* withHttps("http://example.com"); // https://example.com
* ```
*
* @group utils
*/
declare function withHttps(input: string): string;
/**
* Removes the protocol from the input.
*
* @example
* ```js
* withoutProtocol("http://example.com"); // "example.com"
* ```
*/
declare function withoutProtocol(input: string): string;
/**
* Adds or replaces protocol of the input URL.
*
* @example
* ```js
* withProtocol("http://example.com", "ftp://"); // "ftp://example.com"
* ```
*
* @group utils
*/
declare function withProtocol(input: string, protocol: string): string;
/**
* Normalizes the input URL:
*
* - Ensures the URL is properly encoded
* - Ensures pathname starts with a slash
* - Preserves protocol/host if provided
*
* @example
*
* ```js
* normalizeURL("test?query=123 123#hash, test");
* // Returns "test?query=123%20123#hash,%20test"
*
* normalizeURL("http://localhost:3000");
* // Returns "http://localhost:3000"
* ```
*
* @group utils
*/
declare function normalizeURL(input: string): string;
/**
* Resolves multiple URL segments into a single URL.
*
* @example
*
* ```js
* resolveURL("http://foo.com/foo?test=123#token", "bar", "baz");
* // Returns "http://foo.com/foo/bar/baz?test=123#token"
* ```
*
* @group utils
*/
declare function resolveURL(base?: string, ...inputs: string[]): string;
/**
* Check if two paths are equal or not. Trailing slash and encoding are normalized before comparison.
*
* @example
* ```js
* isSamePath("/foo", "/foo/"); // true
* ```
*
* @group utils
*/
declare function isSamePath(p1: string, p2: string): boolean;
interface CompareURLOptions {
trailingSlash?: boolean;
leadingSlash?: boolean;
encoding?: boolean;
}
/**
* Checks if two paths are equal regardless of encoding, trailing slash, and leading slash differences.
*
* You can make slash check strict by setting `{ trailingSlash: true, leadingSlash: true }` as options.
*
* You can make encoding check strict by setting `{ encoding: true }` as options.
*
* @example
*
* ```js
* isEqual("/foo", "foo"); // true
* isEqual("foo/", "foo"); // true
* isEqual("/foo bar", "/foo%20bar"); // true
*
* // Strict compare
* isEqual("/foo", "foo", { leadingSlash: true }); // false
* isEqual("foo/", "foo", { trailingSlash: true }); // false
* isEqual("/foo bar", "/foo%20bar", { encoding: true }); // false
* ```
*
* @group utils
*/
declare function isEqual(a: string, b: string, options?: CompareURLOptions): boolean;
/**
* Adds or replaces the fragment section of the URL.
*
* @example
*
* ```js
* withFragment("/foo", "bar"); // "/foo#bar"
* withFragment("/foo#bar", "baz"); // "/foo#baz"
* withFragment("/foo#bar", ""); // "/foo"
* ```
*
* @group utils
*/
declare function withFragment(input: string, hash: string): string;
/**
* Removes the fragment section from the URL.
*
* @example
*
* ```js
* withoutFragment("http://example.com/foo?q=123#bar")
* // Returns "http://example.com/foo?q=123"
* ```
*
* @group utils
*/
declare function withoutFragment(input: string): string;
/**
* Removes the host from the URL while preserving everything else.
*
* @example
* ```js
* withoutHost("http://example.com/foo?q=123#bar")
* // Returns "/foo?q=123#bar"
* ```
*
* @group utils
*/
declare function withoutHost(input: string): string;
export { $URL, cleanDoubleSlashes, createURL, decode, decodePath, decodeQueryKey, decodeQueryValue, encode, encodeHash, encodeHost, encodeParam, encodePath, encodeQueryItem, encodeQueryKey, encodeQueryValue, filterQuery, getQuery, hasLeadingSlash, hasProtocol, hasTrailingSlash, isEmptyURL, isEqual, isNonEmptyURL, isRelative, isSamePath, isScriptProtocol, joinRelativeURL, joinURL, normalizeURL, parseAuth, parseFilename, parseHost, parsePath, parseQuery, parseURL, resolveURL, stringifyParsedURL, stringifyQuery, withBase, withFragment, withHttp, withHttps, withLeadingSlash, withProtocol, withQuery, withTrailingSlash, withoutBase, withoutFragment, withoutHost, withoutLeadingSlash, withoutProtocol, withoutTrailingSlash };
export type { HasProtocolOptions, ParsedAuth, ParsedHost, ParsedQuery, ParsedURL, QueryObject, QueryValue };

624
node_modules/ufo/dist/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,624 @@
type QueryValue = string | number | undefined | null | boolean | Array<QueryValue> | Record<string, any>;
type QueryObject = Record<string, QueryValue | QueryValue[]>;
type ParsedQuery = Record<string, string | string[]>;
/**
* Parses and decodes a query string into an object.
*
* The input can be a query string with or without the leading `?`.
*
* @note
* The `__proto__` and `constructor` keys are ignored to prevent prototype pollution.
*
* @group Query_utils
*/
declare function parseQuery<T extends ParsedQuery = ParsedQuery>(parametersString?: string): T;
/**
* Encodes a pair of key and value into a url query string value.
*
* If the value is an array, it will be encoded as multiple key-value pairs with the same key.
*
* @group Query_utils
*/
declare function encodeQueryItem(key: string, value: QueryValue | QueryValue[]): string;
/**
* Stringfies and encodes a query object into a query string.
*
* @group Query_utils
*/
declare function stringifyQuery(query: QueryObject): string;
/**
* Encodes characters that need to be encoded in the path, search and hash
* sections of the URL.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encode(text: string | number): string;
/**
* Encodes characters that need to be encoded in the hash section of the URL.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encodeHash(text: string): string;
/**
* Encodes characters that need to be encoded for query values in the query
* section of the URL.
*
* @group encoding_utils
*
* @param input - string to encode
* @returns encoded string
*/
declare function encodeQueryValue(input: QueryValue): string;
/**
* Encodes characters that need to be encoded for query values in the query
* section of the URL and also encodes the `=` character.
*
* @group encoding_utils
*
* @param text - string to encode
*/
declare function encodeQueryKey(text: string | number): string;
/**
* Encodes characters that need to be encoded in the path section of the URL.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encodePath(text: string | number): string;
/**
* Encodes characters that need to be encoded in the path section of the URL as a
* param. This function encodes everything `encodePath` does plus the
* slash (`/`) character.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encodeParam(text: string | number): string;
/**
* Decodes text using `decodeURIComponent`. Returns the original text if it
* fails.
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decode(text?: string | number): string;
/**
* Decodes path section of URL (consistent with encodePath for slash encoding).
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decodePath(text: string): string;
/**
* Decodes query key (consistent with `encodeQueryKey` for plus encoding).
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decodeQueryKey(text: string): string;
/**
* Decodes query value (consistent with `encodeQueryValue` for plus encoding).
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decodeQueryValue(text: string): string;
/**
* Encodes hostname with punycode encoding.
*
* @group encoding_utils
*/
declare function encodeHost(name?: string): string;
declare const protocolRelative: unique symbol;
interface ParsedURL {
protocol?: string;
host?: string;
auth?: string;
href?: string;
pathname: string;
hash: string;
search: string;
[protocolRelative]?: boolean;
}
interface ParsedAuth {
username: string;
password: string;
}
interface ParsedHost {
hostname: string;
port: string;
}
/**
* Takes a URL string and returns an object with the URL's `protocol`, `auth`, `host`, `pathname`, `search`, and `hash`.
*
* @example
*
* ```js
* parseURL("http://foo.com/foo?test=123#token");
* // { protocol: 'http:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
*
* parseURL("foo.com/foo?test=123#token");
* // { pathname: 'foo.com/foo', search: '?test=123', hash: '#token' }
*
* parseURL("foo.com/foo?test=123#token", "https://");
* // { protocol: 'https:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
* ```
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @param [defaultProto] - The default protocol to use if the input doesn't have one.
* @returns A parsed URL object.
*/
declare function parseURL(input?: string, defaultProto?: string): ParsedURL;
/**
* Splits the input string into three parts, and returns an object with those three parts.
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @returns An object with three properties: `pathname`, `search`, and `hash`.
*/
declare function parsePath(input?: string): ParsedURL;
/**
* Takes a string of the form `username:password` and returns an object with the username and
* password decoded.
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @returns An object with two properties: username and password.
*/
declare function parseAuth(input?: string): ParsedAuth;
/**
* Takes a string, and returns an object with two properties: `hostname` and `port`.
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @returns A function that takes a string and returns an object with two properties: `hostname` and
* `port`.
*/
declare function parseHost(input?: string): ParsedHost;
/**
* Takes a `ParsedURL` object and returns the stringified URL.
*
* @group parsing_utils
*
* @example
*
* ```js
* const obj = parseURL("http://foo.com/foo?test=123#token");
* obj.host = "bar.com";
*
* stringifyParsedURL(obj); // "http://bar.com/foo?test=123#token"
* ```
*
* @param [parsed] - The parsed URL
* @returns A stringified URL.
*/
declare function stringifyParsedURL(parsed: Partial<ParsedURL>): string;
/**
* Parses a URL and returns last segment in path as filename.
*
* If `{ strict: true }` is passed as the second argument, it will only return the last segment only if ending with an extension.
*
* @group parsing_utils
*
* @example
*
* ```js
* // Result: filename.ext
* parseFilename("http://example.com/path/to/filename.ext");
*
* // Result: undefined
* parseFilename("/path/to/.hidden-file", { strict: true });
* ```
*
* @param [input] - The URL to parse.
* @param [opts] - Options to use while parsing
*/
declare function parseFilename(input?: string, opts?: {
strict?: boolean;
}): string | undefined;
/**
* @deprecated use native URL with `new URL(input)` or `ufo.parseURL(input)`
*/
declare class $URL implements URL {
protocol: string;
host: string;
auth: string;
pathname: string;
query: QueryObject;
hash: string;
constructor(input?: string);
get hostname(): string;
get port(): string;
get username(): string;
get password(): string;
get hasProtocol(): number;
get isAbsolute(): number | boolean;
get search(): string;
get searchParams(): URLSearchParams;
get origin(): string;
get fullpath(): string;
get encodedAuth(): string;
get href(): string;
append(url: $URL): void;
toJSON(): string;
toString(): string;
}
/**
* @deprecated use native URL with `new URL(input)` or `ufo.parseURL(input)`
*/
declare function createURL(input: string): $URL;
/**
* Check if a path starts with `./` or `../`.
*
* @example
* ```js
* isRelative("./foo"); // true
* ```
*
* @group utils
*/
declare function isRelative(inputString: string): boolean;
interface HasProtocolOptions {
acceptRelative?: boolean;
strict?: boolean;
}
/**
* Checks if the input has a protocol.
*
* You can use `{ acceptRelative: true }` to accept relative URLs as valid protocol.
*
* @group utils
*/
declare function hasProtocol(inputString: string, opts?: HasProtocolOptions): boolean;
/** @deprecated Same as { hasProtocol(inputString, { acceptRelative: true }) */
declare function hasProtocol(inputString: string, acceptRelative: boolean): boolean;
/**
* Checks if the input protocol is any of the dangerous `blob:`, `data:`, `javascript`: or `vbscript:` protocols.
*
* @group utils
*/
declare function isScriptProtocol(protocol?: string): boolean;
/**
* Checks if the input has a trailing slash.
*
* @group utils
*/
declare function hasTrailingSlash(input?: string, respectQueryAndFragment?: boolean): boolean;
/**
* Removes the trailing slash from the URL or pathname.
*
* If second argument is `true`, it will only remove the trailing slash if it's not part of the query or fragment with cost of more expensive operations.
*
* @example
*
* ```js
* withoutTrailingSlash("/foo/"); // "/foo"
*
* withoutTrailingSlash("/path/?query=true", true); // "/path?query=true"
* ```
*
* @group utils
*/
declare function withoutTrailingSlash(input?: string, respectQueryAndFragment?: boolean): string;
/**
* Ensures the URL ends with a trailing slash.
*
* If second argument is `true`, it will only add the trailing slash if it's not part of the query or fragment with cost of more expensive operation.
*
* @example
*
* ```js
* withTrailingSlash("/foo"); // "/foo/"
*
* withTrailingSlash("/path?query=true", true); // "/path/?query=true"
* ```
*
* @group utils
*/
declare function withTrailingSlash(input?: string, respectQueryAndFragment?: boolean): string;
/**
* Checks if the input has a leading slash (e.g. `/foo`).
*
* @group utils
*/
declare function hasLeadingSlash(input?: string): boolean;
/**
* Removes leading slash from the URL or pathname.
*
* @group utils
*/
declare function withoutLeadingSlash(input?: string): string;
/**
* Ensures the URL or pathname has a leading slash.
*
* @group utils
*/
declare function withLeadingSlash(input?: string): string;
/**
* Removes double slashes from the URL.
*
* @example
*
* ```js
* cleanDoubleSlashes("//foo//bar//"); // "/foo/bar/"
*
* cleanDoubleSlashes("http://example.com/analyze//http://localhost:3000//");
* // Returns "http://example.com/analyze/http://localhost:3000/"
* ```
*
* @group utils
*/
declare function cleanDoubleSlashes(input?: string): string;
/**
* Ensures the URL or pathname starts with base.
*
* If input already starts with base, it will not be added again.
*
* @group utils
*/
declare function withBase(input: string, base: string): string;
/**
* Removes the base from the URL or pathname.
*
* If input does not start with base, it will not be removed.
*
* @group utils
*/
declare function withoutBase(input: string, base: string): string;
/**
* Add/Replace the query section of the URL.
*
* @example
*
* ```js
* withQuery("/foo?page=a", { token: "secret" }); // "/foo?page=a&token=secret"
* ```
*
* @group utils
*/
declare function withQuery(input: string, query: QueryObject): string;
/**
* Removes the query section of the URL.
*
* @example
*
* ```js
* filterQuery("/foo?bar=1&baz=2", (key) => key !== "bar"); // "/foo?baz=2"
* ```
*
* @group utils
*/
declare function filterQuery(input: string, predicate: (key: string, value: string | string[]) => boolean): string;
/**
* Parses and decodes the query object of an input URL into an object.
*
* @example
*
* ```js
* getQuery("http://foo.com/foo?test=123&unicode=%E5%A5%BD");
* // { test: "123", unicode: "好" }
* ```
* @group utils
*/
declare function getQuery<T extends ParsedQuery = ParsedQuery>(input: string): T;
/**
* Checks if the input URL is empty or `/`.
*
* @group utils
*/
declare function isEmptyURL(url: string): boolean;
/**
* Checks if the input URL is neither empty nor `/`.
*
* @group utils
*/
declare function isNonEmptyURL(url: string): boolean;
/**
* Joins multiple URL segments into a single URL.
*
* @example
*
* ```js
* joinURL("a", "/b", "/c"); // "a/b/c"
* ```
*
* @group utils
*/
declare function joinURL(base: string, ...input: string[]): string;
/**
* Joins multiple URL segments into a single URL and also handles relative paths with `./` and `../`.
*
* @example
*
* ```js
* joinRelativeURL("/a", "../b", "./c"); // "/b/c"
* ```
*
* @group utils
*/
declare function joinRelativeURL(..._input: string[]): string;
/**
* Adds or replaces the URL protocol to `http://`.
*
* @example
*
* ```js
* withHttp("https://example.com"); // http://example.com
* ```
*
* @group utils
*/
declare function withHttp(input: string): string;
/**
* Adds or replaces the URL protocol to `https://`.
*
* @example
*
* ```js
* withHttps("http://example.com"); // https://example.com
* ```
*
* @group utils
*/
declare function withHttps(input: string): string;
/**
* Removes the protocol from the input.
*
* @example
* ```js
* withoutProtocol("http://example.com"); // "example.com"
* ```
*/
declare function withoutProtocol(input: string): string;
/**
* Adds or replaces protocol of the input URL.
*
* @example
* ```js
* withProtocol("http://example.com", "ftp://"); // "ftp://example.com"
* ```
*
* @group utils
*/
declare function withProtocol(input: string, protocol: string): string;
/**
* Normalizes the input URL:
*
* - Ensures the URL is properly encoded
* - Ensures pathname starts with a slash
* - Preserves protocol/host if provided
*
* @example
*
* ```js
* normalizeURL("test?query=123 123#hash, test");
* // Returns "test?query=123%20123#hash,%20test"
*
* normalizeURL("http://localhost:3000");
* // Returns "http://localhost:3000"
* ```
*
* @group utils
*/
declare function normalizeURL(input: string): string;
/**
* Resolves multiple URL segments into a single URL.
*
* @example
*
* ```js
* resolveURL("http://foo.com/foo?test=123#token", "bar", "baz");
* // Returns "http://foo.com/foo/bar/baz?test=123#token"
* ```
*
* @group utils
*/
declare function resolveURL(base?: string, ...inputs: string[]): string;
/**
* Check if two paths are equal or not. Trailing slash and encoding are normalized before comparison.
*
* @example
* ```js
* isSamePath("/foo", "/foo/"); // true
* ```
*
* @group utils
*/
declare function isSamePath(p1: string, p2: string): boolean;
interface CompareURLOptions {
trailingSlash?: boolean;
leadingSlash?: boolean;
encoding?: boolean;
}
/**
* Checks if two paths are equal regardless of encoding, trailing slash, and leading slash differences.
*
* You can make slash check strict by setting `{ trailingSlash: true, leadingSlash: true }` as options.
*
* You can make encoding check strict by setting `{ encoding: true }` as options.
*
* @example
*
* ```js
* isEqual("/foo", "foo"); // true
* isEqual("foo/", "foo"); // true
* isEqual("/foo bar", "/foo%20bar"); // true
*
* // Strict compare
* isEqual("/foo", "foo", { leadingSlash: true }); // false
* isEqual("foo/", "foo", { trailingSlash: true }); // false
* isEqual("/foo bar", "/foo%20bar", { encoding: true }); // false
* ```
*
* @group utils
*/
declare function isEqual(a: string, b: string, options?: CompareURLOptions): boolean;
/**
* Adds or replaces the fragment section of the URL.
*
* @example
*
* ```js
* withFragment("/foo", "bar"); // "/foo#bar"
* withFragment("/foo#bar", "baz"); // "/foo#baz"
* withFragment("/foo#bar", ""); // "/foo"
* ```
*
* @group utils
*/
declare function withFragment(input: string, hash: string): string;
/**
* Removes the fragment section from the URL.
*
* @example
*
* ```js
* withoutFragment("http://example.com/foo?q=123#bar")
* // Returns "http://example.com/foo?q=123"
* ```
*
* @group utils
*/
declare function withoutFragment(input: string): string;
/**
* Removes the host from the URL while preserving everything else.
*
* @example
* ```js
* withoutHost("http://example.com/foo?q=123#bar")
* // Returns "/foo?q=123#bar"
* ```
*
* @group utils
*/
declare function withoutHost(input: string): string;
export { $URL, cleanDoubleSlashes, createURL, decode, decodePath, decodeQueryKey, decodeQueryValue, encode, encodeHash, encodeHost, encodeParam, encodePath, encodeQueryItem, encodeQueryKey, encodeQueryValue, filterQuery, getQuery, hasLeadingSlash, hasProtocol, hasTrailingSlash, isEmptyURL, isEqual, isNonEmptyURL, isRelative, isSamePath, isScriptProtocol, joinRelativeURL, joinURL, normalizeURL, parseAuth, parseFilename, parseHost, parsePath, parseQuery, parseURL, resolveURL, stringifyParsedURL, stringifyQuery, withBase, withFragment, withHttp, withHttps, withLeadingSlash, withProtocol, withQuery, withTrailingSlash, withoutBase, withoutFragment, withoutHost, withoutLeadingSlash, withoutProtocol, withoutTrailingSlash };
export type { HasProtocolOptions, ParsedAuth, ParsedHost, ParsedQuery, ParsedURL, QueryObject, QueryValue };

624
node_modules/ufo/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,624 @@
type QueryValue = string | number | undefined | null | boolean | Array<QueryValue> | Record<string, any>;
type QueryObject = Record<string, QueryValue | QueryValue[]>;
type ParsedQuery = Record<string, string | string[]>;
/**
* Parses and decodes a query string into an object.
*
* The input can be a query string with or without the leading `?`.
*
* @note
* The `__proto__` and `constructor` keys are ignored to prevent prototype pollution.
*
* @group Query_utils
*/
declare function parseQuery<T extends ParsedQuery = ParsedQuery>(parametersString?: string): T;
/**
* Encodes a pair of key and value into a url query string value.
*
* If the value is an array, it will be encoded as multiple key-value pairs with the same key.
*
* @group Query_utils
*/
declare function encodeQueryItem(key: string, value: QueryValue | QueryValue[]): string;
/**
* Stringfies and encodes a query object into a query string.
*
* @group Query_utils
*/
declare function stringifyQuery(query: QueryObject): string;
/**
* Encodes characters that need to be encoded in the path, search and hash
* sections of the URL.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encode(text: string | number): string;
/**
* Encodes characters that need to be encoded in the hash section of the URL.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encodeHash(text: string): string;
/**
* Encodes characters that need to be encoded for query values in the query
* section of the URL.
*
* @group encoding_utils
*
* @param input - string to encode
* @returns encoded string
*/
declare function encodeQueryValue(input: QueryValue): string;
/**
* Encodes characters that need to be encoded for query values in the query
* section of the URL and also encodes the `=` character.
*
* @group encoding_utils
*
* @param text - string to encode
*/
declare function encodeQueryKey(text: string | number): string;
/**
* Encodes characters that need to be encoded in the path section of the URL.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encodePath(text: string | number): string;
/**
* Encodes characters that need to be encoded in the path section of the URL as a
* param. This function encodes everything `encodePath` does plus the
* slash (`/`) character.
*
* @group encoding_utils
*
* @param text - string to encode
* @returns encoded string
*/
declare function encodeParam(text: string | number): string;
/**
* Decodes text using `decodeURIComponent`. Returns the original text if it
* fails.
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decode(text?: string | number): string;
/**
* Decodes path section of URL (consistent with encodePath for slash encoding).
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decodePath(text: string): string;
/**
* Decodes query key (consistent with `encodeQueryKey` for plus encoding).
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decodeQueryKey(text: string): string;
/**
* Decodes query value (consistent with `encodeQueryValue` for plus encoding).
*
* @group encoding_utils
*
* @param text - string to decode
* @returns decoded string
*/
declare function decodeQueryValue(text: string): string;
/**
* Encodes hostname with punycode encoding.
*
* @group encoding_utils
*/
declare function encodeHost(name?: string): string;
declare const protocolRelative: unique symbol;
interface ParsedURL {
protocol?: string;
host?: string;
auth?: string;
href?: string;
pathname: string;
hash: string;
search: string;
[protocolRelative]?: boolean;
}
interface ParsedAuth {
username: string;
password: string;
}
interface ParsedHost {
hostname: string;
port: string;
}
/**
* Takes a URL string and returns an object with the URL's `protocol`, `auth`, `host`, `pathname`, `search`, and `hash`.
*
* @example
*
* ```js
* parseURL("http://foo.com/foo?test=123#token");
* // { protocol: 'http:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
*
* parseURL("foo.com/foo?test=123#token");
* // { pathname: 'foo.com/foo', search: '?test=123', hash: '#token' }
*
* parseURL("foo.com/foo?test=123#token", "https://");
* // { protocol: 'https:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
* ```
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @param [defaultProto] - The default protocol to use if the input doesn't have one.
* @returns A parsed URL object.
*/
declare function parseURL(input?: string, defaultProto?: string): ParsedURL;
/**
* Splits the input string into three parts, and returns an object with those three parts.
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @returns An object with three properties: `pathname`, `search`, and `hash`.
*/
declare function parsePath(input?: string): ParsedURL;
/**
* Takes a string of the form `username:password` and returns an object with the username and
* password decoded.
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @returns An object with two properties: username and password.
*/
declare function parseAuth(input?: string): ParsedAuth;
/**
* Takes a string, and returns an object with two properties: `hostname` and `port`.
*
* @group parsing_utils
*
* @param [input] - The URL to parse.
* @returns A function that takes a string and returns an object with two properties: `hostname` and
* `port`.
*/
declare function parseHost(input?: string): ParsedHost;
/**
* Takes a `ParsedURL` object and returns the stringified URL.
*
* @group parsing_utils
*
* @example
*
* ```js
* const obj = parseURL("http://foo.com/foo?test=123#token");
* obj.host = "bar.com";
*
* stringifyParsedURL(obj); // "http://bar.com/foo?test=123#token"
* ```
*
* @param [parsed] - The parsed URL
* @returns A stringified URL.
*/
declare function stringifyParsedURL(parsed: Partial<ParsedURL>): string;
/**
* Parses a URL and returns last segment in path as filename.
*
* If `{ strict: true }` is passed as the second argument, it will only return the last segment only if ending with an extension.
*
* @group parsing_utils
*
* @example
*
* ```js
* // Result: filename.ext
* parseFilename("http://example.com/path/to/filename.ext");
*
* // Result: undefined
* parseFilename("/path/to/.hidden-file", { strict: true });
* ```
*
* @param [input] - The URL to parse.
* @param [opts] - Options to use while parsing
*/
declare function parseFilename(input?: string, opts?: {
strict?: boolean;
}): string | undefined;
/**
* @deprecated use native URL with `new URL(input)` or `ufo.parseURL(input)`
*/
declare class $URL implements URL {
protocol: string;
host: string;
auth: string;
pathname: string;
query: QueryObject;
hash: string;
constructor(input?: string);
get hostname(): string;
get port(): string;
get username(): string;
get password(): string;
get hasProtocol(): number;
get isAbsolute(): number | boolean;
get search(): string;
get searchParams(): URLSearchParams;
get origin(): string;
get fullpath(): string;
get encodedAuth(): string;
get href(): string;
append(url: $URL): void;
toJSON(): string;
toString(): string;
}
/**
* @deprecated use native URL with `new URL(input)` or `ufo.parseURL(input)`
*/
declare function createURL(input: string): $URL;
/**
* Check if a path starts with `./` or `../`.
*
* @example
* ```js
* isRelative("./foo"); // true
* ```
*
* @group utils
*/
declare function isRelative(inputString: string): boolean;
interface HasProtocolOptions {
acceptRelative?: boolean;
strict?: boolean;
}
/**
* Checks if the input has a protocol.
*
* You can use `{ acceptRelative: true }` to accept relative URLs as valid protocol.
*
* @group utils
*/
declare function hasProtocol(inputString: string, opts?: HasProtocolOptions): boolean;
/** @deprecated Same as { hasProtocol(inputString, { acceptRelative: true }) */
declare function hasProtocol(inputString: string, acceptRelative: boolean): boolean;
/**
* Checks if the input protocol is any of the dangerous `blob:`, `data:`, `javascript`: or `vbscript:` protocols.
*
* @group utils
*/
declare function isScriptProtocol(protocol?: string): boolean;
/**
* Checks if the input has a trailing slash.
*
* @group utils
*/
declare function hasTrailingSlash(input?: string, respectQueryAndFragment?: boolean): boolean;
/**
* Removes the trailing slash from the URL or pathname.
*
* If second argument is `true`, it will only remove the trailing slash if it's not part of the query or fragment with cost of more expensive operations.
*
* @example
*
* ```js
* withoutTrailingSlash("/foo/"); // "/foo"
*
* withoutTrailingSlash("/path/?query=true", true); // "/path?query=true"
* ```
*
* @group utils
*/
declare function withoutTrailingSlash(input?: string, respectQueryAndFragment?: boolean): string;
/**
* Ensures the URL ends with a trailing slash.
*
* If second argument is `true`, it will only add the trailing slash if it's not part of the query or fragment with cost of more expensive operation.
*
* @example
*
* ```js
* withTrailingSlash("/foo"); // "/foo/"
*
* withTrailingSlash("/path?query=true", true); // "/path/?query=true"
* ```
*
* @group utils
*/
declare function withTrailingSlash(input?: string, respectQueryAndFragment?: boolean): string;
/**
* Checks if the input has a leading slash (e.g. `/foo`).
*
* @group utils
*/
declare function hasLeadingSlash(input?: string): boolean;
/**
* Removes leading slash from the URL or pathname.
*
* @group utils
*/
declare function withoutLeadingSlash(input?: string): string;
/**
* Ensures the URL or pathname has a leading slash.
*
* @group utils
*/
declare function withLeadingSlash(input?: string): string;
/**
* Removes double slashes from the URL.
*
* @example
*
* ```js
* cleanDoubleSlashes("//foo//bar//"); // "/foo/bar/"
*
* cleanDoubleSlashes("http://example.com/analyze//http://localhost:3000//");
* // Returns "http://example.com/analyze/http://localhost:3000/"
* ```
*
* @group utils
*/
declare function cleanDoubleSlashes(input?: string): string;
/**
* Ensures the URL or pathname starts with base.
*
* If input already starts with base, it will not be added again.
*
* @group utils
*/
declare function withBase(input: string, base: string): string;
/**
* Removes the base from the URL or pathname.
*
* If input does not start with base, it will not be removed.
*
* @group utils
*/
declare function withoutBase(input: string, base: string): string;
/**
* Add/Replace the query section of the URL.
*
* @example
*
* ```js
* withQuery("/foo?page=a", { token: "secret" }); // "/foo?page=a&token=secret"
* ```
*
* @group utils
*/
declare function withQuery(input: string, query: QueryObject): string;
/**
* Removes the query section of the URL.
*
* @example
*
* ```js
* filterQuery("/foo?bar=1&baz=2", (key) => key !== "bar"); // "/foo?baz=2"
* ```
*
* @group utils
*/
declare function filterQuery(input: string, predicate: (key: string, value: string | string[]) => boolean): string;
/**
* Parses and decodes the query object of an input URL into an object.
*
* @example
*
* ```js
* getQuery("http://foo.com/foo?test=123&unicode=%E5%A5%BD");
* // { test: "123", unicode: "好" }
* ```
* @group utils
*/
declare function getQuery<T extends ParsedQuery = ParsedQuery>(input: string): T;
/**
* Checks if the input URL is empty or `/`.
*
* @group utils
*/
declare function isEmptyURL(url: string): boolean;
/**
* Checks if the input URL is neither empty nor `/`.
*
* @group utils
*/
declare function isNonEmptyURL(url: string): boolean;
/**
* Joins multiple URL segments into a single URL.
*
* @example
*
* ```js
* joinURL("a", "/b", "/c"); // "a/b/c"
* ```
*
* @group utils
*/
declare function joinURL(base: string, ...input: string[]): string;
/**
* Joins multiple URL segments into a single URL and also handles relative paths with `./` and `../`.
*
* @example
*
* ```js
* joinRelativeURL("/a", "../b", "./c"); // "/b/c"
* ```
*
* @group utils
*/
declare function joinRelativeURL(..._input: string[]): string;
/**
* Adds or replaces the URL protocol to `http://`.
*
* @example
*
* ```js
* withHttp("https://example.com"); // http://example.com
* ```
*
* @group utils
*/
declare function withHttp(input: string): string;
/**
* Adds or replaces the URL protocol to `https://`.
*
* @example
*
* ```js
* withHttps("http://example.com"); // https://example.com
* ```
*
* @group utils
*/
declare function withHttps(input: string): string;
/**
* Removes the protocol from the input.
*
* @example
* ```js
* withoutProtocol("http://example.com"); // "example.com"
* ```
*/
declare function withoutProtocol(input: string): string;
/**
* Adds or replaces protocol of the input URL.
*
* @example
* ```js
* withProtocol("http://example.com", "ftp://"); // "ftp://example.com"
* ```
*
* @group utils
*/
declare function withProtocol(input: string, protocol: string): string;
/**
* Normalizes the input URL:
*
* - Ensures the URL is properly encoded
* - Ensures pathname starts with a slash
* - Preserves protocol/host if provided
*
* @example
*
* ```js
* normalizeURL("test?query=123 123#hash, test");
* // Returns "test?query=123%20123#hash,%20test"
*
* normalizeURL("http://localhost:3000");
* // Returns "http://localhost:3000"
* ```
*
* @group utils
*/
declare function normalizeURL(input: string): string;
/**
* Resolves multiple URL segments into a single URL.
*
* @example
*
* ```js
* resolveURL("http://foo.com/foo?test=123#token", "bar", "baz");
* // Returns "http://foo.com/foo/bar/baz?test=123#token"
* ```
*
* @group utils
*/
declare function resolveURL(base?: string, ...inputs: string[]): string;
/**
* Check if two paths are equal or not. Trailing slash and encoding are normalized before comparison.
*
* @example
* ```js
* isSamePath("/foo", "/foo/"); // true
* ```
*
* @group utils
*/
declare function isSamePath(p1: string, p2: string): boolean;
interface CompareURLOptions {
trailingSlash?: boolean;
leadingSlash?: boolean;
encoding?: boolean;
}
/**
* Checks if two paths are equal regardless of encoding, trailing slash, and leading slash differences.
*
* You can make slash check strict by setting `{ trailingSlash: true, leadingSlash: true }` as options.
*
* You can make encoding check strict by setting `{ encoding: true }` as options.
*
* @example
*
* ```js
* isEqual("/foo", "foo"); // true
* isEqual("foo/", "foo"); // true
* isEqual("/foo bar", "/foo%20bar"); // true
*
* // Strict compare
* isEqual("/foo", "foo", { leadingSlash: true }); // false
* isEqual("foo/", "foo", { trailingSlash: true }); // false
* isEqual("/foo bar", "/foo%20bar", { encoding: true }); // false
* ```
*
* @group utils
*/
declare function isEqual(a: string, b: string, options?: CompareURLOptions): boolean;
/**
* Adds or replaces the fragment section of the URL.
*
* @example
*
* ```js
* withFragment("/foo", "bar"); // "/foo#bar"
* withFragment("/foo#bar", "baz"); // "/foo#baz"
* withFragment("/foo#bar", ""); // "/foo"
* ```
*
* @group utils
*/
declare function withFragment(input: string, hash: string): string;
/**
* Removes the fragment section from the URL.
*
* @example
*
* ```js
* withoutFragment("http://example.com/foo?q=123#bar")
* // Returns "http://example.com/foo?q=123"
* ```
*
* @group utils
*/
declare function withoutFragment(input: string): string;
/**
* Removes the host from the URL while preserving everything else.
*
* @example
* ```js
* withoutHost("http://example.com/foo?q=123#bar")
* // Returns "/foo?q=123#bar"
* ```
*
* @group utils
*/
declare function withoutHost(input: string): string;
export { $URL, cleanDoubleSlashes, createURL, decode, decodePath, decodeQueryKey, decodeQueryValue, encode, encodeHash, encodeHost, encodeParam, encodePath, encodeQueryItem, encodeQueryKey, encodeQueryValue, filterQuery, getQuery, hasLeadingSlash, hasProtocol, hasTrailingSlash, isEmptyURL, isEqual, isNonEmptyURL, isRelative, isSamePath, isScriptProtocol, joinRelativeURL, joinURL, normalizeURL, parseAuth, parseFilename, parseHost, parsePath, parseQuery, parseURL, resolveURL, stringifyParsedURL, stringifyQuery, withBase, withFragment, withHttp, withHttps, withLeadingSlash, withProtocol, withQuery, withTrailingSlash, withoutBase, withoutFragment, withoutHost, withoutLeadingSlash, withoutProtocol, withoutTrailingSlash };
export type { HasProtocolOptions, ParsedAuth, ParsedHost, ParsedQuery, ParsedURL, QueryObject, QueryValue };

638
node_modules/ufo/dist/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,638 @@
const n = /[^\0-\x7E]/;
const t = /[\x2E\u3002\uFF0E\uFF61]/g;
const o = {
overflow: "Overflow Error",
"not-basic": "Illegal Input",
"invalid-input": "Invalid Input"
};
const e = Math.floor;
const r = String.fromCharCode;
function s(n2) {
throw new RangeError(o[n2]);
}
const c = function(n2, t2) {
return n2 + 22 + 75 * (n2 < 26) - ((t2 != 0) << 5);
};
const u = function(n2, t2, o2) {
let r2 = 0;
for (n2 = o2 ? e(n2 / 700) : n2 >> 1, n2 += e(n2 / t2); n2 > 455; r2 += 36) {
n2 = e(n2 / 35);
}
return e(r2 + 36 * n2 / (n2 + 38));
};
function toASCII(o2) {
return function(n2, o3) {
const e2 = n2.split("@");
let r2 = "";
e2.length > 1 && (r2 = e2[0] + "@", n2 = e2[1]);
const s2 = function(n3, t2) {
const o4 = [];
let e3 = n3.length;
for (; e3--; ) {
o4[e3] = t2(n3[e3]);
}
return o4;
}((n2 = n2.replace(t, ".")).split("."), o3).join(".");
return r2 + s2;
}(o2, function(t2) {
return n.test(t2) ? "xn--" + function(n2) {
const t3 = [];
const o3 = (n2 = function(n3) {
const t4 = [];
let o4 = 0;
const e2 = n3.length;
for (; o4 < e2; ) {
const r2 = n3.charCodeAt(o4++);
if (r2 >= 55296 && r2 <= 56319 && o4 < e2) {
const e3 = n3.charCodeAt(o4++);
(64512 & e3) == 56320 ? t4.push(((1023 & r2) << 10) + (1023 & e3) + 65536) : (t4.push(r2), o4--);
} else {
t4.push(r2);
}
}
return t4;
}(n2)).length;
let f = 128;
let i = 0;
let l = 72;
for (const o4 of n2) {
o4 < 128 && t3.push(r(o4));
}
const h = t3.length;
let p = h;
for (h && t3.push("-"); p < o3; ) {
let o4 = 2147483647;
for (const t4 of n2) {
t4 >= f && t4 < o4 && (o4 = t4);
}
const a = p + 1;
o4 - f > e((2147483647 - i) / a) && s("overflow"), i += (o4 - f) * a, f = o4;
for (const o5 of n2) {
if (o5 < f && ++i > 2147483647 && s("overflow"), o5 == f) {
let n3 = i;
for (let o6 = 36; ; o6 += 36) {
const s2 = o6 <= l ? 1 : o6 >= l + 26 ? 26 : o6 - l;
if (n3 < s2) {
break;
}
const u2 = n3 - s2;
const f2 = 36 - s2;
t3.push(r(c(s2 + u2 % f2, 0))), n3 = e(u2 / f2);
}
t3.push(r(c(n3, 0))), l = u(i, a, p == h), i = 0, ++p;
}
}
++i, ++f;
}
return t3.join("");
}(t2) : t2;
});
}
const HASH_RE = /#/g;
const AMPERSAND_RE = /&/g;
const SLASH_RE = /\//g;
const EQUAL_RE = /=/g;
const IM_RE = /\?/g;
const PLUS_RE = /\+/g;
const ENC_CARET_RE = /%5e/gi;
const ENC_BACKTICK_RE = /%60/gi;
const ENC_CURLY_OPEN_RE = /%7b/gi;
const ENC_PIPE_RE = /%7c/gi;
const ENC_CURLY_CLOSE_RE = /%7d/gi;
const ENC_SPACE_RE = /%20/gi;
const ENC_SLASH_RE = /%2f/gi;
const ENC_ENC_SLASH_RE = /%252f/gi;
function encode(text) {
return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
}
function encodeHash(text) {
return encode(text).replace(ENC_CURLY_OPEN_RE, "{").replace(ENC_CURLY_CLOSE_RE, "}").replace(ENC_CARET_RE, "^");
}
function encodeQueryValue(input) {
return encode(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
}
function encodeQueryKey(text) {
return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
}
function encodePath(text) {
return encode(text).replace(HASH_RE, "%23").replace(IM_RE, "%3F").replace(ENC_ENC_SLASH_RE, "%2F").replace(AMPERSAND_RE, "%26").replace(PLUS_RE, "%2B");
}
function encodeParam(text) {
return encodePath(text).replace(SLASH_RE, "%2F");
}
function decode(text = "") {
try {
return decodeURIComponent("" + text);
} catch {
return "" + text;
}
}
function decodePath(text) {
return decode(text.replace(ENC_SLASH_RE, "%252F"));
}
function decodeQueryKey(text) {
return decode(text.replace(PLUS_RE, " "));
}
function decodeQueryValue(text) {
return decode(text.replace(PLUS_RE, " "));
}
function encodeHost(name = "") {
return toASCII(name);
}
function parseQuery(parametersString = "") {
const object = /* @__PURE__ */ Object.create(null);
if (parametersString[0] === "?") {
parametersString = parametersString.slice(1);
}
for (const parameter of parametersString.split("&")) {
const s = parameter.match(/([^=]+)=?(.*)/) || [];
if (s.length < 2) {
continue;
}
const key = decodeQueryKey(s[1]);
if (key === "__proto__" || key === "constructor") {
continue;
}
const value = decodeQueryValue(s[2] || "");
if (object[key] === void 0) {
object[key] = value;
} else if (Array.isArray(object[key])) {
object[key].push(value);
} else {
object[key] = [object[key], value];
}
}
return object;
}
function encodeQueryItem(key, value) {
if (typeof value === "number" || typeof value === "boolean") {
value = String(value);
}
if (!value) {
return encodeQueryKey(key);
}
if (Array.isArray(value)) {
return value.map(
(_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`
).join("&");
}
return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
}
function stringifyQuery(query) {
return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join("&");
}
const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/;
const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/;
const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
const PROTOCOL_SCRIPT_RE = /^[\s\0]*(blob|data|javascript|vbscript):$/i;
const TRAILING_SLASH_RE = /\/$|\/\?|\/#/;
const JOIN_LEADING_SLASH_RE = /^\.?\//;
function isRelative(inputString) {
return ["./", "../"].some((string_) => inputString.startsWith(string_));
}
function hasProtocol(inputString, opts = {}) {
if (typeof opts === "boolean") {
opts = { acceptRelative: opts };
}
if (opts.strict) {
return PROTOCOL_STRICT_REGEX.test(inputString);
}
return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
}
function isScriptProtocol(protocol) {
return !!protocol && PROTOCOL_SCRIPT_RE.test(protocol);
}
function hasTrailingSlash(input = "", respectQueryAndFragment) {
if (!respectQueryAndFragment) {
return input.endsWith("/");
}
return TRAILING_SLASH_RE.test(input);
}
function withoutTrailingSlash(input = "", respectQueryAndFragment) {
if (!respectQueryAndFragment) {
return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
}
if (!hasTrailingSlash(input, true)) {
return input || "/";
}
let path = input;
let fragment = "";
const fragmentIndex = input.indexOf("#");
if (fragmentIndex !== -1) {
path = input.slice(0, fragmentIndex);
fragment = input.slice(fragmentIndex);
}
const [s0, ...s] = path.split("?");
const cleanPath = s0.endsWith("/") ? s0.slice(0, -1) : s0;
return (cleanPath || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
}
function withTrailingSlash(input = "", respectQueryAndFragment) {
if (!respectQueryAndFragment) {
return input.endsWith("/") ? input : input + "/";
}
if (hasTrailingSlash(input, true)) {
return input || "/";
}
let path = input;
let fragment = "";
const fragmentIndex = input.indexOf("#");
if (fragmentIndex !== -1) {
path = input.slice(0, fragmentIndex);
fragment = input.slice(fragmentIndex);
if (!path) {
return fragment;
}
}
const [s0, ...s] = path.split("?");
return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
}
function hasLeadingSlash(input = "") {
return input.startsWith("/");
}
function withoutLeadingSlash(input = "") {
return (hasLeadingSlash(input) ? input.slice(1) : input) || "/";
}
function withLeadingSlash(input = "") {
return hasLeadingSlash(input) ? input : "/" + input;
}
function cleanDoubleSlashes(input = "") {
return input.split("://").map((string_) => string_.replace(/\/{2,}/g, "/")).join("://");
}
function withBase(input, base) {
if (isEmptyURL(base) || hasProtocol(input)) {
return input;
}
const _base = withoutTrailingSlash(base);
if (input.startsWith(_base)) {
return input;
}
return joinURL(_base, input);
}
function withoutBase(input, base) {
if (isEmptyURL(base)) {
return input;
}
const _base = withoutTrailingSlash(base);
if (!input.startsWith(_base)) {
return input;
}
const trimmed = input.slice(_base.length);
return trimmed[0] === "/" ? trimmed : "/" + trimmed;
}
function withQuery(input, query) {
const parsed = parseURL(input);
const mergedQuery = { ...parseQuery(parsed.search), ...query };
parsed.search = stringifyQuery(mergedQuery);
return stringifyParsedURL(parsed);
}
function filterQuery(input, predicate) {
if (!input.includes("?")) {
return input;
}
const parsed = parseURL(input);
const query = parseQuery(parsed.search);
const filteredQuery = Object.fromEntries(
Object.entries(query).filter(([key, value]) => predicate(key, value))
);
parsed.search = stringifyQuery(filteredQuery);
return stringifyParsedURL(parsed);
}
function getQuery(input) {
return parseQuery(parseURL(input).search);
}
function isEmptyURL(url) {
return !url || url === "/";
}
function isNonEmptyURL(url) {
return url && url !== "/";
}
function joinURL(base, ...input) {
let url = base || "";
for (const segment of input.filter((url2) => isNonEmptyURL(url2))) {
if (url) {
const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
url = withTrailingSlash(url) + _segment;
} else {
url = segment;
}
}
return url;
}
function joinRelativeURL(..._input) {
const JOIN_SEGMENT_SPLIT_RE = /\/(?!\/)/;
const input = _input.filter(Boolean);
const segments = [];
let segmentsDepth = 0;
for (const i of input) {
if (!i || i === "/") {
continue;
}
for (const [sindex, s] of i.split(JOIN_SEGMENT_SPLIT_RE).entries()) {
if (!s || s === ".") {
continue;
}
if (s === "..") {
if (segments.length === 1 && hasProtocol(segments[0])) {
continue;
}
segments.pop();
segmentsDepth--;
continue;
}
if (sindex === 1 && segments[segments.length - 1]?.endsWith(":/")) {
segments[segments.length - 1] += "/" + s;
continue;
}
segments.push(s);
segmentsDepth++;
}
}
let url = segments.join("/");
if (segmentsDepth >= 0) {
if (input[0]?.startsWith("/") && !url.startsWith("/")) {
url = "/" + url;
} else if (input[0]?.startsWith("./") && !url.startsWith("./")) {
url = "./" + url;
}
} else {
url = "../".repeat(-1 * segmentsDepth) + url;
}
if (input[input.length - 1]?.endsWith("/") && !url.endsWith("/")) {
url += "/";
}
return url;
}
function withHttp(input) {
return withProtocol(input, "http://");
}
function withHttps(input) {
return withProtocol(input, "https://");
}
function withoutProtocol(input) {
return withProtocol(input, "");
}
function withProtocol(input, protocol) {
let match = input.match(PROTOCOL_REGEX);
if (!match) {
match = input.match(/^\/{2,}/);
}
if (!match) {
return protocol + input;
}
return protocol + input.slice(match[0].length);
}
function normalizeURL(input) {
const parsed = parseURL(input);
parsed.pathname = encodePath(decodePath(parsed.pathname));
parsed.hash = encodeHash(decode(parsed.hash));
parsed.host = encodeHost(decode(parsed.host));
parsed.search = stringifyQuery(parseQuery(parsed.search));
return stringifyParsedURL(parsed);
}
function resolveURL(base = "", ...inputs) {
if (typeof base !== "string") {
throw new TypeError(
`URL input should be string received ${typeof base} (${base})`
);
}
const filteredInputs = inputs.filter((input) => isNonEmptyURL(input));
if (filteredInputs.length === 0) {
return base;
}
const url = parseURL(base);
for (const inputSegment of filteredInputs) {
const urlSegment = parseURL(inputSegment);
if (urlSegment.pathname) {
url.pathname = withTrailingSlash(url.pathname) + withoutLeadingSlash(urlSegment.pathname);
}
if (urlSegment.hash && urlSegment.hash !== "#") {
url.hash = urlSegment.hash;
}
if (urlSegment.search && urlSegment.search !== "?") {
if (url.search && url.search !== "?") {
const queryString = stringifyQuery({
...parseQuery(url.search),
...parseQuery(urlSegment.search)
});
url.search = queryString.length > 0 ? "?" + queryString : "";
} else {
url.search = urlSegment.search;
}
}
}
return stringifyParsedURL(url);
}
function isSamePath(p1, p2) {
return decode(withoutTrailingSlash(p1)) === decode(withoutTrailingSlash(p2));
}
function isEqual(a, b, options = {}) {
if (!options.trailingSlash) {
a = withTrailingSlash(a);
b = withTrailingSlash(b);
}
if (!options.leadingSlash) {
a = withLeadingSlash(a);
b = withLeadingSlash(b);
}
if (!options.encoding) {
a = decode(a);
b = decode(b);
}
return a === b;
}
function withFragment(input, hash) {
if (!hash || hash === "#") {
return input;
}
const parsed = parseURL(input);
parsed.hash = hash === "" ? "" : "#" + encodeHash(hash);
return stringifyParsedURL(parsed);
}
function withoutFragment(input) {
return stringifyParsedURL({ ...parseURL(input), hash: "" });
}
function withoutHost(input) {
const parsed = parseURL(input);
return (parsed.pathname || "/") + parsed.search + parsed.hash;
}
const protocolRelative = Symbol.for("ufo:protocolRelative");
function parseURL(input = "", defaultProto) {
const _specialProtoMatch = input.match(
/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i
);
if (_specialProtoMatch) {
const [, _proto, _pathname = ""] = _specialProtoMatch;
return {
protocol: _proto.toLowerCase(),
pathname: _pathname,
href: _proto + _pathname,
auth: "",
host: "",
search: "",
hash: ""
};
}
if (!hasProtocol(input, { acceptRelative: true })) {
return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
}
const [, protocol = "", auth, hostAndPath = ""] = input.replace(/\\/g, "/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/) || [];
let [, host = "", path = ""] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];
if (protocol === "file:") {
path = path.replace(/\/(?=[A-Za-z]:)/, "");
}
const { pathname, search, hash } = parsePath(path);
return {
protocol: protocol.toLowerCase(),
auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
host,
pathname,
search,
hash,
[protocolRelative]: !protocol
};
}
function parsePath(input = "") {
const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
return {
pathname,
search,
hash
};
}
function parseAuth(input = "") {
const [username, password] = input.split(":");
return {
username: decode(username),
password: decode(password)
};
}
function parseHost(input = "") {
const [hostname, port] = (input.match(/([^/:]*):?(\d+)?/) || []).splice(1);
return {
hostname: decode(hostname),
port
};
}
function stringifyParsedURL(parsed) {
const pathname = parsed.pathname || "";
const search = parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "";
const hash = parsed.hash || "";
const auth = parsed.auth ? parsed.auth + "@" : "";
const host = parsed.host || "";
const proto = parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "";
return proto + auth + host + pathname + search + hash;
}
const FILENAME_STRICT_REGEX = /\/([^/]+\.[^/]+)$/;
const FILENAME_REGEX = /\/([^/]+)$/;
function parseFilename(input = "", opts) {
const { pathname } = parseURL(input);
const matches = opts?.strict ? pathname.match(FILENAME_STRICT_REGEX) : pathname.match(FILENAME_REGEX);
return matches ? matches[1] : void 0;
}
class $URL {
protocol;
host;
auth;
pathname;
query = {};
hash;
constructor(input = "") {
if (typeof input !== "string") {
throw new TypeError(
`URL input should be string received ${typeof input} (${input})`
);
}
const parsed = parseURL(input);
this.protocol = decode(parsed.protocol);
this.host = decode(parsed.host);
this.auth = decode(parsed.auth);
this.pathname = decodePath(parsed.pathname);
this.query = parseQuery(parsed.search);
this.hash = decode(parsed.hash);
}
get hostname() {
return parseHost(this.host).hostname;
}
get port() {
return parseHost(this.host).port || "";
}
get username() {
return parseAuth(this.auth).username;
}
get password() {
return parseAuth(this.auth).password || "";
}
get hasProtocol() {
return this.protocol.length;
}
get isAbsolute() {
return this.hasProtocol || this.pathname[0] === "/";
}
get search() {
const q = stringifyQuery(this.query);
return q.length > 0 ? "?" + q : "";
}
get searchParams() {
const p = new URLSearchParams();
for (const name in this.query) {
const value = this.query[name];
if (Array.isArray(value)) {
for (const v of value) {
p.append(name, v);
}
} else {
p.append(
name,
typeof value === "string" ? value : JSON.stringify(value)
);
}
}
return p;
}
get origin() {
return (this.protocol ? this.protocol + "//" : "") + encodeHost(this.host);
}
get fullpath() {
return encodePath(this.pathname) + this.search + encodeHash(this.hash);
}
get encodedAuth() {
if (!this.auth) {
return "";
}
const { username, password } = parseAuth(this.auth);
return encodeURIComponent(username) + (password ? ":" + encodeURIComponent(password) : "");
}
get href() {
const auth = this.encodedAuth;
const originWithAuth = (this.protocol ? this.protocol + "//" : "") + (auth ? auth + "@" : "") + encodeHost(this.host);
return this.hasProtocol && this.isAbsolute ? originWithAuth + this.fullpath : this.fullpath;
}
append(url) {
if (url.hasProtocol) {
throw new Error("Cannot append a URL with protocol");
}
Object.assign(this.query, url.query);
if (url.pathname) {
this.pathname = withTrailingSlash(this.pathname) + withoutLeadingSlash(url.pathname);
}
if (url.hash) {
this.hash = url.hash;
}
}
toJSON() {
return this.href;
}
toString() {
return this.href;
}
}
function createURL(input) {
return new $URL(input);
}
export { $URL, cleanDoubleSlashes, createURL, decode, decodePath, decodeQueryKey, decodeQueryValue, encode, encodeHash, encodeHost, encodeParam, encodePath, encodeQueryItem, encodeQueryKey, encodeQueryValue, filterQuery, getQuery, hasLeadingSlash, hasProtocol, hasTrailingSlash, isEmptyURL, isEqual, isNonEmptyURL, isRelative, isSamePath, isScriptProtocol, joinRelativeURL, joinURL, normalizeURL, parseAuth, parseFilename, parseHost, parsePath, parseQuery, parseURL, resolveURL, stringifyParsedURL, stringifyQuery, withBase, withFragment, withHttp, withHttps, withLeadingSlash, withProtocol, withQuery, withTrailingSlash, withoutBase, withoutFragment, withoutHost, withoutLeadingSlash, withoutProtocol, withoutTrailingSlash };

47
node_modules/ufo/package.json generated vendored Normal file
View File

@@ -0,0 +1,47 @@
{
"name": "ufo",
"version": "1.6.1",
"description": "URL utils for humans",
"repository": "unjs/ufo",
"license": "MIT",
"sideEffects": false,
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.cjs",
"import": "./dist/index.mjs"
},
"./*": "./*"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "automd && unbuild",
"automd": "automd",
"dev": "vitest",
"lint": "eslint . && prettier -c src test",
"lint:fix": "eslint --fix . && prettier -w src test",
"prepack": "pnpm build",
"release": "pnpm test && changelogen --release && npm publish && git push --follow-tags",
"test": "pnpm lint && vitest run --typecheck"
},
"devDependencies": {
"@types/node": "^22.14.0",
"@vitest/coverage-v8": "^3.1.1",
"automd": "^0.4.0",
"changelogen": "^0.6.1",
"eslint": "^9.24.0",
"eslint-config-unjs": "^0.4.2",
"jiti": "^2.4.2",
"prettier": "^3.5.3",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"untyped": "^2.0.0",
"vitest": "^3.1.1"
},
"packageManager": "pnpm@10.7.1"
}