import { parseQuery, stringifyQuery } from '@/core/serializer/query-serializer' import { parseUrl } from '@/core/serializer/url-serializer' import { deepClone } from '@/shared/helpers/deep-clone' import type { FLuentUrlPlainObject, FluentUrlConfig, NormalizeOptionsArgs, PlainObjectConstraint, } from '@/shared/types' export function normalizeConfig< PQO extends PlainObjectConstraint, SQO extends PlainObjectConstraint, >(config?: Partial>): FluentUrlConfig { return { parseQuery: config?.parseQuery ?? parseQuery, parseQueryOptions: config?.parseQueryOptions, stringifyQuery: config?.stringifyQuery ?? stringifyQuery, stringifyQueryOptions: config?.stringifyQueryOptions, } } export function normalizeOptions({ urlOrOptions, parseQuery, parseQueryOptions, }: NormalizeOptionsArgs): FLuentUrlPlainObject { if (typeof urlOrOptions === 'string') { return parseUrl({ str: urlOrOptions, parseQuery, parseQueryOptions, }) } return { protocol: urlOrOptions?.protocol, hostname: urlOrOptions?.hostname, paths: deepClone(urlOrOptions?.paths) ?? [], port: urlOrOptions?.port, fragment: urlOrOptions?.fragment, queries: deepClone(urlOrOptions?.queries) ?? Object.create(null), } } export function mergeConfig< PQO extends PlainObjectConstraint, SQO extends PlainObjectConstraint, >( current: FluentUrlConfig, merge?: Partial>, ): FluentUrlConfig { return { parseQuery: merge?.parseQuery ?? current.parseQuery, parseQueryOptions: merge?.parseQueryOptions, stringifyQuery: merge?.stringifyQuery ?? current.stringifyQuery, stringifyQueryOptions: merge?.stringifyQueryOptions, } } export function mergeOptions( current: FLuentUrlPlainObject, merge?: Partial, ): FLuentUrlPlainObject { return { protocol: merge?.protocol ?? current.protocol, hostname: merge?.hostname ?? current.hostname, paths: merge?.paths ?? current.paths, port: merge?.port ?? current.port, fragment: merge?.fragment ?? current.fragment, queries: merge?.queries ?? current.queries, } }