@herlinus/coloquent
Version:
Library for retrieving model objects from a JSON-API, with a fluent syntax inspired by Laravel Eloquent.
171 lines • 5.31 kB
JavaScript
import { ClassFilterSpec } from "./ClassFilterSpec";
import { QueryParam } from "./QueryParam";
export class Query {
constructor(jsonApiType, queriedRelationName = undefined, jsonApiId = undefined) {
this.jsonApiType = jsonApiType;
this.jsonApiId = jsonApiId;
this.queriedRelationName = queriedRelationName;
this.include = [];
this.filters = [];
this.options = [];
this.sort = [];
}
addFilterParameters(searchParams) {
for (let f of this.filters) {
if (f instanceof ClassFilterSpec) {
let ff = f;
searchParams.push(new QueryParam(`filter[${ff.getClass()}][${ff.getAttribute()}]`, ff.getValue()));
}
else {
searchParams.push(new QueryParam(`filter[${f.getAttribute()}]`, f.getValue()));
}
}
}
addIncludeParameters(searchParams) {
if (this.include.length > 0) {
let p = '';
for (let incl of this.include) {
if (p !== '') {
p += ',';
}
p += incl;
}
searchParams.push(new QueryParam('include', p));
}
}
addOptionsParameters(searchParams) {
for (let option of this.options) {
searchParams.push(new QueryParam(option.getParameter(), option.getValue()));
}
}
addPaginationParameters(searchParams) {
for (let param of this.paginationSpec.getPaginationParameters()) {
searchParams.push(new QueryParam(param.name, param.value));
}
}
addSortParameters(searchParams) {
if (this.sort.length > 0) {
let p = '';
for (let sortSpec of this.sort) {
if (p !== '') {
p += ',';
}
if (!sortSpec.getPositiveDirection()) {
p += '-';
}
p += sortSpec.getAttribute();
}
searchParams.push(new QueryParam('sort', p));
}
}
toString() {
let relationToFind = '';
if (!this.jsonApiId) {
relationToFind = this.queriedRelationName
? '/' + this.queriedRelationName
: '';
}
else {
relationToFind = this.queriedRelationName
? '/' + this.jsonApiId + '/' + this.queriedRelationName
: '';
}
let idToFind = this.idToFind
? '/' + this.idToFind
: '';
let searchParams = [];
this.addFilterParameters(searchParams);
this.addIncludeParameters(searchParams);
this.addOptionsParameters(searchParams);
this.addPaginationParameters(searchParams);
this.addSortParameters(searchParams);
let paramString = '';
for (let searchParam of searchParams) {
if (paramString === '') {
paramString += '?';
}
else {
paramString += '&';
}
paramString += encodeURIComponent(searchParam.name) + '=' + encodeURIComponent(searchParam.value);
}
return this.jsonApiType + relationToFind + idToFind + paramString;
}
getJsonApiType() {
return this.jsonApiType;
}
getJsonApiId() {
return this.jsonApiId;
}
getQueriedRelationName() {
return this.queriedRelationName;
}
setIdToFind(idToFind) {
this.idToFind = idToFind;
}
getPaginationSpec() {
return this.paginationSpec;
}
setPaginationSpec(paginationSpec) {
this.paginationSpec = paginationSpec;
}
addInclude(includeSpec) {
this.include.push(includeSpec);
}
getInclude() {
return this.include;
}
addFilter(filter) {
this.filters.push(filter);
}
getFilters() {
return this.filters;
}
addSort(sort) {
this.sort.push(sort);
}
getSort() {
return this.sort;
}
addOption(option) {
this.options.push(option);
}
getOptions() {
return this.options;
}
setLimit(limit) {
this.limit = limit;
}
getLimit() {
return this.limit;
}
/**
* Example: When including 'foo.bar, goo', then the include paths are [[foo, bar], [goo]].
*/
get includePaths() {
return this
.include
.map(includePath => includePath.split('.'));
}
/**
* Example: When including 'foo.bar, goo', then the include tree is {foo: {bar: true}, goo: true}.
*/
get includeTree() {
const tree = {};
for (let path of this.includePaths) {
this.includeTreeRecurse(tree, path);
}
return tree;
}
includeTreeRecurse(tree, path) {
if (path.length === 1) {
tree[path[0]] = {};
}
else if (path.length > 1) {
const subtree = {};
tree[path[0]] = subtree;
this.includeTreeRecurse(subtree, path.slice(1));
}
}
}
//# sourceMappingURL=Query.js.map