UNPKG

paradigm-core

Version:
691 lines (504 loc) 13.9 kB
const { RootController, ComposeError, UsersPlugin: {UserModel}, } = require('structure-core') const errorCodes = require('../../../lib/error-codes') const slug = require('../../../lib/slugs') const TemplateModel = require('../models/template') const DocumentModel = require('../models/document') const errorComposer = new ComposeError(errorCodes) /** * DocumentsController Class * * @public * @class DocumentsController */ class DocumentsController extends RootController { /** * DocumentsController constructor * * @public * @constructor * @param {Object} options - Options */ constructor(options = {}) { super(Object.assign({}, { name: 'documents' }, options)) } /** * Check existence of key value pair * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ checkExistence(req, res) { const applicationId = req.headers.applicationid const organizationId = req.headers.organizationid const blacklist = [ ] const key = req.params.key.toLowerCase() const docModel = new DocumentModel({ applicationId, logger: this.logger, organizationId }) const val = req.params.value.toLowerCase() return new Promise( async (resolve, reject) => { if(!key || blacklist.indexOf(key) > -1) return reject({ code: 'UNKNOWN' }) if(!val) return reject({ code: 'UNKNOWN' }) try { const existence = await docModel.checkExistence(key, val) resolve(existence) } catch(e) { reject({ code: 'UNKNOWN', message: e.message, stack: e.stack }) } }) } /** * Create new document * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ create(req, res) { const applicationId = req.headers.applicationid const organizationId = req.headers.organizationid const document = new DocumentModel({ applicationId, logger: this.logger, organizationId }) const pkg = req.body return new Promise( async (resolve, reject) => { try { if(typeof pkg.slug === 'string' && pkg.slug.length > 0) { pkg.slug = slug(pkg.slug) } else if(pkg.title) { pkg.slug = slug(pkg.title) } else { pkg.slug = '' } const existence = await document.checkExistence('slug', pkg.slug) const exists = existence.exists // Don't create a document with a slug that already exists or is empty if(exists) { return reject(errorComposer.compose('DOCUMENT_SLUG_INVALID', { applicationId, organizationId, slug: pkg.slug })) } pkg.applicationId = applicationId pkg.organizationId = organizationId const doc = await document.create(pkg) resolve(doc) } catch(e) { this.logger.error(e) reject(e) } }) } /** * Delete document by id * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ deleteById(req, res) { const applicationId = req.headers.applicationid const organizationId = req.headers.organizationid const document = new DocumentModel({ applicationId, logger: this.logger, organizationId }) return new Promise( async (resolve, reject) => { try { const id = req.params.id const result = await document.deleteById(id) resolve(result) } catch(e) { this.logger.error(e) reject(e) } }) } /** * Create new document from existing document * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ fork(req, res) { var documentId = req.params.id this.logger.debug('Forking document', documentId) return new Promise( async (resolve, reject) => { var documentModel = new DocumentModel({ logger: this.logger, }) try { var doc1 = await documentModel.getById(documentId) this.logger.debug('Feteched document', doc1) } catch(e) { this.logger.error(e) return reject(e) } try { var pkg = Object.assign({}, doc1, { forkId: doc1.id, forkRevisionAt: doc1.activeRevisionId, forkType: 'document' }) delete pkg.id delete pkg.sid delete pkg.activeRevisionId delete pkg.revisionIds var doc2 = await documentModel.create(pkg) this.logger.debug('Created document', doc2) } catch(e) { this.logger.error(e) return reject(e) } resolve(doc2) }) } /** * Create new document from existing template * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ forkTemplate(req, res) { var templateId = req.params.id this.logger.debug('Forking template', templateId) return new Promise( async (resolve, reject) => { try { var template = await new TemplateModel().getById(templateId) this.logger.debug('Feteched template', template) } catch(e) { this.logger.error(e) return reject(e) } try { var pkg = Object.assign({}, template, { forkId: template.id, forkRevisionAt: template.activeRevisionId, forkType: 'template' }) delete pkg.id delete pkg.sid var doc = await new DocumentModel({logger: this.logger}).create(pkg) this.logger.debug('Created document', doc) } catch(e) { this.logger.error(e) return reject(e) } resolve(doc) }) } /** * Get all documents * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ getAll(req, res) { const applicationId = req.headers.applicationid const organizationId = req.headers.organizationid const document = new DocumentModel({ applicationId, logger: this.logger, organizationId }) return new Promise( async (resolve, reject) => { try { const items = await Promise.all([ document.getAll(false, { applicationId, categoryIds: req.query.categoryIds, categorySlugs: req.query.categorySlugs, expand: req.query.expand, ignoreDocumentIds: req.query.ignoreDocumentIds, order: { by: req.query.orderBy, dir: req.query.orderDir }, organizationId, page: req.query.page && Number(req.query.page), limit: req.query.limit && Number(req.query.limit), tags: req.query.tags, status: req.query.status, taxonomyOperator: req.query.taxonomyOperator, userId: req.query.userId, title: req.query.title, }), document.count('draft'), document.count('published'), document.count('scheduled') ]) const total = items[1] + items[2] + items[3] let pkg = { documents: items[0].results, pagination: items[0].pagination, stats: { draft: items[1], published: items[2], scheduled: items[3], total } } resolve(pkg) } catch(e) { this.logger.error(e) reject(e) } }) } /** * Get all documents for a user. This simply wraps the standard getAll * endpoint, but will convert user sids to ids. * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ async getAllByUser(req, res) { const applicationId = req.headers.applicationid const organizationId = req.headers.organizationid const userModel = new UserModel({ applicationId, logger: this.logger, organizationId }) // Ensure that we pass const user = await userModel.getById(req.params.id) req.query.userId = user.id return this.getAll(req, res) } /** * Get document by id * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ getById(req, res) { const applicationId = req.headers.applicationid const organizationId = req.headers.organizationid const document = new DocumentModel({ applicationId, logger: this.logger, organizationId }) const query = req.query return new Promise( async (resolve, reject) => { try { const doc = await document.getById(req.params.id, { query }) // const sids = this.getSidsFromDoc(doc) resolve(doc) } catch(e) { this.logger.error(e) reject(e) } }) } /** * Get document by permalink * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ getByPermalink(req, res) { const applicationId = req.headers.applicationid const organizationId = req.headers.organizationid const document = new DocumentModel({ applicationId, logger: this.logger, organizationId }) return document.getByPermalink(req.params.permalink) } /** * Get document by slug * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ getBySlug(req, res) { const applicationId = req.headers.applicationid const organizationId = req.headers.organizationid var document = new DocumentModel({ applicationId, logger: this.logger, organizationId }) return document.getBySlug(req.params.slug) } /** * Get document categories * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ getCategories(req, res) { const applicationId = req.headers.applicationid const organizationId = req.headers.organizationid return new Promise( async (resolve, reject) => { try { const document = new DocumentModel({ applicationId, logger: this.logger, organizationId }) const categories = await document.getCategories(req.params.id, null) resolve({categories}) } catch(e) { this.logger.error(e) reject(e) } }) } getSidsFromDoc(doc) { const fields = doc.fields || [] const sids = [] if(doc.featuredImage) { sids.push(doc.featuredImage.sid) } if(doc.facebookImage && doc.facebookImage.sid) { sids.push(doc.facebookImage.sid) } if(doc.twitterImage && doc.twitterImage.sid) { sids.push(doc.twitterImage.sid) } for(let i = 0, l = fields.length; i < l; i++) { const field = fields[i] if(field.props && field.props.digitalAsset) { sids.push(field.props.digitalAsset.sid) } } return sids } /** * Publish a document * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ publishById(req, res) { const document = new DocumentModel({ logger: this.logger, }) const pkg = req.body pkg.status = 'published' return document.updateById(req.params.id, pkg) } /** * Purge CDN cache of a document * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ purgeById(req, res) { return new Promise( async (resolve, reject) => { try { resolve({status: 'purging'}) } catch(e) { this.logger.error(e) reject(e) } }) } /** * Un-Publish a document * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ unpublishById(req, res) { const document = new DocumentModel({ logger: this.logger, }) const pkg = req.body pkg.status = 'draft' return document.updateById(req.params.id, pkg) } /** * Update a document * * @public * @param {Object} req - Express req * @param {Object} res - Express res */ updateById(req, res) { const applicationId = req.headers.applicationid const pkg = req.body const id = req.params.id const organizationId = req.headers.organizationid const document = new DocumentModel({ applicationId, logger: this.logger, organizationId }) return new Promise( async (resolve, reject) => { try { const oldDoc = await document.getById(id) if(typeof pkg.slug === 'string' && pkg.slug.length > 0) { pkg.slug = slug(pkg.slug) } else if(pkg.title) { pkg.slug = slug(pkg.title) } else { pkg.slug = oldDoc.slug } if (pkg.slug !== oldDoc.slug) { const existence = await document.checkExistence('slug', pkg.slug) const exists = existence.exists // Can't update a document with a slug that already exists or is empty if(exists) { return reject(errorComposer.compose('DOCUMENT_SLUG_INVALID', { applicationId, organizationId, slug: pkg.slug })) } } const doc = await document.updateById(id, pkg) doc.previousStatus = oldDoc.status resolve(doc) } catch(e) { this.logger.error(e) reject(e) } }) } updateMany(req, res) { const document = new DocumentModel({ logger: this.logger, }) return document.updateMany(req.body) } } module.exports = DocumentsController