mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[ui/url] add modifyUrl() helper
This commit is contained in:
parent
f38e7dc428
commit
d4b9849fe5
4 changed files with 108 additions and 3 deletions
44
src/ui/public/url/__tests__/modify_url.js
Normal file
44
src/ui/public/url/__tests__/modify_url.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { parse as parseUrl } from 'url';
|
||||
|
||||
import expect from 'expect.js';
|
||||
|
||||
import { modifyUrl } from '../modify_url';
|
||||
|
||||
describe('modifyUrl()', () => {
|
||||
it('throws an error with invalid input', () => {
|
||||
expect(() => modifyUrl(1, () => {})).to.throwError();
|
||||
expect(() => modifyUrl(undefined, () => {})).to.throwError();
|
||||
expect(() => modifyUrl('http://localhost')).to.throwError(); // no block
|
||||
});
|
||||
|
||||
it('supports returning a new url spec', () => {
|
||||
expect(modifyUrl('http://localhost', () => ({}))).to.eql('');
|
||||
});
|
||||
|
||||
it('supports modifying the passed object', () => {
|
||||
expect(modifyUrl('http://localhost', parsed => {
|
||||
parsed.port = 9999;
|
||||
parsed.auth = 'foo:bar';
|
||||
})).to.eql('http://foo:bar@localhost:9999/');
|
||||
});
|
||||
|
||||
it('supports changing pathname', () => {
|
||||
expect(modifyUrl('http://localhost/some/path', parsed => {
|
||||
parsed.pathname += '/subpath';
|
||||
})).to.eql('http://localhost/some/path/subpath');
|
||||
});
|
||||
|
||||
it('supports changing port', () => {
|
||||
expect(modifyUrl('http://localhost:5601', parsed => {
|
||||
parsed.port = (parsed.port * 1) + 1;
|
||||
})).to.eql('http://localhost:5602/');
|
||||
});
|
||||
|
||||
it('supports changing protocol', () => {
|
||||
expect(modifyUrl('http://localhost', parsed => {
|
||||
parsed.protocol = 'mail';
|
||||
parsed.slashes = false;
|
||||
parsed.pathname = null;
|
||||
})).to.eql('mail:localhost');
|
||||
});
|
||||
});
|
2
src/ui/public/url/index.js
Normal file
2
src/ui/public/url/index.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
export { KbnUrlProvider as default } from './url';
|
||||
export { modifyUrl } from './modify_url';
|
61
src/ui/public/url/modify_url.js
Normal file
61
src/ui/public/url/modify_url.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
import { parse as parseUrl, format as formatUrl } from 'url';
|
||||
|
||||
/**
|
||||
* Takes a URL and a function that takes the meaningful parts
|
||||
* of the URL as a key-value object, modifies some or all of
|
||||
* the parts, and returns the modified parts formatted again
|
||||
* as a url.
|
||||
*
|
||||
* Url Parts sent:
|
||||
* - protocol
|
||||
* - slashes (does the url have the //)
|
||||
* - auth
|
||||
* - hostname (just the name of the host, no port or auth information)
|
||||
* - port
|
||||
* - pathmame (the path after the hostname, no query or hash, starts
|
||||
* with a slash if there was a path)
|
||||
* - query (always an object, even when no query on original url)
|
||||
* - hash
|
||||
*
|
||||
* Why?
|
||||
* - The default url library in node produces several conflicting
|
||||
* properties on the "parsed" output. Modifying any of these might
|
||||
* lead to the modifications being ignored (depending on which
|
||||
* property was modified)
|
||||
* - It's not always clear wither to use path/pathname, host/hostname,
|
||||
* so this trys to add helpful constraints
|
||||
*
|
||||
* @param {String} url - the url to parse
|
||||
* @param {Function<Object|undefined>} block - a function that will modify the parsed url, or return a new one
|
||||
* @return {String} the modified and reformatted url
|
||||
*/
|
||||
export function modifyUrl(url, block) {
|
||||
if (typeof block !== 'function') {
|
||||
throw new TypeError('You must pass a block to define the modifications desired');
|
||||
}
|
||||
|
||||
const parsed = parseUrl(url, true);
|
||||
|
||||
// copy over the most specific version of each
|
||||
// property. By default, the parsed url includes
|
||||
// several conflicting properties (like path and
|
||||
// pathname + search, or search and query) and keeping
|
||||
// track of which property is actually used when they
|
||||
// are formatted is harder than necessary
|
||||
const meaningfulParts = {
|
||||
protocol: parsed.protocol,
|
||||
slashes: parsed.slashes,
|
||||
auth: parsed.auth,
|
||||
hostname: parsed.hostname,
|
||||
port: parsed.port,
|
||||
pathname: parsed.pathname,
|
||||
query: parsed.query || {},
|
||||
hash: parsed.hash,
|
||||
};
|
||||
|
||||
// the block modifies the meaningfulParts object, or returns a new one
|
||||
const modifications = block(meaningfulParts) || meaningfulParts;
|
||||
|
||||
// format the modified/replaced meaningfulParts back into a url
|
||||
return formatUrl(modifications);
|
||||
}
|
|
@ -8,7 +8,7 @@ import AppStateProvider from 'ui/state_management/app_state';
|
|||
uiModules.get('kibana/url')
|
||||
.service('kbnUrl', function (Private) { return Private(KbnUrlProvider); });
|
||||
|
||||
function KbnUrlProvider($injector, $location, $rootScope, $parse, Private) {
|
||||
export function KbnUrlProvider($injector, $location, $rootScope, $parse, Private) {
|
||||
const self = this;
|
||||
|
||||
/**
|
||||
|
@ -207,5 +207,3 @@ function KbnUrlProvider($injector, $location, $rootScope, $parse, Private) {
|
|||
return (reloadOnSearch && searchSame) || !reloadOnSearch;
|
||||
};
|
||||
}
|
||||
|
||||
export default KbnUrlProvider;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue