import { normalizeConfig, normalizeOptions } from '@/core/config-defaults' import { deepClone } from '@/shared/helpers/deep-clone' import { stringifyUrl } from './serializer/url-serializer' export class FluentUrl { private config: FluentUrlConfig private readonly protocol?: string private readonly hostname?: string private readonly paths: string[] private readonly port?: number private readonly fragment?: string private readonly queries: QueriesPlainObject constructor( urlOrOptions?: Partial | string, config?: FluentUrlConfig, ) { this.config = normalizeConfig(config) const { protocol, hostname, paths, port, fragment, queries } = normalizeOptions({ urlOptions: urlOrOptions, parseQuery: this.config.parseQuery, }) this.protocol = protocol this.hostname = hostname this.paths = paths this.port = port this.fragment = fragment this.queries = queries } public toString(): string { return stringifyUrl({ obj: { protocol: this.protocol, hostname: this.hostname, paths: this.paths, port: this.port, fragment: this.fragment, queries: this.queries, }, stringifyQuery: this.config.stringifyQuery, }) } public toJSON(): string { return this.toString() } public valueOf(): string { return this.toString() } public toPlainObject(): FLuentUrlPlainObject { return deepClone({ protocol: this.protocol, hostname: this.hostname, paths: this.paths, port: this.port, fragment: this.fragment, queries: this.queries, }) } public clone( options?: Partial, config?: FluentUrlConfig, ): FluentUrl { return new FluentUrl( { protocol: options?.protocol ?? this.protocol, hostname: options?.hostname ?? this.hostname, paths: options?.paths ?? this.paths, port: options?.port ?? this.port, fragment: options?.fragment ?? this.fragment, queries: options?.queries ?? this.queries, }, { parseQuery: config?.parseQuery ?? this.config.parseQuery, stringifyQuery: config?.stringifyQuery ?? this.config.stringifyQuery, }, ) } }