Files
fluent-url/lib/core/serializer/url-serializer.ts

75 lines
1.8 KiB
TypeScript

import type { FLuentUrlPlainObject, UrlSerializer } from '@/shared/types'
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'] = (_args) => {
throw new Error('Not implemented')
}