feat: refine FluentUrl class and enhance URL serializer with improved parsing logic
This commit is contained in:
@@ -13,7 +13,7 @@ import type {
|
|||||||
} from '@/shared/types'
|
} from '@/shared/types'
|
||||||
|
|
||||||
export class FluentUrl {
|
export class FluentUrl {
|
||||||
private config: FluentUrlConfig
|
private readonly config: FluentUrlConfig
|
||||||
private readonly protocol?: string
|
private readonly protocol?: string
|
||||||
private readonly hostname?: string
|
private readonly hostname?: string
|
||||||
private readonly paths: string[]
|
private readonly paths: string[]
|
||||||
@@ -76,7 +76,7 @@ export class FluentUrl {
|
|||||||
|
|
||||||
public clone(
|
public clone(
|
||||||
options?: Partial<FLuentUrlPlainObject>,
|
options?: Partial<FLuentUrlPlainObject>,
|
||||||
config?: FluentUrlConfig,
|
config?: Partial<FluentUrlConfig>,
|
||||||
): FluentUrl {
|
): FluentUrl {
|
||||||
return new FluentUrl(
|
return new FluentUrl(
|
||||||
mergeOptions(
|
mergeOptions(
|
||||||
|
|||||||
@@ -1,9 +1,74 @@
|
|||||||
import type { UrlSerializer } from '@/shared/types'
|
import type { FLuentUrlPlainObject, UrlSerializer } from '@/shared/types'
|
||||||
|
|
||||||
export const parseUrl: UrlSerializer['parseUrl'] = () => {
|
const URLTypesObj = {
|
||||||
throw new Error('Not implemented')
|
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}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const stringifyUrl: UrlSerializer['stringifyUrl'] = () => {
|
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')
|
throw new Error('Not implemented')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ export interface QuerySerializer {
|
|||||||
export interface UrlSerializer {
|
export interface UrlSerializer {
|
||||||
parseUrl: (args: {
|
parseUrl: (args: {
|
||||||
str: string
|
str: string
|
||||||
parseQuery?: QuerySerializer['parseQuery']
|
parseQuery: QuerySerializer['parseQuery']
|
||||||
}) => FLuentUrlPlainObject
|
}) => FLuentUrlPlainObject
|
||||||
stringifyUrl: (args: {
|
stringifyUrl: (args: {
|
||||||
obj: FLuentUrlPlainObject
|
obj: FLuentUrlPlainObject
|
||||||
stringifyQuery?: QuerySerializer['stringifyQuery']
|
stringifyQuery: QuerySerializer['stringifyQuery']
|
||||||
}) => string
|
}) => string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user