|
|
@@ -0,0 +1,219 @@
|
|
|
+// src/utils/url.ts
|
|
|
+var splitPath = (path) => {
|
|
|
+ const paths = path.split("/");
|
|
|
+ if (paths[0] === "") {
|
|
|
+ paths.shift();
|
|
|
+ }
|
|
|
+ return paths;
|
|
|
+};
|
|
|
+var splitRoutingPath = (routePath) => {
|
|
|
+ const { groups, path } = extractGroupsFromPath(routePath);
|
|
|
+ const paths = splitPath(path);
|
|
|
+ return replaceGroupMarks(paths, groups);
|
|
|
+};
|
|
|
+var extractGroupsFromPath = (path) => {
|
|
|
+ const groups = [];
|
|
|
+ path = path.replace(/\{[^}]+\}/g, (match, index) => {
|
|
|
+ const mark = `@${index}`;
|
|
|
+ groups.push([mark, match]);
|
|
|
+ return mark;
|
|
|
+ });
|
|
|
+ return { groups, path };
|
|
|
+};
|
|
|
+var 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;
|
|
|
+};
|
|
|
+var patternCache = {};
|
|
|
+var 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;
|
|
|
+};
|
|
|
+var 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;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+};
|
|
|
+var tryDecodeURI = (str) => tryDecode(str, decodeURI);
|
|
|
+var getPath = (request) => {
|
|
|
+ const url = request.url;
|
|
|
+ const start = url.indexOf(
|
|
|
+ "/",
|
|
|
+ url.charCodeAt(9) === 58 ? 13 : 8
|
|
|
+ );
|
|
|
+ let i = start;
|
|
|
+ for (; i < url.length; i++) {
|
|
|
+ const charCode = url.charCodeAt(i);
|
|
|
+ if (charCode === 37) {
|
|
|
+ const queryIndex = url.indexOf("?", i);
|
|
|
+ const path = url.slice(start, queryIndex === -1 ? void 0 : queryIndex);
|
|
|
+ return tryDecodeURI(path.includes("%25") ? path.replace(/%25/g, "%2525") : path);
|
|
|
+ } else if (charCode === 63) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return url.slice(start, i);
|
|
|
+};
|
|
|
+var getQueryStrings = (url) => {
|
|
|
+ const queryIndex = url.indexOf("?", 8);
|
|
|
+ return queryIndex === -1 ? "" : "?" + url.slice(queryIndex + 1);
|
|
|
+};
|
|
|
+var getPathNoStrict = (request) => {
|
|
|
+ const result = getPath(request);
|
|
|
+ return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
|
|
|
+};
|
|
|
+var 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}`}`;
|
|
|
+};
|
|
|
+var 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 (/\?/.test(segment)) {
|
|
|
+ if (results.length === 0 && basePath === "") {
|
|
|
+ results.push("/");
|
|
|
+ } else {
|
|
|
+ results.push(basePath);
|
|
|
+ }
|
|
|
+ const optionalSegment = segment.replace("?", "");
|
|
|
+ basePath += "/" + optionalSegment;
|
|
|
+ results.push(basePath);
|
|
|
+ } else {
|
|
|
+ basePath += "/" + segment;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return results.filter((v, i, a) => a.indexOf(v) === i);
|
|
|
+};
|
|
|
+var _decodeURI = (value) => {
|
|
|
+ if (!/[%+]/.test(value)) {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ if (value.indexOf("+") !== -1) {
|
|
|
+ value = value.replace(/\+/g, " ");
|
|
|
+ }
|
|
|
+ return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
|
|
|
+};
|
|
|
+var _getQueryParam = (url, key, multiple) => {
|
|
|
+ let encoded;
|
|
|
+ if (!multiple && key && !/[%+]/.test(key)) {
|
|
|
+ let keyIndex2 = url.indexOf(`?${key}`, 8);
|
|
|
+ if (keyIndex2 === -1) {
|
|
|
+ keyIndex2 = url.indexOf(`&${key}`, 8);
|
|
|
+ }
|
|
|
+ while (keyIndex2 !== -1) {
|
|
|
+ const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
|
|
|
+ if (trailingKeyCode === 61) {
|
|
|
+ const valueIndex = keyIndex2 + 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 "";
|
|
|
+ }
|
|
|
+ keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
|
|
|
+ }
|
|
|
+ encoded = /[%+]/.test(url);
|
|
|
+ if (!encoded) {
|
|
|
+ return void 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const results = {};
|
|
|
+ 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;
|
|
|
+};
|
|
|
+var getQueryParam = _getQueryParam;
|
|
|
+var getQueryParams = (url, key) => {
|
|
|
+ return _getQueryParam(url, key, true);
|
|
|
+};
|
|
|
+var decodeURIComponent_ = decodeURIComponent;
|
|
|
+export {
|
|
|
+ checkOptionalParameter,
|
|
|
+ decodeURIComponent_,
|
|
|
+ getPath,
|
|
|
+ getPathNoStrict,
|
|
|
+ getPattern,
|
|
|
+ getQueryParam,
|
|
|
+ getQueryParams,
|
|
|
+ getQueryStrings,
|
|
|
+ mergePath,
|
|
|
+ splitPath,
|
|
|
+ splitRoutingPath,
|
|
|
+ tryDecode
|
|
|
+};
|