import type { FLuentUrlPlainObject, ParseUrlArgs, PlainObjectConstraint, StringifyUrlArgs, } 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 function parseUrl({ str, parseQuery, parseQueryOptions, }: ParseUrlArgs): FLuentUrlPlainObject { 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, parseQueryOptions) : Object.create(null) return urlPlainObject } export function stringifyUrl( _args: StringifyUrlArgs, ): string { throw new Error('Not implemented') }