Skip to content

Instantly share code, notes, and snippets.

@abalad
Created November 8, 2018 16:28
Show Gist options
  • Save abalad/a9b135b69b031c286f7ab54be10c5592 to your computer and use it in GitHub Desktop.
Save abalad/a9b135b69b031c286f7ab54be10c5592 to your computer and use it in GitHub Desktop.
import { Sails } from './sails';
import { SailsModel } from './sails.model';
import { SailsRequest } from './sails.request';
import { SailsModelInterface } from './sails.model.interface';
import { RequestCriteria } from './sails.request.criteria';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { SailsResponse } from './sails.response';
export class SailsQuery<T extends SailsModelInterface, U extends SailsModelInterface = T&{ new(): T }> {
private model: T;
private request: SailsRequest;
private criteria: RequestCriteria;
private associationModel: U;
private assosiationModelClass?: { new(): U };
private errorMsg = `[SailsSocketIO]: the data is not an instance of ${this.modelClass.name}.
You could SailsModel.unserialize(${this.modelClass.name}, data) as ${this.modelClass.name}[] (Array of Models), Or
SailsModel.unserialize(${this.modelClass.name}, data) as ${this.modelClass.name} (Single Models)
after fetching the data with SailsRequest.`;
constructor(sails: Sails, private modelClass: { new(): T } ) {
this.request = new SailsRequest(sails);
this.model = new modelClass();
}
public find(): Observable<T[]> {
this.request.addParam('where', this.getRequestCriteria());
return this.request.get(`/${this.model.getEndPoint()}`).pipe(
map((res: SailsResponse) => {
if (res.isOk()) {
return SailsModel.unserialize<T>(this.modelClass, res.getData()) as T[];
}
throw res;
})
);
}
public findOne(id: string): Observable<T> {
this.request.addParam('where', this.getRequestCriteria());
return this.request.get(`/${this.model.getEndPoint()}/${id}`).pipe(
map((res: SailsResponse) => {
if (res.isOk()) {
return SailsModel.unserialize<T>(this.modelClass, res.getData()) as T;
}
throw res;
})
);
}
public populate(id: string): Observable<U[]> {
this.request.addParam('where', this.getRequestCriteria());
return this.request.get(`/${this.model.getEndPoint()}/${id}/${this.associationModel.getEndPoint()}`).pipe(
map((res: SailsResponse) => {
if (res.isOk()) {
return SailsModel.unserialize<U>(this.assosiationModelClass, res.getData()) as U[];
}
throw res;
})
);
}
public save(model: T): Observable<T> {
if (!(model instanceof this.modelClass)) {
throw new TypeError(this.errorMsg);
}
const data = SailsModel.serialize(model);
const url = `/${model.getEndPoint()}`;
if (model.id === null || model.id === '') {
return this.request.post(url, data).pipe(
map(( res: SailsResponse ) => {
if (res.isOk()) {
return SailsModel.unserialize<T>(this.modelClass, res.getData()) as T;
}
throw res;
})
);
} else {
return this.request.put(url.concat('/', model.id), data).pipe(
map(( res: SailsResponse ) => {
if (res.isOk()) {
return SailsModel.unserialize<T>(this.modelClass, res.getData()) as T;
}
throw res;
})
);
}
}
public update(id: string, model: Partial<T>): Observable<T> {
if (model.createdAt) {
delete model.createdAt;
}
if (model.updatedAt) {
delete model.updatedAt;
}
const data = model instanceof SailsModel ? SailsModel.serialize(model) : Object.assign({}, model);
return this.request.patch(`/${this.model.getEndPoint()}/${id}`, data).pipe(
map(( res: SailsResponse ) => {
if (res.isOk()) {
return SailsModel.unserialize<T>(this.modelClass, res.getData()) as T;
}
throw res;
})
);
}
public restore(id: string, model: Partial<T>): Observable<T> {
if (model.createdAt) {
delete model.createdAt;
}
if (model.updatedAt) {
delete model.updatedAt;
}
const data = model instanceof SailsModel ? SailsModel.serialize(model) : Object.assign({}, model);
return this.request.patch(`/${this.model.getEndPoint()}/${id}/restore`, data).pipe(
map(( res: SailsResponse ) => {
if (res.isOk()) {
return SailsModel.unserialize<T>(this.modelClass, res.getData()) as T;
}
throw res;
})
);
}
public replace(id: string, model: Partial<T> ): Observable<T> {
if (model.createdAt) {
delete model.createdAt;
}
if (model.updatedAt) {
delete model.updatedAt;
}
const data = model instanceof SailsModel ? SailsModel.serialize(model) : Object.assign({}, model);
const endpoint = this.associationModel.getEndPoint();
return this.request.put(`/${this.model.getEndPoint()}/${id}/${endpoint}`, data[endpoint]).pipe(
map(( res: SailsResponse ) => {
if (res.isOk()) {
return SailsModel.unserialize<T>(this.modelClass, res.getData()) as T;
}
throw res;
})
);
}
public remove(id: string): Observable<T> {
return this.request.delete(`/${this.model.getEndPoint()}/${id}`).pipe(
map(( res: SailsResponse ) => {
if (res.isOk()) {
return SailsModel.unserialize<T>(this.modelClass, res.getData()) as T;
}
throw res;
})
);
}
public setAssociation(association: { new(): U }): this {
this.associationModel = new association();
this.assosiationModelClass = association;
return this;
}
public setLimit(limit: number): this {
this.request.addParam('limit', limit);
return this;
}
public setSort(sort: string): this {
this.request.addParam('sort', sort);
return this;
}
public setSkip(skip: number): this {
this.request.addParam('skip', skip);
return this;
}
public setPopulation(...population: string[]): this {
this.request.addParam('populate', `[${population.join(',')}]`);
return this;
}
public setRequestCriteria(criteria: RequestCriteria): this {
this.criteria = criteria;
return this;
}
private getRequestCriteria(): RequestCriteria {
return this.criteria || new RequestCriteria();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment