Skip to content

Instantly share code, notes, and snippets.

@bjoerge
Last active January 31, 2016 15:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bjoerge/1541448d3b5270d58b28 to your computer and use it in GitHub Desktop.
Save bjoerge/1541448d3b5270d58b28 to your computer and use it in GitHub Desktop.
An require('url') replacement which keeps its properties in sync and supports a custom query parser/stringifier
import url from 'url'
export default Object.assign(configure(), configure)
function configure({qsImpl} = {}) {
return {
parse(urlToParse) {
return Object.assign(createUrlObject({qsImpl}), {
href: urlToParse
})
},
stringify: url.stringify
}
}
function createUrlObject({qsImpl = require('querystring')}) {
const urlObject = {}
Reflect.defineProperty(urlObject, 'host', {
enumerable: true,
get() {
return this.port ? `${this.hostname}:${this.port}` : this.hostname
},
set(newVal) {
const [hostname, port] = newVal.split(':')
Object.assign(this, {
hostname: hostname,
port: port
})
}
})
Reflect.defineProperty(urlObject, 'search', {
enumerable: true,
get() {
const stringified = qsImpl.stringify(this.query || {})
return stringified.length > 1 ? `?${stringified}` : null
},
set(newSearch) {
this.query = qsImpl.parse(newSearch.replace(/^\?/, ''))
}
})
Reflect.defineProperty(urlObject, 'path', {
enumerable: true,
get() {
return this.pathname + (this.search || '')
},
set(newPath) {
const parsed = url.parse(newPath, false, false)
Object.assign(this, {
pathname: parsed.pathname,
query: qsImpl.parse(parsed.search.substring(1))
})
}
})
Reflect.defineProperty(urlObject, 'href', {
get() {
return url.format(this)
},
set(newHref) {
const parsed = url.parse(newHref, false, false)
Object.assign(this, {
protocol: parsed.protocol,
slashes: parsed.slashes,
hostname: parsed.hostname,
pathname: parsed.pathname,
port: parsed.port,
auth: parsed.auth,
query: qsImpl.parse(parsed.search.substring(1)),
hash: parsed.hash
})
}
})
return urlObject
}
// # Usage
const syncUrl = configure({qsImpl: require('qs')})
const parsedUrl = syncUrl.parse('http://user:foo@example.com:8080/p/a/t/h?query=string#hash')
console.log(JSON.stringify(parsedUrl, null, 2))
console.log()
parsedUrl.host = 'another-example.com:5999'
console.log(JSON.stringify(parsedUrl, null, 2))
parsedUrl.hostname = 'another-example.com'
console.log(JSON.stringify(parsedUrl, null, 2))
console.log(parsedUrl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment