vue-useurl
Version:
Reactive Url Builder Vue Composable
71 lines (70 loc) • 2.71 kB
JavaScript
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 };