@trusthab/composable-resources
Version:
migrating https://github.com/knetikmedia/hab-api/tree/integration/app/resources/composable
203 lines (160 loc) • 5.31 kB
JavaScript
const composer = require('../mixin_loader');
const Q = require('q');
const _ = require('lodash');
const moment = require('moment');
module.exports = (App) => {
const { underscore } = require('inflected');
// const ListHandler = App.get('Utils.ListHandler');
class AreasPersistenceResource {
static checkRequirements(modifier) {
if (!this[`areasParams_${modifier}`]) {
return Q.reject(
new Error(
`Not Implemmented! Create the areasParams_${modifier} method in your resources class`,
),
);
}
return Q(true);
}
static getPersistedList(query = {}) {
let defaults;
if (this.areasParams_list) {
defaults = this.areasParams_list().filter;
}
return createQuery
.call(this, query, { filter: defaults })
.then((builtQuery) => {
const method_params = ['/areas', { params: builtQuery }];
return this.checkRequirements('list').then(() => App.Areas.send('get', method_params));
});
}
static getPersistedCount(query = {}) {
let defaults;
if (this.areasParams_count) {
defaults = this.areasParams_count().filter;
}
return createQuery
.call(this, query, { filter: defaults })
.then((builtQuery) => {
const method_params = ['/areas', { params: builtQuery }];
return this.checkRequirements('count')
.then(() => App.Areas.send('get', method_params))
.then(result => _.get(result, 'total_elements'));
});
}
static persistCreate(data) {
_.unset(data, 'created_at');
_.unset(data, 'updated_at');
_.unset(data, 'id');
if (this.areasParams_create) {
const params = this.areasParams_create(data);
data = _.merge(data, params);
}
const method_params = ['/areas', data];
return this.checkRequirements('create').then(() => App.Areas.send('post', method_params));
}
static getPersistedRecord(id) {
return App.Areas.send('get', [`/areas/${id}`]);
}
persistUpdate() {
if (this.areasParams_update) {
const params = this.constructor.areasParams_update();
this.set(params);
}
const data = this.eject();
_.unset(data, 'created_at');
_.unset(data, 'updated_at');
_.unset(data, 'id');
const method_params = [`/areas/${this.id}`, data];
return this.constructor
.checkRequirements('update')
.then(() => App.Areas.send('put', method_params));
}
persistDestroy() {
this.updateAttributes({ deleted_at: moment().unix() });
return this.persistUpdate();
}
}
function createQuery(query, defaults) {
return buildFilter.call(this, query.filter, defaults, false).then((filters) => {
const { page, size } = query;
const order = buildSort.call(this, query.sort);
query = {
page,
size,
order,
...filters
};
return query;
});
}
function buildSort(order = 'name:ASC') {
const sort = order
.split('|')
.map((prop) => {
const [key, val] = prop.split(':');
const config = this.mapping[key];
if (!config) {
return undefined;
}
return `${config.path || key}:${val.toUpperCase()}`;
})
.join(';');
return sort;
}
function buildCustomFilters(filter_str) {
if (!this.customFilters) {
return Q();
}
const custom_filters = this.customFilters();
const filters = {};
// converts a array of array pairs to an object { arry[0][0]: arry[0][1], arry[1][0]: arry[1][1] }
const filter = _.fromPairs(
(filter_str || '')
// either the filter or an empty string
.split('|') // split into key,value array pairs
// split into an array of array pairs [ [ 'location_id', '1232312' ] ]
.map(item => item.split(':')),
);
Object.keys(filter).forEach((key) => {
if (custom_filters[key]) {
filters[key] = custom_filters[key];
}
});
if (!Object.keys(filters).length) {
return Promise.resolve('');
}
const promises = Object.keys(filters).map(key => custom_filters[key].callback(filter[key]).then(result => result));
return Promise.all(promises);
}
function buildFilter(filter = '', defaults = { filter: {} }, with_deleted) {
let filters = {};
filter.split('|').forEach((prop) => {
const [key, val] = prop.split(':');
const config = this.mapping[key];
if (!config) {
return;
}
filters[`filter_${config.path || key}`] = val;
});
Object.keys(defaults.filter).forEach((key) => {
const val = defaults.filter[key];
const config = this.mapping[key];
if (!config) {
return;
}
filters[`filter_${config.path || key}`] = val;
});
if (!with_deleted) {
filters['filter_additional_properties.deleted_at.value'] = 'null';
}
return buildCustomFilters.call(this, filter).then((results) => {
if (!results) {
return filters;
}
results.forEach(result => (filters = { ...filters, ...result }));
return filters;
});
}
return composer(AreasPersistenceResource, App);
};