diff --git a/services/document-updater/.github/dependabot.yml b/services/document-updater/.github/dependabot.yml new file mode 100644 index 0000000000..c6f98d843d --- /dev/null +++ b/services/document-updater/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + + pull-request-branch-name: + # Separate sections of the branch name with a hyphen + # Docker images use the branch name and do not support slashes in tags + # https://github.com/overleaf/google-ops/issues/822 + # https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#pull-request-branch-nameseparator + separator: "-" + + # Block informal upgrades -- security upgrades use a separate queue. + # https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#open-pull-requests-limit + open-pull-requests-limit: 0 diff --git a/services/document-updater/.gitignore b/services/document-updater/.gitignore index 86e9e7a2fc..624e78f096 100644 --- a/services/document-updater/.gitignore +++ b/services/document-updater/.gitignore @@ -47,3 +47,6 @@ forever/ **/appendonly.aof **/dump.rdb **/nodes.conf + +# managed by dev-environment$ bin/update_build_scripts +.npmrc diff --git a/services/document-updater/Dockerfile b/services/document-updater/Dockerfile index b07f7117bc..78a715757d 100644 --- a/services/document-updater/Dockerfile +++ b/services/document-updater/Dockerfile @@ -15,8 +15,6 @@ RUN npm ci --quiet COPY . /app - - FROM base COPY --from=app /app /app diff --git a/services/document-updater/Jenkinsfile b/services/document-updater/Jenkinsfile deleted file mode 100644 index 803963773e..0000000000 --- a/services/document-updater/Jenkinsfile +++ /dev/null @@ -1,131 +0,0 @@ -String cron_string = BRANCH_NAME == "master" ? "@daily" : "" - -pipeline { - agent any - - environment { - GIT_PROJECT = "document-updater" - JENKINS_WORKFLOW = "document-updater-sharelatex" - TARGET_URL = "${env.JENKINS_URL}blue/organizations/jenkins/${JENKINS_WORKFLOW}/detail/$BRANCH_NAME/$BUILD_NUMBER/pipeline" - GIT_API_URL = "https://api.github.com/repos/overleaf/${GIT_PROJECT}/statuses/$GIT_COMMIT" - } - - triggers { - pollSCM('* * * * *') - cron(cron_string) - } - - stages { - - stage('Install') { - steps { - withCredentials([usernamePassword(credentialsId: 'GITHUB_INTEGRATION', usernameVariable: 'GH_AUTH_USERNAME', passwordVariable: 'GH_AUTH_PASSWORD')]) { - sh "curl $GIT_API_URL \ - --data '{ \ - \"state\" : \"pending\", \ - \"target_url\": \"$TARGET_URL\", \ - \"description\": \"Your build is underway\", \ - \"context\": \"ci/jenkins\" }' \ - -u $GH_AUTH_USERNAME:$GH_AUTH_PASSWORD" - } - } - } - - stage('Build') { - steps { - sh 'make build' - } - } - - stage('Linting') { - steps { - sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make format' - sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make lint' - } - } - - stage('Unit Tests') { - steps { - sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_unit' - } - } - - stage('Acceptance Tests') { - steps { - sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' - } - } - - stage('Package and docker push') { - steps { - sh 'echo ${BUILD_NUMBER} > build_number.txt' - sh 'touch build.tar.gz' // Avoid tar warning about files changing during read - sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make tar' - - withCredentials([file(credentialsId: 'gcr.io_overleaf-ops', variable: 'DOCKER_REPO_KEY_PATH')]) { - sh 'docker login -u _json_key --password-stdin https://gcr.io/overleaf-ops < ${DOCKER_REPO_KEY_PATH}' - } - sh 'DOCKER_REPO=gcr.io/overleaf-ops make publish' - sh 'docker logout https://gcr.io/overleaf-ops' - - } - } - - stage('Publish to s3') { - steps { - sh 'echo ${BRANCH_NAME}-${BUILD_NUMBER} > build_number.txt' - withAWS(credentials:'S3_CI_BUILDS_AWS_KEYS', region:"${S3_REGION_BUILD_ARTEFACTS}") { - s3Upload(file:'build.tar.gz', bucket:"${S3_BUCKET_BUILD_ARTEFACTS}", path:"${JOB_NAME}/${BUILD_NUMBER}.tar.gz") - } - withAWS(credentials:'S3_CI_BUILDS_AWS_KEYS', region:"${S3_REGION_BUILD_ARTEFACTS}") { - // The deployment process uses this file to figure out the latest build - s3Upload(file:'build_number.txt', bucket:"${S3_BUCKET_BUILD_ARTEFACTS}", path:"${JOB_NAME}/latest") - } - } - } - } - - post { - always { - sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_clean' - sh 'make clean' - } - - success { - withCredentials([usernamePassword(credentialsId: 'GITHUB_INTEGRATION', usernameVariable: 'GH_AUTH_USERNAME', passwordVariable: 'GH_AUTH_PASSWORD')]) { - sh "curl $GIT_API_URL \ - --data '{ \ - \"state\" : \"success\", \ - \"target_url\": \"$TARGET_URL\", \ - \"description\": \"Your build succeeded!\", \ - \"context\": \"ci/jenkins\" }' \ - -u $GH_AUTH_USERNAME:$GH_AUTH_PASSWORD" - } - } - - failure { - mail(from: "${EMAIL_ALERT_FROM}", - to: "${EMAIL_ALERT_TO}", - subject: "Jenkins build failed: ${JOB_NAME}:${BUILD_NUMBER}", - body: "Build: ${BUILD_URL}") - withCredentials([usernamePassword(credentialsId: 'GITHUB_INTEGRATION', usernameVariable: 'GH_AUTH_USERNAME', passwordVariable: 'GH_AUTH_PASSWORD')]) { - sh "curl $GIT_API_URL \ - --data '{ \ - \"state\" : \"failure\", \ - \"target_url\": \"$TARGET_URL\", \ - \"description\": \"Your build failed\", \ - \"context\": \"ci/jenkins\" }' \ - -u $GH_AUTH_USERNAME:$GH_AUTH_PASSWORD" - } - } - } - - // The options directive is for configuration that applies to the whole job. - options { - // we'd like to make sure remove old builds, so we don't fill up our storage! - buildDiscarder(logRotator(numToKeepStr:'50')) - - // And we'd really like to be sure that this build doesn't hang forever, so let's time it out after: - timeout(time: 30, unit: 'MINUTES') - } -} diff --git a/services/document-updater/Makefile b/services/document-updater/Makefile index df879265c9..596aa47fdb 100644 --- a/services/document-updater/Makefile +++ b/services/document-updater/Makefile @@ -25,13 +25,13 @@ clean: docker rmi gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) format: - $(DOCKER_COMPOSE) run --rm test_unit npm run format + $(DOCKER_COMPOSE) run --rm test_unit npm run --silent format format_fix: - $(DOCKER_COMPOSE) run --rm test_unit npm run format:fix + $(DOCKER_COMPOSE) run --rm test_unit npm run --silent format:fix lint: - $(DOCKER_COMPOSE) run --rm test_unit npm run lint + $(DOCKER_COMPOSE) run --rm test_unit npm run --silent lint test: format lint test_unit test_acceptance diff --git a/services/document-updater/buildscript.txt b/services/document-updater/buildscript.txt index 7c1e06607e..1593c6c188 100644 --- a/services/document-updater/buildscript.txt +++ b/services/document-updater/buildscript.txt @@ -1,10 +1,8 @@ document-updater ---acceptance-creds=None --dependencies=mongo,redis --docker-repos=gcr.io/overleaf-ops --env-add= --env-pass-through= ---language=es --node-version=10.21.0 --public-repo=True ---script-version=2.2.0 +--script-version=3.3.1 diff --git a/services/document-updater/docker-compose.ci.yml b/services/document-updater/docker-compose.ci.yml index d609e7b5ec..848ca57a38 100644 --- a/services/document-updater/docker-compose.ci.yml +++ b/services/document-updater/docker-compose.ci.yml @@ -11,6 +11,7 @@ services: command: npm run test:unit:_run environment: NODE_ENV: test + NODE_OPTIONS: "--unhandled-rejections=strict" test_acceptance: @@ -23,6 +24,7 @@ services: POSTGRES_HOST: postgres MOCHA_GREP: ${MOCHA_GREP} NODE_ENV: test + NODE_OPTIONS: "--unhandled-rejections=strict" depends_on: mongo: condition: service_healthy diff --git a/services/document-updater/docker-compose.yml b/services/document-updater/docker-compose.yml index 47c4ffc1b1..f8e0219b19 100644 --- a/services/document-updater/docker-compose.yml +++ b/services/document-updater/docker-compose.yml @@ -13,7 +13,8 @@ services: environment: MOCHA_GREP: ${MOCHA_GREP} NODE_ENV: test - command: npm run test:unit + NODE_OPTIONS: "--unhandled-rejections=strict" + command: npm run --silent test:unit user: node test_acceptance: @@ -29,13 +30,14 @@ services: MOCHA_GREP: ${MOCHA_GREP} LOG_LEVEL: ERROR NODE_ENV: test + NODE_OPTIONS: "--unhandled-rejections=strict" user: node depends_on: mongo: condition: service_healthy redis: condition: service_healthy - command: npm run test:acceptance + command: npm run --silent test:acceptance redis: image: redis diff --git a/services/document-updater/nodemon.json b/services/document-updater/nodemon.json index 5826281b84..e3e8817d90 100644 --- a/services/document-updater/nodemon.json +++ b/services/document-updater/nodemon.json @@ -8,7 +8,6 @@ "execMap": { "js": "npm run start" }, - "watch": [ "app/js/", "app.js", diff --git a/services/document-updater/package-lock.json b/services/document-updater/package-lock.json index 8bc91495cb..c154414b01 100644 --- a/services/document-updater/package-lock.json +++ b/services/document-updater/package-lock.json @@ -2032,9 +2032,9 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.6.0.tgz", - "integrity": "sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -2052,7 +2052,7 @@ "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", - "globals": "^11.7.0", + "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -2065,7 +2065,7 @@ "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", + "optionator": "^0.8.3", "progress": "^2.0.0", "regexpp": "^2.0.1", "semver": "^6.1.2", @@ -2106,6 +2106,15 @@ "ms": "^2.1.1" } }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -2126,6 +2135,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, @@ -2240,9 +2255,9 @@ "dev": true }, "eslint-plugin-chai-friendly": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.6.0.tgz", - "integrity": "sha512-Uvvv1gkbRGp/qfN15B0kQyQWg+oFA8buDSqrwmW3egNSk/FpqH2MjQqKOuKwmEL6w4QIQrIjDp+gg6kGGmD3oQ==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.5.0.tgz", + "integrity": "sha512-Pxe6z8C9fP0pn2X2nGFU/b3GBOCM/5FVus1hsMwJsXP3R7RiXFl7g0ksJbsc0GxiLyidTW4mEFk77qsNn7Tk7g==", "dev": true }, "eslint-plugin-es": { @@ -2526,9 +2541,9 @@ "dev": true }, "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -2562,9 +2577,9 @@ }, "dependencies": { "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", "dev": true } } @@ -3283,21 +3298,21 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", + "chalk": "^4.1.0", "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", + "cli-width": "^3.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", - "lodash": "^4.17.15", + "lodash": "^4.17.19", "mute-stream": "0.0.8", "run-async": "^2.4.0", - "rxjs": "^6.5.3", + "rxjs": "^6.6.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" @@ -3320,15 +3335,21 @@ } }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3362,6 +3383,21 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "rxjs": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", + "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -4554,9 +4590,9 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.1.tgz", + "integrity": "sha512-ZpZpjcJeugQfWsfyQlshVoowIIQ1qBGSVll4rfDq6JJVO//fesjoX808hXWfBjY+ROZgpKDI5TRSRBSoJiZ8eg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" @@ -6312,9 +6348,9 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" }, "strip-json-comments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", - "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "stubs": { @@ -6599,9 +6635,9 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", "dev": true }, "validate-npm-package-license": { diff --git a/services/document-updater/package.json b/services/document-updater/package.json index 04484720ea..5858eebd9a 100644 --- a/services/document-updater/package.json +++ b/services/document-updater/package.json @@ -13,7 +13,7 @@ "test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js", "test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP", "nodemon": "nodemon --config nodemon.json", - "lint": "node_modules/.bin/eslint .", + "lint": "node_modules/.bin/eslint --max-warnings 0 .", "format": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --list-different", "format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write" }, @@ -36,23 +36,23 @@ "chai": "^3.5.0", "chai-spies": "^0.7.1", "cluster-key-slot": "^1.0.5", - "eslint": "^6.6.0", - "eslint-config-prettier": "^6.11.0", - "eslint-config-standard": "^14.1.1", + "eslint": "^6.8.0", + "eslint-config-prettier": "^6.10.0", + "eslint-config-standard": "^14.1.0", "eslint-config-standard-jsx": "^8.1.0", "eslint-config-standard-react": "^9.2.0", "eslint-plugin-chai-expect": "^2.1.0", - "eslint-plugin-chai-friendly": "^0.6.0", - "eslint-plugin-import": "^2.20.2", + "eslint-plugin-chai-friendly": "^0.5.0", + "eslint-plugin-import": "^2.20.1", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-mocha": "^6.3.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^3.1.3", + "eslint-plugin-node": "^11.0.0", + "eslint-plugin-prettier": "^3.1.2", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-react": "^7.19.0", "eslint-plugin-standard": "^4.0.1", "mocha": "^5.0.1", - "prettier": "^2.0.5", + "prettier": "^2.0.0", "prettier-eslint-cli": "^5.0.0", "sandboxed-module": "~0.2.0", "sinon": "^9.0.2",