From cb5fe82cd5ec08b5021fc45fb1e57ae15e13637e Mon Sep 17 00:00:00 2001 From: Bogdan Cochior <bogdan.cochior@thinslices.com> Date: Fri, 16 Mar 2018 09:41:01 +0200 Subject: [PATCH] chore: update packages --- packages/component-aws-download/index.js | 5 - packages/component-aws-download/package.json | 18 -- .../component-aws-download/src/FileBackend.js | 62 ------ packages/component-local-aws/index.js | 5 - packages/component-local-aws/package.json | 18 -- .../component-local-aws/src/FileBackend.js | 45 ----- .../src/FileBackend.test.js | 188 ------------------ .../src/middeware/upload.js | 53 ----- .../src/routeHandlers/deleteFile.js | 22 -- .../src/routeHandlers/getSignedUrl.js | 24 --- .../src/routeHandlers/postFile.js | 15 -- .../src/routeHandlers/zipFiles.js | 55 ----- .../app/config/journal/submit-wizard.js | 4 +- packages/xpub-faraday/config/components.json | 4 +- packages/xpub-faraday/package.json | 7 +- yarn.lock | 74 +++++-- 16 files changed, 67 insertions(+), 532 deletions(-) delete mode 100644 packages/component-aws-download/index.js delete mode 100644 packages/component-aws-download/package.json delete mode 100644 packages/component-aws-download/src/FileBackend.js delete mode 100644 packages/component-local-aws/index.js delete mode 100644 packages/component-local-aws/package.json delete mode 100644 packages/component-local-aws/src/FileBackend.js delete mode 100644 packages/component-local-aws/src/FileBackend.test.js delete mode 100644 packages/component-local-aws/src/middeware/upload.js delete mode 100644 packages/component-local-aws/src/routeHandlers/deleteFile.js delete mode 100644 packages/component-local-aws/src/routeHandlers/getSignedUrl.js delete mode 100644 packages/component-local-aws/src/routeHandlers/postFile.js delete mode 100644 packages/component-local-aws/src/routeHandlers/zipFiles.js diff --git a/packages/component-aws-download/index.js b/packages/component-aws-download/index.js deleted file mode 100644 index 140b65ac0..000000000 --- a/packages/component-aws-download/index.js +++ /dev/null @@ -1,5 +0,0 @@ -require('dotenv').config() - -module.exports = { - backend: () => app => require('./src/FileBackend')(app), -} diff --git a/packages/component-aws-download/package.json b/packages/component-aws-download/package.json deleted file mode 100644 index 4d54d2c1d..000000000 --- a/packages/component-aws-download/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "component-aws-download", - "version": "0.0.1", - "main": "index.js", - "license": "MIT", - "dependencies": { - "archiver": "^2.1.1", - "aws-sdk": "^2.185.0", - "body-parser": "^1.17.2", - "multer": "^1.3.0", - "multer-s3": "^2.7.0", - "node-mocks-http": "^1.6.6" - }, - "peerDependencies": { - "@pubsweet/logger": "^0.0.1", - "pubsweet-server": "^1.0.1" - } -} diff --git a/packages/component-aws-download/src/FileBackend.js b/packages/component-aws-download/src/FileBackend.js deleted file mode 100644 index 74c4a5a76..000000000 --- a/packages/component-aws-download/src/FileBackend.js +++ /dev/null @@ -1,62 +0,0 @@ -const AWS = require('aws-sdk') -const _ = require('lodash') -const util = require('util') -const config = require('config') -const archiver = require('archiver') -// const logger = require('@pubsweet/logger') - -const s3Config = _.get(config, 'pubsweet-component-aws-s3') - -const FileBackend = app => { - const authBearer = app.locals.passport.authenticate('bearer', { - session: false, - }) - AWS.config.update({ - secretAccessKey: s3Config.secretAccessKey, - accessKeyId: s3Config.accessKeyId, - region: s3Config.region, - }) - const s3 = new AWS.S3() - - app.get('/api/fileZip/:fragmentId', authBearer, async (req, res) => { - const archive = archiver('zip') - const { fragmentId } = req.params - const getObject = util.promisify(s3.getObject.bind(s3)) - const listObjects = util.promisify(s3.listObjects.bind(s3)) - - try { - archive.pipe(res) - res.attachment(`${fragmentId}-archive.zip`) - - const params = { - Bucket: s3Config.bucket, - Prefix: `${fragmentId}`, - } - - const s3Items = await listObjects(params) - const s3Files = await Promise.all( - s3Items.Contents.map(content => - getObject({ - Bucket: s3Config.bucket, - Key: content.Key, - }), - ), - ) - - s3Files.forEach(f => { - archive.append(f.Body, { - name: `${_.get(f, 'Metadata.filetype') || 'supplementary'}/${_.get( - f, - 'Metadata.filename', - ) || f.ETag}`, - }) - }) - - archive.finalize() - } catch (err) { - res.status(err.statusCode).json({ error: err.message }) - } - }) -} - -module.exports = FileBackend diff --git a/packages/component-local-aws/index.js b/packages/component-local-aws/index.js deleted file mode 100644 index 140b65ac0..000000000 --- a/packages/component-local-aws/index.js +++ /dev/null @@ -1,5 +0,0 @@ -require('dotenv').config() - -module.exports = { - backend: () => app => require('./src/FileBackend')(app), -} diff --git a/packages/component-local-aws/package.json b/packages/component-local-aws/package.json deleted file mode 100644 index b38c67c0a..000000000 --- a/packages/component-local-aws/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "component-local-aws", - "version": "1.0.0", - "main": "index.js", - "license": "MIT", - "dependencies": { - "aws-sdk": "^2.185.0", - "body-parser": "^1.17.2", - "multer": "^1.3.0", - "multer-s3": "^2.7.0", - "node-mocks-http": "^1.6.6", - "nodemailer": "^4.4.2" - }, - "peerDependencies": { - "@pubsweet/logger": "^0.0.1", - "pubsweet-server": "^1.0.1" - } -} diff --git a/packages/component-local-aws/src/FileBackend.js b/packages/component-local-aws/src/FileBackend.js deleted file mode 100644 index b7866aa58..000000000 --- a/packages/component-local-aws/src/FileBackend.js +++ /dev/null @@ -1,45 +0,0 @@ -const _ = require('lodash') -const AWS = require('aws-sdk') -const config = require('config') - -const s3Config = _.get(config, 'pubsweet-component-aws-s3') - -const FileBackend = app => { - const authBearer = app.locals.passport.authenticate('bearer', { - session: false, - }) - AWS.config.update({ - secretAccessKey: s3Config.secretAccessKey, - accessKeyId: s3Config.accessKeyId, - region: s3Config.region, - }) - const s3 = new AWS.S3() - const upload = require('./middeware/upload').setupMulter(s3) - - app.post( - '/api/files', - authBearer, - upload.single('file'), - require('./routeHandlers/postFile'), - ) - - app.get( - '/api/files/:fragmentId/:fileId', - authBearer, - require('./routeHandlers/getSignedUrl')(s3, s3Config), - ) - - app.get( - '/api/files/:fragmentId', - authBearer, - require('./routeHandlers/zipFiles')(s3, s3Config), - ) - - app.delete( - '/api/files/:fragmentId/:fileId', - authBearer, - require('./routeHandlers/deleteFile')(s3, s3Config), - ) -} - -module.exports = FileBackend diff --git a/packages/component-local-aws/src/FileBackend.test.js b/packages/component-local-aws/src/FileBackend.test.js deleted file mode 100644 index 95a026ff5..000000000 --- a/packages/component-local-aws/src/FileBackend.test.js +++ /dev/null @@ -1,188 +0,0 @@ -process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' -process.env.SUPPRESS_NO_CONFIG_WARNING = true - -const httpMocks = require('node-mocks-http') - -const zipHandler = require('./routeHandlers/zipFiles') - -describe('ValidateFile for multer fileFilter', () => { - it('should return TRUE when fileType is supplementary', () => { - const validateFile = require('./middeware/upload').validateFile( - ...buildValidateFileParams('supplementary', 'image/png'), - ) - expect(validateFile).toBe(true) - }) - it('should return TRUE when fileType is manuscripts or coverLetter and the file is either Word Doc or PDF', () => { - const randFileType = getRandValueFromArray(['manuscripts', 'coverLetter']) - const randMimeType = getRandValueFromArray([ - 'application/pdf', - 'application/msword', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - ]) - - const validateFile = require('./middeware/upload').validateFile( - ...buildValidateFileParams(randFileType, randMimeType), - ) - expect(validateFile).toBe(true) - }) - it('should return FALSE when fileType is manuscripts or coverLetter and the file is neither Word Doc or PDF', () => { - const randFileType = getRandValueFromArray(['manuscripts', 'coverLetter']) - const randMimeType = getRandValueFromArray([ - 'text/plain', - 'text/html', - 'image/jpeg', - 'image/png', - ]) - - const validateFile = require('./middeware/upload').validateFile( - ...buildValidateFileParams(randFileType, randMimeType), - ) - expect(validateFile).toBe(false) - }) -}) - -describe('Upload file route handler', () => { - it('should return success when the file passed validation', async () => { - const file = { - key: '123abc', - originalname: 'file.txt', - size: 128, - } - const req = httpMocks.createRequest({ - file, - }) - const res = httpMocks.createResponse() - await require('./routeHandlers/postFile')(req, res) - expect(res.statusCode).toBe(200) - const data = JSON.parse(res._getData()) - expect(data.id).toEqual(file.key) - expect(data.name).toEqual(file.originalname) - expect(data.size).toEqual(file.size) - }) - it('should return an error when the file failed validation', async () => { - const req = httpMocks.createRequest({ - fileValidationError: 'Only Word documents and PDFs are allowed', - }) - const res = httpMocks.createResponse() - await require('./routeHandlers/postFile')(req, res) - expect(res.statusCode).toBe(400) - const data = JSON.parse(res._getData()) - expect(data.error).toEqual(req.fileValidationError) - }) -}) - -describe('Zip files endpoint', () => { - const testObject = { - Key: 'KeyToMyHeart', - Body: Buffer.alloc(10), - Metadata: { - filetype: 'manuscripts', - filename: 'test.txt', - }, - } - const mockBucket = { - RandomKey: { - Contents: [testObject, testObject], - }, - } - - const s3 = {} - const mocks = {} - let mockArchiver = null - const s3Config = { - bucket: 'TestBucket', - } - beforeAll(() => { - s3.getObject = jest.fn((params, cb) => { - cb(null, testObject) - }) - - s3.listObjects = jest.fn((params, cb) => { - cb(null, mockBucket[params.Prefix]) - }) - mocks.pipe = jest.fn() - mocks.append = jest.fn() - mocks.finalize = jest.fn() - mocks.attachment = jest.fn() - - mockArchiver = jest.fn(p => ({ - pipe: mocks.pipe, - append: mocks.append, - finalize: mocks.finalize, - })) - }) - afterEach(() => { - s3.getObject.mockClear() - s3.listObjects.mockClear() - mocks.pipe.mockClear() - mocks.append.mockClear() - mocks.attachment.mockClear() - }) - it(`no zipping if no files found`, async () => { - const zipFiles = zipHandler(s3, s3Config, mockArchiver) - const request = httpMocks.createRequest({ - method: 'GET', - params: { - fragmentId: 'NotFoundKey', - }, - }) - const response = httpMocks.createResponse() - response.attachment = mocks.attachment - - await zipFiles(request, response) - - expect(s3.listObjects.mock.calls).toHaveLength(1) - expect(s3.getObject.mock.calls).toHaveLength(0) - expect(mocks.attachment.mock.calls).toHaveLength(0) - expect(mocks.append.mock.calls).toHaveLength(0) - expect(mocks.pipe.mock.calls).toHaveLength(0) - - const responseData = JSON.parse(response._getData()) - - expect(responseData.message).toEqual( - `No files found for the requested manuscript.`, - ) - expect(response._getStatusCode()).toEqual(204) - }) - it('zips all the files', async () => { - const zipFiles = zipHandler(s3, s3Config, mockArchiver) - - const request = httpMocks.createRequest({ - method: 'GET', - params: { - fragmentId: 'RandomKey', - }, - }) - const response = httpMocks.createResponse() - response.attachment = mocks.attachment - - await zipFiles(request, response) - - expect(s3.listObjects.mock.calls).toHaveLength(1) - expect(s3.getObject.mock.calls).toHaveLength(2) - expect(mocks.attachment.mock.calls).toHaveLength(1) - expect(mocks.attachment.mock.calls[0][0]).toEqual('RandomKey-archive.zip') - expect(mocks.append.mock.calls).toHaveLength(2) - expect(mocks.pipe.mock.calls).toHaveLength(1) - expect(response._getStatusCode()).toEqual(200) - }) -}) - -const getRandValueFromArray = arr => arr[Math.floor(Math.random() * arr.length)] - -const buildValidateFileParams = (fileType, mimetype) => { - const req = { - body: { - fileType, - }, - } - const file = { - mimetype, - } - const cb = (p1, p2) => { - if (p2 === true) return true - return false - } - - return [req, file, cb] -} diff --git a/packages/component-local-aws/src/middeware/upload.js b/packages/component-local-aws/src/middeware/upload.js deleted file mode 100644 index f46f41766..000000000 --- a/packages/component-local-aws/src/middeware/upload.js +++ /dev/null @@ -1,53 +0,0 @@ -const Joi = require('joi') -const uuid = require('uuid') -const config = require('config') -const multer = require('multer') -const { get } = require('lodash') -const multerS3 = require('multer-s3') - -const s3Config = get(config, 'pubsweet-component-aws-s3') -const uploadValidations = require(s3Config.validations) - -const setupMulter = s3 => { - const upload = multer({ - storage: multerS3({ - s3, - bucket: s3Config.bucket, - contentType: (req, file, cb) => { - cb(null, file.mimetype) - }, - metadata: (req, file, cb) => { - cb(null, { - FileType: get(req, 'body.fileType'), - FileName: get(file, 'originalname'), - }) - }, - key: (req, file, cb) => { - const fileKey = `${req.body.fragmentId}/${uuid.v4()}` - cb(null, fileKey) - }, - }), - fileFilter: (req, file, cb) => validateFile(req, file, cb), - }) - - return upload -} - -const validateFile = (req, file, cb) => { - const { fileType } = req.body - const { mimetype } = file - - const valid = Joi.validate({ [fileType]: mimetype }, uploadValidations) - - if (valid.error) { - req.fileValidationError = valid.error.message - return cb(null, false) - } - - return cb(null, true) -} - -module.exports = { - setupMulter, - validateFile, -} diff --git a/packages/component-local-aws/src/routeHandlers/deleteFile.js b/packages/component-local-aws/src/routeHandlers/deleteFile.js deleted file mode 100644 index 9aa8974b7..000000000 --- a/packages/component-local-aws/src/routeHandlers/deleteFile.js +++ /dev/null @@ -1,22 +0,0 @@ -const { promisify } = require('util') -const logger = require('@pubsweet/logger') - -const deleteFile = (s3, s3Config) => { - const asyncDeleteObject = promisify(s3.deleteObject.bind(s3)) - return async (req, res) => { - const params = { - Bucket: s3Config.bucket, - Key: `${req.params.fragmentId}/${req.params.fileId}`, - } - - try { - await asyncDeleteObject(params) - res.status(204) - } catch (err) { - logger.error(err.message) - res.status(err.statusCode).json({ error: err.message }) - } - } -} - -module.exports = deleteFile diff --git a/packages/component-local-aws/src/routeHandlers/getSignedUrl.js b/packages/component-local-aws/src/routeHandlers/getSignedUrl.js deleted file mode 100644 index edbad7102..000000000 --- a/packages/component-local-aws/src/routeHandlers/getSignedUrl.js +++ /dev/null @@ -1,24 +0,0 @@ -const { promisify } = require('util') -const logger = require('@pubsweet/logger') - -const getSignedUrl = (s3, s3Config) => { - const asyncGetSignedUrl = promisify(s3.getSignedUrl.bind(s3)) - return async (req, res) => { - const params = { - Bucket: s3Config.bucket, - Key: `${req.params.fragmentId}/${req.params.fileId}`, - } - - try { - const signedUrl = await asyncGetSignedUrl(params) - res.status(200).json({ - signedUrl, - }) - } catch (err) { - logger.error(err.message) - res.status(err.statusCode).json({ error: err.message }) - } - } -} - -module.exports = getSignedUrl diff --git a/packages/component-local-aws/src/routeHandlers/postFile.js b/packages/component-local-aws/src/routeHandlers/postFile.js deleted file mode 100644 index 228c78fed..000000000 --- a/packages/component-local-aws/src/routeHandlers/postFile.js +++ /dev/null @@ -1,15 +0,0 @@ -const logger = require('@pubsweet/logger') - -module.exports = async (req, res) => { - if (req.fileValidationError !== undefined) { - logger.error(req.fileValidationError) - return res.status(400).json({ error: req.fileValidationError }) - } - logger.debug(`${req.file.originalname} has been uploaded`) - - return res.status(200).json({ - id: req.file.key, - name: req.file.originalname, - size: req.file.size, - }) -} diff --git a/packages/component-local-aws/src/routeHandlers/zipFiles.js b/packages/component-local-aws/src/routeHandlers/zipFiles.js deleted file mode 100644 index 272eccbfb..000000000 --- a/packages/component-local-aws/src/routeHandlers/zipFiles.js +++ /dev/null @@ -1,55 +0,0 @@ -const { get } = require('lodash') -const { promisify } = require('util') -const nodeArchiver = require('archiver') -const logger = require('@pubsweet/logger') - -const zipFiles = (s3, s3Config, archiver = nodeArchiver) => { - const asyncGetObject = promisify(s3.getObject.bind(s3)) - const asyncListObjects = promisify(s3.listObjects.bind(s3)) - return async (req, res) => { - const { fragmentId } = req.params - try { - const params = { - Bucket: s3Config.bucket, - Prefix: `${fragmentId}`, - } - const s3Items = await asyncListObjects(params) - - if (s3Items) { - const s3Files = await Promise.all( - s3Items.Contents.map(content => - asyncGetObject({ - Bucket: s3Config.bucket, - Key: content.Key, - }), - ), - ) - - if (s3Files) { - const archive = archiver('zip') - archive.pipe(res) - res.attachment(`${fragmentId}-archive.zip`) - - s3Files.forEach(f => { - archive.append(f.Body, { - name: `${get(f, 'Metadata.filetype') || 'supplementary'}/${get( - f, - 'Metadata.filename', - ) || f.ETag}`, - }) - }) - archive.finalize() - } - } else { - res.status(204).json({ - message: `No files found for the requested manuscript.`, - }) - } - } catch (err) { - logger.error(err.message) - res.status(err.statusCode).json({ error: err.message }) - } - } -} - -module.exports = zipFiles diff --git a/packages/xpub-faraday/app/config/journal/submit-wizard.js b/packages/xpub-faraday/app/config/journal/submit-wizard.js index 5f3ff6b74..b4b8cc37a 100644 --- a/packages/xpub-faraday/app/config/journal/submit-wizard.js +++ b/packages/xpub-faraday/app/config/journal/submit-wizard.js @@ -1,9 +1,7 @@ import React from 'react' import styled from 'styled-components' import uploadFileFn from 'xpub-upload' -// TODO: Add back abstract when xpub-edit is published -// import { AbstractEditor, TitleEditor } from 'xpub-edit' -import { TitleEditor } from 'xpub-edit' +import { AbstractEditor, TitleEditor } from 'xpub-edit' import { Menu, YesOrNo, TextField, CheckboxGroup } from '@pubsweet/ui' import { required, minChars, minSize } from 'xpub-validators' import { AuthorList, Files } from 'pubsweet-components-faraday/src/components' diff --git a/packages/xpub-faraday/config/components.json b/packages/xpub-faraday/config/components.json index 7a1555ce9..4f60ab58b 100644 --- a/packages/xpub-faraday/config/components.json +++ b/packages/xpub-faraday/config/components.json @@ -6,7 +6,5 @@ "pubsweet-component-modal", "pubsweet-components-faraday", "@pubsweet/component-aws-s3", - "pubsweet-component-invite", - "component-aws-download", - "component-local-aws" + "pubsweet-component-invite" ] diff --git a/packages/xpub-faraday/package.json b/packages/xpub-faraday/package.json index 7a7955bd8..f4ffca9a6 100644 --- a/packages/xpub-faraday/package.json +++ b/packages/xpub-faraday/package.json @@ -8,11 +8,10 @@ "url": "https://gitlab.coko.foundation/xpub/xpub-faraday" }, "dependencies": { - "@pubsweet/component-aws-s3": "^0.1.1", - "@pubsweet/ui": "^3.0.0", + "@pubsweet/ui": "^3.2.0", + "@pubsweet/component-aws-s3": "^1.0.0", "aws-sdk": "^2.197.0", "babel-core": "^6.26.0", - "component-aws-download": "0.0.1", "config": "^1.26.2", "dotenv": "^5.0.0", "flavors": "^3.3.1", @@ -44,7 +43,7 @@ "typeface-ubuntu-mono": "^0.0.54", "winston": "^2.4.0", "xpub-connect": "^0.0.3", - "xpub-edit": "^0.0.3", + "xpub-edit": "^0.0.4", "xpub-faraday-server": "^0.0.1", "xpub-journal": "^0.0.3", "xpub-selectors": "^0.0.3", diff --git a/yarn.lock b/yarn.lock index a20d4b3bb..50204ef2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -71,10 +71,11 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" -"@pubsweet/component-aws-s3@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@pubsweet/component-aws-s3/-/component-aws-s3-0.1.1.tgz#2faa379c1b8c12dbc6573a5627b09f536a484cc3" +"@pubsweet/component-aws-s3@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@pubsweet/component-aws-s3/-/component-aws-s3-1.0.0.tgz#5cb1715709ba5ad7b8ad79d1ef42d6818d17ca3e" dependencies: + archiver "^2.1.1" aws-sdk "^2.185.0" body-parser "^1.17.2" multer "^1.3.0" @@ -164,7 +165,7 @@ redux-form "^7.0.3" styled-components "^2.4.0" -"@pubsweet/ui@^3.0.0", "@pubsweet/ui@^3.1.0": +"@pubsweet/ui@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@pubsweet/ui/-/ui-3.1.0.tgz#24c25c29fc36e34b9f654fe4378502232f8204fa" dependencies: @@ -186,6 +187,28 @@ redux-form "^7.0.3" styled-components "^2.4.0" +"@pubsweet/ui@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@pubsweet/ui/-/ui-3.2.0.tgz#b787f1bb53fa818aade863c221bf47e2929e669e" + dependencies: + babel-jest "^21.2.0" + classnames "^2.2.5" + enzyme "^3.2.0" + enzyme-adapter-react-16 "^1.1.1" + humps "^2.0.1" + lodash "^4.17.4" + prop-types "^15.5.10" + react "^16.2.0" + react-dom "^16.2.0" + react-feather "^1.0.8" + react-redux "^5.0.2" + react-router-dom "^4.2.2" + react-tag-autocomplete "^5.5.0" + recompose "^0.26.0" + redux "^3.6.0" + redux-form "^7.0.3" + styled-components "^2.4.0" + "@types/node@*": version "9.4.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.6.tgz#d8176d864ee48753d053783e4e463aec86b8d82e" @@ -3132,7 +3155,19 @@ enzyme-adapter-react-15@^1.0.5: object.values "^1.0.4" prop-types "^15.5.10" -enzyme-adapter-utils@^1.1.0: +enzyme-adapter-react-16@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.1.1.tgz#a8f4278b47e082fbca14f5bfb1ee50ee650717b4" + dependencies: + enzyme-adapter-utils "^1.3.0" + lodash "^4.17.4" + object.assign "^4.0.4" + object.values "^1.0.4" + prop-types "^15.6.0" + react-reconciler "^0.7.0" + react-test-renderer "^16.0.0-0" + +enzyme-adapter-utils@^1.1.0, enzyme-adapter-utils@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.3.0.tgz#d6c85756826c257a8544d362cc7a67e97ea698c7" dependencies: @@ -8375,6 +8410,15 @@ react-proxy@^3.0.0-alpha.0: dependencies: lodash "^4.6.1" +react-reconciler@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.7.0.tgz#9614894103e5f138deeeb5eabaf3ee80eb1d026d" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.0" + react-redux@^5.0.2, react-redux@^5.0.6, react-redux@^5.0.7: version "5.0.7" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8" @@ -8417,10 +8461,18 @@ react-router@^4.2.0: prop-types "^15.5.4" warning "^3.0.0" -react-tag-autocomplete@^5.4.1: +react-tag-autocomplete@^5.4.1, react-tag-autocomplete@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/react-tag-autocomplete/-/react-tag-autocomplete-5.5.0.tgz#49841388b88323f6bccb0c10039bd0252875b49f" +react-test-renderer@^16.0.0-0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.2.0.tgz#bddf259a6b8fcd8555f012afc8eacc238872a211" + dependencies: + fbjs "^0.8.16" + object-assign "^4.1.1" + prop-types "^15.6.0" + react-transition-group@^2.0.0, react-transition-group@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10" @@ -10754,11 +10806,11 @@ xpub-connect@^0.0.3: redux "^3.6.0" styled-components "^2.4.0" -xpub-edit@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/xpub-edit/-/xpub-edit-0.0.3.tgz#76947a18140d1b61c460fcd96127569d322e0da7" +xpub-edit@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/xpub-edit/-/xpub-edit-0.0.4.tgz#2d20d4ab0ba83ac0b4b3d3f273a74da1518b55d1" dependencies: - "@pubsweet/ui" "3.0.0" + "@pubsweet/ui" "^3.2.0" prosemirror-commands "^1.0.1" prosemirror-dropcursor "^1.0.0" prosemirror-gapcursor "^1.0.0" @@ -10768,8 +10820,6 @@ xpub-edit@^0.0.3: prosemirror-model "^1.0.0" prosemirror-state "^1.0.1" prosemirror-view "^1.0.0" - react "^16.2.0" - react-dom "^16.2.0" xpub-journal@^0.0.3: version "0.0.3" -- GitLab