editoria-templates
Version:
Template collection for Editoria
125 lines (110 loc) • 3.89 kB
JavaScript
const { exec } = require('child_process')
const logger = require('@pubsweet/logger')
const { Template, File } = require('editoria-data-model/src').models
const map = require('lodash/map')
const path = require('path')
const fs = require('fs-extra')
const config = require('config')
const mime = require('mime-types')
const execute = async command => {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
return reject(error.message)
}
return resolve(stdout)
})
})
}
const filesChecker = async folder => {
// the .map has no place in the below array but exists there as it is
// created during the build process of template's css
const allowedFiles = ['.css', '.otf', '.woff', '.woff2', '.ttf', '.svg', '.map']
const regexFiles = new RegExp(
`([a-zA-Z0-9s_\\.-:])+(${allowedFiles.join('|')})$`,
)
const availableAssets = []
if (fs.existsSync(path.join(folder, 'img'))) {
availableAssets.push(path.join(folder, 'img'))
}
if (fs.existsSync(path.join(folder, 'fonts'))) {
availableAssets.push(path.join(folder, 'fonts'))
}
if (fs.existsSync(path.join(folder, 'css'))) {
availableAssets.push(path.join(folder, 'css'))
}
const everythingChecked = await Promise.all(
map(availableAssets, async parentFolder => {
const dirFiles = await fs.readdir(parentFolder)
const checkedFiles = map(dirFiles, file => {
if (!regexFiles.test(file)) {
return false
}
return true
})
return !checkedFiles.includes(false)
}),
)
return !everythingChecked.includes(false)
}
const createTemplate = async (sourceRoot, data, cssFile, notes) => {
try {
const assetsRoot = path.join(sourceRoot, 'dist')
const areAssetsOK = await filesChecker(assetsRoot)
if (areAssetsOK) {
const { name, author, target } = data
const uploadsPath = config.get('pubsweet-server.uploads')
logger.info('About to create a new template')
const newTemplate = await Template.query().insert({
name: `${name} (${notes})`,
author,
target,
notes,
})
logger.info(`New template created with id ${newTemplate.id}`)
const destinationRoot = path.join(
process.cwd(),
uploadsPath,
'templates',
newTemplate.id,
)
await fs.ensureDir(path.join(process.cwd(), uploadsPath))
await fs.ensureDir(path.join(process.cwd(), uploadsPath, 'templates'))
await fs.ensureDir(destinationRoot)
logger.info(`The path the the files will be stored is ${destinationRoot}`)
if (fs.existsSync(path.join(assetsRoot, 'fonts'))) {
await fs.copy(path.join(assetsRoot, 'fonts'), destinationRoot)
}
if (fs.existsSync(path.join(assetsRoot, 'img'))) {
await fs.copy(path.join(assetsRoot, 'img'), destinationRoot)
}
if (fs.existsSync(path.join(assetsRoot, 'css'))) {
await fs.copy(path.join(assetsRoot, 'css', cssFile), path.join(destinationRoot, cssFile))
}
const destinationContents = await fs.readdir(destinationRoot)
await Promise.all(
map(destinationContents, async file => {
const newFile = await File.query().insert({
name: file,
mimetype: mime.lookup(file),
source: path.join(uploadsPath, 'templates', newTemplate.id, file),
templateId: newTemplate.id,
})
logger.info(
`File representation created on the db with file id ${newFile.id}`,
)
}),
)
} else {
throw new Error(
'an unsupported file exists in either dist/css, dist/fonts, dist/img. The supported files are .css, .otf, .woff, .woff2, .ttf, .svg',
)
}
} catch (e) {
throw new Error(e)
}
}
module.exports = {
execute,
createTemplate,
}