diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index.js index 59cdd6281..dc8d525da 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index.js @@ -5,55 +5,7 @@ import StyledWrapper from './StyledWrapper'; import { isValidUrl } from 'utils/url'; import { find, get } from 'lodash'; import { findEnvironmentInCollection } from 'utils/collections'; - -// Todo: Fix this -// import { interpolate } from '@usebruno/common'; -import brunoCommon from '@usebruno/common'; -const { interpolate } = brunoCommon; - -const interpolateUrl = ({ url, envVars, collectionVariables, processEnvVars }) => { - if (!url || !url.length || typeof url !== 'string') { - return; - } - - return interpolate(url, { - ...envVars, - ...collectionVariables, - process: { - env: { - ...processEnvVars - } - } - }); -}; - -// interpolate URL paths -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; - try { - uri = new URL(url); - } catch (error) { - uri = new URL(`http://${url}`); - } - - const basePath = getInterpolatedBasePath(uri.pathname, params); - - return `${uri.origin}${basePath}${uri?.search || ''}`; -}; +import { interpolateUrl, interpolateUrlPathParams } from 'utils/url/index'; const languages = [ { @@ -117,7 +69,7 @@ const GenerateCodeItem = ({ collection, item, onClose }) => { const requestUrl = get(item, 'draft.request.url') !== undefined ? get(item, 'draft.request.url') : get(item, 'request.url'); - // interpolate the query params + // interpolate the url const interpolatedUrl = interpolateUrl({ url: requestUrl, envVars, diff --git a/packages/bruno-app/src/utils/url/index.js b/packages/bruno-app/src/utils/url/index.js index e1aea7316..0b9f2201a 100644 --- a/packages/bruno-app/src/utils/url/index.js +++ b/packages/bruno-app/src/utils/url/index.js @@ -4,6 +4,9 @@ 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; @@ -103,3 +106,52 @@ export const isValidUrl = (url) => { return false; } }; + +export const interpolateUrl = ({ url, envVars, collectionVariables, processEnvVars }) => { + if (!url || !url.length || typeof url !== 'string') { + return; + } + + return interpolate(url, { + ...envVars, + ...collectionVariables, + 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 || ''}`; +}; diff --git a/packages/bruno-app/src/utils/url/index.spec.js b/packages/bruno-app/src/utils/url/index.spec.js index 1f43affaf..2fd3f0815 100644 --- a/packages/bruno-app/src/utils/url/index.spec.js +++ b/packages/bruno-app/src/utils/url/index.spec.js @@ -1,4 +1,4 @@ -import { parseQueryParams, splitOnFirst, parsePathParams } from './index'; +import { parseQueryParams, splitOnFirst, parsePathParams, interpolateUrl, interpolateUrlPathParams } from './index'; describe('Url Utils - parseQueryParams', () => { it('should parse query - case 1', () => { @@ -122,3 +122,73 @@ describe('Url Utils - splitOnFirst', () => { expect(params).toEqual(['a=1', 'b=2']); }); }); + +describe('Url Utils - interpolateUrl, interpolateUrlPathParams', () => { + it('should interpolate url correctly', () => { + const url = '{{host}}/api/:id/path?foo={{foo}}&bar={{bar}}&baz={{process.env.baz}}'; + const expectedUrl = 'https://example.com/api/:id/path?foo=foo_value&bar=bar_value&baz=baz_value'; + + const envVars = { host: 'https://example.com', foo: 'foo_value' }; + const collectionVariables = { bar: 'bar_value' }; + const processEnvVars = { baz: 'baz_value' }; + + const result = interpolateUrl({ url, envVars, collectionVariables, processEnvVars }); + + expect(result).toEqual(expectedUrl); + }); + + it('should interpolate path params correctly', () => { + const url = 'https://example.com/api/:id/path'; + const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }]; + const expectedUrl = 'https://example.com/api/123/path'; + + const result = interpolateUrlPathParams(url, params); + + expect(result).toEqual(expectedUrl); + }); + + it('should interpolate url and path params correctly', () => { + const url = '{{host}}/api/:id/path?foo={{foo}}&bar={{bar}}&baz={{process.env.baz}}'; + const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }]; + const expectedUrl = 'https://example.com/api/123/path?foo=foo_value&bar=bar_value&baz=baz_value'; + + const envVars = { host: 'https://example.com', foo: 'foo_value' }; + const collectionVariables = { bar: 'bar_value' }; + const processEnvVars = { baz: 'baz_value' }; + + const intermediateResult = interpolateUrl({ url, envVars, collectionVariables, processEnvVars }); + const result = interpolateUrlPathParams(intermediateResult, params); + + expect(result).toEqual(expectedUrl); + }); + + it('should handle empty params', () => { + const url = 'https://example.com/api'; + const params = []; + const expectedUrl = 'https://example.com/api'; + + const result = interpolateUrlPathParams(url, params); + + expect(result).toEqual(expectedUrl); + }); + + it('should handle invalid URL, case 1', () => { + const url = 'example.com/api/:id'; + const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }]; + const expectedUrl = 'http://example.com/api/123'; + + const result = interpolateUrlPathParams(url, params); + + expect(result).toEqual(expectedUrl); + }); + + it('should handle invalid URL, case 2', () => { + const url = 'http://1.1.1.1:3000:id'; + const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }]; + const expectedUrl = 'http://1.1.1.1:3000:id'; + + const result = interpolateUrlPathParams(url, params); + + expect(result).toEqual(expectedUrl); + }); +}); diff --git a/packages/bruno-toml/tests/index.spec.js b/packages/bruno-toml/tests/index.spec.js index cad9d2e17..bcd00b77f 100644 --- a/packages/bruno-toml/tests/index.spec.js +++ b/packages/bruno-toml/tests/index.spec.js @@ -43,48 +43,3 @@ describe('bruno toml', () => { }); }); }); -describe('joinPathUrl', () => { - it('should join path and query params correctly', () => { - const url = 'https://example.com/api/:id'; - const params = [ - { name: 'id', type: 'path', enabled: true, value: '123' }, - { name: 'sort', type: 'query', enabled: true, value: 'asc' }, - { name: 'filter', type: 'query', enabled: true, value: 'active' } - ]; - const expectedUrl = 'https://example.com/api/123?sort=asc&filter=active'; - - const result = joinPathUrl(url, params); - - expect(result).toEqual(expectedUrl); - }); - - it('should handle empty path and query params', () => { - const url = 'https://example.com/api'; - const params = []; - const expectedUrl = 'https://example.com/api'; - - const result = joinPathUrl(url, params); - - expect(result).toEqual(expectedUrl); - }); - - it('should handle empty query params', () => { - const url = 'https://example.com/api/:id'; - const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }]; - const expectedUrl = 'https://example.com/api/123'; - - const result = joinPathUrl(url, params); - - expect(result).toEqual(expectedUrl); - }); - - it('should handle invalid URL', () => { - const url = 'example.com/api/:id'; - const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }]; - const expectedUrl = 'http://example.com/api/123'; - - const result = joinPathUrl(url, params); - - expect(result).toEqual(expectedUrl); - }); -});