feat: refine FluentUrl class and enhance URL serializer with improved parsing logic
This commit is contained in:
@@ -1,9 +1,74 @@
|
||||
import type { UrlSerializer } from '@/shared/types'
|
||||
import type { FLuentUrlPlainObject, UrlSerializer } from '@/shared/types'
|
||||
|
||||
export const parseUrl: UrlSerializer['parseUrl'] = () => {
|
||||
throw new Error('Not implemented')
|
||||
const URLTypesObj = {
|
||||
absolute: 'absolute',
|
||||
relative: 'relative',
|
||||
protocolRelative: 'protocol-relative',
|
||||
} as const
|
||||
|
||||
type URLTypes = (typeof URLTypesObj)[keyof typeof URLTypesObj]
|
||||
|
||||
const defaultProtocol = 'https'
|
||||
const defaultHost = 'example.com'
|
||||
|
||||
export const parseUrl: UrlSerializer['parseUrl'] = ({ str, parseQuery }) => {
|
||||
const urlString = str.trim()
|
||||
|
||||
const urlType: URLTypes = urlString.startsWith('//')
|
||||
? URLTypesObj.protocolRelative
|
||||
: urlString.startsWith('/')
|
||||
? URLTypesObj.relative
|
||||
: URLTypesObj.absolute
|
||||
|
||||
let newUrlString = urlString
|
||||
|
||||
if (urlType === URLTypesObj.protocolRelative) {
|
||||
newUrlString = `${defaultProtocol}:${newUrlString}`
|
||||
}
|
||||
|
||||
if (urlType === URLTypesObj.relative) {
|
||||
newUrlString = `${defaultProtocol}://${defaultHost}${newUrlString}`
|
||||
}
|
||||
|
||||
let url: URL
|
||||
|
||||
try {
|
||||
url = new URL(newUrlString)
|
||||
} catch {
|
||||
throw new Error('Invalid URL')
|
||||
}
|
||||
|
||||
const urlPlainObject: FLuentUrlPlainObject = {
|
||||
paths: [],
|
||||
queries: {},
|
||||
}
|
||||
|
||||
if (urlType === URLTypesObj.absolute) {
|
||||
urlPlainObject.protocol =
|
||||
url.protocol !== '' ? url.protocol.replace(':', '') : undefined
|
||||
}
|
||||
|
||||
if (
|
||||
urlType === URLTypesObj.absolute ||
|
||||
urlType === URLTypesObj.protocolRelative
|
||||
) {
|
||||
urlPlainObject.hostname = url.hostname || undefined
|
||||
}
|
||||
|
||||
urlPlainObject.paths =
|
||||
url.pathname === '/' ? [] : url.pathname.split('/').filter((p) => p !== '')
|
||||
|
||||
urlPlainObject.port = url.port !== '' ? Number(url.port) : undefined
|
||||
|
||||
urlPlainObject.fragment =
|
||||
url.hash !== '' ? url.hash.replace('#', '') : undefined
|
||||
|
||||
urlPlainObject.queries =
|
||||
url.search !== '' ? parseQuery(url.search) : Object.create(null)
|
||||
|
||||
return urlPlainObject
|
||||
}
|
||||
|
||||
export const stringifyUrl: UrlSerializer['stringifyUrl'] = () => {
|
||||
export const stringifyUrl: UrlSerializer['stringifyUrl'] = (_args) => {
|
||||
throw new Error('Not implemented')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user