@trusthab/composable-resources
Version:
migrating https://github.com/knetikmedia/hab-api/tree/integration/app/resources/composable
218 lines (180 loc) • 5.94 kB
JavaScript
const composer = require('../mixin_loader');
module.exports = (App) => {
class PersistableResource {
static fromFilter(filter) {
const params = {};
const filters = filter.split('|')
.map(property => property.split(':'));
filters.forEach((filter) => {
const [key, value] = filter;
params[key] = value || true;
});
return params;
}
static toFilter(params = {}) {
// converts an object to a filter string
//
// { location_id: '123', type: 'property' }
// 'location_id:123|type:property'
//
return Object.keys(params)
.map(key => [key, params[key]].join(':'))
.join('|');
}
static count(params) {
if (!this.getPersistedCount) {
return Promise.reject(
new Error(
'Not Implemented! Create a getPersistedCount static method in your resources class',
),
);
}
return this.getPersistedCount(params);
}
static search(params = {}, mapper) {
if (!this.createSearch) {
return Promise.reject(
new Error(
'Not Implemented! Create a createSearch static method in your resources class',
),
);
}
if (!mapper) { mapper = (res => res); }
return this.createSearch(params)
.then(mapper);
}
static list(params = {}, options) {
options = options || {};
const { processHooks } = options;
if (!this.getPersistedList) {
return Promise.reject(
new Error(
'Not Implemented! Create a getPersistedList static method in your resources class',
),
);
}
return this.getPersistedList(params)
.then((result) => {
result.content = this.setAll(result.content);
return result;
})
.then((result) => {
const promise = this.afterList && processHooks
? this.afterList(result)
: Promise.resolve(result);
return promise.then(afterListResult => (
createPage({ ...result, ...afterListResult }, params)
));
});
}
static create(params) {
if (!this.persistCreate) {
return Promise.reject(
new Error(
'Not Implemented! Create a persistCreate static method in your resources class',
),
);
}
const obj = this.deserialize(params);
const data = obj.eject();
return this.validate(params)
.then(() => this.persistCreate(data))
.then(record => new this(record));
}
static find(id, with_deleted = false, options) {
options = options || {};
const { processHooks } = options;
if (!this.getPersistedRecord) {
return Promise.reject(
new Error(
'Not Implemented! Create a getPersistedRecord static method in your resources class',
),
);
}
App.Logger.info('Persistable Mixin: static find');
return this.getPersistedRecord(id)
.then((record) => {
if (!record) { throw new Error('Record Not Found'); }
const result = new this(record);
if (result.deleted_at && !with_deleted) { throw new Error('Record Deleted'); }
return result;
})
.then(result => (this.afterFind && processHooks ? this.afterFind(result) : result))
.catch((err) => {
App.Logger.error('Persistable find failure', err.message);
const { Errors: { RecordNotFound } } = require('@knetik/micro-lib')(App);
throw new RecordNotFound({
message: `Record not found for id: ${id}`
});
});
}
updateAttributes(params = {}) {
Object.keys(params).forEach((prop) => {
const config = this.mapping[prop];
if (!config) {
return;
}
this[prop] = params[prop];
});
return this;
}
static update(id, params, with_deleted) {
if (!this.prototype.persistUpdate) {
return Promise.reject(
new Error(
'Not Implemented! Create a persisteUpdateMany method in your resources class',
),
);
}
App.Logger.info('Persistable Mixin: static update');
return this.find(id, with_deleted)
.then(resource => resource.set(params))
.then(resource => resource.update(with_deleted));
}
update(with_deleted = false) {
if (!this.persistUpdate) {
return Promise.reject(
new Error(
'Not Implemented! Create a persisteUpdate method in your resources class',
),
);
}
App.Logger.info('Persistable Mixin: instance update');
const params = this.serialize();
return this.constructor.validate(params)
.then(() => this.persistUpdate())
.then(() => this.constructor.find(this.id, with_deleted));
}
static destroy(id, params = {}) {
return this.find(id)
.then(obj => obj.updateAttributes(params))
.then(obj => obj.destroy())
.then(() => true);
}
destroy() {
if (!this.persistDestroy) {
return Promise.reject(
new Error(
'Not Implemented! Create a persistDestroy method in your resources class',
),
);
}
return this.persistDestroy();
}
}
function createPage(result, params) {
// is it already a page?
if (result.number_of_elements) {
return result;
}
const { Resources: { Page } } = require('@knetik/micro-lib')(App);
return new Page({
content: result.content,
total_elements: parseInt(result.total),
size: params.size ? parseInt(params.size) : 25,
page: params.page ? parseInt(params.page) : 1,
order: params.order ? params.order.replace('|', ',') : []
});
}
return composer(PersistableResource, App);
};