Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class URL extends Function {
- constructor(originalPath, other) {
- const [onlyPath, pathQuery = ""] = originalPath.split("?")
- const pathParams = queryStringToObj(pathQuery)
- const params = { ...pathParams, ...other }
- const [nextPath, nextQuery] = interpolateRoute(onlyPath, params)
- let path = nextPath
- if (!isEmptyObject(nextQuery)) {
- path += objToQueryString(nextQuery)
- }
- super("params", `return new URL("${path}", params)`)
- this.path = path
- }
- toString() {
- return this.path
- }
- }
- const ROUTE_TOKENIZER = /:([^/?]*)/g
- function without() {
- const obj = {}
- const { indexOf } = Array.prototype
- for (const i in this) {
- if (indexOf.call(arguments, i) >= 0) {
- continue
- }
- if (!Object.prototype.hasOwnProperty.call(this, i)) {
- continue
- }
- obj[i] = this[i]
- }
- return obj
- }
- function interpolateRoute(route, originalAttributes) {
- let attributes = originalAttributes
- const interpolatedRoute = route.replace(ROUTE_TOKENIZER, (token, attributeName) => {
- let match = null
- if (attributes.hasOwnProperty(attributeName)) {
- match = attributes[attributeName]
- }
- attributes = without.call(attributes, attributeName)
- return match || token
- })
- return [interpolatedRoute, attributes]
- }
- function isEmptyObject() {
- for (let name in this) {
- return false
- }
- return true
- }
- function objToQueryString(obj, keyPrefix = "") {
- return Object.keys(obj).reduce((final, current) => {
- let delimiter = "?"
- if (final.length) {delimiter = "&"}
- if (keyPrefix && !final) {delimiter = ""}
- const initialValue = obj[current]
- let key = keyPrefix
- ? `${keyPrefix}[${encodeURIComponent(current)}]`
- : encodeURIComponent(current)
- let value = null
- if (typeof initialValue === "object" && initialValue !== null && !isEmptyObject.call(initialValue)) {
- value = objToQueryString(initialValue, key)
- return `${final}${delimiter}${value}`
- } else {
- value = encodeURIComponent(obj[current])
- return `${final}${delimiter}${key}=${value}`
- }
- }, "")
- }
- function tryTypeCastFromURL(item) {
- if (item === "") {
- return ""
- }
- if (isNaN(item)) {
- if (item === "null"){ return null}
- if (item === "undefined") {return undefined}
- if (item === "true") {return true}
- if (item === "false") {return false}
- return item
- }
- return parseFloat(item)
- }
- function queryStringToObj(str) {
- let response = {}
- if (str) {
- response = JSON.parse(
- `{"${str
- .replace(/^\?/, "")
- .replace(/&/g, "\",\"")
- .replace(/=/g, "\":\"")}"}`,
- function(k, v) {
- return k === "" ? v : decodeURIComponent(v)
- }
- )
- Object.keys(response).forEach(function(key) {
- const matches = key.split(/[[\]]/).filter(Boolean)
- if (matches.length > 1) {
- matches.reduce((ref, nextKey, index) => {
- let keyType = {}
- const isFinalValue = index + 1 === matches.length
- if (!isFinalValue && /^\d+$/.test(matches[index + 1])) {
- keyType = []
- }
- ref[nextKey] = ref[nextKey] || (isFinalValue ? tryTypeCastFromURL(response[key]) : keyType)
- return ref[nextKey]
- }, response)
- delete response[key]
- } else {
- response[key] = tryTypeCastFromURL(response[key])
- }
- })
- }
- return response
- }
Add Comment
Please, Sign In to add comment