mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-07 14:08:38 +00:00
* fix: Issue with Parameters Passed in the URL(#2124) The '=' should be allowed within query parameter value. While first equals sign separates parameter name from its value, any subsequent occurrences are valid and should not be discarded. The '#' in URL always indicates the start of URI Fragment component, and should not be treated as part of any parameter value. * chore: gracefully fail when URLSearchParams throws error --------- Co-authored-by: Anoop M D <anoop.md1421@gmail.com>
160 lines
3.4 KiB
JavaScript
160 lines
3.4 KiB
JavaScript
import isEmpty from 'lodash/isEmpty';
|
|
import trim from 'lodash/trim';
|
|
import each from 'lodash/each';
|
|
import filter from 'lodash/filter';
|
|
import find from 'lodash/find';
|
|
|
|
import brunoCommon from '@usebruno/common';
|
|
const { interpolate } = brunoCommon;
|
|
|
|
const hasLength = (str) => {
|
|
if (!str || !str.length) {
|
|
return false;
|
|
}
|
|
|
|
str = str.trim();
|
|
|
|
return str.length > 0;
|
|
};
|
|
|
|
export const parseQueryParams = (query) => {
|
|
try {
|
|
if (!query || !query.length) {
|
|
return [];
|
|
}
|
|
|
|
return Array.from(new URLSearchParams(query.split('#')[0]).entries())
|
|
.map(([name, value]) => ({ name, value }));
|
|
} catch (error) {
|
|
console.error('Error parsing query params:', error);
|
|
return [];
|
|
}
|
|
};
|
|
|
|
export const parsePathParams = (url) => {
|
|
let uri = url.slice();
|
|
|
|
if (!uri || !uri.length) {
|
|
return [];
|
|
}
|
|
|
|
if (!uri.startsWith('http://') && !uri.startsWith('https://')) {
|
|
uri = `http://${uri}`;
|
|
}
|
|
|
|
try {
|
|
uri = new URL(uri);
|
|
} catch (e) {
|
|
// URL is non-parsable, is it incomplete? Ignore.
|
|
return [];
|
|
}
|
|
|
|
let paths = uri.pathname.split('/');
|
|
|
|
paths = paths.reduce((acc, path) => {
|
|
if (path !== '' && path[0] === ':') {
|
|
let name = path.slice(1, path.length);
|
|
if (name) {
|
|
let isExist = find(acc, (path) => path.name === name);
|
|
if (!isExist) {
|
|
acc.push({ name: path.slice(1, path.length), value: '' });
|
|
}
|
|
}
|
|
}
|
|
return acc;
|
|
}, []);
|
|
|
|
return paths;
|
|
};
|
|
|
|
export const stringifyQueryParams = (params) => {
|
|
if (!params || isEmpty(params)) {
|
|
return '';
|
|
}
|
|
|
|
let queryString = [];
|
|
each(params, (p) => {
|
|
const hasEmptyName = isEmpty(trim(p.name));
|
|
const hasEmptyVal = isEmpty(trim(p.value));
|
|
|
|
// query param name must be present
|
|
if (!hasEmptyName) {
|
|
// if query param value is missing, push only <param-name>, else push <param-name: param-value>
|
|
queryString.push(hasEmptyVal ? p.name : `${p.name}=${p.value}`);
|
|
}
|
|
});
|
|
|
|
return queryString.join('&');
|
|
};
|
|
|
|
export const splitOnFirst = (str, char) => {
|
|
if (!str || !str.length) {
|
|
return [str];
|
|
}
|
|
|
|
let index = str.indexOf(char);
|
|
if (index === -1) {
|
|
return [str];
|
|
}
|
|
|
|
return [str.slice(0, index), str.slice(index + 1)];
|
|
};
|
|
|
|
export const isValidUrl = (url) => {
|
|
try {
|
|
new URL(url);
|
|
return true;
|
|
} catch (err) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
export const interpolateUrl = ({ url, envVars, runtimeVariables, processEnvVars }) => {
|
|
if (!url || !url.length || typeof url !== 'string') {
|
|
return;
|
|
}
|
|
|
|
return interpolate(url, {
|
|
...envVars,
|
|
...runtimeVariables,
|
|
process: {
|
|
env: {
|
|
...processEnvVars
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
export const interpolateUrlPathParams = (url, params) => {
|
|
const getInterpolatedBasePath = (pathname, params) => {
|
|
return pathname
|
|
.split('/')
|
|
.map((segment) => {
|
|
if (segment.startsWith(':')) {
|
|
const pathParamName = segment.slice(1);
|
|
const pathParam = params.find((p) => p?.name === pathParamName && p?.type === 'path');
|
|
return pathParam ? pathParam.value : segment;
|
|
}
|
|
return segment;
|
|
})
|
|
.join('/');
|
|
};
|
|
|
|
let uri;
|
|
|
|
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
|
url = `http://${url}`;
|
|
}
|
|
|
|
try {
|
|
uri = new URL(url);
|
|
} catch (error) {
|
|
// if the URL is invalid, return the URL as is
|
|
return url;
|
|
}
|
|
|
|
const basePath = getInterpolatedBasePath(uri.pathname, params);
|
|
|
|
return `${uri.origin}${basePath}${uri?.search || ''}`;
|
|
};
|