paradigm-core
Version:
Paradigm Core Modules
691 lines (504 loc) • 13.9 kB
JavaScript
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