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') }