UNPKG

vue-useurl

Version:

Reactive Url Builder Vue Composable

71 lines (70 loc) 2.71 kB
import { computed, isReactive, reactive, ref } from 'vue-demi'; export class BuilderResult { path; pathVariables; queryParams; hash; arraySerializer; url; constructor(path, pathVariables, queryParams, hash, arraySerializer) { this.path = ref(path); this.pathVariables = reactive(pathVariables); this.queryParams = reactive(queryParams); this.hash = ref(hash); this.arraySerializer = arraySerializer; this.url = computed(() => ''); } setUrl(url) { this.url = url; } } export class UrlBuilder { baseUrl; defaultSerializer; constructor(baseUrl) { this.baseUrl = baseUrl ?? ''; this.defaultSerializer = v => v.join(','); } buildHash(url, hash) { hash = hash ? `#${hash}` : ''; if (url.match(/#.+/gi)) return url.replace(/#.+/gi, `${hash}`); return `${url}${hash}`; } buildPathVariables(url, pathVariables) { Object.keys(pathVariables).forEach((_, index) => { const value = Object.values(pathVariables)[index]; url = url.replace(/:([^\/]+)/gi, isReactive(value) ? value.value : value?.toString()); }); return url; } buildQueryParams(url, queryParams, arraySerializer) { const serializer = arraySerializer ?? this.defaultSerializer; Object.entries(queryParams) .filter(([, value]) => value instanceof Array) .forEach(([key, value]) => { queryParams[key] = serializer(value); }); const urlObject = new URL(url); var searchParams = new URLSearchParams(queryParams); searchParams.forEach((value, key) => urlObject.searchParams.set(key, value)); return urlObject.toString(); } } const useUrl = (options, baseUrl) => { const builderResult = new BuilderResult(options?.path ?? '', options?.pathVariables ?? {}, options?.queryParams ?? {}, options?.hash ?? '', options?.arraySerializer); const { queryParams, pathVariables, path, hash, arraySerializer } = builderResult; const builder = new UrlBuilder(baseUrl); const computedUrl = computed(() => { let tempUrl = `${builder.baseUrl}${path.value}`; tempUrl = tempUrl.replace(/([^:]\/)\/+/g, '$1'); tempUrl = builder.buildPathVariables(tempUrl, pathVariables); tempUrl = builder.buildQueryParams(tempUrl, queryParams, arraySerializer); tempUrl = builder.buildHash(tempUrl, hash.value); return new URL(tempUrl).toString(); }); builderResult.setUrl(computedUrl); return builderResult; }; const createUseUrlInstance = () => useUrl; export { useUrl, createUseUrlInstance };