'use strict'; const { Router } = require('express'); const joi = require('joi'); const eventType = require('../../event-type'); const logger = require('../../logger')('/admin-api/strategy.js'); const NameExistsError = require('../../error/name-exists-error'); const extractUser = require('../../extract-user'); const strategySchema = require('./strategy-schema'); const version = 1; const handleError = (req, res, error) => { logger.warn('Error creating or updating strategy', error); switch (error.name) { case 'NotFoundError': return res.status(404).end(); case 'NameExistsError': return res .status(403) .json([ { msg: `A strategy named '${req.body .name}' already exists.`, }, ]) .end(); case 'ValidationError': return res .status(400) .json(error) .end(); default: logger.error('Could perfom operation', error); return res.status(500).end(); } }; function validateEditable(strategyName) { return strategy => { if (strategy.editable === false) { throw new Error( `Cannot edit strategy ${strategyName}, editable is false` ); } return strategy; }; } function validateInput(data) { return new Promise((resolve, reject) => { joi.validate(data, strategySchema, (err, cleaned) => { if (err) { return reject(err); } return resolve(cleaned); }); }); } exports.router = function(config) { const { strategyStore, eventStore } = config.stores; const router = Router(); router.get('/', (req, res) => { strategyStore.getStrategies().then(strategies => { res.json({ version, strategies }); }); }); router.get('/:name', (req, res) => { strategyStore .getStrategy(req.params.name) .then(strategy => res.json(strategy).end()) .catch(() => res.status(404).json({ error: 'Could not find strategy' }) ); }); router.delete('/:name', (req, res) => { const strategyName = req.params.name; strategyStore .getStrategy(strategyName) .then(validateEditable(strategyName)) .then(() => eventStore.store({ type: eventType.STRATEGY_DELETED, createdBy: extractUser(req), data: { name: strategyName, }, }) ) .then(() => res.status(200).end()) .catch(error => handleError(req, res, error)); }); function validateStrategyName(data) { return new Promise((resolve, reject) => { strategyStore .getStrategy(data.name) .then(() => reject(new NameExistsError('Feature name already exist')) ) .catch(() => resolve(data)); }); } router.post('/', (req, res) => { const data = req.body; validateInput(data) .then(validateStrategyName) .then(newStrategy => eventStore.store({ type: eventType.STRATEGY_CREATED, createdBy: extractUser(req), data: newStrategy, }) ) .then(() => res.status(201).end()) .catch(error => handleError(req, res, error)); }); router.put('/:strategyName', (req, res) => { const strategyName = req.params.strategyName; const updatedStrategy = req.body; updatedStrategy.name = strategyName; strategyStore .getStrategy(strategyName) .then(validateEditable(strategyName)) .then(() => validateInput(updatedStrategy)) .then(() => eventStore.store({ type: eventType.STRATEGY_UPDATED, createdBy: extractUser(req), data: updatedStrategy, }) ) .then(() => res.status(200).end()) .catch(error => handleError(req, res, error)); }); return router; };