UNPKG

punchcard-cms

Version:
225 lines (193 loc) 5.45 kB
'use strict'; const _ = require('lodash'); const Promise = require('bluebird'); const utils = require('./utils'); const follow = require('./follow'); const database = require('../database'); /* * Determines Content Types and Content Type Keys * * @param {object} app - An Express app * * @returns {object} types - An object containing `key` of Content Type keys and `types` of all Content Types */ const types = app => { let cts = _.cloneDeep(app.get('content-types')).map(ct => { const type = {}; Object.keys(ct).forEach(attr => { if (attr !== 'attributes') { type[attr] = ct[attr]; } }); return type; }); const ctKeys = Object.keys(cts[0]).sort().filter(key => { if (key === 'name') { return false; } return true; }); ctKeys.unshift('name'); cts = cts.map(ct => { const type = ct; type.meta = { url: `/api/types/${ct.id}`, }; delete type.workflow; delete type.identifier; return type; }); return { keys: ctKeys, all: cts, }; }; /* * API for all Content * * @param {object} query - Request queries * @param {array} models - Object of all content types * * @returns {object} - All items and the pagination for the items */ // TODO: Return error if no items are found const all = (query, models, next) => { const organize = utils.organize(query); const mods = _.cloneDeep(models) || []; return database.transaction(trx => { const results = trx('live').select('*'); if (query.key) { results.where({ key: query.key, }); } else if (query.key_slug) { // eslint-disable-line camelcase results.where({ 'key-slug': query.key_slug, // eslint-disable-line camelcase }); } return results.orderBy(organize.sort.by, organize.sort.dir).offset(organize.page.offset).limit(organize.page.limit).then(rows => { return trx('live').count('id').then(total => { if (query.follow) { return follow(query, rows, mods, total, organize, trx); } return utils.format(rows, '', mods, query, trx).then(formatted => { return { items: formatted, pages: utils.page('api', organize, total[0].count), }; }); }) .catch(e => { const err = { message: e.message, safe: '/', status: 500, }; return next(err); }); }); }); }; /* * API for all Content Types * * @param {object} query - Request queries * @param {object} cts - Content types * * @returns {object} - All items and the pagination for the items */ // TODO: Return error if no items are found const content = (query, cts) => { const organize = utils.organize(query, cts.keys); const pages = utils.page('api/types', organize, cts.all.length); const items = _.sortBy(cts.all, o => { return o[organize.sort.by]; }); if (organize.sort.dir === 'desc') { items.reverse(); } const results = _.cloneDeep(items).slice(organize.page.offset, organize.page.offset + organize.page.limit); return Promise.map(results, ct => { return database('live').count('id').where({ 'type-slug': ct.id, }).then(total => { const type = ct; type.meta.count = parseInt(total[0].count, 10); return type; }); }).then(formatted => { return { items: formatted, pages, }; }); }; /* * API for all Content of a given Type * * @param {object} query - Request queries * @param {object} model - The content type model * @param {array} models - Object of all content types * * @returns {object} - All items and the pagination for the items */ // TODO: Return error if no items are found const ofType = (query, model, models) => { const organize = utils.organize(query); const mods = _.cloneDeep(models) || []; let attrs = []; if (model.hasOwnProperty('attributes')) { attrs = model.attributes; } const where = { 'type-slug': model.id, }; if (query.key) { where.key = query.key; } else if (query.key_slug) { // eslint-disable-line camelcase where['key-slug'] = query.key_slug; // eslint-disable-line camelcase } return database.transaction(trx => { return trx('live').select('*').where(where).orderBy(organize.sort.by, organize.sort.dir).offset(organize.page.offset).limit(organize.page.limit).then(rows => { return trx('live').where({ 'type-slug': model.id, }).count('id').then(total => { if (query.follow) { return follow(query, rows, mods, total, organize, trx); } return utils.format(rows, attrs, mods, query, trx).then(formatted => { return { items: formatted, pages: utils.page('api', organize, total[0].count), }; }); }); }); }); }; /* * A Specific Piece of Content * * @param {object} query - Request queries * @param {string} id - The GUID to search * @param {array} model - Array of content type attributes * * @returns {object} - All items and the pagination for the items */ // TODO: Return error if no items are found const one = (query, id, model, models) => { const params = _.cloneDeep(query) || {}; params.follow = true; return database.transaction(trx => { return utils.one(params, id, model, models, trx); }); }; module.exports = { types, all, content, ofType, one, };