123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- const graphHelper = require('../../helpers/graph')
- const _ = require('lodash')
- const CleanCSS = require('clean-css')
- const path = require('path')
- /* global WIKI */
- module.exports = {
- Query: {
- async sites () {
- const sites = await WIKI.models.sites.query().orderBy('hostname')
- return sites.map(s => ({
- ...s.config,
- id: s.id,
- hostname: s.hostname,
- isEnabled: s.isEnabled,
- pageExtensions: s.config.pageExtensions.join(', ')
- }))
- },
- async siteById (obj, args) {
- const site = await WIKI.models.sites.query().findById(args.id)
- return site ? {
- ...site.config,
- id: site.id,
- hostname: site.hostname,
- isEnabled: site.isEnabled,
- pageExtensions: site.config.pageExtensions.join(', ')
- } : null
- },
- async siteByHostname (obj, args) {
- let site = await WIKI.models.sites.query().where({
- hostname: args.hostname
- }).first()
- if (!site && !args.exact) {
- site = await WIKI.models.sites.query().where({
- hostname: '*'
- }).first()
- }
- return site ? {
- ...site.config,
- id: site.id,
- hostname: site.hostname,
- isEnabled: site.isEnabled,
- pageExtensions: site.config.pageExtensions.join(', ')
- } : null
- }
- },
- Mutation: {
- /**
- * CREATE SITE
- */
- async createSite (obj, args) {
- try {
- // -> Validate inputs
- if (!args.hostname || args.hostname.length < 1 || !/^(\\*)|([a-z0-9\-.:]+)$/.test(args.hostname)) {
- throw WIKI.ERROR(new Error('Invalid Site Hostname'), 'SiteCreateInvalidHostname')
- }
- if (!args.title || args.title.length < 1 || !/^[^<>"]+$/.test(args.title)) {
- throw WIKI.ERROR(new Error('Invalid Site Title'), 'SiteCreateInvalidTitle')
- }
- // -> Check for duplicate catch-all
- if (args.hostname === '*') {
- const site = await WIKI.models.sites.query().where({
- hostname: args.hostname
- }).first()
- if (site) {
- throw WIKI.ERROR(new Error('A site with a catch-all hostname already exists! Cannot have 2 catch-all hostnames.'), 'SiteCreateDuplicateCatchAll')
- }
- }
- // -> Create site
- const newSite = await WIKI.models.sites.createSite(args.hostname, {
- title: args.title
- })
- return {
- operation: graphHelper.generateSuccess('Site created successfully'),
- site: newSite
- }
- } catch (err) {
- WIKI.logger.warn(err)
- return graphHelper.generateError(err)
- }
- },
- /**
- * UPDATE SITE
- */
- async updateSite (obj, args) {
- try {
- // -> Load site
- const site = await WIKI.models.sites.query().findById(args.id)
- if (!site) {
- throw WIKI.ERROR(new Error('Invalid Site ID'), 'SiteInvalidId')
- }
- // -> Check for bad input
- if (_.has(args.patch, 'hostname') && _.trim(args.patch.hostname).length < 1) {
- throw WIKI.ERROR(new Error('Hostname is invalid.'), 'SiteInvalidHostname')
- }
- // -> Check for duplicate catch-all
- if (args.patch.hostname === '*' && site.hostname !== '*') {
- const dupSite = await WIKI.models.sites.query().where({ hostname: '*' }).first()
- if (dupSite) {
- throw WIKI.ERROR(new Error(`Site ${dupSite.config.title} with a catch-all hostname already exists! Cannot have 2 catch-all hostnames.`), 'SiteUpdateDuplicateCatchAll')
- }
- }
- // -> Format Code
- if (args.patch?.theme?.injectCSS) {
- args.patch.theme.injectCSS = new CleanCSS({ inline: false }).minify(args.patch.theme.injectCSS).styles
- }
- // -> Format Page Extensions
- if (args.patch?.pageExtensions) {
- args.patch.pageExtensions = args.patch.pageExtensions.split(',').map(ext => ext.trim().toLowerCase()).filter(ext => ext.length > 0)
- }
- // -> Update site
- await WIKI.models.sites.updateSite(args.id, {
- hostname: args.patch.hostname ?? site.hostname,
- isEnabled: args.patch.isEnabled ?? site.isEnabled,
- config: _.defaultsDeep(_.omit(args.patch, ['hostname', 'isEnabled']), site.config)
- })
- return {
- operation: graphHelper.generateSuccess('Site updated successfully')
- }
- } catch (err) {
- WIKI.logger.warn(err)
- return graphHelper.generateError(err)
- }
- },
- /**
- * DELETE SITE
- */
- async deleteSite (obj, args) {
- try {
- // -> Ensure site isn't last one
- const sitesCount = await WIKI.models.sites.query().count('id').first()
- if (sitesCount?.count && _.toNumber(sitesCount?.count) <= 1) {
- throw WIKI.ERROR(new Error('Cannot delete the last site. At least 1 site must exists at all times.'), 'SiteDeleteLastSite')
- }
- // -> Delete site
- await WIKI.models.sites.deleteSite(args.id)
- return {
- operation: graphHelper.generateSuccess('Site deleted successfully')
- }
- } catch (err) {
- WIKI.logger.warn(err)
- return graphHelper.generateError(err)
- }
- },
- /**
- * UPLOAD LOGO
- */
- async uploadSiteLogo (obj, args) {
- try {
- const { filename, mimetype, createReadStream } = await args.image
- WIKI.logger.info(`Processing site logo ${filename} of type ${mimetype}...`)
- if (!WIKI.extensions.ext.sharp.isInstalled) {
- throw new Error('This feature requires the Sharp extension but it is not installed.')
- }
- console.info(mimetype)
- const destFormat = mimetype.startsWith('image/svg') ? 'svg' : 'png'
- const destPath = path.resolve(
- process.cwd(),
- WIKI.config.dataPath,
- `assets/logo.${destFormat}`
- )
- await WIKI.extensions.ext.sharp.resize({
- format: destFormat,
- inputStream: createReadStream(),
- outputPath: destPath,
- width: 100
- })
- WIKI.logger.info('New site logo processed successfully.')
- return {
- operation: graphHelper.generateSuccess('Site logo uploaded successfully')
- }
- } catch (err) {
- return graphHelper.generateError(err)
- }
- },
- /**
- * UPLOAD FAVICON
- */
- async uploadSiteFavicon (obj, args) {
- const { filename, mimetype, createReadStream } = await args.image
- console.info(filename, mimetype)
- return {
- operation: graphHelper.generateSuccess('Site favicon uploaded successfully')
- }
- }
- }
- }
|