contensis-core-api
Version:
A dependency library used by contensis-delivery-api and contensis-management-api
93 lines (76 loc) • 2.67 kB
text/typescript
import { ClientParams, MapperFn, UrlFn} from '../models';
import { hasProp, isString, toQuery } from '../utils';
export class UrlBuilder {
private paramMatcher = /(:\b\D\w*)/g;
private options: any = {};
private clientParams: ClientParams;
private mappers: { [key: string]: MapperFn } = {};
static create(url: string | UrlFn, query: { [key: string]: any } = null) {
return new UrlBuilder(url, query);
}
constructor(private url: string | UrlFn, private query: { [key: string]: any }) {
}
addOptions(options: any, defaultParamName: string = null) {
if (isString(options) && !!defaultParamName) {
this.options[defaultParamName] = options;
} else {
this.options = { ...this.options, ...options };
}
return this;
}
setParams(clientParams: ClientParams) {
this.clientParams = clientParams;
return this;
}
addMappers(mappers: { [key: string]: MapperFn }) {
if (mappers) {
Object.keys(mappers).forEach(key => {
this.mappers[key] = mappers[key];
});
}
return this;
}
toUrl(): string {
let namedParams = {};
let urlTemplate = typeof this.url === 'function' ? this.url(this.options, this.clientParams) : this.url;
let paramNames = urlTemplate.match(this.paramMatcher);
if (paramNames) {
paramNames.forEach(paramName => {
let key = paramName.substring(1);
let value: any = null;
if (hasProp(this.options, key)
&& this.options[key] !== null) {
value = this.options[key];
} else if (hasProp(this.clientParams, key)
&& this.clientParams[key] !== null) {
value = this.clientParams[key];
}
let mapperValue: any = null;
if (this.mappers[paramName]) {
mapperValue = this.mappers[paramName](value, this.options, this.clientParams);
}
namedParams[paramName] = mapperValue !== null ? mapperValue : value;
});
}
let query = {};
if (this.query) {
query = { ...this.query };
Object.keys(this.query).forEach(paramName => {
let value = query[paramName];
if (hasProp(this.options, paramName)
&& this.options[paramName] !== null) {
value = this.options[paramName];
} else if (hasProp(this.clientParams, paramName)
&& this.clientParams[paramName] !== null) {
value = this.clientParams[paramName];
}
query[paramName] = this.mappers[paramName] ?
this.mappers[paramName](value, this.options, this.clientParams) : value;
});
}
let url = Object.keys(namedParams)
.reduce((url, key) => url.replace(key, namedParams[key]), urlTemplate);
let queryString = toQuery(query);
return `${url}${queryString}`;
}
}