Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); //#region src/utils/url.ts const splitPath = (path) => { const paths = path.split("/"); if (paths[0] === "") paths.shift(); return paths; }; const splitRoutingPath = (routePath) => { const { groups, path } = extractGroupsFromPath(routePath); const paths = splitPath(path); return replaceGroupMarks(paths, groups); }; const extractGroupsFromPath = (path) => { const groups = []; path = path.replace(/\{[^}]+\}/g, (match, index) => { const mark = `@${index}`; groups.push([mark, match]); return mark; }); return { groups, path }; }; const replaceGroupMarks = (paths, groups) => { for (let i = groups.length - 1; i >= 0; i--) { const [mark] = groups[i]; for (let j = paths.length - 1; j >= 0; j--) if (paths[j].includes(mark)) { paths[j] = paths[j].replace(mark, groups[i][1]); break; } } return paths; }; const patternCache = {}; const getPattern = (label, next) => { if (label === "*") return "*"; const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/); if (match) { const cacheKey = `${label}#${next}`; if (!patternCache[cacheKey]) { if (match[2]) patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [ cacheKey, match[1], new RegExp(`^${match[2]}(?=/${next})`) ] : [ label, match[1], new RegExp(`^${match[2]}$`) ]; else patternCache[cacheKey] = [ label, match[1], true ]; } return patternCache[cacheKey]; } return null; }; const tryDecode = (str, decoder) => { try { return decoder(str); } catch { return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => { try { return decoder(match); } catch { return match; } }); } }; /** * Try to apply decodeURI() to given string. * If it fails, skip invalid percent encoding or invalid UTF-8 sequences, and apply decodeURI() to the rest as much as possible. * @param str The string to decode. * @returns The decoded string that sometimes contains undecodable percent encoding. * @example * tryDecodeURI('Hello%20World') // 'Hello World' * tryDecodeURI('Hello%20World/%A4%A2') // 'Hello World/%A4%A2' */ const tryDecodeURI = (str) => tryDecode(str, decodeURI); const getPath = (request) => { const url = request.url; const start = url.indexOf("/", url.indexOf(":") + 4); let i = start; for (; i < url.length; i++) { const charCode = url.charCodeAt(i); if (charCode === 37) { const queryIndex = url.indexOf("?", i); const hashIndex = url.indexOf("#", i); const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex); const path = url.slice(start, end); return tryDecodeURI(path.includes("%25") ? path.replace(/%25/g, "%2525") : path); } else if (charCode === 63 || charCode === 35) break; } return url.slice(start, i); }; /** * @deprecated * Use the `URL` API instead. */ const getQueryStrings = (url) => { const queryIndex = url.indexOf("?", 8); if (queryIndex === -1) return ""; const hashIndex = url.indexOf("#", 8); return hashIndex === -1 ? url.slice(queryIndex) : queryIndex < hashIndex ? url.slice(queryIndex, hashIndex) : ""; }; const getPathNoStrict = (request) => { const result = getPath(request); return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result; }; /** * Merge paths. * @param {string[]} ...paths - The paths to merge. * @returns {string} The merged path. * @example * mergePath('/api', '/users') // '/api/users' * mergePath('/api/', '/users') // '/api/users' * mergePath('/api', '/') // '/api' * mergePath('/api/', '/') // '/api/' */ const mergePath = (base, sub, ...rest) => { if (rest.length) sub = mergePath(sub, ...rest); return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`; }; const checkOptionalParameter = (path) => { if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) return null; const segments = path.split("/"); const results = []; let basePath = ""; segments.forEach((segment) => { if (segment !== "" && !/\:/.test(segment)) basePath += "/" + segment; else if (/\:/.test(segment)) { if (segment.charCodeAt(segment.length - 1) === 63) { if (results.length === 0 && basePath === "") results.push("/"); else results.push(basePath); const optionalSegment = segment.slice(0, -1); basePath += "/" + optionalSegment; results.push(basePath); } else basePath += "/" + segment; } }); return results.filter((v, i, a) => a.indexOf(v) === i); }; const tryDecodeURIComponent = (str) => str.indexOf("%") !== -1 ? tryDecode(str, decodeURIComponent_) : str; const _decodeURI = (value) => { if (value.indexOf("+") !== -1) value = value.replace(/\+/g, " "); return tryDecodeURIComponent(value); }; const _getQueryParam = (url, key, multiple) => { const hashIndex = url.indexOf("#", 8); if (hashIndex !== -1) url = url.slice(0, hashIndex); let encoded; if (!multiple && key && key.indexOf("%") === -1 && key.indexOf("+") === -1) { let keyIndex = url.indexOf("?", 8); if (keyIndex === -1) return; if (!url.startsWith(key, keyIndex + 1)) keyIndex = url.indexOf(`&${key}`, keyIndex + 1); while (keyIndex !== -1) { const trailingKeyCode = url.charCodeAt(keyIndex + key.length + 1); if (trailingKeyCode === 61) { const valueIndex = keyIndex + key.length + 2; const endIndex = url.indexOf("&", valueIndex); return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex)); } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) return ""; keyIndex = url.indexOf(`&${key}`, keyIndex + 1); } encoded = /[%+]/.test(url); if (!encoded) return; } const results = Object.create(null); encoded ??= /[%+]/.test(url); let keyIndex = url.indexOf("?", 8); while (keyIndex !== -1) { const nextKeyIndex = url.indexOf("&", keyIndex + 1); let valueIndex = url.indexOf("=", keyIndex); if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) valueIndex = -1; let name = url.slice(keyIndex + 1, valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex); if (encoded) name = _decodeURI(name); keyIndex = nextKeyIndex; if (name === "") continue; let value; if (valueIndex === -1) value = ""; else { value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex); if (encoded) value = _decodeURI(value); } if (multiple) { if (!(results[name] && Array.isArray(results[name]))) results[name] = []; results[name].push(value); } else results[name] ??= value; } return key ? results[key] : results; }; const getQueryParam = _getQueryParam; const getQueryParams = (url, key) => { return _getQueryParam(url, key, true); }; const decodeURIComponent_ = decodeURIComponent; //#endregion exports.checkOptionalParameter = checkOptionalParameter; exports.decodeURIComponent_ = decodeURIComponent_; exports.getPath = getPath; exports.getPathNoStrict = getPathNoStrict; exports.getPattern = getPattern; exports.getQueryParam = getQueryParam; exports.getQueryParams = getQueryParams; exports.getQueryStrings = getQueryStrings; exports.mergePath = mergePath; exports.splitPath = splitPath; exports.splitRoutingPath = splitRoutingPath; exports.tryDecode = tryDecode; exports.tryDecodeURI = tryDecodeURI; exports.tryDecodeURIComponent = tryDecodeURIComponent;