Guest User

Untitled

a guest
Oct 22nd, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.30 KB | None | 0 0
  1. class URL extends Function {
  2. constructor(originalPath, other) {
  3. const [onlyPath, pathQuery = ""] = originalPath.split("?")
  4. const pathParams = queryStringToObj(pathQuery)
  5. const params = { ...pathParams, ...other }
  6. const [nextPath, nextQuery] = interpolateRoute(onlyPath, params)
  7. let path = nextPath
  8. if (!isEmptyObject(nextQuery)) {
  9. path += objToQueryString(nextQuery)
  10. }
  11. super("params", `return new URL("${path}", params)`)
  12. this.path = path
  13. }
  14.  
  15. toString() {
  16. return this.path
  17. }
  18. }
  19.  
  20. const ROUTE_TOKENIZER = /:([^/?]*)/g
  21.  
  22. function without() {
  23. const obj = {}
  24. const { indexOf } = Array.prototype
  25. for (const i in this) {
  26. if (indexOf.call(arguments, i) >= 0) {
  27. continue
  28. }
  29. if (!Object.prototype.hasOwnProperty.call(this, i)) {
  30. continue
  31. }
  32. obj[i] = this[i]
  33. }
  34. return obj
  35. }
  36.  
  37. function interpolateRoute(route, originalAttributes) {
  38. let attributes = originalAttributes
  39. const interpolatedRoute = route.replace(ROUTE_TOKENIZER, (token, attributeName) => {
  40. let match = null
  41. if (attributes.hasOwnProperty(attributeName)) {
  42. match = attributes[attributeName]
  43. }
  44. attributes = without.call(attributes, attributeName)
  45. return match || token
  46. })
  47. return [interpolatedRoute, attributes]
  48. }
  49.  
  50. function isEmptyObject() {
  51. for (let name in this) {
  52. return false
  53. }
  54. return true
  55. }
  56.  
  57. function objToQueryString(obj, keyPrefix = "") {
  58. return Object.keys(obj).reduce((final, current) => {
  59. let delimiter = "?"
  60. if (final.length) {delimiter = "&"}
  61. if (keyPrefix && !final) {delimiter = ""}
  62.  
  63. const initialValue = obj[current]
  64. let key = keyPrefix
  65. ? `${keyPrefix}[${encodeURIComponent(current)}]`
  66. : encodeURIComponent(current)
  67. let value = null
  68. if (typeof initialValue === "object" && initialValue !== null && !isEmptyObject.call(initialValue)) {
  69. value = objToQueryString(initialValue, key)
  70. return `${final}${delimiter}${value}`
  71. } else {
  72. value = encodeURIComponent(obj[current])
  73. return `${final}${delimiter}${key}=${value}`
  74. }
  75. }, "")
  76. }
  77.  
  78. function tryTypeCastFromURL(item) {
  79. if (item === "") {
  80. return ""
  81. }
  82. if (isNaN(item)) {
  83. if (item === "null"){ return null}
  84. if (item === "undefined") {return undefined}
  85. if (item === "true") {return true}
  86. if (item === "false") {return false}
  87. return item
  88. }
  89. return parseFloat(item)
  90. }
  91.  
  92. function queryStringToObj(str) {
  93. let response = {}
  94. if (str) {
  95. response = JSON.parse(
  96. `{"${str
  97. .replace(/^\?/, "")
  98. .replace(/&/g, "\",\"")
  99. .replace(/=/g, "\":\"")}"}`,
  100. function(k, v) {
  101. return k === "" ? v : decodeURIComponent(v)
  102. }
  103. )
  104. Object.keys(response).forEach(function(key) {
  105. const matches = key.split(/[[\]]/).filter(Boolean)
  106. if (matches.length > 1) {
  107. matches.reduce((ref, nextKey, index) => {
  108. let keyType = {}
  109. const isFinalValue = index + 1 === matches.length
  110. if (!isFinalValue && /^\d+$/.test(matches[index + 1])) {
  111. keyType = []
  112. }
  113. ref[nextKey] = ref[nextKey] || (isFinalValue ? tryTypeCastFromURL(response[key]) : keyType)
  114. return ref[nextKey]
  115. }, response)
  116. delete response[key]
  117. } else {
  118. response[key] = tryTypeCastFromURL(response[key])
  119. }
  120. })
  121. }
  122. return response
  123. }
Add Comment
Please, Sign In to add comment