diff --git a/packages/url-manager/.eslintrc.js b/packages/url-manager/.eslintrc.js new file mode 100644 index 0000000..7a0472e --- /dev/null +++ b/packages/url-manager/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + "parserOptions": { + "project": __dirname + "/tsconfig.json" + } +} \ No newline at end of file diff --git a/packages/url-manager/src/URLManager.ts b/packages/url-manager/src/URLManager.ts index d132e5e..af21a41 100644 --- a/packages/url-manager/src/URLManager.ts +++ b/packages/url-manager/src/URLManager.ts @@ -30,83 +30,6 @@ export default class URLManager { this.fromURL(`${url}`) } - private fromURL(url: string) { - const protocolIndex = url.indexOf('://') - let indexOfPath = url.indexOf('/', protocolIndex !== -1 ? protocolIndex + 3 : undefined) - if (indexOfPath === -1) { - indexOfPath = url.indexOf('?', protocolIndex !== -1 ? protocolIndex + 3 : undefined) - } - if (indexOfPath === -1) { - indexOfPath = url.indexOf('#', protocolIndex !== -1 ? protocolIndex + 3 : undefined) - } - const firstPart = url.substr(0, indexOfPath !== -1 ? indexOfPath : undefined) - const path = url.substr(firstPart.length) - - // PROTOCOL - const procotolSplit = firstPart.split('://') - if (procotolSplit.length === 2) { - this.protocols(procotolSplit[0].split('+')) - } - - // USERNAME and PASSWORD - const usrSplit = url.split('@') - if (usrSplit.length === 2) { - const usrPass = usrSplit[0].substr(protocolIndex !== -1 ? protocolIndex + 3 : 0) - const data = usrPass.split(':') - this.username(data.shift() as string) - if (data.length >= 1) { - this.password(data.join(':')) - } - } - - // DOMAIN & PORT - let splitted = firstPart.split('@') - if (splitted.length === 1) { - splitted = firstPart.split('://') - } - const post = splitted.length > 1 ? splitted[1] : splitted[0] - const data = post.split(':') - this.domain(data[0]) - if (data.length === 2) { - this.port(parseInt(data[1])) - } - - const hashPos = path.indexOf('#') - const queryStart = path.indexOf('?') - - // PATH - const pathEnd = queryStart !== -1 ? queryStart : hashPos - this.path(path.substr(0, pathEnd !== -1 ? pathEnd : undefined)) - - // QUERY - if (queryStart !== -1) { - const queryString = path.substring(queryStart + 1, hashPos !== -1 ? hashPos : undefined) - const queryArray = queryString.split('&') - for (const queryItem of queryArray) { - const item = queryItem.split('=') - const key = item[0] - const val = item.length === 2 ? item[1] : '' - - let query = this.query(key) - if (query) { - if (typeof query === 'string') { - query = [query, val] - } else { - query.push(val) - } - this.query(key, query) - } else { - this.query(key, val) - } - } - } - - // HASH - if (hashPos !== -1) { - this.hash(path.substr(hashPos + 1)) - } - } - /** * Make a new URLManager from the current location * @return { this } @@ -134,18 +57,11 @@ export default class URLManager { public query(key: string): string | Array /** - * set a key to a value in the query string - * @param key the key to set - * @param value the value to set + * set/delete a key to a value in the query string + * @param key the key to set/delete + * @param value the value to set or null to delete it */ - public query(key: string, value: string | Array): this - - /** - * delete key from the query string - * @param key the key to delete - * @param value the `null` keyword - */ - public query(key: string, value: null): this + public query(key: string, value: string | Array | null): this /** * Manipulate the query string @@ -332,63 +248,6 @@ export default class URLManager { return this } - private formatPath(format?: Record) { - let path = this.path() - if (!path) { - return undefined - } - if (format) { - for (const key in format) { - if (!(key in format)) { - continue - } - const replacing = format[key] - path = path.replace(`[${key}]`, replacing) - } - } - return `${(path.startsWith('/') ? '' : '/')}${path}` - } - - private formatQuery(options?: { queryArrayJoin?: string }) { - let result = '' - const queryTmp = this.query() - - for (const key in queryTmp) { - if (!Object.prototype.hasOwnProperty.call(queryTmp, key)) { - continue - } - - const element = queryTmp[key] - - result += result.length === 0 ? '?' : '&' - - if (typeof element !== 'object') { - result += `${key}=${element}` - continue - } - - if (options?.queryArrayJoin) { - result += `${key}=${element.join(options.queryArrayJoin)}` - continue - } - - for (let i = 0; i < element.length; i++) { - const val = element[i] - if (i !== 0) { - result += '&' - } - result += `${key}=${val}` - } - } - - if (!result) { - return undefined - } - - return result - } - - /** * Build the string back * @param { Record | undefined } format Formatting options ex: if path contains `[test]` and format is `{test: 'working'}` `[test]` will be replaced by the value @@ -446,4 +305,137 @@ export default class URLManager { window.history.pushState(undefined, document.head.title, this.toString()) } + private formatPath(format?: Record) { + let path = this.path() + if (!path) { + return undefined + } + if (format) { + for (const key in format) { + if (!(key in format)) { + continue + } + const replacing = format[key] + path = path.replace(`[${key}]`, replacing) + } + } + return `${(path.startsWith('/') ? '' : '/')}${path}` + } + + private formatQuery(options?: { queryArrayJoin?: string }) { + let result = '' + const queryTmp = this.query() + + for (const key in queryTmp) { + if (!Object.prototype.hasOwnProperty.call(queryTmp, key)) { + continue + } + + const element = queryTmp[key] + + result += result.length === 0 ? '?' : '&' + + if (typeof element !== 'object') { + result += `${key}=${element}` + continue + } + + if (options?.queryArrayJoin) { + result += `${key}=${element.join(options.queryArrayJoin)}` + continue + } + + for (let i = 0; i < element.length; i++) { + const val = element[i] + if (i !== 0) { + result += '&' + } + result += `${key}=${val}` + } + } + + if (!result) { + return undefined + } + + return result + } + + private fromURL(url: string) { + const protocolIndex = url.indexOf('://') + let indexOfPath = url.indexOf('/', protocolIndex !== -1 ? protocolIndex + 3 : undefined) + if (indexOfPath === -1) { + indexOfPath = url.indexOf('?', protocolIndex !== -1 ? protocolIndex + 3 : undefined) + } + if (indexOfPath === -1) { + indexOfPath = url.indexOf('#', protocolIndex !== -1 ? protocolIndex + 3 : undefined) + } + const firstPart = url.substr(0, indexOfPath !== -1 ? indexOfPath : undefined) + const path = url.substr(firstPart.length) + + // PROTOCOL + const procotolSplit = firstPart.split('://') + if (procotolSplit.length === 2) { + this.protocols(procotolSplit[0].split('+')) + } + + // USERNAME and PASSWORD + const usrSplit = url.split('@') + if (usrSplit.length === 2) { + const usrPass = usrSplit[0].substr(protocolIndex !== -1 ? protocolIndex + 3 : 0) + const arr = usrPass.split(':') + this.username(arr.shift() as string) + if (arr.length >= 1) { + this.password(arr.join(':')) + } + } + + // DOMAIN & PORT + let splitted = firstPart.split('@') + if (splitted.length === 1) { + splitted = firstPart.split('://') + } + const post = splitted.length > 1 ? splitted[1] : splitted[0] + const data = post.split(':') + this.domain(data[0]) + if (data.length === 2) { + this.port(parseInt(data[1])) + } + + const hashPos = path.indexOf('#') + const queryStart = path.indexOf('?') + + // PATH + const pathEnd = queryStart !== -1 ? queryStart : hashPos + this.path(path.substr(0, pathEnd !== -1 ? pathEnd : undefined)) + + // QUERY + if (queryStart !== -1) { + const queryString = path.substring(queryStart + 1, hashPos !== -1 ? hashPos : undefined) + const queryArray = queryString.split('&') + for (const queryItem of queryArray) { + const item = queryItem.split('=') + const key = item[0] + const val = item.length === 2 ? item[1] : '' + + let query = this.query(key) + if (query) { + if (typeof query === 'string') { + query = [query, val] + } else { + query.push(val) + } + this.query(key, query) + } else { + this.query(key, val) + } + } + } + + // HASH + if (hashPos !== -1) { + this.hash(path.substr(hashPos + 1)) + } + } + }